From: Peng Fan <peng....@nxp.com>

Add i.MX8MM clk driver support.

Signed-off-by: Peng Fan <peng....@nxp.com>
---
 arch/arm/mach-imx/imx8m/clock_imx8mm.c | 203 +++++++++++++++++----------------
 drivers/clk/imx/Kconfig                |   2 -
 drivers/clk/imx/Makefile               |   1 +
 drivers/clk/imx/clk-imx8mm.c           | 106 +++++++++++++++++
 4 files changed, 211 insertions(+), 101 deletions(-)
 create mode 100644 drivers/clk/imx/clk-imx8mm.c

diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mm.c 
b/arch/arm/mach-imx/imx8m/clock_imx8mm.c
index 07399023d5..541561f276 100644
--- a/arch/arm/mach-imx/imx8m/clock_imx8mm.c
+++ b/arch/arm/mach-imx/imx8m/clock_imx8mm.c
@@ -119,6 +119,110 @@ void init_wdog_clk(void)
        clock_enable(CCGR_WDOG3, 1);
 }
 
+static int intpll_configure(enum pll_clocks pll, ulong freq)
+{
+       void __iomem *pll_gnrl_ctl, __iomem *pll_div_ctl;
+       u32 pll_div_ctl_val, pll_clke_masks;
+
+       switch (pll) {
+       case ANATOP_SYSTEM_PLL1:
+               pll_gnrl_ctl = &ana_pll->sys_pll1_gnrl_ctl;
+               pll_div_ctl = &ana_pll->sys_pll1_div_ctl;
+               pll_clke_masks = INTPLL_DIV20_CLKE_MASK |
+                       INTPLL_DIV10_CLKE_MASK | INTPLL_DIV8_CLKE_MASK |
+                       INTPLL_DIV6_CLKE_MASK | INTPLL_DIV5_CLKE_MASK |
+                       INTPLL_DIV4_CLKE_MASK | INTPLL_DIV3_CLKE_MASK |
+                       INTPLL_DIV2_CLKE_MASK | INTPLL_CLKE_MASK;
+               break;
+       case ANATOP_SYSTEM_PLL2:
+               pll_gnrl_ctl = &ana_pll->sys_pll2_gnrl_ctl;
+               pll_div_ctl = &ana_pll->sys_pll2_div_ctl;
+               pll_clke_masks = INTPLL_DIV20_CLKE_MASK |
+                       INTPLL_DIV10_CLKE_MASK | INTPLL_DIV8_CLKE_MASK |
+                       INTPLL_DIV6_CLKE_MASK | INTPLL_DIV5_CLKE_MASK |
+                       INTPLL_DIV4_CLKE_MASK | INTPLL_DIV3_CLKE_MASK |
+                       INTPLL_DIV2_CLKE_MASK | INTPLL_CLKE_MASK;
+               break;
+       case ANATOP_SYSTEM_PLL3:
+               pll_gnrl_ctl = &ana_pll->sys_pll3_gnrl_ctl;
+               pll_div_ctl = &ana_pll->sys_pll3_div_ctl;
+               pll_clke_masks = INTPLL_CLKE_MASK;
+               break;
+       case ANATOP_ARM_PLL:
+               pll_gnrl_ctl = &ana_pll->arm_pll_gnrl_ctl;
+               pll_div_ctl = &ana_pll->arm_pll_div_ctl;
+               pll_clke_masks = INTPLL_CLKE_MASK;
+               break;
+       case ANATOP_GPU_PLL:
+               pll_gnrl_ctl = &ana_pll->gpu_pll_gnrl_ctl;
+               pll_div_ctl = &ana_pll->gpu_pll_div_ctl;
+               pll_clke_masks = INTPLL_CLKE_MASK;
+               break;
+       case ANATOP_VPU_PLL:
+               pll_gnrl_ctl = &ana_pll->vpu_pll_gnrl_ctl;
+               pll_div_ctl = &ana_pll->vpu_pll_div_ctl;
+               pll_clke_masks = INTPLL_CLKE_MASK;
+               break;
+       default:
+               return -EINVAL;
+       };
+
+       switch (freq) {
+       case MHZ(600):
+               /* 24 * 0x12c / 3 / 2 ^ 2 */
+               pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0x12c) |
+                       INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(2);
+               break;
+       case MHZ(750):
+               /* 24 * 0xfa / 2 / 2 ^ 2 */
+               pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xfa) |
+                       INTPLL_PRE_DIV_VAL(2) | INTPLL_POST_DIV_VAL(2);
+               break;
+       case MHZ(800):
+               /* 24 * 0x190 / 3 / 2 ^ 2 */
+               pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0x190) |
+                       INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(2);
+               break;
+       case MHZ(1000):
+               /* 24 * 0xfa / 3 / 2 ^ 1 */
+               pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xfa) |
+                       INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(1);
+               break;
+       case MHZ(1200):
+               /* 24 * 0xc8 / 2 / 2 ^ 1 */
+               pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xc8) |
+                       INTPLL_PRE_DIV_VAL(2) | INTPLL_POST_DIV_VAL(1);
+               break;
+       case MHZ(2000):
+               /* 24 * 0xfa / 3 / 2 ^ 0 */
+               pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xfa) |
+                       INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(0);
+               break;
+       default:
+               return -EINVAL;
+       };
+       /* Bypass clock and set lock to pll output lock */
+       setbits_le32(pll_gnrl_ctl, INTPLL_BYPASS_MASK |
+                    INTPLL_LOCK_SEL_MASK);
+       /* Enable reset */
+       clrbits_le32(pll_gnrl_ctl, INTPLL_RST_MASK);
+       /* Configure */
+       writel(pll_div_ctl_val, pll_div_ctl);
+
+       __udelay(100);
+
+       /* Disable reset */
+       setbits_le32(pll_gnrl_ctl, INTPLL_RST_MASK);
+       /* Wait Lock */
+       while (!(readl(pll_gnrl_ctl) & INTPLL_LOCK_MASK))
+               ;
+       /* Clear bypass */
+       clrbits_le32(pll_gnrl_ctl, INTPLL_BYPASS_MASK);
+       setbits_le32(pll_gnrl_ctl, pll_clke_masks);
+
+       return 0;
+}
+
 int clock_init(void)
 {
        u32 val_cfg0;
@@ -467,105 +571,6 @@ int fracpll_configure(enum pll_clocks pll, u32 freq)
        return 0;
 }
 
