diff mbox

[U-Boot,V2,09/19] imx: clock: gate clk before changing pix clk mux

Message ID 1481455478-8258-10-git-send-email-peng.fan@nxp.com
State Awaiting Upstream
Delegated to: Stefano Babic
Headers show

Commit Message

Peng Fan Dec. 11, 2016, 11:24 a.m. UTC
The LCDIF Pixel clock mux is not glitchless, so need
to gate before changing mux.

Also change enable_lcdif_clock prototype with a new input
parameter to indicate disable or enable.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
Cc: Stefano Babic <sbabic@denx.de>
---
 arch/arm/cpu/armv7/mx6/clock.c                    | 50 ++++++++++++++---------
 arch/arm/include/asm/arch-mx6/clock.h             |  2 +-
 board/freescale/mx6sxsabresd/mx6sxsabresd.c       |  2 +-
 board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c |  2 +-
 4 files changed, 33 insertions(+), 23 deletions(-)
diff mbox

Patch

diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
index 007c135..de3665f 100644
--- a/arch/arm/cpu/armv7/mx6/clock.c
+++ b/arch/arm/cpu/armv7/mx6/clock.c
@@ -707,6 +707,7 @@  void mxs_set_lcdclk(u32 base_addr, u32 freq)
 		if (enable_pll_video(pll_div, pll_num, pll_denom, post_div))
 			return;
 
+		enable_lcdif_clock(base_addr, 0);
 		if (!is_mx6sl()) {
 			/* Select pre-lcd clock to PLL5 and set pre divider */
 			clrsetbits_le32(&imx_ccm->cscdr2,
@@ -736,11 +737,14 @@  void mxs_set_lcdclk(u32 base_addr, u32 freq)
 					(((postd - 1)^0x6) <<
 					 MXC_CCM_CSCMR1_LCDIF_PIX_PODF_OFFSET));
 		}
+
+		enable_lcdif_clock(base_addr, 1);
 	} else if (is_mx6sx()) {
 		/* Setting LCDIF2 for i.MX6SX */
 		if (enable_pll_video(pll_div, pll_num, pll_denom, post_div))
 			return;
 
+		enable_lcdif_clock(base_addr, 0);
 		/* Select pre-lcd clock to PLL5 and set pre divider */
 		clrsetbits_le32(&imx_ccm->cscdr2,
 				MXC_CCM_CSCDR2_LCDIF2_PRED_SEL_MASK |
@@ -754,10 +758,12 @@  void mxs_set_lcdclk(u32 base_addr, u32 freq)
 				MXC_CCM_CSCMR1_LCDIF2_PODF_MASK,
 				((postd - 1) <<
 				 MXC_CCM_CSCMR1_LCDIF2_PODF_OFFSET));
+
+		enable_lcdif_clock(base_addr, 1);
 	}
 }
 
-int enable_lcdif_clock(u32 base_addr)
+int enable_lcdif_clock(u32 base_addr, bool enable)
 {
 	u32 reg = 0;
 	u32 lcdif_clk_sel_mask, lcdif_ccgr3_mask;
@@ -796,15 +802,17 @@  int enable_lcdif_clock(u32 base_addr)
 			 MXC_CCM_CCGR3_LCDIF_PIX_MASK);
 		writel(reg, &imx_ccm->CCGR3);
 
