summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/iaudio/x5/lcd-x5.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/coldfire/iaudio/x5/lcd-x5.c')
-rw-r--r--firmware/target/coldfire/iaudio/x5/lcd-x5.c77
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;
50static unsigned short r_drv_output_control = 0x0313; 50static unsigned short r_drv_output_control = 0x0313;
51static unsigned short r_horiz_ram_addr_pos = 0x7f00; 51static 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
56static unsigned short r_entry_mode = R_ENTRY_MODE_SOLID;
57
58/* Forward declarations */ 53/* Forward declarations */
59static void lcd_display_off(void); 54static 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! */
101static inline void lcd_write_reg(int reg, int val) 99static 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 */
117static 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
126int lcd_default_contrast(void) 116int 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 */
439extern void lcd_write_yuv420_lines(const unsigned char *y, 430extern 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