diff options
Diffstat (limited to 'firmware/target/arm/samsung/yh925/lcd-yh925.c')
-rw-r--r-- | firmware/target/arm/samsung/yh925/lcd-yh925.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/firmware/target/arm/samsung/yh925/lcd-yh925.c b/firmware/target/arm/samsung/yh925/lcd-yh925.c index e2b3ae3694..93bfb3a5f2 100644 --- a/firmware/target/arm/samsung/yh925/lcd-yh925.c +++ b/firmware/target/arm/samsung/yh925/lcd-yh925.c | |||
@@ -37,6 +37,8 @@ static unsigned short disp_control_rev; | |||
37 | /* Contrast setting << 8 */ | 37 | /* Contrast setting << 8 */ |
38 | static int lcd_contrast; | 38 | static int lcd_contrast; |
39 | 39 | ||
40 | static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0; | ||
41 | |||
40 | /* Forward declarations */ | 42 | /* Forward declarations */ |
41 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) | 43 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) |
42 | static void lcd_display_off(void); | 44 | static void lcd_display_off(void); |
@@ -508,6 +510,98 @@ bool lcd_active(void) | |||
508 | 510 | ||
509 | /*** update functions ***/ | 511 | /*** update functions ***/ |
510 | 512 | ||
513 | void lcd_yuv_set_options(unsigned options) | ||
514 | { | ||
515 | lcd_yuv_options = options; | ||
516 | } | ||
517 | |||
518 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | ||
519 | extern void lcd_write_yuv420_lines(unsigned char const * const src[3], | ||
520 | int width, | ||
521 | int stride); | ||
522 | extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3], | ||
523 | int width, | ||
524 | int stride, | ||
525 | int x_screen, /* To align dither pattern */ | ||
526 | int y_screen); | ||
527 | |||
528 | /* Performance function to blit a YUV bitmap directly to the LCD */ | ||
529 | void lcd_blit_yuv(unsigned char * const src[3], | ||
530 | int src_x, int src_y, int stride, | ||
531 | int x, int y, int width, int height) | ||
532 | { | ||
533 | const unsigned char *yuv_src[3]; | ||
534 | const unsigned char *ysrc_max; | ||
535 | int y0; | ||
536 | int options; | ||
537 | |||
538 | /* NOT MODIFIED FOR THE YH-925 */ | ||
539 | |||
540 | if (!display_on) | ||
541 | return; | ||
542 | |||
543 | width &= ~1; | ||
544 | height &= ~1; | ||
545 | |||
546 | x += x_offset; | ||
547 | |||
548 | /* calculate the drawing region */ | ||
549 | |||
550 | /* The 20GB LCD is actually 128x160 but rotated 90 degrees so the origin | ||
551 | * is actually the bottom left and horizontal and vertical are swapped. | ||
552 | * Rockbox expects the origin to be the top left so we need to use | ||
553 | * 127 - y instead of just y */ | ||
554 | |||
555 | /* max vert << 8 | start vert */ | ||
556 | lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x); | ||
557 | |||
558 | y0 = LCD_HEIGHT - 1 - y + y_offset; | ||
559 | |||
560 | /* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=0, LG2-0=000 */ | ||
561 | lcd_write_reg(R_ENTRY_MODE, 0x1020); | ||
562 | |||
563 | yuv_src[0] = src[0] + src_y * stride + src_x; | ||
564 | yuv_src[1] = src[1] + (src_y * stride >> 2) + (src_x >> 1); | ||
565 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | ||
566 | ysrc_max = yuv_src[0] + height * stride; | ||
567 | |||
568 | options = lcd_yuv_options; | ||
569 | |||
570 | do | ||
571 | { | ||
572 | /* max horiz << 8 | start horiz */ | ||
573 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (y0 << 8) | (y0 - 1)); | ||
574 | |||
575 | /* position cursor (set AD0-AD15) */ | ||
576 | /* start vert << 8 | start horiz */ | ||
577 | lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | y0); | ||
578 | |||
579 | /* start drawing */ | ||
580 | lcd_send_cmd(R_WRITE_DATA_2_GRAM); | ||
581 | |||
582 | if (options & LCD_YUV_DITHER) | ||
583 | { | ||
584 | lcd_write_yuv420_lines_odither(yuv_src, width, stride, | ||
585 | x, y); | ||
586 | y -= 2; | ||
587 | } | ||
588 | else | ||
589 | { | ||
590 | lcd_write_yuv420_lines(yuv_src, width, stride); | ||
591 | } | ||
592 | |||
593 | y0 -= 2; | ||
594 | yuv_src[0] += stride << 1; | ||
595 | yuv_src[1] += stride >> 1; | ||
596 | yuv_src[2] += stride >> 1; | ||
597 | } | ||
598 | while (yuv_src[0] < ysrc_max); | ||
599 | |||
600 | /* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=1, LG2-0=000 */ | ||
601 | lcd_write_reg(R_ENTRY_MODE, 0x1028); | ||
602 | } | ||
603 | |||
604 | |||
511 | /* Update a fraction of the display. */ | 605 | /* Update a fraction of the display. */ |
512 | void lcd_update_rect(int x0, int y0, int width, int height) | 606 | void lcd_update_rect(int x0, int y0, int width, int height) |
513 | { | 607 | { |