video: mxsfb: introduce lcdif_power_down
authorPeng Fan <Peng.Fan@freescale.com>
Thu, 29 Oct 2015 07:54:49 +0000 (15:54 +0800)
committerStefano Babic <sbabic@denx.de>
Thu, 12 Nov 2015 16:40:53 +0000 (17:40 +0100)
Introudce a new function lcdif_power_down.

1. Waits for a VSYNC interrupt to guarantee the reset is done at the
   VSYNC edge, which somehow makes the LCDIF consume the display FIFO(?)
   and helps the LCDIF work normally at the kernel stage.
2. Add power down function to stop lcdif.

The reason to introduce lcdif_power_down is that we want lcdif to be in
initial state when doing uboot reset or before kernel boot to make
system stable, otherwise system may hang.

Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Anatolij Gustschin <agust@denx.de>
Acked-by: Anatolij Gustschin <agust@denx.de>
arch/arm/include/asm/imx-common/sys_proto.h
drivers/video/mxsfb.c

index 5673fb4bc1dcda24739fdc42b5b5246430dbb831..386c2dc42b9f300ba9a4aac4bc2987e59ca7394e 100644 (file)
@@ -47,6 +47,8 @@ int fecmxc_initialize(bd_t *bis);
 u32 get_ahb_clk(void);
 u32 get_periph_clk(void);
 
+void lcdif_power_down(void);
+
 int mxs_reset_block(struct mxs_register_32 *reg);
 int mxs_wait_mask_set(struct mxs_register_32 *reg, u32 mask, u32 timeout);
 int mxs_wait_mask_clr(struct mxs_register_32 *reg, u32 mask, u32 timeout);
index eed57d55c3812e56157d48495a7901713b8bdc20..ddbb118d709e4a2521af801099cb80e15f484fff 100644 (file)
@@ -131,6 +131,23 @@ static void mxs_lcd_init(GraphicDevice *panel,
        writel(LCDIF_CTRL_RUN, &regs->hw_lcdif_ctrl_set);
 }
 
+void lcdif_power_down(void)
+{
+       struct mxs_lcdif_regs *regs = (struct mxs_lcdif_regs *)MXS_LCDIF_BASE;
+       int timeout = 1000000;
+
+       writel(panel.frameAdrs, &regs->hw_lcdif_cur_buf_reg);
+       writel(panel.frameAdrs, &regs->hw_lcdif_next_buf_reg);
+       writel(LCDIF_CTRL1_VSYNC_EDGE_IRQ, &regs->hw_lcdif_ctrl1_clr);
+       while (--timeout) {
+               if (readl(&regs->hw_lcdif_ctrl1_reg) &
+                   LCDIF_CTRL1_VSYNC_EDGE_IRQ)
+                       break;
+               udelay(1);
+       }
+       mxs_reset_block((struct mxs_register_32 *)&regs->hw_lcdif_ctrl_reg);
+}
+
 void *video_hw_init(void)
 {
        int bpp = -1;