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
This commit is contained in:
Amaury Pouly 2013-11-26 15:55:14 +00:00
parent f04d3c518a
commit cbed7ecafe

View file

@ -36,9 +36,7 @@
#include "action.h" #include "action.h"
#endif #endif
#ifdef HAVE_LCD_ENABLE
static bool lcd_on; static bool lcd_on;
#endif
/** /**
* DMA * DMA
@ -71,7 +69,7 @@ static void wait_frames_cb(void)
static void wait_nr_frames(int nr) static void wait_nr_frames(int nr)
{ {
g_wait_nr_frame = 1 + nr; // +1 because we want entire frames g_wait_nr_frame = 2 + nr; // +1 because we want entire frames, +1 to be safe
imx233_lcdif_set_vsync_edge_cb(wait_frames_cb); imx233_lcdif_set_vsync_edge_cb(wait_frames_cb);
imx233_lcdif_enable_vsync_edge_irq(true); imx233_lcdif_enable_vsync_edge_irq(true);
semaphore_wait(&g_wait_sema, TIMEOUT_BLOCK); semaphore_wait(&g_wait_sema, TIMEOUT_BLOCK);
@ -90,20 +88,15 @@ static void wait_nr_frames(int nr)
#define RS 0x2 #define RS 0x2
#define RW 0x1 #define RW 0x1
static void spi_init(void) static void spi_enable(bool en)
{ {
imx233_pinctrl_acquire(1, 9, "lcd_spi_sdo"); imx233_pinctrl_set_gpio(1, 9, en);
imx233_pinctrl_acquire(1, 10, "lcd_spi_scl"); imx233_pinctrl_set_gpio(1, 10, en);
imx233_pinctrl_acquire(1, 11, "lcd_spi_cs"); imx233_pinctrl_set_gpio(1, 11, en);
imx233_pinctrl_set_function(1, 9, PINCTRL_FUNCTION_GPIO); imx233_pinctrl_enable_gpio(1, 9, en);
imx233_pinctrl_set_function(1, 10, PINCTRL_FUNCTION_GPIO); imx233_pinctrl_enable_gpio(1, 10, en);
imx233_pinctrl_set_function(1, 11, PINCTRL_FUNCTION_GPIO); imx233_pinctrl_enable_gpio(1, 11, en);
imx233_pinctrl_set_gpio(1, 9, true); mdelay(1);
imx233_pinctrl_set_gpio(1, 10, true);
imx233_pinctrl_set_gpio(1, 11, true);
imx233_pinctrl_enable_gpio(1, 9, true);
imx233_pinctrl_enable_gpio(1, 10, true);
imx233_pinctrl_enable_gpio(1, 11, true);
} }
static void spi_delay(void) static void spi_delay(void)
@ -216,7 +209,6 @@ static void lcd_display_on_seq(void)
spi_write_reg(0x7, 0x103); spi_write_reg(0x7, 0x103);
} }
#ifdef HAVE_LCD_ENABLE
static void lcd_display_off_seq(void) static void lcd_display_off_seq(void)
{ {
spi_write_reg(0xb, 0x30e1); spi_write_reg(0xb, 0x30e1);
@ -227,30 +219,69 @@ static void lcd_display_off_seq(void)
spi_write_reg(0x10, 0x100); spi_write_reg(0x10, 0x100);
} }
static void lcd_standby_in_seq(void)
{
lcd_display_off_seq();
spi_write_reg(0x10, 0x1);
}
static void lcd_standby_out_seq(void)
{
spi_write_reg(0x10, 0);
lcd_power_seq();
lcd_display_on_seq();
}
#endif
/** /**
* Rockbox * Rockbox
*/ */
bool lcd_active(void)
{
return lcd_on;
}
void lcd_enable(bool enable)
{
if(lcd_on == enable)
return;
lcd_on = enable;
if(lcd_on)
{
// enable spi
spi_enable(true);
// reset
imx233_lcdif_reset_lcd(true);
imx233_lcdif_reset_lcd(false);
mdelay(1);
imx233_lcdif_reset_lcd(true);
mdelay(1);
// "power" on
lcd_power(true);
// setup registers
imx233_lcdif_enable_sync_signals(true); // we need frame signals during init
lcd_power_seq();
lcd_init_seq();
lcd_display_on_seq();
imx233_dma_reset_channel(APB_LCDIF);
imx233_dma_start_command(APB_LCDIF, &lcdif_dma[0].dma);
BF_SET(LCDIF_CTRL, DOTCLK_MODE);
BF_SET(LCDIF_CTRL, RUN);
}
else
{
// power down
lcd_display_off_seq();
lcd_power(false);
// stop lcdif
BF_CLR(LCDIF_CTRL, DOTCLK_MODE);
// disable spi
spi_enable(false);
}
}
void lcd_init_device(void) void lcd_init_device(void)
{ {
semaphore_init(&g_wait_sema, 1, 0); semaphore_init(&g_wait_sema, 1, 0);
#ifdef HAVE_LCD_ENABLE /* I'm not really sure this pin is related to power, it does not seem to do anything */
lcd_on = true; imx233_pinctrl_acquire(1, 8, "lcd_power");
#endif imx233_pinctrl_acquire(1, 9, "lcd_spi_sdo");
imx233_pinctrl_acquire(1, 10, "lcd_spi_scl");
imx233_pinctrl_acquire(1, 11, "lcd_spi_cs");
imx233_pinctrl_set_function(1, 9, PINCTRL_FUNCTION_GPIO);
imx233_pinctrl_set_function(1, 10, PINCTRL_FUNCTION_GPIO);
imx233_pinctrl_set_function(1, 11, PINCTRL_FUNCTION_GPIO);
imx233_pinctrl_set_function(1, 8, PINCTRL_FUNCTION_GPIO);
imx233_pinctrl_enable_gpio(1, 8, true);
/** lcd is 320x240, data bus is 8-bit, depth is 24-bit so we need 3clk/pix /** lcd is 320x240, data bus is 8-bit, depth is 24-bit so we need 3clk/pix
* by running PIX clock at 24MHz we can sustain ~100 fps */ * by running PIX clock at 24MHz we can sustain ~100 fps */
imx233_clkctrl_enable(CLK_PIX, false); imx233_clkctrl_enable(CLK_PIX, false);
@ -275,26 +306,7 @@ void lcd_init_device(void)
/*h_front_porch*/4, LCD_WIDTH, LCD_HEIGHT, /*clk_per_pix*/3, /*h_front_porch*/4, LCD_WIDTH, LCD_HEIGHT, /*clk_per_pix*/3,
/*enable_present*/false); /*enable_present*/false);
imx233_lcdif_set_byte_packing_format(0xf); imx233_lcdif_set_byte_packing_format(0xf);
// prepare pins // setup dma
spi_init();
imx233_pinctrl_acquire(1, 8, "lcd_power");
imx233_pinctrl_set_function(1, 8, PINCTRL_FUNCTION_GPIO);
imx233_pinctrl_enable_gpio(1, 8, true);
// reset lcd
imx233_lcdif_reset_lcd(true);
mdelay(10);
imx233_lcdif_reset_lcd(false);
mdelay(10);
imx233_lcdif_reset_lcd(true);
mdelay(10);
// power up
lcd_power(true);
// setup registers
imx233_lcdif_enable_sync_signals(true); // we need frame signals during init
lcd_power_seq();
lcd_init_seq();
lcd_display_on_seq();
// setup refresh
unsigned size = IMX233_FRAMEBUFFER_SIZE; unsigned size = IMX233_FRAMEBUFFER_SIZE;
uint8_t *frame_p = FRAME; uint8_t *frame_p = FRAME;
for(int i = 0; i < NR_CMDS; i++) for(int i = 0; i < NR_CMDS; i++)
@ -307,29 +319,10 @@ void lcd_init_device(void)
size -= xfer; size -= xfer;
frame_p += xfer; frame_p += xfer;
} }
imx233_dma_start_command(APB_LCDIF, &lcdif_dma[0].dma); // enable
BF_SET(LCDIF_CTRL, RUN); lcd_enable(true);
} }
#ifdef HAVE_LCD_ENABLE
bool lcd_active(void)
{
return lcd_on;
}
void lcd_enable(bool enable)
{
if(lcd_on == enable)
return;
lcd_on = enable;
if(lcd_on)
lcd_standby_out_seq();
else
lcd_standby_in_seq();
}
#endif
void lcd_update(void) void lcd_update(void)
{ {
lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); 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)
} }
} }
} }