1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 by Karl Kurbjun
12 * Some of this is based on the Cowon A2 Firmware release:
13 * http://www.cowonglobal.com/download/gnu/cowon_pmp_a2_src_1.59_GPL.tar.gz
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
23 ****************************************************************************/
25 #include <sys/types.h>
30 #include "string-extra.h" /* memset16() */
32 #include "system-target.h"
34 #include "lcd-target.h"
35 #include "dsp-target.h"
38 #if CONFIG_ORIENTATION == SCREEN_PORTRAIT
40 #elif defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
44 /* Copies a rectangle from one framebuffer to another. Can be used in
45 single transfer mode with width = num pixels, and height = 1 which
46 allows a full-width rectangle to be copied more efficiently. */
47 extern void lcd_copy_buffer_rect(fb_data
*dst
, const fb_data
*src
,
48 int width
, int height
);
50 #if defined(HAVE_LCD_SLEEP)
51 static bool lcd_on
= true;
55 ** These are imported from lcd-16bit.c
57 extern unsigned fg_pattern
;
58 extern unsigned bg_pattern
;
60 #if defined(HAVE_LCD_SLEEP)
67 #if defined(HAVE_LCD_SLEEP)
73 memset16(FRAME
, 0xFFFF, LCD_WIDTH
*LCD_HEIGHT
);
75 /* Disabling these saves another ~15mA */
76 IO_OSD_OSDWINMD0
&= ~(0x01);
77 IO_VID_ENC_VMOD
&= ~(0x01);
79 /* Disabling the LCD saves ~50mA */
80 IO_GIO_BITCLR2
=1<<4; /* pin 36 */
86 /* "enabled" implies "powered" */
90 IO_OSD_OSDWINMD0
|= 0x01;
91 IO_VID_ENC_VMOD
|= 0x01;
94 IO_GIO_BITSET2
= 1<<4;
98 /* Wait long enough for a frame to be written */
102 send_event(LCD_EVENT_ACTIVATION
, NULL
);
107 void lcd_enable_composite(bool enable
)
109 /* Pin 39 appears to be related to the composite output */
110 /* 39: output, non-inverted, no-irq, falling edge, no-chat, normal */
111 dm320_set_io(39, false, false, false, false, false, 0x00);
113 short vidtemp
= (IO_VID_ENC_VMOD
& 0x7E8);
117 IO_GIO_BITSET2
= 0x80;
122 IO_GIO_BITCLR2
= 0x80;
124 IO_VID_ENC_DCLKCTL
= 0x0800;
125 IO_VID_ENC_DCLKPTN0
= 0x0001;
128 IO_VID_ENC_VMOD
= vidtemp
;
131 /* Note this is expecting a screen size of 480x640 or 240x320, other screen
132 * sizes need to be considered for fudge factors
134 #define LCD_FUDGE LCD_NATIVE_WIDTH%32
136 /* LCD init - based on code from ingenient-bsp/bootloader/board/dm320/splash.c
137 * and code by Catalin Patulea from the M:Robe 500i linux port
139 void lcd_init_device(void)
145 * 34 - R2 for 18 bit output
146 * 35 - Resolution (MO?)
147 * 36 - LCD power (INI?)
148 * 37 - Backlight and LCD power
149 * 38 - B2 for 18 bit output
152 /* Setup main LCD pins */
153 /* 32: output, non-inverted, no-irq, falling edge, no-chat, normal */
154 dm320_set_io(32, false, false, false, false, false, 0x00);
155 IO_GIO_BITCLR2
= 1; /* Turn the LED off */
157 /* 34: output, non-inverted, no-irq, falling edge, no-chat, R2 */
158 dm320_set_io(34, false, false, false, false, false, 0x02);
160 /* 35: output, non-inverted, no-irq, falling edge, no-chat, normal */
161 dm320_set_io(35, false, false, false, false, false, 0x00);
162 #if LCD_NATIVE_HEIGHT > 320
163 IO_GIO_BITSET2
= 1<<3; /* Set LCD resolution to VGA */
165 IO_GIO_BITCLR2
= 1<<3; /* Set LCD resolution to QVGA */
168 /* 36: output, non-inverted, no-irq, falling edge, no-chat, normal */
169 dm320_set_io(36, false, false, false, false, false, 0x00);
170 IO_GIO_BITSET2
= 0x10; /* LCD on */
172 /* 37: output, non-inverted, no-irq, falling edge, no-chat, normal */
173 dm320_set_io(37, false, false, false, false, false, 0x00);
174 IO_GIO_BITCLR2
= (1 << 5); /* output low (backlight/lcd on) */
176 /* 38: output, non-inverted, no-irq, falling edge, no-chat, B2 */
177 dm320_set_io(38, false, false, false, false, false, 0x02);
179 /* Enable clocks for display */
180 IO_CLK_MOD1
|= (CLK_MOD1_VENC
| CLK_MOD1_OSD
);
182 /* Clear the Frame */
183 memset16(FRAME
, 0x0000, LCD_WIDTH
*LCD_HEIGHT
);
185 IO_OSD_OSDWINMD0
&= ~(0x0001);
186 IO_OSD_VIDWINMD
&= ~(0x0001);
188 /* Setup the LCD controller */
189 IO_VID_ENC_VMOD
= 0x2014;
190 IO_VID_ENC_VDCTL
= 0x2000;
191 IO_VID_ENC_VDPRO
= 0x0000;
192 IO_VID_ENC_SYNCTL
= 0x100E;
193 IO_VID_ENC_HSPLS
= 1; /* HSYNC pulse width */
194 IO_VID_ENC_VSPLS
= 1; /* VSYNC pulse width */
196 /* These calculations support 640x480 and 320x240 (based on OF) */
197 IO_VID_ENC_HINT
= LCD_NATIVE_WIDTH
+LCD_NATIVE_WIDTH
/3;
198 IO_VID_ENC_HSTART
= LCD_NATIVE_WIDTH
/6; /* Back porch */
199 IO_VID_ENC_HVALID
= LCD_NATIVE_WIDTH
; /* Data valid */
200 IO_VID_ENC_VINT
= LCD_NATIVE_HEIGHT
+8;
201 IO_VID_ENC_VSTART
= 2;
202 IO_VID_ENC_VVALID
= LCD_NATIVE_HEIGHT
;
204 IO_VID_ENC_HSDLY
= 0x0000;
205 IO_VID_ENC_VSDLY
= 0x0000;
206 IO_VID_ENC_YCCTL
= 0x0000;
207 IO_VID_ENC_RGBCTL
= 0x0000;
208 IO_VID_ENC_RGBCLP
= 0xFF00;
209 IO_VID_ENC_LNECTL
= 0x0000;
210 IO_VID_ENC_CULLLNE
= 0x0000;
211 IO_VID_ENC_LCDOUT
= 0x0000;
212 IO_VID_ENC_BRTS
= 0x0000;
213 IO_VID_ENC_BRTW
= 0x0000;
214 IO_VID_ENC_ACCTL
= 0x0000;
215 IO_VID_ENC_PWMP
= 0x0000;
216 IO_VID_ENC_PWMW
= 0x0000;
218 /* Setup the display */
219 IO_OSD_MODE
= 0x00ff;
221 IO_OSD_ATRMD
= 0x0000;
222 IO_OSD_RECTCUR
= 0x0000;
224 IO_OSD_BASEPX
= IO_VID_ENC_HSTART
;
225 IO_OSD_BASEPY
= IO_VID_ENC_VSTART
;
227 addr
= ((int)FRAME
-CONFIG_SDRAM_START
) / 32;
229 /* Setup the OSD windows */
231 /* Used for 565 RGB */
232 IO_OSD_OSDWINMD0
= 0x30C0;
234 IO_OSD_OSDWIN0OFST
= LCD_NATIVE_WIDTH
*2 / 32;
236 IO_OSD_OSDWINADH
= addr
>> 16;
237 IO_OSD_OSDWIN0ADL
= addr
& 0xFFFF;
239 IO_OSD_OSDWIN0XP
= 0;
240 IO_OSD_OSDWIN0YP
= 0;
243 IO_OSD_OSDWIN0XL
= LCD_NATIVE_WIDTH
;
244 IO_OSD_OSDWIN0YL
= LCD_NATIVE_HEIGHT
;
247 IO_OSD_OSDWINMD1
= 0x10C0;
249 #if LCD_NATIVE_WIDTH%32!=0
250 IO_OSD_OSDWIN1OFST
= LCD_NATIVE_WIDTH
/ 32+1;
252 IO_OSD_OSDWIN1OFST
= LCD_NATIVE_WIDTH
/ 32;
255 IO_OSD_OSDWIN1ADL
= addr
& 0xFFFF;
257 IO_OSD_OSDWIN1XP
= 0;
258 IO_OSD_OSDWIN1YP
= 0;
260 IO_OSD_OSDWIN1XL
= LCD_NATIVE_WIDTH
;
261 IO_OSD_OSDWIN1YL
= LCD_NATIVE_HEIGHT
;
263 IO_OSD_VIDWINMD
= 0x0000;
265 addr
= ((int)FRAME2
-CONFIG_SDRAM_START
+
266 2*(LCD_NATIVE_WIDTH
*(LCD_NATIVE_HEIGHT
-320)/2+
267 (LCD_NATIVE_WIDTH
-240)/2))/ 32;
269 /* This is a bit messy, the LCD transfers appear to happen in chunks of 32
270 * pixels. (based on OF)
272 #if LCD_NATIVE_WIDTH%32!=0
273 IO_OSD_VIDWIN0OFST
= LCD_NATIVE_WIDTH
* 2 / 32+1;
275 IO_OSD_VIDWIN0OFST
= LCD_NATIVE_WIDTH
* 2 / 32;
278 IO_OSD_VIDWINADH
= addr
>> 16;
279 IO_OSD_VIDWIN0ADL
= addr
& 0xFFFF;
281 IO_OSD_VIDWIN0XP
= 0;
282 IO_OSD_VIDWIN0YP
= 0;
284 IO_OSD_VIDWIN0XL
= LCD_NATIVE_WIDTH
;
285 IO_OSD_VIDWIN0YL
= LCD_NATIVE_HEIGHT
;
287 IO_OSD_OSDWINMD0
|= 0x01;
289 lcd_enable_composite(false);
292 #if defined(HAVE_LCD_MODES)
293 void lcd_set_mode(int mode
)
295 if(mode
==LCD_MODE_YUV
) {
296 /* Turn off the RGB buffer and enable the YUV buffer with zoom */
297 IO_OSD_OSDWINMD0
|= 0x04;
298 IO_OSD_VIDWINMD
|= 0x01;
299 #if LCD_NATIVE_WIDTH > 240
300 IO_OSD_VIDWINMD
|= (0x05<<2); /* This does a 2x zoom */
302 memset16(FRAME2
, 0x0080, LCD_NATIVE_HEIGHT
*(LCD_NATIVE_WIDTH
+LCD_FUDGE
));
303 } else if(mode
==LCD_MODE_RGB565
) {
304 /* Turn on the RGB window, set it to 16 bit and turn YUV window off */
305 IO_OSD_VIDWINMD
&= ~(0x01);
306 IO_OSD_OSDWIN0OFST
= LCD_NATIVE_WIDTH
/ 16;
307 IO_OSD_OSDWINMD0
|= (1<<13);
308 IO_OSD_OSDWINMD0
&= ~0x04;
310 } else if(mode
==LCD_MODE_PAL256
) {
311 #if LCD_NATIVE_WIDTH%32!=0
312 IO_OSD_OSDWIN0OFST
= LCD_NATIVE_WIDTH
/ 32+1;
314 IO_OSD_OSDWIN0OFST
= LCD_NATIVE_WIDTH
/ 32;
317 IO_OSD_VIDWINMD
&= ~(0x01);
318 IO_OSD_OSDWINMD0
&= ~(1<<13);
319 IO_OSD_OSDWINMD0
|= 0x01;
324 #if defined(LCD_USE_DMA)
325 static void dma_start_transfer16( char *src
, int src_x
, int src_y
, int stride
,
327 int width
, int height
, int pix_width
)
328 __attribute__ ((section(".icode")));
329 #if CONFIG_ORIENTATION == SCREEN_PORTRAIT
330 static void dma_start_transfer16( char *src
, int src_x
, int src_y
, int stride
,
332 int width
, int height
, int pix_width
) {
335 /* Addresses are relative to start of SDRAM */
336 src
= src
+ (src_y
*LCD_HEIGHT
+ src_x
) * pix_width
;
337 dst
= (char *)FRAME
+ (y
* LCD_HEIGHT
+ x
) * pix_width
;
339 /* Flush the area that is being copied from. */
340 clean_dcache_range(src
, (stride
*pix_width
*width
));
342 /* Addresses are relative to start of SDRAM */
343 src
-= CONFIG_SDRAM_START
;
344 dst
-= CONFIG_SDRAM_START
;
348 COP_CP_CLKC
|= 0x0001;
351 COP_BUF_MUX1
= 0x0005;
352 /* Give the DMA access to the buffer */
353 COP_BUF_MUX0
= 0x0663;
355 /* Setup buffer offsets and transfer width/height */
356 COP_BUF_LOFST
= width
;
357 COP_DMA_XNUM
= width
;
361 COP_IMG_MODE
= 0x0000;
363 /* Set the start address of buffer */
364 COP_BUF_ADDR
= 0x0000;
366 /* Setup SDRAM stride */
367 COP_SDEM_LOFST
= stride
;
371 addr
>>= 1; /* Addresses are in 16-bit words */
373 /* Setup the registers to initiate the read from SDRAM */
374 COP_SDEM_ADDRH
= addr
>> 16;
375 COP_SDEM_ADDRL
= addr
& 0xFFFF;
377 /* Set direction and start */
378 COP_DMA_CTRL
= 0x0001;
379 COP_DMA_CTRL
|= 0x0003;
381 /* Wait for read to finish */
382 while(COP_DMA_CTRL
& 0x02) {};
387 COP_SDEM_ADDRH
= addr
>> 16;
388 COP_SDEM_ADDRL
= addr
& 0xFFFF;
390 /* Set direction and start transfer */
391 COP_DMA_CTRL
= 0x0000;
392 COP_DMA_CTRL
= 0x0002;
394 /* Wait for the transfer to complete */
395 while(COP_DMA_CTRL
& 0x02) {};
397 /* Decrease height, update pointers/counters */
398 src
+= (stride
*pix_width
);
399 dst
+= (stride
*pix_width
);
404 static void dma_start_transfer16( char *src
, int src_x
, int src_y
, int stride
,
406 int width
, int height
, int pix_width
) {
409 /* Calculate starting place */
410 src
= src
+ (src_x
*LCD_HEIGHT
+ src_y
) * pix_width
;
411 dst
= (char *)FRAME
+ (LCD_HEIGHT
*(LCD_WIDTH
-1) - x
* LCD_HEIGHT
+ y
)
414 /* Flush the area that is being copied from. */
415 clean_dcache_range(src
, (stride
*pix_width
*width
));
417 /* Addresses are relative to start of SDRAM */
418 src
-= CONFIG_SDRAM_START
;
419 dst
-= CONFIG_SDRAM_START
;
423 COP_CP_CLKC
|= 0x0001;
426 COP_BUF_MUX1
= 0x0005;
427 /* Give the DMA access to the buffer */
428 COP_BUF_MUX0
= 0x0663;
430 /* Setup buffer offsets and transfer width/height */
431 COP_BUF_LOFST
= height
;
432 COP_DMA_XNUM
= height
;
436 COP_IMG_MODE
= 0x0000;
438 /* Set the start address of buffer */
439 COP_BUF_ADDR
= 0x0000;
441 /* Setup SDRAM stride */
442 COP_SDEM_LOFST
= stride
;
446 addr
>>= 1; /* Addresses are in 16-bit words */
448 /* Setup the registers to initiate the read from SDRAM */
449 COP_SDEM_ADDRH
= addr
>> 16;
450 COP_SDEM_ADDRL
= addr
& 0xFFFF;
452 /* Set direction and start */
453 COP_DMA_CTRL
= 0x0001;
454 COP_DMA_CTRL
|= 0x0003;
456 /* Wait for read to finish */
457 while(COP_DMA_CTRL
& 0x02) {};
462 COP_SDEM_ADDRH
= addr
>> 16;
463 COP_SDEM_ADDRL
= addr
& 0xFFFF;
465 /* Set direction and start transfer */
466 COP_DMA_CTRL
= 0x0000;
467 COP_DMA_CTRL
= 0x0002;
469 /* Wait for the transfer to complete */
470 while(COP_DMA_CTRL
& 0x02) {};
472 /* update the width, update pointers/counters */
473 src
+= (stride
*pix_width
);
474 dst
-= (stride
*pix_width
);
481 /* Update a fraction of the display. */
482 void lcd_update_rect(int x
, int y
, int width
, int height
)
483 __attribute__ ((section(".icode")));
484 void lcd_update_rect(int x
, int y
, int width
, int height
)
489 if ( (width
| height
) < 0)
490 return; /* nothing left to do */
492 if (x
+ width
> LCD_WIDTH
)
493 width
= LCD_WIDTH
- x
; /* Clip right */
495 width
+= x
, x
= 0; /* Clip left */
497 if (y
+ height
> LCD_HEIGHT
)
498 height
= LCD_HEIGHT
- y
; /* Clip bottom */
500 height
+= y
, y
= 0; /* Clip top */
502 #if CONFIG_ORIENTATION == SCREEN_PORTRAIT
504 #if defined(LCD_USE_DMA)
505 dma_start_transfer16( (char *)lcd_framebuffer
, x
, y
, LCD_WIDTH
,
506 x
, y
, width
, height
, 2);
508 register fb_data
*dst
;
510 dst
= (fb_data
*)FRAME
+ LCD_WIDTH
*y
+ x
;
512 /* Copy part of the Rockbox framebuffer to the second framebuffer */
513 if (width
< LCD_WIDTH
)
515 /* Not full width - do line-by-line */
516 lcd_copy_buffer_rect(dst
, &lcd_framebuffer
[y
][x
], width
, height
);
520 /* Full width - copy as one line */
521 lcd_copy_buffer_rect(dst
, &lcd_framebuffer
[y
][x
], LCD_WIDTH
*height
, 1);
527 #if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
529 #if defined(LCD_USE_DMA)
530 dma_start_transfer16( (char *)lcd_framebuffer
, x
, y
, LCD_HEIGHT
,
531 x
, y
, width
, height
, 2);
535 src
= &lcd_framebuffer
[0][0] + (x
*LCD_HEIGHT
+ y
);
536 dst
= FRAME
+ (LCD_HEIGHT
*(LCD_WIDTH
-1) - x
* LCD_HEIGHT
+ y
);
539 memcpy(src
, dst
, height
);
547 register fb_data
*dst
, *src
;
548 src
= &lcd_framebuffer
[y
][x
];
550 dst
=FRAME
+ (LCD_NATIVE_WIDTH
*(LCD_NATIVE_HEIGHT
-1))
551 - LCD_NATIVE_WIDTH
*x
+ y
;
555 register int c_width
=width
-1;
556 register fb_data
*c_dst
=dst
;
560 c_dst
-=LCD_NATIVE_WIDTH
;
563 src
+=LCD_WIDTH
-width
;
571 /* Update the display.
572 This must be called after all other LCD functions that change the display. */
573 void lcd_update(void) __attribute__ ((section(".icode")));
574 void lcd_update(void)
579 lcd_update_rect(0, 0, LCD_WIDTH
, LCD_HEIGHT
);
582 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
583 void lcd_blit_pal256(unsigned char *src
, int src_x
, int src_y
, int x
, int y
,
584 int width
, int height
) __attribute__ ((section(".icode")));
585 void lcd_blit_pal256(unsigned char *src
, int src_x
, int src_y
, int x
, int y
,
586 int width
, int height
)
588 #if CONFIG_ORIENTATION == SCREEN_PORTRAIT
589 #if defined(LCD_USE_DMA)
590 // char *dst=(char *)FRAME+x+y*(LCD_NATIVE_WIDTH+LCD_FUDGE);
592 dma_start_transfer16( src
, src_x
, src_y
, LCD_WIDTH
,
593 x
, y
, width
, height
, 1);
595 char *dst
=(char *)FRAME
+x
+y
*(LCD_NATIVE_WIDTH
+LCD_FUDGE
);
597 src
= src
+src_x
+src_y
*LCD_WIDTH
;
600 memcpy(dst
, src
, width
);
602 dst
= dst
+ ((LCD_WIDTH
-x
+LCD_FUDGE
));
603 src
= src
+ (LCD_WIDTH
- x
);
607 char *dst
=(char *)FRAME
608 + (LCD_NATIVE_WIDTH
+LCD_FUDGE
)*(LCD_NATIVE_HEIGHT
-1)
609 - (LCD_NATIVE_WIDTH
+LCD_FUDGE
)*x
+ y
;
611 src
=src
+src_x
+src_y
*width
;
615 register char *c_src
=src
;
616 register char *c_dst
=dst
;
617 register int c_width
=width
;
622 c_dst
-= (LCD_NATIVE_WIDTH
+LCD_FUDGE
);
631 void lcd_pal256_update_pal(fb_data
*palette
)
634 for(i
=0; i
< 255; i
++)
637 unsigned char r
=RGB_UNPACK_RED_LCD(palette
[i
])<<3;
638 unsigned char g
=RGB_UNPACK_GREEN_LCD(palette
[i
])<<2;
639 unsigned char b
=RGB_UNPACK_BLUE_LCD(palette
[i
])<<3;
641 y
= ((77 * r
+ 150 * g
+ 29 * b
) >> 8);
cb
= ((-43 * r
- 85 * g
+ 128 * b
) >> 8) + 128;
642 cr
= ((128 * r
- 107 * g
- 21 * b
) >> 8) + 128;
644 while(IO_OSD_MISCCTL
&0x08)
647 /* Write in y and cb */
648 IO_OSD_CLUTRAMYCB
= ((unsigned char)y
<< 8) | (unsigned char)cb
;
650 /* Write in the index and cr */
651 IO_OSD_CLUTRAMCR
=((unsigned char)cr
<< 8) | i
;
656 /* Performance function to blit a YUV bitmap directly to the LCD */
657 /* Show it rotated so the LCD_WIDTH is now the height */
658 void lcd_blit_yuv(unsigned char * const src
[3],
659 int src_x
, int src_y
, int stride
,
660 int x
, int y
, int width
, int height
)
662 unsigned char const * yuv_src
[3];
667 /* y has to be on a 16 pixel boundary */
670 if( ((y
| x
| height
| width
) < 0)
671 || y
>LCD_NATIVE_HEIGHT
|| x
>LCD_NATIVE_WIDTH
)
674 if(y
+height
>LCD_NATIVE_WIDTH
)
676 height
=LCD_NATIVE_WIDTH
-y
;
678 if(x
+width
>LCD_NATIVE_HEIGHT
)
680 width
=LCD_NATIVE_HEIGHT
-x
;
683 /* Sorry, but width and height must be >= 2 or else */
687 fb_data
* dst
= FRAME2
688 + ((LCD_NATIVE_WIDTH
+LCD_FUDGE
)*(LCD_NATIVE_HEIGHT
-1))
689 - (LCD_NATIVE_WIDTH
+LCD_FUDGE
)*x
+ y
;
695 yuv_src
[0] = src
[0] + z
+ src_x
;
696 yuv_src
[1] = src
[1] + (z
>> 2) + (src_x
>> 1);
697 yuv_src
[2] = src
[2] + (yuv_src
[1] - src
[1]);
700 int cbcr_remain
=(stride
>>1)-(width
>>1);
701 int y_remain
=(stride
<<1)-width
;
704 register int c_width
=width
;
705 register unsigned int *c_dst
=(unsigned int*)dst
;
708 register unsigned short Y
=*((unsigned short*)yuv_src
[0]);
709 register unsigned short Yst
=*((unsigned short*)(yuv_src
[0]+stride
));
712 register unsigned char Cb
=*yuv_src
[1]++;
713 register unsigned char Cr
=*yuv_src
[2]++;
715 *c_dst
= (Yst
<<24) | (Cr
<< 16) | ((Y
&0xFF)<<8) | Cb
;
716 *(c_dst
- (LCD_NATIVE_WIDTH
+LCD_FUDGE
)/2) =
717 ( (Yst
&0xFF00)<<16) | (Cr
<< 16) | (Y
&0xFF00) | Cb
;
719 c_dst
-= (LCD_NATIVE_WIDTH
+LCD_FUDGE
);
725 yuv_src
[0] += y_remain
; /* Skip down two luma lines-width */
726 yuv_src
[1] += cbcr_remain
; /* Skip down one chroma line-width/2 */
727 yuv_src
[2] += cbcr_remain
;
731 while (--height
> 0);
734 void lcd_set_contrast(int val
) {
739 void lcd_set_invert_display(bool yesno
) {
744 void lcd_set_flip(bool yesno
) {