From 708f69275329d4e23ed2f927cee7674ca25c1544 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 11 Dec 2016 19:24:28 +0800 Subject: [PATCH] imx: clock: gate clk before changing pix clk mux 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 Cc: Stefano Babic --- arch/arm/cpu/armv7/mx6/clock.c | 50 +++++++++++-------- arch/arm/include/asm/arch-mx6/clock.h | 2 +- board/freescale/mx6sxsabresd/mx6sxsabresd.c | 2 +- .../mx6ul_14x14_evk/mx6ul_14x14_evk.c | 2 +- 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c index 007c135fd1..de3665f8c3 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 ed1433ebc6..2d9c45e255 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 965e511166..0460cd9257 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 399bad215f..b28ce10495 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)); -- GitLab