[U-Boot] [PATCH 08/19] imx: mx6sl: add lcdif clock support
Peng Fan
peng.fan at nxp.com
Thu Nov 24 07:47:50 CET 2016
Add lcdif clock support for i.MX6SL.
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
arch/arm/cpu/armv7/mx6/clock.c | 78 ++++++++++++++++++++++++--------
arch/arm/include/asm/arch-mx6/crm_regs.h | 21 +++++++++
2 files changed, 80 insertions(+), 19 deletions(-)
diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
index 644b9d7..e307b28 100644
--- a/arch/arm/cpu/armv7/mx6/clock.c
+++ b/arch/arm/cpu/armv7/mx6/clock.c
@@ -625,16 +625,18 @@ void mxs_set_lcdclk(u32 base_addr, u32 freq)
debug("mxs_set_lcdclk, freq = %dKHz\n", freq);
- if (!is_mx6sx() && !is_mx6ul() && !is_mx6ull()) {
+ if (!is_mx6sx() && !is_mx6ul() && !is_mx6ull() && !is_mx6sl()) {
debug("This chip not support lcd!\n");
return;
}
- if (base_addr == LCDIF1_BASE_ADDR) {
- reg = readl(&imx_ccm->cscdr2);
- /* Can't change clocks when clock not from pre-mux */
- if ((reg & MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK) != 0)
- return;
+ if (!is_mx6sl()) {
+ if (base_addr == LCDIF1_BASE_ADDR) {
+ reg = readl(&imx_ccm->cscdr2);
+ /* Can't change clocks when clock not from pre-mux */
+ if ((reg & MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK) != 0)
+ return;
+ }
}
if (is_mx6sx()) {
@@ -705,19 +707,35 @@ void mxs_set_lcdclk(u32 base_addr, u32 freq)
if (enable_pll_video(pll_div, pll_num, pll_denom, post_div))
return;
- /* Select pre-lcd clock to PLL5 and set pre divider */
- clrsetbits_le32(&imx_ccm->cscdr2,
- MXC_CCM_CSCDR2_LCDIF1_PRED_SEL_MASK |
- MXC_CCM_CSCDR2_LCDIF1_PRE_DIV_MASK,
- (0x2 << MXC_CCM_CSCDR2_LCDIF1_PRED_SEL_OFFSET) |
- ((pred - 1) <<
- MXC_CCM_CSCDR2_LCDIF1_PRE_DIV_OFFSET));
-
- /* Set the post divider */
- clrsetbits_le32(&imx_ccm->cbcmr,
- MXC_CCM_CBCMR_LCDIF1_PODF_MASK,
- ((postd - 1) <<
- MXC_CCM_CBCMR_LCDIF1_PODF_OFFSET));
+ if (!is_mx6sl()) {
+ /* Select pre-lcd clock to PLL5 and set pre divider */
+ clrsetbits_le32(&imx_ccm->cscdr2,
+ MXC_CCM_CSCDR2_LCDIF1_PRED_SEL_MASK |
+ MXC_CCM_CSCDR2_LCDIF1_PRE_DIV_MASK,
+ (0x2 << MXC_CCM_CSCDR2_LCDIF1_PRED_SEL_OFFSET) |
+ ((pred - 1) <<
+ MXC_CCM_CSCDR2_LCDIF1_PRE_DIV_OFFSET));
+
+ /* Set the post divider */
+ clrsetbits_le32(&imx_ccm->cbcmr,
+ MXC_CCM_CBCMR_LCDIF1_PODF_MASK,
+ ((postd - 1) <<
+ MXC_CCM_CBCMR_LCDIF1_PODF_OFFSET));
+ } else {
+ /* Select pre-lcd clock to PLL5 and set pre divider */
+ clrsetbits_le32(&imx_ccm->cscdr2,
+ MXC_CCM_CSCDR2_LCDIF_PIX_CLK_SEL_MASK |
+ MXC_CCM_CSCDR2_LCDIF_PIX_PRE_DIV_MASK,
+ (0x2 << MXC_CCM_CSCDR2_LCDIF_PIX_CLK_SEL_OFFSET) |
+ ((pred - 1) <<
+ MXC_CCM_CSCDR2_LCDIF_PIX_PRE_DIV_OFFSET));
+
+ /* Set the post divider */
+ clrsetbits_le32(&imx_ccm->cscmr1,
+ MXC_CCM_CSCMR1_LCDIF_PIX_PODF_MASK,
+ (((postd - 1)^0x6) <<
+ MXC_CCM_CSCMR1_LCDIF_PIX_PODF_OFFSET));
+ }
} else if (is_mx6sx()) {
/* Setting LCDIF2 for i.MX6SX */
if (enable_pll_video(pll_div, pll_num, pll_denom, post_div))
@@ -767,6 +785,28 @@ int enable_lcdif_clock(u32 base_addr)
/* Set to pre-mux clock at default */
lcdif_clk_sel_mask = MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK;
lcdif_ccgr3_mask = MXC_CCM_CCGR3_LCDIF1_PIX_MASK;
+ } else if (is_mx6sl()) {
+ if (base_addr != LCDIF1_BASE_ADDR) {
+ puts("Wrong LCD interface!\n");
+ return -EINVAL;
+ }
+
+ 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->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);
+
+ return 0;
} else {
return 0;
}
diff --git a/arch/arm/include/asm/arch-mx6/crm_regs.h b/arch/arm/include/asm/arch-mx6/crm_regs.h
index f74737a..7eade7b 100644
--- a/arch/arm/include/asm/arch-mx6/crm_regs.h
+++ b/arch/arm/include/asm/arch-mx6/crm_regs.h
@@ -307,6 +307,9 @@ struct mxc_ccm_reg {
/* LCFIF2_PODF on i.MX6SX */
#define MXC_CCM_CSCMR1_LCDIF2_PODF_MASK (0x7 << 20)
#define MXC_CCM_CSCMR1_LCDIF2_PODF_OFFSET 20
+/* LCDIF_PIX_PODF on i.MX6SL */
+#define MXC_CCM_CSCMR1_LCDIF_PIX_PODF_MASK (0x7 << 20)
+#define MXC_CCM_CSCMR1_LCDIF_PIX_PODF_OFFSET 20
/* ACLK_EMI on i.MX6DQ/SDL/DQP */
#define MXC_CCM_CSCMR1_ACLK_EMI_PODF_MASK (0x7 << 20)
#define MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET 20
@@ -529,6 +532,12 @@ struct mxc_ccm_reg {
#define MXC_CCM_CSCDR2_LCDIF2_CLK_SEL_MASK (0x7 << 0)
#define MXC_CCM_CSCDR2_LCDIF2_CLK_SEL_OFFSET 0
+/*LCD on i.MX6SL */
+#define MXC_CCM_CSCDR2_LCDIF_PIX_CLK_SEL_MASK (0x7 << 6)
+#define MXC_CCM_CSCDR2_LCDIF_PIX_CLK_SEL_OFFSET 6
+#define MXC_CCM_CSCDR2_LCDIF_PIX_PRE_DIV_MASK (0x7 << 3)
+#define MXC_CCM_CSCDR2_LCDIF_PIX_PRE_DIV_OFFSET 3
+
/* All IPU2_DI1 are LCDIF1 on MX6SX */
#define MXC_CCM_CHSCCDR_IPU2_DI1_PRE_CLK_SEL_MASK (0x7 << 15)
#define MXC_CCM_CHSCCDR_IPU2_DI1_PRE_CLK_SEL_OFFSET 15
@@ -554,6 +563,12 @@ struct mxc_ccm_reg {
#define MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_MASK (0x3 << 9)
#define MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_OFFSET 9
+/* For i.MX6SL */
+#define MXC_CCM_CSCDR3_LCDIF_AXI_PODF_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR3_LCDIF_AXI_PODF_OFFSET 16
+#define MXC_CCM_CSCDR3_LCDIF_AXI_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CSCDR3_LCDIF_AXI_CLK_SEL_OFFSET 14
+
/* Define the bits in register CDHIPR */
#define MXC_CCM_CDHIPR_ARM_PODF_BUSY (1 << 16)
#define MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY (1 << 5)
@@ -783,6 +798,12 @@ struct mxc_ccm_reg {
#define MXC_CCM_CCGR3_QSPI_OFFSET 14
#define MXC_CCM_CCGR3_QSPI_MASK (3 << MXC_CCM_CCGR3_QSPI_OFFSET)
+/* i.MX6SL */
+#define MXC_CCM_CCGR3_LCDIF_AXI_OFFSET 6
+#define MXC_CCM_CCGR3_LCDIF_AXI_MASK (3 << MXC_CCM_CCGR3_LCDIF_AXI_OFFSET)
+#define MXC_CCM_CCGR3_LCDIF_PIX_OFFSET 8
+#define MXC_CCM_CCGR3_LCDIF_PIX_MASK (3 << MXC_CCM_CCGR3_LCDIF_PIX_OFFSET)
+
#define MXC_CCM_CCGR3_IPU1_IPU_OFFSET 0
#define MXC_CCM_CCGR3_IPU1_IPU_MASK (3 << MXC_CCM_CCGR3_IPU1_IPU_OFFSET)
#define MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET 2
--
2.6.2
More information about the U-Boot
mailing list