-		reg = readl(&imx_ccm->cscdr3);
-		reg &= ~MXC_CCM_CSCDR3_LCDIF_AXI_CLK_SEL_MASK;
-		reg |= 1 << MXC_CCM_CSCDR3_LCDIF_AXI_CLK_SEL_OFFSET;
-		writel(reg, &imx_ccm->cscdr3);
+		if (enable) {
+			reg = readl(&imx_ccm->cscdr3);
+			reg &= ~MXC_CCM_CSCDR3_LCDIF_AXI_CLK_SEL_MASK;
+			reg |= 1 << MXC_CCM_CSCDR3_LCDIF_AXI_CLK_SEL_OFFSET;
+			writel(reg, &imx_ccm->cscdr3);
 
-		reg = readl(&imx_ccm->CCGR3);
-		reg |= MXC_CCM_CCGR3_LCDIF_AXI_MASK |
-			MXC_CCM_CCGR3_LCDIF_PIX_MASK;
-		writel(reg, &imx_ccm->CCGR3);
+			reg = readl(&imx_ccm->CCGR3);
+			reg |= MXC_CCM_CCGR3_LCDIF_AXI_MASK |
+				MXC_CCM_CCGR3_LCDIF_PIX_MASK;
+			writel(reg, &imx_ccm->CCGR3);
+		}
 
 		return 0;
 	} else {
@@ -820,19 +828,21 @@  int enable_lcdif_clock(u32 base_addr)
 	reg &= ~MXC_CCM_CCGR2_LCD_MASK;
 	writel(reg, &imx_ccm->CCGR2);
 
-	/* Select pre-mux */
-	reg = readl(&imx_ccm->cscdr2);
-	reg &= ~lcdif_clk_sel_mask;
-	writel(reg, &imx_ccm->cscdr2);
+	if (enable) {
+		/* Select pre-mux */
+		reg = readl(&imx_ccm->cscdr2);
+		reg &= ~lcdif_clk_sel_mask;
+		writel(reg, &imx_ccm->cscdr2);
 
-	/* Enable the LCDIF pix clock */
-	reg = readl(&imx_ccm->CCGR3);
-	reg |= lcdif_ccgr3_mask;
-	writel(reg, &imx_ccm->CCGR3);
+		/* Enable the LCDIF pix clock */
+		reg = readl(&imx_ccm->CCGR3);
+		reg |= lcdif_ccgr3_mask;
+		writel(reg, &imx_ccm->CCGR3);
 
-	reg = readl(&imx_ccm->CCGR2);
-	reg |= MXC_CCM_CCGR2_LCD_MASK;
-	writel(reg, &imx_ccm->CCGR2);
+		reg = readl(&imx_ccm->CCGR2);
+		reg |= MXC_CCM_CCGR2_LCD_MASK;
+		writel(reg, &imx_ccm->CCGR2);
+	}
 
 	return 0;
 }
diff --git a/arch/arm/include/asm/arch-mx6/clock.h b/arch/arm/include/asm/arch-mx6/clock.h
index ed1433e..2d9c45e 100644
--- a/arch/arm/include/asm/arch-mx6/clock.h
+++ b/arch/arm/include/asm/arch-mx6/clock.h
@@ -74,7 +74,7 @@  int enable_spi_clk(unsigned char enable, unsigned spi_num);
 void enable_ipu_clock(void);
 int enable_fec_anatop_clock(int fec_id, enum enet_freq freq);
 void enable_enet_clk(unsigned char enable);
-int enable_lcdif_clock(u32 base_addr);
+int enable_lcdif_clock(u32 base_addr, bool enable);
 void enable_qspi_clk(int qspi_num);
 void enable_thermal_clk(void);
 void mxs_set_lcdclk(u32 base_addr, u32 freq);
diff --git a/board/freescale/mx6sxsabresd/mx6sxsabresd.c b/board/freescale/mx6sxsabresd/mx6sxsabresd.c
index 965e511..0460cd9 100644
--- a/board/freescale/mx6sxsabresd/mx6sxsabresd.c
+++ b/board/freescale/mx6sxsabresd/mx6sxsabresd.c
@@ -504,7 +504,7 @@  static iomux_v3_cfg_t const lcd_pads[] = {
 
 static int setup_lcd(void)
 {
-	enable_lcdif_clock(LCDIF1_BASE_ADDR);
+	enable_lcdif_clock(LCDIF1_BASE_ADDR, 1);
 
 	imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads));
 
diff --git a/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c b/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c
index 399bad2..b28ce10 100644
--- a/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c
+++ b/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c
@@ -600,7 +600,7 @@  static iomux_v3_cfg_t const lcd_pads[] = {
 
 static int setup_lcd(void)
 {
-	enable_lcdif_clock(LCDIF1_BASE_ADDR);
+	enable_lcdif_clock(LCDIF1_BASE_ADDR, 1);
 
 	imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads));