diff options
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c')
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c | 71 |
1 files changed, 57 insertions, 14 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c index 783621c88b..25265395b2 100644 --- a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c | |||
@@ -71,7 +71,14 @@ bool lcd_active(void) | |||
71 | /* Update a fraction of the display. */ | 71 | /* Update a fraction of the display. */ |
72 | void lcd_update_rect(int x, int y, int width, int height) | 72 | void lcd_update_rect(int x, int y, int width, int height) |
73 | { | 73 | { |
74 | x=0;y=0;width=LCD_WIDTH;height=LCD_HEIGHT; /* HACK! */ | 74 | /* Currently only do full updates. |
75 | * DMA can't handle partial updates and CPU is too slow compared | ||
76 | * to full DMA updates */ | ||
77 | x = 0; | ||
78 | y = 0; | ||
79 | width = LCD_WIDTH; | ||
80 | height = LCD_HEIGHT; | ||
81 | |||
75 | mutex_lock(&lcd_mtx); | 82 | mutex_lock(&lcd_mtx); |
76 | 83 | ||
77 | __cpm_start_lcd(); | 84 | __cpm_start_lcd(); |
@@ -82,12 +89,12 @@ x=0;y=0;width=LCD_WIDTH;height=LCD_HEIGHT; /* HACK! */ | |||
82 | 89 | ||
83 | REG_DMAC_DCCSR(DMA_LCD_CHANNEL) = DMAC_DCCSR_NDES; | 90 | REG_DMAC_DCCSR(DMA_LCD_CHANNEL) = DMAC_DCCSR_NDES; |
84 | REG_DMAC_DSAR(DMA_LCD_CHANNEL) = PHYSADDR((unsigned long)&lcd_framebuffer[y][x]); | 91 | REG_DMAC_DSAR(DMA_LCD_CHANNEL) = PHYSADDR((unsigned long)&lcd_framebuffer[y][x]); |
85 | REG_DMAC_DRSR(DMA_LCD_CHANNEL) = DMAC_DRSR_RS_SLCD; /* source = SLCD */ | 92 | REG_DMAC_DRSR(DMA_LCD_CHANNEL) = DMAC_DRSR_RS_SLCD; |
86 | REG_DMAC_DTAR(DMA_LCD_CHANNEL) = PHYSADDR(SLCD_FIFO); | 93 | REG_DMAC_DTAR(DMA_LCD_CHANNEL) = PHYSADDR(SLCD_FIFO); |
87 | REG_DMAC_DTCR(DMA_LCD_CHANNEL) = width*height; | 94 | REG_DMAC_DTCR(DMA_LCD_CHANNEL) = (width * height) >> 3; |
88 | 95 | ||
89 | REG_DMAC_DCMD(DMA_LCD_CHANNEL) = ( DMAC_DCMD_SAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | 96 | REG_DMAC_DCMD(DMA_LCD_CHANNEL) = ( DMAC_DCMD_SAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 |
90 | | DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_16BIT ); | 97 | | DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_16BYTE ); |
91 | 98 | ||
92 | __dcache_writeback_all(); /* Size of framebuffer is way bigger than cache size. | 99 | __dcache_writeback_all(); /* Size of framebuffer is way bigger than cache size. |
93 | We need to find a way to make the framebuffer uncached, so this statement can get removed. */ | 100 | We need to find a way to make the framebuffer uncached, so this statement can get removed. */ |
@@ -101,7 +108,6 @@ x=0;y=0;width=LCD_WIDTH;height=LCD_HEIGHT; /* HACK! */ | |||
101 | wakeup_wait(&lcd_wkup, TIMEOUT_BLOCK); /* Sleeping in lcd_update() should be safe */ | 108 | wakeup_wait(&lcd_wkup, TIMEOUT_BLOCK); /* Sleeping in lcd_update() should be safe */ |
102 | 109 | ||
103 | REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */ | 110 | REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */ |
104 | |||
105 | dma_disable(); | 111 | dma_disable(); |
106 | 112 | ||
107 | while(REG_SLCD_STATE & SLCD_STATE_BUSY); | 113 | while(REG_SLCD_STATE & SLCD_STATE_BUSY); |
@@ -139,17 +145,54 @@ void lcd_update(void) | |||
139 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); | 145 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); |
140 | } | 146 | } |
141 | 147 | ||
142 | /* TODO: use IPU */ | 148 | /* (Mis)use LCD framebuffer as a temporary buffer */ |
143 | void lcd_blit_yuv(unsigned char * const src[3], | 149 | void lcd_blit_yuv(unsigned char * const src[3], |
144 | int src_x, int src_y, int stride, | 150 | int src_x, int src_y, int stride, |
145 | int x, int y, int width, int height) | 151 | int x, int y, int width, int height) |
146 | { | 152 | { |
147 | (void)src; | 153 | __dcache_writeback_all(); |
148 | (void)src_x; | 154 | |
149 | (void)src_y; | 155 | __cpm_start_ipu(); |
150 | (void)stride; | 156 | |
151 | (void)x; | 157 | IPU_STOP_IPU(); |
152 | (void)y; | 158 | IPU_RESET_IPU() |
153 | (void)width; | 159 | IPU_CLEAR_END_FLAG(); |
154 | (void)height; | 160 | |
161 | IPU_DISABLE_RSIZE(); | ||
162 | IPU_DISABLE_IRQ(); | ||
163 | |||
164 | IPU_SET_INFMT(INFMT_YUV420); | ||
165 | IPU_SET_OUTFMT(OUTFMT_RGB565); | ||
166 | |||
167 | IPU_SET_IN_FM(width, height); | ||
168 | IPU_SET_Y_STRIDE(stride); | ||
169 | IPU_SET_UV_STRIDE(stride, stride); | ||
170 | |||
171 | IPU_SET_Y_ADDR((unsigned long)src[0]); | ||
172 | IPU_SET_U_ADDR((unsigned long)src[2]); | ||
173 | IPU_SET_V_ADDR((unsigned long)src[3]); | ||
174 | IPU_SET_OUT_ADDR(PHYSADDR((unsigned long)&lcd_framebuffer[y][x])); | ||
175 | |||
176 | IPU_SET_OUT_FM(width, height); | ||
177 | IPU_SET_OUT_STRIDE(stride); | ||
178 | |||
179 | IPU_SET_CSC_C0_COEF(YUV_CSC_C0); | ||
180 | IPU_SET_CSC_C1_COEF(YUV_CSC_C1); | ||
181 | IPU_SET_CSC_C2_COEF(YUV_CSC_C2); | ||
182 | IPU_SET_CSC_C2_COEF(YUV_CSC_C3); | ||
183 | IPU_SET_CSC_C4_COEF(YUV_CSC_C4); | ||
184 | |||
185 | IPU_RUN_IPU(); | ||
186 | |||
187 | while(!(IPU_POLLING_END_FLAG()) && IPU_IS_ENABLED()); | ||
188 | |||
189 | IPU_CLEAR_END_FLAG(); | ||
190 | IPU_STOP_IPU(); | ||
191 | |||
192 | //__cpm_stop_ipu(); | ||
193 | |||
194 | __dcache_invalidate_all(); | ||
195 | |||
196 | /* YUV speed is limited by LCD speed */ | ||
197 | lcd_update_rect(x, y, width, height); | ||
155 | } | 198 | } |