summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2014-03-08 18:20:08 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2014-03-08 18:51:54 +0100
commit4b2f59b3db7d378a42dfebd39e4e3b4ccc8280f8 (patch)
tree4cdc80e4c11752ed447a45f0b2b07a6d51010c2f /firmware/target
parentb0940b1dd388a3d7b8d50da329b84e8f65717b9a (diff)
downloadrockbox-4b2f59b3db7d378a42dfebd39e4e3b4ccc8280f8.tar.gz
rockbox-4b2f59b3db7d378a42dfebd39e4e3b4ccc8280f8.zip
zen: handle lcd underflow by hand
Contrary to the imx233, the stmp37xx lcdif doesn't know how to properly recover from underflow and things are worse because of the errata which makes the lcdif not clear the fifo. Workaround this by detecting underflow and taking action: stop dotclk mode (will clear fifo) and schedule next frame. The dma transfers now write the ctrl register as part of the PIO writes, making the code simpler. Change-Id: I15abc24567f322cd03bf2ef7903094f7f0178427
Diffstat (limited to 'firmware/target')
-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}