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 <peng.fan@nxp.com>
Cc: Stefano Babic <sbabic@denx.de>
This commit is contained in:
Peng Fan 2016-12-11 19:24:28 +08:00 committed by Stefano Babic
parent e332623b03
commit 708f692753
4 changed files with 33 additions and 23 deletions

View 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;
}

View 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);

View 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));

View 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));