summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c')
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c216
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
39static bool lcd_on; 39static bool lcd_on;
40#endif 40#endif
41static unsigned lcd_yuv_options = 0;
42static int lcd_dcp_channel = -1; 41static int lcd_dcp_channel = -1;
43#ifdef HAVE_LCD_INVERT 42#ifdef HAVE_LCD_INVERT
44static int lcd_reg_0x61_val = 1; /* used to invert display */ 43static int lcd_reg_0x61_val = 1; /* used to invert display */
@@ -55,9 +54,9 @@ static enum lcd_kind_t
55 54
56static void setup_parameters(void) 55static 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, &reg); 225 imx233_lcdif_pio_send(false, 1, &reg);
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
231static uint32_t lcd_read_reg(uint32_t reg) 230static 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
629void 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
640static 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
649void 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
822bool lcd_debug_screen(void) 628bool lcd_debug_screen(void)
823{ 629{