summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2013-11-26 15:55:14 +0000
committerAmaury Pouly <amaury.pouly@gmail.com>2013-11-26 15:57:13 +0000
commitcbed7ecafed52f41a06fdd1315e06f5601063606 (patch)
tree5ea15b05c46dd59b9f6788e3cd93413fc2683065
parentf04d3c518a3c26def9a003a108bec254499c7c90 (diff)
downloadrockbox-cbed7ecafed52f41a06fdd1315e06f5601063606.tar.gz
rockbox-cbed7ecafed52f41a06fdd1315e06f5601063606.zip
zen: rework lcd enable
The ZEN/ZEN-XFi seem to be very picky about the lcd. And they do not like standby mode so I'm going to drop it, the OF doesn't use it anyway. I still don't know what this "power" pin is about, obviously it's not real power but the OF toggle it. Let's hope the lcd will finally become more stable with fix: the driver now does full power on/off on enable/disable. Change-Id: I1c465ee4f2462bc3d9507e5f575f0a181af60214
-rw-r--r--firmware/target/arm/imx233/creative-zen/lcd-zen.c140
1 files changed, 67 insertions, 73 deletions
diff --git a/firmware/target/arm/imx233/creative-zen/lcd-zen.c b/firmware/target/arm/imx233/creative-zen/lcd-zen.c
index d1d690a974..7e9e98271c 100644
--- a/firmware/target/arm/imx233/creative-zen/lcd-zen.c
+++ b/firmware/target/arm/imx233/creative-zen/lcd-zen.c
@@ -36,9 +36,7 @@
36#include "action.h" 36#include "action.h"
37#endif 37#endif
38 38
39#ifdef HAVE_LCD_ENABLE
40static bool lcd_on; 39static bool lcd_on;
41#endif
42 40
43/** 41/**
44 * DMA 42 * DMA
@@ -71,7 +69,7 @@ static void wait_frames_cb(void)
71 69
72static void wait_nr_frames(int nr) 70static void wait_nr_frames(int nr)
73{ 71{
74 g_wait_nr_frame = 1 + nr; // +1 because we want entire frames 72 g_wait_nr_frame = 2 + nr; // +1 because we want entire frames, +1 to be safe
75 imx233_lcdif_set_vsync_edge_cb(wait_frames_cb); 73 imx233_lcdif_set_vsync_edge_cb(wait_frames_cb);
76 imx233_lcdif_enable_vsync_edge_irq(true); 74 imx233_lcdif_enable_vsync_edge_irq(true);
77 semaphore_wait(&g_wait_sema, TIMEOUT_BLOCK); 75 semaphore_wait(&g_wait_sema, TIMEOUT_BLOCK);
@@ -90,20 +88,15 @@ static void wait_nr_frames(int nr)
90#define RS 0x2 88#define RS 0x2
91#define RW 0x1 89#define RW 0x1
92 90
93static void spi_init(void) 91static void spi_enable(bool en)
94{ 92{
95 imx233_pinctrl_acquire(1, 9, "lcd_spi_sdo"); 93 imx233_pinctrl_set_gpio(1, 9, en);
96 imx233_pinctrl_acquire(1, 10, "lcd_spi_scl"); 94 imx233_pinctrl_set_gpio(1, 10, en);
97 imx233_pinctrl_acquire(1, 11, "lcd_spi_cs"); 95 imx233_pinctrl_set_gpio(1, 11, en);
98 imx233_pinctrl_set_function(1, 9, PINCTRL_FUNCTION_GPIO); 96 imx233_pinctrl_enable_gpio(1, 9, en);
99 imx233_pinctrl_set_function(1, 10, PINCTRL_FUNCTION_GPIO); 97 imx233_pinctrl_enable_gpio(1, 10, en);
100 imx233_pinctrl_set_function(1, 11, PINCTRL_FUNCTION_GPIO); 98 imx233_pinctrl_enable_gpio(1, 11, en);
101 imx233_pinctrl_set_gpio(1, 9, true); 99 mdelay(1);
102 imx233_pinctrl_set_gpio(1, 10, true);
103 imx233_pinctrl_set_gpio(1, 11, true);
104 imx233_pinctrl_enable_gpio(1, 9, true);
105 imx233_pinctrl_enable_gpio(1, 10, true);
106 imx233_pinctrl_enable_gpio(1, 11, true);
107} 100}
108 101
109static void spi_delay(void) 102static void spi_delay(void)
@@ -216,7 +209,6 @@ static void lcd_display_on_seq(void)
216 spi_write_reg(0x7, 0x103); 209 spi_write_reg(0x7, 0x103);
217} 210}
218 211
219#ifdef HAVE_LCD_ENABLE
220static void lcd_display_off_seq(void) 212static void lcd_display_off_seq(void)
221{ 213{
222 spi_write_reg(0xb, 0x30e1); 214 spi_write_reg(0xb, 0x30e1);
@@ -227,30 +219,69 @@ static void lcd_display_off_seq(void)
227 spi_write_reg(0x10, 0x100); 219 spi_write_reg(0x10, 0x100);
228} 220}
229 221
230static void lcd_standby_in_seq(void) 222/**
223 * Rockbox
224 */
225
226bool lcd_active(void)
231{ 227{
232 lcd_display_off_seq(); 228 return lcd_on;
233 spi_write_reg(0x10, 0x1);
234} 229}
235 230
236static void lcd_standby_out_seq(void) 231void lcd_enable(bool enable)
237{ 232{
238 spi_write_reg(0x10, 0); 233 if(lcd_on == enable)
239 lcd_power_seq(); 234 return;
240 lcd_display_on_seq();
241}
242#endif
243 235
244/** 236 lcd_on = enable;
245 * Rockbox 237 if(lcd_on)
246 */ 238 {
239 // enable spi
240 spi_enable(true);
241 // reset
242 imx233_lcdif_reset_lcd(true);
243 imx233_lcdif_reset_lcd(false);
244 mdelay(1);
245 imx233_lcdif_reset_lcd(true);
246 mdelay(1);
247 // "power" on
248 lcd_power(true);
249 // setup registers
250 imx233_lcdif_enable_sync_signals(true); // we need frame signals during init
251 lcd_power_seq();
252 lcd_init_seq();
253 lcd_display_on_seq();
254
255 imx233_dma_reset_channel(APB_LCDIF);
256 imx233_dma_start_command(APB_LCDIF, &lcdif_dma[0].dma);
257 BF_SET(LCDIF_CTRL, DOTCLK_MODE);
258 BF_SET(LCDIF_CTRL, RUN);
259 }
260 else
261 {
262 // power down
263 lcd_display_off_seq();
264 lcd_power(false);
265 // stop lcdif
266 BF_CLR(LCDIF_CTRL, DOTCLK_MODE);
267 // disable spi
268 spi_enable(false);
269 }
270}
247 271
248void lcd_init_device(void) 272void lcd_init_device(void)
249{ 273{
250 semaphore_init(&g_wait_sema, 1, 0); 274 semaphore_init(&g_wait_sema, 1, 0);
251#ifdef HAVE_LCD_ENABLE 275 /* I'm not really sure this pin is related to power, it does not seem to do anything */
252 lcd_on = true; 276 imx233_pinctrl_acquire(1, 8, "lcd_power");
253#endif 277 imx233_pinctrl_acquire(1, 9, "lcd_spi_sdo");
278 imx233_pinctrl_acquire(1, 10, "lcd_spi_scl");
279 imx233_pinctrl_acquire(1, 11, "lcd_spi_cs");
280 imx233_pinctrl_set_function(1, 9, PINCTRL_FUNCTION_GPIO);
281 imx233_pinctrl_set_function(1, 10, PINCTRL_FUNCTION_GPIO);
282 imx233_pinctrl_set_function(1, 11, PINCTRL_FUNCTION_GPIO);
283 imx233_pinctrl_set_function(1, 8, PINCTRL_FUNCTION_GPIO);
284 imx233_pinctrl_enable_gpio(1, 8, true);
254 /** lcd is 320x240, data bus is 8-bit, depth is 24-bit so we need 3clk/pix 285 /** lcd is 320x240, data bus is 8-bit, depth is 24-bit so we need 3clk/pix
255 * by running PIX clock at 24MHz we can sustain ~100 fps */ 286 * by running PIX clock at 24MHz we can sustain ~100 fps */
256 imx233_clkctrl_enable(CLK_PIX, false); 287 imx233_clkctrl_enable(CLK_PIX, false);
@@ -275,26 +306,7 @@ void lcd_init_device(void)
275 /*h_front_porch*/4, LCD_WIDTH, LCD_HEIGHT, /*clk_per_pix*/3, 306 /*h_front_porch*/4, LCD_WIDTH, LCD_HEIGHT, /*clk_per_pix*/3,
276 /*enable_present*/false); 307 /*enable_present*/false);
277 imx233_lcdif_set_byte_packing_format(0xf); 308 imx233_lcdif_set_byte_packing_format(0xf);
278 // prepare pins 309 // setup dma
279 spi_init();
280 imx233_pinctrl_acquire(1, 8, "lcd_power");
281 imx233_pinctrl_set_function(1, 8, PINCTRL_FUNCTION_GPIO);
282 imx233_pinctrl_enable_gpio(1, 8, true);
283 // reset lcd
284 imx233_lcdif_reset_lcd(true);
285 mdelay(10);
286 imx233_lcdif_reset_lcd(false);
287 mdelay(10);
288 imx233_lcdif_reset_lcd(true);
289 mdelay(10);
290 // power up
291 lcd_power(true);
292 // setup registers
293 imx233_lcdif_enable_sync_signals(true); // we need frame signals during init
294 lcd_power_seq();
295 lcd_init_seq();
296 lcd_display_on_seq();
297 // setup refresh
298 unsigned size = IMX233_FRAMEBUFFER_SIZE; 310 unsigned size = IMX233_FRAMEBUFFER_SIZE;
299 uint8_t *frame_p = FRAME; 311 uint8_t *frame_p = FRAME;
300 for(int i = 0; i < NR_CMDS; i++) 312 for(int i = 0; i < NR_CMDS; i++)
@@ -307,29 +319,10 @@ void lcd_init_device(void)
307 size -= xfer; 319 size -= xfer;
308 frame_p += xfer; 320 frame_p += xfer;
309 } 321 }
310 imx233_dma_start_command(APB_LCDIF, &lcdif_dma[0].dma); 322 // enable
311 BF_SET(LCDIF_CTRL, RUN); 323 lcd_enable(true);
312} 324}
313 325
314#ifdef HAVE_LCD_ENABLE
315bool lcd_active(void)
316{
317 return lcd_on;
318}
319
320void lcd_enable(bool enable)
321{
322 if(lcd_on == enable)
323 return;
324
325 lcd_on = enable;
326 if(lcd_on)
327 lcd_standby_out_seq();
328 else
329 lcd_standby_in_seq();
330}
331#endif
332
333void lcd_update(void) 326void lcd_update(void)
334{ 327{
335 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); 328 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
@@ -353,3 +346,4 @@ void lcd_update_rect(int x, int y, int w, int h)
353 } 346 }
354 } 347 }
355} 348}
349