diff options
Diffstat (limited to 'firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c')
-rw-r--r-- | firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c | 216 |
1 files changed, 11 insertions, 205 deletions
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c b/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c index 3fd63de623..79a4151682 100644 --- a/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c +++ b/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #ifdef HAVE_LCD_ENABLE | 38 | #ifdef HAVE_LCD_ENABLE |
39 | static bool lcd_on; | 39 | static bool lcd_on; |
40 | #endif | 40 | #endif |
41 | static unsigned lcd_yuv_options = 0; | ||
42 | static int lcd_dcp_channel = -1; | 41 | static int lcd_dcp_channel = -1; |
43 | #ifdef HAVE_LCD_INVERT | 42 | #ifdef HAVE_LCD_INVERT |
44 | static int lcd_reg_0x61_val = 1; /* used to invert display */ | 43 | static int lcd_reg_0x61_val = 1; /* used to invert display */ |
@@ -55,9 +54,9 @@ static enum lcd_kind_t | |||
55 | 54 | ||
56 | static void setup_parameters(void) | 55 | static void setup_parameters(void) |
57 | { | 56 | { |
58 | imx233_lcdif_reset(); | 57 | imx233_lcdif_init(); |
59 | imx233_lcdif_set_lcd_databus_width(BV_LCDIF_CTRL_LCD_DATABUS_WIDTH__18_BIT); | 58 | imx233_lcdif_set_lcd_databus_width(18); |
60 | imx233_lcdif_set_word_length(BV_LCDIF_CTRL_WORD_LENGTH__18_BIT); | 59 | imx233_lcdif_set_word_length(18); |
61 | imx233_lcdif_set_timings(1, 2, 2, 2); | 60 | imx233_lcdif_set_timings(1, 2, 2, 2); |
62 | imx233_lcdif_enable_underflow_recover(true); | 61 | imx233_lcdif_enable_underflow_recover(true); |
63 | } | 62 | } |
@@ -126,7 +125,7 @@ static void setup_lcd_pins_i80(bool i80) | |||
126 | else | 125 | else |
127 | { | 126 | { |
128 | HW_PINCTRL_DOUTn_SET(1) = (1 << 19) | (1 << 20) | (1 << 21) | (1 << 23); | 127 | HW_PINCTRL_DOUTn_SET(1) = (1 << 19) | (1 << 20) | (1 << 21) | (1 << 23); |
129 | 128 | ||
130 | imx233_pinctrl_set_drive(1, 19, PINCTRL_DRIVE_4mA); /* lcd_rs */ | 129 | imx233_pinctrl_set_drive(1, 19, PINCTRL_DRIVE_4mA); /* lcd_rs */ |
131 | imx233_pinctrl_set_drive(1, 20, PINCTRL_DRIVE_4mA); /* lcd_wr */ | 130 | imx233_pinctrl_set_drive(1, 20, PINCTRL_DRIVE_4mA); /* lcd_wr */ |
132 | imx233_pinctrl_set_drive(1, 21, PINCTRL_DRIVE_4mA); /* lcd_cs */ | 131 | imx233_pinctrl_set_drive(1, 21, PINCTRL_DRIVE_4mA); /* lcd_cs */ |
@@ -219,13 +218,13 @@ static void lcd_write_reg(uint32_t reg, uint32_t data) | |||
219 | uint32_t old_reg = reg; | 218 | uint32_t old_reg = reg; |
220 | imx233_lcdif_wait_ready(); | 219 | imx233_lcdif_wait_ready(); |
221 | /* get back to 18-bit word length */ | 220 | /* get back to 18-bit word length */ |
222 | imx233_lcdif_set_word_length(BV_LCDIF_CTRL_WORD_LENGTH__18_BIT); | 221 | imx233_lcdif_set_word_length(18); |
223 | reg = encode_16_to_18(reg); | 222 | reg = encode_16_to_18(reg); |
224 | data = encode_16_to_18(data); | 223 | data = encode_16_to_18(data); |
225 | 224 | ||
226 | imx233_lcdif_pio_send(false, 2, ®); | 225 | imx233_lcdif_pio_send(false, 1, ®); |
227 | if(old_reg != 0x22) | 226 | if(old_reg != 0x22) |
228 | imx233_lcdif_pio_send(true, 2, &data); | 227 | imx233_lcdif_pio_send(true, 1, &data); |
229 | } | 228 | } |
230 | 229 | ||
231 | static uint32_t lcd_read_reg(uint32_t reg) | 230 | static uint32_t lcd_read_reg(uint32_t reg) |
@@ -399,11 +398,11 @@ void lcd_init_device(void) | |||
399 | break; | 398 | break; |
400 | } | 399 | } |
401 | // reset device | 400 | // reset device |
402 | BF_SET(LCDIF_CTRL1, RESET); | 401 | imx233_lcdif_reset_lcd(true); |
403 | mdelay(50); | 402 | mdelay(50); |
404 | BF_CLR(LCDIF_CTRL1, RESET); | 403 | imx233_lcdif_reset_lcd(false); |
405 | mdelay(10); | 404 | mdelay(10); |
406 | BF_SET(LCDIF_CTRL1, RESET); | 405 | imx233_lcdif_reset_lcd(true); |
407 | 406 | ||
408 | switch(lcd_kind) | 407 | switch(lcd_kind) |
409 | { | 408 | { |
@@ -579,9 +578,8 @@ void lcd_update_rect(int x, int y, int w, int h) | |||
579 | lcd_write_reg(0x21, y); | 578 | lcd_write_reg(0x21, y); |
580 | lcd_write_reg(0x22, 0); | 579 | lcd_write_reg(0x22, 0); |
581 | imx233_lcdif_wait_ready(); | 580 | imx233_lcdif_wait_ready(); |
582 | imx233_lcdif_set_word_length(BV_LCDIF_CTRL_WORD_LENGTH__16_BIT); | 581 | imx233_lcdif_set_word_length(16); |
583 | imx233_lcdif_set_byte_packing_format(0xf); /* two pixels per 32-bit word */ | 582 | imx233_lcdif_set_byte_packing_format(0xf); /* two pixels per 32-bit word */ |
584 | imx233_lcdif_set_data_format(false, false, false); /* RGB565, don't care, don't care */ | ||
585 | /* there are two cases here: | 583 | /* there are two cases here: |
586 | * - either width = LCD_WIDTH and we can directly memcopy a part of lcd_framebuffer to FRAME | 584 | * - either width = LCD_WIDTH and we can directly memcopy a part of lcd_framebuffer to FRAME |
587 | * and send it | 585 | * and send it |
@@ -626,198 +624,6 @@ void lcd_update_rect(int x, int y, int w, int h) | |||
626 | imx233_lcdif_dma_send((void *)FRAME_PHYS_ADDR, w, h); | 624 | imx233_lcdif_dma_send((void *)FRAME_PHYS_ADDR, w, h); |
627 | } | 625 | } |
628 | 626 | ||
629 | void lcd_yuv_set_options(unsigned options) | ||
630 | { | ||
631 | lcd_yuv_options = options; | ||
632 | } | ||
633 | |||
634 | #define YFAC (74) | ||
635 | #define RVFAC (101) | ||
636 | #define GUFAC (-24) | ||
637 | #define GVFAC (-51) | ||
638 | #define BUFAC (128) | ||
639 | |||
640 | static inline int clamp(int val, int min, int max) | ||
641 | { | ||
642 | if (val < min) | ||
643 | val = min; | ||
644 | else if (val > max) | ||
645 | val = max; | ||
646 | return val; | ||
647 | } | ||
648 | |||
649 | void lcd_blit_yuv(unsigned char * const src[3], | ||
650 | int src_x, int src_y, int stride, | ||
651 | int x, int y, int width, int height) | ||
652 | { | ||
653 | const unsigned char *ysrc, *usrc, *vsrc; | ||
654 | int linecounter; | ||
655 | fb_data *dst, *row_end; | ||
656 | long z; | ||
657 | |||
658 | /* width and height must be >= 2 and an even number */ | ||
659 | width &= ~1; | ||
660 | linecounter = height >> 1; | ||
661 | |||
662 | #if LCD_WIDTH >= LCD_HEIGHT | ||
663 | dst = FBADDR(x,y); | ||
664 | row_end = dst + width; | ||
665 | #else | ||
666 | dst = FBADDR(LCD_WIDTH - y - 1,x); | ||
667 | row_end = dst + LCD_WIDTH * width; | ||
668 | #endif | ||
669 | |||
670 | z = stride * src_y; | ||
671 | ysrc = src[0] + z + src_x; | ||
672 | usrc = src[1] + (z >> 2) + (src_x >> 1); | ||
673 | vsrc = src[2] + (usrc - src[1]); | ||
674 | |||
675 | /* stride => amount to jump from end of last row to start of next */ | ||
676 | stride -= width; | ||
677 | |||
678 | /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */ | ||
679 | |||
680 | do | ||
681 | { | ||
682 | do | ||
683 | { | ||
684 | int y, cb, cr, rv, guv, bu, r, g, b; | ||
685 | |||
686 | y = YFAC*(*ysrc++ - 16); | ||
687 | cb = *usrc++ - 128; | ||
688 | cr = *vsrc++ - 128; | ||
689 | |||
690 | rv = RVFAC*cr; | ||
691 | guv = GUFAC*cb + GVFAC*cr; | ||
692 | bu = BUFAC*cb; | ||
693 | |||
694 | r = y + rv; | ||
695 | g = y + guv; | ||
696 | b = y + bu; | ||
697 | |||
698 | if ((unsigned)(r | g | b) > 64*256-1) | ||
699 | { | ||
700 | r = clamp(r, 0, 64*256-1); | ||
701 | g = clamp(g, 0, 64*256-1); | ||
702 | b = clamp(b, 0, 64*256-1); | ||
703 | } | ||
704 | |||
705 | *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); | ||
706 | |||
707 | #if LCD_WIDTH >= LCD_HEIGHT | ||
708 | dst++; | ||
709 | #else | ||
710 | dst += LCD_WIDTH; | ||
711 | #endif | ||
712 | |||
713 | y = YFAC*(*ysrc++ - 16); | ||
714 | r = y + rv; | ||
715 | g = y + guv; | ||
716 | b = y + bu; | ||
717 | |||
718 | if ((unsigned)(r | g | b) > 64*256-1) | ||
719 | { | ||
720 | r = clamp(r, 0, 64*256-1); | ||
721 | g = clamp(g, 0, 64*256-1); | ||
722 | b = clamp(b, 0, 64*256-1); | ||
723 | } | ||
724 | |||
725 | *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); | ||
726 | |||
727 | #if LCD_WIDTH >= LCD_HEIGHT | ||
728 | dst++; | ||
729 | #else | ||
730 | dst += LCD_WIDTH; | ||
731 | #endif | ||
732 | } | ||
733 | while (dst < row_end); | ||
734 | |||
735 | ysrc += stride; | ||
736 | usrc -= width >> 1; | ||
737 | vsrc -= width >> 1; | ||
738 | |||
739 | #if LCD_WIDTH >= LCD_HEIGHT | ||
740 | row_end += LCD_WIDTH; | ||
741 | dst += LCD_WIDTH - width; | ||
742 | #else | ||
743 | row_end -= 1; | ||
744 | dst -= LCD_WIDTH*width + 1; | ||
745 | #endif | ||
746 | |||
747 | do | ||
748 | { | ||
749 | int y, cb, cr, rv, guv, bu, r, g, b; | ||
750 | |||
751 | y = YFAC*(*ysrc++ - 16); | ||
752 | cb = *usrc++ - 128; | ||
753 | cr = *vsrc++ - 128; | ||
754 | |||
755 | rv = RVFAC*cr; | ||
756 | guv = GUFAC*cb + GVFAC*cr; | ||
757 | bu = BUFAC*cb; | ||
758 | |||
759 | r = y + rv; | ||
760 | g = y + guv; | ||
761 | b = y + bu; | ||
762 | |||
763 | if ((unsigned)(r | g | b) > 64*256-1) | ||
764 | { | ||
765 | r = clamp(r, 0, 64*256-1); | ||
766 | g = clamp(g, 0, 64*256-1); | ||
767 | b = clamp(b, 0, 64*256-1); | ||
768 | } | ||
769 | |||
770 | *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); | ||
771 | |||
772 | #if LCD_WIDTH >= LCD_HEIGHT | ||
773 | dst++; | ||
774 | #else | ||
775 | dst += LCD_WIDTH; | ||
776 | #endif | ||
777 | |||
778 | y = YFAC*(*ysrc++ - 16); | ||
779 | r = y + rv; | ||
780 | g = y + guv; | ||
781 | b = y + bu; | ||
782 | |||
783 | if ((unsigned)(r | g | b) > 64*256-1) | ||
784 | { | ||
785 | r = clamp(r, 0, 64*256-1); | ||
786 | g = clamp(g, 0, 64*256-1); | ||
787 | b = clamp(b, 0, 64*256-1); | ||
788 | } | ||
789 | |||
790 | *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); | ||
791 | |||
792 | #if LCD_WIDTH >= LCD_HEIGHT | ||
793 | dst++; | ||
794 | #else | ||
795 | dst += LCD_WIDTH; | ||
796 | #endif | ||
797 | } | ||
798 | while (dst < row_end); | ||
799 | |||
800 | ysrc += stride; | ||
801 | usrc += stride >> 1; | ||
802 | vsrc += stride >> 1; | ||
803 | |||
804 | #if LCD_WIDTH >= LCD_HEIGHT | ||
805 | row_end += LCD_WIDTH; | ||
806 | dst += LCD_WIDTH - width; | ||
807 | #else | ||
808 | row_end -= 1; | ||
809 | dst -= LCD_WIDTH*width + 1; | ||
810 | #endif | ||
811 | } | ||
812 | while (--linecounter > 0); | ||
813 | |||
814 | #if LCD_WIDTH >= LCD_HEIGHT | ||
815 | lcd_update_rect(x, y, width, height); | ||
816 | #else | ||
817 | lcd_update_rect(LCD_WIDTH - y - height, x, height, width); | ||
818 | #endif | ||
819 | } | ||
820 | |||
821 | #ifndef BOOTLOADER | 627 | #ifndef BOOTLOADER |
822 | bool lcd_debug_screen(void) | 628 | bool lcd_debug_screen(void) |
823 | { | 629 | { |