-int intpll_configure(enum pll_clocks pll, ulong freq)
-{
-       void __iomem *pll_gnrl_ctl, __iomem *pll_div_ctl;
-       u32 pll_div_ctl_val, pll_clke_masks;
-
-       switch (pll) {
-       case ANATOP_SYSTEM_PLL1:
-               pll_gnrl_ctl = &ana_pll->sys_pll1_gnrl_ctl;
-               pll_div_ctl = &ana_pll->sys_pll1_div_ctl;
-               pll_clke_masks = INTPLL_DIV20_CLKE_MASK |
-                       INTPLL_DIV10_CLKE_MASK | INTPLL_DIV8_CLKE_MASK |
-                       INTPLL_DIV6_CLKE_MASK | INTPLL_DIV5_CLKE_MASK |
-                       INTPLL_DIV4_CLKE_MASK | INTPLL_DIV3_CLKE_MASK |
-                       INTPLL_DIV2_CLKE_MASK | INTPLL_CLKE_MASK;
-               break;
-       case ANATOP_SYSTEM_PLL2:
-               pll_gnrl_ctl = &ana_pll->sys_pll2_gnrl_ctl;
-               pll_div_ctl = &ana_pll->sys_pll2_div_ctl;
-               pll_clke_masks = INTPLL_DIV20_CLKE_MASK |
-                       INTPLL_DIV10_CLKE_MASK | INTPLL_DIV8_CLKE_MASK |
-                       INTPLL_DIV6_CLKE_MASK | INTPLL_DIV5_CLKE_MASK |
-                       INTPLL_DIV4_CLKE_MASK | INTPLL_DIV3_CLKE_MASK |
-                       INTPLL_DIV2_CLKE_MASK | INTPLL_CLKE_MASK;
-               break;
-       case ANATOP_SYSTEM_PLL3:
-               pll_gnrl_ctl = &ana_pll->sys_pll3_gnrl_ctl;
-               pll_div_ctl = &ana_pll->sys_pll3_div_ctl;
-               pll_clke_masks = INTPLL_CLKE_MASK;
-               break;
-       case ANATOP_ARM_PLL:
-               pll_gnrl_ctl = &ana_pll->arm_pll_gnrl_ctl;
-               pll_div_ctl = &ana_pll->arm_pll_div_ctl;
-               pll_clke_masks = INTPLL_CLKE_MASK;
-               break;
-       case ANATOP_GPU_PLL:
-               pll_gnrl_ctl = &ana_pll->gpu_pll_gnrl_ctl;
-               pll_div_ctl = &ana_pll->gpu_pll_div_ctl;
-               pll_clke_masks = INTPLL_CLKE_MASK;
-               break;
-       case ANATOP_VPU_PLL:
-               pll_gnrl_ctl = &ana_pll->vpu_pll_gnrl_ctl;
-               pll_div_ctl = &ana_pll->vpu_pll_div_ctl;
-               pll_clke_masks = INTPLL_CLKE_MASK;
-               break;
-       default:
-               return -EINVAL;
-       };
-
-       switch (freq) {
-       case MHZ(750):
-               /* 24 * 0xfa / 2 / 2 ^ 2 */
-               pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xfa) |
-                       INTPLL_PRE_DIV_VAL(2) | INTPLL_POST_DIV_VAL(2);
-               break;
-       case MHZ(800):
-               /* 24 * 0x190 / 3 / 2 ^ 2 */
-               pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0x190) |
-                       INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(2);
-               break;
-       case MHZ(1000):
-               /* 24 * 0xfa / 3 / 2 ^ 1 */
-               pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xfa) |
-                       INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(1);
-               break;
-       case MHZ(1200):
-               /* 24 * 0xc8 / 2 / 2 ^ 1 */
-               pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xc8) |
-                       INTPLL_PRE_DIV_VAL(2) | INTPLL_POST_DIV_VAL(1);
-               break;
-       case MHZ(2000):
-               /* 24 * 0xfa / 3 / 2 ^ 0 */
-               pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xfa) |
-                       INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(0);
-               break;
-       default:
-               return -EINVAL;
-       };
-       /* Bypass clock and set lock to pll output lock */
-       setbits_le32(pll_gnrl_ctl, INTPLL_BYPASS_MASK |
-                    INTPLL_LOCK_SEL_MASK);
-       /* Enable reset */
-       clrbits_le32(pll_gnrl_ctl, INTPLL_RST_MASK);
-       /* Configure */
-       writel(pll_div_ctl_val, pll_div_ctl);
-
-       __udelay(100);
-
-       /* Disable reset */
-       setbits_le32(pll_gnrl_ctl, INTPLL_RST_MASK);
-       /* Wait Lock */
-       while (!(readl(pll_gnrl_ctl) & INTPLL_LOCK_MASK))
-               ;
-       /* Clear bypass */
-       clrbits_le32(pll_gnrl_ctl, INTPLL_BYPASS_MASK);
-       setbits_le32(pll_gnrl_ctl, pll_clke_masks);
-
-       return 0;
-}
-
 u32 get_root_src_clk(enum clk_root_src root_src)
 {
        switch (root_src) {
diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index e8f8b9461e..07ecad0a72 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -9,7 +9,5 @@ config CLK_IMX8MM
        bool "Clock support for i.MX8MM"
        depends on IMX8MM
        select CLK
-       select CLK_CCF
-       select SPL_CLK_CCF
        help
          This enables support clock driver for i.MX8 platforms.
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index eb379c188a..b55566f2e9 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -8,3 +8,4 @@ ifdef CONFIG_CLK_IMX8
 obj-$(CONFIG_IMX8QXP) += clk-imx8qxp.o
 obj-$(CONFIG_IMX8QM) += clk-imx8qm.o
 endif
+obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
new file mode 100644
index 0000000000..1e0669494f
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 NXP
+ * Peng Fan <peng....@nxp.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <asm/arch/clock.h>
+#include <dt-bindings/clock/imx8mm-clock.h>
+
+static ulong imx8mm_clk_get_rate(struct clk *clk)
+{
+       debug("%s(#%lu)\n", __func__, clk->id);
+
+       switch (clk->id) {
+       case IMX8MM_CLK_USDHC1_ROOT:
+               return get_root_clk(USDHC1_CLK_ROOT);
+       case IMX8MM_CLK_USDHC2_ROOT:
+               return get_root_clk(USDHC2_CLK_ROOT);
+       case IMX8MM_CLK_USDHC3_ROOT:
+               return get_root_clk(USDHC3_CLK_ROOT);
+       case IMX8MM_CLK_I2C1:
+               return get_root_clk(I2C1_CLK_ROOT);
+       case IMX8MM_CLK_I2C2:
+               return get_root_clk(I2C2_CLK_ROOT);
+       case IMX8MM_CLK_I2C3:
+               return get_root_clk(I2C3_CLK_ROOT);
+       case IMX8MM_CLK_I2C4:
+               return get_root_clk(I2C4_CLK_ROOT);
+       }
+
+       return 0;
+}
+
+static int __imx8mm_clk_enable(struct clk *clk, bool enable)
+{
+       switch (clk->id) {
+       case IMX8MM_CLK_USDHC1_ROOT:
+               return clock_enable(CCGR_USDHC1, enable);
+       case IMX8MM_CLK_USDHC2_ROOT:
+               return clock_enable(CCGR_USDHC2, enable);
+       case IMX8MM_CLK_USDHC3_ROOT:
+               return clock_enable(CCGR_USDHC3, enable);
+       case IMX8MM_CLK_I2C1:
+               return clock_enable(CCGR_I2C1, enable);
+       case IMX8MM_CLK_I2C2:
+               return clock_enable(CCGR_I2C2, enable);
+       case IMX8MM_CLK_I2C3:
+               return clock_enable(CCGR_I2C3, enable);
+       case IMX8MM_CLK_I2C4:
+               return clock_enable(CCGR_I2C4, enable);
+       }
+
+       return -EINVAL;
+}
+
+static int imx8mm_clk_disable(struct clk *clk)
+{
+       debug("%s(#%lu)\n", __func__, clk->id);
+
+       return __imx8mm_clk_enable(clk, false);
+}
+
+static int imx8mm_clk_enable(struct clk *clk)
+{
+       debug("%s(#%lu)\n", __func__, clk->id);
+
+       return __imx8mm_clk_enable(clk, true);
+}
+
+static ulong imx8mm_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       debug("%s(#%lu)\n", __func__, clk->id);
+
+       /* TODO: */
+
+       return imx8mm_clk_get_rate(clk);
+}
+
+static struct clk_ops imx8mm_clk_ops = {
+       .set_rate = imx8mm_clk_set_rate,
+       .get_rate = imx8mm_clk_get_rate,
+       .enable = imx8mm_clk_enable,
+       .disable = imx8mm_clk_disable,
+};
+
+static int imx8mm_clk_probe(struct udevice *dev)
+{
+       return 0;
+}
+
+static const struct udevice_id imx8mm_clk_ids[] = {
+       { .compatible = "fsl,imx8mm-ccm" },
+       { },
+};
+
+U_BOOT_DRIVER(imx8mm_clk) = {
+       .name = "clk_imx8mm",
+       .id = UCLASS_CLK,
+       .of_match = imx8mm_clk_ids,
+       .ops = &imx8mm_clk_ops,
+       .probe = imx8mm_clk_probe,
+       .flags = DM_FLAG_PRE_RELOC,
+};
-- 
2.16.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to