summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2013-06-17 00:06:24 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2013-06-17 00:29:25 +0200
commit069a0269a922ad466d35611d128dda377ef305c1 (patch)
tree2873857099d2f7f5ee2bf16c73b245fa821c8597 /firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c
parent52426d08918eadfba178f74e1bd5d1663f9c73e0 (diff)
downloadrockbox-069a0269a922ad466d35611d128dda377ef305c1.tar.gz
rockbox-069a0269a922ad466d35611d128dda377ef305c1.zip
imx233: fix/improve lcdif for stmp3600 and stmp4700, fix drivers
Factorise pin setup, rewrite PIO code, add support for lcdif irq, handle all the various differences between the stmps, drop yuv blitting code since it already exists in the common lcd drivers. Change-Id: Ifc40aed9b3b12f16611ce960602e46a5bc87ae53
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{