diff options
author | Rafaël Carré <rafael.carre@gmail.com> | 2009-05-12 13:22:39 +0000 |
---|---|---|
committer | Rafaël Carré <rafael.carre@gmail.com> | 2009-05-12 13:22:39 +0000 |
commit | b1d03ccee7066d7e8e218b7cafcd85b17f5549d8 (patch) | |
tree | dc0039d583343471b3e3315fd04625fe9212e567 /firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c | |
parent | f2c18d6922257c6610f4c01ed09ce318295bee68 (diff) | |
download | rockbox-b1d03ccee7066d7e8e218b7cafcd85b17f5549d8.tar.gz rockbox-b1d03ccee7066d7e8e218b7cafcd85b17f5549d8.zip |
FS#10118 & FS#10165 : lcd_blit_yuv() for Sansa Fuze & Sansa e200v2
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20919 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c')
-rw-r--r-- | firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c | 99 |
1 files changed, 84 insertions, 15 deletions
diff --git a/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c b/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c index 30ba8911ea..ef21893494 100644 --- a/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c +++ b/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c | |||
@@ -74,7 +74,7 @@ static volatile bool lcd_busy = false; | |||
74 | #define R_GAMMA_GRAD_ADJ_NEG 0x37 | 74 | #define R_GAMMA_GRAD_ADJ_NEG 0x37 |
75 | 75 | ||
76 | #define R_GAMMA_AMP_ADJ_RES_POS 0x38 | 76 | #define R_GAMMA_AMP_ADJ_RES_POS 0x38 |
77 | #define R_GAMMA_AMP_AVG_ADJ_RES_NEG 0x39 | 77 | #define R_GAMMA_AMP_AVG_ADJ_RES_NEG 0x39 |
78 | 78 | ||
79 | #define R_GATE_SCAN_POS 0x40 | 79 | #define R_GATE_SCAN_POS 0x40 |
80 | #define R_VERT_SCROLL_CONTROL 0x41 | 80 | #define R_VERT_SCROLL_CONTROL 0x41 |
@@ -89,6 +89,7 @@ static volatile bool lcd_busy = false; | |||
89 | static unsigned short r_entry_mode = R_ENTRY_MODE_HORZ_NORMAL; | 89 | static unsigned short r_entry_mode = R_ENTRY_MODE_HORZ_NORMAL; |
90 | #define R_ENTRY_MODE_VERT 0x7038 | 90 | #define R_ENTRY_MODE_VERT 0x7038 |
91 | #define R_ENTRY_MODE_SOLID_VERT 0x1038 | 91 | #define R_ENTRY_MODE_SOLID_VERT 0x1038 |
92 | #define R_ENTRY_MODE_VIDEO 0x7020 | ||
92 | 93 | ||
93 | 94 | ||
94 | /* Reverse Flag */ | 95 | /* Reverse Flag */ |
@@ -182,7 +183,7 @@ void lcd_set_invert_display(bool yesno) | |||
182 | void lcd_set_flip(bool yesno) | 183 | void lcd_set_flip(bool yesno) |
183 | { | 184 | { |
184 | display_flipped = yesno; | 185 | display_flipped = yesno; |
185 | 186 | ||
186 | r_entry_mode = yesno ? R_ENTRY_MODE_HORZ_FLIPPED : | 187 | r_entry_mode = yesno ? R_ENTRY_MODE_HORZ_FLIPPED : |
187 | R_ENTRY_MODE_HORZ_NORMAL; | 188 | R_ENTRY_MODE_HORZ_NORMAL; |
188 | } | 189 | } |
@@ -253,13 +254,13 @@ static void _display_on(void) | |||
253 | /* DC12-10 = 000b: Step-up1 = clock/8, | 254 | /* DC12-10 = 000b: Step-up1 = clock/8, |
254 | * DC02-00 = 000b: Step-up2 = clock/16, | 255 | * DC02-00 = 000b: Step-up2 = clock/16, |
255 | * VC2-0 = 010b: VciOUT = 0.87 * VciLVL */ | 256 | * VC2-0 = 010b: VciOUT = 0.87 * VciLVL */ |
256 | lcd_write_reg(R_POWER_CONTROL2, 0x0002); | 257 | lcd_write_reg(R_POWER_CONTROL2, 0x0002); |
257 | 258 | ||
258 | /* VRH3-0 = 1000b: Vreg1OUT = REGP * 1.90 */ | 259 | /* VRH3-0 = 1000b: Vreg1OUT = REGP * 1.90 */ |
259 | lcd_write_reg(R_POWER_CONTROL3, 0x0008); | 260 | lcd_write_reg(R_POWER_CONTROL3, 0x0008); |
260 | 261 | ||
261 | lcd_delay(40); | 262 | lcd_delay(40); |
262 | 263 | ||
263 | lcd_write_reg(R_POWER_CONTROL4, 0x0000); /* VCOMG = 0 */ | 264 | lcd_write_reg(R_POWER_CONTROL4, 0x0000); /* VCOMG = 0 */ |
264 | 265 | ||
265 | /* This register is unknown */ | 266 | /* This register is unknown */ |
@@ -270,8 +271,8 @@ static void _display_on(void) | |||
270 | 271 | ||
271 | lcd_delay(10); | 272 | lcd_delay(10); |
272 | 273 | ||
273 | lcd_write_reg(R_POWER_CONTROL2, 0x0000); | 274 | lcd_write_reg(R_POWER_CONTROL2, 0x0000); |
274 | lcd_write_reg(R_POWER_CONTROL3, 0x0013); | 275 | lcd_write_reg(R_POWER_CONTROL3, 0x0013); |
275 | 276 | ||
276 | lcd_delay(20); | 277 | lcd_delay(20); |
277 | 278 | ||
@@ -296,7 +297,7 @@ static void _display_on(void) | |||
296 | lcd_write_reg(R_GATE_SCAN_POS, 0); | 297 | lcd_write_reg(R_GATE_SCAN_POS, 0); |
297 | lcd_write_reg(R_VERT_SCROLL_CONTROL, 0); | 298 | lcd_write_reg(R_VERT_SCROLL_CONTROL, 0); |
298 | 299 | ||
299 | lcd_window(0, 0, LCD_WIDTH-1, LCD_HEIGHT-1); | 300 | lcd_window(0, 0, LCD_WIDTH-1, LCD_HEIGHT-1); |
300 | lcd_write_reg(R_1ST_SCR_DRV_POS, (LCD_HEIGHT-1) << 8); | 301 | lcd_write_reg(R_1ST_SCR_DRV_POS, (LCD_HEIGHT-1) << 8); |
301 | lcd_write_reg(R_2ND_SCR_DRV_POS, (LCD_HEIGHT-1) << 8); | 302 | lcd_write_reg(R_2ND_SCR_DRV_POS, (LCD_HEIGHT-1) << 8); |
302 | 303 | ||
@@ -356,6 +357,30 @@ bool lcd_active(void) | |||
356 | 357 | ||
357 | /*** update functions ***/ | 358 | /*** update functions ***/ |
358 | 359 | ||
360 | static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0; | ||
361 | |||
362 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | ||
363 | extern void lcd_write_yuv420_lines(unsigned char const * const src[3], | ||
364 | int width, | ||
365 | int stride); | ||
366 | extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3], | ||
367 | int width, | ||
368 | int stride, | ||
369 | int x_screen, /* To align dither pattern */ | ||
370 | int y_screen); | ||
371 | |||
372 | void lcd_yuv_set_options(unsigned options) | ||
373 | { | ||
374 | lcd_yuv_options = options; | ||
375 | } | ||
376 | |||
377 | static void lcd_window_blit(int xmin, int ymin, int xmax, int ymax) | ||
378 | { | ||
379 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, ((LCD_WIDTH-1 - xmin) << 8) | (LCD_WIDTH-1 - xmax)); | ||
380 | lcd_write_reg(R_VERT_RAM_ADDR_POS, (ymax << 8) | ymin); | ||
381 | lcd_write_reg(R_RAM_ADDR_SET, (ymin << 8) | (LCD_WIDTH-1 - xmin)); | ||
382 | } | ||
383 | |||
359 | /* Performance function to blit a YUV bitmap directly to the LCD | 384 | /* Performance function to blit a YUV bitmap directly to the LCD |
360 | * src_x, src_y, width and height should be even | 385 | * src_x, src_y, width and height should be even |
361 | * x, y, width and height have to be within LCD bounds | 386 | * x, y, width and height have to be within LCD bounds |
@@ -364,14 +389,58 @@ void lcd_blit_yuv(unsigned char * const src[3], | |||
364 | int src_x, int src_y, int stride, | 389 | int src_x, int src_y, int stride, |
365 | int x, int y, int width, int height) | 390 | int x, int y, int width, int height) |
366 | { | 391 | { |
367 | (void)src; | 392 | unsigned char const * yuv_src[3]; |
368 | (void)src_x; | 393 | off_t z; |
369 | (void)src_y; | 394 | |
370 | (void)stride; | 395 | lcd_busy = true; |
371 | (void)x; | 396 | |
372 | (void)y; | 397 | /* Sorry, but width and height must be >= 2 or else */ |
373 | (void)width; | 398 | width &= ~1; |
374 | (void)height; | 399 | height >>= 1; |
400 | |||
401 | z = stride*src_y; | ||
402 | yuv_src[0] = src[0] + z + src_x; | ||
403 | yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); | ||
404 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | ||
405 | |||
406 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VIDEO); | ||
407 | |||
408 | if (lcd_yuv_options & LCD_YUV_DITHER) | ||
409 | { | ||
410 | do | ||
411 | { | ||
412 | lcd_window_blit(y, x, y+1, x+width-1); | ||
413 | |||
414 | /* Start write to GRAM */ | ||
415 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); | ||
416 | |||
417 | lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y); | ||
418 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
419 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
420 | yuv_src[2] += stride >> 1; | ||
421 | y+=2; | ||
422 | } | ||
423 | while (--height > 0); | ||
424 | } | ||
425 | else | ||
426 | { | ||
427 | do | ||
428 | { | ||
429 | lcd_window_blit(y, x, y+1, x+width-1); | ||
430 | |||
431 | /* Start write to GRAM */ | ||
432 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); | ||
433 | |||
434 | lcd_write_yuv420_lines(yuv_src, width, stride); | ||
435 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
436 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
437 | yuv_src[2] += stride >> 1; | ||
438 | y+=2; | ||
439 | } | ||
440 | while (--height > 0); | ||
441 | } | ||
442 | |||
443 | lcd_busy = false; | ||
375 | } | 444 | } |
376 | 445 | ||
377 | /* Update the display. | 446 | /* Update the display. |