All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH V4 0/4] Prepare i.MX8MM clk
@ 2019-08-19  7:53 Peng Fan
  2019-08-19  7:53 ` [U-Boot] [PATCH V4 1/4] clk: imx: expose CCF entry for all Peng Fan
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Peng Fan @ 2019-08-19  7:53 UTC (permalink / raw)
  To: u-boot

V4:
 1/4: Expose CCF for all
 2/4: Improve commit log
 3/4: Typo fix
 4/4: Drop unneeded initialization

V3:
 2/4: Fix RST/BYPASS seq issue to avoid glitch
 4/4: ARM clk not use 24M for switch, use pll2_500m  Add R-b/A-b tag
      Fix pll gate shift bit.

V2:
 2/4: fix MASK/SHIFT usage

This is to support i.MX8MM clk driver.
i.MX8MM use similar clock design as i.MX7D, but it has use
different PLL, so we need to add pll14xx driver. And to simplify
the clock usage, import the composite clk driver from Linux Kernel,
then we could have simple clk tree.


Peng Fan (4):
  clk: imx: expose CCF entry for all
  clk: imx: add pll14xx driver
  clk: imx: add i.MX8M composite clk support
  clk: imx: add i.MX8MM clk driver

 drivers/clk/Kconfig                |   2 -
 drivers/clk/imx/Kconfig            |  16 ++
 drivers/clk/imx/Makefile           |   2 +
 drivers/clk/imx/clk-composite-8m.c | 170 +++++++++++++++
 drivers/clk/imx/clk-imx8mm.c       | 415 +++++++++++++++++++++++++++++++++++++
 drivers/clk/imx/clk-pll14xx.c      | 381 ++++++++++++++++++++++++++++++++++
 drivers/clk/imx/clk.h              |  25 +++
 7 files changed, 1009 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/imx/clk-composite-8m.c
 create mode 100644 drivers/clk/imx/clk-imx8mm.c
 create mode 100644 drivers/clk/imx/clk-pll14xx.c

-- 
2.16.4

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH V4 1/4] clk: imx: expose CCF entry for all
  2019-08-19  7:53 [U-Boot] [PATCH V4 0/4] Prepare i.MX8MM clk Peng Fan
@ 2019-08-19  7:53 ` Peng Fan
  2019-08-19  7:53 ` [U-Boot] [PATCH V4 2/4] clk: imx: add pll14xx driver Peng Fan
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Peng Fan @ 2019-08-19  7:53 UTC (permalink / raw)
  To: u-boot

Expose CCF entry, then we could avoid expand the SoC support list

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/clk/Kconfig     |  2 --
 drivers/clk/imx/Kconfig | 16 ++++++++++++++++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index a3f0171b45..82cd8f623c 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -48,7 +48,6 @@ config CLK_BOSTON
 
 config SPL_CLK_CCF
 	bool "SPL Common Clock Framework [CCF] support "
-	depends on SPL_CLK_IMX6Q
 	help
 	  Enable this option if you want to (re-)use the Linux kernel's Common
 	  Clock Framework [CCF] code in U-Boot's SPL.
@@ -62,7 +61,6 @@ config SPL_CLK_COMPOSITE_CCF
 
 config CLK_CCF
 	bool "Common Clock Framework [CCF] support "
-	depends on CLK_IMX6Q || SANDBOX_CLK_CCF
 	help
 	  Enable this option if you want to (re-)use the Linux kernel's Common
 	  Clock Framework [CCF] code in U-Boot's clock driver.
diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index 3e6a980c8c..aae69cf9b0 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -20,3 +20,19 @@ config CLK_IMX8
 	select CLK
 	help
 	  This enables support clock driver for i.MX8 platforms.
+
+config SPL_CLK_IMX8MM
+	bool "SPL clock support for i.MX8MM"
+	depends on ARCH_IMX8M && SPL
+	select SPL_CLK
+	select SPL_CLK_CCF
+	help
+	  This enables SPL DM/DTS support for clock driver in i.MX8MM
+
+config CLK_IMX8MM
+	bool "Clock support for i.MX8MM"
+	depends on ARCH_IMX8M
+	select CLK
+	select CLK_CCF
+	help
+	  This enables support clock driver for i.MX8MM platforms.
-- 
2.16.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH V4 2/4] clk: imx: add pll14xx driver
  2019-08-19  7:53 [U-Boot] [PATCH V4 0/4] Prepare i.MX8MM clk Peng Fan
  2019-08-19  7:53 ` [U-Boot] [PATCH V4 1/4] clk: imx: expose CCF entry for all Peng Fan
@ 2019-08-19  7:53 ` Peng Fan
  2019-08-19  7:54 ` [U-Boot] [PATCH V4 3/4] clk: imx: add i.MX8M composite clk support Peng Fan
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Peng Fan @ 2019-08-19  7:53 UTC (permalink / raw)
  To: u-boot

Add pll14xx driver for i.MX8MM usage, modifed
from Linux Kernel 5.3.0-rc1

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/clk/imx/clk-pll14xx.c | 381 ++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/imx/clk.h         |  25 +++
 2 files changed, 406 insertions(+)
 create mode 100644 drivers/clk/imx/clk-pll14xx.c

diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
new file mode 100644
index 0000000000..2246beb21b
--- /dev/null
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -0,0 +1,381 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2017-2019 NXP.
+ *
+ * Peng Fan <peng.fan@nxp.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <linux/clk-provider.h>
+#include <linux/iopoll.h>
+#include <clk.h>
+#include <div64.h>
+
+#include "clk.h"
+
+#define UBOOT_DM_CLK_IMX_PLL1443X "imx_clk_pll1443x"
+#define UBOOT_DM_CLK_IMX_PLL1416X "imx_clk_pll1416x"
+
+#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)
+
+#define LOCK_TIMEOUT_US		10000
+
+struct clk_pll14xx {
+	struct clk			clk;
+	void __iomem			*base;
+	enum imx_pll14xx_type		type;
+	const struct imx_pll14xx_rate_table *rate_table;
+	int rate_count;
+};
+
+#define to_clk_pll14xx(_clk) container_of(_clk, struct clk_pll14xx, clk)
+
+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 unsigned long clk_pll1416x_recalc_rate(struct clk *clk)
+{
+	struct clk_pll14xx *pll = to_clk_pll14xx(dev_get_clk_ptr(clk->dev));
+	u64 fvco = clk_get_parent_rate(clk);
+	u32 mdiv, pdiv, sdiv, pll_div;
+
+	pll_div = readl(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 fvco;
+}
+
+static unsigned long clk_pll1443x_recalc_rate(struct clk *clk)
+{
+	struct clk_pll14xx *pll = to_clk_pll14xx(dev_get_clk_ptr(clk->dev));
+	u64 fvco = clk_get_parent_rate(clk);
+	u32 mdiv, pdiv, sdiv, pll_div_ctl0, pll_div_ctl1;
+	short int kdiv;
+
+	pll_div_ctl0 = readl(pll->base + 4);
+	pll_div_ctl1 = readl(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 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_MASK) >> MDIV_SHIFT;
+	old_pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
+
+	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_MASK) >> MDIV_SHIFT;
+	old_pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT;
+	old_kdiv = (pll_div_ctl1 & KDIV_MASK) >> KDIV_SHIFT;
+
+	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_MASK) >> MDIV_SHIFT;
+	old_pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT;
+	old_kdiv = (pll_div_ctl1 & KDIV_MASK) >> KDIV_SHIFT;
+
+	return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
+		rate->kdiv != old_kdiv;
+}
+
+static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll)
+{
+	u32 val;
+
+	return readl_poll_timeout(pll->base, val, val & LOCK_TIMEOUT_US,
+			LOCK_TIMEOUT_US);
+}
+
+static ulong clk_pll1416x_set_rate(struct clk *clk, unsigned long drate)
+{
+	struct clk_pll14xx *pll = to_clk_pll14xx(dev_get_clk_ptr(clk->dev));
+	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, "xxxx");
+		return -EINVAL;
+	}
+
+	tmp = readl(pll->base + 4);
+
+	if (!clk_pll1416x_mp_change(rate, tmp)) {
+		tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
+		tmp |= rate->sdiv << SDIV_SHIFT;
+		writel(tmp, pll->base + 4);
+
+		return clk_pll1416x_recalc_rate(clk);
+	}
+
+	/* Bypass clock and set lock to pll output lock */
+	tmp = readl(pll->base);
+	tmp |= LOCK_SEL_MASK;
+	writel(tmp, pll->base);
+
+	/* Enable RST */
+	tmp &= ~RST_MASK;
+	writel(tmp, pll->base);
+
+	/* Enable BYPASS */
+	tmp |= BYPASS_MASK;
+	writel(tmp, pll->base);
+
+
+	div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
+		(rate->sdiv << SDIV_SHIFT);
+	writel(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(tmp, pll->base);
+
+	/* Wait Lock */
+	ret = clk_pll14xx_wait_lock(pll);
+	if (ret)
+		return ret;
+
+	/* Bypass */
+	tmp &= ~BYPASS_MASK;
+	writel(tmp, pll->base);
+
+	return clk_pll1416x_recalc_rate(clk);
+}
+
+static ulong clk_pll1443x_set_rate(struct clk *clk, unsigned long drate)
+{
+	struct clk_pll14xx *pll = to_clk_pll14xx(dev_get_clk_ptr(clk->dev));
+	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, "===");
+		return -EINVAL;
+	}
+
+	tmp = readl(pll->base + 4);
+	div_val = readl(pll->base + 8);
+
+	if (!clk_pll1443x_mpk_change(rate, tmp, div_val)) {
+		tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
+		tmp |= rate->sdiv << SDIV_SHIFT;
+		writel(tmp, pll->base + 4);
+
+		return clk_pll1443x_recalc_rate(clk);
+	}
+
+	tmp = readl(pll->base);
+
+	/* Enable RST */
+	tmp &= ~RST_MASK;
+	writel(tmp, pll->base);
+
+	/* Enable BYPASS */
+	tmp |= BYPASS_MASK;
+	writel(tmp, pll->base);
+
+	div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
+		(rate->sdiv << SDIV_SHIFT);
+	writel(div_val, pll->base + 0x4);
+	writel(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(tmp, pll->base);
+
+	/* Wait Lock*/
+	ret = clk_pll14xx_wait_lock(pll);
+	if (ret)
+		return ret;
+
+	/* Bypass */
+	tmp &= ~BYPASS_MASK;
+	writel(tmp, pll->base);
+
+	return clk_pll1443x_recalc_rate(clk);
+}
+
+static int clk_pll14xx_prepare(struct clk *clk)
+{
+	struct clk_pll14xx *pll = to_clk_pll14xx(dev_get_clk_ptr(clk->dev));
+	u32 val;
+
+	/*
+	 * RESETB = 1 from 0, PLL starts its normal
+	 * operation after lock time
+	 */
+	val = readl(pll->base + GNRL_CTL);
+	val |= RST_MASK;
+	writel(val, pll->base + GNRL_CTL);
+
+	return clk_pll14xx_wait_lock(pll);
+}
+
+static int clk_pll14xx_unprepare(struct clk *clk)
+{
+	struct clk_pll14xx *pll = to_clk_pll14xx(dev_get_clk_ptr(clk->dev));
+	u32 val;
+
+	/*
+	 * Set RST to 0, power down mode is enabled and
+	 * every digital block is reset
+	 */
+	val = readl(pll->base + GNRL_CTL);
+	val &= ~RST_MASK;
+	writel(val, pll->base + GNRL_CTL);
+
+	return 0;
+}
+
+static const struct clk_ops clk_pll1416x_ops = {
+	.enable		= clk_pll14xx_prepare,
+	.disable	= clk_pll14xx_unprepare,
+	.set_rate	= clk_pll1416x_set_rate,
+	.get_rate	= clk_pll1416x_recalc_rate,
+};
+
+static const struct clk_ops clk_pll1443x_ops = {
+	.enable		= clk_pll14xx_prepare,
+	.disable	= clk_pll14xx_unprepare,
+	.set_rate	= clk_pll1443x_set_rate,
+	.get_rate	= clk_pll1443x_recalc_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;
+	char *type_name;
+	int ret;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	switch (pll_clk->type) {
+	case PLL_1416X:
+		type_name = UBOOT_DM_CLK_IMX_PLL1416X;
+		break;
+	case PLL_1443X:
+		type_name = UBOOT_DM_CLK_IMX_PLL1443X;
+		break;
+	default:
+		pr_err("%s: Unknown pll type for pll clk %s\n",
+		       __func__, name);
+		return ERR_PTR(-EINVAL);
+	};
+
+	pll->base = base;
+	pll->type = pll_clk->type;
+	pll->rate_table = pll_clk->rate_table;
+	pll->rate_count = pll_clk->rate_count;
+
+	clk = &pll->clk;
+
+	ret = clk_register(clk, type_name, name, parent_name);
+	if (ret) {
+		pr_err("%s: failed to register pll %s %d\n",
+		       __func__, name, ret);
+		kfree(pll);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
+
+U_BOOT_DRIVER(clk_pll1443x) = {
+	.name	= UBOOT_DM_CLK_IMX_PLL1443X,
+	.id	= UCLASS_CLK,
+	.ops	= &clk_pll1443x_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(clk_pll1416x) = {
+	.name	= UBOOT_DM_CLK_IMX_PLL1416X,
+	.id	= UCLASS_CLK,
+	.ops	= &clk_pll1416x_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 1d480d8722..4956e04a92 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -20,6 +20,31 @@ enum imx_pllv3_type {
 	IMX_PLLV3_DDR_IMX7,
 };
 
+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 rate_count;
+	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 *clk_register_gate2(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 bit_idx, u8 cgr_val,
-- 
2.16.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH V4 3/4] clk: imx: add i.MX8M composite clk support
  2019-08-19  7:53 [U-Boot] [PATCH V4 0/4] Prepare i.MX8MM clk Peng Fan
  2019-08-19  7:53 ` [U-Boot] [PATCH V4 1/4] clk: imx: expose CCF entry for all Peng Fan
  2019-08-19  7:53 ` [U-Boot] [PATCH V4 2/4] clk: imx: add pll14xx driver Peng Fan
@ 2019-08-19  7:54 ` Peng Fan
  2019-08-19  7:54 ` [U-Boot] [PATCH V4 4/4] clk: imx: add i.MX8MM clk driver Peng Fan
  2019-08-20 11:05 ` [U-Boot] [PATCH V4 0/4] Prepare i.MX8MM clk Lukasz Majewski
  4 siblings, 0 replies; 8+ messages in thread
From: Peng Fan @ 2019-08-19  7:54 UTC (permalink / raw)
  To: u-boot

Import i.MX8M composite clk from Linux Kernel 5.3.0-rc2

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/clk/imx/clk-composite-8m.c | 170 +++++++++++++++++++++++++++++++++++++
 1 file changed, 170 insertions(+)
 create mode 100644 drivers/clk/imx/clk-composite-8m.c

diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c
new file mode 100644
index 0000000000..95120d6559
--- /dev/null
+++ b/drivers/clk/imx/clk-composite-8m.c
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 NXP
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <linux/clk-provider.h>
+#include <clk.h>
+#include "clk.h"
+
+#define UBOOT_DM_CLK_IMX_COMPOSITE "imx_clk_composite"
+
+#define PCG_PREDIV_SHIFT	16
+#define PCG_PREDIV_WIDTH	3
+#define PCG_PREDIV_MAX		8
+
+#define PCG_DIV_SHIFT		0
+#define PCG_DIV_WIDTH		6
+#define PCG_DIV_MAX		64
+
+#define PCG_PCS_SHIFT		24
+#define PCG_PCS_MASK		0x7
+
+#define PCG_CGC_SHIFT		28
+
+static unsigned long imx8m_clk_composite_divider_recalc_rate(struct clk *clk)
+{
+	struct clk_divider *divider = (struct clk_divider *)to_clk_divider(clk);
+	struct clk_composite *composite = (struct clk_composite *)clk->data;
+	ulong parent_rate = clk_get_parent_rate(&composite->clk);
+	unsigned long prediv_rate;
+	unsigned int prediv_value;
+	unsigned int div_value;
+
+	debug("%s: name %s prate: %lu reg: %p\n", __func__,
+	      (&composite->clk)->dev->name, parent_rate, divider->reg);
+	prediv_value = readl(divider->reg) >> divider->shift;
+	prediv_value &= clk_div_mask(divider->width);
+
+	prediv_rate = divider_recalc_rate(clk, parent_rate, prediv_value,
+					  NULL, divider->flags,
+					  divider->width);
+
+	div_value = readl(divider->reg) >> PCG_DIV_SHIFT;
+	div_value &= clk_div_mask(PCG_DIV_WIDTH);
+
+	return divider_recalc_rate(clk, prediv_rate, div_value, NULL,
+				   divider->flags, PCG_DIV_WIDTH);
+}
+
+static int imx8m_clk_composite_compute_dividers(unsigned long rate,
+						unsigned long parent_rate,
+						int *prediv, int *postdiv)
+{
+	int div1, div2;
+	int error = INT_MAX;
+	int ret = -EINVAL;
+
+	*prediv = 1;
+	*postdiv = 1;
+
+	for (div1 = 1; div1 <= PCG_PREDIV_MAX; div1++) {
+		for (div2 = 1; div2 <= PCG_DIV_MAX; div2++) {
+			int new_error = ((parent_rate / div1) / div2) - rate;
+
+			if (abs(new_error) < abs(error)) {
+				*prediv = div1;
+				*postdiv = div2;
+				error = new_error;
+				ret = 0;
+			}
+		}
+	}
+	return ret;
+}
+
+/*
+ * The clk are bound to a dev, because it is part of composite clk
+ * use composite clk to get dev
+ */
+static ulong imx8m_clk_composite_divider_set_rate(struct clk *clk,
+						  unsigned long rate)
+{
+	struct clk_divider *divider = (struct clk_divider *)to_clk_divider(clk);
+	struct clk_composite *composite = (struct clk_composite *)clk->data;
+	ulong parent_rate = clk_get_parent_rate(&composite->clk);
+	int prediv_value;
+	int div_value;
+	int ret;
+	u32 val;
+
+	ret = imx8m_clk_composite_compute_dividers(rate, parent_rate,
+						   &prediv_value, &div_value);
+	if (ret)
+		return ret;
+
+	val = readl(divider->reg);
+	val &= ~((clk_div_mask(divider->width) << divider->shift) |
+			(clk_div_mask(PCG_DIV_WIDTH) << PCG_DIV_SHIFT));
+
+	val |= (u32)(prediv_value  - 1) << divider->shift;
+	val |= (u32)(div_value - 1) << PCG_DIV_SHIFT;
+	writel(val, divider->reg);
+
+	return clk_get_rate(&composite->clk);
+}
+
+static const struct clk_ops imx8m_clk_composite_divider_ops = {
+	.get_rate = imx8m_clk_composite_divider_recalc_rate,
+	.set_rate = imx8m_clk_composite_divider_set_rate,
+};
+
+struct clk *imx8m_clk_composite_flags(const char *name,
+				      const char * const *parent_names,
+				      int num_parents, void __iomem *reg,
+				      unsigned long flags)
+{
+	struct clk *clk = ERR_PTR(-ENOMEM);
+	struct clk_divider *div = NULL;
+	struct clk_gate *gate = NULL;
+	struct clk_mux *mux = NULL;
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		goto fail;
+
+	mux->reg = reg;
+	mux->shift = PCG_PCS_SHIFT;
+	mux->mask = PCG_PCS_MASK;
+	mux->num_parents = num_parents;
+	mux->flags = flags;
+	mux->parent_names = parent_names;
+
+	div = kzalloc(sizeof(*div), GFP_KERNEL);
+	if (!div)
+		goto fail;
+
+	div->reg = reg;
+	div->shift = PCG_PREDIV_SHIFT;
+	div->width = PCG_PREDIV_WIDTH;
+	div->flags = CLK_DIVIDER_ROUND_CLOSEST | flags;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		goto fail;
+
+	gate->reg = reg;
+	gate->bit_idx = PCG_CGC_SHIFT;
+	gate->flags = flags;
+
+	clk = clk_register_composite(NULL, name,
+				     parent_names, num_parents,
+				     &mux->clk, &clk_mux_ops, &div->clk,
+				     &imx8m_clk_composite_divider_ops,
+				     &gate->clk, &clk_gate_ops, flags);
+	if (IS_ERR(clk))
+		goto fail;
+
+	return clk;
+
+fail:
+	kfree(gate);
+	kfree(div);
+	kfree(mux);
+	return ERR_CAST(clk);
+}
-- 
2.16.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH V4 4/4] clk: imx: add i.MX8MM clk driver
  2019-08-19  7:53 [U-Boot] [PATCH V4 0/4] Prepare i.MX8MM clk Peng Fan
                   ` (2 preceding siblings ...)
  2019-08-19  7:54 ` [U-Boot] [PATCH V4 3/4] clk: imx: add i.MX8M composite clk support Peng Fan
@ 2019-08-19  7:54 ` Peng Fan
  2019-08-20 11:05 ` [U-Boot] [PATCH V4 0/4] Prepare i.MX8MM clk Lukasz Majewski
  4 siblings, 0 replies; 8+ messages in thread
From: Peng Fan @ 2019-08-19  7:54 UTC (permalink / raw)
  To: u-boot

Add i.MX8MM clk driver support.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/clk/imx/Makefile     |   2 +
 drivers/clk/imx/clk-imx8mm.c | 415 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 417 insertions(+)
 create mode 100644 drivers/clk/imx/clk-imx8mm.c

diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 105a58ca90..5ad7967fe9 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -10,3 +10,5 @@ ifdef CONFIG_CLK_IMX8
 obj-$(CONFIG_IMX8QXP) += clk-imx8qxp.o
 obj-$(CONFIG_IMX8QM) += clk-imx8qm.o
 endif
+obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MM) += clk-imx8mm.o clk-pll14xx.o \
+				clk-composite-8m.o
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
new file mode 100644
index 0000000000..f4913e70ab
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -0,0 +1,415 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 NXP
+ * Peng Fan <peng.fan@nxp.com>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <dt-bindings/clock/imx8mm-clock.h>
+
+#include "clk.h"
+
+#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_drampll_tbl[] = {
+	PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+};
+
+static struct imx_pll14xx_clk imx8mm_dram_pll __initdata = {
+		.type = PLL_1443X,
+		.rate_table = imx8mm_drampll_tbl,
+		.rate_count = ARRAY_SIZE(imx8mm_drampll_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mm_arm_pll __initdata = {
+		.type = PLL_1416X,
+		.rate_table = imx8mm_pll1416x_tbl,
+		.rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mm_sys_pll __initdata = {
+		.type = PLL_1416X,
+		.rate_table = imx8mm_pll1416x_tbl,
+		.rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
+};
+
+static const char *pll_ref_sels[] = { "clock-osc-24m", "dummy", "dummy", "dummy", };
+static const char *dram_pll_bypass_sels[] = {"dram_pll", "dram_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", };
+
+static const char *imx8mm_a53_sels[] = {"clock-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_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_enet_axi_sels[] = {"clock-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[] = {"clock-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_usdhc1_sels[] = {"clock-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[] = {"clock-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[] = {"clock-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[] = {"clock-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[] = {"clock-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[] = {"clock-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_wdog_sels[] = {"clock-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_usdhc3_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
+					   "sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", };
+
+static ulong imx8mm_clk_get_rate(struct clk *clk)
+{
+	struct clk *c;
+	int ret;
+
+	debug("%s(#%lu)\n", __func__, clk->id);
+
+	ret = clk_get_by_id(clk->id, &c);
+	if (ret)
+		return ret;
+
+	return clk_get_rate(c);
+}
+
+static ulong imx8mm_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	struct clk *c;
+	int ret;
+
+	debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
+
+	ret = clk_get_by_id(clk->id, &c);
+	if (ret)
+		return ret;
+
+	return clk_set_rate(c, rate);
+}
+
+static int __imx8mm_clk_enable(struct clk *clk, bool enable)
+{
+	struct clk *c;
+	int ret;
+
+	debug("%s(#%lu) en: %d\n", __func__, clk->id, enable);
+
+	ret = clk_get_by_id(clk->id, &c);
+	if (ret)
+		return ret;
+
+	if (enable)
+		ret = clk_enable(c);
+	else
+		ret = clk_disable(c);
+
+	return ret;
+}
+
+static int imx8mm_clk_disable(struct clk *clk)
+{
+	return __imx8mm_clk_enable(clk, 0);
+}
+
+static int imx8mm_clk_enable(struct clk *clk)
+{
+	return __imx8mm_clk_enable(clk, 1);
+}
+
+static struct clk_ops imx8mm_clk_ops = {
+	.set_rate = imx8mm_clk_set_rate,
+	.get_rate = imx8mm_clk_get_rate,
+	.enable = imx8mm_clk_enable,
+	.disable = imx8mm_clk_disable,
+};
+
+static int imx8mm_clk_probe(struct udevice *dev)
+{
+	void __iomem *base;
+
+	base = (void *)ANATOP_BASE_ADDR;
+
+	clk_dm(IMX8MM_DRAM_PLL_REF_SEL,
+	       imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+	clk_dm(IMX8MM_ARM_PLL_REF_SEL,
+	       imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+	clk_dm(IMX8MM_SYS_PLL1_REF_SEL,
+	       imx_clk_mux("sys_pll1_ref_sel", base + 0x94, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+	clk_dm(IMX8MM_SYS_PLL2_REF_SEL,
+	       imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+	clk_dm(IMX8MM_SYS_PLL3_REF_SEL,
+	       imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+
+	clk_dm(IMX8MM_DRAM_PLL,
+	       imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel",
+			       base + 0x50, &imx8mm_dram_pll));
+	clk_dm(IMX8MM_ARM_PLL,
+	       imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel",
+			       base + 0x84, &imx8mm_arm_pll));
+	clk_dm(IMX8MM_SYS_PLL1,
+	       imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel",
+			       base + 0x94, &imx8mm_sys_pll));
+	clk_dm(IMX8MM_SYS_PLL2,
+	       imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel",
+			       base + 0x104, &imx8mm_sys_pll));
+	clk_dm(IMX8MM_SYS_PLL3,
+	       imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel",
+			       base + 0x114, &imx8mm_sys_pll));
+
+	/* PLL bypass out */
+	clk_dm(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));
+	clk_dm(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));
+	clk_dm(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));
+	clk_dm(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));
+	clk_dm(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));
+
+	/* PLL out gate */
+	clk_dm(IMX8MM_DRAM_PLL_OUT,
+	       imx_clk_gate("dram_pll_out", "dram_pll_bypass",
+			    base + 0x50, 13));
+	clk_dm(IMX8MM_ARM_PLL_OUT,
+	       imx_clk_gate("arm_pll_out", "arm_pll_bypass",
+			    base + 0x84, 11));
+	clk_dm(IMX8MM_SYS_PLL1_OUT,
+	       imx_clk_gate("sys_pll1_out", "sys_pll1_bypass",
+			    base + 0x94, 11));
+	clk_dm(IMX8MM_SYS_PLL2_OUT,
+	       imx_clk_gate("sys_pll2_out", "sys_pll2_bypass",
+			    base + 0x104, 11));
+	clk_dm(IMX8MM_SYS_PLL3_OUT,
+	       imx_clk_gate("sys_pll3_out", "sys_pll3_bypass",
+			    base + 0x114, 11));
+
+	/* SYS PLL fixed output */
+	clk_dm(IMX8MM_SYS_PLL1_40M,
+	       imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20));
+	clk_dm(IMX8MM_SYS_PLL1_80M,
+	       imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10));
+	clk_dm(IMX8MM_SYS_PLL1_100M,
+	       imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8));
+	clk_dm(IMX8MM_SYS_PLL1_133M,
+	       imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6));
+	clk_dm(IMX8MM_SYS_PLL1_160M,
+	       imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5));
+	clk_dm(IMX8MM_SYS_PLL1_200M,
+	       imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4));
+	clk_dm(IMX8MM_SYS_PLL1_266M,
+	       imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3));
+	clk_dm(IMX8MM_SYS_PLL1_400M,
+	       imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2));
+	clk_dm(IMX8MM_SYS_PLL1_800M,
+	       imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1));
+
+	clk_dm(IMX8MM_SYS_PLL2_50M,
+	       imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20));
+	clk_dm(IMX8MM_SYS_PLL2_100M,
+	       imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10));
+	clk_dm(IMX8MM_SYS_PLL2_125M,
+	       imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8));
+	clk_dm(IMX8MM_SYS_PLL2_166M,
+	       imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6));
+	clk_dm(IMX8MM_SYS_PLL2_200M,
+	       imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5));
+	clk_dm(IMX8MM_SYS_PLL2_250M,
+	       imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4));
+	clk_dm(IMX8MM_SYS_PLL2_333M,
+	       imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3));
+	clk_dm(IMX8MM_SYS_PLL2_500M,
+	       imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2));
+	clk_dm(IMX8MM_SYS_PLL2_1000M,
+	       imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1));
+
+	base = dev_read_addr_ptr(dev);
+	if (base == (void *)FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	clk_dm(IMX8MM_CLK_A53_SRC,
+	       imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3,
+			    imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels)));
+	clk_dm(IMX8MM_CLK_A53_CG,
+	       imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28));
+	clk_dm(IMX8MM_CLK_A53_DIV,
+	       imx_clk_divider2("arm_a53_div", "arm_a53_cg",
+				base + 0x8000, 0, 3));
+
+	clk_dm(IMX8MM_CLK_AHB,
+	       imx8m_clk_composite_critical("ahb", imx8mm_ahb_sels,
+					    base + 0x9000));
+	clk_dm(IMX8MM_CLK_IPG_ROOT,
+	       imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1));
+
+	clk_dm(IMX8MM_CLK_ENET_AXI,
+	       imx8m_clk_composite("enet_axi", imx8mm_enet_axi_sels,
+				   base + 0x8880));
+	clk_dm(IMX8MM_CLK_NAND_USDHC_BUS,
+	       imx8m_clk_composite_critical("nand_usdhc_bus",
+					    imx8mm_nand_usdhc_sels,
+					    base + 0x8900));
+
+	/* IP */
+	clk_dm(IMX8MM_CLK_USDHC1,
+	       imx8m_clk_composite("usdhc1", imx8mm_usdhc1_sels,
+				   base + 0xac00));
+	clk_dm(IMX8MM_CLK_USDHC2,
+	       imx8m_clk_composite("usdhc2", imx8mm_usdhc2_sels,
+				   base + 0xac80));
+	clk_dm(IMX8MM_CLK_I2C1,
+	       imx8m_clk_composite("i2c1", imx8mm_i2c1_sels, base + 0xad00));
+	clk_dm(IMX8MM_CLK_I2C2,
+	       imx8m_clk_composite("i2c2", imx8mm_i2c2_sels, base + 0xad80));
+	clk_dm(IMX8MM_CLK_I2C3,
+	       imx8m_clk_composite("i2c3", imx8mm_i2c3_sels, base + 0xae00));
+	clk_dm(IMX8MM_CLK_I2C4,
+	       imx8m_clk_composite("i2c4", imx8mm_i2c4_sels, base + 0xae80));
+	clk_dm(IMX8MM_CLK_WDOG,
+	       imx8m_clk_composite("wdog", imx8mm_wdog_sels, base + 0xb900));
+	clk_dm(IMX8MM_CLK_USDHC3,
+	       imx8m_clk_composite("usdhc3", imx8mm_usdhc3_sels,
+				   base + 0xbc80));
+
+	clk_dm(IMX8MM_CLK_I2C1_ROOT,
+	       imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0));
+	clk_dm(IMX8MM_CLK_I2C2_ROOT,
+	       imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0));
+	clk_dm(IMX8MM_CLK_I2C3_ROOT,
+	       imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0));
+	clk_dm(IMX8MM_CLK_I2C4_ROOT,
+	       imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0));
+	clk_dm(IMX8MM_CLK_OCOTP_ROOT,
+	       imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0));
+	clk_dm(IMX8MM_CLK_USDHC1_ROOT,
+	       imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0));
+	clk_dm(IMX8MM_CLK_USDHC2_ROOT,
+	       imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0));
+	clk_dm(IMX8MM_CLK_WDOG1_ROOT,
+	       imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0));
+	clk_dm(IMX8MM_CLK_WDOG2_ROOT,
+	       imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0));
+	clk_dm(IMX8MM_CLK_WDOG3_ROOT,
+	       imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0));
+	clk_dm(IMX8MM_CLK_USDHC3_ROOT,
+	       imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0));
+
+#ifdef CONFIG_SPL_BUILD
+	struct clk *clkp, *clkp1;
+
+	clk_get_by_id(IMX8MM_CLK_WDOG1_ROOT, &clkp);
+	clk_enable(clkp);
+	clk_get_by_id(IMX8MM_CLK_WDOG2_ROOT, &clkp);
+	clk_enable(clkp);
+	clk_get_by_id(IMX8MM_CLK_WDOG3_ROOT, &clkp);
+	clk_enable(clkp);
+
+	/* Configure SYS_PLL3 to 750MHz */
+	clk_get_by_id(IMX8MM_SYS_PLL3, &clkp);
+	clk_set_rate(clkp, 750000000UL);
+	clk_enable(clkp);
+
+	/* Configure ARM to sys_pll2_500m */
+	clk_get_by_id(IMX8MM_CLK_A53_SRC, &clkp);
+	clk_get_by_id(IMX8MM_SYS_PLL2_OUT, &clkp1);
+	clk_enable(clkp1);
+	clk_get_by_id(IMX8MM_SYS_PLL2_500M, &clkp1);
+	clk_set_parent(clkp, clkp1);
+
+	/* Configure ARM PLL to 1.2GHz */
+	clk_get_by_id(IMX8MM_ARM_PLL, &clkp1);
+	clk_set_rate(clkp1, 1200000000UL);
+	clk_get_by_id(IMX8MM_ARM_PLL_OUT, &clkp1);
+	clk_enable(clkp1);
+	clk_set_parent(clkp, clkp1);
+
+	/* Configure DIV to 1.2GHz */
+	clk_get_by_id(IMX8MM_CLK_A53_DIV, &clkp1);
+	clk_set_rate(clkp1, 1200000000UL);
+#endif
+
+	return 0;
+}
+
+static const struct udevice_id imx8mm_clk_ids[] = {
+	{ .compatible = "fsl,imx8mm-ccm" },
+	{ },
+};
+
+U_BOOT_DRIVER(imx8mm_clk) = {
+	.name = "clk_imx8mm",
+	.id = UCLASS_CLK,
+	.of_match = imx8mm_clk_ids,
+	.ops = &imx8mm_clk_ops,
+	.probe = imx8mm_clk_probe,
+	.flags = DM_FLAG_PRE_RELOC,
+};
-- 
2.16.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH V4 0/4] Prepare i.MX8MM clk
  2019-08-19  7:53 [U-Boot] [PATCH V4 0/4] Prepare i.MX8MM clk Peng Fan
                   ` (3 preceding siblings ...)
  2019-08-19  7:54 ` [U-Boot] [PATCH V4 4/4] clk: imx: add i.MX8MM clk driver Peng Fan
@ 2019-08-20 11:05 ` Lukasz Majewski
  2019-08-21  8:31   ` Peng Fan
  4 siblings, 1 reply; 8+ messages in thread
From: Lukasz Majewski @ 2019-08-20 11:05 UTC (permalink / raw)
  To: u-boot

Hi Peng,

> V4:
>  1/4: Expose CCF for all
>  2/4: Improve commit log
>  3/4: Typo fix
>  4/4: Drop unneeded initialization

Your patches cause some build breaks on sandbox:
https://travis-ci.org/lmajewski/u-boot-dfu/jobs/574198639

and TI:
https://travis-ci.org/lmajewski/u-boot-dfu/jobs/574198655

The branch which I've used for testing (with your commits):
https://github.com/lmajewski/u-boot-dfu/commits/testing

Please fix above errors and resend your patches.


> 
> V3:
>  2/4: Fix RST/BYPASS seq issue to avoid glitch
>  4/4: ARM clk not use 24M for switch, use pll2_500m  Add R-b/A-b tag
>       Fix pll gate shift bit.
> 
> V2:
>  2/4: fix MASK/SHIFT usage
> 
> This is to support i.MX8MM clk driver.
> i.MX8MM use similar clock design as i.MX7D, but it has use
> different PLL, so we need to add pll14xx driver. And to simplify
> the clock usage, import the composite clk driver from Linux Kernel,
> then we could have simple clk tree.
> 
> 
> Peng Fan (4):
>   clk: imx: expose CCF entry for all
>   clk: imx: add pll14xx driver
>   clk: imx: add i.MX8M composite clk support
>   clk: imx: add i.MX8MM clk driver
> 
>  drivers/clk/Kconfig                |   2 -
>  drivers/clk/imx/Kconfig            |  16 ++
>  drivers/clk/imx/Makefile           |   2 +
>  drivers/clk/imx/clk-composite-8m.c | 170 +++++++++++++++
>  drivers/clk/imx/clk-imx8mm.c       | 415
> +++++++++++++++++++++++++++++++++++++ drivers/clk/imx/clk-pll14xx.c
>    | 381 ++++++++++++++++++++++++++++++++++ drivers/clk/imx/clk.h
>          |  25 +++ 7 files changed, 1009 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/clk/imx/clk-composite-8m.c
>  create mode 100644 drivers/clk/imx/clk-imx8mm.c
>  create mode 100644 drivers/clk/imx/clk-pll14xx.c
> 



Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190820/f9b1a620/attachment.sig>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH V4 0/4] Prepare i.MX8MM clk
  2019-08-20 11:05 ` [U-Boot] [PATCH V4 0/4] Prepare i.MX8MM clk Lukasz Majewski
@ 2019-08-21  8:31   ` Peng Fan
  2019-08-21 13:39     ` Peng Fan
  0 siblings, 1 reply; 8+ messages in thread
From: Peng Fan @ 2019-08-21  8:31 UTC (permalink / raw)
  To: u-boot

> Subject: Re: [PATCH V4 0/4] Prepare i.MX8MM clk
> 
> Hi Peng,
> 
> > V4:
> >  1/4: Expose CCF for all
> >  2/4: Improve commit log
> >  3/4: Typo fix
> >  4/4: Drop unneeded initialization
> 
> Your patches cause some build breaks on sandbox:
> https://travis-ci.org/lmajewski/u-boot-dfu/jobs/574198639
> 
> and TI:
> https://travis-ci.org/lmajewski/u-boot-dfu/jobs/574198655
> 
> The branch which I've used for testing (with your commits):
> https://github.com/lmajewski/u-boot-dfu/commits/testing
> 
> Please fix above errors and resend your patches.

Sorry, I should run CI before posting patches. Will fix and send
new version patches.

Thanks,
Peng.

> 
> 
> >
> > V3:
> >  2/4: Fix RST/BYPASS seq issue to avoid glitch
> >  4/4: ARM clk not use 24M for switch, use pll2_500m  Add R-b/A-b tag
> >       Fix pll gate shift bit.
> >
> > V2:
> >  2/4: fix MASK/SHIFT usage
> >
> > This is to support i.MX8MM clk driver.
> > i.MX8MM use similar clock design as i.MX7D, but it has use different
> > PLL, so we need to add pll14xx driver. And to simplify the clock
> > usage, import the composite clk driver from Linux Kernel, then we
> > could have simple clk tree.
> >
> >
> > Peng Fan (4):
> >   clk: imx: expose CCF entry for all
> >   clk: imx: add pll14xx driver
> >   clk: imx: add i.MX8M composite clk support
> >   clk: imx: add i.MX8MM clk driver
> >
> >  drivers/clk/Kconfig                |   2 -
> >  drivers/clk/imx/Kconfig            |  16 ++
> >  drivers/clk/imx/Makefile           |   2 +
> >  drivers/clk/imx/clk-composite-8m.c | 170 +++++++++++++++
> >  drivers/clk/imx/clk-imx8mm.c       | 415
> > +++++++++++++++++++++++++++++++++++++ drivers/clk/imx/clk-pll14xx.c
> >    | 381 ++++++++++++++++++++++++++++++++++ drivers/clk/imx/clk.h
> >          |  25 +++ 7 files changed, 1009 insertions(+), 2 deletions(-)
> > create mode 100644 drivers/clk/imx/clk-composite-8m.c
> >  create mode 100644 drivers/clk/imx/clk-imx8mm.c  create mode
> 100644
> > drivers/clk/imx/clk-pll14xx.c
> >
> 
> 
> 
> Best regards,
> 
> Lukasz Majewski
> 
> --
> 
> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email:
> lukma at denx.de

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH V4 0/4] Prepare i.MX8MM clk
  2019-08-21  8:31   ` Peng Fan
@ 2019-08-21 13:39     ` Peng Fan
  0 siblings, 0 replies; 8+ messages in thread
From: Peng Fan @ 2019-08-21 13:39 UTC (permalink / raw)
  To: u-boot

Hi Lukasz

> Subject: RE: [PATCH V4 0/4] Prepare i.MX8MM clk
> 
> > Subject: Re: [PATCH V4 0/4] Prepare i.MX8MM clk
> >
> > Hi Peng,
> >
> > > V4:
> > >  1/4: Expose CCF for all
> > >  2/4: Improve commit log
> > >  3/4: Typo fix
> > >  4/4: Drop unneeded initialization
> >
> > Your patches cause some build breaks on sandbox:
> > https://travis-ci.org/lmajewski/u-boot-dfu/jobs/574198639
> >
> > and TI:
> > https://travis-ci.org/lmajewski/u-boot-dfu/jobs/574198655
> >
> > The branch which I've used for testing (with your commits):
> > https://github.com/lmajewski/u-boot-dfu/commits/testing
> >
> > Please fix above errors and resend your patches.

I just sent out new version patchset for enable_count
https://patchwork.ozlabs.org/patch/1150848/

This patchset is not changed.

CI: https://travis-ci.org/MrVan/u-boot/builds/574753709

Github: https://github.com/MrVan/u-boot/tree/ccf-8-24

Thanks,
Peng.

> 
> Sorry, I should run CI before posting patches. Will fix and send new version
> patches.
> 
> Thanks,
> Peng.
> 
> >
> >
> > >
> > > V3:
> > >  2/4: Fix RST/BYPASS seq issue to avoid glitch
> > >  4/4: ARM clk not use 24M for switch, use pll2_500m  Add R-b/A-b tag
> > >       Fix pll gate shift bit.
> > >
> > > V2:
> > >  2/4: fix MASK/SHIFT usage
> > >
> > > This is to support i.MX8MM clk driver.
> > > i.MX8MM use similar clock design as i.MX7D, but it has use different
> > > PLL, so we need to add pll14xx driver. And to simplify the clock
> > > usage, import the composite clk driver from Linux Kernel, then we
> > > could have simple clk tree.
> > >
> > >
> > > Peng Fan (4):
> > >   clk: imx: expose CCF entry for all
> > >   clk: imx: add pll14xx driver
> > >   clk: imx: add i.MX8M composite clk support
> > >   clk: imx: add i.MX8MM clk driver
> > >
> > >  drivers/clk/Kconfig                |   2 -
> > >  drivers/clk/imx/Kconfig            |  16 ++
> > >  drivers/clk/imx/Makefile           |   2 +
> > >  drivers/clk/imx/clk-composite-8m.c | 170 +++++++++++++++
> > >  drivers/clk/imx/clk-imx8mm.c       | 415
> > > +++++++++++++++++++++++++++++++++++++
> drivers/clk/imx/clk-pll14xx.c
> > >    | 381 ++++++++++++++++++++++++++++++++++ drivers/clk/imx/clk.h
> > >          |  25 +++ 7 files changed, 1009 insertions(+), 2
> > > deletions(-) create mode 100644 drivers/clk/imx/clk-composite-8m.c
> > >  create mode 100644 drivers/clk/imx/clk-imx8mm.c  create mode
> > 100644
> > > drivers/clk/imx/clk-pll14xx.c
> > >
> >
> >
> >
> > Best regards,
> >
> > Lukasz Majewski
> >
> > --
> >
> > DENX Software Engineering GmbH,      Managing Director: Wolfgang
> Denk
> > HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> > Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email:
> > lukma at denx.de

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2019-08-21 13:39 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-19  7:53 [U-Boot] [PATCH V4 0/4] Prepare i.MX8MM clk Peng Fan
2019-08-19  7:53 ` [U-Boot] [PATCH V4 1/4] clk: imx: expose CCF entry for all Peng Fan
2019-08-19  7:53 ` [U-Boot] [PATCH V4 2/4] clk: imx: add pll14xx driver Peng Fan
2019-08-19  7:54 ` [U-Boot] [PATCH V4 3/4] clk: imx: add i.MX8M composite clk support Peng Fan
2019-08-19  7:54 ` [U-Boot] [PATCH V4 4/4] clk: imx: add i.MX8MM clk driver Peng Fan
2019-08-20 11:05 ` [U-Boot] [PATCH V4 0/4] Prepare i.MX8MM clk Lukasz Majewski
2019-08-21  8:31   ` Peng Fan
2019-08-21 13:39     ` Peng Fan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.