imx: mx6sl: add lcdif clock support
authorPeng Fan <peng.fan@nxp.com>
Sun, 11 Dec 2016 11:24:27 +0000 (19:24 +0800)
committerStefano Babic <sbabic@denx.de>
Fri, 16 Dec 2016 10:38:24 +0000 (11:38 +0100)
Add lcdif clock support for i.MX6SL.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
arch/arm/cpu/armv7/mx6/clock.c
arch/arm/include/asm/arch-mx6/crm_regs.h

index 20922606e0884e385cdf3b5371e5bd9d984d8fff..007c135fd1d53e897af9f97865c65ecd5a119cd4 100644 (file)
@@ -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;
        }
index 29674ce54d82b4dfa4125355c9f22303d380cc0d..74ed91230f57bdec18394e23411cb3ca1ee96f5d 100644 (file)
@@ -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