diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2013-11-26 15:55:14 +0000 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2013-11-26 15:57:13 +0000 |
commit | cbed7ecafed52f41a06fdd1315e06f5601063606 (patch) | |
tree | 5ea15b05c46dd59b9f6788e3cd93413fc2683065 | |
parent | f04d3c518a3c26def9a003a108bec254499c7c90 (diff) | |
download | rockbox-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.c | 140 |
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 | ||
40 | static bool lcd_on; | 39 | static 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 | ||
72 | static void wait_nr_frames(int nr) | 70 | static 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 | ||
93 | static void spi_init(void) | 91 | static 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 | ||
109 | static void spi_delay(void) | 102 | static 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 | ||
220 | static void lcd_display_off_seq(void) | 212 | static 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 | ||
230 | static void lcd_standby_in_seq(void) | 222 | /** |
223 | * Rockbox | ||
224 | */ | ||
225 | |||
226 | bool lcd_active(void) | ||
231 | { | 227 | { |
232 | lcd_display_off_seq(); | 228 | return lcd_on; |
233 | spi_write_reg(0x10, 0x1); | ||
234 | } | 229 | } |
235 | 230 | ||
236 | static void lcd_standby_out_seq(void) | 231 | void 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 | ||
248 | void lcd_init_device(void) | 272 | void 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 | ||
315 | bool lcd_active(void) | ||
316 | { | ||
317 | return lcd_on; | ||
318 | } | ||
319 | |||
320 | void 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 | |||
333 | void lcd_update(void) | 326 | void 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 | |||