imx: clock: gate clk before changing pix clk mux
authorPeng Fan <peng.fan@nxp.com>
Sun, 11 Dec 2016 11:24:28 +0000 (19:24 +0800)
committerStefano Babic <sbabic@denx.de>
Fri, 16 Dec 2016 10:38:24 +0000 (11:38 +0100)
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
arch/arm/include/asm/arch-mx6/clock.h
board/freescale/mx6sxsabresd/mx6sxsabresd.c
board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c

index 007c135fd1d53e897af9f97865c65ecd5a119cd4..de3665f8c3f24446f49434e01dd07033db16d5ac 100644 (file)
@@ -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;
 }
index ed1433ebc6839994b5653869c3e15dd978fd642b..2d9c45e255da011c119e6d38bc9feaacb301855d 100644 (file)
@@ -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);
index 965e51116652a5762d3bfec3467e81f29b581fcd..0460cd9257b15196288a17cac35a130f9205f390 100644 (file)
@@ -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));
 
index 399bad215fa7e7be36fbecc68c7836a4348dfe1e..b28ce104958945c2be1a1d65771d5a2d4a151936 100644 (file)
@@ -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));