summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx233/creative-zen/lcd-zen.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx233/creative-zen/lcd-zen.c')
-rw-r--r--firmware/target/arm/imx233/creative-zen/lcd-zen.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/firmware/target/arm/imx233/creative-zen/lcd-zen.c b/firmware/target/arm/imx233/creative-zen/lcd-zen.c
index e9644278f1..6482c58787 100644
--- a/firmware/target/arm/imx233/creative-zen/lcd-zen.c
+++ b/firmware/target/arm/imx233/creative-zen/lcd-zen.c
@@ -48,7 +48,7 @@ static bool lcd_on;
48struct lcdif_dma_command_t 48struct lcdif_dma_command_t
49{ 49{
50 struct apb_dma_command_t dma; 50 struct apb_dma_command_t dma;
51 uint32_t pad; 51 uint32_t ctrl;
52} __attribute__((packed)) CACHEALIGN_ATTR; 52} __attribute__((packed)) CACHEALIGN_ATTR;
53 53
54__ENSURE_STRUCT_CACHE_FRIENDLY(struct lcdif_dma_command_t) 54__ENSURE_STRUCT_CACHE_FRIENDLY(struct lcdif_dma_command_t)
@@ -249,15 +249,12 @@ void lcd_enable(bool enable)
249 // "power" on 249 // "power" on
250 lcd_power(true); 250 lcd_power(true);
251 // setup registers 251 // setup registers
252 imx233_lcdif_enable_sync_signals(true); // we need frame signals during init
253 lcd_power_seq(); 252 lcd_power_seq();
254 lcd_init_seq(); 253 lcd_init_seq();
255 lcd_display_on_seq(); 254 lcd_display_on_seq();
256 255
257 imx233_dma_reset_channel(APB_LCDIF); 256 imx233_dma_reset_channel(APB_LCDIF);
258 imx233_dma_start_command(APB_LCDIF, &lcdif_dma[0].dma); 257 imx233_dma_start_command(APB_LCDIF, &lcdif_dma[0].dma);
259 BF_SET(LCDIF_CTRL, DOTCLK_MODE);
260 BF_SET(LCDIF_CTRL, RUN);
261 } 258 }
262 else 259 else
263 { 260 {
@@ -275,6 +272,15 @@ void lcd_enable(bool enable)
275 } 272 }
276} 273}
277 274
275static void lcd_underflow(void)
276{
277 /* on underflow, current frame is dead so stop lcdif and prepare for next frame
278 * don't bother with the errata, fifo is empty since we are underflowing ! */
279 BF_CLR(LCDIF_CTRL, DOTCLK_MODE);
280 imx233_dma_reset_channel(APB_LCDIF);
281 imx233_dma_start_command(APB_LCDIF, &lcdif_dma[0].dma);
282}
283
278void lcd_init_device(void) 284void lcd_init_device(void)
279{ 285{
280 semaphore_init(&g_wait_sema, 1, 0); 286 semaphore_init(&g_wait_sema, 1, 0);
@@ -297,6 +303,8 @@ void lcd_init_device(void)
297 imx233_lcdif_init(); 303 imx233_lcdif_init();
298 imx233_lcdif_setup_dotclk_pins(8, false); 304 imx233_lcdif_setup_dotclk_pins(8, false);
299 imx233_lcdif_set_word_length(8); 305 imx233_lcdif_set_word_length(8);
306 imx233_lcdif_set_underflow_cb(&lcd_underflow);
307 imx233_lcdif_enable_underflow_irq(true);
300 imx233_dma_clkgate_channel(APB_LCDIF, true); 308 imx233_dma_clkgate_channel(APB_LCDIF, true);
301 imx233_dma_reset_channel(APB_LCDIF); 309 imx233_dma_reset_channel(APB_LCDIF);
302 /** Datasheet states: 310 /** Datasheet states:
@@ -312,6 +320,7 @@ void lcd_init_device(void)
312 /*h_front_porch*/4, LCD_WIDTH, LCD_HEIGHT, /*clk_per_pix*/3, 320 /*h_front_porch*/4, LCD_WIDTH, LCD_HEIGHT, /*clk_per_pix*/3,
313 /*enable_present*/false); 321 /*enable_present*/false);
314 imx233_lcdif_set_byte_packing_format(0xf); 322 imx233_lcdif_set_byte_packing_format(0xf);
323 imx233_lcdif_enable_sync_signals(true); // we need frame signals during init
315 // setup dma 324 // setup dma
316 unsigned size = IMX233_FRAMEBUFFER_SIZE; 325 unsigned size = IMX233_FRAMEBUFFER_SIZE;
317 uint8_t *frame_p = FRAME; 326 uint8_t *frame_p = FRAME;
@@ -325,6 +334,10 @@ void lcd_init_device(void)
325 size -= xfer; 334 size -= xfer;
326 frame_p += xfer; 335 frame_p += xfer;
327 } 336 }
337 // first transfer: enable run, dotclk and so on
338 lcdif_dma[0].dma.cmd |= BF_OR1(APB_CHx_CMD, CMDWORDS(1));
339 lcdif_dma[0].ctrl = BF_OR4(LCDIF_CTRL, BYPASS_COUNT(1), DOTCLK_MODE(1),
340 RUN(1), WORD_LENGTH(1));
328 // enable 341 // enable
329 lcd_enable(true); 342 lcd_enable(true);
330} 343}