diff options
Diffstat (limited to 'firmware/target/coldfire/iaudio/x5/lcd-x5.c')
-rw-r--r-- | firmware/target/coldfire/iaudio/x5/lcd-x5.c | 77 |
1 files changed, 33 insertions, 44 deletions
diff --git a/firmware/target/coldfire/iaudio/x5/lcd-x5.c b/firmware/target/coldfire/iaudio/x5/lcd-x5.c index 2cc5b5ba65..5ca2cb508c 100644 --- a/firmware/target/coldfire/iaudio/x5/lcd-x5.c +++ b/firmware/target/coldfire/iaudio/x5/lcd-x5.c | |||
@@ -50,11 +50,6 @@ static unsigned short r_gate_scan_start_pos = 0x0002; | |||
50 | static unsigned short r_drv_output_control = 0x0313; | 50 | static unsigned short r_drv_output_control = 0x0313; |
51 | static unsigned short r_horiz_ram_addr_pos = 0x7f00; | 51 | static unsigned short r_horiz_ram_addr_pos = 0x7f00; |
52 | 52 | ||
53 | /* Dithering */ | ||
54 | #define R_ENTRY_MODE_SOLID 0x1038 | ||
55 | #define R_ENTRY_MODE_DIT 0x9038 | ||
56 | static unsigned short r_entry_mode = R_ENTRY_MODE_SOLID; | ||
57 | |||
58 | /* Forward declarations */ | 53 | /* Forward declarations */ |
59 | static void lcd_display_off(void); | 54 | static void lcd_display_off(void); |
60 | 55 | ||
@@ -97,6 +92,9 @@ static void lcd_display_off(void); | |||
97 | #define R_GAMMA_AMP_ADJ_POS 0x3a | 92 | #define R_GAMMA_AMP_ADJ_POS 0x3a |
98 | #define R_GAMMA_AMP_ADJ_NEG 0x3b | 93 | #define R_GAMMA_AMP_ADJ_NEG 0x3b |
99 | 94 | ||
95 | #define R_ENTRY_MODE_SOLID_VERT 0x1038 | ||
96 | #define R_ENTRY_MODE_DIT_HORZ 0x9030 | ||
97 | |||
100 | /* called very frequently - inline! */ | 98 | /* called very frequently - inline! */ |
101 | static inline void lcd_write_reg(int reg, int val) | 99 | static inline void lcd_write_reg(int reg, int val) |
102 | { | 100 | { |
@@ -113,14 +111,6 @@ static inline void lcd_begin_write_gram(void) | |||
113 | LCD_CMD = R_WRITE_DATA_2_GRAM << 1; | 111 | LCD_CMD = R_WRITE_DATA_2_GRAM << 1; |
114 | } | 112 | } |
115 | 113 | ||
116 | /* set hard dither mode on/off */ | ||
117 | static void hw_dither(bool on) | ||
118 | { | ||
119 | /* DIT=x, BGR=1, HWM=0, I/D1-0=11, AM=1, LG2-0=000 */ | ||
120 | r_entry_mode = on ? R_ENTRY_MODE_DIT : R_ENTRY_MODE_SOLID; | ||
121 | lcd_write_reg(R_ENTRY_MODE, r_entry_mode); | ||
122 | } | ||
123 | |||
124 | /*** hardware configuration ***/ | 114 | /*** hardware configuration ***/ |
125 | 115 | ||
126 | int lcd_default_contrast(void) | 116 | int lcd_default_contrast(void) |
@@ -233,7 +223,7 @@ static void lcd_power_on(void) | |||
233 | /* FLD1-0=01 (1 field), B/C=1, EOR=1 (C-pat), NW5-0=000000 (1 row) */ | 223 | /* FLD1-0=01 (1 field), B/C=1, EOR=1 (C-pat), NW5-0=000000 (1 row) */ |
234 | lcd_write_reg(R_DRV_AC_CONTROL, 0x0700); | 224 | lcd_write_reg(R_DRV_AC_CONTROL, 0x0700); |
235 | /* DIT=x, BGR=1, HWM=0, I/D1-0=11, AM=1, LG2-0=000 */ | 225 | /* DIT=x, BGR=1, HWM=0, I/D1-0=11, AM=1, LG2-0=000 */ |
236 | lcd_write_reg(R_ENTRY_MODE, r_entry_mode); | 226 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_SOLID_VERT); |
237 | /* CP15-0=0000000000000000 */ | 227 | /* CP15-0=0000000000000000 */ |
238 | lcd_write_reg(R_COMPARE_REG, 0x0000); | 228 | lcd_write_reg(R_COMPARE_REG, 0x0000); |
239 | /* NO1-0=01, SDT1-0=00, EQ1-0=00, DIV1-0=00, RTN3-00000 */ | 229 | /* NO1-0=01, SDT1-0=00, EQ1-0=00, DIV1-0=00, RTN3-00000 */ |
@@ -377,7 +367,8 @@ void lcd_init_device(void) | |||
377 | lcd_set_contrast(DEFAULT_CONTRAST_SETTING); | 367 | lcd_set_contrast(DEFAULT_CONTRAST_SETTING); |
378 | lcd_set_invert_display(false); | 368 | lcd_set_invert_display(false); |
379 | lcd_set_flip(false); | 369 | lcd_set_flip(false); |
380 | hw_dither(false); /* do this or all bootloaders will need reflashing */ | 370 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_SOLID_VERT); |
371 | /* do this or all bootloaders will need reflashing */ | ||
381 | #endif | 372 | #endif |
382 | } | 373 | } |
383 | 374 | ||
@@ -432,13 +423,12 @@ void lcd_blit(const fb_data* data, int x, int by, int width, | |||
432 | } | 423 | } |
433 | 424 | ||
434 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. | 425 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. |
435 | * y should have two lines of Y back to back. | 426 | * y should have two lines of Y back to back, 2nd line first. |
436 | * bu and rv should contain the Cb and Cr data for the two lines of Y. | 427 | * c should contain the Cb and Cr data for the two lines of Y back to back. |
437 | * Needs EMAC set to saturated, signed integer mode. | 428 | * Needs EMAC set to saturated, signed integer mode. |
438 | */ | 429 | */ |
439 | extern void lcd_write_yuv420_lines(const unsigned char *y, | 430 | extern void lcd_write_yuv420_lines(const unsigned char *y, |
440 | const unsigned char *bu, | 431 | const unsigned char *c, int width); |
441 | const unsigned char *rv, int width); | ||
442 | 432 | ||
443 | /* Performance function to blit a YUV bitmap directly to the LCD | 433 | /* Performance function to blit a YUV bitmap directly to the LCD |
444 | * src_x, src_y, width and height should be even and within the LCD's | 434 | * src_x, src_y, width and height should be even and within the LCD's |
@@ -450,25 +440,19 @@ void lcd_yuv_blit(unsigned char * const src[3], | |||
450 | { | 440 | { |
451 | /* IRAM Y, Cb/bu, guv and Cb/rv buffers. */ | 441 | /* IRAM Y, Cb/bu, guv and Cb/rv buffers. */ |
452 | unsigned char y_ibuf[LCD_WIDTH*2]; | 442 | unsigned char y_ibuf[LCD_WIDTH*2]; |
453 | unsigned char bu_ibuf[LCD_WIDTH/2]; | 443 | unsigned char c_ibuf[LCD_WIDTH]; |
454 | unsigned char rv_ibuf[LCD_WIDTH/2]; | ||
455 | const unsigned char *ysrc, *usrc, *vsrc; | 444 | const unsigned char *ysrc, *usrc, *vsrc; |
456 | const unsigned char *ysrc_max; | 445 | const unsigned char *ysrc_max; |
457 | 446 | ||
458 | if (!display_on) | 447 | if (!display_on) |
459 | return; | 448 | return; |
460 | 449 | ||
461 | if (r_entry_mode == R_ENTRY_MODE_SOLID) | ||
462 | hw_dither(true); | ||
463 | |||
464 | width &= ~1; /* stay on the safe side */ | 450 | width &= ~1; /* stay on the safe side */ |
465 | height &= ~1; | 451 | height &= ~1; |
466 | 452 | ||
453 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_DIT_HORZ); | ||
467 | /* Set start position and window */ | 454 | /* Set start position and window */ |
468 | lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | (y + y_offset)); | 455 | lcd_write_reg(R_VERT_RAM_ADDR_POS, (LCD_WIDTH-1) << 8); |
469 | lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x); | ||
470 | |||
471 | lcd_begin_write_gram(); | ||
472 | 456 | ||
473 | ysrc = src[0] + src_y * stride + src_x; | 457 | ysrc = src[0] + src_y * stride + src_x; |
474 | usrc = src[1] + (src_y * stride >> 2) + (src_x >> 1); | 458 | usrc = src[1] + (src_y * stride >> 2) + (src_x >> 1); |
@@ -478,11 +462,17 @@ void lcd_yuv_blit(unsigned char * const src[3], | |||
478 | coldfire_set_macsr(EMAC_SATURATE); | 462 | coldfire_set_macsr(EMAC_SATURATE); |
479 | do | 463 | do |
480 | { | 464 | { |
481 | memcpy(y_ibuf, ysrc, width); | 465 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, ((y + y_offset + 1) << 8) | (y + y_offset)); |
482 | memcpy(y_ibuf + width, ysrc + stride, width); | 466 | lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | (y + y_offset)); |
483 | memcpy(bu_ibuf, usrc, width >> 1); | 467 | lcd_begin_write_gram(); |
484 | memcpy(rv_ibuf, vsrc, width >> 1); | 468 | |
485 | lcd_write_yuv420_lines(y_ibuf, bu_ibuf, rv_ibuf, width); | 469 | memcpy(y_ibuf + width, ysrc, width); |
470 | memcpy(y_ibuf, ysrc + stride, width); | ||
471 | memcpy(c_ibuf, usrc, width >> 1); | ||
472 | memcpy(c_ibuf + (width >> 1), vsrc, width >> 1); | ||
473 | lcd_write_yuv420_lines(y_ibuf, c_ibuf, width >> 1); | ||
474 | |||
475 | y += 2; | ||
486 | ysrc += 2 * stride; | 476 | ysrc += 2 * stride; |
487 | usrc += stride >> 1; | 477 | usrc += stride >> 1; |
488 | vsrc += stride >> 1; | 478 | vsrc += stride >> 1; |
@@ -499,17 +489,16 @@ void lcd_update(void) | |||
499 | if (!display_on) | 489 | if (!display_on) |
500 | return; | 490 | return; |
501 | 491 | ||
502 | if (r_entry_mode == R_ENTRY_MODE_DIT) | 492 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_SOLID_VERT); |
503 | hw_dither(false); | ||
504 | |||
505 | /* Set start position and window */ | 493 | /* Set start position and window */ |
506 | lcd_write_reg(R_RAM_ADDR_SET, y_offset); /* X == 0 */ | 494 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, |
495 | ((y_offset + LCD_HEIGHT-1) << 8) | y_offset); | ||
507 | lcd_write_reg(R_VERT_RAM_ADDR_POS, (LCD_WIDTH-1) << 8); | 496 | lcd_write_reg(R_VERT_RAM_ADDR_POS, (LCD_WIDTH-1) << 8); |
497 | lcd_write_reg(R_RAM_ADDR_SET, y_offset); | ||
508 | 498 | ||
509 | lcd_begin_write_gram(); | 499 | lcd_begin_write_gram(); |
510 | 500 | ||
511 | lcd_write_data((unsigned short *)lcd_framebuffer, | 501 | lcd_write_data((unsigned short *)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); |
512 | LCD_WIDTH*LCD_HEIGHT); | ||
513 | } /* lcd_update */ | 502 | } /* lcd_update */ |
514 | 503 | ||
515 | /* Update a fraction of the display. */ | 504 | /* Update a fraction of the display. */ |
@@ -521,9 +510,6 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
521 | if (!display_on) | 510 | if (!display_on) |
522 | return; | 511 | return; |
523 | 512 | ||
524 | if (r_entry_mode == R_ENTRY_MODE_DIT) | ||
525 | hw_dither(false); | ||
526 | |||
527 | if (x + width > LCD_WIDTH) | 513 | if (x + width > LCD_WIDTH) |
528 | width = LCD_WIDTH - x; /* Clip right */ | 514 | width = LCD_WIDTH - x; /* Clip right */ |
529 | if (x < 0) | 515 | if (x < 0) |
@@ -539,9 +525,12 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
539 | if (y >= ymax) | 525 | if (y >= ymax) |
540 | return; /* nothing left to do */ | 526 | return; /* nothing left to do */ |
541 | 527 | ||
528 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_SOLID_VERT); | ||
542 | /* Set start position and window */ | 529 | /* Set start position and window */ |
543 | lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | (y + y_offset)); | 530 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, |
531 | ((y_offset + LCD_HEIGHT-1) << 8) | y_offset); | ||
544 | lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x); | 532 | lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x); |
533 | lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | (y + y_offset)); | ||
545 | 534 | ||
546 | lcd_begin_write_gram(); | 535 | lcd_begin_write_gram(); |
547 | 536 | ||