* [PATCH 1/3] clk: imx: Add PLLs driver for imx8mm soc
@ 2019-01-08 9:00 Jacky Bai
2019-01-08 9:00 ` [PATCH 2/3] dt-bindings: imx: Add clock binding doc for imx8mm Jacky Bai
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Jacky Bai @ 2019-01-08 9:00 UTC (permalink / raw)
To: sboyd, mturquette, robh+dt, shawnguo
Cc: Fabio Estevam, Aisheng Dong, dl-linux-imx, linux-clk, devicetree
New PLLs are introduced on i.MX8M Mini SOC.
PLL1416X is Integer PLL, PLL1443X is a Frac PLL.
Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
drivers/clk/imx/Makefile | 3 +-
drivers/clk/imx/clk-pll14xx.c | 409 ++++++++++++++++++++++++++++++++++++++++++
drivers/clk/imx/clk.h | 23 +++
3 files changed, 434 insertions(+), 1 deletion(-)
create mode 100644 drivers/clk/imx/clk-pll14xx.c
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 73119fb..ff74287 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -18,7 +18,8 @@ obj-$(CONFIG_MXC_CLK) += \
clk-pllv2.o \
clk-pllv3.o \
clk-pllv4.o \
- clk-sccg-pll.o
+ clk-sccg-pll.o \
+ clk-pll14xx.o
obj-$(CONFIG_MXC_CLK_SCU) += \
clk-scu.o \
diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
new file mode 100644
index 0000000..c9f83fd
--- /dev/null
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -0,0 +1,409 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2017-2018 NXP.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+
+#include "clk.h"
+
+#define GNRL_CTL 0x0
+#define DIV_CTL 0x4
+#define LOCK_STATUS BIT(31)
+#define LOCK_SEL_MASK BIT(29)
+#define CLKE_MASK BIT(11)
+#define RST_MASK BIT(9)
+#define BYPASS_MASK BIT(4)
+#define MDIV_SHIFT 12
+#define MDIV_MASK GENMASK(21, 12)
+#define PDIV_SHIFT 4
+#define PDIV_MASK GENMASK(9, 4)
+#define SDIV_SHIFT 0
+#define SDIV_MASK GENMASK(2, 0)
+#define KDIV_SHIFT 0
+#define KDIV_MASK GENMASK(15, 0)
+
+struct clk_pll14xx {
+ struct clk_hw hw;
+ void __iomem *base;
+ enum imx_pll14xx_type type;
+ struct imx_pll14xx_rate_table *rate_table;
+ int rate_count;
+};
+
+#define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
+
+static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
+ struct clk_pll14xx *pll, unsigned long rate)
+{
+ const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
+ int i;
+
+ for (i = 0; i < pll->rate_count; i++) {
+ if (rate == rate_table[i].rate)
+ return &rate_table[i];
+ }
+
+ return NULL;
+}
+
+static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+ const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
+ int i;
+
+ /* Assumming rate_table is in descending order */
+ for (i = 0; i < pll->rate_count; i++) {
+ if (rate >= rate_table[i].rate)
+ return rate_table[i].rate;
+ }
+ /* return minimum supported value */
+ return rate_table[i - 1].rate;
+}
+
+static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+ u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div;
+ u64 fvco = parent_rate;
+
+ pll_gnrl = readl_relaxed(pll->base);
+ pll_div = readl_relaxed(pll->base + 4);
+ mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
+ pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
+ sdiv = (pll_div & SDIV_MASK) >> SDIV_SHIFT;
+
+ fvco *= mdiv;
+ do_div(fvco, pdiv << sdiv);
+
+ return (unsigned long)fvco;
+}
+
+static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+ u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div_ctl0, pll_div_ctl1;
+ short int kdiv;
+ u64 fvco = parent_rate;
+
+ pll_gnrl = readl_relaxed(pll->base);
+ pll_div_ctl0 = readl_relaxed(pll->base + 4);
+ pll_div_ctl1 = readl_relaxed(pll->base + 8);
+ mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT;
+ pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT;
+ sdiv = (pll_div_ctl0 & SDIV_MASK) >> SDIV_SHIFT;
+ kdiv = pll_div_ctl1 & KDIV_MASK;
+
+ /* fvco = (m * 65536 + k) * Fin / (p * 65536) */
+ fvco *= (mdiv * 65536 + kdiv);
+ pdiv *= 65536;
+
+ do_div(fvco, pdiv << sdiv);
+
+ return (unsigned long)fvco;
+}
+
+static inline bool clk_pll1416x_mp_change(const struct imx_pll14xx_rate_table *rate,
+ u32 pll_div)
+{
+ u32 old_mdiv, old_pdiv;
+
+ old_mdiv = (pll_div >> MDIV_SHIFT) & MDIV_MASK;
+ old_pdiv = (pll_div >> PDIV_SHIFT) & PDIV_MASK;
+
+ return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
+}
+
+static inline bool clk_pll1443x_mpk_change(const struct imx_pll14xx_rate_table *rate,
+ u32 pll_div_ctl0, u32 pll_div_ctl1)
+{
+ u32 old_mdiv, old_pdiv, old_kdiv;
+
+ old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
+ old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
+ old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
+
+ return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
+ rate->kdiv != old_kdiv);
+}
+
+static inline bool clk_pll1443x_mp_change(const struct imx_pll14xx_rate_table *rate,
+ u32 pll_div_ctl0, u32 pll_div_ctl1)
+{
+ u32 old_mdiv, old_pdiv, old_kdiv;
+
+ old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
+ old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
+ old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
+
+ return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
+ rate->kdiv != old_kdiv);
+}
+
+static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(10);
+
+ /* Wait for PLL to lock */
+ do {
+ if (readl_relaxed(pll->base) & LOCK_STATUS)
+ break;
+ if (time_after(jiffies, timeout))
+ break;
+ } while (1);
+
+ return readl_relaxed(pll->base) & LOCK_STATUS ? 0 : -ETIMEDOUT;
+}
+
+static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,
+ unsigned long prate)
+{
+ struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+ const struct imx_pll14xx_rate_table *rate;
+ u32 tmp, div_val;
+ int ret;
+
+ rate = imx_get_pll_settings(pll, drate);
+ if (!rate) {
+ pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+ drate, clk_hw_get_name(hw));
+ return -EINVAL;
+ }
+
+ tmp = readl_relaxed(pll->base + 4);
+
+ if (!clk_pll1416x_mp_change(rate, tmp)) {
+ tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
+ tmp |= rate->sdiv << SDIV_SHIFT;
+ writel_relaxed(tmp, pll->base + 4);
+
+ return 0;
+ }
+
+ /* Bypass clock and set lock to pll output lock */
+ tmp = readl_relaxed(pll->base);
+ tmp |= LOCK_SEL_MASK;
+ writel_relaxed(tmp, pll->base);
+
+ /* Enable RST */
+ tmp &= ~RST_MASK;
+ writel_relaxed(tmp, pll->base);
+
+ div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
+ (rate->sdiv << SDIV_SHIFT);
+ writel_relaxed(div_val, pll->base + 0x4);
+
+ /*
+ * According to SPEC, t3 - t2 need to be greater than
+ * 1us and 1/FREF, respectively.
+ * FREF is FIN / Prediv, the prediv is [1, 63], so choose
+ * 3us.
+ */
+ udelay(3);
+
+ /* Disable RST */
+ tmp |= RST_MASK;
+ writel_relaxed(tmp, pll->base);
+
+ /* Wait Lock */
+ ret = clk_pll14xx_wait_lock(pll);
+ if (ret)
+ return ret;
+
+ /* Bypass */
+ tmp &= ~BYPASS_MASK;
+ writel_relaxed(tmp, pll->base);
+
+ return 0;
+}
+
+static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
+ unsigned long prate)
+{
+ struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+ const struct imx_pll14xx_rate_table *rate;
+ u32 tmp, div_val;
+ int ret;
+
+ rate = imx_get_pll_settings(pll, drate);
+ if (!rate) {
+ pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+ drate, clk_hw_get_name(hw));
+ return -EINVAL;
+ }
+
+ tmp = readl_relaxed(pll->base + 4);
+ div_val = readl_relaxed(pll->base + 8);
+
+ if (!clk_pll1443x_mpk_change(rate, tmp, div_val)) {
+ tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
+ tmp |= rate->sdiv << SDIV_SHIFT;
+ writel_relaxed(tmp, pll->base + 4);
+
+ return 0;
+ }
+
+ /* Enable RST */
+ tmp = readl_relaxed(pll->base);
+ tmp &= ~RST_MASK;
+ writel_relaxed(tmp, pll->base);
+
+ div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
+ (rate->sdiv << SDIV_SHIFT);
+ writel_relaxed(div_val, pll->base + 0x4);
+ writel_relaxed(rate->kdiv << KDIV_SHIFT, pll->base + 0x8);
+
+ /*
+ * According to SPEC, t3 - t2 need to be greater than
+ * 1us and 1/FREF, respectively.
+ * FREF is FIN / Prediv, the prediv is [1, 63], so choose
+ * 3us.
+ */
+ udelay(3);
+
+ /* Disable RST */
+ tmp |= RST_MASK;
+ writel_relaxed(tmp, pll->base);
+
+ /* Wait Lock*/
+ ret = clk_pll14xx_wait_lock(pll);
+ if (ret)
+ return ret;
+
+ /* Bypass */
+ tmp &= ~BYPASS_MASK;
+ writel_relaxed(tmp, pll->base);
+
+ return 0;
+}
+
+static int clk_pll14xx_prepare(struct clk_hw *hw)
+{
+ struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+ u32 val;
+
+ /*
+ * RESETB = 1 from 0, PLL starts its normal
+ * operation after lock time
+ */
+ val = readl_relaxed(pll->base + GNRL_CTL);
+ val |= RST_MASK;
+ writel_relaxed(val, pll->base + GNRL_CTL);
+
+ return clk_pll14xx_wait_lock(pll);
+}
+
+static int clk_pll14xx_is_prepared(struct clk_hw *hw)
+{
+ struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+ u32 val;
+
+ val = readl_relaxed(pll->base + GNRL_CTL);
+
+ return (val & RST_MASK) ? 1 : 0;
+}
+
+static void clk_pll14xx_unprepare(struct clk_hw *hw)
+{
+ struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+ u32 val;
+
+ /*
+ * Set RST to 0, power down mode is enabled and
+ * every digital block is reset
+ */
+ val = readl_relaxed(pll->base + GNRL_CTL);
+ val &= ~RST_MASK;
+ writel_relaxed(val, pll->base + GNRL_CTL);
+}
+
+static const struct clk_ops clk_pll1416x_ops = {
+ .prepare = clk_pll14xx_prepare,
+ .unprepare = clk_pll14xx_unprepare,
+ .is_prepared = clk_pll14xx_is_prepared,
+ .recalc_rate = clk_pll1416x_recalc_rate,
+ .round_rate = clk_pll14xx_round_rate,
+ .set_rate = clk_pll1416x_set_rate,
+};
+
+static const struct clk_ops clk_pll1416x_min_ops = {
+ .recalc_rate = clk_pll1416x_recalc_rate,
+};
+
+static const struct clk_ops clk_pll1443x_ops = {
+ .prepare = clk_pll14xx_prepare,
+ .unprepare = clk_pll14xx_unprepare,
+ .is_prepared = clk_pll14xx_is_prepared,
+ .recalc_rate = clk_pll1443x_recalc_rate,
+ .round_rate = clk_pll14xx_round_rate,
+ .set_rate = clk_pll1443x_set_rate,
+};
+
+struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
+ void __iomem *base,
+ const struct imx_pll14xx_clk *pll_clk)
+{
+ struct clk_pll14xx *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+ int len;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.flags = pll_clk->flags;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ if (pll_clk->rate_table) {
+ for (len = 0; pll_clk->rate_table[len].rate != 0; )
+ len++;
+
+ pll->rate_count = len;
+ pll->rate_table = kmemdup(pll_clk->rate_table,
+ pll->rate_count *
+ sizeof(struct imx_pll14xx_rate_table),
+ GFP_KERNEL);
+ WARN(!pll->rate_table, "%s : could not alloc rate table\n", __func__);
+ }
+
+ switch (pll_clk->type) {
+ case PLL_1416X:
+ if (!pll->rate_table)
+ init.ops = &clk_pll1416x_min_ops;
+ else
+ init.ops = &clk_pll1416x_ops;
+ break;
+ case PLL_1443X:
+ init.ops = &clk_pll1443x_ops;
+ break;
+ default:
+ pr_err("%s: Unknown pll type for pll clk %s\n",
+ __func__, name);
+ };
+
+ pll->base = base;
+ pll->hw.init = &init;
+ pll->type = pll_clk->type;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register pll %s %lu\n",
+ __func__, name, PTR_ERR(clk));
+ kfree(pll);
+ }
+
+ return clk;
+}
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 028312d..27372f7 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -27,6 +27,29 @@ enum imx_sccg_pll_type {
SCCG_PLL2,
};
+enum imx_pll14xx_type {
+ PLL_1416X,
+ PLL_1443X,
+};
+
+/* NOTE: Rate table should be kept sorted in descending order. */
+struct imx_pll14xx_rate_table {
+ unsigned int rate;
+ unsigned int pdiv;
+ unsigned int mdiv;
+ unsigned int sdiv;
+ unsigned int kdiv;
+};
+
+struct imx_pll14xx_clk {
+ enum imx_pll14xx_type type;
+ const struct imx_pll14xx_rate_table *rate_table;
+ int flags;
+};
+
+struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
+ void __iomem *base, const struct imx_pll14xx_clk *pll_clk);
+
struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
const char *parent, void __iomem *base);
--
1.9.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/3] dt-bindings: imx: Add clock binding doc for imx8mm
2019-01-08 9:00 [PATCH 1/3] clk: imx: Add PLLs driver for imx8mm soc Jacky Bai
@ 2019-01-08 9:00 ` Jacky Bai
2019-01-09 20:36 ` Stephen Boyd
2019-01-21 20:33 ` Rob Herring
2019-01-08 9:01 ` [PATCH 3/3] clk: imx: Add clock driver support " Jacky Bai
2019-01-09 20:35 ` [PATCH 1/3] clk: imx: Add PLLs driver for imx8mm soc Stephen Boyd
2 siblings, 2 replies; 10+ messages in thread
From: Jacky Bai @ 2019-01-08 9:00 UTC (permalink / raw)
To: sboyd, mturquette, robh+dt, shawnguo
Cc: Fabio Estevam, Aisheng Dong, dl-linux-imx, linux-clk, devicetree
Add the clock binding doc for i.MX8MM.
Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
.../devicetree/bindings/clock/imx8mm-clock.txt | 19 ++
include/dt-bindings/clock/imx8mm-clock.h | 244 +++++++++++++++++++++
2 files changed, 263 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/imx8mm-clock.txt
create mode 100644 include/dt-bindings/clock/imx8mm-clock.h
diff --git a/Documentation/devicetree/bindings/clock/imx8mm-clock.txt b/Documentation/devicetree/bindings/clock/imx8mm-clock.txt
new file mode 100644
index 0000000..034b6d4
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx8mm-clock.txt
@@ -0,0 +1,19 @@
+* Clock bindings for NXP i.MX8M Mini
+
+Required properties:
+- compatible: Should be "fsl,imx8mm-ccm"
+- reg: Address and length of the register set
+- #clock-cells: Should be <1>
+- clocks: list of clock specifiers, must contain an entry for each required
+ entry in clock-names
+- clock-names: should include the following entries:
+ - "osc_32k"
+ - "osc_24m"
+ - "clk_ext1"
+ - "clk_ext2"
+ - "clk_ext3"
+ - "clk_ext4"
+
+The clock consumer should specify the desired clock by having the clock
+ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8mm-clock.h
+for the full list of i.MX8M Mini clock IDs.
diff --git a/include/dt-bindings/clock/imx8mm-clock.h b/include/dt-bindings/clock/imx8mm-clock.h
new file mode 100644
index 0000000..0301581
--- /dev/null
+++ b/include/dt-bindings/clock/imx8mm-clock.h
@@ -0,0 +1,244 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2017-2018 NXP
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMX8MM_H
+#define __DT_BINDINGS_CLOCK_IMX8MM_H
+
+#define IMX8MM_CLK_DUMMY 0
+#define IMX8MM_CLK_32K 1
+#define IMX8MM_CLK_24M 2
+#define IMX8MM_OSC_HDMI_CLK 3
+#define IMX8MM_CLK_EXT1 4
+#define IMX8MM_CLK_EXT2 5
+#define IMX8MM_CLK_EXT3 6
+#define IMX8MM_CLK_EXT4 7
+#define IMX8MM_AUDIO_PLL1_REF_SEL 8
+#define IMX8MM_AUDIO_PLL2_REF_SEL 9
+#define IMX8MM_VIDEO_PLL1_REF_SEL 10
+#define IMX8MM_DRAM_PLL_REF_SEL 11
+#define IMX8MM_GPU_PLL_REF_SEL 12
+#define IMX8MM_VPU_PLL_REF_SEL 13
+#define IMX8MM_ARM_PLL_REF_SEL 14
+#define IMX8MM_SYS_PLL1_REF_SEL 15
+#define IMX8MM_SYS_PLL2_REF_SEL 16
+#define IMX8MM_SYS_PLL3_REF_SEL 17
+#define IMX8MM_AUDIO_PLL1 18
+#define IMX8MM_AUDIO_PLL2 19
+#define IMX8MM_VIDEO_PLL1 20
+#define IMX8MM_DRAM_PLL 21
+#define IMX8MM_GPU_PLL 22
+#define IMX8MM_VPU_PLL 23
+#define IMX8MM_ARM_PLL 24
+#define IMX8MM_SYS_PLL1 25
+#define IMX8MM_SYS_PLL2 26
+#define IMX8MM_SYS_PLL3 27
+#define IMX8MM_AUDIO_PLL1_BYPASS 28
+#define IMX8MM_AUDIO_PLL2_BYPASS 29
+#define IMX8MM_VIDEO_PLL1_BYPASS 30
+#define IMX8MM_DRAM_PLL_BYPASS 31
+#define IMX8MM_GPU_PLL_BYPASS 32
+#define IMX8MM_VPU_PLL_BYPASS 33
+#define IMX8MM_ARM_PLL_BYPASS 34
+#define IMX8MM_SYS_PLL1_BYPASS 35
+#define IMX8MM_SYS_PLL2_BYPASS 36
+#define IMX8MM_SYS_PLL3_BYPASS 37
+#define IMX8MM_AUDIO_PLL1_OUT 38
+#define IMX8MM_AUDIO_PLL2_OUT 39
+#define IMX8MM_VIDEO_PLL1_OUT 40
+#define IMX8MM_DRAM_PLL_OUT 41
+#define IMX8MM_GPU_PLL_OUT 42
+#define IMX8MM_VPU_PLL_OUT 43
+#define IMX8MM_ARM_PLL_OUT 44
+#define IMX8MM_SYS_PLL1_OUT 45
+#define IMX8MM_SYS_PLL2_OUT 46
+#define IMX8MM_SYS_PLL3_OUT 47
+#define IMX8MM_SYS_PLL1_40M 48
+#define IMX8MM_SYS_PLL1_80M 49
+#define IMX8MM_SYS_PLL1_100M 50
+#define IMX8MM_SYS_PLL1_133M 51
+#define IMX8MM_SYS_PLL1_160M 52
+#define IMX8MM_SYS_PLL1_200M 53
+#define IMX8MM_SYS_PLL1_266M 54
+#define IMX8MM_SYS_PLL1_400M 55
+#define IMX8MM_SYS_PLL1_800M 56
+#define IMX8MM_SYS_PLL2_50M 57
+#define IMX8MM_SYS_PLL2_100M 58
+#define IMX8MM_SYS_PLL2_125M 59
+#define IMX8MM_SYS_PLL2_166M 60
+#define IMX8MM_SYS_PLL2_200M 61
+#define IMX8MM_SYS_PLL2_250M 62
+#define IMX8MM_SYS_PLL2_333M 63
+#define IMX8MM_SYS_PLL2_500M 64
+#define IMX8MM_SYS_PLL2_1000M 65
+
+/* core */
+#define IMX8MM_CLK_A53_SRC 66
+#define IMX8MM_CLK_M4_SRC 67
+#define IMX8MM_CLK_VPU_SRC 68
+#define IMX8MM_CLK_GPU3D_SRC 69
+#define IMX8MM_CLK_GPU2D_SRC 70
+#define IMX8MM_CLK_A53_CG 71
+#define IMX8MM_CLK_M4_CG 72
+#define IMX8MM_CLK_VPU_CG 73
+#define IMX8MM_CLK_GPU3D_CG 74
+#define IMX8MM_CLK_GPU2D_CG 75
+#define IMX8MM_CLK_A53_DIV 76
+#define IMX8MM_CLK_M4_DIV 77
+#define IMX8MM_CLK_VPU_DIV 78
+#define IMX8MM_CLK_GPU3D_DIV 79
+#define IMX8MM_CLK_GPU2D_DIV 80
+
+/* bus */
+#define IMX8MM_CLK_MAIN_AXI 81
+#define IMX8MM_CLK_ENET_AXI 82
+#define IMX8MM_CLK_NAND_USDHC_BUS 83
+#define IMX8MM_CLK_VPU_BUS 84
+#define IMX8MM_CLK_DISP_AXI 85
+#define IMX8MM_CLK_DISP_APB 86
+#define IMX8MM_CLK_DISP_RTRM 87
+#define IMX8MM_CLK_USB_BUS 88
+#define IMX8MM_CLK_GPU_AXI 89
+#define IMX8MM_CLK_GPU_AHB 90
+#define IMX8MM_CLK_NOC 91
+#define IMX8MM_CLK_NOC_APB 92
+
+#define IMX8MM_CLK_AHB 93
+#define IMX8MM_CLK_AUDIO_AHB 94
+#define IMX8MM_CLK_IPG_ROOT 95
+#define IMX8MM_CLK_IPG_AUDIO_ROOT 96
+
+#define IMX8MM_CLK_DRAM_ALT 97
+#define IMX8MM_CLK_DRAM_APB 98
+#define IMX8MM_CLK_VPU_G1 99
+#define IMX8MM_CLK_VPU_G2 100
+#define IMX8MM_CLK_DISP_DTRC 101
+#define IMX8MM_CLK_DISP_DC8000 102
+#define IMX8MM_CLK_PCIE1_CTRL 103
+#define IMX8MM_CLK_PCIE1_PHY 104
+#define IMX8MM_CLK_PCIE1_AUX 105
+#define IMX8MM_CLK_DC_PIXEL 106
+#define IMX8MM_CLK_LCDIF_PIXEL 107
+#define IMX8MM_CLK_SAI1 108
+#define IMX8MM_CLK_SAI2 109
+#define IMX8MM_CLK_SAI3 110
+#define IMX8MM_CLK_SAI4 111
+#define IMX8MM_CLK_SAI5 112
+#define IMX8MM_CLK_SAI6 113
+#define IMX8MM_CLK_SPDIF1 114
+#define IMX8MM_CLK_SPDIF2 115
+#define IMX8MM_CLK_ENET_REF 116
+#define IMX8MM_CLK_ENET_TIMER 117
+#define IMX8MM_CLK_ENET_PHY_REF 118
+#define IMX8MM_CLK_NAND 119
+#define IMX8MM_CLK_QSPI 120
+#define IMX8MM_CLK_USDHC1 121
+#define IMX8MM_CLK_USDHC2 122
+#define IMX8MM_CLK_I2C1 123
+#define IMX8MM_CLK_I2C2 124
+#define IMX8MM_CLK_I2C3 125
+#define IMX8MM_CLK_I2C4 126
+#define IMX8MM_CLK_UART1 127
+#define IMX8MM_CLK_UART2 128
+#define IMX8MM_CLK_UART3 129
+#define IMX8MM_CLK_UART4 130
+#define IMX8MM_CLK_USB_CORE_REF 131
+#define IMX8MM_CLK_USB_PHY_REF 132
+#define IMX8MM_CLK_ECSPI1 133
+#define IMX8MM_CLK_ECSPI2 134
+#define IMX8MM_CLK_PWM1 135
+#define IMX8MM_CLK_PWM2 136
+#define IMX8MM_CLK_PWM3 137
+#define IMX8MM_CLK_PWM4 138
+#define IMX8MM_CLK_GPT1 139
+#define IMX8MM_CLK_WDOG 140
+#define IMX8MM_CLK_WRCLK 141
+#define IMX8MM_CLK_DSI_CORE 142
+#define IMX8MM_CLK_DSI_PHY_REF 143
+#define IMX8MM_CLK_DSI_DBI 144
+#define IMX8MM_CLK_USDHC3 145
+#define IMX8MM_CLK_CSI1_CORE 146
+#define IMX8MM_CLK_CSI1_PHY_REF 147
+#define IMX8MM_CLK_CSI1_ESC 148
+#define IMX8MM_CLK_CSI2_CORE 149
+#define IMX8MM_CLK_CSI2_PHY_REF 150
+#define IMX8MM_CLK_CSI2_ESC 151
+#define IMX8MM_CLK_PCIE2_CTRL 152
+#define IMX8MM_CLK_PCIE2_PHY 153
+#define IMX8MM_CLK_PCIE2_AUX 154
+#define IMX8MM_CLK_ECSPI3 155
+#define IMX8MM_CLK_PDM 156
+#define IMX8MM_CLK_VPU_H1 157
+#define IMX8MM_CLK_CLKO1 158
+
+#define IMX8MM_CLK_ECSPI1_ROOT 159
+#define IMX8MM_CLK_ECSPI2_ROOT 160
+#define IMX8MM_CLK_ECSPI3_ROOT 161
+#define IMX8MM_CLK_ENET1_ROOT 162
+#define IMX8MM_CLK_GPT1_ROOT 163
+#define IMX8MM_CLK_I2C1_ROOT 164
+#define IMX8MM_CLK_I2C2_ROOT 165
+#define IMX8MM_CLK_I2C3_ROOT 166
+#define IMX8MM_CLK_I2C4_ROOT 167
+#define IMX8MM_CLK_OCOTP_ROOT 168
+#define IMX8MM_CLK_PCIE1_ROOT 169
+#define IMX8MM_CLK_PWM1_ROOT 170
+#define IMX8MM_CLK_PWM2_ROOT 171
+#define IMX8MM_CLK_PWM3_ROOT 172
+#define IMX8MM_CLK_PWM4_ROOT 173
+#define IMX8MM_CLK_QSPI_ROOT 174
+#define IMX8MM_CLK_NAND_ROOT 175
+#define IMX8MM_CLK_SAI1_ROOT 176
+#define IMX8MM_CLK_SAI1_IPG 177
+#define IMX8MM_CLK_SAI2_ROOT 178
+#define IMX8MM_CLK_SAI2_IPG 179
+#define IMX8MM_CLK_SAI3_ROOT 180
+#define IMX8MM_CLK_SAI3_IPG 181
+#define IMX8MM_CLK_SAI4_ROOT 182
+#define IMX8MM_CLK_SAI4_IPG 183
+#define IMX8MM_CLK_SAI5_ROOT 184
+#define IMX8MM_CLK_SAI5_IPG 185
+#define IMX8MM_CLK_SAI6_ROOT 186
+#define IMX8MM_CLK_SAI6_IPG 187
+#define IMX8MM_CLK_UART1_ROOT 188
+#define IMX8MM_CLK_UART2_ROOT 189
+#define IMX8MM_CLK_UART3_ROOT 190
+#define IMX8MM_CLK_UART4_ROOT 191
+#define IMX8MM_CLK_USB1_CTRL_ROOT 192
+#define IMX8MM_CLK_GPU3D_ROOT 193
+#define IMX8MM_CLK_USDHC1_ROOT 194
+#define IMX8MM_CLK_USDHC2_ROOT 195
+#define IMX8MM_CLK_WDOG1_ROOT 196
+#define IMX8MM_CLK_WDOG2_ROOT 197
+#define IMX8MM_CLK_WDOG3_ROOT 198
+#define IMX8MM_CLK_VPU_G1_ROOT 199
+#define IMX8MM_CLK_GPU_BUS_ROOT 200
+#define IMX8MM_CLK_VPU_H1_ROOT 201
+#define IMX8MM_CLK_VPU_G2_ROOT 202
+#define IMX8MM_CLK_PDM_ROOT 203
+#define IMX8MM_CLK_DISP_ROOT 204
+#define IMX8MM_CLK_DISP_AXI_ROOT 205
+#define IMX8MM_CLK_DISP_APB_ROOT 206
+#define IMX8MM_CLK_DISP_RTRM_ROOT 207
+#define IMX8MM_CLK_USDHC3_ROOT 208
+#define IMX8MM_CLK_TMU_ROOT 209
+#define IMX8MM_CLK_VPU_DEC_ROOT 210
+#define IMX8MM_CLK_SDMA1_ROOT 211
+#define IMX8MM_CLK_SDMA2_ROOT 212
+#define IMX8MM_CLK_SDMA3_ROOT 213
+#define IMX8MM_CLK_GPT_3M 214
+#define IMX8MM_CLK_ARM 215
+#define IMX8MM_CLK_PDM_IPG 216
+#define IMX8MM_CLK_GPU2D_ROOT 217
+#define IMX8MM_CLK_MU_ROOT 218
+#define IMX8MM_CLK_CSI1_ROOT 219
+
+#define IMX8MM_CLK_DRAM_CORE 220
+#define IMX8MM_CLK_DRAM_ALT_ROOT 221
+
+#define IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK 222
+
+#define IMX8MM_CLK_END 223
+
+#endif
--
1.9.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3] clk: imx: Add clock driver support for imx8mm
2019-01-08 9:00 [PATCH 1/3] clk: imx: Add PLLs driver for imx8mm soc Jacky Bai
2019-01-08 9:00 ` [PATCH 2/3] dt-bindings: imx: Add clock binding doc for imx8mm Jacky Bai
@ 2019-01-08 9:01 ` Jacky Bai
2019-01-09 20:32 ` Stephen Boyd
2019-01-09 20:35 ` [PATCH 1/3] clk: imx: Add PLLs driver for imx8mm soc Stephen Boyd
2 siblings, 1 reply; 10+ messages in thread
From: Jacky Bai @ 2019-01-08 9:01 UTC (permalink / raw)
To: sboyd, mturquette, robh+dt, shawnguo
Cc: Fabio Estevam, Aisheng Dong, dl-linux-imx, linux-clk, devicetree
Add clock driver support for i.MX8MM SOC.
Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
drivers/clk/imx/Kconfig | 6 +
drivers/clk/imx/Makefile | 1 +
drivers/clk/imx/clk-imx8mm.c | 686 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 693 insertions(+)
create mode 100644 drivers/clk/imx/clk-imx8mm.c
diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index 4aae31a..0eaf418 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -8,6 +8,12 @@ config MXC_CLK_SCU
bool
depends on IMX_SCU
+config CLK_IMX8MM
+ bool "IMX8MM CCM Clock Driver"
+ depends on ARCH_MXC && ARM64
+ help
+ Build the driver for i.MX8MM CCM Clock Driver
+
config CLK_IMX8MQ
bool "IMX8MQ CCM Clock Driver"
depends on ARCH_MXC && ARM64
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index ff74287..0d5180f 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
clk-scu.o \
clk-lpcg-scu.o
+obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
new file mode 100644
index 0000000..7cd9e86
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -0,0 +1,686 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2017-2018 NXP.
+ */
+
+#include <dt-bindings/clock/imx8mm-clock.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#include "clk.h"
+
+static u32 share_count_sai1;
+static u32 share_count_sai2;
+static u32 share_count_sai3;
+static u32 share_count_sai4;
+static u32 share_count_sai5;
+static u32 share_count_sai6;
+static u32 share_count_dcss;
+static u32 share_count_pdm;
+static u32 share_count_nand;
+
+#define PLL_1416X_RATE(_rate, _m, _p, _s) \
+ { \
+ .rate = (_rate), \
+ .mdiv = (_m), \
+ .pdiv = (_p), \
+ .sdiv = (_s), \
+ }
+
+#define PLL_1443X_RATE(_rate, _m, _p, _s, _k) \
+ { \
+ .rate = (_rate), \
+ .mdiv = (_m), \
+ .pdiv = (_p), \
+ .sdiv = (_s), \
+ .kdiv = (_k), \
+ }
+
+static const struct imx_pll14xx_rate_table imx8mm_pll1416x_tbl[] = {
+ PLL_1416X_RATE(1800000000U, 225, 3, 0),
+ PLL_1416X_RATE(1600000000U, 200, 3, 0),
+ PLL_1416X_RATE(1200000000U, 300, 3, 1),
+ PLL_1416X_RATE(1000000000U, 250, 3, 1),
+ PLL_1416X_RATE(800000000U, 200, 3, 1),
+ PLL_1416X_RATE(750000000U, 250, 2, 2),
+ PLL_1416X_RATE(700000000U, 350, 3, 2),
+ PLL_1416X_RATE(600000000U, 300, 3, 2),
+};
+
+static const struct imx_pll14xx_rate_table imx8mm_audiopll_tbl[] = {
+ PLL_1443X_RATE(786432000U, 655, 5, 2, 23593),
+ PLL_1443X_RATE(722534400U, 301, 5, 1, 3670),
+};
+
+static const struct imx_pll14xx_rate_table imx8mm_videopll_tbl[] = {
+ PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+ PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
+};
+
+static const struct imx_pll14xx_rate_table imx8mm_drampll_tbl[] = {
+ PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+};
+
+static struct imx_pll14xx_clk imx8mm_audio_pll __initdata = {
+ .type = PLL_1443X,
+ .rate_table = imx8mm_audiopll_tbl,
+};
+
+static struct imx_pll14xx_clk imx8mm_video_pll __initdata = {
+ .type = PLL_1443X,
+ .rate_table = imx8mm_videopll_tbl,
+};
+
+static struct imx_pll14xx_clk imx8mm_dram_pll __initdata = {
+ .type = PLL_1443X,
+ .rate_table = imx8mm_drampll_tbl,
+};
+
+static struct imx_pll14xx_clk imx8mm_arm_pll __initdata = {
+ .type = PLL_1416X,
+ .rate_table = imx8mm_pll1416x_tbl,
+};
+
+static struct imx_pll14xx_clk imx8mm_gpu_pll __initdata = {
+ .type = PLL_1416X,
+ .rate_table = imx8mm_pll1416x_tbl,
+};
+
+static struct imx_pll14xx_clk imx8mm_vpu_pll __initdata = {
+ .type = PLL_1416X,
+ .rate_table = imx8mm_pll1416x_tbl,
+};
+
+static struct imx_pll14xx_clk imx8mm_sys_pll __initdata = {
+ .type = PLL_1416X,
+ .rate_table = imx8mm_pll1416x_tbl,
+};
+
+static const char *pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
+static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
+static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
+static const char *video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
+static const char *dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
+static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
+static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
+static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
+static const char *sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", };
+static const char *sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
+static const char *sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
+
+/* CCM ROOT */
+static const char *imx8mm_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m",
+ "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "sys_pll3_out", };
+
+static const char *imx8mm_m4_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "sys_pll1_266m",
+ "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
+
+static const char *imx8mm_vpu_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m",
+ "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "vpu_pll_out", };
+
+static const char *imx8mm_gpu3d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
+ "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_gpu2d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
+ "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m", "sys_pll2_250m",
+ "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "sys_pll1_100m",};
+
+static const char *imx8mm_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m",
+ "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
+
+static const char *imx8mm_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m",
+ "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", };
+
+static const char *imx8mm_vpu_bus_sels[] = {"osc_24m", "sys_pll1_800m", "vpu_pll_out", "audio_pll2_out",
+ "sys_pll3_out", "sys_pll2_1000m", "sys_pll2_200m", "sys_pll1_100m", };
+
+static const char *imx8mm_disp_axi_sels[] = {"osc_24m", "sys_pll2_1000m", "sys_pll1_800m", "sys_pll3_out",
+ "sys_pll1_40m", "audio_pll2_out", "clk_ext1", "clk_ext4", };
+
+static const char *imx8mm_disp_apb_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll1_800m", "sys_pll3_out",
+ "sys_pll1_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", };
+
+static const char *imx8mm_disp_rtrm_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll2_1000m",
+ "audio_pll1_out", "video_pll1_out", "clk_ext2", "clk_ext3", };
+
+static const char *imx8mm_usb_bus_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_100m",
+ "sys_pll2_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", };
+
+static const char *imx8mm_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
+ "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
+ "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_1000m", "sys_pll2_500m",
+ "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_noc_apb_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll3_out", "sys_pll2_333m", "sys_pll2_200m",
+ "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", };
+
+static const char *imx8mm_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m", "sys_pll1_400m",
+ "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
+
+static const char *imx8mm_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_1000m",
+ "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
+
+static const char *imx8mm_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m", "sys_pll2_500m",
+ "sys_pll2_1000m", "sys_pll3_out", "audio_pll1_out", "sys_pll1_266m", };
+
+static const char *imx8mm_dram_apb_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
+ "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
+
+static const char *imx8mm_vpu_g1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
+ "sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
+
+static const char *imx8mm_vpu_g2_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
+ "sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
+
+static const char *imx8mm_disp_dtrc_sels[] = {"osc_24m", "video_pll2_out", "sys_pll1_800m", "sys_pll2_1000m",
+ "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
+
+static const char *imx8mm_disp_dc8000_sels[] = {"osc_24m", "video_pll2_out", "sys_pll1_800m", "sys_pll2_1000m",
+ "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
+
+static const char *imx8mm_pcie1_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m",
+ "sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", };
+
+static const char *imx8mm_pcie1_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m", "clk_ext1", "clk_ext2",
+ "clk_ext3", "clk_ext4", "sys_pll1_400m", };
+
+static const char *imx8mm_pcie1_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out",
+ "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", };
+
+static const char *imx8mm_dc_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
+ "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
+
+static const char *imx8mm_lcdif_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
+ "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
+
+static const char *imx8mm_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+ "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
+
+static const char *imx8mm_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+ "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
+
+static const char *imx8mm_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+ "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
+
+static const char *imx8mm_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+ "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
+
+static const char *imx8mm_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+ "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
+
+static const char *imx8mm_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+ "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
+
+static const char *imx8mm_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+ "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
+
+static const char *imx8mm_spdif2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
+ "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
+
+static const char *imx8mm_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m",
+ "sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
+
+static const char *imx8mm_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "clk_ext1", "clk_ext2",
+ "clk_ext3", "clk_ext4", "video_pll1_out", };
+
+static const char *imx8mm_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m", "sys_pll2_200m",
+ "sys_pll2_500m", "video_pll1_out", "audio_pll2_out", };
+
+static const char *imx8mm_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out", "sys_pll1_400m",
+ "audio_pll2_out", "sys_pll3_out", "sys_pll2_250m", "video_pll1_out", };
+
+static const char *imx8mm_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
+ "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", };
+
+static const char *imx8mm_usdhc1_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
+ "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
+
+static const char *imx8mm_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
+ "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
+
+static const char *imx8mm_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
+ "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mm_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
+ "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mm_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
+ "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mm_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
+ "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mm_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
+ "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
+
+static const char *imx8mm_uart2_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
+ "sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_uart3_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
+ "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
+
+static const char *imx8mm_uart4_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
+ "sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_usb_core_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m",
+ "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_usb_phy_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m",
+ "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_ecspi1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
+ "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
+
+static const char *imx8mm_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
+ "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
+
+static const char *imx8mm_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
+ "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
+
+static const char *imx8mm_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
+ "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
+
+static const char *imx8mm_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
+ "sys3_pll2_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
+
+static const char *imx8mm_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
+ "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
+
+static const char *imx8mm_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", "sys_pll1_40m",
+ "video_pll1_out", "sys_pll1_800m", "audio_pll1_out", "clk_ext1" };
+
+static const char *imx8mm_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m", "vpu_pll_out",
+ "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m", };
+
+static const char *imx8mm_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_out", "sys_pll3_out", "sys_pll2_200m",
+ "sys_pll1_266m", "sys_pll2_500m", "sys_pll1_100m", };
+
+static const char *imx8mm_dsi_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
+ "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_dsi_phy_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_100m", "sys_pll1_800m",
+ "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_100m", "sys_pll1_800m",
+ "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
+ "sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", };
+
+static const char *imx8mm_csi1_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
+ "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_csi1_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
+ "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_csi1_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
+ "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_csi2_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
+ "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_csi2_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
+ "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
+
+static const char *imx8mm_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
+ "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_pcie2_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m",
+ "sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", };
+
+static const char *imx8mm_pcie2_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m", "clk_ext1",
+ "clk_ext2", "clk_ext3", "clk_ext4", "sys_pll1_400m", };
+
+static const char *imx8mm_pcie2_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out",
+ "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", };
+
+static const char *imx8mm_ecspi3_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
+ "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
+
+static const char *imx8mm_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "sys_pll1_800m",
+ "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mm_vpu_h1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
+ "audio_pll2_clk", "sys_pll2_125m", "sys_pll3_clk", "audio_pll1_out", };
+
+static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
+
+static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m", "sys_pll1_200m", "audio_pll2_clk",
+ "vpu_pll", "sys_pll1_80m", };
+
+static struct clk *clks[IMX8MM_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static struct clk ** const uart_clks[] __initconst = {
+ &clks[IMX8MM_CLK_UART1_ROOT],
+ &clks[IMX8MM_CLK_UART2_ROOT],
+ &clks[IMX8MM_CLK_UART3_ROOT],
+ &clks[IMX8MM_CLK_UART4_ROOT],
+ NULL
+};
+
+static int imx8mm_clocks_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ void __iomem *base;
+ int ret = 0;
+
+ clks[IMX8MM_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+ clks[IMX8MM_CLK_24M] = of_clk_get_by_name(np, "osc_24m");
+ clks[IMX8MM_CLK_32K] = of_clk_get_by_name(np, "osc_32k"); /* Check more */
+ clks[IMX8MM_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1");
+ clks[IMX8MM_CLK_EXT2] = of_clk_get_by_name(np, "clk_ext2");
+ clks[IMX8MM_CLK_EXT3] = of_clk_get_by_name(np, "clk_ext3");
+ clks[IMX8MM_CLK_EXT4] = of_clk_get_by_name(np, "clk_ext4");
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop");
+ base = of_iomap(np, 0);
+ if (WARN_ON(!base))
+ return -ENOMEM;
+
+ clks[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_SYS_PLL1_REF_SEL] = imx_clk_mux("sys_pll1_ref_sel", base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ clks[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+ clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx8mm_audio_pll);
+ clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mm_audio_pll);
+ clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mm_video_pll);
+ clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mm_dram_pll);
+ clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mm_gpu_pll);
+ clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mm_vpu_pll);
+ clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mm_arm_pll);
+ clks[IMX8MM_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mm_sys_pll);
+ clks[IMX8MM_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mm_sys_pll);
+ clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mm_sys_pll);
+
+ /* PLL bypass out */
+ clks[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 4, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 4, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 4, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 4, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 4, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 4, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 4, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_SYS_PLL1_BYPASS] = imx_clk_mux_flags("sys_pll1_bypass", base + 0x94, 4, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_SYS_PLL2_BYPASS] = imx_clk_mux_flags("sys_pll2_bypass", base + 0x104, 4, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+ clks[IMX8MM_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 4, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
+
+ /* unbypass all the plls */
+ clk_set_parent(clks[IMX8MM_AUDIO_PLL1_BYPASS], clks[IMX8MM_AUDIO_PLL1]);
+ clk_set_parent(clks[IMX8MM_AUDIO_PLL2_BYPASS], clks[IMX8MM_AUDIO_PLL2]);
+ clk_set_parent(clks[IMX8MM_VIDEO_PLL1_BYPASS], clks[IMX8MM_VIDEO_PLL1]);
+ clk_set_parent(clks[IMX8MM_DRAM_PLL_BYPASS], clks[IMX8MM_DRAM_PLL]);
+ clk_set_parent(clks[IMX8MM_GPU_PLL_BYPASS], clks[IMX8MM_GPU_PLL]);
+ clk_set_parent(clks[IMX8MM_VPU_PLL_BYPASS], clks[IMX8MM_VPU_PLL]);
+ clk_set_parent(clks[IMX8MM_ARM_PLL_BYPASS], clks[IMX8MM_ARM_PLL]);
+ clk_set_parent(clks[IMX8MM_SYS_PLL1_BYPASS], clks[IMX8MM_SYS_PLL1]);
+ clk_set_parent(clks[IMX8MM_SYS_PLL2_BYPASS], clks[IMX8MM_SYS_PLL2]);
+ clk_set_parent(clks[IMX8MM_SYS_PLL3_BYPASS], clks[IMX8MM_SYS_PLL3]);
+
+ /* PLL out gate */
+ clks[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
+ clks[IMX8MM_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
+ clks[IMX8MM_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
+ clks[IMX8MM_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
+ clks[IMX8MM_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 13);
+ clks[IMX8MM_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 13);
+ clks[IMX8MM_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 13);
+ clks[IMX8MM_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1_bypass", base + 0x94, 13);
+ clks[IMX8MM_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2_bypass", base + 0x104, 13);
+ clks[IMX8MM_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 13);
+
+ /* SYS PLL fixed output */
+ clks[IMX8MM_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
+ clks[IMX8MM_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
+ clks[IMX8MM_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
+ clks[IMX8MM_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
+ clks[IMX8MM_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
+ clks[IMX8MM_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
+ clks[IMX8MM_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
+ clks[IMX8MM_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
+ clks[IMX8MM_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
+
+ clks[IMX8MM_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
+ clks[IMX8MM_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
+ clks[IMX8MM_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
+ clks[IMX8MM_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
+ clks[IMX8MM_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
+ clks[IMX8MM_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
+ clks[IMX8MM_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
+ clks[IMX8MM_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
+ clks[IMX8MM_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
+
+ np = dev->of_node;
+ base = of_iomap(np, 0);
+ if (WARN_ON(!base))
+ return -ENOMEM;
+
+ /* Core Slice */
+ clks[IMX8MM_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels));
+ clks[IMX8MM_CLK_M4_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mm_m4_sels, ARRAY_SIZE(imx8mm_m4_sels));
+ clks[IMX8MM_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mm_vpu_sels, ARRAY_SIZE(imx8mm_vpu_sels));
+ clks[IMX8MM_CLK_GPU3D_SRC] = imx_clk_mux2("gpu3d_src", base + 0x8180, 24, 3, imx8mm_gpu3d_sels, ARRAY_SIZE(imx8mm_gpu3d_sels));
+ clks[IMX8MM_CLK_GPU2D_SRC] = imx_clk_mux2("gpu2d_src", base + 0x8200, 24, 3, imx8mm_gpu2d_sels, ARRAY_SIZE(imx8mm_gpu2d_sels));
+ clks[IMX8MM_CLK_A53_CG] = imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
+ clks[IMX8MM_CLK_M4_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
+ clks[IMX8MM_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
+ clks[IMX8MM_CLK_GPU3D_CG] = imx_clk_gate3("gpu3d_cg", "gpu3d_src", base + 0x8180, 28);
+ clks[IMX8MM_CLK_GPU2D_CG] = imx_clk_gate3("gpu2d_cg", "gpu2d_src", base + 0x8200, 28);
+
+ clks[IMX8MM_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
+ clks[IMX8MM_CLK_M4_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
+ clks[IMX8MM_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
+ clks[IMX8MM_CLK_GPU3D_DIV] = imx_clk_divider2("gpu3d_div", "gpu3d_cg", base + 0x8180, 0, 3);
+ clks[IMX8MM_CLK_GPU2D_DIV] = imx_clk_divider2("gpu2d_div", "gpu2d_cg", base + 0x8200, 0, 3);
+
+ /* BUS */
+ clks[IMX8MM_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mm_main_axi_sels, base + 0x8800);
+ clks[IMX8MM_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mm_enet_axi_sels, base + 0x8880);
+ clks[IMX8MM_CLK_NAND_USDHC_BUS] = imx8m_clk_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900);
+ clks[IMX8MM_CLK_VPU_BUS] = imx8m_clk_composite("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980);
+ clks[IMX8MM_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00);
+ clks[IMX8MM_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80);
+ clks[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_composite("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00);
+ clks[IMX8MM_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80);
+ clks[IMX8MM_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00);
+ clks[IMX8MM_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80);
+ clks[IMX8MM_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mm_noc_sels, base + 0x8d00);
+ clks[IMX8MM_CLK_NOC_APB] = imx8m_clk_composite_critical("noc_apb", imx8mm_noc_apb_sels, base + 0x8d80);
+
+ /* AHB */
+ clks[IMX8MM_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mm_ahb_sels, base + 0x9000);
+ clks[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100);
+
+ /* IPG */
+ clks[IMX8MM_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
+ clks[IMX8MM_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
+
+ /* IP */
+ clks[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000);
+ clks[IMX8MM_CLK_DRAM_APB] = imx8m_clk_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080);
+ clks[IMX8MM_CLK_VPU_G1] = imx8m_clk_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100);
+ clks[IMX8MM_CLK_VPU_G2] = imx8m_clk_composite("vpu_g2", imx8mm_vpu_g2_sels, base + 0xa180);
+ clks[IMX8MM_CLK_DISP_DTRC] = imx8m_clk_composite("disp_dtrc", imx8mm_disp_dtrc_sels, base + 0xa200);
+ clks[IMX8MM_CLK_DISP_DC8000] = imx8m_clk_composite("disp_dc8000", imx8mm_disp_dc8000_sels, base + 0xa280);
+ clks[IMX8MM_CLK_PCIE1_CTRL] = imx8m_clk_composite("pcie1_ctrl", imx8mm_pcie1_ctrl_sels, base + 0xa300);
+ clks[IMX8MM_CLK_PCIE1_PHY] = imx8m_clk_composite("pcie1_phy", imx8mm_pcie1_phy_sels, base + 0xa380);
+ clks[IMX8MM_CLK_PCIE1_AUX] = imx8m_clk_composite("pcie1_aux", imx8mm_pcie1_aux_sels, base + 0xa400);
+ clks[IMX8MM_CLK_DC_PIXEL] = imx8m_clk_composite("dc_pixel", imx8mm_dc_pixel_sels, base + 0xa480);
+ clks[IMX8MM_CLK_LCDIF_PIXEL] = imx8m_clk_composite("lcdif_pixel", imx8mm_lcdif_pixel_sels, base + 0xa500);
+ clks[IMX8MM_CLK_SAI1] = imx8m_clk_composite("sai1", imx8mm_sai1_sels, base + 0xa580);
+ clks[IMX8MM_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mm_sai2_sels, base + 0xa600);
+ clks[IMX8MM_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mm_sai3_sels, base + 0xa680);
+ clks[IMX8MM_CLK_SAI4] = imx8m_clk_composite("sai4", imx8mm_sai4_sels, base + 0xa700);
+ clks[IMX8MM_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mm_sai5_sels, base + 0xa780);
+ clks[IMX8MM_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mm_sai6_sels, base + 0xa800);
+ clks[IMX8MM_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mm_spdif1_sels, base + 0xa880);
+ clks[IMX8MM_CLK_SPDIF2] = imx8m_clk_composite("spdif2", imx8mm_spdif2_sels, base + 0xa900);
+ clks[IMX8MM_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mm_enet_ref_sels, base + 0xa980);
+ clks[IMX8MM_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mm_enet_timer_sels, base + 0xaa00);
+ clks[IMX8MM_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mm_enet_phy_sels, base + 0xaa80);
+ clks[IMX8MM_CLK_NAND] = imx8m_clk_composite("nand", imx8mm_nand_sels, base + 0xab00);
+ clks[IMX8MM_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mm_qspi_sels, base + 0xab80);
+ clks[IMX8MM_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mm_usdhc1_sels, base + 0xac00);
+ clks[IMX8MM_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mm_usdhc2_sels, base + 0xac80);
+ clks[IMX8MM_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mm_i2c1_sels, base + 0xad00);
+ clks[IMX8MM_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mm_i2c2_sels, base + 0xad80);
+ clks[IMX8MM_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mm_i2c3_sels, base + 0xae00);
+ clks[IMX8MM_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mm_i2c4_sels, base + 0xae80);
+ clks[IMX8MM_CLK_UART1] = imx8m_clk_composite("uart1", imx8mm_uart1_sels, base + 0xaf00);
+ clks[IMX8MM_CLK_UART2] = imx8m_clk_composite("uart2", imx8mm_uart2_sels, base + 0xaf80);
+ clks[IMX8MM_CLK_UART3] = imx8m_clk_composite("uart3", imx8mm_uart3_sels, base + 0xb000);
+ clks[IMX8MM_CLK_UART4] = imx8m_clk_composite("uart4", imx8mm_uart4_sels, base + 0xb080);
+ clks[IMX8MM_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100);
+ clks[IMX8MM_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180);
+ clks[IMX8MM_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280);
+ clks[IMX8MM_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300);
+ clks[IMX8MM_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380);
+ clks[IMX8MM_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mm_pwm2_sels, base + 0xb400);
+ clks[IMX8MM_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mm_pwm3_sels, base + 0xb480);
+ clks[IMX8MM_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mm_pwm4_sels, base + 0xb500);
+ clks[IMX8MM_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mm_gpt1_sels, base + 0xb580);
+ clks[IMX8MM_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mm_wdog_sels, base + 0xb900);
+ clks[IMX8MM_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mm_wrclk_sels, base + 0xb980);
+ clks[IMX8MM_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mm_clko1_sels, base + 0xba00);
+ clks[IMX8MM_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mm_dsi_core_sels, base + 0xbb00);
+ clks[IMX8MM_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mm_dsi_phy_sels, base + 0xbb80);
+ clks[IMX8MM_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mm_dsi_dbi_sels, base + 0xbc00);
+ clks[IMX8MM_CLK_USDHC3] = imx8m_clk_composite("usdhc3", imx8mm_usdhc3_sels, base + 0xbc80);
+ clks[IMX8MM_CLK_CSI1_CORE] = imx8m_clk_composite("csi1_core", imx8mm_csi1_core_sels, base + 0xbd00);
+ clks[IMX8MM_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mm_csi1_phy_sels, base + 0xbd80);
+ clks[IMX8MM_CLK_CSI1_ESC] = imx8m_clk_composite("csi1_esc", imx8mm_csi1_esc_sels, base + 0xbe00);
+ clks[IMX8MM_CLK_CSI2_CORE] = imx8m_clk_composite("csi2_core", imx8mm_csi2_core_sels, base + 0xbe80);
+ clks[IMX8MM_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mm_csi2_phy_sels, base + 0xbf00);
+ clks[IMX8MM_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mm_csi2_esc_sels, base + 0xbf80);
+ clks[IMX8MM_CLK_PCIE2_CTRL] = imx8m_clk_composite("pcie2_ctrl", imx8mm_pcie2_ctrl_sels, base + 0xc000);
+ clks[IMX8MM_CLK_PCIE2_PHY] = imx8m_clk_composite("pcie2_phy", imx8mm_pcie2_phy_sels, base + 0xc080);
+ clks[IMX8MM_CLK_PCIE2_AUX] = imx8m_clk_composite("pcie2_aux", imx8mm_pcie2_aux_sels, base + 0xc100);
+ clks[IMX8MM_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mm_ecspi3_sels, base + 0xc180);
+ clks[IMX8MM_CLK_PDM] = imx8m_clk_composite("pdm", imx8mm_pdm_sels, base + 0xc200);
+ clks[IMX8MM_CLK_VPU_H1] = imx8m_clk_composite("vpu_h1", imx8mm_vpu_h1_sels, base + 0xc280);
+
+ /* CCGR */
+ clks[IMX8MM_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
+ clks[IMX8MM_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
+ clks[IMX8MM_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
+ clks[IMX8MM_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
+ clks[IMX8MM_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
+ clks[IMX8MM_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
+ clks[IMX8MM_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
+ clks[IMX8MM_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
+ clks[IMX8MM_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
+ clks[IMX8MM_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
+ clks[IMX8MM_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
+ clks[IMX8MM_CLK_PCIE1_ROOT] = imx_clk_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0);
+ clks[IMX8MM_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
+ clks[IMX8MM_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
+ clks[IMX8MM_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
+ clks[IMX8MM_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
+ clks[IMX8MM_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
+ clks[IMX8MM_CLK_NAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
+ clks[IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
+ clks[IMX8MM_CLK_SAI1_ROOT] = imx_clk_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1);
+ clks[IMX8MM_CLK_SAI1_IPG] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1);
+ clks[IMX8MM_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
+ clks[IMX8MM_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2);
+ clks[IMX8MM_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
+ clks[IMX8MM_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3);
+ clks[IMX8MM_CLK_SAI4_ROOT] = imx_clk_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4);
+ clks[IMX8MM_CLK_SAI4_IPG] = imx_clk_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4);
+ clks[IMX8MM_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
+ clks[IMX8MM_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
+ clks[IMX8MM_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
+ clks[IMX8MM_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
+ clks[IMX8MM_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
+ clks[IMX8MM_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
+ clks[IMX8MM_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
+ clks[IMX8MM_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
+ clks[IMX8MM_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref", base + 0x44d0, 0);
+ clks[IMX8MM_CLK_GPU3D_ROOT] = imx_clk_gate4("gpu3d_root_clk", "gpu3d_div", base + 0x44f0, 0);
+ clks[IMX8MM_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
+ clks[IMX8MM_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
+ clks[IMX8MM_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
+ clks[IMX8MM_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
+ clks[IMX8MM_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
+ clks[IMX8MM_CLK_VPU_G1_ROOT] = imx_clk_gate4("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0);
+ clks[IMX8MM_CLK_GPU_BUS_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0);
+ clks[IMX8MM_CLK_VPU_H1_ROOT] = imx_clk_gate4("vpu_h1_root_clk", "vpu_h1", base + 0x4590, 0);
+ clks[IMX8MM_CLK_VPU_G2_ROOT] = imx_clk_gate4("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0);
+ clks[IMX8MM_CLK_PDM_ROOT] = imx_clk_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm);
+ clks[IMX8MM_CLK_PDM_IPG] = imx_clk_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
+ clks[IMX8MM_CLK_DISP_ROOT] = imx_clk_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_dcss);
+ clks[IMX8MM_CLK_DISP_AXI_ROOT] = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss);
+ clks[IMX8MM_CLK_DISP_APB_ROOT] = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss);
+ clks[IMX8MM_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss);
+ clks[IMX8MM_CLK_USDHC3_ROOT] = imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0);
+ clks[IMX8MM_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
+ clks[IMX8MM_CLK_VPU_DEC_ROOT] = imx_clk_gate4("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0);
+ clks[IMX8MM_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
+ clks[IMX8MM_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
+ clks[IMX8MM_CLK_SDMA3_ROOT] = imx_clk_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
+ clks[IMX8MM_CLK_GPU2D_ROOT] = imx_clk_gate4("gpu2d_root_clk", "gpu2d_div", base + 0x4660, 0);
+ clks[IMX8MM_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
+
+ clks[IMX8MM_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc_24m", 1, 8);
+
+ clks[IMX8MM_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
+ clks[IMX8MM_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mm_dram_core_sels, ARRAY_SIZE(imx8mm_dram_core_sels), CLK_IS_CRITICAL);
+
+ clks[IMX8MM_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
+ clks[IMX8MM_CLK_A53_DIV],
+ clks[IMX8MM_CLK_A53_SRC],
+ clks[IMX8MM_ARM_PLL_OUT],
+ clks[IMX8MM_CLK_24M]);
+
+ imx_check_clocks(clks, ARRAY_SIZE(clks));
+
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+ if (ret < 0) {
+ dev_err(dev, "failed to register clks for i.MX8MM\n");
+ return -EINVAL;
+ }
+
+ imx_register_uart_clocks(uart_clks);
+
+ pr_info("i.MX8MM clock driver init done\n");
+
+ return 0;
+}
+
+static const struct of_device_id imx8mm_clk_of_match[] = {
+ { .compatible = "fsl,imx8mm-ccm" },
+ { /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, imx8mm_clk_of_match);
+
+static struct platform_driver imx8mm_clk_driver = {
+ .probe = imx8mm_clocks_probe,
+ .driver = {
+ .name = "imx8mm-ccm",
+ .of_match_table = of_match_ptr(imx8mm_clk_of_match),
+ },
+};
+module_platform_driver(imx8mm_clk_driver);
--
1.9.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] clk: imx: Add clock driver support for imx8mm
2019-01-08 9:01 ` [PATCH 3/3] clk: imx: Add clock driver support " Jacky Bai
@ 2019-01-09 20:32 ` Stephen Boyd
2019-01-10 2:14 ` Jacky Bai
0 siblings, 1 reply; 10+ messages in thread
From: Stephen Boyd @ 2019-01-09 20:32 UTC (permalink / raw)
To: mturquette, robh+dt, shawnguo, Jacky Bai
Cc: Fabio Estevam, Aisheng Dong, dl-linux-imx, linux-clk, devicetree
Quoting Jacky Bai (2019-01-08 01:01:04)
> +
> +static int imx8mm_clocks_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + void __iomem *base;
> + int ret = 0;
Please don't assign ret here. Just let it be assigned later on.
> +
> + clks[IMX8MM_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
> + clks[IMX8MM_CLK_24M] = of_clk_get_by_name(np, "osc_24m");
> + clks[IMX8MM_CLK_32K] = of_clk_get_by_name(np, "osc_32k"); /* Check more */
> + clks[IMX8MM_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1");
> + clks[IMX8MM_CLK_EXT2] = of_clk_get_by_name(np, "clk_ext2");
> + clks[IMX8MM_CLK_EXT3] = of_clk_get_by_name(np, "clk_ext3");
> + clks[IMX8MM_CLK_EXT4] = of_clk_get_by_name(np, "clk_ext4");
> +
> + np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop");
> + base = of_iomap(np, 0);
> + if (WARN_ON(!base))
> + return -ENOMEM;
Why do we need to reach into some other node to get the memory region to
map?
> +
> + clks[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
> + clks[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
> + clks[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
> + clks[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
[...]
> + clks[IMX8MM_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
> + clks[IMX8MM_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
> + clks[IMX8MM_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
> +
> + np = dev->of_node;
> + base = of_iomap(np, 0);
> + if (WARN_ON(!base))
> + return -ENOMEM;
This can surely use the platform device APIs to map and retrieve memory
regions.
> +
[...]
> +
> + imx_check_clocks(clks, ARRAY_SIZE(clks));
> +
> + clk_data.clks = clks;
> + clk_data.clk_num = ARRAY_SIZE(clks);
> + ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
> + if (ret < 0) {
> + dev_err(dev, "failed to register clks for i.MX8MM\n");
> + return -EINVAL;
> + }
> +
> + imx_register_uart_clocks(uart_clks);
> +
> + pr_info("i.MX8MM clock driver init done\n");
Please no "I"m alive" messages.
> +
> + return 0;
> +}
> +
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] clk: imx: Add PLLs driver for imx8mm soc
2019-01-08 9:00 [PATCH 1/3] clk: imx: Add PLLs driver for imx8mm soc Jacky Bai
2019-01-08 9:00 ` [PATCH 2/3] dt-bindings: imx: Add clock binding doc for imx8mm Jacky Bai
2019-01-08 9:01 ` [PATCH 3/3] clk: imx: Add clock driver support " Jacky Bai
@ 2019-01-09 20:35 ` Stephen Boyd
2019-01-10 2:09 ` Jacky Bai
2 siblings, 1 reply; 10+ messages in thread
From: Stephen Boyd @ 2019-01-09 20:35 UTC (permalink / raw)
To: mturquette, robh+dt, shawnguo, Jacky Bai
Cc: Fabio Estevam, Aisheng Dong, dl-linux-imx, linux-clk, devicetree
Quoting Jacky Bai (2019-01-08 01:00:45)
> diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
> new file mode 100644
> index 0000000..c9f83fd
> --- /dev/null
> +++ b/drivers/clk/imx/clk-pll14xx.c
> @@ -0,0 +1,409 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2017-2018 NXP.
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/clk-provider.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/slab.h>
> +#include <linux/jiffies.h>
> +
> +#include "clk.h"
> +
> +#define GNRL_CTL 0x0
> +#define DIV_CTL 0x4
> +#define LOCK_STATUS BIT(31)
> +#define LOCK_SEL_MASK BIT(29)
> +#define CLKE_MASK BIT(11)
> +#define RST_MASK BIT(9)
> +#define BYPASS_MASK BIT(4)
> +#define MDIV_SHIFT 12
> +#define MDIV_MASK GENMASK(21, 12)
> +#define PDIV_SHIFT 4
> +#define PDIV_MASK GENMASK(9, 4)
> +#define SDIV_SHIFT 0
> +#define SDIV_MASK GENMASK(2, 0)
> +#define KDIV_SHIFT 0
> +#define KDIV_MASK GENMASK(15, 0)
> +
> +struct clk_pll14xx {
> + struct clk_hw hw;
> + void __iomem *base;
> + enum imx_pll14xx_type type;
> + struct imx_pll14xx_rate_table *rate_table;
> + int rate_count;
> +};
> +
> +#define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
> +
> +static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
> + struct clk_pll14xx *pll, unsigned long rate)
> +{
> + const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
> + int i;
> +
> + for (i = 0; i < pll->rate_count; i++) {
> + if (rate == rate_table[i].rate)
> + return &rate_table[i];
> + }
Nitpick: Drop the brackets.
> +
> + return NULL;
> +}
> +
> +static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long *prate)
> +{
> + struct clk_pll14xx *pll = to_clk_pll14xx(hw);
> + const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
> + int i;
> +
> + /* Assumming rate_table is in descending order */
> + for (i = 0; i < pll->rate_count; i++) {
> + if (rate >= rate_table[i].rate)
> + return rate_table[i].rate;
> + }
> + /* return minimum supported value */
> + return rate_table[i - 1].rate;
> +}
> +
> +static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct clk_pll14xx *pll = to_clk_pll14xx(hw);
> + u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div;
> + u64 fvco = parent_rate;
> +
> + pll_gnrl = readl_relaxed(pll->base);
> + pll_div = readl_relaxed(pll->base + 4);
> + mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
> + pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
> + sdiv = (pll_div & SDIV_MASK) >> SDIV_SHIFT;
> +
> + fvco *= mdiv;
> + do_div(fvco, pdiv << sdiv);
> +
> + return (unsigned long)fvco;
Nitpick: Drop the cast.
> +}
> +
> +static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct clk_pll14xx *pll = to_clk_pll14xx(hw);
> + u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div_ctl0, pll_div_ctl1;
> + short int kdiv;
> + u64 fvco = parent_rate;
> +
> + pll_gnrl = readl_relaxed(pll->base);
> + pll_div_ctl0 = readl_relaxed(pll->base + 4);
> + pll_div_ctl1 = readl_relaxed(pll->base + 8);
> + mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT;
> + pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT;
> + sdiv = (pll_div_ctl0 & SDIV_MASK) >> SDIV_SHIFT;
> + kdiv = pll_div_ctl1 & KDIV_MASK;
> +
> + /* fvco = (m * 65536 + k) * Fin / (p * 65536) */
> + fvco *= (mdiv * 65536 + kdiv);
> + pdiv *= 65536;
> +
> + do_div(fvco, pdiv << sdiv);
> +
> + return (unsigned long)fvco;
Nitpick: Drop the cast.
> +}
> +
> +static inline bool clk_pll1416x_mp_change(const struct imx_pll14xx_rate_table *rate,
> + u32 pll_div)
> +{
> + u32 old_mdiv, old_pdiv;
> +
> + old_mdiv = (pll_div >> MDIV_SHIFT) & MDIV_MASK;
> + old_pdiv = (pll_div >> PDIV_SHIFT) & PDIV_MASK;
> +
> + return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
> +}
> +
> +static inline bool clk_pll1443x_mpk_change(const struct imx_pll14xx_rate_table *rate,
> + u32 pll_div_ctl0, u32 pll_div_ctl1)
> +{
> + u32 old_mdiv, old_pdiv, old_kdiv;
> +
> + old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
> + old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
> + old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
> +
> + return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
> + rate->kdiv != old_kdiv);
> +}
> +
> +static inline bool clk_pll1443x_mp_change(const struct imx_pll14xx_rate_table *rate,
> + u32 pll_div_ctl0, u32 pll_div_ctl1)
> +{
> + u32 old_mdiv, old_pdiv, old_kdiv;
> +
> + old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
> + old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
> + old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
> +
> + return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
> + rate->kdiv != old_kdiv);
Nitpick: Please drop the parenthesis on all the returns above.
> +}
> +
> +static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll)
> +{
> + unsigned long timeout = jiffies + msecs_to_jiffies(10);
> +
> + /* Wait for PLL to lock */
> + do {
> + if (readl_relaxed(pll->base) & LOCK_STATUS)
> + break;
> + if (time_after(jiffies, timeout))
> + break;
> + } while (1);
> +
> + return readl_relaxed(pll->base) & LOCK_STATUS ? 0 : -ETIMEDOUT;
Is this readl_poll_timeout()?
> +}
> +
[...]
> +
> +struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
> + void __iomem *base,
> + const struct imx_pll14xx_clk *pll_clk)
> +{
> + struct clk_pll14xx *pll;
> + struct clk *clk;
> + struct clk_init_data init;
> + int len;
> +
> + pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> + if (!pll)
> + return ERR_PTR(-ENOMEM);
> +
> + init.name = name;
> + init.flags = pll_clk->flags;
> + init.parent_names = &parent_name;
> + init.num_parents = 1;
> +
> + if (pll_clk->rate_table) {
> + for (len = 0; pll_clk->rate_table[len].rate != 0; )
> + len++;
> +
> + pll->rate_count = len;
> + pll->rate_table = kmemdup(pll_clk->rate_table,
> + pll->rate_count *
> + sizeof(struct imx_pll14xx_rate_table),
Is this struct_size()?
> + GFP_KERNEL);
> + WARN(!pll->rate_table, "%s : could not alloc rate table\n", __func__);
Allocations will fail with a loud message indicating as such, so this
WARN is not necessary.
> + }
> +
> + switch (pll_clk->type) {
> + case PLL_1416X:
> + if (!pll->rate_table)
> + init.ops = &clk_pll1416x_min_ops;
> + else
> + init.ops = &clk_pll1416x_ops;
> + break;
> + case PLL_1443X:
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] dt-bindings: imx: Add clock binding doc for imx8mm
2019-01-08 9:00 ` [PATCH 2/3] dt-bindings: imx: Add clock binding doc for imx8mm Jacky Bai
@ 2019-01-09 20:36 ` Stephen Boyd
2019-01-10 1:59 ` Jacky Bai
2019-01-21 20:33 ` Rob Herring
1 sibling, 1 reply; 10+ messages in thread
From: Stephen Boyd @ 2019-01-09 20:36 UTC (permalink / raw)
To: mturquette, robh+dt, shawnguo, Jacky Bai
Cc: Fabio Estevam, Aisheng Dong, dl-linux-imx, linux-clk, devicetree
Quoting Jacky Bai (2019-01-08 01:00:58)
> Add the clock binding doc for i.MX8MM.
>
> Signed-off-by: Bai Ping <ping.bai@nxp.com>
> ---
> .../devicetree/bindings/clock/imx8mm-clock.txt | 19 ++
> include/dt-bindings/clock/imx8mm-clock.h | 244 +++++++++++++++++++++
> 2 files changed, 263 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/clock/imx8mm-clock.txt
> create mode 100644 include/dt-bindings/clock/imx8mm-clock.h
>
> diff --git a/Documentation/devicetree/bindings/clock/imx8mm-clock.txt b/Documentation/devicetree/bindings/clock/imx8mm-clock.txt
> new file mode 100644
> index 0000000..034b6d4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/imx8mm-clock.txt
> @@ -0,0 +1,19 @@
> +* Clock bindings for NXP i.MX8M Mini
> +
> +Required properties:
> +- compatible: Should be "fsl,imx8mm-ccm"
> +- reg: Address and length of the register set
> +- #clock-cells: Should be <1>
> +- clocks: list of clock specifiers, must contain an entry for each required
> + entry in clock-names
> +- clock-names: should include the following entries:
> + - "osc_32k"
> + - "osc_24m"
> + - "clk_ext1"
> + - "clk_ext2"
> + - "clk_ext3"
> + - "clk_ext4"
> +
> +The clock consumer should specify the desired clock by having the clock
> +ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8mm-clock.h
> +for the full list of i.MX8M Mini clock IDs.
Any example of this node? Not the clock consumer.
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [PATCH 2/3] dt-bindings: imx: Add clock binding doc for imx8mm
2019-01-09 20:36 ` Stephen Boyd
@ 2019-01-10 1:59 ` Jacky Bai
0 siblings, 0 replies; 10+ messages in thread
From: Jacky Bai @ 2019-01-10 1:59 UTC (permalink / raw)
To: Stephen Boyd, mturquette, robh+dt, shawnguo
Cc: Fabio Estevam, Aisheng Dong, dl-linux-imx, linux-clk, devicetree
> Subject: Re: [PATCH 2/3] dt-bindings: imx: Add clock binding doc for imx8mm
>
> Quoting Jacky Bai (2019-01-08 01:00:58)
> > Add the clock binding doc for i.MX8MM.
> >
> > Signed-off-by: Bai Ping <ping.bai@nxp.com>
> > ---
> > .../devicetree/bindings/clock/imx8mm-clock.txt | 19 ++
> > include/dt-bindings/clock/imx8mm-clock.h | 244
> +++++++++++++++++++++
> > 2 files changed, 263 insertions(+)
> > create mode 100644
> > Documentation/devicetree/bindings/clock/imx8mm-clock.txt
> > create mode 100644 include/dt-bindings/clock/imx8mm-clock.h
> >
> > diff --git a/Documentation/devicetree/bindings/clock/imx8mm-clock.txt
> > b/Documentation/devicetree/bindings/clock/imx8mm-clock.txt
> > new file mode 100644
> > index 0000000..034b6d4
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/imx8mm-clock.txt
> > @@ -0,0 +1,19 @@
> > +* Clock bindings for NXP i.MX8M Mini
> > +
> > +Required properties:
> > +- compatible: Should be "fsl,imx8mm-ccm"
> > +- reg: Address and length of the register set
> > +- #clock-cells: Should be <1>
> > +- clocks: list of clock specifiers, must contain an entry for each required
> > + entry in clock-names
> > +- clock-names: should include the following entries:
> > + - "osc_32k"
> > + - "osc_24m"
> > + - "clk_ext1"
> > + - "clk_ext2"
> > + - "clk_ext3"
> > + - "clk_ext4"
> > +
> > +The clock consumer should specify the desired clock by having the
> > +clock ID in its "clocks" phandle cell. See
> > +include/dt-bindings/clock/imx8mm-clock.h
> > +for the full list of i.MX8M Mini clock IDs.
>
> Any example of this node? Not the clock consumer.
Sure, I can add an example in V2.
BR
Jacky Bai
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [PATCH 1/3] clk: imx: Add PLLs driver for imx8mm soc
2019-01-09 20:35 ` [PATCH 1/3] clk: imx: Add PLLs driver for imx8mm soc Stephen Boyd
@ 2019-01-10 2:09 ` Jacky Bai
0 siblings, 0 replies; 10+ messages in thread
From: Jacky Bai @ 2019-01-10 2:09 UTC (permalink / raw)
To: Stephen Boyd, mturquette, robh+dt, shawnguo
Cc: Fabio Estevam, Aisheng Dong, dl-linux-imx, linux-clk, devicetree
> Subject: Re: [PATCH 1/3] clk: imx: Add PLLs driver for imx8mm soc
>
> Quoting Jacky Bai (2019-01-08 01:00:45)
> > diff --git a/drivers/clk/imx/clk-pll14xx.c
> > b/drivers/clk/imx/clk-pll14xx.c new file mode 100644 index
> > 0000000..c9f83fd
> > --- /dev/null
> > +++ b/drivers/clk/imx/clk-pll14xx.c
> > @@ -0,0 +1,409 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright 2017-2018 NXP.
> > + */
> > +
> > +#include <linux/bitops.h>
> > +#include <linux/clk-provider.h>
> > +#include <linux/delay.h>
> > +#include <linux/err.h>
> > +#include <linux/io.h>
> > +#include <linux/slab.h>
> > +#include <linux/jiffies.h>
> > +
> > +#include "clk.h"
> > +
> > +#define GNRL_CTL 0x0
> > +#define DIV_CTL 0x4
> > +#define LOCK_STATUS BIT(31)
> > +#define LOCK_SEL_MASK BIT(29)
> > +#define CLKE_MASK BIT(11)
> > +#define RST_MASK BIT(9)
> > +#define BYPASS_MASK BIT(4)
> > +#define MDIV_SHIFT 12
> > +#define MDIV_MASK GENMASK(21, 12)
> > +#define PDIV_SHIFT 4
> > +#define PDIV_MASK GENMASK(9, 4)
> > +#define SDIV_SHIFT 0
> > +#define SDIV_MASK GENMASK(2, 0)
> > +#define KDIV_SHIFT 0
> > +#define KDIV_MASK GENMASK(15, 0)
> > +
> > +struct clk_pll14xx {
> > + struct clk_hw hw;
> > + void __iomem *base;
> > + enum imx_pll14xx_type type;
> > + struct imx_pll14xx_rate_table *rate_table;
> > + int rate_count;
> > +};
> > +
> > +#define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
> > +
> > +static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
> > + struct clk_pll14xx *pll, unsigned long rate) {
> > + const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
> > + int i;
> > +
> > + for (i = 0; i < pll->rate_count; i++) {
> > + if (rate == rate_table[i].rate)
> > + return &rate_table[i];
> > + }
>
> Nitpick: Drop the brackets.
>
Thanks, will fix it in V2.
> > +
> > + return NULL;
> > +}
> > +
> > +static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate,
> > + unsigned long *prate) {
> > + struct clk_pll14xx *pll = to_clk_pll14xx(hw);
> > + const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
> > + int i;
> > +
> > + /* Assumming rate_table is in descending order */
> > + for (i = 0; i < pll->rate_count; i++) {
> > + if (rate >= rate_table[i].rate)
> > + return rate_table[i].rate;
> > + }
> > + /* return minimum supported value */
> > + return rate_table[i - 1].rate; }
> > +
> > +static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw,
> > + unsigned long
> > +parent_rate) {
> > + struct clk_pll14xx *pll = to_clk_pll14xx(hw);
> > + u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div;
> > + u64 fvco = parent_rate;
> > +
> > + pll_gnrl = readl_relaxed(pll->base);
> > + pll_div = readl_relaxed(pll->base + 4);
> > + mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
> > + pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
> > + sdiv = (pll_div & SDIV_MASK) >> SDIV_SHIFT;
> > +
> > + fvco *= mdiv;
> > + do_div(fvco, pdiv << sdiv);
> > +
> > + return (unsigned long)fvco;
>
> Nitpick: Drop the cast.
>
Thanks, will fix it in V2.
> > +}
> > +
> > +static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw,
> > + unsigned long
> > +parent_rate) {
> > + struct clk_pll14xx *pll = to_clk_pll14xx(hw);
> > + u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div_ctl0, pll_div_ctl1;
> > + short int kdiv;
> > + u64 fvco = parent_rate;
> > +
> > + pll_gnrl = readl_relaxed(pll->base);
> > + pll_div_ctl0 = readl_relaxed(pll->base + 4);
> > + pll_div_ctl1 = readl_relaxed(pll->base + 8);
> > + mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT;
> > + pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT;
> > + sdiv = (pll_div_ctl0 & SDIV_MASK) >> SDIV_SHIFT;
> > + kdiv = pll_div_ctl1 & KDIV_MASK;
> > +
> > + /* fvco = (m * 65536 + k) * Fin / (p * 65536) */
> > + fvco *= (mdiv * 65536 + kdiv);
> > + pdiv *= 65536;
> > +
> > + do_div(fvco, pdiv << sdiv);
> > +
> > + return (unsigned long)fvco;
>
> Nitpick: Drop the cast.
>
Will fix in V2.
> > +}
> > +
> > +static inline bool clk_pll1416x_mp_change(const struct
> imx_pll14xx_rate_table *rate,
> > + u32 pll_div) {
> > + u32 old_mdiv, old_pdiv;
> > +
> > + old_mdiv = (pll_div >> MDIV_SHIFT) & MDIV_MASK;
> > + old_pdiv = (pll_div >> PDIV_SHIFT) & PDIV_MASK;
> > +
> > + return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv); }
> > +
> > +static inline bool clk_pll1443x_mpk_change(const struct
> imx_pll14xx_rate_table *rate,
> > + u32 pll_div_ctl0, u32
> > +pll_div_ctl1) {
> > + u32 old_mdiv, old_pdiv, old_kdiv;
> > +
> > + old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
> > + old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
> > + old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
> > +
> > + return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
> > + rate->kdiv != old_kdiv); }
> > +
> > +static inline bool clk_pll1443x_mp_change(const struct
> imx_pll14xx_rate_table *rate,
> > + u32 pll_div_ctl0, u32
> > +pll_div_ctl1) {
> > + u32 old_mdiv, old_pdiv, old_kdiv;
> > +
> > + old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
> > + old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
> > + old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
> > +
> > + return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
> > + rate->kdiv != old_kdiv);
>
> Nitpick: Please drop the parenthesis on all the returns above.
>
Will fix in V2.
> > +}
> > +
> > +static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll) {
> > + unsigned long timeout = jiffies + msecs_to_jiffies(10);
> > +
> > + /* Wait for PLL to lock */
> > + do {
> > + if (readl_relaxed(pll->base) & LOCK_STATUS)
> > + break;
> > + if (time_after(jiffies, timeout))
> > + break;
> > + } while (1);
> > +
> > + return readl_relaxed(pll->base) & LOCK_STATUS ? 0 :
> > + -ETIMEDOUT;
>
> Is this readl_poll_timeout()?
>
Yes, will fix it.
> > +}
> > +
> [...]
> > +
> > +struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
> > + void __iomem *base,
> > + const struct imx_pll14xx_clk *pll_clk) {
> > + struct clk_pll14xx *pll;
> > + struct clk *clk;
> > + struct clk_init_data init;
> > + int len;
> > +
> > + pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> > + if (!pll)
> > + return ERR_PTR(-ENOMEM);
> > +
> > + init.name = name;
> > + init.flags = pll_clk->flags;
> > + init.parent_names = &parent_name;
> > + init.num_parents = 1;
> > +
> > + if (pll_clk->rate_table) {
> > + for (len = 0; pll_clk->rate_table[len].rate != 0; )
> > + len++;
> > +
> > + pll->rate_count = len;
> > + pll->rate_table = kmemdup(pll_clk->rate_table,
> > + pll->rate_count *
> > + sizeof(struct
> > + imx_pll14xx_rate_table),
>
> Is this struct_size()?
Will fix it in V2
>
> > + GFP_KERNEL);
> > + WARN(!pll->rate_table, "%s : could not alloc rate
> > + table\n", __func__);
>
> Allocations will fail with a loud message indicating as such, so this WARN is not
> necessary.
>
Will fix in V2
BR
> > + }
> > +
> > + switch (pll_clk->type) {
> > + case PLL_1416X:
> > + if (!pll->rate_table)
> > + init.ops = &clk_pll1416x_min_ops;
> > + else
> > + init.ops = &clk_pll1416x_ops;
> > + break;
> > + case PLL_1443X:
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [PATCH 3/3] clk: imx: Add clock driver support for imx8mm
2019-01-09 20:32 ` Stephen Boyd
@ 2019-01-10 2:14 ` Jacky Bai
0 siblings, 0 replies; 10+ messages in thread
From: Jacky Bai @ 2019-01-10 2:14 UTC (permalink / raw)
To: Stephen Boyd, mturquette, robh+dt, shawnguo
Cc: Fabio Estevam, Aisheng Dong, dl-linux-imx, linux-clk, devicetree
> Subject: Re: [PATCH 3/3] clk: imx: Add clock driver support for imx8mm
>
> Quoting Jacky Bai (2019-01-08 01:01:04)
> > +
> > +static int imx8mm_clocks_probe(struct platform_device *pdev) {
> > + struct device *dev = &pdev->dev;
> > + struct device_node *np = dev->of_node;
> > + void __iomem *base;
> > + int ret = 0;
>
> Please don't assign ret here. Just let it be assigned later on.
>
Sure.
> > +
> > + clks[IMX8MM_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
> > + clks[IMX8MM_CLK_24M] = of_clk_get_by_name(np, "osc_24m");
> > + clks[IMX8MM_CLK_32K] = of_clk_get_by_name(np, "osc_32k");
> /* Check more */
> > + clks[IMX8MM_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1");
> > + clks[IMX8MM_CLK_EXT2] = of_clk_get_by_name(np, "clk_ext2");
> > + clks[IMX8MM_CLK_EXT3] = of_clk_get_by_name(np, "clk_ext3");
> > + clks[IMX8MM_CLK_EXT4] = of_clk_get_by_name(np, "clk_ext4");
> > +
> > + np = of_find_compatible_node(NULL, NULL,
> "fsl,imx8mm-anatop");
> > + base = of_iomap(np, 0);
> > + if (WARN_ON(!base))
> > + return -ENOMEM;
>
> Why do we need to reach into some other node to get the memory region to
> map?
>
The PLLs' config register is in a sperate memory region. As we registered all the PLLs clocks in this driver, the PLLs memory region
Need to be read out from its corresponding node. This is the method that we used on our all i.MX platform.
> > +
> > + clks[IMX8MM_AUDIO_PLL1_REF_SEL] =
> imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels,
> ARRAY_SIZE(pll_ref_sels));
> > + clks[IMX8MM_AUDIO_PLL2_REF_SEL] =
> imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels,
> ARRAY_SIZE(pll_ref_sels));
> > + clks[IMX8MM_VIDEO_PLL1_REF_SEL] =
> imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels,
> ARRAY_SIZE(pll_ref_sels));
> > + clks[IMX8MM_DRAM_PLL_REF_SEL] =
> > + imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels,
> > + ARRAY_SIZE(pll_ref_sels));
> [...]
> > + clks[IMX8MM_SYS_PLL2_333M] =
> imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
> > + clks[IMX8MM_SYS_PLL2_500M] =
> imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
> > + clks[IMX8MM_SYS_PLL2_1000M] =
> > + imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
> > +
> > + np = dev->of_node;
> > + base = of_iomap(np, 0);
> > + if (WARN_ON(!base))
> > + return -ENOMEM;
>
> This can surely use the platform device APIs to map and retrieve memory
> regions.
>
Ok, will fix it
> > +
> [...]
> > +
> > + imx_check_clocks(clks, ARRAY_SIZE(clks));
> > +
> > + clk_data.clks = clks;
> > + clk_data.clk_num = ARRAY_SIZE(clks);
> > + ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
> > + if (ret < 0) {
> > + dev_err(dev, "failed to register clks for i.MX8MM\n");
> > + return -EINVAL;
> > + }
> > +
> > + imx_register_uart_clocks(uart_clks);
> > +
> > + pr_info("i.MX8MM clock driver init done\n");
>
> Please no "I"m alive" messages.
I will remove it in V2.
BR
>
> > +
> > + return 0;
> > +}
> > +
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] dt-bindings: imx: Add clock binding doc for imx8mm
2019-01-08 9:00 ` [PATCH 2/3] dt-bindings: imx: Add clock binding doc for imx8mm Jacky Bai
2019-01-09 20:36 ` Stephen Boyd
@ 2019-01-21 20:33 ` Rob Herring
1 sibling, 0 replies; 10+ messages in thread
From: Rob Herring @ 2019-01-21 20:33 UTC (permalink / raw)
To: Jacky Bai
Cc: sboyd, mturquette, shawnguo, Fabio Estevam, Aisheng Dong,
dl-linux-imx, linux-clk, devicetree
On Tue, Jan 08, 2019 at 09:00:58AM +0000, Jacky Bai wrote:
> Add the clock binding doc for i.MX8MM.
>
> Signed-off-by: Bai Ping <ping.bai@nxp.com>
> ---
> .../devicetree/bindings/clock/imx8mm-clock.txt | 19 ++
> include/dt-bindings/clock/imx8mm-clock.h | 244 +++++++++++++++++++++
> 2 files changed, 263 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/clock/imx8mm-clock.txt
> create mode 100644 include/dt-bindings/clock/imx8mm-clock.h
>
> diff --git a/Documentation/devicetree/bindings/clock/imx8mm-clock.txt b/Documentation/devicetree/bindings/clock/imx8mm-clock.txt
> new file mode 100644
> index 0000000..034b6d4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/imx8mm-clock.txt
> @@ -0,0 +1,19 @@
> +* Clock bindings for NXP i.MX8M Mini
> +
> +Required properties:
> +- compatible: Should be "fsl,imx8mm-ccm"
> +- reg: Address and length of the register set
> +- #clock-cells: Should be <1>
> +- clocks: list of clock specifiers, must contain an entry for each required
> + entry in clock-names
> +- clock-names: should include the following entries:
> + - "osc_32k"
> + - "osc_24m"
> + - "clk_ext1"
> + - "clk_ext2"
> + - "clk_ext3"
> + - "clk_ext4"
> +
> +The clock consumer should specify the desired clock by having the clock
> +ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8mm-clock.h
> +for the full list of i.MX8M Mini clock IDs.
> diff --git a/include/dt-bindings/clock/imx8mm-clock.h b/include/dt-bindings/clock/imx8mm-clock.h
> new file mode 100644
> index 0000000..0301581
> --- /dev/null
> +++ b/include/dt-bindings/clock/imx8mm-clock.h
> @@ -0,0 +1,244 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright 2017-2018 NXP
> + */
> +
> +#ifndef __DT_BINDINGS_CLOCK_IMX8MM_H
> +#define __DT_BINDINGS_CLOCK_IMX8MM_H
> +
> +#define IMX8MM_CLK_DUMMY 0
Should be a space, not a tab after the #define.
> +#define IMX8MM_CLK_32K 1
> +#define IMX8MM_CLK_24M 2
> +#define IMX8MM_OSC_HDMI_CLK 3
> +#define IMX8MM_CLK_EXT1 4
> +#define IMX8MM_CLK_EXT2 5
> +#define IMX8MM_CLK_EXT3 6
> +#define IMX8MM_CLK_EXT4 7
> +#define IMX8MM_AUDIO_PLL1_REF_SEL 8
> +#define IMX8MM_AUDIO_PLL2_REF_SEL 9
> +#define IMX8MM_VIDEO_PLL1_REF_SEL 10
> +#define IMX8MM_DRAM_PLL_REF_SEL 11
> +#define IMX8MM_GPU_PLL_REF_SEL 12
> +#define IMX8MM_VPU_PLL_REF_SEL 13
> +#define IMX8MM_ARM_PLL_REF_SEL 14
> +#define IMX8MM_SYS_PLL1_REF_SEL 15
> +#define IMX8MM_SYS_PLL2_REF_SEL 16
> +#define IMX8MM_SYS_PLL3_REF_SEL 17
> +#define IMX8MM_AUDIO_PLL1 18
> +#define IMX8MM_AUDIO_PLL2 19
> +#define IMX8MM_VIDEO_PLL1 20
> +#define IMX8MM_DRAM_PLL 21
> +#define IMX8MM_GPU_PLL 22
> +#define IMX8MM_VPU_PLL 23
> +#define IMX8MM_ARM_PLL 24
> +#define IMX8MM_SYS_PLL1 25
> +#define IMX8MM_SYS_PLL2 26
> +#define IMX8MM_SYS_PLL3 27
> +#define IMX8MM_AUDIO_PLL1_BYPASS 28
> +#define IMX8MM_AUDIO_PLL2_BYPASS 29
> +#define IMX8MM_VIDEO_PLL1_BYPASS 30
> +#define IMX8MM_DRAM_PLL_BYPASS 31
> +#define IMX8MM_GPU_PLL_BYPASS 32
> +#define IMX8MM_VPU_PLL_BYPASS 33
> +#define IMX8MM_ARM_PLL_BYPASS 34
> +#define IMX8MM_SYS_PLL1_BYPASS 35
> +#define IMX8MM_SYS_PLL2_BYPASS 36
> +#define IMX8MM_SYS_PLL3_BYPASS 37
> +#define IMX8MM_AUDIO_PLL1_OUT 38
> +#define IMX8MM_AUDIO_PLL2_OUT 39
> +#define IMX8MM_VIDEO_PLL1_OUT 40
> +#define IMX8MM_DRAM_PLL_OUT 41
> +#define IMX8MM_GPU_PLL_OUT 42
> +#define IMX8MM_VPU_PLL_OUT 43
> +#define IMX8MM_ARM_PLL_OUT 44
> +#define IMX8MM_SYS_PLL1_OUT 45
> +#define IMX8MM_SYS_PLL2_OUT 46
> +#define IMX8MM_SYS_PLL3_OUT 47
> +#define IMX8MM_SYS_PLL1_40M 48
> +#define IMX8MM_SYS_PLL1_80M 49
> +#define IMX8MM_SYS_PLL1_100M 50
> +#define IMX8MM_SYS_PLL1_133M 51
> +#define IMX8MM_SYS_PLL1_160M 52
> +#define IMX8MM_SYS_PLL1_200M 53
> +#define IMX8MM_SYS_PLL1_266M 54
> +#define IMX8MM_SYS_PLL1_400M 55
> +#define IMX8MM_SYS_PLL1_800M 56
> +#define IMX8MM_SYS_PLL2_50M 57
> +#define IMX8MM_SYS_PLL2_100M 58
> +#define IMX8MM_SYS_PLL2_125M 59
> +#define IMX8MM_SYS_PLL2_166M 60
> +#define IMX8MM_SYS_PLL2_200M 61
> +#define IMX8MM_SYS_PLL2_250M 62
> +#define IMX8MM_SYS_PLL2_333M 63
> +#define IMX8MM_SYS_PLL2_500M 64
> +#define IMX8MM_SYS_PLL2_1000M 65
> +
> +/* core */
> +#define IMX8MM_CLK_A53_SRC 66
> +#define IMX8MM_CLK_M4_SRC 67
> +#define IMX8MM_CLK_VPU_SRC 68
> +#define IMX8MM_CLK_GPU3D_SRC 69
> +#define IMX8MM_CLK_GPU2D_SRC 70
> +#define IMX8MM_CLK_A53_CG 71
> +#define IMX8MM_CLK_M4_CG 72
> +#define IMX8MM_CLK_VPU_CG 73
> +#define IMX8MM_CLK_GPU3D_CG 74
> +#define IMX8MM_CLK_GPU2D_CG 75
> +#define IMX8MM_CLK_A53_DIV 76
> +#define IMX8MM_CLK_M4_DIV 77
> +#define IMX8MM_CLK_VPU_DIV 78
> +#define IMX8MM_CLK_GPU3D_DIV 79
> +#define IMX8MM_CLK_GPU2D_DIV 80
> +
> +/* bus */
> +#define IMX8MM_CLK_MAIN_AXI 81
> +#define IMX8MM_CLK_ENET_AXI 82
> +#define IMX8MM_CLK_NAND_USDHC_BUS 83
> +#define IMX8MM_CLK_VPU_BUS 84
> +#define IMX8MM_CLK_DISP_AXI 85
> +#define IMX8MM_CLK_DISP_APB 86
> +#define IMX8MM_CLK_DISP_RTRM 87
> +#define IMX8MM_CLK_USB_BUS 88
> +#define IMX8MM_CLK_GPU_AXI 89
> +#define IMX8MM_CLK_GPU_AHB 90
> +#define IMX8MM_CLK_NOC 91
> +#define IMX8MM_CLK_NOC_APB 92
> +
> +#define IMX8MM_CLK_AHB 93
> +#define IMX8MM_CLK_AUDIO_AHB 94
> +#define IMX8MM_CLK_IPG_ROOT 95
> +#define IMX8MM_CLK_IPG_AUDIO_ROOT 96
> +
> +#define IMX8MM_CLK_DRAM_ALT 97
> +#define IMX8MM_CLK_DRAM_APB 98
> +#define IMX8MM_CLK_VPU_G1 99
> +#define IMX8MM_CLK_VPU_G2 100
> +#define IMX8MM_CLK_DISP_DTRC 101
> +#define IMX8MM_CLK_DISP_DC8000 102
> +#define IMX8MM_CLK_PCIE1_CTRL 103
> +#define IMX8MM_CLK_PCIE1_PHY 104
> +#define IMX8MM_CLK_PCIE1_AUX 105
> +#define IMX8MM_CLK_DC_PIXEL 106
> +#define IMX8MM_CLK_LCDIF_PIXEL 107
> +#define IMX8MM_CLK_SAI1 108
> +#define IMX8MM_CLK_SAI2 109
> +#define IMX8MM_CLK_SAI3 110
> +#define IMX8MM_CLK_SAI4 111
> +#define IMX8MM_CLK_SAI5 112
> +#define IMX8MM_CLK_SAI6 113
> +#define IMX8MM_CLK_SPDIF1 114
> +#define IMX8MM_CLK_SPDIF2 115
> +#define IMX8MM_CLK_ENET_REF 116
> +#define IMX8MM_CLK_ENET_TIMER 117
> +#define IMX8MM_CLK_ENET_PHY_REF 118
> +#define IMX8MM_CLK_NAND 119
> +#define IMX8MM_CLK_QSPI 120
> +#define IMX8MM_CLK_USDHC1 121
> +#define IMX8MM_CLK_USDHC2 122
> +#define IMX8MM_CLK_I2C1 123
> +#define IMX8MM_CLK_I2C2 124
> +#define IMX8MM_CLK_I2C3 125
> +#define IMX8MM_CLK_I2C4 126
> +#define IMX8MM_CLK_UART1 127
> +#define IMX8MM_CLK_UART2 128
> +#define IMX8MM_CLK_UART3 129
> +#define IMX8MM_CLK_UART4 130
> +#define IMX8MM_CLK_USB_CORE_REF 131
> +#define IMX8MM_CLK_USB_PHY_REF 132
> +#define IMX8MM_CLK_ECSPI1 133
> +#define IMX8MM_CLK_ECSPI2 134
> +#define IMX8MM_CLK_PWM1 135
> +#define IMX8MM_CLK_PWM2 136
> +#define IMX8MM_CLK_PWM3 137
> +#define IMX8MM_CLK_PWM4 138
> +#define IMX8MM_CLK_GPT1 139
> +#define IMX8MM_CLK_WDOG 140
> +#define IMX8MM_CLK_WRCLK 141
> +#define IMX8MM_CLK_DSI_CORE 142
> +#define IMX8MM_CLK_DSI_PHY_REF 143
> +#define IMX8MM_CLK_DSI_DBI 144
> +#define IMX8MM_CLK_USDHC3 145
> +#define IMX8MM_CLK_CSI1_CORE 146
> +#define IMX8MM_CLK_CSI1_PHY_REF 147
> +#define IMX8MM_CLK_CSI1_ESC 148
> +#define IMX8MM_CLK_CSI2_CORE 149
> +#define IMX8MM_CLK_CSI2_PHY_REF 150
> +#define IMX8MM_CLK_CSI2_ESC 151
> +#define IMX8MM_CLK_PCIE2_CTRL 152
> +#define IMX8MM_CLK_PCIE2_PHY 153
> +#define IMX8MM_CLK_PCIE2_AUX 154
> +#define IMX8MM_CLK_ECSPI3 155
> +#define IMX8MM_CLK_PDM 156
> +#define IMX8MM_CLK_VPU_H1 157
> +#define IMX8MM_CLK_CLKO1 158
> +
> +#define IMX8MM_CLK_ECSPI1_ROOT 159
> +#define IMX8MM_CLK_ECSPI2_ROOT 160
> +#define IMX8MM_CLK_ECSPI3_ROOT 161
> +#define IMX8MM_CLK_ENET1_ROOT 162
> +#define IMX8MM_CLK_GPT1_ROOT 163
> +#define IMX8MM_CLK_I2C1_ROOT 164
> +#define IMX8MM_CLK_I2C2_ROOT 165
> +#define IMX8MM_CLK_I2C3_ROOT 166
> +#define IMX8MM_CLK_I2C4_ROOT 167
> +#define IMX8MM_CLK_OCOTP_ROOT 168
> +#define IMX8MM_CLK_PCIE1_ROOT 169
> +#define IMX8MM_CLK_PWM1_ROOT 170
> +#define IMX8MM_CLK_PWM2_ROOT 171
> +#define IMX8MM_CLK_PWM3_ROOT 172
> +#define IMX8MM_CLK_PWM4_ROOT 173
> +#define IMX8MM_CLK_QSPI_ROOT 174
> +#define IMX8MM_CLK_NAND_ROOT 175
> +#define IMX8MM_CLK_SAI1_ROOT 176
> +#define IMX8MM_CLK_SAI1_IPG 177
> +#define IMX8MM_CLK_SAI2_ROOT 178
> +#define IMX8MM_CLK_SAI2_IPG 179
> +#define IMX8MM_CLK_SAI3_ROOT 180
> +#define IMX8MM_CLK_SAI3_IPG 181
> +#define IMX8MM_CLK_SAI4_ROOT 182
> +#define IMX8MM_CLK_SAI4_IPG 183
> +#define IMX8MM_CLK_SAI5_ROOT 184
> +#define IMX8MM_CLK_SAI5_IPG 185
> +#define IMX8MM_CLK_SAI6_ROOT 186
> +#define IMX8MM_CLK_SAI6_IPG 187
> +#define IMX8MM_CLK_UART1_ROOT 188
> +#define IMX8MM_CLK_UART2_ROOT 189
> +#define IMX8MM_CLK_UART3_ROOT 190
> +#define IMX8MM_CLK_UART4_ROOT 191
> +#define IMX8MM_CLK_USB1_CTRL_ROOT 192
> +#define IMX8MM_CLK_GPU3D_ROOT 193
> +#define IMX8MM_CLK_USDHC1_ROOT 194
> +#define IMX8MM_CLK_USDHC2_ROOT 195
> +#define IMX8MM_CLK_WDOG1_ROOT 196
> +#define IMX8MM_CLK_WDOG2_ROOT 197
> +#define IMX8MM_CLK_WDOG3_ROOT 198
> +#define IMX8MM_CLK_VPU_G1_ROOT 199
> +#define IMX8MM_CLK_GPU_BUS_ROOT 200
> +#define IMX8MM_CLK_VPU_H1_ROOT 201
> +#define IMX8MM_CLK_VPU_G2_ROOT 202
> +#define IMX8MM_CLK_PDM_ROOT 203
> +#define IMX8MM_CLK_DISP_ROOT 204
> +#define IMX8MM_CLK_DISP_AXI_ROOT 205
> +#define IMX8MM_CLK_DISP_APB_ROOT 206
> +#define IMX8MM_CLK_DISP_RTRM_ROOT 207
> +#define IMX8MM_CLK_USDHC3_ROOT 208
> +#define IMX8MM_CLK_TMU_ROOT 209
> +#define IMX8MM_CLK_VPU_DEC_ROOT 210
> +#define IMX8MM_CLK_SDMA1_ROOT 211
> +#define IMX8MM_CLK_SDMA2_ROOT 212
> +#define IMX8MM_CLK_SDMA3_ROOT 213
> +#define IMX8MM_CLK_GPT_3M 214
> +#define IMX8MM_CLK_ARM 215
> +#define IMX8MM_CLK_PDM_IPG 216
> +#define IMX8MM_CLK_GPU2D_ROOT 217
> +#define IMX8MM_CLK_MU_ROOT 218
> +#define IMX8MM_CLK_CSI1_ROOT 219
> +
> +#define IMX8MM_CLK_DRAM_CORE 220
> +#define IMX8MM_CLK_DRAM_ALT_ROOT 221
> +
> +#define IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK 222
> +
> +#define IMX8MM_CLK_END 223
> +
> +#endif
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2019-01-21 20:33 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-08 9:00 [PATCH 1/3] clk: imx: Add PLLs driver for imx8mm soc Jacky Bai
2019-01-08 9:00 ` [PATCH 2/3] dt-bindings: imx: Add clock binding doc for imx8mm Jacky Bai
2019-01-09 20:36 ` Stephen Boyd
2019-01-10 1:59 ` Jacky Bai
2019-01-21 20:33 ` Rob Herring
2019-01-08 9:01 ` [PATCH 3/3] clk: imx: Add clock driver support " Jacky Bai
2019-01-09 20:32 ` Stephen Boyd
2019-01-10 2:14 ` Jacky Bai
2019-01-09 20:35 ` [PATCH 1/3] clk: imx: Add PLLs driver for imx8mm soc Stephen Boyd
2019-01-10 2:09 ` Jacky Bai
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).