All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/4] Add a clock driver for the imx8mq
@ 2022-03-15 13:08 Angus Ainslie
  2022-03-15 13:08 ` [PATCH v4 1/4] dt-bindings: imx8mq-clock: add mainline definitions Angus Ainslie
                   ` (3 more replies)
  0 siblings, 4 replies; 26+ messages in thread
From: Angus Ainslie @ 2022-03-15 13:08 UTC (permalink / raw)
  To: u-boot, Marek Vasut
  Cc: lukma, seanga2, sbabic, festevam, kernel, uboot-imx, peng.fan,
	Angus Ainslie

This is a DM clock driver for the imx8mq based on the linux kernel
driver and the u-boot imx8mm clock driver.

It also removes some code duplication in the imx8m[nmp] clock drivers.

Changes since v3:

Fixed driver spelling
Moved rate macros out of the header into the dot c

Changes since v2:

Added kernel commit IDs
Re-factored rate table code to remove duplication
Remove duplicate code by creating a common clk-imx8m

Changes since v1:

More verbose clock driver description
Added forgotten dt-bindings
Synced PLL frequencies with mainline kernel

Angus Ainslie (4):
  dt-bindings: imx8mq-clock: add mainline definitions
  clk: imx8mq: Add a clock driver for the imx8mq
  clk: imx8m: reduce rate table duplication
  clk: imx8m: remove code duplication

 drivers/clk/imx/Kconfig                  |  16 +
 drivers/clk/imx/Makefile                 |   8 +-
 drivers/clk/imx/clk-imx8m.c              | 108 ++++++
 drivers/clk/imx/clk-imx8m.h              |  12 +
 drivers/clk/imx/clk-imx8mm.c             | 149 +-------
 drivers/clk/imx/clk-imx8mn.c             | 149 +-------
 drivers/clk/imx/clk-imx8mp.c             | 156 +-------
 drivers/clk/imx/clk-imx8mq.c             | 441 +++++++++++++++++++++++
 drivers/clk/imx/clk-pll14xx.c            |  61 ++++
 drivers/clk/imx/clk.h                    |   4 +
 include/dt-bindings/clock/imx8mq-clock.h |  16 +-
 11 files changed, 688 insertions(+), 432 deletions(-)
 create mode 100644 drivers/clk/imx/clk-imx8m.c
 create mode 100644 drivers/clk/imx/clk-imx8m.h
 create mode 100644 drivers/clk/imx/clk-imx8mq.c

-- 
2.25.1


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

* [PATCH v4 1/4] dt-bindings: imx8mq-clock: add mainline definitions
  2022-03-15 13:08 [PATCH v4 0/4] Add a clock driver for the imx8mq Angus Ainslie
@ 2022-03-15 13:08 ` Angus Ainslie
  2022-03-15 13:08 ` [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq Angus Ainslie
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 26+ messages in thread
From: Angus Ainslie @ 2022-03-15 13:08 UTC (permalink / raw)
  To: u-boot, Marek Vasut
  Cc: lukma, seanga2, sbabic, festevam, kernel, uboot-imx, peng.fan,
	Angus Ainslie

Sync the clock ids with the mainline kernel

077de6e1c9f ("clk: imx8mq: add PLL monitor output")

Signed-off-by: Angus Ainslie <angus@akkea.ca>
Reviewed-by: Marek Vasut <marex@denx.de>
---
 include/dt-bindings/clock/imx8mq-clock.h | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/include/dt-bindings/clock/imx8mq-clock.h b/include/dt-bindings/clock/imx8mq-clock.h
index 9b8045d75b8..82e907ce7bd 100644
--- a/include/dt-bindings/clock/imx8mq-clock.h
+++ b/include/dt-bindings/clock/imx8mq-clock.h
@@ -431,6 +431,20 @@
 
 #define IMX8MQ_CLK_A53_CORE			289
 
-#define IMX8MQ_CLK_END				290
+#define IMX8MQ_CLK_MON_AUDIO_PLL1_DIV		290
+#define IMX8MQ_CLK_MON_AUDIO_PLL2_DIV		291
+#define IMX8MQ_CLK_MON_VIDEO_PLL1_DIV		292
+#define IMX8MQ_CLK_MON_GPU_PLL_DIV		293
+#define IMX8MQ_CLK_MON_VPU_PLL_DIV		294
+#define IMX8MQ_CLK_MON_ARM_PLL_DIV		295
+#define IMX8MQ_CLK_MON_SYS_PLL1_DIV		296
+#define IMX8MQ_CLK_MON_SYS_PLL2_DIV		297
+#define IMX8MQ_CLK_MON_SYS_PLL3_DIV		298
+#define IMX8MQ_CLK_MON_DRAM_PLL_DIV		299
+#define IMX8MQ_CLK_MON_VIDEO_PLL2_DIV		300
+#define IMX8MQ_CLK_MON_SEL			301
+#define IMX8MQ_CLK_MON_CLK2_OUT			302
+
+#define IMX8MQ_CLK_END				303
 
 #endif /* __DT_BINDINGS_CLOCK_IMX8MQ_H */
-- 
2.25.1


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

* [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-15 13:08 [PATCH v4 0/4] Add a clock driver for the imx8mq Angus Ainslie
  2022-03-15 13:08 ` [PATCH v4 1/4] dt-bindings: imx8mq-clock: add mainline definitions Angus Ainslie
@ 2022-03-15 13:08 ` Angus Ainslie
  2022-03-15 15:12   ` Heiko Thiery
                     ` (3 more replies)
  2022-03-15 13:08 ` [PATCH v4 3/4] clk: imx8m: reduce rate table duplication Angus Ainslie
  2022-03-15 13:08 ` [PATCH v4 4/4] clk: imx8m: remove code duplication Angus Ainslie
  3 siblings, 4 replies; 26+ messages in thread
From: Angus Ainslie @ 2022-03-15 13:08 UTC (permalink / raw)
  To: u-boot, Marek Vasut
  Cc: lukma, seanga2, sbabic, festevam, kernel, uboot-imx, peng.fan,
	Angus Ainslie

This is a DM clock driver based off the imx8mm u-boot driver and the linux
kernel driver.

All of the PLLs and clocks are initialized so the subsystems below are
functional and tested.

1) USB host and peripheral
2) ECSPI
3) UART
4) I2C all busses
5) USDHC for eMMC support
6) USB storage
7) GPIO
8) DRAM

Signed-off-by: Angus Ainslie <angus@akkea.ca>
---
 drivers/clk/imx/Kconfig      |  16 +
 drivers/clk/imx/Makefile     |   2 +
 drivers/clk/imx/clk-imx8mq.c | 575 +++++++++++++++++++++++++++++++++++
 3 files changed, 593 insertions(+)
 create mode 100644 drivers/clk/imx/clk-imx8mq.c

diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index cdd348020b0..06d8c1a5dd3 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -71,6 +71,22 @@ config CLK_IMX8MP
 	help
 	  This enables support clock driver for i.MX8MP platforms.
 
+config SPL_CLK_IMX8MQ
+	bool "SPL clock support for i.MX8MQ"
+	depends on ARCH_IMX8M && SPL
+	select SPL_CLK
+	select SPL_CLK_CCF
+	help
+	  This enables SPL DM/DTS support for clock driver in i.MX8MQ
+
+config CLK_IMX8MQ
+	bool "Clock support for i.MX8MQ"
+	depends on ARCH_IMX8M
+	select CLK
+	select CLK_CCF
+	help
+	  This enables support clock driver for i.MX8MQ platforms.
+
 config SPL_CLK_IMXRT1020
 	bool "SPL clock support for i.MXRT1020"
 	depends on ARCH_IMXRT && SPL
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 01bbbdf3aea..c5766901f2b 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -16,6 +16,8 @@ obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MN) += clk-imx8mn.o clk-pll14xx.o \
 				clk-composite-8m.o
 obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MP) += clk-imx8mp.o clk-pll14xx.o \
 				clk-composite-8m.o
+obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MQ) += clk-imx8mq.o clk-pll14xx.o \
+				clk-composite-8m.o
 
 obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1020) += clk-imxrt1020.o
 obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1050) += clk-imxrt1050.o
diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
new file mode 100644
index 00000000000..0aea417a29b
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8mq.c
@@ -0,0 +1,575 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 NXP
+ * Copyright 2022 Purism
+ * Peng Fan <peng.fan@nxp.com>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <log.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <dt-bindings/clock/imx8mq-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 imx8mq_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),
+};
+
+const struct imx_pll14xx_rate_table imx8mq_pll1443x_tbl[] = {
+	PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+	PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
+	PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
+	PLL_1443X_RATE(361267200U, 361, 3, 3, 17511),
+};
+
+static struct imx_pll14xx_clk imx8mq_1416x_pll __initdata = {
+		.type = PLL_1416X,
+		.rate_table = imx8mq_pll1416x_tbl,
+		.rate_count = ARRAY_SIZE(imx8mq_pll1416x_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mq_1443x_pll __initdata = {
+		.type = PLL_1443X,
+		.rate_table = imx8mq_pll1443x_tbl,
+		.rate_count = ARRAY_SIZE(imx8mq_pll1443x_tbl),
+};
+
+static const char *pll_ref_sels[] = { "clock-osc-25m", "clock-osc-27m", "clock-phy-27m", "dummy", };
+static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_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 *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 *imx8mq_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", };
+static const char *imx8mq_a53_sels[] = {"clock-osc-25m", "arm_pll_out", "sys_pll2_500m",
+					"sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m",
+					"audio_pll1_out", "sys_pll3_out", };
+
+static const char *imx8mq_ahb_sels[] = {"clock-osc-25m", "sys_pll1_133m", "sys_pll1_800m",
+					"sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out",
+					"audio_pll1_out", "video_pll1_out", };
+
+static const char *imx8mq_enet_axi_sels[] = {"clock-osc-25m", "sys_pll1_266m", "sys_pll1_800m",
+					     "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out",
+					     "video_pll1_out", "sys_pll3_out", };
+
+static const char *imx8mq_enet_ref_sels[] = {"clock-osc-25m", "sys_pll2_125m", "sys_pll2_50m",
+					     "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
+					     "video_pll1_out", "clk_ext4", };
+
+static const char *imx8mq_enet_timer_sels[] = {"clock-osc-25m", "sys_pll2_100m", "audio_pll1_out",
+					       "clk_ext1", "clk_ext2", "clk_ext3", "clk_ext4",
+					       "video_pll1_out", };
+
+static const char *imx8mq_enet_phy_sels[] = {"clock-osc-25m", "sys_pll2_50m", "sys_pll2_125m",
+					     "sys_pll2_200m", "sys_pll2_500m", "video_pll1_out",
+					     "audio_pll2_out", };
+
+static const char *imx8mq_nand_usdhc_sels[] = {"clock-osc-25m", "sys_pll1_266m", "sys_pll1_800m",
+					       "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out",
+					       "sys_pll2_250m", "audio_pll1_out", };
+
+static const char *imx8mq_usb_bus_sels[] = {"clock-osc-25m", "sys_pll2_500m", "sys_pll1_800m",
+					    "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
+					    "clk_ext4", "audio_pll2_out", };
+
+static const char *imx8mq_usdhc1_sels[] = {"clock-osc-25m", "sys_pll1_400m", "sys_pll1_800m",
+					   "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
+					   "audio_pll2_out", "sys_pll1_100m", };
+
+static const char *imx8mq_usdhc2_sels[] = {"clock-osc-25m", "sys_pll1_400m", "sys_pll1_800m",
+					   "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
+					   "audio_pll2_out", "sys_pll1_100m", };
+
+static const char *imx8mq_i2c1_sels[] = {"clock-osc-25m", "sys_pll1_160m", "sys_pll2_50m",
+					 "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+					 "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mq_i2c2_sels[] = {"clock-osc-25m", "sys_pll1_160m", "sys_pll2_50m",
+					 "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+					 "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mq_i2c3_sels[] = {"clock-osc-25m", "sys_pll1_160m", "sys_pll2_50m",
+					 "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+					 "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mq_i2c4_sels[] = {"clock-osc-25m", "sys_pll1_160m", "sys_pll2_50m",
+					 "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+					 "audio_pll2_out", "sys_pll1_133m", };
+
+static const char *imx8mq_wdog_sels[] = {"clock-osc-25m", "sys_pll1_133m", "sys_pll1_160m",
+					 "vpu_pll_out", "sys_pll2_125m", "sys_pll3_out",
+					 "sys_pll1_80m", "sys_pll2_166m", };
+
+static const char *imx8mq_qspi_sels[] = {"clock-osc-25m", "sys_pll1_400m", "sys_pll2_333m",
+					 "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m",
+					 "sys_pll3_out", "sys_pll1_100m", };
+
+static const char *imx8mq_usb_core_sels[] = {"clock-osc-25m", "sys_pll1_100m", "sys_pll1_40m",
+					     "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
+					     "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mq_usb_phy_sels[] = {"clock-osc-25m", "sys_pll1_100m", "sys_pll1_40m",
+					    "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
+					    "clk_ext3", "audio_pll2_out", };
+
+static const char *imx8mq_ecspi1_sels[] = {"clock-osc-25m", "sys_pll2_200m", "sys_pll1_40m",
+					   "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+					   "sys_pll2_250m", "audio_pll2_out", };
+
+static const char *imx8mq_ecspi2_sels[] = {"clock-osc-25m", "sys_pll2_200m", "sys_pll1_40m",
+					   "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+					   "sys_pll2_250m", "audio_pll2_out", };
+
+static const char *imx8mq_ecspi3_sels[] = {"clock-osc-25m", "sys_pll2_200m", "sys_pll1_40m",
+					   "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+					   "sys_pll2_250m", "audio_pll2_out", };
+
+static const char *pllout_monitor_sels[] = {"clock-osc-25m", "clock-osc-27m", "clock-phy-27m",
+					    "dummy", "clock-ckil", "audio_pll1_out_monitor",
+					    "audio_pll2_out_monitor", "gpu_pll_out_monitor",
+					    "vpu_pll_out_monitor", "video_pll1_out_monitor",
+					    "arm_pll_out_monitor", "sys_pll1_out_monitor",
+					    "sys_pll2_out_monitor", "sys_pll3_out_monitor",
+					    "dummy", "dram_pll_out_monitor", };
+
+static ulong imx8mq_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 imx8mq_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 __imx8mq_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) {
+		debug("%s: clk_get_by_id failed\n", __func__);
+		return ret;
+	}
+
+	if (enable)
+		ret = clk_enable(c);
+	else
+		ret = clk_disable(c);
+
+	return ret;
+}
+
+static int imx8mq_clk_disable(struct clk *clk)
+{
+	return __imx8mq_clk_enable(clk, 0);
+}
+
+static int imx8mq_clk_enable(struct clk *clk)
+{
+	return __imx8mq_clk_enable(clk, 1);
+}
+
+static int imx8mq_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	struct clk *c, *cp;
+	int ret;
+
+	debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
+
+	ret = clk_get_by_id(clk->id, &c);
+	if (ret)
+		return ret;
+
+	ret = clk_get_by_id(parent->id, &cp);
+	if (ret)
+		return ret;
+
+	ret = clk_set_parent(c, cp);
+	c->dev->parent = cp->dev;
+
+	return ret;
+}
+
+static struct clk_ops imx8mq_clk_ops = {
+	.set_rate = imx8mq_clk_set_rate,
+	.get_rate = imx8mq_clk_get_rate,
+	.enable = imx8mq_clk_enable,
+	.disable = imx8mq_clk_disable,
+	.set_parent = imx8mq_clk_set_parent,
+};
+
+static int imx8mq_clk_probe(struct udevice *dev)
+{
+	void __iomem *base;
+
+	base = (void *)ANATOP_BASE_ADDR;
+
+	clk_dm(IMX8MQ_CLK_32K, clk_register_fixed_rate(NULL, "ckil", 32768));
+
+	clk_dm(IMX8MQ_DRAM_PLL1_REF_SEL,
+	       imx_clk_mux("dram_pll_ref_sel", base + 0x60, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+	clk_dm(IMX8MQ_ARM_PLL_REF_SEL,
+	       imx_clk_mux("arm_pll_ref_sel", base + 0x28, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+	clk_dm(IMX8MQ_GPU_PLL_REF_SEL,
+	       imx_clk_mux("gpu_pll_ref_sel", base + 0x18, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+	clk_dm(IMX8MQ_VPU_PLL_REF_SEL,
+	       imx_clk_mux("vpu_pll_ref_sel", base + 0x20, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+	clk_dm(IMX8MQ_SYS3_PLL1_REF_SEL,
+	       imx_clk_mux("sys3_pll_ref_sel", base + 0x48, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+	clk_dm(IMX8MQ_AUDIO_PLL1_REF_SEL,
+	       imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+	clk_dm(IMX8MQ_AUDIO_PLL2_REF_SEL,
+	       imx_clk_mux("audio_pll2_ref_sel", base + 0x8, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+	clk_dm(IMX8MQ_VIDEO_PLL1_REF_SEL,
+	       imx_clk_mux("video_pll1_ref_sel", base + 0x10, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+
+	clk_dm(IMX8MQ_ARM_PLL,
+	       imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel",
+			       base + 0x28, &imx8mq_1416x_pll));
+	clk_dm(IMX8MQ_GPU_PLL,
+	       imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel",
+			       base + 0x18, &imx8mq_1416x_pll));
+	clk_dm(IMX8MQ_VPU_PLL,
+	       imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel",
+			       base + 0x20, &imx8mq_1416x_pll));
+
+	clk_dm(IMX8MQ_SYS1_PLL1,
+	       clk_register_fixed_rate(NULL, "sys1_pll", 800000000));
+	clk_dm(IMX8MQ_SYS2_PLL1,
+	       clk_register_fixed_rate(NULL, "sys2_pll", 1000000000));
+	clk_dm(IMX8MQ_SYS2_PLL1,
+	       clk_register_fixed_rate(NULL, "sys3_pll", 1000000000));
+	clk_dm(IMX8MQ_AUDIO_PLL1,
+	       imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel",
+			       base + 0x0, &imx8mq_1443x_pll));
+	clk_dm(IMX8MQ_AUDIO_PLL2,
+	       imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel",
+			       base + 0x8, &imx8mq_1443x_pll));
+	clk_dm(IMX8MQ_VIDEO_PLL1,
+	       imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel",
+			       base + 0x10, &imx8mq_1443x_pll));
+
+	/* PLL bypass out */
+	clk_dm(IMX8MQ_ARM_PLL_BYPASS,
+	       imx_clk_mux_flags("arm_pll_bypass", base + 0x28, 4, 1,
+				 arm_pll_bypass_sels,
+				 ARRAY_SIZE(arm_pll_bypass_sels),
+				 CLK_SET_RATE_PARENT));
+	clk_dm(IMX8MQ_GPU_PLL_BYPASS,
+	       imx_clk_mux_flags("gpu_pll_bypass", base + 0x18, 4, 1,
+				 gpu_pll_bypass_sels,
+				 ARRAY_SIZE(gpu_pll_bypass_sels),
+				 CLK_SET_RATE_PARENT));
+	clk_dm(IMX8MQ_VPU_PLL_BYPASS,
+	       imx_clk_mux_flags("vpu_pll_bypass", base + 0x20, 4, 1,
+				 vpu_pll_bypass_sels,
+				 ARRAY_SIZE(vpu_pll_bypass_sels),
+				 CLK_SET_RATE_PARENT));
+	clk_dm(IMX8MQ_AUDIO_PLL1_BYPASS,
+	       imx_clk_mux_flags("audio_pll1_bypass", base + 0x0, 4, 1,
+				 audio_pll1_bypass_sels,
+				 ARRAY_SIZE(audio_pll1_bypass_sels),
+				 CLK_SET_RATE_PARENT));
+	clk_dm(IMX8MQ_AUDIO_PLL2_BYPASS,
+	       imx_clk_mux_flags("audio_pll2_bypass", base + 0x8, 4, 1,
+				 audio_pll2_bypass_sels,
+				 ARRAY_SIZE(audio_pll2_bypass_sels),
+				 CLK_SET_RATE_PARENT));
+	clk_dm(IMX8MQ_VIDEO_PLL1_BYPASS,
+	       imx_clk_mux_flags("video_pll1_bypass", base + 0x10, 4, 1,
+				 video_pll1_bypass_sels,
+				 ARRAY_SIZE(video_pll1_bypass_sels),
+				 CLK_SET_RATE_PARENT));
+
+	/* PLL out gate */
+	clk_dm(IMX8MQ_DRAM_PLL_OUT,
+	       imx_clk_gate("dram_pll_out", "dram_pll_ref_sel",
+			    base + 0x60, 13));
+	clk_dm(IMX8MQ_ARM_PLL_OUT,
+	       imx_clk_gate("arm_pll_out", "arm_pll_bypass",
+			    base + 0x28, 11));
+	clk_dm(IMX8MQ_GPU_PLL_OUT,
+	       imx_clk_gate("gpu_pll_out", "gpu_pll_bypass",
+			    base + 0x18, 11));
+	clk_dm(IMX8MQ_VPU_PLL_OUT,
+	       imx_clk_gate("vpu_pll_out", "vpu_pll_bypass",
+			    base + 0x20, 11));
+	clk_dm(IMX8MQ_AUDIO_PLL1_OUT,
+	       imx_clk_gate("audio_pll1_out", "audio_pll1_bypass",
+			    base + 0x0, 11));
+	clk_dm(IMX8MQ_AUDIO_PLL2_OUT,
+	       imx_clk_gate("audio_pll2_out", "audio_pll2_bypass",
+			    base + 0x8, 11));
+	clk_dm(IMX8MQ_VIDEO_PLL1_OUT,
+	       imx_clk_gate("video_pll1_out", "video_pll1_bypass",
+			    base + 0x10, 11));
+
+	clk_dm(IMX8MQ_SYS1_PLL_OUT,
+	       imx_clk_gate("sys_pll1_out", "sys1_pll",
+			    base + 0x30, 11));
+	clk_dm(IMX8MQ_SYS2_PLL_OUT,
+	       imx_clk_gate("sys_pll2_out", "sys2_pll",
+			    base + 0x3c, 11));
+	clk_dm(IMX8MQ_SYS3_PLL_OUT,
+	       imx_clk_gate("sys_pll3_out", "sys3_pll",
+			    base + 0x48, 11));
+
+	/* SYS PLL fixed output */
+	clk_dm(IMX8MQ_SYS1_PLL_40M,
+	       imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20));
+	clk_dm(IMX8MQ_SYS1_PLL_80M,
+	       imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10));
+	clk_dm(IMX8MQ_SYS1_PLL_100M,
+	       imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8));
+	clk_dm(IMX8MQ_SYS1_PLL_133M,
+	       imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6));
+	clk_dm(IMX8MQ_SYS1_PLL_160M,
+	       imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5));
+	clk_dm(IMX8MQ_SYS1_PLL_200M,
+	       imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4));
+	clk_dm(IMX8MQ_SYS1_PLL_266M,
+	       imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3));
+	clk_dm(IMX8MQ_SYS1_PLL_400M,
+	       imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2));
+	clk_dm(IMX8MQ_SYS1_PLL_800M,
+	       imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1));
+
+	clk_dm(IMX8MQ_SYS2_PLL_50M,
+	       imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20));
+	clk_dm(IMX8MQ_SYS2_PLL_100M,
+	       imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10));
+	clk_dm(IMX8MQ_SYS2_PLL_125M,
+	       imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8));
+	clk_dm(IMX8MQ_SYS2_PLL_166M,
+	       imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6));
+	clk_dm(IMX8MQ_SYS2_PLL_200M,
+	       imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5));
+	clk_dm(IMX8MQ_SYS2_PLL_250M,
+	       imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4));
+	clk_dm(IMX8MQ_SYS2_PLL_333M,
+	       imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3));
+	clk_dm(IMX8MQ_SYS2_PLL_500M,
+	       imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2));
+	clk_dm(IMX8MQ_SYS2_PLL_1000M,
+	       imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1));
+
+	clk_dm(IMX8MQ_CLK_MON_AUDIO_PLL1_DIV,
+	       imx_clk_divider("audio_pll1_out_monitor", "audio_pll1_bypass", base + 0x78, 0, 3));
+	clk_dm(IMX8MQ_CLK_MON_AUDIO_PLL2_DIV,
+	       imx_clk_divider("audio_pll2_out_monitor", "audio_pll2_bypass", base + 0x78, 4, 3));
+	clk_dm(IMX8MQ_CLK_MON_VIDEO_PLL1_DIV,
+	       imx_clk_divider("video_pll1_out_monitor", "video_pll1_bypass", base + 0x78, 8, 3));
+	clk_dm(IMX8MQ_CLK_MON_GPU_PLL_DIV,
+	       imx_clk_divider("gpu_pll_out_monitor", "gpu_pll_bypass", base + 0x78, 12, 3));
+	clk_dm(IMX8MQ_CLK_MON_VPU_PLL_DIV,
+	       imx_clk_divider("vpu_pll_out_monitor", "vpu_pll_bypass", base + 0x78, 16, 3));
+	clk_dm(IMX8MQ_CLK_MON_ARM_PLL_DIV,
+	       imx_clk_divider("arm_pll_out_monitor", "arm_pll_bypass", base + 0x78, 20, 3));
+	clk_dm(IMX8MQ_CLK_MON_SYS_PLL1_DIV,
+	       imx_clk_divider("sys_pll1_out_monitor", "sys_pll1_out", base + 0x7c, 0, 3));
+	clk_dm(IMX8MQ_CLK_MON_SYS_PLL2_DIV,
+	       imx_clk_divider("sys_pll2_out_monitor", "sys_pll2_out", base + 0x7c, 4, 3));
+	clk_dm(IMX8MQ_CLK_MON_SYS_PLL3_DIV,
+	       imx_clk_divider("sys_pll3_out_monitor", "sys_pll3_out", base + 0x7c, 8, 3));
+	clk_dm(IMX8MQ_CLK_MON_DRAM_PLL_DIV,
+	       imx_clk_divider("dram_pll_out_monitor", "dram_pll_out", base + 0x7c, 12, 3));
+	clk_dm(IMX8MQ_CLK_MON_SEL,
+	       imx_clk_mux_flags("pllout_monitor_sel", base + 0x74, 0, 4,
+				 pllout_monitor_sels,
+				 ARRAY_SIZE(pllout_monitor_sels),
+				 CLK_SET_RATE_PARENT));
+	clk_dm(IMX8MQ_CLK_MON_CLK2_OUT,
+	       imx_clk_gate4("pllout_monitor_clk2", "pllout_monitor_sel", base + 0x74, 4));
+
+	base = dev_read_addr_ptr(dev);
+	if (!base) {
+		printf("%s : base failed\n", __func__);
+		return -EINVAL;
+	}
+
+	clk_dm(IMX8MQ_CLK_A53_SRC,
+	       imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3,
+			    imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels)));
+	clk_dm(IMX8MQ_CLK_A53_CG,
+	       imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28));
+	clk_dm(IMX8MQ_CLK_A53_DIV,
+	       imx_clk_divider2("arm_a53_div", "arm_a53_cg",
+				base + 0x8000, 0, 3));
+	clk_dm(IMX8MQ_CLK_A53_CORE,
+	       imx_clk_mux2("arm_a53_src", base + 0x9880, 24, 1,
+			    imx8mq_a53_core_sels, ARRAY_SIZE(imx8mq_a53_core_sels)));
+
+	clk_dm(IMX8MQ_CLK_AHB,
+	       imx8m_clk_composite_critical("ahb", imx8mq_ahb_sels,
+					    base + 0x9000));
+	clk_dm(IMX8MQ_CLK_IPG_ROOT,
+	       imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1));
+
+	clk_dm(IMX8MQ_CLK_ENET_AXI,
+	       imx8m_clk_composite("enet_axi", imx8mq_enet_axi_sels,
+				   base + 0x8880));
+	clk_dm(IMX8MQ_CLK_NAND_USDHC_BUS,
+	       imx8m_clk_composite_critical("nand_usdhc_bus",
+					    imx8mq_nand_usdhc_sels,
+					    base + 0x8900));
+	clk_dm(IMX8MQ_CLK_USB_BUS,
+	       imx8m_clk_composite("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80));
+
+	/* IP */
+	clk_dm(IMX8MQ_CLK_USDHC1,
+	       imx8m_clk_composite("usdhc1", imx8mq_usdhc1_sels,
+				   base + 0xac00));
+	clk_dm(IMX8MQ_CLK_USDHC2,
+	       imx8m_clk_composite("usdhc2", imx8mq_usdhc2_sels,
+				   base + 0xac80));
+	clk_dm(IMX8MQ_CLK_I2C1,
+	       imx8m_clk_composite("i2c1", imx8mq_i2c1_sels, base + 0xad00));
+	clk_dm(IMX8MQ_CLK_I2C2,
+	       imx8m_clk_composite("i2c2", imx8mq_i2c2_sels, base + 0xad80));
+	clk_dm(IMX8MQ_CLK_I2C3,
+	       imx8m_clk_composite("i2c3", imx8mq_i2c3_sels, base + 0xae00));
+	clk_dm(IMX8MQ_CLK_I2C4,
+	       imx8m_clk_composite("i2c4", imx8mq_i2c4_sels, base + 0xae80));
+	clk_dm(IMX8MQ_CLK_WDOG,
+	       imx8m_clk_composite("wdog", imx8mq_wdog_sels, base + 0xb900));
+	clk_dm(IMX8MQ_CLK_QSPI,
+	       imx8m_clk_composite("qspi", imx8mq_qspi_sels, base + 0xab80));
+	clk_dm(IMX8MQ_CLK_USB_CORE_REF,
+	       imx8m_clk_composite("usb_core_ref", imx8mq_usb_core_sels, base + 0xb100));
+	clk_dm(IMX8MQ_CLK_USB_PHY_REF,
+	       imx8m_clk_composite("usb_phy_ref", imx8mq_usb_phy_sels, base + 0xb180));
+	clk_dm(IMX8MQ_CLK_ECSPI1,
+	       imx8m_clk_composite("ecspi1", imx8mq_ecspi1_sels, base + 0xb280));
+	clk_dm(IMX8MQ_CLK_ECSPI2,
+	       imx8m_clk_composite("ecspi2", imx8mq_ecspi2_sels, base + 0xb300));
+	clk_dm(IMX8MQ_CLK_ECSPI3,
+	       imx8m_clk_composite("ecspi3", imx8mq_ecspi3_sels, base + 0xc180));
+
+	clk_dm(IMX8MQ_CLK_ECSPI1_ROOT,
+	       imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0));
+	clk_dm(IMX8MQ_CLK_ECSPI2_ROOT,
+	       imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0));
+	clk_dm(IMX8MQ_CLK_ECSPI3_ROOT,
+	       imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0));
+	clk_dm(IMX8MQ_CLK_I2C1_ROOT,
+	       imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0));
+	clk_dm(IMX8MQ_CLK_I2C2_ROOT,
+	       imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0));
+	clk_dm(IMX8MQ_CLK_I2C3_ROOT,
+	       imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0));
+	clk_dm(IMX8MQ_CLK_I2C4_ROOT,
+	       imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0));
+	clk_dm(IMX8MQ_CLK_OCOTP_ROOT,
+	       imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0));
+	clk_dm(IMX8MQ_CLK_USDHC1_ROOT,
+	       imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0));
+	clk_dm(IMX8MQ_CLK_USDHC2_ROOT,
+	       imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0));
+	clk_dm(IMX8MQ_CLK_WDOG1_ROOT,
+	       imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0));
+	clk_dm(IMX8MQ_CLK_WDOG2_ROOT,
+	       imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0));
+	clk_dm(IMX8MQ_CLK_WDOG3_ROOT,
+	       imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0));
+	clk_dm(IMX8MQ_CLK_QSPI_ROOT,
+	       imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0));
+	clk_dm(IMX8MQ_CLK_USB1_CTRL_ROOT,
+	       imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0));
+	clk_dm(IMX8MQ_CLK_USB2_CTRL_ROOT,
+	       imx_clk_gate4("usb2_ctrl_root_clk", "usb_bus", base + 0x44e0, 0));
+	clk_dm(IMX8MQ_CLK_USB1_PHY_ROOT,
+	       imx_clk_gate4("usb1_phy_root_clk", "usb_phy_ref", base + 0x44f0, 0));
+	clk_dm(IMX8MQ_CLK_USB2_PHY_ROOT,
+	       imx_clk_gate4("usb2_phy_root_clk", "usb_phy_ref", base + 0x4500, 0));
+
+	clk_dm(IMX8MQ_CLK_ENET_REF,
+	       imx8m_clk_composite("enet_ref", imx8mq_enet_ref_sels,
+				   base + 0xa980));
+	clk_dm(IMX8MQ_CLK_ENET_TIMER,
+	       imx8m_clk_composite("enet_timer", imx8mq_enet_timer_sels,
+				   base + 0xaa00));
+	clk_dm(IMX8MQ_CLK_ENET_PHY_REF,
+	       imx8m_clk_composite("enet_phy", imx8mq_enet_phy_sels,
+				   base + 0xaa80));
+	clk_dm(IMX8MQ_CLK_ENET1_ROOT,
+	       imx_clk_gate4("enet1_root_clk", "enet_axi",
+			     base + 0x40a0, 0));
+
+	return 0;
+}
+
+static const struct udevice_id imx8mq_clk_ids[] = {
+	{ .compatible = "fsl,imx8mq-ccm" },
+	{ },
+};
+
+U_BOOT_DRIVER(imx8mq_clk) = {
+	.name = "clk_imx8mq",
+	.id = UCLASS_CLK,
+	.of_match = imx8mq_clk_ids,
+	.ops = &imx8mq_clk_ops,
+	.probe = imx8mq_clk_probe,
+	.flags = DM_FLAG_PRE_RELOC,
+};
-- 
2.25.1


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

* [PATCH v4 3/4] clk: imx8m: reduce rate table duplication
  2022-03-15 13:08 [PATCH v4 0/4] Add a clock driver for the imx8mq Angus Ainslie
  2022-03-15 13:08 ` [PATCH v4 1/4] dt-bindings: imx8mq-clock: add mainline definitions Angus Ainslie
  2022-03-15 13:08 ` [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq Angus Ainslie
@ 2022-03-15 13:08 ` Angus Ainslie
  2022-03-15 13:08 ` [PATCH v4 4/4] clk: imx8m: remove code duplication Angus Ainslie
  3 siblings, 0 replies; 26+ messages in thread
From: Angus Ainslie @ 2022-03-15 13:08 UTC (permalink / raw)
  To: u-boot, Marek Vasut
  Cc: lukma, seanga2, sbabic, festevam, kernel, uboot-imx, peng.fan,
	Angus Ainslie

Re-factor the imx8m[nmpq] rate tables into the common pll1416x clock
driver.

43cdaa1567ad3 ("clk: imx8mm: Move 1443X/1416X PLL clock structure to common place")

Signed-off-by: Angus Ainslie <angus@akkea.ca>
---
 drivers/clk/imx/clk-imx8mm.c  | 60 +++-----------------------------
 drivers/clk/imx/clk-imx8mn.c  | 60 +++-----------------------------
 drivers/clk/imx/clk-imx8mp.c  | 65 ++++++-----------------------------
 drivers/clk/imx/clk-imx8mq.c  | 59 ++++---------------------------
 drivers/clk/imx/clk-pll14xx.c | 61 ++++++++++++++++++++++++++++++++
 drivers/clk/imx/clk.h         |  4 +++
 6 files changed, 91 insertions(+), 218 deletions(-)

diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
index 3aa8c641f9a..ab8f9b4d6b9 100644
--- a/drivers/clk/imx/clk-imx8mm.c
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -15,56 +15,6 @@
 
 #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", };
@@ -250,19 +200,19 @@ static int imx8mm_clk_probe(struct udevice *dev)
 
 	clk_dm(IMX8MM_DRAM_PLL,
 	       imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel",
-			       base + 0x50, &imx8mm_dram_pll));
+			       base + 0x50, &imx_1443x_dram_pll));
 	clk_dm(IMX8MM_ARM_PLL,
 	       imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel",
-			       base + 0x84, &imx8mm_arm_pll));
+			       base + 0x84, &imx_1416x_pll));
 	clk_dm(IMX8MM_SYS_PLL1,
 	       imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel",
-			       base + 0x94, &imx8mm_sys_pll));
+			       base + 0x94, &imx_1416x_pll));
 	clk_dm(IMX8MM_SYS_PLL2,
 	       imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel",
-			       base + 0x104, &imx8mm_sys_pll));
+			       base + 0x104, &imx_1416x_pll));
 	clk_dm(IMX8MM_SYS_PLL3,
 	       imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel",
-			       base + 0x114, &imx8mm_sys_pll));
+			       base + 0x114, &imx_1416x_pll));
 
 	/* PLL bypass out */
 	clk_dm(IMX8MM_DRAM_PLL_BYPASS,
diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
index e398d7de02a..c3d60ad057c 100644
--- a/drivers/clk/imx/clk-imx8mn.c
+++ b/drivers/clk/imx/clk-imx8mn.c
@@ -15,56 +15,6 @@
 
 #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 imx8mn_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 imx8mn_drampll_tbl[] = {
-	PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
-};
-
-static struct imx_pll14xx_clk imx8mn_dram_pll __initdata = {
-		.type = PLL_1443X,
-		.rate_table = imx8mn_drampll_tbl,
-		.rate_count = ARRAY_SIZE(imx8mn_drampll_tbl),
-};
-
-static struct imx_pll14xx_clk imx8mn_arm_pll __initdata = {
-		.type = PLL_1416X,
-		.rate_table = imx8mn_pll1416x_tbl,
-		.rate_count = ARRAY_SIZE(imx8mn_pll1416x_tbl),
-};
-
-static struct imx_pll14xx_clk imx8mn_sys_pll __initdata = {
-		.type = PLL_1416X,
-		.rate_table = imx8mn_pll1416x_tbl,
-		.rate_count = ARRAY_SIZE(imx8mn_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", };
@@ -258,19 +208,19 @@ static int imx8mn_clk_probe(struct udevice *dev)
 
 	clk_dm(IMX8MN_DRAM_PLL,
 	       imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel",
-			       base + 0x50, &imx8mn_dram_pll));
+			       base + 0x50, &imx_1443x_dram_pll));
 	clk_dm(IMX8MN_ARM_PLL,
 	       imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel",
-			       base + 0x84, &imx8mn_arm_pll));
+			       base + 0x84, &imx_1416x_pll));
 	clk_dm(IMX8MN_SYS_PLL1,
 	       imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel",
-			       base + 0x94, &imx8mn_sys_pll));
+			       base + 0x94, &imx_1416x_pll));
 	clk_dm(IMX8MN_SYS_PLL2,
 	       imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel",
-			       base + 0x104, &imx8mn_sys_pll));
+			       base + 0x104, &imx_1416x_pll));
 	clk_dm(IMX8MN_SYS_PLL3,
 	       imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel",
-			       base + 0x114, &imx8mn_sys_pll));
+			       base + 0x114, &imx_1416x_pll));
 
 	/* PLL bypass out */
 	clk_dm(IMX8MN_DRAM_PLL_BYPASS,
diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
index c77500bcce0..5ccb969da3b 100644
--- a/drivers/clk/imx/clk-imx8mp.c
+++ b/drivers/clk/imx/clk-imx8mp.c
@@ -15,56 +15,6 @@
 
 #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 imx8mp_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 imx8mp_drampll_tbl[] = {
-	PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
-};
-
-static struct imx_pll14xx_clk imx8mp_dram_pll __initdata = {
-		.type = PLL_1443X,
-		.rate_table = imx8mp_drampll_tbl,
-		.rate_count = ARRAY_SIZE(imx8mp_drampll_tbl),
-};
-
-static struct imx_pll14xx_clk imx8mp_arm_pll __initdata = {
-		.type = PLL_1416X,
-		.rate_table = imx8mp_pll1416x_tbl,
-		.rate_count = ARRAY_SIZE(imx8mp_pll1416x_tbl),
-};
-
-static struct imx_pll14xx_clk imx8mp_sys_pll __initdata = {
-		.type = PLL_1416X,
-		.rate_table = imx8mp_pll1416x_tbl,
-		.rate_count = ARRAY_SIZE(imx8mp_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", };
@@ -286,11 +236,16 @@ static int imx8mp_clk_probe(struct udevice *dev)
 	clk_dm(IMX8MP_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(IMX8MP_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(IMX8MP_DRAM_PLL, imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mp_dram_pll));
-	clk_dm(IMX8MP_ARM_PLL, imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mp_arm_pll));
-	clk_dm(IMX8MP_SYS_PLL1, imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mp_sys_pll));
-	clk_dm(IMX8MP_SYS_PLL2, imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mp_sys_pll));
-	clk_dm(IMX8MP_SYS_PLL3, imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mp_sys_pll));
+	clk_dm(IMX8MP_DRAM_PLL, imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50,
+						&imx_1443x_dram_pll));
+	clk_dm(IMX8MP_ARM_PLL, imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84,
+					       &imx_1416x_pll));
+	clk_dm(IMX8MP_SYS_PLL1, imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94,
+						&imx_1416x_pll));
+	clk_dm(IMX8MP_SYS_PLL2, imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104,
+						&imx_1416x_pll));
+	clk_dm(IMX8MP_SYS_PLL3, imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114,
+						&imx_1416x_pll));
 
 	clk_dm(IMX8MP_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(IMX8MP_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));
diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
index 0aea417a29b..e753613f6c3 100644
--- a/drivers/clk/imx/clk-imx8mq.c
+++ b/drivers/clk/imx/clk-imx8mq.c
@@ -16,53 +16,6 @@
 
 #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 imx8mq_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),
-};
-
-const struct imx_pll14xx_rate_table imx8mq_pll1443x_tbl[] = {
-	PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
-	PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
-	PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
-	PLL_1443X_RATE(361267200U, 361, 3, 3, 17511),
-};
-
-static struct imx_pll14xx_clk imx8mq_1416x_pll __initdata = {
-		.type = PLL_1416X,
-		.rate_table = imx8mq_pll1416x_tbl,
-		.rate_count = ARRAY_SIZE(imx8mq_pll1416x_tbl),
-};
-
-static struct imx_pll14xx_clk imx8mq_1443x_pll __initdata = {
-		.type = PLL_1443X,
-		.rate_table = imx8mq_pll1443x_tbl,
-		.rate_count = ARRAY_SIZE(imx8mq_pll1443x_tbl),
-};
-
 static const char *pll_ref_sels[] = { "clock-osc-25m", "clock-osc-27m", "clock-phy-27m", "dummy", };
 static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
 static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
@@ -287,13 +240,13 @@ static int imx8mq_clk_probe(struct udevice *dev)
 
 	clk_dm(IMX8MQ_ARM_PLL,
 	       imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel",
-			       base + 0x28, &imx8mq_1416x_pll));
+			       base + 0x28, &imx_1416x_pll));
 	clk_dm(IMX8MQ_GPU_PLL,
 	       imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel",
-			       base + 0x18, &imx8mq_1416x_pll));
+			       base + 0x18, &imx_1416x_pll));
 	clk_dm(IMX8MQ_VPU_PLL,
 	       imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel",
-			       base + 0x20, &imx8mq_1416x_pll));
+			       base + 0x20, &imx_1416x_pll));
 
 	clk_dm(IMX8MQ_SYS1_PLL1,
 	       clk_register_fixed_rate(NULL, "sys1_pll", 800000000));
@@ -303,13 +256,13 @@ static int imx8mq_clk_probe(struct udevice *dev)
 	       clk_register_fixed_rate(NULL, "sys3_pll", 1000000000));
 	clk_dm(IMX8MQ_AUDIO_PLL1,
 	       imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel",
-			       base + 0x0, &imx8mq_1443x_pll));
+			       base + 0x0, &imx_1443x_pll));
 	clk_dm(IMX8MQ_AUDIO_PLL2,
 	       imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel",
-			       base + 0x8, &imx8mq_1443x_pll));
+			       base + 0x8, &imx_1443x_pll));
 	clk_dm(IMX8MQ_VIDEO_PLL1,
 	       imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel",
-			       base + 0x10, &imx8mq_1443x_pll));
+			       base + 0x10, &imx_1443x_pll));
 
 	/* PLL bypass out */
 	clk_dm(IMX8MQ_ARM_PLL_BYPASS,
diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
index b0ccb6c8eda..b93c0bc64e7 100644
--- a/drivers/clk/imx/clk-pll14xx.c
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -52,6 +52,67 @@ struct clk_pll14xx {
 
 #define to_clk_pll14xx(_clk) container_of(_clk, struct clk_pll14xx, clk)
 
+#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 imx_pll1416x_tbl[] = {
+	PLL_1416X_RATE(1800000000U, 225, 3, 0),
+	PLL_1416X_RATE(1600000000U, 200, 3, 0),
+	PLL_1416X_RATE(1500000000U, 375, 3, 1),
+	PLL_1416X_RATE(1400000000U, 350, 3, 1),
+	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),
+};
+
+const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
+	PLL_1443X_RATE(1039500000U, 173, 2, 1, 16384),
+	PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+	PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
+	PLL_1443X_RATE(519750000U, 173, 2, 2, 16384),
+	PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
+	PLL_1443X_RATE(361267200U, 361, 3, 3, 17511),
+};
+
+struct imx_pll14xx_clk imx_1443x_pll __initdata = {
+	.type = PLL_1443X,
+	.rate_table = imx_pll1443x_tbl,
+	.rate_count = ARRAY_SIZE(imx_pll1443x_tbl),
+};
+EXPORT_SYMBOL_GPL(imx_1443x_pll);
+
+struct imx_pll14xx_clk imx_1443x_dram_pll __initdata = {
+	.type = PLL_1443X,
+	.rate_table = imx_pll1443x_tbl,
+	.rate_count = ARRAY_SIZE(imx_pll1443x_tbl),
+	.flags = CLK_GET_RATE_NOCACHE,
+};
+EXPORT_SYMBOL_GPL(imx_1443x_dram_pll);
+
+struct imx_pll14xx_clk imx_1416x_pll __initdata = {
+	.type = PLL_1416X,
+	.rate_table = imx_pll1416x_tbl,
+	.rate_count = ARRAY_SIZE(imx_pll1416x_tbl),
+};
+EXPORT_SYMBOL_GPL(imx_1416x_pll);
+
 static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
 		struct clk_pll14xx *pll, unsigned long rate)
 {
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 60f287046b9..0e1eaf03d41 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -41,6 +41,10 @@ struct imx_pll14xx_clk {
 	int flags;
 };
 
+extern struct imx_pll14xx_clk imx_1416x_pll;
+extern struct imx_pll14xx_clk imx_1443x_pll;
+extern struct imx_pll14xx_clk imx_1443x_dram_pll;
+
 struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
 			    void __iomem *base,
 			    const struct imx_pll14xx_clk *pll_clk);
-- 
2.25.1


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

* [PATCH v4 4/4] clk: imx8m: remove code duplication
  2022-03-15 13:08 [PATCH v4 0/4] Add a clock driver for the imx8mq Angus Ainslie
                   ` (2 preceding siblings ...)
  2022-03-15 13:08 ` [PATCH v4 3/4] clk: imx8m: reduce rate table duplication Angus Ainslie
@ 2022-03-15 13:08 ` Angus Ainslie
  2022-03-20 23:58   ` Sean Anderson
  3 siblings, 1 reply; 26+ messages in thread
From: Angus Ainslie @ 2022-03-15 13:08 UTC (permalink / raw)
  To: u-boot, Marek Vasut
  Cc: lukma, seanga2, sbabic, festevam, kernel, uboot-imx, peng.fan,
	Angus Ainslie

All of the imx8m[nmpq] use the same clk_ops functions so move them
to a common file.

Signed-off-by: Angus Ainslie <angus@akkea.ca>
Reviewed-by: Marek Vasut <marex@denx.de>
---
 drivers/clk/imx/Makefile     |   8 +--
 drivers/clk/imx/clk-imx8m.c  | 108 +++++++++++++++++++++++++++++++++++
 drivers/clk/imx/clk-imx8m.h  |  12 ++++
 drivers/clk/imx/clk-imx8mm.c |  89 +----------------------------
 drivers/clk/imx/clk-imx8mn.c |  89 +----------------------------
 drivers/clk/imx/clk-imx8mp.c |  91 +----------------------------
 drivers/clk/imx/clk-imx8mq.c |  91 +----------------------------
 7 files changed, 132 insertions(+), 356 deletions(-)
 create mode 100644 drivers/clk/imx/clk-imx8m.c
 create mode 100644 drivers/clk/imx/clk-imx8m.h

diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index c5766901f2b..09030f1ded2 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -11,13 +11,13 @@ 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
+				clk-composite-8m.o clk-imx8m.o
 obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MN) += clk-imx8mn.o clk-pll14xx.o \
-				clk-composite-8m.o
+				clk-composite-8m.o clk-imx8m.o
 obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MP) += clk-imx8mp.o clk-pll14xx.o \
-				clk-composite-8m.o
+				clk-composite-8m.o clk-imx8m.o
 obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MQ) += clk-imx8mq.o clk-pll14xx.o \
-				clk-composite-8m.o
+				clk-composite-8m.o clk-imx8m.o
 
 obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1020) += clk-imxrt1020.o
 obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1050) += clk-imxrt1050.o
diff --git a/drivers/clk/imx/clk-imx8m.c b/drivers/clk/imx/clk-imx8m.c
new file mode 100644
index 00000000000..d3e9f8aaee0
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8m.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2018 NXP
+ * Copyright 2022 Purism SPC
+ * Peng Fan <peng.fan@nxp.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <log.h>
+#include <malloc.h>
+#include <asm/arch/clock.h>
+#include <misc.h>
+
+#include "clk-imx8m.h"
+
+ulong imx8m_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);
+}
+EXPORT_SYMBOL_GPL(imx8m_clk_get_rate);
+
+ulong imx8m_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);
+}
+EXPORT_SYMBOL_GPL(imx8m_clk_set_rate);
+
+static int __imx8m_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;
+}
+
+int imx8m_clk_disable(struct clk *clk)
+{
+	return __imx8m_clk_enable(clk, 0);
+}
+EXPORT_SYMBOL_GPL(imx8m_clk_disable);
+
+int imx8m_clk_enable(struct clk *clk)
+{
+	return __imx8m_clk_enable(clk, 1);
+}
+EXPORT_SYMBOL_GPL(imx8m_clk_enable);
+
+int imx8m_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	struct clk *c, *cp;
+	int ret;
+
+	debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
+
+	ret = clk_get_by_id(clk->id, &c);
+	if (ret)
+		return ret;
+
+	ret = clk_get_by_id(parent->id, &cp);
+	if (ret)
+		return ret;
+
+	ret = clk_set_parent(c, cp);
+	c->dev->parent = cp->dev;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(imx8m_clk_set_parent);
+
+struct clk_ops imx8m_clk_ops = {
+	.set_rate = imx8m_clk_set_rate,
+	.get_rate = imx8m_clk_get_rate,
+	.enable = imx8m_clk_enable,
+	.disable = imx8m_clk_disable,
+	.set_parent = imx8m_clk_set_parent,
+};
+EXPORT_SYMBOL_GPL(imx8m_clk_ops);
diff --git a/drivers/clk/imx/clk-imx8m.h b/drivers/clk/imx/clk-imx8m.h
new file mode 100644
index 00000000000..7c0892e148d
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8m.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2022 Purism SPC
+ */
+
+extern ulong imx8m_clk_get_rate(struct clk *clk);
+extern ulong imx8m_clk_set_rate(struct clk *clk, unsigned long rate);
+extern int imx8m_clk_disable(struct clk *clk);
+extern int imx8m_clk_enable(struct clk *clk);
+extern int imx8m_clk_set_parent(struct clk *clk, struct clk *parent);
+
+extern struct clk_ops imx8m_clk_ops;
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
index ab8f9b4d6b9..fb3e4e7d0df 100644
--- a/drivers/clk/imx/clk-imx8mm.c
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -14,6 +14,7 @@
 #include <dt-bindings/clock/imx8mm-clock.h>
 
 #include "clk.h"
+#include "clk-imx8m.h"
 
 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", };
@@ -90,92 +91,6 @@ static const char *imx8mm_ecspi2_sels[] = {"clock-osc-24m", "sys_pll2_200m", "sy
 static const char *imx8mm_ecspi3_sels[] = {"clock-osc-24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
 					   "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
 
-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 int imx8mm_clk_set_parent(struct clk *clk, struct clk *parent)
-{
-	struct clk *c, *cp;
-	int ret;
-
-	debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
-
-	ret = clk_get_by_id(clk->id, &c);
-	if (ret)
-		return ret;
-
-	ret = clk_get_by_id(parent->id, &cp);
-	if (ret)
-		return ret;
-
-	ret = clk_set_parent(c, cp);
-	c->dev->parent = cp->dev;
-
-	return ret;
-}
-
-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,
-	.set_parent = imx8mm_clk_set_parent,
-};
-
 static int imx8mm_clk_probe(struct udevice *dev)
 {
 	void __iomem *base;
@@ -420,7 +335,7 @@ U_BOOT_DRIVER(imx8mm_clk) = {
 	.name = "clk_imx8mm",
 	.id = UCLASS_CLK,
 	.of_match = imx8mm_clk_ids,
-	.ops = &imx8mm_clk_ops,
+	.ops = &imx8m_clk_ops,
 	.probe = imx8mm_clk_probe,
 	.flags = DM_FLAG_PRE_RELOC,
 };
diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
index c3d60ad057c..08fdcf5d86d 100644
--- a/drivers/clk/imx/clk-imx8mn.c
+++ b/drivers/clk/imx/clk-imx8mn.c
@@ -14,6 +14,7 @@
 #include <dt-bindings/clock/imx8mn-clock.h>
 
 #include "clk.h"
+#include "clk-imx8m.h"
 
 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", };
@@ -98,92 +99,6 @@ static const char * const imx8mn_usb_phy_sels[] = {"clock-osc-24m", "sys_pll1_10
 						"sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
 						"clk_ext3", "audio_pll2_out", };
 
-static ulong imx8mn_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 imx8mn_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 __imx8mn_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 imx8mn_clk_disable(struct clk *clk)
-{
-	return __imx8mn_clk_enable(clk, 0);
-}
-
-static int imx8mn_clk_enable(struct clk *clk)
-{
-	return __imx8mn_clk_enable(clk, 1);
-}
-
-static int imx8mn_clk_set_parent(struct clk *clk, struct clk *parent)
-{
-	struct clk *c, *cp;
-	int ret;
-
-	debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
-
-	ret = clk_get_by_id(clk->id, &c);
-	if (ret)
-		return ret;
-
-	ret = clk_get_by_id(parent->id, &cp);
-	if (ret)
-		return ret;
-
-	ret = clk_set_parent(c, cp);
-	c->dev->parent = cp->dev;
-
-	return ret;
-}
-
-static struct clk_ops imx8mn_clk_ops = {
-	.set_rate = imx8mn_clk_set_rate,
-	.get_rate = imx8mn_clk_get_rate,
-	.enable = imx8mn_clk_enable,
-	.disable = imx8mn_clk_disable,
-	.set_parent = imx8mn_clk_set_parent,
-};
-
 static int imx8mn_clk_probe(struct udevice *dev)
 {
 	void __iomem *base;
@@ -431,7 +346,7 @@ U_BOOT_DRIVER(imx8mn_clk) = {
 	.name = "clk_imx8mn",
 	.id = UCLASS_CLK,
 	.of_match = imx8mn_clk_ids,
-	.ops = &imx8mn_clk_ops,
+	.ops = &imx8m_clk_ops,
 	.probe = imx8mn_clk_probe,
 	.flags = DM_FLAG_PRE_RELOC,
 };
diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
index 5ccb969da3b..00c0fbcbcb2 100644
--- a/drivers/clk/imx/clk-imx8mp.c
+++ b/drivers/clk/imx/clk-imx8mp.c
@@ -14,6 +14,7 @@
 #include <dt-bindings/clock/imx8mp-clock.h>
 
 #include "clk.h"
+#include "clk-imx8m.h"
 
 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", };
@@ -136,94 +137,6 @@ static const char *imx8mp_enet_phy_ref_sels[] = {"clock-osc-24m", "sys_pll2_50m"
 
 static const char *imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
 
-
-static ulong imx8mp_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 imx8mp_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 __imx8mp_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 imx8mp_clk_disable(struct clk *clk)
-{
-	return __imx8mp_clk_enable(clk, 0);
-}
-
-static int imx8mp_clk_enable(struct clk *clk)
-{
-	return __imx8mp_clk_enable(clk, 1);
-}
-
-static int imx8mp_clk_set_parent(struct clk *clk, struct clk *parent)
-{
-	struct clk *c, *cp;
-	int ret;
-
-	debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
-
-	ret = clk_get_by_id(clk->id, &c);
-	if (ret)
-		return ret;
-
-	ret = clk_get_by_id(parent->id, &cp);
-	if (ret)
-		return ret;
-
-	ret = clk_set_parent(c, cp);
-
-	c->dev->parent = cp->dev;
-
-	return ret;
-}
-
-static struct clk_ops imx8mp_clk_ops = {
-	.set_rate = imx8mp_clk_set_rate,
-	.get_rate = imx8mp_clk_get_rate,
-	.enable = imx8mp_clk_enable,
-	.disable = imx8mp_clk_disable,
-	.set_parent = imx8mp_clk_set_parent,
-};
-
 static int imx8mp_clk_probe(struct udevice *dev)
 {
 	void __iomem *base;
@@ -364,7 +277,7 @@ U_BOOT_DRIVER(imx8mp_clk) = {
 	.name = "clk_imx8mp",
 	.id = UCLASS_CLK,
 	.of_match = imx8mp_clk_ids,
-	.ops = &imx8mp_clk_ops,
+	.ops = &imx8m_clk_ops,
 	.probe = imx8mp_clk_probe,
 	.flags = DM_FLAG_PRE_RELOC,
 };
diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
index e753613f6c3..c3b685dbaab 100644
--- a/drivers/clk/imx/clk-imx8mq.c
+++ b/drivers/clk/imx/clk-imx8mq.c
@@ -15,6 +15,7 @@
 #include <dt-bindings/clock/imx8mq-clock.h>
 
 #include "clk.h"
+#include "clk-imx8m.h"
 
 static const char *pll_ref_sels[] = { "clock-osc-25m", "clock-osc-27m", "clock-phy-27m", "dummy", };
 static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
@@ -117,94 +118,6 @@ static const char *pllout_monitor_sels[] = {"clock-osc-25m", "clock-osc-27m", "c
 					    "sys_pll2_out_monitor", "sys_pll3_out_monitor",
 					    "dummy", "dram_pll_out_monitor", };
 
-static ulong imx8mq_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 imx8mq_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 __imx8mq_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) {
-		debug("%s: clk_get_by_id failed\n", __func__);
-		return ret;
-	}
-
-	if (enable)
-		ret = clk_enable(c);
-	else
-		ret = clk_disable(c);
-
-	return ret;
-}
-
-static int imx8mq_clk_disable(struct clk *clk)
-{
-	return __imx8mq_clk_enable(clk, 0);
-}
-
-static int imx8mq_clk_enable(struct clk *clk)
-{
-	return __imx8mq_clk_enable(clk, 1);
-}
-
-static int imx8mq_clk_set_parent(struct clk *clk, struct clk *parent)
-{
-	struct clk *c, *cp;
-	int ret;
-
-	debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
-
-	ret = clk_get_by_id(clk->id, &c);
-	if (ret)
-		return ret;
-
-	ret = clk_get_by_id(parent->id, &cp);
-	if (ret)
-		return ret;
-
-	ret = clk_set_parent(c, cp);
-	c->dev->parent = cp->dev;
-
-	return ret;
-}
-
-static struct clk_ops imx8mq_clk_ops = {
-	.set_rate = imx8mq_clk_set_rate,
-	.get_rate = imx8mq_clk_get_rate,
-	.enable = imx8mq_clk_enable,
-	.disable = imx8mq_clk_disable,
-	.set_parent = imx8mq_clk_set_parent,
-};
-
 static int imx8mq_clk_probe(struct udevice *dev)
 {
 	void __iomem *base;
@@ -522,7 +435,7 @@ U_BOOT_DRIVER(imx8mq_clk) = {
 	.name = "clk_imx8mq",
 	.id = UCLASS_CLK,
 	.of_match = imx8mq_clk_ids,
-	.ops = &imx8mq_clk_ops,
+	.ops = &imx8m_clk_ops,
 	.probe = imx8mq_clk_probe,
 	.flags = DM_FLAG_PRE_RELOC,
 };
-- 
2.25.1


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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-15 13:08 ` [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq Angus Ainslie
@ 2022-03-15 15:12   ` Heiko Thiery
  2022-03-15 15:35   ` Heiko Thiery
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 26+ messages in thread
From: Heiko Thiery @ 2022-03-15 15:12 UTC (permalink / raw)
  To: Angus Ainslie
  Cc: u-boot, Marek Vasut, lukma, seanga2, sbabic, festevam, kernel,
	uboot-imx, peng.fan

Hi Angus,

Am Di., 15. März 2022 um 14:09 Uhr schrieb Angus Ainslie <angus@akkea.ca>:

> This is a DM clock driver based off the imx8mm u-boot driver and the linux
> kernel driver.
>
> All of the PLLs and clocks are initialized so the subsystems below are
> functional and tested.
>
> 1) USB host and peripheral
> 2) ECSPI
> 3) UART
> 4) I2C all busses
> 5) USDHC for eMMC support
> 6) USB storage
> 7) GPIO
> 8) DRAM
>
> Signed-off-by: Angus Ainslie <angus@akkea.ca>
> ---
>  drivers/clk/imx/Kconfig      |  16 +
>  drivers/clk/imx/Makefile     |   2 +
>  drivers/clk/imx/clk-imx8mq.c | 575 +++++++++++++++++++++++++++++++++++
>  3 files changed, 593 insertions(+)
>  create mode 100644 drivers/clk/imx/clk-imx8mq.c
>
> diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
> index cdd348020b0..06d8c1a5dd3 100644
> --- a/drivers/clk/imx/Kconfig
> +++ b/drivers/clk/imx/Kconfig
> @@ -71,6 +71,22 @@ config CLK_IMX8MP
>         help
>           This enables support clock driver for i.MX8MP platforms.
>
> +config SPL_CLK_IMX8MQ
> +       bool "SPL clock support for i.MX8MQ"
> +       depends on ARCH_IMX8M && SPL
> +       select SPL_CLK
> +       select SPL_CLK_CCF
>

you should select SPL_CLK_COMPOSITE_CCF ...


> +       help
> +         This enables SPL DM/DTS support for clock driver in i.MX8MQ
> +
> +config CLK_IMX8MQ
> +       bool "Clock support for i.MX8MQ"
> +       depends on ARCH_IMX8M
> +       select CLK
> +       select CLK_CCF
>

.. and select CLK_COMPOSITE_CCF here.


> +       help
> +         This enables support clock driver for i.MX8MQ platforms.
> +
>  config SPL_CLK_IMXRT1020
>         bool "SPL clock support for i.MXRT1020"
>         depends on ARCH_IMXRT && SPL
>
> [SNIP]

-- 
Heiko

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-15 13:08 ` [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq Angus Ainslie
  2022-03-15 15:12   ` Heiko Thiery
@ 2022-03-15 15:35   ` Heiko Thiery
  2022-03-15 15:46     ` Angus Ainslie
                       ` (2 more replies)
  2022-03-20 23:57   ` Sean Anderson
  2022-03-24  8:28   ` Heiko Thiery
  3 siblings, 3 replies; 26+ messages in thread
From: Heiko Thiery @ 2022-03-15 15:35 UTC (permalink / raw)
  To: Angus Ainslie
  Cc: u-boot, Marek Vasut, lukma, seanga2, sbabic, festevam, kernel,
	uboot-imx, peng.fan

Hi Angus and all,




Am Di., 15. März 2022 um 14:09 Uhr schrieb Angus Ainslie <angus@akkea.ca>:

> This is a DM clock driver based off the imx8mm u-boot driver and the linux
> kernel driver.
>
> All of the PLLs and clocks are initialized so the subsystems below are
> functional and tested.
>
> 1) USB host and peripheral
> 2) ECSPI
> 3) UART
> 4) I2C all busses
> 5) USDHC for eMMC support
> 6) USB storage
> 7) GPIO
> 8) DRAM
>
> Signed-off-by: Angus Ainslie <angus@akkea.ca>
> ---
>  drivers/clk/imx/Kconfig      |  16 +
>  drivers/clk/imx/Makefile     |   2 +
>  drivers/clk/imx/clk-imx8mq.c | 575 +++++++++++++++++++++++++++++++++++
>  3 files changed, 593 insertions(+)
>  create mode 100644 drivers/clk/imx/clk-imx8mq.c
>
> diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
> index cdd348020b0..06d8c1a5dd3 100644
> --- a/drivers/clk/imx/Kconfig
> +++ b/drivers/clk/imx/Kconfig
> @@ -71,6 +71,22 @@ config CLK_IMX8MP
>         help
>           This enables support clock driver for i.MX8MP platforms.
>
> +config SPL_CLK_IMX8MQ
> +       bool "SPL clock support for i.MX8MQ"
> +       depends on ARCH_IMX8M && SPL
> +       select SPL_CLK
> +       select SPL_CLK_CCF
> +       help
> +         This enables SPL DM/DTS support for clock driver in i.MX8MQ
> +
> +config CLK_IMX8MQ
> +       bool "Clock support for i.MX8MQ"
> +       depends on ARCH_IMX8M
> +       select CLK
> +       select CLK_CCF
> +       help
> +         This enables support clock driver for i.MX8MQ platforms.
> +
>  config SPL_CLK_IMXRT1020
>         bool "SPL clock support for i.MXRT1020"
>         depends on ARCH_IMXRT && SPL
> diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
> index 01bbbdf3aea..c5766901f2b 100644
> --- a/drivers/clk/imx/Makefile
> +++ b/drivers/clk/imx/Makefile
> @@ -16,6 +16,8 @@ obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MN) += clk-imx8mn.o
> clk-pll14xx.o \
>                                 clk-composite-8m.o
>  obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MP) += clk-imx8mp.o clk-pll14xx.o \
>                                 clk-composite-8m.o
> +obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MQ) += clk-imx8mq.o clk-pll14xx.o \
> +                               clk-composite-8m.o
>
>  obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1020) += clk-imxrt1020.o
>  obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1050) += clk-imxrt1050.o
> diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
> new file mode 100644
> index 00000000000..0aea417a29b
> --- /dev/null
> +++ b/drivers/clk/imx/clk-imx8mq.c
> @@ -0,0 +1,575 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2019 NXP
> + * Copyright 2022 Purism
> + * Peng Fan <peng.fan@nxp.com>
> + */
> +
> +#include <common.h>
> +#include <clk.h>
> +#include <clk-uclass.h>
> +#include <dm.h>
> +#include <log.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/imx-regs.h>
> +#include <dt-bindings/clock/imx8mq-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 imx8mq_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),
> +};
> +
> +const struct imx_pll14xx_rate_table imx8mq_pll1443x_tbl[] = {
> +       PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
> +       PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
> +       PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
> +       PLL_1443X_RATE(361267200U, 361, 3, 3, 17511),
> +};
> +
> +static struct imx_pll14xx_clk imx8mq_1416x_pll __initdata = {
> +               .type = PLL_1416X,
> +               .rate_table = imx8mq_pll1416x_tbl,
> +               .rate_count = ARRAY_SIZE(imx8mq_pll1416x_tbl),
> +};
> +
> +static struct imx_pll14xx_clk imx8mq_1443x_pll __initdata = {
> +               .type = PLL_1443X,
> +               .rate_table = imx8mq_pll1443x_tbl,
> +               .rate_count = ARRAY_SIZE(imx8mq_pll1443x_tbl),
> +};
> +
> +static const char *pll_ref_sels[] = { "clock-osc-25m", "clock-osc-27m",
> "clock-phy-27m", "dummy", };
> +static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_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 *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 *imx8mq_a53_core_sels[] = {"arm_a53_div",
> "arm_pll_out", };
> +static const char *imx8mq_a53_sels[] = {"clock-osc-25m", "arm_pll_out",
> "sys_pll2_500m",
> +                                       "sys_pll2_1000m", "sys_pll1_800m",
> "sys_pll1_400m",
> +                                       "audio_pll1_out", "sys_pll3_out",
> };
> +
> +static const char *imx8mq_ahb_sels[] = {"clock-osc-25m", "sys_pll1_133m",
> "sys_pll1_800m",
> +                                       "sys_pll1_400m", "sys_pll2_125m",
> "sys_pll3_out",
> +                                       "audio_pll1_out",
> "video_pll1_out", };
> +
> +static const char *imx8mq_enet_axi_sels[] = {"clock-osc-25m",
> "sys_pll1_266m", "sys_pll1_800m",
> +                                            "sys_pll2_250m",
> "sys_pll2_200m", "audio_pll1_out",
> +                                            "video_pll1_out",
> "sys_pll3_out", };
> +
> +static const char *imx8mq_enet_ref_sels[] = {"clock-osc-25m",
> "sys_pll2_125m", "sys_pll2_50m",
> +                                            "sys_pll2_100m",
> "sys_pll1_160m", "audio_pll1_out",
> +                                            "video_pll1_out", "clk_ext4",
> };
> +
> +static const char *imx8mq_enet_timer_sels[] = {"clock-osc-25m",
> "sys_pll2_100m", "audio_pll1_out",
> +                                              "clk_ext1", "clk_ext2",
> "clk_ext3", "clk_ext4",
> +                                              "video_pll1_out", };
> +
> +static const char *imx8mq_enet_phy_sels[] = {"clock-osc-25m",
> "sys_pll2_50m", "sys_pll2_125m",
> +                                            "sys_pll2_200m",
> "sys_pll2_500m", "video_pll1_out",
> +                                            "audio_pll2_out", };
> +
> +static const char *imx8mq_nand_usdhc_sels[] = {"clock-osc-25m",
> "sys_pll1_266m", "sys_pll1_800m",
> +                                              "sys_pll2_200m",
> "sys_pll1_133m", "sys_pll3_out",
> +                                              "sys_pll2_250m",
> "audio_pll1_out", };
> +
> +static const char *imx8mq_usb_bus_sels[] = {"clock-osc-25m",
> "sys_pll2_500m", "sys_pll1_800m",
> +                                           "sys_pll2_100m",
> "sys_pll2_200m", "clk_ext2",
> +                                           "clk_ext4", "audio_pll2_out",
> };
> +
> +static const char *imx8mq_usdhc1_sels[] = {"clock-osc-25m",
> "sys_pll1_400m", "sys_pll1_800m",
> +                                          "sys_pll2_500m",
> "sys_pll3_out", "sys_pll1_266m",
> +                                          "audio_pll2_out",
> "sys_pll1_100m", };
> +
> +static const char *imx8mq_usdhc2_sels[] = {"clock-osc-25m",
> "sys_pll1_400m", "sys_pll1_800m",
> +                                          "sys_pll2_500m",
> "sys_pll3_out", "sys_pll1_266m",
> +                                          "audio_pll2_out",
> "sys_pll1_100m", };
> +
> +static const char *imx8mq_i2c1_sels[] = {"clock-osc-25m",
> "sys_pll1_160m", "sys_pll2_50m",
> +                                        "sys_pll3_out", "audio_pll1_out",
> "video_pll1_out",
> +                                        "audio_pll2_out",
> "sys_pll1_133m", };
> +
> +static const char *imx8mq_i2c2_sels[] = {"clock-osc-25m",
> "sys_pll1_160m", "sys_pll2_50m",
> +                                        "sys_pll3_out", "audio_pll1_out",
> "video_pll1_out",
> +                                        "audio_pll2_out",
> "sys_pll1_133m", };
> +
> +static const char *imx8mq_i2c3_sels[] = {"clock-osc-25m",
> "sys_pll1_160m", "sys_pll2_50m",
> +                                        "sys_pll3_out", "audio_pll1_out",
> "video_pll1_out",
> +                                        "audio_pll2_out",
> "sys_pll1_133m", };
> +
> +static const char *imx8mq_i2c4_sels[] = {"clock-osc-25m",
> "sys_pll1_160m", "sys_pll2_50m",
> +                                        "sys_pll3_out", "audio_pll1_out",
> "video_pll1_out",
> +                                        "audio_pll2_out",
> "sys_pll1_133m", };
> +
> +static const char *imx8mq_wdog_sels[] = {"clock-osc-25m",
> "sys_pll1_133m", "sys_pll1_160m",
> +                                        "vpu_pll_out", "sys_pll2_125m",
> "sys_pll3_out",
> +                                        "sys_pll1_80m", "sys_pll2_166m",
> };
> +
> +static const char *imx8mq_qspi_sels[] = {"clock-osc-25m",
> "sys_pll1_400m", "sys_pll2_333m",
> +                                        "sys_pll2_500m",
> "audio_pll2_out", "sys_pll1_266m",
> +                                        "sys_pll3_out", "sys_pll1_100m",
> };
> +
> +static const char *imx8mq_usb_core_sels[] = {"clock-osc-25m",
> "sys_pll1_100m", "sys_pll1_40m",
> +                                            "sys_pll2_100m",
> "sys_pll2_200m", "clk_ext2",
> +                                            "clk_ext3", "audio_pll2_out",
> };
> +
> +static const char *imx8mq_usb_phy_sels[] = {"clock-osc-25m",
> "sys_pll1_100m", "sys_pll1_40m",
> +                                           "sys_pll2_100m",
> "sys_pll2_200m", "clk_ext2",
> +                                           "clk_ext3", "audio_pll2_out",
> };
> +
> +static const char *imx8mq_ecspi1_sels[] = {"clock-osc-25m",
> "sys_pll2_200m", "sys_pll1_40m",
> +                                          "sys_pll1_160m",
> "sys_pll1_800m", "sys_pll3_out",
> +                                          "sys_pll2_250m",
> "audio_pll2_out", };
> +
> +static const char *imx8mq_ecspi2_sels[] = {"clock-osc-25m",
> "sys_pll2_200m", "sys_pll1_40m",
> +                                          "sys_pll1_160m",
> "sys_pll1_800m", "sys_pll3_out",
> +                                          "sys_pll2_250m",
> "audio_pll2_out", };
> +
> +static const char *imx8mq_ecspi3_sels[] = {"clock-osc-25m",
> "sys_pll2_200m", "sys_pll1_40m",
> +                                          "sys_pll1_160m",
> "sys_pll1_800m", "sys_pll3_out",
> +                                          "sys_pll2_250m",
> "audio_pll2_out", };
> +
> +static const char *pllout_monitor_sels[] = {"clock-osc-25m",
> "clock-osc-27m", "clock-phy-27m",
> +                                           "dummy", "clock-ckil",
> "audio_pll1_out_monitor",
> +                                           "audio_pll2_out_monitor",
> "gpu_pll_out_monitor",
> +                                           "vpu_pll_out_monitor",
> "video_pll1_out_monitor",
> +                                           "arm_pll_out_monitor",
> "sys_pll1_out_monitor",
> +                                           "sys_pll2_out_monitor",
> "sys_pll3_out_monitor",
> +                                           "dummy",
> "dram_pll_out_monitor", };
> +
> +static ulong imx8mq_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 imx8mq_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 __imx8mq_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) {
> +               debug("%s: clk_get_by_id failed\n", __func__);
> +               return ret;
> +       }
> +
> +       if (enable)
> +               ret = clk_enable(c);
> +       else
> +               ret = clk_disable(c);
> +
> +       return ret;
> +}
> +
> +static int imx8mq_clk_disable(struct clk *clk)
> +{
> +       return __imx8mq_clk_enable(clk, 0);
> +}
> +
> +static int imx8mq_clk_enable(struct clk *clk)
> +{
> +       return __imx8mq_clk_enable(clk, 1);
> +}
> +
> +static int imx8mq_clk_set_parent(struct clk *clk, struct clk *parent)
> +{
> +       struct clk *c, *cp;
> +       int ret;
> +
> +       debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
> +
> +       ret = clk_get_by_id(clk->id, &c);
> +       if (ret)
> +               return ret;
> +
> +       ret = clk_get_by_id(parent->id, &cp);
> +       if (ret)
> +               return ret;
> +
> +       ret = clk_set_parent(c, cp);
> +       c->dev->parent = cp->dev;
> +
> +       return ret;
> +}
> +
> +static struct clk_ops imx8mq_clk_ops = {
> +       .set_rate = imx8mq_clk_set_rate,
> +       .get_rate = imx8mq_clk_get_rate,
> +       .enable = imx8mq_clk_enable,
> +       .disable = imx8mq_clk_disable,
> +       .set_parent = imx8mq_clk_set_parent,
> +};
> +
> +static int imx8mq_clk_probe(struct udevice *dev)
> +{
> +       void __iomem *base;
> +
> +       base = (void *)ANATOP_BASE_ADDR;
> +
> +       clk_dm(IMX8MQ_CLK_32K, clk_register_fixed_rate(NULL, "ckil",
> 32768));
> +
> +       clk_dm(IMX8MQ_DRAM_PLL1_REF_SEL,
> +              imx_clk_mux("dram_pll_ref_sel", base + 0x60, 0, 2,
> +                          pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
> +       clk_dm(IMX8MQ_ARM_PLL_REF_SEL,
> +              imx_clk_mux("arm_pll_ref_sel", base + 0x28, 0, 2,
> +                          pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
> +       clk_dm(IMX8MQ_GPU_PLL_REF_SEL,
> +              imx_clk_mux("gpu_pll_ref_sel", base + 0x18, 0, 2,
> +                          pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
> +       clk_dm(IMX8MQ_VPU_PLL_REF_SEL,
> +              imx_clk_mux("vpu_pll_ref_sel", base + 0x20, 0, 2,
> +                          pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
> +       clk_dm(IMX8MQ_SYS3_PLL1_REF_SEL,
> +              imx_clk_mux("sys3_pll_ref_sel", base + 0x48, 0, 2,
> +                          pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
> +       clk_dm(IMX8MQ_AUDIO_PLL1_REF_SEL,
> +              imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2,
> +                          pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
> +       clk_dm(IMX8MQ_AUDIO_PLL2_REF_SEL,
> +              imx_clk_mux("audio_pll2_ref_sel", base + 0x8, 0, 2,
> +                          pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
> +       clk_dm(IMX8MQ_VIDEO_PLL1_REF_SEL,
> +              imx_clk_mux("video_pll1_ref_sel", base + 0x10, 0, 2,
> +                          pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
> +
> +       clk_dm(IMX8MQ_ARM_PLL,
> +              imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel",
> +                              base + 0x28, &imx8mq_1416x_pll));
> +       clk_dm(IMX8MQ_GPU_PLL,
> +              imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel",
> +                              base + 0x18, &imx8mq_1416x_pll));
> +       clk_dm(IMX8MQ_VPU_PLL,
> +              imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel",
> +                              base + 0x20, &imx8mq_1416x_pll));
> +
> +       clk_dm(IMX8MQ_SYS1_PLL1,
> +              clk_register_fixed_rate(NULL, "sys1_pll", 800000000));
> +       clk_dm(IMX8MQ_SYS2_PLL1,
> +              clk_register_fixed_rate(NULL, "sys2_pll", 1000000000));
> +       clk_dm(IMX8MQ_SYS2_PLL1,
> +              clk_register_fixed_rate(NULL, "sys3_pll", 1000000000));
> +       clk_dm(IMX8MQ_AUDIO_PLL1,
> +              imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel",
> +                              base + 0x0, &imx8mq_1443x_pll));
> +       clk_dm(IMX8MQ_AUDIO_PLL2,
> +              imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel",
> +                              base + 0x8, &imx8mq_1443x_pll));
> +       clk_dm(IMX8MQ_VIDEO_PLL1,
> +              imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel",
> +                              base + 0x10, &imx8mq_1443x_pll));
> +
> +       /* PLL bypass out */
> +       clk_dm(IMX8MQ_ARM_PLL_BYPASS,
> +              imx_clk_mux_flags("arm_pll_bypass", base + 0x28, 4, 1,
> +                                arm_pll_bypass_sels,
> +                                ARRAY_SIZE(arm_pll_bypass_sels),
> +                                CLK_SET_RATE_PARENT));
> +       clk_dm(IMX8MQ_GPU_PLL_BYPASS,
> +              imx_clk_mux_flags("gpu_pll_bypass", base + 0x18, 4, 1,
> +                                gpu_pll_bypass_sels,
> +                                ARRAY_SIZE(gpu_pll_bypass_sels),
> +                                CLK_SET_RATE_PARENT));
> +       clk_dm(IMX8MQ_VPU_PLL_BYPASS,
> +              imx_clk_mux_flags("vpu_pll_bypass", base + 0x20, 4, 1,
> +                                vpu_pll_bypass_sels,
> +                                ARRAY_SIZE(vpu_pll_bypass_sels),
> +                                CLK_SET_RATE_PARENT));
> +       clk_dm(IMX8MQ_AUDIO_PLL1_BYPASS,
> +              imx_clk_mux_flags("audio_pll1_bypass", base + 0x0, 4, 1,
> +                                audio_pll1_bypass_sels,
> +                                ARRAY_SIZE(audio_pll1_bypass_sels),
> +                                CLK_SET_RATE_PARENT));
> +       clk_dm(IMX8MQ_AUDIO_PLL2_BYPASS,
> +              imx_clk_mux_flags("audio_pll2_bypass", base + 0x8, 4, 1,
> +                                audio_pll2_bypass_sels,
> +                                ARRAY_SIZE(audio_pll2_bypass_sels),
> +                                CLK_SET_RATE_PARENT));
> +       clk_dm(IMX8MQ_VIDEO_PLL1_BYPASS,
> +              imx_clk_mux_flags("video_pll1_bypass", base + 0x10, 4, 1,
> +                                video_pll1_bypass_sels,
> +                                ARRAY_SIZE(video_pll1_bypass_sels),
> +                                CLK_SET_RATE_PARENT));
> +
> +       /* PLL out gate */
> +       clk_dm(IMX8MQ_DRAM_PLL_OUT,
> +              imx_clk_gate("dram_pll_out", "dram_pll_ref_sel",
> +                           base + 0x60, 13));
> +       clk_dm(IMX8MQ_ARM_PLL_OUT,
> +              imx_clk_gate("arm_pll_out", "arm_pll_bypass",
> +                           base + 0x28, 11));
> +       clk_dm(IMX8MQ_GPU_PLL_OUT,
> +              imx_clk_gate("gpu_pll_out", "gpu_pll_bypass",
> +                           base + 0x18, 11));
> +       clk_dm(IMX8MQ_VPU_PLL_OUT,
> +              imx_clk_gate("vpu_pll_out", "vpu_pll_bypass",
> +                           base + 0x20, 11));
> +       clk_dm(IMX8MQ_AUDIO_PLL1_OUT,
> +              imx_clk_gate("audio_pll1_out", "audio_pll1_bypass",
> +                           base + 0x0, 11));
> +       clk_dm(IMX8MQ_AUDIO_PLL2_OUT,
> +              imx_clk_gate("audio_pll2_out", "audio_pll2_bypass",
> +                           base + 0x8, 11));
> +       clk_dm(IMX8MQ_VIDEO_PLL1_OUT,
> +              imx_clk_gate("video_pll1_out", "video_pll1_bypass",
> +                           base + 0x10, 11));
> +
> +       clk_dm(IMX8MQ_SYS1_PLL_OUT,
> +              imx_clk_gate("sys_pll1_out", "sys1_pll",
> +                           base + 0x30, 11));
> +       clk_dm(IMX8MQ_SYS2_PLL_OUT,
> +              imx_clk_gate("sys_pll2_out", "sys2_pll",
> +                           base + 0x3c, 11));
> +       clk_dm(IMX8MQ_SYS3_PLL_OUT,
> +              imx_clk_gate("sys_pll3_out", "sys3_pll",
> +                           base + 0x48, 11));
> +
> +       /* SYS PLL fixed output */
> +       clk_dm(IMX8MQ_SYS1_PLL_40M,
> +              imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1,
> 20));
> +       clk_dm(IMX8MQ_SYS1_PLL_80M,
> +              imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1,
> 10));
> +       clk_dm(IMX8MQ_SYS1_PLL_100M,
> +              imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1,
> 8));
> +       clk_dm(IMX8MQ_SYS1_PLL_133M,
> +              imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1,
> 6));
> +       clk_dm(IMX8MQ_SYS1_PLL_160M,
> +              imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1,
> 5));
> +       clk_dm(IMX8MQ_SYS1_PLL_200M,
> +              imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1,
> 4));
> +       clk_dm(IMX8MQ_SYS1_PLL_266M,
> +              imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1,
> 3));
> +       clk_dm(IMX8MQ_SYS1_PLL_400M,
> +              imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1,
> 2));
> +       clk_dm(IMX8MQ_SYS1_PLL_800M,
> +              imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1,
> 1));
> +
> +       clk_dm(IMX8MQ_SYS2_PLL_50M,
> +              imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1,
> 20));
> +       clk_dm(IMX8MQ_SYS2_PLL_100M,
> +              imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1,
> 10));
> +       clk_dm(IMX8MQ_SYS2_PLL_125M,
> +              imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1,
> 8));
> +       clk_dm(IMX8MQ_SYS2_PLL_166M,
> +              imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1,
> 6));
> +       clk_dm(IMX8MQ_SYS2_PLL_200M,
> +              imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1,
> 5));
> +       clk_dm(IMX8MQ_SYS2_PLL_250M,
> +              imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1,
> 4));
> +       clk_dm(IMX8MQ_SYS2_PLL_333M,
> +              imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1,
> 3));
> +       clk_dm(IMX8MQ_SYS2_PLL_500M,
> +              imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1,
> 2));
> +       clk_dm(IMX8MQ_SYS2_PLL_1000M,
> +              imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1,
> 1));
> +
> +       clk_dm(IMX8MQ_CLK_MON_AUDIO_PLL1_DIV,
> +              imx_clk_divider("audio_pll1_out_monitor",
> "audio_pll1_bypass", base + 0x78, 0, 3));
> +       clk_dm(IMX8MQ_CLK_MON_AUDIO_PLL2_DIV,
> +              imx_clk_divider("audio_pll2_out_monitor",
> "audio_pll2_bypass", base + 0x78, 4, 3));
> +       clk_dm(IMX8MQ_CLK_MON_VIDEO_PLL1_DIV,
> +              imx_clk_divider("video_pll1_out_monitor",
> "video_pll1_bypass", base + 0x78, 8, 3));
> +       clk_dm(IMX8MQ_CLK_MON_GPU_PLL_DIV,
> +              imx_clk_divider("gpu_pll_out_monitor", "gpu_pll_bypass",
> base + 0x78, 12, 3));
> +       clk_dm(IMX8MQ_CLK_MON_VPU_PLL_DIV,
> +              imx_clk_divider("vpu_pll_out_monitor", "vpu_pll_bypass",
> base + 0x78, 16, 3));
> +       clk_dm(IMX8MQ_CLK_MON_ARM_PLL_DIV,
> +              imx_clk_divider("arm_pll_out_monitor", "arm_pll_bypass",
> base + 0x78, 20, 3));
> +       clk_dm(IMX8MQ_CLK_MON_SYS_PLL1_DIV,
> +              imx_clk_divider("sys_pll1_out_monitor", "sys_pll1_out",
> base + 0x7c, 0, 3));
> +       clk_dm(IMX8MQ_CLK_MON_SYS_PLL2_DIV,
> +              imx_clk_divider("sys_pll2_out_monitor", "sys_pll2_out",
> base + 0x7c, 4, 3));
> +       clk_dm(IMX8MQ_CLK_MON_SYS_PLL3_DIV,
> +              imx_clk_divider("sys_pll3_out_monitor", "sys_pll3_out",
> base + 0x7c, 8, 3));
> +       clk_dm(IMX8MQ_CLK_MON_DRAM_PLL_DIV,
> +              imx_clk_divider("dram_pll_out_monitor", "dram_pll_out",
> base + 0x7c, 12, 3));
> +       clk_dm(IMX8MQ_CLK_MON_SEL,
> +              imx_clk_mux_flags("pllout_monitor_sel", base + 0x74, 0, 4,
> +                                pllout_monitor_sels,
> +                                ARRAY_SIZE(pllout_monitor_sels),
> +                                CLK_SET_RATE_PARENT));
> +       clk_dm(IMX8MQ_CLK_MON_CLK2_OUT,
> +              imx_clk_gate4("pllout_monitor_clk2", "pllout_monitor_sel",
> base + 0x74, 4));
> +
> +       base = dev_read_addr_ptr(dev);
> +       if (!base) {
> +               printf("%s : base failed\n", __func__);
> +               return -EINVAL;
> +       }
> +
> +       clk_dm(IMX8MQ_CLK_A53_SRC,
> +              imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3,
> +                           imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels)));
> +       clk_dm(IMX8MQ_CLK_A53_CG,
> +              imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000,
> 28));
> +       clk_dm(IMX8MQ_CLK_A53_DIV,
> +              imx_clk_divider2("arm_a53_div", "arm_a53_cg",
> +                               base + 0x8000, 0, 3));
> +       clk_dm(IMX8MQ_CLK_A53_CORE,
> +              imx_clk_mux2("arm_a53_src", base + 0x9880, 24, 1,
> +                           imx8mq_a53_core_sels,
> ARRAY_SIZE(imx8mq_a53_core_sels)));
> +
> +       clk_dm(IMX8MQ_CLK_AHB,
> +              imx8m_clk_composite_critical("ahb", imx8mq_ahb_sels,
> +                                           base + 0x9000));
> +       clk_dm(IMX8MQ_CLK_IPG_ROOT,
> +              imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1));
> +
> +       clk_dm(IMX8MQ_CLK_ENET_AXI,
> +              imx8m_clk_composite("enet_axi", imx8mq_enet_axi_sels,
> +                                  base + 0x8880));
> +       clk_dm(IMX8MQ_CLK_NAND_USDHC_BUS,
> +              imx8m_clk_composite_critical("nand_usdhc_bus",
> +                                           imx8mq_nand_usdhc_sels,
> +                                           base + 0x8900));
> +       clk_dm(IMX8MQ_CLK_USB_BUS,
> +              imx8m_clk_composite("usb_bus", imx8mq_usb_bus_sels, base +
> 0x8b80));
> +
> +       /* IP */
> +       clk_dm(IMX8MQ_CLK_USDHC1,
> +              imx8m_clk_composite("usdhc1", imx8mq_usdhc1_sels,
> +                                  base + 0xac00));
> +       clk_dm(IMX8MQ_CLK_USDHC2,
> +              imx8m_clk_composite("usdhc2", imx8mq_usdhc2_sels,
> +                                  base + 0xac80));
> +       clk_dm(IMX8MQ_CLK_I2C1,
> +              imx8m_clk_composite("i2c1", imx8mq_i2c1_sels, base +
> 0xad00));
> +       clk_dm(IMX8MQ_CLK_I2C2,
> +              imx8m_clk_composite("i2c2", imx8mq_i2c2_sels, base +
> 0xad80));
> +       clk_dm(IMX8MQ_CLK_I2C3,
> +              imx8m_clk_composite("i2c3", imx8mq_i2c3_sels, base +
> 0xae00));
> +       clk_dm(IMX8MQ_CLK_I2C4,
> +              imx8m_clk_composite("i2c4", imx8mq_i2c4_sels, base +
> 0xae80));
> +       clk_dm(IMX8MQ_CLK_WDOG,
> +              imx8m_clk_composite("wdog", imx8mq_wdog_sels, base +
> 0xb900));
> +       clk_dm(IMX8MQ_CLK_QSPI,
> +              imx8m_clk_composite("qspi", imx8mq_qspi_sels, base +
> 0xab80));
> +       clk_dm(IMX8MQ_CLK_USB_CORE_REF,
> +              imx8m_clk_composite("usb_core_ref", imx8mq_usb_core_sels,
> base + 0xb100));
> +       clk_dm(IMX8MQ_CLK_USB_PHY_REF,
> +              imx8m_clk_composite("usb_phy_ref", imx8mq_usb_phy_sels,
> base + 0xb180));
> +       clk_dm(IMX8MQ_CLK_ECSPI1,
> +              imx8m_clk_composite("ecspi1", imx8mq_ecspi1_sels, base +
> 0xb280));
> +       clk_dm(IMX8MQ_CLK_ECSPI2,
> +              imx8m_clk_composite("ecspi2", imx8mq_ecspi2_sels, base +
> 0xb300));
> +       clk_dm(IMX8MQ_CLK_ECSPI3,
> +              imx8m_clk_composite("ecspi3", imx8mq_ecspi3_sels, base +
> 0xc180));
> +
> +       clk_dm(IMX8MQ_CLK_ECSPI1_ROOT,
> +              imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070,
> 0));
> +       clk_dm(IMX8MQ_CLK_ECSPI2_ROOT,
> +              imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080,
> 0));
> +       clk_dm(IMX8MQ_CLK_ECSPI3_ROOT,
> +              imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090,
> 0));
> +       clk_dm(IMX8MQ_CLK_I2C1_ROOT,
> +              imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0));
> +       clk_dm(IMX8MQ_CLK_I2C2_ROOT,
> +              imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0));
> +       clk_dm(IMX8MQ_CLK_I2C3_ROOT,
> +              imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0));
> +       clk_dm(IMX8MQ_CLK_I2C4_ROOT,
> +              imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0));
> +       clk_dm(IMX8MQ_CLK_OCOTP_ROOT,
> +              imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220,
> 0));
> +       clk_dm(IMX8MQ_CLK_USDHC1_ROOT,
> +              imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510,
> 0));
> +       clk_dm(IMX8MQ_CLK_USDHC2_ROOT,
> +              imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520,
> 0));
> +       clk_dm(IMX8MQ_CLK_WDOG1_ROOT,
> +              imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0));
> +       clk_dm(IMX8MQ_CLK_WDOG2_ROOT,
> +              imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0));
> +       clk_dm(IMX8MQ_CLK_WDOG3_ROOT,
> +              imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0));
> +       clk_dm(IMX8MQ_CLK_QSPI_ROOT,
> +              imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0));
> +       clk_dm(IMX8MQ_CLK_USB1_CTRL_ROOT,
> +              imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base +
> 0x44d0, 0));
> +       clk_dm(IMX8MQ_CLK_USB2_CTRL_ROOT,
> +              imx_clk_gate4("usb2_ctrl_root_clk", "usb_bus", base +
> 0x44e0, 0));
> +       clk_dm(IMX8MQ_CLK_USB1_PHY_ROOT,
> +              imx_clk_gate4("usb1_phy_root_clk", "usb_phy_ref", base +
> 0x44f0, 0));
> +       clk_dm(IMX8MQ_CLK_USB2_PHY_ROOT,
> +              imx_clk_gate4("usb2_phy_root_clk", "usb_phy_ref", base +
> 0x4500, 0));
> +
> +       clk_dm(IMX8MQ_CLK_ENET_REF,
> +              imx8m_clk_composite("enet_ref", imx8mq_enet_ref_sels,
> +                                  base + 0xa980));
> +       clk_dm(IMX8MQ_CLK_ENET_TIMER,
> +              imx8m_clk_composite("enet_timer", imx8mq_enet_timer_sels,
> +                                  base + 0xaa00));
> +       clk_dm(IMX8MQ_CLK_ENET_PHY_REF,
> +              imx8m_clk_composite("enet_phy", imx8mq_enet_phy_sels,
> +                                  base + 0xaa80));
> +       clk_dm(IMX8MQ_CLK_ENET1_ROOT,
> +              imx_clk_gate4("enet1_root_clk", "enet_axi",
> +                            base + 0x40a0, 0));
> +
> +       return 0;
> +}
> +
> +static const struct udevice_id imx8mq_clk_ids[] = {
> +       { .compatible = "fsl,imx8mq-ccm" },
> +       { },
> +};
> +
> +U_BOOT_DRIVER(imx8mq_clk) = {
> +       .name = "clk_imx8mq",
> +       .id = UCLASS_CLK,
> +       .of_match = imx8mq_clk_ids,
> +       .ops = &imx8mq_clk_ops,
> +       .probe = imx8mq_clk_probe,
> +       .flags = DM_FLAG_PRE_RELOC,
> +};
> --
> 2.25.1
>
>
when adding this patch and enabling CLK_IMX8MQ I see the following on my
board .. Any idea what I missed here?

--- >8 ---
U-Boot SPL 2022.04-rc4-00008-g390d9bf9a1 (Mar 15 2022 - 16:26:59 +0100)
Trying to boot from SD card


U-Boot 2022.04-rc4-00008-g390d9bf9a1 (Mar 15 2022 - 16:26:59 +0100)

CPU:   Freescale i.MX8MQ rev2.1 at 800 MHz
Reset cause: POR
Model: Kontron pITX-imx8m
DRAM:  alloc space exhausted
alloc space exhausted
alloc space exhausted
alloc space exhausted
alloc space exhausted
alloc space exhausted
alloc space exhausted
alloc space exhausted
alloc space exhausted
alloc space exhausted
alloc space exhausted
alloc space exhausted
4 GiB
clk_register: failed to get <NULL> device (parent of ckil)
clk_register: failed to get <NULL> device (parent of sys1_pll)
clk_register: failed to get <NULL> device (parent of sys2_pll)
clk_register: failed to get <NULL> device (parent of sys3_pll)
No serial driver found
resetting ...

--- >8 ---

-- 
Heiko

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-15 15:35   ` Heiko Thiery
@ 2022-03-15 15:46     ` Angus Ainslie
  2022-03-15 16:13       ` Angus Ainslie
  2022-03-16  7:14       ` Heiko Thiery
  2022-03-15 19:01     ` Marek Vasut
  2022-03-21  1:32     ` Peng Fan (OSS)
  2 siblings, 2 replies; 26+ messages in thread
From: Angus Ainslie @ 2022-03-15 15:46 UTC (permalink / raw)
  To: Heiko Thiery, Angus Ainslie
  Cc: u-boot, Marek Vasut, lukma, seanga2, sbabic, festevam, kernel,
	uboot-imx, peng.fan

Hi Heiko,

On 2022-03-15 08:35, Heiko Thiery wrote:
> Hi Angus and all,
>
>
>
>
> Am Di., 15. März 2022 um 14:09 Uhr schrieb Angus Ainslie <angus@akkea.ca>:
>
>     This is a DM clock driver based off the imx8mm u-boot driver and
>     the linux
>     kernel driver.
>
>     All of the PLLs and clocks are initialized so the subsystems below are
>     functional and tested.
>
>     1) USB host and peripheral
>     2) ECSPI
>     3) UART
>     4) I2C all busses
>     5) USDHC for eMMC support
>     6) USB storage
>     7) GPIO
>     8) DRAM
>
>
Snip
>
> when adding this patch and enabling CLK_IMX8MQ I see the following on 
> my board .. Any idea what I missed here?
>
> --- >8 ---
> U-Boot SPL 2022.04-rc4-00008-g390d9bf9a1 (Mar 15 2022 - 16:26:59 +0100)
> Trying to boot from SD card
>
>
> U-Boot 2022.04-rc4-00008-g390d9bf9a1 (Mar 15 2022 - 16:26:59 +0100)
>
> CPU:   Freescale i.MX8MQ rev2.1 at 800 MHz
> Reset cause: POR
> Model: Kontron pITX-imx8m
> DRAM:  alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> 4 GiB

My guess is that there was static code that was setting up the DRAM pll 
that isn't get executed now that there's a DM clock driver.

I'd try enabling DEBUG in the clk-uclass and clk-composite drivers.

Also look at what DRAM initialization code is not being run now. Our 
board doesn't have an DRAM specific initialization so there could be a 
bug in the DRAM setup.

> clk_register: failed to get <NULL> device (parent of ckil)
> clk_register: failed to get <NULL> device (parent of sys1_pll)
> clk_register: failed to get <NULL> device (parent of sys2_pll)
> clk_register: failed to get <NULL> device (parent of sys3_pll)

These are warnings and shouldn't affect the functioning of the driver.


> No serial driver found

Are you using the DM serial driver ?

Again this is not something that is running on our board. But I can try 
enabling it.

Thanks

Angus

> resetting ...
>
> --- >8 ---
>
> -- 
> Heiko

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-15 15:46     ` Angus Ainslie
@ 2022-03-15 16:13       ` Angus Ainslie
  2022-03-16  7:14       ` Heiko Thiery
  1 sibling, 0 replies; 26+ messages in thread
From: Angus Ainslie @ 2022-03-15 16:13 UTC (permalink / raw)
  To: Heiko Thiery, Angus Ainslie
  Cc: u-boot, Marek Vasut, lukma, seanga2, sbabic, festevam, kernel,
	uboot-imx, peng.fan

On 2022-03-15 08:46, Angus Ainslie wrote:
>
> Hi Heiko,
>
> On 2022-03-15 08:35, Heiko Thiery wrote:
>> Hi Angus and all,
>>
>>
>>
>>
>> Am Di., 15. März 2022 um 14:09 Uhr schrieb Angus Ainslie 
>> <angus@akkea.ca>:
>>
>>     This is a DM clock driver based off the imx8mm u-boot driver and
>>     the linux
>>     kernel driver.
>>
>>     All of the PLLs and clocks are initialized so the subsystems
>>     below are
>>     functional and tested.
>>
>>     1) USB host and peripheral
>>     2) ECSPI
>>     3) UART
>>     4) I2C all busses
>>     5) USDHC for eMMC support
>>     6) USB storage
>>     7) GPIO
>>     8) DRAM
>>
>>
> Snip
>>
>> when adding this patch and enabling CLK_IMX8MQ I see the following on 
>> my board .. Any idea what I missed here?
>>
>> --- >8 ---
>> U-Boot SPL 2022.04-rc4-00008-g390d9bf9a1 (Mar 15 2022 - 16:26:59 +0100)
>> Trying to boot from SD card
>>
>>
>> U-Boot 2022.04-rc4-00008-g390d9bf9a1 (Mar 15 2022 - 16:26:59 +0100)
>>
>> CPU:   Freescale i.MX8MQ rev2.1 at 800 MHz
>> Reset cause: POR
>> Model: Kontron pITX-imx8m
>> DRAM:  alloc space exhausted
>> alloc space exhausted
>> alloc space exhausted
>> alloc space exhausted
>> alloc space exhausted
>> alloc space exhausted
>> alloc space exhausted
>> alloc space exhausted
>> alloc space exhausted
>> alloc space exhausted
>> alloc space exhausted
>> alloc space exhausted
>> 4 GiB
>
> My guess is that there was static code that was setting up the DRAM 
> pll that isn't get executed now that there's a DM clock driver.
>
> I'd try enabling DEBUG in the clk-uclass and clk-composite drivers.
>
> Also look at what DRAM initialization code is not being run now. Our 
> board doesn't have an DRAM specific initialization so there could be a 
> bug in the DRAM setup.
>
>> clk_register: failed to get <NULL> device (parent of ckil)
>> clk_register: failed to get <NULL> device (parent of sys1_pll)
>> clk_register: failed to get <NULL> device (parent of sys2_pll)
>> clk_register: failed to get <NULL> device (parent of sys3_pll)
>
> These are warnings and shouldn't affect the functioning of the driver.
>
>
>> No serial driver found
>
> Are you using the DM serial driver ?
>
> Again this is not something that is running on our board. But I can 
> try enabling it.
>
With DM_SERIAL enabled and SPL_DM_SERIAL disabled

U-Boot SPL 2022.04-rc3-00076-gb363332dc70-dirty (Mar 15 2022 - 09:09:24 
-0700) [0/1906]
Initializing pinmux
Initializing ECSPI
Initializing DRAM
USB Boot
Trying to boot from USB SDP
board_usb_init : index 0 type 1
SDP: initialize...
SDP: handle requests...
Downloading file of size 868420 to 0x40400000... done
Jumping to header at 0x40400000
Header Tag is not an IMX image
Found header at 0x40406e00
board_usb_cleanup : 0
Status: -108


U-Boot 2022.04-rc3-00076-gb363332dc70-dirty (Mar 15 2022 - 09:09:24 -0700)

CPU:   Freescale i.MX8MQ rev2.1 1500 MHz (running at 1000 MHz)
CPU:   Commercial temperature grade (0C to 95C) at 60C
Reset cause: POR
Model: Purism Librem 5r4
DRAM:  3 GiB
Enabling regulator-hub
clk_register: failed to get <NULL> device (parent of ckil)
clk_register: failed to get <NULL> device (parent of sys1_pll)
clk_register: failed to get <NULL> device (parent of sys2_pll)
clk_register: failed to get <NULL> device (parent of sys3_pll)
tps65982 boot successful
Core:  178 devices, 23 uclasses, devicetree: separate
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from MMC... *** Warning - bad CRC, using default 
environment

In:    serial
Out:   serial
Err:   serial

BuildInfo:
  - ATF 1fd3ff8

Board name: librem5
Board rev:  4
USB Boot
vol_down_key_pressed : 1
Net:   No ethernet found.
Hit any key to stop autoboot:  0


> Thanks
>
> Angus
>
>> resetting ...
>>
>> --- >8 ---
>>
>> -- 
>> Heiko

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-15 15:35   ` Heiko Thiery
  2022-03-15 15:46     ` Angus Ainslie
@ 2022-03-15 19:01     ` Marek Vasut
  2022-03-16  7:02       ` Heiko Thiery
  2022-03-21  1:32     ` Peng Fan (OSS)
  2 siblings, 1 reply; 26+ messages in thread
From: Marek Vasut @ 2022-03-15 19:01 UTC (permalink / raw)
  To: Heiko Thiery, Angus Ainslie
  Cc: u-boot, lukma, seanga2, sbabic, festevam, kernel, uboot-imx, peng.fan

On 3/15/22 16:35, Heiko Thiery wrote:
> Hi Angus and all,

Hi,

[...]

> U-Boot 2022.04-rc4-00008-g390d9bf9a1 (Mar 15 2022 - 16:26:59 +0100)
> 
> CPU:   Freescale i.MX8MQ rev2.1 at 800 MHz
> Reset cause: POR
> Model: Kontron pITX-imx8m
> DRAM:  alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted

Try increasing MALLOC_F_LEN in your .config , that should do the trick I 
think. There is now a lot of clock drivers that are being instantiated 
early, so your early malloc area is likely exhausted.

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-15 19:01     ` Marek Vasut
@ 2022-03-16  7:02       ` Heiko Thiery
  0 siblings, 0 replies; 26+ messages in thread
From: Heiko Thiery @ 2022-03-16  7:02 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Angus Ainslie, u-boot, lukma, seanga2, sbabic, festevam, kernel,
	uboot-imx, peng.fan

Hi Marek,



Am Di., 15. März 2022 um 20:01 Uhr schrieb Marek Vasut <marex@denx.de>:
>
> On 3/15/22 16:35, Heiko Thiery wrote:
> > Hi Angus and all,
>
> Hi,
>
> [...]
>
> > U-Boot 2022.04-rc4-00008-g390d9bf9a1 (Mar 15 2022 - 16:26:59 +0100)
> >
> > CPU:   Freescale i.MX8MQ rev2.1 at 800 MHz
> > Reset cause: POR
> > Model: Kontron pITX-imx8m
> > DRAM:  alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
>
> Try increasing MALLOC_F_LEN in your .config , that should do the trick I
> think. There is now a lot of clock drivers that are being instantiated
> early, so your early malloc area is likely exhausted.

You're right. Increasing the value from 0x2000 to 0x10000 fixes this problem.

Thanks
-- 
Heiko

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-15 15:46     ` Angus Ainslie
  2022-03-15 16:13       ` Angus Ainslie
@ 2022-03-16  7:14       ` Heiko Thiery
  2022-03-16 12:26         ` Heiko Thiery
  1 sibling, 1 reply; 26+ messages in thread
From: Heiko Thiery @ 2022-03-16  7:14 UTC (permalink / raw)
  To: Angus Ainslie
  Cc: Angus Ainslie, u-boot, Marek Vasut, lukma, seanga2, sbabic,
	festevam, kernel, uboot-imx, peng.fan

Hi Angus,

Am Di., 15. März 2022 um 16:46 Uhr schrieb Angus Ainslie
<angus.ainslie@puri.sm>:
>
> Hi Heiko,
>
> On 2022-03-15 08:35, Heiko Thiery wrote:
>
> Hi Angus and all,
>
>
>
>
> Am Di., 15. März 2022 um 14:09 Uhr schrieb Angus Ainslie <angus@akkea.ca>:
>>
>> This is a DM clock driver based off the imx8mm u-boot driver and the linux
>> kernel driver.
>>
>> All of the PLLs and clocks are initialized so the subsystems below are
>> functional and tested.
>>
>> 1) USB host and peripheral
>> 2) ECSPI
>> 3) UART
>> 4) I2C all busses
>> 5) USDHC for eMMC support
>> 6) USB storage
>> 7) GPIO
>> 8) DRAM
>>
>>
> Snip
>
>
> when adding this patch and enabling CLK_IMX8MQ I see the following on my board .. Any idea what I missed here?
>
> --- >8 ---
> U-Boot SPL 2022.04-rc4-00008-g390d9bf9a1 (Mar 15 2022 - 16:26:59 +0100)
> Trying to boot from SD card
>
>
> U-Boot 2022.04-rc4-00008-g390d9bf9a1 (Mar 15 2022 - 16:26:59 +0100)
>
> CPU:   Freescale i.MX8MQ rev2.1 at 800 MHz
> Reset cause: POR
> Model: Kontron pITX-imx8m
> DRAM:  alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> 4 GiB
>
> My guess is that there was static code that was setting up the DRAM pll that isn't get executed now that there's a DM clock driver.
>
> I'd try enabling DEBUG in the clk-uclass and clk-composite drivers.
>
> Also look at what DRAM initialization code is not being run now. Our board doesn't have an DRAM specific initialization so there could be a bug in the DRAM setup.

The problem was the MALLOC_F_LEN value. Increasing that the "alloc
space exhausted" is gone.

But with the enabled DM_SERIAL the problem of "No serial driver found"
is still there and the board reboots. You said you have DM_SERIAL
enabled and it works?

[snip]

-- 
Heiko

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-16  7:14       ` Heiko Thiery
@ 2022-03-16 12:26         ` Heiko Thiery
  2022-03-16 12:35           ` Angus Ainslie
  0 siblings, 1 reply; 26+ messages in thread
From: Heiko Thiery @ 2022-03-16 12:26 UTC (permalink / raw)
  To: Angus Ainslie
  Cc: Angus Ainslie, u-boot, Marek Vasut, lukma, seanga2, sbabic,
	festevam, kernel, uboot-imx, peng.fan

Hi,

Am Mi., 16. März 2022 um 08:14 Uhr schrieb Heiko Thiery
<heiko.thiery@gmail.com>:
>
> Hi Angus,
>
> Am Di., 15. März 2022 um 16:46 Uhr schrieb Angus Ainslie
> <angus.ainslie@puri.sm>:
> >
> > Hi Heiko,
> >
> > On 2022-03-15 08:35, Heiko Thiery wrote:
> >
> > Hi Angus and all,
> >
> >
> >
> >
> > Am Di., 15. März 2022 um 14:09 Uhr schrieb Angus Ainslie <angus@akkea.ca>:
> >>
> >> This is a DM clock driver based off the imx8mm u-boot driver and the linux
> >> kernel driver.
> >>
> >> All of the PLLs and clocks are initialized so the subsystems below are
> >> functional and tested.
> >>
> >> 1) USB host and peripheral
> >> 2) ECSPI
> >> 3) UART
> >> 4) I2C all busses
> >> 5) USDHC for eMMC support
> >> 6) USB storage
> >> 7) GPIO
> >> 8) DRAM
> >>
> >>
> > Snip
> >
> >
> > when adding this patch and enabling CLK_IMX8MQ I see the following on my board .. Any idea what I missed here?
> >
> > --- >8 ---
> > U-Boot SPL 2022.04-rc4-00008-g390d9bf9a1 (Mar 15 2022 - 16:26:59 +0100)
> > Trying to boot from SD card
> >
> >
> > U-Boot 2022.04-rc4-00008-g390d9bf9a1 (Mar 15 2022 - 16:26:59 +0100)
> >
> > CPU:   Freescale i.MX8MQ rev2.1 at 800 MHz
> > Reset cause: POR
> > Model: Kontron pITX-imx8m
> > DRAM:  alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > alloc space exhausted
> > 4 GiB
> >
> > My guess is that there was static code that was setting up the DRAM pll that isn't get executed now that there's a DM clock driver.
> >
> > I'd try enabling DEBUG in the clk-uclass and clk-composite drivers.
> >
> > Also look at what DRAM initialization code is not being run now. Our board doesn't have an DRAM specific initialization so there could be a bug in the DRAM setup.
>
> The problem was the MALLOC_F_LEN value. Increasing that the "alloc
> space exhausted" is gone.
>
> But with the enabled DM_SERIAL the problem of "No serial driver found"
> is still there and the board reboots. You said you have DM_SERIAL
> enabled and it works?

Meanwhile I figured out what the problem is with the 'No serial driver
found'. In the used dtb there are 'assigned-clocks' and
'assigned-clock-parents' set in the uart nodes. When removing this the
serial will work. I have to admit that I do not know why this is set
that way. I can only imagine that this was taken from the uboot-imx
tree.

---
assigned-clocks = <&clk IMX8MQ_CLK_UART1>;
assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_80M>;
---

see also here: https://source.denx.de/u-boot/u-boot/-/blob/master/arch/arm/dts/imx8mq-kontron-pitx-imx8m.dts#L315

-- 
Heiko

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-16 12:26         ` Heiko Thiery
@ 2022-03-16 12:35           ` Angus Ainslie
  2022-03-16 14:02             ` Heiko Thiery
  0 siblings, 1 reply; 26+ messages in thread
From: Angus Ainslie @ 2022-03-16 12:35 UTC (permalink / raw)
  To: Heiko Thiery
  Cc: Angus Ainslie, u-boot, Marek Vasut, lukma, seanga2, sbabic,
	festevam, kernel, uboot-imx, peng.fan

On 2022-03-16 05:26, Heiko Thiery wrote:
> Hi,
> 
> Am Mi., 16. März 2022 um 08:14 Uhr schrieb Heiko Thiery
> <heiko.thiery@gmail.com>:
>> 
>> Hi Angus,
>> 
>> Am Di., 15. März 2022 um 16:46 Uhr schrieb Angus Ainslie
>> <angus.ainslie@puri.sm>:
>> >
>> > Hi Heiko,
>> >
>> > On 2022-03-15 08:35, Heiko Thiery wrote:
>> >
>> > Hi Angus and all,
>> >
>> >
>> >
>> >
>> > Am Di., 15. März 2022 um 14:09 Uhr schrieb Angus Ainslie <angus@akkea.ca>:
>> >>
>> >> This is a DM clock driver based off the imx8mm u-boot driver and the linux
>> >> kernel driver.
>> >>
>> >> All of the PLLs and clocks are initialized so the subsystems below are
>> >> functional and tested.
>> >>
>> >> 1) USB host and peripheral
>> >> 2) ECSPI
>> >> 3) UART
>> >> 4) I2C all busses
>> >> 5) USDHC for eMMC support
>> >> 6) USB storage
>> >> 7) GPIO
>> >> 8) DRAM
>> >>
>> >>
>> > Snip
>> >
>> >
>> > when adding this patch and enabling CLK_IMX8MQ I see the following on my board .. Any idea what I missed here?
>> >
>> > --- >8 ---
>> > U-Boot SPL 2022.04-rc4-00008-g390d9bf9a1 (Mar 15 2022 - 16:26:59 +0100)
>> > Trying to boot from SD card
>> >
>> >
>> > U-Boot 2022.04-rc4-00008-g390d9bf9a1 (Mar 15 2022 - 16:26:59 +0100)
>> >
>> > CPU:   Freescale i.MX8MQ rev2.1 at 800 MHz
>> > Reset cause: POR
>> > Model: Kontron pITX-imx8m
>> > DRAM:  alloc space exhausted
>> > alloc space exhausted
>> > alloc space exhausted
>> > alloc space exhausted
>> > alloc space exhausted
>> > alloc space exhausted
>> > alloc space exhausted
>> > alloc space exhausted
>> > alloc space exhausted
>> > alloc space exhausted
>> > alloc space exhausted
>> > alloc space exhausted
>> > 4 GiB
>> >
>> > My guess is that there was static code that was setting up the DRAM pll that isn't get executed now that there's a DM clock driver.
>> >
>> > I'd try enabling DEBUG in the clk-uclass and clk-composite drivers.
>> >
>> > Also look at what DRAM initialization code is not being run now. Our board doesn't have an DRAM specific initialization so there could be a bug in the DRAM setup.
>> 
>> The problem was the MALLOC_F_LEN value. Increasing that the "alloc
>> space exhausted" is gone.
>> 
>> But with the enabled DM_SERIAL the problem of "No serial driver found"
>> is still there and the board reboots. You said you have DM_SERIAL
>> enabled and it works?
> 
> Meanwhile I figured out what the problem is with the 'No serial driver
> found'. In the used dtb there are 'assigned-clocks' and
> 'assigned-clock-parents' set in the uart nodes. When removing this the
> serial will work. I have to admit that I do not know why this is set
> that way. I can only imagine that this was taken from the uboot-imx
> tree.
> 
> ---
> assigned-clocks = <&clk IMX8MQ_CLK_UART1>;
> assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_80M>;
> ---
> 

Does that solve the reboot ?

> see also here:
> https://source.denx.de/u-boot/u-boot/-/blob/master/arch/arm/dts/imx8mq-kontron-pitx-imx8m.dts#L315

If that works for Linux it should also work for u-boot. It may be that 
the SYS1_PLL_80M isn't set correctly or that the CLK_UART1 mux isn't 
correctly setup. If you enable DEBUG in clk-uclass I might be able to 
figure out were the problem is.


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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-16 12:35           ` Angus Ainslie
@ 2022-03-16 14:02             ` Heiko Thiery
  2022-03-16 14:15               ` Angus Ainslie
  0 siblings, 1 reply; 26+ messages in thread
From: Heiko Thiery @ 2022-03-16 14:02 UTC (permalink / raw)
  To: Angus Ainslie
  Cc: Angus Ainslie, u-boot, Marek Vasut, lukma, seanga2, sbabic,
	festevam, kernel, uboot-imx, peng.fan

Hi Angus,

[snip]

> >
> > Meanwhile I figured out what the problem is with the 'No serial driver
> > found'. In the used dtb there are 'assigned-clocks' and
> > 'assigned-clock-parents' set in the uart nodes. When removing this the
> > serial will work. I have to admit that I do not know why this is set
> > that way. I can only imagine that this was taken from the uboot-imx
> > tree.
> >
> > ---
> > assigned-clocks = <&clk IMX8MQ_CLK_UART1>;
> > assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_80M>;
> > ---
> >
>
> Does that solve the reboot ?

Yes, when I remove these assigned-clocks from my dtb the issue is
solved and the board finds the serial driver and starts correctly.

>
> > see also here:
> > https://source.denx.de/u-boot/u-boot/-/blob/master/arch/arm/dts/imx8mq-kontron-pitx-imx8m.dts#L315
>
> If that works for Linux it should also work for u-boot. It may be that
> the SYS1_PLL_80M isn't set correctly or that the CLK_UART1 mux isn't
> correctly setup. If you enable DEBUG in clk-uclass I might be able to
> figure out were the problem is.

The problem is that the IMX8MQ_CLK_UART1 is not found and that is the
reason that the probe fails. I tried to add the missing clocks to how
it is done in the kernel.

see here: https://pastebin.com/raw/iYYMHEdy

But then something went wrong when probing uart3 ... the baudrate
switched for the uart2 (console) and the serial output became broken.
Later when the kernel starts the output becomes correct again. So the
kernel seems to configure it correctly.

see here: https://pastebin.com/raw/qXVShb3Q

When I remove the "assigned-clock-parents = <&clk
IMX8MQ_SYS1_PLL_80M>;" for uart3 the output of uart2 (console) keeps
ok.

-- 
Heiko

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-16 14:02             ` Heiko Thiery
@ 2022-03-16 14:15               ` Angus Ainslie
  2022-03-16 14:21                 ` Heiko Thiery
  0 siblings, 1 reply; 26+ messages in thread
From: Angus Ainslie @ 2022-03-16 14:15 UTC (permalink / raw)
  To: Heiko Thiery
  Cc: Angus Ainslie, u-boot, Marek Vasut, lukma, seanga2, sbabic,
	festevam, kernel, uboot-imx, peng.fan

On 2022-03-16 07:02, Heiko Thiery wrote:
> Hi Angus,
> 
> [snip]
> 
>> >
>> > Meanwhile I figured out what the problem is with the 'No serial driver
>> > found'. In the used dtb there are 'assigned-clocks' and
>> > 'assigned-clock-parents' set in the uart nodes. When removing this the
>> > serial will work. I have to admit that I do not know why this is set
>> > that way. I can only imagine that this was taken from the uboot-imx
>> > tree.
>> >
>> > ---
>> > assigned-clocks = <&clk IMX8MQ_CLK_UART1>;
>> > assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_80M>;
>> > ---
>> >
>> 
>> Does that solve the reboot ?
> 
> Yes, when I remove these assigned-clocks from my dtb the issue is
> solved and the board finds the serial driver and starts correctly.
> 
>> 
>> > see also here:
>> > https://source.denx.de/u-boot/u-boot/-/blob/master/arch/arm/dts/imx8mq-kontron-pitx-imx8m.dts#L315
>> 
>> If that works for Linux it should also work for u-boot. It may be that
>> the SYS1_PLL_80M isn't set correctly or that the CLK_UART1 mux isn't
>> correctly setup. If you enable DEBUG in clk-uclass I might be able to
>> figure out were the problem is.
> 
> The problem is that the IMX8MQ_CLK_UART1 is not found and that is the
> reason that the probe fails. I tried to add the missing clocks to how
> it is done in the kernel.
> 
> see here: https://pastebin.com/raw/iYYMHEdy

Looking at that you shouldn't need

+       clk_dm(IMX8MQ_CLK_25M, clk_register_fixed_rate(NULL, 
"clock-osc-25m", 25000000));
+       clk_dm(IMX8MQ_CLK_25M, clk_register_fixed_rate(NULL, 
"clock-osc-27m", 27000000));

Those get correctly probed by the clock-controller.

The rest of it looks OK and could be a follow on patch to the clock 
driver,

> 
> But then something went wrong when probing uart3 ... the baudrate
> switched for the uart2 (console) and the serial output became broken.
> Later when the kernel starts the output becomes correct again. So the
> kernel seems to configure it correctly.
> 
> see here: https://pastebin.com/raw/qXVShb3Q
> 
> When I remove the "assigned-clock-parents = <&clk
> IMX8MQ_SYS1_PLL_80M>;" for uart3 the output of uart2 (console) keeps
> ok.

If that "fixes" it then it means that the parent IMX8MQ_SYS1_PLL_80M 
clock rate is getting changed by the uart3 stanza.

Are you using the mainline devicetree file for your board ? If not could 
you provide a link ?



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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-16 14:15               ` Angus Ainslie
@ 2022-03-16 14:21                 ` Heiko Thiery
  2022-03-16 15:55                   ` Heiko Thiery
  0 siblings, 1 reply; 26+ messages in thread
From: Heiko Thiery @ 2022-03-16 14:21 UTC (permalink / raw)
  To: Angus Ainslie
  Cc: Angus Ainslie, u-boot, Marek Vasut, lukma, seanga2, sbabic,
	festevam, kernel, uboot-imx, peng.fan

Am Mi., 16. März 2022 um 15:15 Uhr schrieb Angus Ainslie <angus@akkea.ca>:
>
> On 2022-03-16 07:02, Heiko Thiery wrote:
> > Hi Angus,
> >
> > [snip]
> >
> >> >
> >> > Meanwhile I figured out what the problem is with the 'No serial driver
> >> > found'. In the used dtb there are 'assigned-clocks' and
> >> > 'assigned-clock-parents' set in the uart nodes. When removing this the
> >> > serial will work. I have to admit that I do not know why this is set
> >> > that way. I can only imagine that this was taken from the uboot-imx
> >> > tree.
> >> >
> >> > ---
> >> > assigned-clocks = <&clk IMX8MQ_CLK_UART1>;
> >> > assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_80M>;
> >> > ---
> >> >
> >>
> >> Does that solve the reboot ?
> >
> > Yes, when I remove these assigned-clocks from my dtb the issue is
> > solved and the board finds the serial driver and starts correctly.
> >
> >>
> >> > see also here:
> >> > https://source.denx.de/u-boot/u-boot/-/blob/master/arch/arm/dts/imx8mq-kontron-pitx-imx8m.dts#L315
> >>
> >> If that works for Linux it should also work for u-boot. It may be that
> >> the SYS1_PLL_80M isn't set correctly or that the CLK_UART1 mux isn't
> >> correctly setup. If you enable DEBUG in clk-uclass I might be able to
> >> figure out were the problem is.
> >
> > The problem is that the IMX8MQ_CLK_UART1 is not found and that is the
> > reason that the probe fails. I tried to add the missing clocks to how
> > it is done in the kernel.
> >
> > see here: https://pastebin.com/raw/iYYMHEdy
>
> Looking at that you shouldn't need
>
> +       clk_dm(IMX8MQ_CLK_25M, clk_register_fixed_rate(NULL,
> "clock-osc-25m", 25000000));
> +       clk_dm(IMX8MQ_CLK_25M, clk_register_fixed_rate(NULL,
> "clock-osc-27m", 27000000));
>
> Those get correctly probed by the clock-controller.
>
> The rest of it looks OK and could be a follow on patch to the clock
> driver,
>
> >
> > But then something went wrong when probing uart3 ... the baudrate
> > switched for the uart2 (console) and the serial output became broken.
> > Later when the kernel starts the output becomes correct again. So the
> > kernel seems to configure it correctly.
> >
> > see here: https://pastebin.com/raw/qXVShb3Q
> >
> > When I remove the "assigned-clock-parents = <&clk
> > IMX8MQ_SYS1_PLL_80M>;" for uart3 the output of uart2 (console) keeps
> > ok.
>
> If that "fixes" it then it means that the parent IMX8MQ_SYS1_PLL_80M
> clock rate is getting changed by the uart3 stanza.
>
> Are you using the mainline devicetree file for your board ? If not could
> you provide a link ?

I use the mainline u-boot/linux one.

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-16 14:21                 ` Heiko Thiery
@ 2022-03-16 15:55                   ` Heiko Thiery
  2022-03-16 16:00                     ` Angus Ainslie
  2022-03-21  1:38                     ` Peng Fan (OSS)
  0 siblings, 2 replies; 26+ messages in thread
From: Heiko Thiery @ 2022-03-16 15:55 UTC (permalink / raw)
  To: Angus Ainslie
  Cc: Angus Ainslie, u-boot, Marek Vasut, lukma, seanga2, sbabic,
	festevam, kernel, uboot-imx, peng.fan, Michael Walle

Hi Angus,

[snip]
> > > But then something went wrong when probing uart3 ... the baudrate
> > > switched for the uart2 (console) and the serial output became broken.
> > > Later when the kernel starts the output becomes correct again. So the
> > > kernel seems to configure it correctly.
> > >
> > > see here: https://pastebin.com/raw/qXVShb3Q
> > >
> > > When I remove the "assigned-clock-parents = <&clk
> > > IMX8MQ_SYS1_PLL_80M>;" for uart3 the output of uart2 (console) keeps
> > > ok.
> >
> > If that "fixes" it then it means that the parent IMX8MQ_SYS1_PLL_80M
> > clock rate is getting changed by the uart3 stanza.
> >
> > Are you using the mainline devicetree file for your board ? If not could
> > you provide a link ?
>
> I use the mainline u-boot/linux one.

We (thanks to Michael) found the issue. For the imx8mq the
imx_get_uartclk() returns always the values for UART1_CLK_ROOT [1].
This is wrong. Here we have to get the value dependent on the used
UART.

[1] https://source.denx.de/u-boot/u-boot/-/blob/master/arch/arm/mach-imx/imx8m/clock_imx8mq.c#L381

-- 
Heiko

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-16 15:55                   ` Heiko Thiery
@ 2022-03-16 16:00                     ` Angus Ainslie
  2022-03-16 16:20                       ` Michael Walle
  2022-03-21  1:38                     ` Peng Fan (OSS)
  1 sibling, 1 reply; 26+ messages in thread
From: Angus Ainslie @ 2022-03-16 16:00 UTC (permalink / raw)
  To: Heiko Thiery
  Cc: Angus Ainslie, u-boot, Marek Vasut, lukma, seanga2, sbabic,
	festevam, kernel, uboot-imx, peng.fan, Michael Walle

Hi Heiko,

On 2022-03-16 08:55, Heiko Thiery wrote:
> Hi Angus,
> 
> [snip]
>> > > But then something went wrong when probing uart3 ... the baudrate
>> > > switched for the uart2 (console) and the serial output became broken.
>> > > Later when the kernel starts the output becomes correct again. So the
>> > > kernel seems to configure it correctly.
>> > >
>> > > see here: https://pastebin.com/raw/qXVShb3Q
>> > >
>> > > When I remove the "assigned-clock-parents = <&clk
>> > > IMX8MQ_SYS1_PLL_80M>;" for uart3 the output of uart2 (console) keeps
>> > > ok.
>> >
>> > If that "fixes" it then it means that the parent IMX8MQ_SYS1_PLL_80M
>> > clock rate is getting changed by the uart3 stanza.
>> >
>> > Are you using the mainline devicetree file for your board ? If not could
>> > you provide a link ?
>> 
>> I use the mainline u-boot/linux one.
> 
> We (thanks to Michael) found the issue. For the imx8mq the
> imx_get_uartclk() returns always the values for UART1_CLK_ROOT [1].
> This is wrong. Here we have to get the value dependent on the used
> UART.
> 
> [1]
> https://source.denx.de/u-boot/u-boot/-/blob/master/arch/arm/mach-imx/imx8m/clock_imx8mq.c#L381

Yeah that driver could do with an overhaul as it also does that for the 
ECSPI clocks which can also break things.

Angus

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-16 16:00                     ` Angus Ainslie
@ 2022-03-16 16:20                       ` Michael Walle
  0 siblings, 0 replies; 26+ messages in thread
From: Michael Walle @ 2022-03-16 16:20 UTC (permalink / raw)
  To: Angus Ainslie
  Cc: Heiko Thiery, Angus Ainslie, u-boot, Marek Vasut, lukma, seanga2,
	sbabic, festevam, kernel, uboot-imx, peng.fan

Am 2022-03-16 17:00, schrieb Angus Ainslie:
> Hi Heiko,
> 
> On 2022-03-16 08:55, Heiko Thiery wrote:
>> Hi Angus,
>> 
>> [snip]
>>> > > But then something went wrong when probing uart3 ... the baudrate
>>> > > switched for the uart2 (console) and the serial output became broken.
>>> > > Later when the kernel starts the output becomes correct again. So the
>>> > > kernel seems to configure it correctly.
>>> > >
>>> > > see here: https://pastebin.com/raw/qXVShb3Q
>>> > >
>>> > > When I remove the "assigned-clock-parents = <&clk
>>> > > IMX8MQ_SYS1_PLL_80M>;" for uart3 the output of uart2 (console) keeps
>>> > > ok.
>>> >
>>> > If that "fixes" it then it means that the parent IMX8MQ_SYS1_PLL_80M
>>> > clock rate is getting changed by the uart3 stanza.
>>> >
>>> > Are you using the mainline devicetree file for your board ? If not could
>>> > you provide a link ?
>>> 
>>> I use the mainline u-boot/linux one.
>> 
>> We (thanks to Michael) found the issue. For the imx8mq the
>> imx_get_uartclk() returns always the values for UART1_CLK_ROOT [1].
>> This is wrong. Here we have to get the value dependent on the used
>> UART.
>> 
>> [1]
>> https://source.denx.de/u-boot/u-boot/-/blob/master/arch/arm/mach-imx/imx8m/clock_imx8mq.c#L381
> 
> Yeah that driver could do with an overhaul as it also does that for
> the ECSPI clocks which can also break things.

IMHO the imx serial driver should get its clock from the device
tree. Not sure about the debug serial part though.

-michael

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-15 13:08 ` [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq Angus Ainslie
  2022-03-15 15:12   ` Heiko Thiery
  2022-03-15 15:35   ` Heiko Thiery
@ 2022-03-20 23:57   ` Sean Anderson
  2022-03-24  8:28   ` Heiko Thiery
  3 siblings, 0 replies; 26+ messages in thread
From: Sean Anderson @ 2022-03-20 23:57 UTC (permalink / raw)
  To: Angus Ainslie, u-boot, Marek Vasut
  Cc: lukma, sbabic, festevam, kernel, uboot-imx, peng.fan

On 3/15/22 9:08 AM, Angus Ainslie wrote:
> This is a DM clock driver based off the imx8mm u-boot driver and the linux
> kernel driver.
> 
> All of the PLLs and clocks are initialized so the subsystems below are
> functional and tested.
> 
> 1) USB host and peripheral
> 2) ECSPI
> 3) UART
> 4) I2C all busses
> 5) USDHC for eMMC support
> 6) USB storage
> 7) GPIO
> 8) DRAM
> 
> Signed-off-by: Angus Ainslie <angus@akkea.ca>
> ---
>   drivers/clk/imx/Kconfig      |  16 +
>   drivers/clk/imx/Makefile     |   2 +
>   drivers/clk/imx/clk-imx8mq.c | 575 +++++++++++++++++++++++++++++++++++
>   3 files changed, 593 insertions(+)
>   create mode 100644 drivers/clk/imx/clk-imx8mq.c
> 
> diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
> index cdd348020b0..06d8c1a5dd3 100644
> --- a/drivers/clk/imx/Kconfig
> +++ b/drivers/clk/imx/Kconfig
> @@ -71,6 +71,22 @@ config CLK_IMX8MP
>   	help
>   	  This enables support clock driver for i.MX8MP platforms.
>   
> +config SPL_CLK_IMX8MQ
> +	bool "SPL clock support for i.MX8MQ"
> +	depends on ARCH_IMX8M && SPL
> +	select SPL_CLK
> +	select SPL_CLK_CCF
> +	help
> +	  This enables SPL DM/DTS support for clock driver in i.MX8MQ
> +
> +config CLK_IMX8MQ
> +	bool "Clock support for i.MX8MQ"
> +	depends on ARCH_IMX8M
> +	select CLK
> +	select CLK_CCF
> +	help
> +	  This enables support clock driver for i.MX8MQ platforms.
> +
>   config SPL_CLK_IMXRT1020
>   	bool "SPL clock support for i.MXRT1020"
>   	depends on ARCH_IMXRT && SPL
> diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
> index 01bbbdf3aea..c5766901f2b 100644
> --- a/drivers/clk/imx/Makefile
> +++ b/drivers/clk/imx/Makefile
> @@ -16,6 +16,8 @@ obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MN) += clk-imx8mn.o clk-pll14xx.o \
>   				clk-composite-8m.o
>   obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MP) += clk-imx8mp.o clk-pll14xx.o \
>   				clk-composite-8m.o
> +obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MQ) += clk-imx8mq.o clk-pll14xx.o \
> +				clk-composite-8m.o
>   
>   obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1020) += clk-imxrt1020.o
>   obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1050) += clk-imxrt1050.o
> diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
> new file mode 100644
> index 00000000000..0aea417a29b
> --- /dev/null
> +++ b/drivers/clk/imx/clk-imx8mq.c
> @@ -0,0 +1,575 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2019 NXP
> + * Copyright 2022 Purism
> + * Peng Fan <peng.fan@nxp.com>
> + */
> +
> +#include <common.h>
> +#include <clk.h>
> +#include <clk-uclass.h>
> +#include <dm.h>
> +#include <log.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/imx-regs.h>
> +#include <dt-bindings/clock/imx8mq-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 imx8mq_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),
> +};
> +
> +const struct imx_pll14xx_rate_table imx8mq_pll1443x_tbl[] = {
> +	PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
> +	PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
> +	PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
> +	PLL_1443X_RATE(361267200U, 361, 3, 3, 17511),
> +};
> +
> +static struct imx_pll14xx_clk imx8mq_1416x_pll __initdata = {
> +		.type = PLL_1416X,
> +		.rate_table = imx8mq_pll1416x_tbl,
> +		.rate_count = ARRAY_SIZE(imx8mq_pll1416x_tbl),
> +};
> +
> +static struct imx_pll14xx_clk imx8mq_1443x_pll __initdata = {
> +		.type = PLL_1443X,
> +		.rate_table = imx8mq_pll1443x_tbl,
> +		.rate_count = ARRAY_SIZE(imx8mq_pll1443x_tbl),
> +};
> +
> +static const char *pll_ref_sels[] = { "clock-osc-25m", "clock-osc-27m", "clock-phy-27m", "dummy", };

static const char *const?

> +static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_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 *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 *imx8mq_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", };
> +static const char *imx8mq_a53_sels[] = {"clock-osc-25m", "arm_pll_out", "sys_pll2_500m",
> +					"sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m",
> +					"audio_pll1_out", "sys_pll3_out", };
> +
> +static const char *imx8mq_ahb_sels[] = {"clock-osc-25m", "sys_pll1_133m", "sys_pll1_800m",
> +					"sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out",
> +					"audio_pll1_out", "video_pll1_out", };
> +
> +static const char *imx8mq_enet_axi_sels[] = {"clock-osc-25m", "sys_pll1_266m", "sys_pll1_800m",
> +					     "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out",
> +					     "video_pll1_out", "sys_pll3_out", };
> +
> +static const char *imx8mq_enet_ref_sels[] = {"clock-osc-25m", "sys_pll2_125m", "sys_pll2_50m",
> +					     "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
> +					     "video_pll1_out", "clk_ext4", };
> +
> +static const char *imx8mq_enet_timer_sels[] = {"clock-osc-25m", "sys_pll2_100m", "audio_pll1_out",
> +					       "clk_ext1", "clk_ext2", "clk_ext3", "clk_ext4",
> +					       "video_pll1_out", };
> +
> +static const char *imx8mq_enet_phy_sels[] = {"clock-osc-25m", "sys_pll2_50m", "sys_pll2_125m",
> +					     "sys_pll2_200m", "sys_pll2_500m", "video_pll1_out",
> +					     "audio_pll2_out", };
> +
> +static const char *imx8mq_nand_usdhc_sels[] = {"clock-osc-25m", "sys_pll1_266m", "sys_pll1_800m",
> +					       "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out",
> +					       "sys_pll2_250m", "audio_pll1_out", };
> +
> +static const char *imx8mq_usb_bus_sels[] = {"clock-osc-25m", "sys_pll2_500m", "sys_pll1_800m",
> +					    "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
> +					    "clk_ext4", "audio_pll2_out", };
> +
> +static const char *imx8mq_usdhc1_sels[] = {"clock-osc-25m", "sys_pll1_400m", "sys_pll1_800m",
> +					   "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
> +					   "audio_pll2_out", "sys_pll1_100m", };
> +
> +static const char *imx8mq_usdhc2_sels[] = {"clock-osc-25m", "sys_pll1_400m", "sys_pll1_800m",
> +					   "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
> +					   "audio_pll2_out", "sys_pll1_100m", };
> +
> +static const char *imx8mq_i2c1_sels[] = {"clock-osc-25m", "sys_pll1_160m", "sys_pll2_50m",
> +					 "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
> +					 "audio_pll2_out", "sys_pll1_133m", };
> +
> +static const char *imx8mq_i2c2_sels[] = {"clock-osc-25m", "sys_pll1_160m", "sys_pll2_50m",
> +					 "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
> +					 "audio_pll2_out", "sys_pll1_133m", };
> +
> +static const char *imx8mq_i2c3_sels[] = {"clock-osc-25m", "sys_pll1_160m", "sys_pll2_50m",
> +					 "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
> +					 "audio_pll2_out", "sys_pll1_133m", };
> +
> +static const char *imx8mq_i2c4_sels[] = {"clock-osc-25m", "sys_pll1_160m", "sys_pll2_50m",
> +					 "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
> +					 "audio_pll2_out", "sys_pll1_133m", };
> +
> +static const char *imx8mq_wdog_sels[] = {"clock-osc-25m", "sys_pll1_133m", "sys_pll1_160m",
> +					 "vpu_pll_out", "sys_pll2_125m", "sys_pll3_out",
> +					 "sys_pll1_80m", "sys_pll2_166m", };
> +
> +static const char *imx8mq_qspi_sels[] = {"clock-osc-25m", "sys_pll1_400m", "sys_pll2_333m",
> +					 "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m",
> +					 "sys_pll3_out", "sys_pll1_100m", };
> +
> +static const char *imx8mq_usb_core_sels[] = {"clock-osc-25m", "sys_pll1_100m", "sys_pll1_40m",
> +					     "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
> +					     "clk_ext3", "audio_pll2_out", };
> +
> +static const char *imx8mq_usb_phy_sels[] = {"clock-osc-25m", "sys_pll1_100m", "sys_pll1_40m",
> +					    "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
> +					    "clk_ext3", "audio_pll2_out", };
> +
> +static const char *imx8mq_ecspi1_sels[] = {"clock-osc-25m", "sys_pll2_200m", "sys_pll1_40m",
> +					   "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
> +					   "sys_pll2_250m", "audio_pll2_out", };
> +
> +static const char *imx8mq_ecspi2_sels[] = {"clock-osc-25m", "sys_pll2_200m", "sys_pll1_40m",
> +					   "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
> +					   "sys_pll2_250m", "audio_pll2_out", };
> +
> +static const char *imx8mq_ecspi3_sels[] = {"clock-osc-25m", "sys_pll2_200m", "sys_pll1_40m",
> +					   "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
> +					   "sys_pll2_250m", "audio_pll2_out", };
> +
> +static const char *pllout_monitor_sels[] = {"clock-osc-25m", "clock-osc-27m", "clock-phy-27m",
> +					    "dummy", "clock-ckil", "audio_pll1_out_monitor",
> +					    "audio_pll2_out_monitor", "gpu_pll_out_monitor",
> +					    "vpu_pll_out_monitor", "video_pll1_out_monitor",
> +					    "arm_pll_out_monitor", "sys_pll1_out_monitor",
> +					    "sys_pll2_out_monitor", "sys_pll3_out_monitor",
> +					    "dummy", "dram_pll_out_monitor", };
> +
> +static ulong imx8mq_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 imx8mq_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 __imx8mq_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) {
> +		debug("%s: clk_get_by_id failed\n", __func__);
> +		return ret;
> +	}
> +
> +	if (enable)
> +		ret = clk_enable(c);
> +	else
> +		ret = clk_disable(c);
> +
> +	return ret;
> +}
> +
> +static int imx8mq_clk_disable(struct clk *clk)
> +{
> +	return __imx8mq_clk_enable(clk, 0);
> +}
> +
> +static int imx8mq_clk_enable(struct clk *clk)
> +{
> +	return __imx8mq_clk_enable(clk, 1);
> +}
> +
> +static int imx8mq_clk_set_parent(struct clk *clk, struct clk *parent)
> +{
> +	struct clk *c, *cp;
> +	int ret;
> +
> +	debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
> +
> +	ret = clk_get_by_id(clk->id, &c);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_get_by_id(parent->id, &cp);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_set_parent(c, cp);
> +	c->dev->parent = cp->dev;
> +
> +	return ret;
> +}
> +
> +static struct clk_ops imx8mq_clk_ops = {
> +	.set_rate = imx8mq_clk_set_rate,
> +	.get_rate = imx8mq_clk_get_rate,
> +	.enable = imx8mq_clk_enable,
> +	.disable = imx8mq_clk_disable,
> +	.set_parent = imx8mq_clk_set_parent,
> +};
> +
> +static int imx8mq_clk_probe(struct udevice *dev)
> +{
> +	void __iomem *base;
> +
> +	base = (void *)ANATOP_BASE_ADDR;
> +
> +	clk_dm(IMX8MQ_CLK_32K, clk_register_fixed_rate(NULL, "ckil", 32768));
> +
> +	clk_dm(IMX8MQ_DRAM_PLL1_REF_SEL,
> +	       imx_clk_mux("dram_pll_ref_sel", base + 0x60, 0, 2,
> +			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
> +	clk_dm(IMX8MQ_ARM_PLL_REF_SEL,
> +	       imx_clk_mux("arm_pll_ref_sel", base + 0x28, 0, 2,
> +			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
> +	clk_dm(IMX8MQ_GPU_PLL_REF_SEL,
> +	       imx_clk_mux("gpu_pll_ref_sel", base + 0x18, 0, 2,
> +			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
> +	clk_dm(IMX8MQ_VPU_PLL_REF_SEL,
> +	       imx_clk_mux("vpu_pll_ref_sel", base + 0x20, 0, 2,
> +			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
> +	clk_dm(IMX8MQ_SYS3_PLL1_REF_SEL,
> +	       imx_clk_mux("sys3_pll_ref_sel", base + 0x48, 0, 2,
> +			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
> +	clk_dm(IMX8MQ_AUDIO_PLL1_REF_SEL,
> +	       imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2,
> +			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
> +	clk_dm(IMX8MQ_AUDIO_PLL2_REF_SEL,
> +	       imx_clk_mux("audio_pll2_ref_sel", base + 0x8, 0, 2,
> +			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
> +	clk_dm(IMX8MQ_VIDEO_PLL1_REF_SEL,
> +	       imx_clk_mux("video_pll1_ref_sel", base + 0x10, 0, 2,
> +			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
> +
> +	clk_dm(IMX8MQ_ARM_PLL,
> +	       imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel",
> +			       base + 0x28, &imx8mq_1416x_pll));
> +	clk_dm(IMX8MQ_GPU_PLL,
> +	       imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel",
> +			       base + 0x18, &imx8mq_1416x_pll));
> +	clk_dm(IMX8MQ_VPU_PLL,
> +	       imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel",
> +			       base + 0x20, &imx8mq_1416x_pll));
> +
> +	clk_dm(IMX8MQ_SYS1_PLL1,
> +	       clk_register_fixed_rate(NULL, "sys1_pll", 800000000));
> +	clk_dm(IMX8MQ_SYS2_PLL1,
> +	       clk_register_fixed_rate(NULL, "sys2_pll", 1000000000));
> +	clk_dm(IMX8MQ_SYS2_PLL1,
> +	       clk_register_fixed_rate(NULL, "sys3_pll", 1000000000));
> +	clk_dm(IMX8MQ_AUDIO_PLL1,
> +	       imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel",
> +			       base + 0x0, &imx8mq_1443x_pll));
> +	clk_dm(IMX8MQ_AUDIO_PLL2,
> +	       imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel",
> +			       base + 0x8, &imx8mq_1443x_pll));
> +	clk_dm(IMX8MQ_VIDEO_PLL1,
> +	       imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel",
> +			       base + 0x10, &imx8mq_1443x_pll));
> +
> +	/* PLL bypass out */
> +	clk_dm(IMX8MQ_ARM_PLL_BYPASS,
> +	       imx_clk_mux_flags("arm_pll_bypass", base + 0x28, 4, 1,
> +				 arm_pll_bypass_sels,
> +				 ARRAY_SIZE(arm_pll_bypass_sels),
> +				 CLK_SET_RATE_PARENT));
> +	clk_dm(IMX8MQ_GPU_PLL_BYPASS,
> +	       imx_clk_mux_flags("gpu_pll_bypass", base + 0x18, 4, 1,
> +				 gpu_pll_bypass_sels,
> +				 ARRAY_SIZE(gpu_pll_bypass_sels),
> +				 CLK_SET_RATE_PARENT));
> +	clk_dm(IMX8MQ_VPU_PLL_BYPASS,
> +	       imx_clk_mux_flags("vpu_pll_bypass", base + 0x20, 4, 1,
> +				 vpu_pll_bypass_sels,
> +				 ARRAY_SIZE(vpu_pll_bypass_sels),
> +				 CLK_SET_RATE_PARENT));
> +	clk_dm(IMX8MQ_AUDIO_PLL1_BYPASS,
> +	       imx_clk_mux_flags("audio_pll1_bypass", base + 0x0, 4, 1,
> +				 audio_pll1_bypass_sels,
> +				 ARRAY_SIZE(audio_pll1_bypass_sels),
> +				 CLK_SET_RATE_PARENT));
> +	clk_dm(IMX8MQ_AUDIO_PLL2_BYPASS,
> +	       imx_clk_mux_flags("audio_pll2_bypass", base + 0x8, 4, 1,
> +				 audio_pll2_bypass_sels,
> +				 ARRAY_SIZE(audio_pll2_bypass_sels),
> +				 CLK_SET_RATE_PARENT));
> +	clk_dm(IMX8MQ_VIDEO_PLL1_BYPASS,
> +	       imx_clk_mux_flags("video_pll1_bypass", base + 0x10, 4, 1,
> +				 video_pll1_bypass_sels,
> +				 ARRAY_SIZE(video_pll1_bypass_sels),
> +				 CLK_SET_RATE_PARENT));
> +
> +	/* PLL out gate */
> +	clk_dm(IMX8MQ_DRAM_PLL_OUT,
> +	       imx_clk_gate("dram_pll_out", "dram_pll_ref_sel",
> +			    base + 0x60, 13));
> +	clk_dm(IMX8MQ_ARM_PLL_OUT,
> +	       imx_clk_gate("arm_pll_out", "arm_pll_bypass",
> +			    base + 0x28, 11));
> +	clk_dm(IMX8MQ_GPU_PLL_OUT,
> +	       imx_clk_gate("gpu_pll_out", "gpu_pll_bypass",
> +			    base + 0x18, 11));
> +	clk_dm(IMX8MQ_VPU_PLL_OUT,
> +	       imx_clk_gate("vpu_pll_out", "vpu_pll_bypass",
> +			    base + 0x20, 11));
> +	clk_dm(IMX8MQ_AUDIO_PLL1_OUT,
> +	       imx_clk_gate("audio_pll1_out", "audio_pll1_bypass",
> +			    base + 0x0, 11));
> +	clk_dm(IMX8MQ_AUDIO_PLL2_OUT,
> +	       imx_clk_gate("audio_pll2_out", "audio_pll2_bypass",
> +			    base + 0x8, 11));
> +	clk_dm(IMX8MQ_VIDEO_PLL1_OUT,
> +	       imx_clk_gate("video_pll1_out", "video_pll1_bypass",
> +			    base + 0x10, 11));
> +
> +	clk_dm(IMX8MQ_SYS1_PLL_OUT,
> +	       imx_clk_gate("sys_pll1_out", "sys1_pll",
> +			    base + 0x30, 11));
> +	clk_dm(IMX8MQ_SYS2_PLL_OUT,
> +	       imx_clk_gate("sys_pll2_out", "sys2_pll",
> +			    base + 0x3c, 11));
> +	clk_dm(IMX8MQ_SYS3_PLL_OUT,
> +	       imx_clk_gate("sys_pll3_out", "sys3_pll",
> +			    base + 0x48, 11));
> +
> +	/* SYS PLL fixed output */
> +	clk_dm(IMX8MQ_SYS1_PLL_40M,
> +	       imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20));
> +	clk_dm(IMX8MQ_SYS1_PLL_80M,
> +	       imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10));
> +	clk_dm(IMX8MQ_SYS1_PLL_100M,
> +	       imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8));
> +	clk_dm(IMX8MQ_SYS1_PLL_133M,
> +	       imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6));
> +	clk_dm(IMX8MQ_SYS1_PLL_160M,
> +	       imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5));
> +	clk_dm(IMX8MQ_SYS1_PLL_200M,
> +	       imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4));
> +	clk_dm(IMX8MQ_SYS1_PLL_266M,
> +	       imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3));
> +	clk_dm(IMX8MQ_SYS1_PLL_400M,
> +	       imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2));
> +	clk_dm(IMX8MQ_SYS1_PLL_800M,
> +	       imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1));
> +
> +	clk_dm(IMX8MQ_SYS2_PLL_50M,
> +	       imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20));
> +	clk_dm(IMX8MQ_SYS2_PLL_100M,
> +	       imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10));
> +	clk_dm(IMX8MQ_SYS2_PLL_125M,
> +	       imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8));
> +	clk_dm(IMX8MQ_SYS2_PLL_166M,
> +	       imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6));
> +	clk_dm(IMX8MQ_SYS2_PLL_200M,
> +	       imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5));
> +	clk_dm(IMX8MQ_SYS2_PLL_250M,
> +	       imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4));
> +	clk_dm(IMX8MQ_SYS2_PLL_333M,
> +	       imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3));
> +	clk_dm(IMX8MQ_SYS2_PLL_500M,
> +	       imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2));
> +	clk_dm(IMX8MQ_SYS2_PLL_1000M,
> +	       imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1));
> +
> +	clk_dm(IMX8MQ_CLK_MON_AUDIO_PLL1_DIV,
> +	       imx_clk_divider("audio_pll1_out_monitor", "audio_pll1_bypass", base + 0x78, 0, 3));
> +	clk_dm(IMX8MQ_CLK_MON_AUDIO_PLL2_DIV,
> +	       imx_clk_divider("audio_pll2_out_monitor", "audio_pll2_bypass", base + 0x78, 4, 3));
> +	clk_dm(IMX8MQ_CLK_MON_VIDEO_PLL1_DIV,
> +	       imx_clk_divider("video_pll1_out_monitor", "video_pll1_bypass", base + 0x78, 8, 3));
> +	clk_dm(IMX8MQ_CLK_MON_GPU_PLL_DIV,
> +	       imx_clk_divider("gpu_pll_out_monitor", "gpu_pll_bypass", base + 0x78, 12, 3));
> +	clk_dm(IMX8MQ_CLK_MON_VPU_PLL_DIV,
> +	       imx_clk_divider("vpu_pll_out_monitor", "vpu_pll_bypass", base + 0x78, 16, 3));
> +	clk_dm(IMX8MQ_CLK_MON_ARM_PLL_DIV,
> +	       imx_clk_divider("arm_pll_out_monitor", "arm_pll_bypass", base + 0x78, 20, 3));
> +	clk_dm(IMX8MQ_CLK_MON_SYS_PLL1_DIV,
> +	       imx_clk_divider("sys_pll1_out_monitor", "sys_pll1_out", base + 0x7c, 0, 3));
> +	clk_dm(IMX8MQ_CLK_MON_SYS_PLL2_DIV,
> +	       imx_clk_divider("sys_pll2_out_monitor", "sys_pll2_out", base + 0x7c, 4, 3));
> +	clk_dm(IMX8MQ_CLK_MON_SYS_PLL3_DIV,
> +	       imx_clk_divider("sys_pll3_out_monitor", "sys_pll3_out", base + 0x7c, 8, 3));
> +	clk_dm(IMX8MQ_CLK_MON_DRAM_PLL_DIV,
> +	       imx_clk_divider("dram_pll_out_monitor", "dram_pll_out", base + 0x7c, 12, 3));
> +	clk_dm(IMX8MQ_CLK_MON_SEL,
> +	       imx_clk_mux_flags("pllout_monitor_sel", base + 0x74, 0, 4,
> +				 pllout_monitor_sels,
> +				 ARRAY_SIZE(pllout_monitor_sels),
> +				 CLK_SET_RATE_PARENT));
> +	clk_dm(IMX8MQ_CLK_MON_CLK2_OUT,
> +	       imx_clk_gate4("pllout_monitor_clk2", "pllout_monitor_sel", base + 0x74, 4));
> +
> +	base = dev_read_addr_ptr(dev);
> +	if (!base) {
> +		printf("%s : base failed\n", __func__);
> +		return -EINVAL;
> +	}
> +
> +	clk_dm(IMX8MQ_CLK_A53_SRC,
> +	       imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3,
> +			    imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels)));
> +	clk_dm(IMX8MQ_CLK_A53_CG,
> +	       imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28));
> +	clk_dm(IMX8MQ_CLK_A53_DIV,
> +	       imx_clk_divider2("arm_a53_div", "arm_a53_cg",
> +				base + 0x8000, 0, 3));
> +	clk_dm(IMX8MQ_CLK_A53_CORE,
> +	       imx_clk_mux2("arm_a53_src", base + 0x9880, 24, 1,
> +			    imx8mq_a53_core_sels, ARRAY_SIZE(imx8mq_a53_core_sels)));
> +
> +	clk_dm(IMX8MQ_CLK_AHB,
> +	       imx8m_clk_composite_critical("ahb", imx8mq_ahb_sels,
> +					    base + 0x9000));
> +	clk_dm(IMX8MQ_CLK_IPG_ROOT,
> +	       imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1));
> +
> +	clk_dm(IMX8MQ_CLK_ENET_AXI,
> +	       imx8m_clk_composite("enet_axi", imx8mq_enet_axi_sels,
> +				   base + 0x8880));
> +	clk_dm(IMX8MQ_CLK_NAND_USDHC_BUS,
> +	       imx8m_clk_composite_critical("nand_usdhc_bus",
> +					    imx8mq_nand_usdhc_sels,
> +					    base + 0x8900));
> +	clk_dm(IMX8MQ_CLK_USB_BUS,
> +	       imx8m_clk_composite("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80));
> +
> +	/* IP */
> +	clk_dm(IMX8MQ_CLK_USDHC1,
> +	       imx8m_clk_composite("usdhc1", imx8mq_usdhc1_sels,
> +				   base + 0xac00));
> +	clk_dm(IMX8MQ_CLK_USDHC2,
> +	       imx8m_clk_composite("usdhc2", imx8mq_usdhc2_sels,
> +				   base + 0xac80));
> +	clk_dm(IMX8MQ_CLK_I2C1,
> +	       imx8m_clk_composite("i2c1", imx8mq_i2c1_sels, base + 0xad00));
> +	clk_dm(IMX8MQ_CLK_I2C2,
> +	       imx8m_clk_composite("i2c2", imx8mq_i2c2_sels, base + 0xad80));
> +	clk_dm(IMX8MQ_CLK_I2C3,
> +	       imx8m_clk_composite("i2c3", imx8mq_i2c3_sels, base + 0xae00));
> +	clk_dm(IMX8MQ_CLK_I2C4,
> +	       imx8m_clk_composite("i2c4", imx8mq_i2c4_sels, base + 0xae80));
> +	clk_dm(IMX8MQ_CLK_WDOG,
> +	       imx8m_clk_composite("wdog", imx8mq_wdog_sels, base + 0xb900));
> +	clk_dm(IMX8MQ_CLK_QSPI,
> +	       imx8m_clk_composite("qspi", imx8mq_qspi_sels, base + 0xab80));
> +	clk_dm(IMX8MQ_CLK_USB_CORE_REF,
> +	       imx8m_clk_composite("usb_core_ref", imx8mq_usb_core_sels, base + 0xb100));
> +	clk_dm(IMX8MQ_CLK_USB_PHY_REF,
> +	       imx8m_clk_composite("usb_phy_ref", imx8mq_usb_phy_sels, base + 0xb180));
> +	clk_dm(IMX8MQ_CLK_ECSPI1,
> +	       imx8m_clk_composite("ecspi1", imx8mq_ecspi1_sels, base + 0xb280));
> +	clk_dm(IMX8MQ_CLK_ECSPI2,
> +	       imx8m_clk_composite("ecspi2", imx8mq_ecspi2_sels, base + 0xb300));
> +	clk_dm(IMX8MQ_CLK_ECSPI3,
> +	       imx8m_clk_composite("ecspi3", imx8mq_ecspi3_sels, base + 0xc180));
> +
> +	clk_dm(IMX8MQ_CLK_ECSPI1_ROOT,
> +	       imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0));
> +	clk_dm(IMX8MQ_CLK_ECSPI2_ROOT,
> +	       imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0));
> +	clk_dm(IMX8MQ_CLK_ECSPI3_ROOT,
> +	       imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0));
> +	clk_dm(IMX8MQ_CLK_I2C1_ROOT,
> +	       imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0));
> +	clk_dm(IMX8MQ_CLK_I2C2_ROOT,
> +	       imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0));
> +	clk_dm(IMX8MQ_CLK_I2C3_ROOT,
> +	       imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0));
> +	clk_dm(IMX8MQ_CLK_I2C4_ROOT,
> +	       imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0));
> +	clk_dm(IMX8MQ_CLK_OCOTP_ROOT,
> +	       imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0));
> +	clk_dm(IMX8MQ_CLK_USDHC1_ROOT,
> +	       imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0));
> +	clk_dm(IMX8MQ_CLK_USDHC2_ROOT,
> +	       imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0));
> +	clk_dm(IMX8MQ_CLK_WDOG1_ROOT,
> +	       imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0));
> +	clk_dm(IMX8MQ_CLK_WDOG2_ROOT,
> +	       imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0));
> +	clk_dm(IMX8MQ_CLK_WDOG3_ROOT,
> +	       imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0));
> +	clk_dm(IMX8MQ_CLK_QSPI_ROOT,
> +	       imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0));
> +	clk_dm(IMX8MQ_CLK_USB1_CTRL_ROOT,
> +	       imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0));
> +	clk_dm(IMX8MQ_CLK_USB2_CTRL_ROOT,
> +	       imx_clk_gate4("usb2_ctrl_root_clk", "usb_bus", base + 0x44e0, 0));
> +	clk_dm(IMX8MQ_CLK_USB1_PHY_ROOT,
> +	       imx_clk_gate4("usb1_phy_root_clk", "usb_phy_ref", base + 0x44f0, 0));
> +	clk_dm(IMX8MQ_CLK_USB2_PHY_ROOT,
> +	       imx_clk_gate4("usb2_phy_root_clk", "usb_phy_ref", base + 0x4500, 0));
> +
> +	clk_dm(IMX8MQ_CLK_ENET_REF,
> +	       imx8m_clk_composite("enet_ref", imx8mq_enet_ref_sels,
> +				   base + 0xa980));
> +	clk_dm(IMX8MQ_CLK_ENET_TIMER,
> +	       imx8m_clk_composite("enet_timer", imx8mq_enet_timer_sels,
> +				   base + 0xaa00));
> +	clk_dm(IMX8MQ_CLK_ENET_PHY_REF,
> +	       imx8m_clk_composite("enet_phy", imx8mq_enet_phy_sels,
> +				   base + 0xaa80));
> +	clk_dm(IMX8MQ_CLK_ENET1_ROOT,
> +	       imx_clk_gate4("enet1_root_clk", "enet_axi",
> +			     base + 0x40a0, 0));
> +
> +	return 0;
> +}
> +
> +static const struct udevice_id imx8mq_clk_ids[] = {
> +	{ .compatible = "fsl,imx8mq-ccm" },
> +	{ },
> +};
> +
> +U_BOOT_DRIVER(imx8mq_clk) = {
> +	.name = "clk_imx8mq",
> +	.id = UCLASS_CLK,
> +	.of_match = imx8mq_clk_ids,
> +	.ops = &imx8mq_clk_ops,
> +	.probe = imx8mq_clk_probe,
> +	.flags = DM_FLAG_PRE_RELOC,
> +};
> 

With Heiko's comments fixed,

Acked-by: Sean Anderson <seanga2@gmail.com>

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

* Re: [PATCH v4 4/4] clk: imx8m: remove code duplication
  2022-03-15 13:08 ` [PATCH v4 4/4] clk: imx8m: remove code duplication Angus Ainslie
@ 2022-03-20 23:58   ` Sean Anderson
  0 siblings, 0 replies; 26+ messages in thread
From: Sean Anderson @ 2022-03-20 23:58 UTC (permalink / raw)
  To: Angus Ainslie, u-boot, Marek Vasut
  Cc: lukma, sbabic, festevam, kernel, uboot-imx, peng.fan

Hi Angus,

On 3/15/22 9:08 AM, Angus Ainslie wrote:
> All of the imx8m[nmpq] use the same clk_ops functions so move them
> to a common file.
> 
> Signed-off-by: Angus Ainslie <angus@akkea.ca>
> Reviewed-by: Marek Vasut <marex@denx.de>
> ---
>   drivers/clk/imx/Makefile     |   8 +--
>   drivers/clk/imx/clk-imx8m.c  | 108 +++++++++++++++++++++++++++++++++++
>   drivers/clk/imx/clk-imx8m.h  |  12 ++++
>   drivers/clk/imx/clk-imx8mm.c |  89 +----------------------------
>   drivers/clk/imx/clk-imx8mn.c |  89 +----------------------------
>   drivers/clk/imx/clk-imx8mp.c |  91 +----------------------------
>   drivers/clk/imx/clk-imx8mq.c |  91 +----------------------------
>   7 files changed, 132 insertions(+), 356 deletions(-)
>   create mode 100644 drivers/clk/imx/clk-imx8m.c
>   create mode 100644 drivers/clk/imx/clk-imx8m.h

Looks like this is accomplishing the same thing as [1], which also covers
at91 and mpfs. Great minds think alike :)

Would it be possible for you to rebase your series on mine?

--Sean

[1] https://patchwork.ozlabs.org/project/uboot/patch/20220320203446.740178-2-seanga2@gmail.com/

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-15 15:35   ` Heiko Thiery
  2022-03-15 15:46     ` Angus Ainslie
  2022-03-15 19:01     ` Marek Vasut
@ 2022-03-21  1:32     ` Peng Fan (OSS)
  2 siblings, 0 replies; 26+ messages in thread
From: Peng Fan (OSS) @ 2022-03-21  1:32 UTC (permalink / raw)
  To: Heiko Thiery, Angus Ainslie
  Cc: u-boot, Marek Vasut, lukma, seanga2, sbabic, festevam, kernel,
	dl-uboot-imx, Peng Fan



On 2022/3/15 23:35, Heiko Thiery wrote:
> Hi Angus and all,
> 
> 
> 
> 
> Am Di., 15. März 2022 um 14:09 Uhr schrieb Angus Ainslie <angus@akkea.ca 
> <mailto:angus@akkea.ca>>:
> 
>     This is a DM clock driver based off the imx8mm u-boot driver and the
>     linux
>     kernel driver.
> 
>     All of the PLLs and clocks are initialized so the subsystems below are
>     functional and tested.
> 
>     1) USB host and peripheral
>     2) ECSPI
>     3) UART
>     4) I2C all busses
>     5) USDHC for eMMC support
>     6) USB storage
>     7) GPIO
>     8) DRAM
> 
>     Signed-off-by: Angus Ainslie <angus@akkea.ca <mailto:angus@akkea.ca>>
>     ---
>       drivers/clk/imx/Kconfig      |  16 +
>       drivers/clk/imx/Makefile     |   2 +
>       drivers/clk/imx/clk-imx8mq.c | 575 +++++++++++++++++++++++++++++++++++
>       3 files changed, 593 insertions(+)
>       create mode 100644 drivers/clk/imx/clk-imx8mq.c
> 
>     diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
>     index cdd348020b0..06d8c1a5dd3 100644
>     --- a/drivers/clk/imx/Kconfig
>     +++ b/drivers/clk/imx/Kconfig
>     @@ -71,6 +71,22 @@ config CLK_IMX8MP
>              help
>                This enables support clock driver for i.MX8MP platforms.
> 
>     +config SPL_CLK_IMX8MQ
>     +       bool "SPL clock support for i.MX8MQ"
>     +       depends on ARCH_IMX8M && SPL
>     +       select SPL_CLK
>     +       select SPL_CLK_CCF
>     +       help
>     +         This enables SPL DM/DTS support for clock driver in i.MX8MQ
>     +
>     +config CLK_IMX8MQ
>     +       bool "Clock support for i.MX8MQ"
>     +       depends on ARCH_IMX8M
>     +       select CLK
>     +       select CLK_CCF
>     +       help
>     +         This enables support clock driver for i.MX8MQ platforms.
>     +
>       config SPL_CLK_IMXRT1020
>              bool "SPL clock support for i.MXRT1020"
>              depends on ARCH_IMXRT && SPL
>     diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
>     index 01bbbdf3aea..c5766901f2b 100644
>     --- a/drivers/clk/imx/Makefile
>     +++ b/drivers/clk/imx/Makefile
>     @@ -16,6 +16,8 @@ obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MN) +=
>     clk-imx8mn.o clk-pll14xx.o \
>                                      clk-composite-8m.o
>       obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MP) += clk-imx8mp.o clk-pll14xx.o \
>                                      clk-composite-8m.o
>     +obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MQ) += clk-imx8mq.o clk-pll14xx.o \
>     +                               clk-composite-8m.o
> 
>       obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1020) += clk-imxrt1020.o
>       obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1050) += clk-imxrt1050.o
>     diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
>     new file mode 100644
>     index 00000000000..0aea417a29b
>     --- /dev/null
>     +++ b/drivers/clk/imx/clk-imx8mq.c
>     @@ -0,0 +1,575 @@
>     +// SPDX-License-Identifier: GPL-2.0
>     +/*
>     + * Copyright 2019 NXP
>     + * Copyright 2022 Purism
>     + * Peng Fan <peng.fan@nxp.com <mailto:peng.fan@nxp.com>>
>     + */
>     +
>     +#include <common.h>
>     +#include <clk.h>
>     +#include <clk-uclass.h>
>     +#include <dm.h>
>     +#include <log.h>
>     +#include <asm/arch/clock.h>
>     +#include <asm/arch/imx-regs.h>
>     +#include <dt-bindings/clock/imx8mq-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 imx8mq_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),
>     +};
>     +
>     +const struct imx_pll14xx_rate_table imx8mq_pll1443x_tbl[] = {
>     +       PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
>     +       PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
>     +       PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
>     +       PLL_1443X_RATE(361267200U, 361, 3, 3, 17511),
>     +};
>     +
>     +static struct imx_pll14xx_clk imx8mq_1416x_pll __initdata = {
>     +               .type = PLL_1416X,
>     +               .rate_table = imx8mq_pll1416x_tbl,
>     +               .rate_count = ARRAY_SIZE(imx8mq_pll1416x_tbl),
>     +};
>     +
>     +static struct imx_pll14xx_clk imx8mq_1443x_pll __initdata = {
>     +               .type = PLL_1443X,
>     +               .rate_table = imx8mq_pll1443x_tbl,
>     +               .rate_count = ARRAY_SIZE(imx8mq_pll1443x_tbl),
>     +};
>     +
>     +static const char *pll_ref_sels[] = { "clock-osc-25m",
>     "clock-osc-27m", "clock-phy-27m", "dummy", };
>     +static const char *arm_pll_bypass_sels[] = {"arm_pll",
>     "arm_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 *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 *imx8mq_a53_core_sels[] = {"arm_a53_div",
>     "arm_pll_out", };
>     +static const char *imx8mq_a53_sels[] = {"clock-osc-25m",
>     "arm_pll_out", "sys_pll2_500m",
>     +                                       "sys_pll2_1000m",
>     "sys_pll1_800m", "sys_pll1_400m",
>     +                                       "audio_pll1_out",
>     "sys_pll3_out", };
>     +
>     +static const char *imx8mq_ahb_sels[] = {"clock-osc-25m",
>     "sys_pll1_133m", "sys_pll1_800m",
>     +                                       "sys_pll1_400m",
>     "sys_pll2_125m", "sys_pll3_out",
>     +                                       "audio_pll1_out",
>     "video_pll1_out", };
>     +
>     +static const char *imx8mq_enet_axi_sels[] = {"clock-osc-25m",
>     "sys_pll1_266m", "sys_pll1_800m",
>     +                                            "sys_pll2_250m",
>     "sys_pll2_200m", "audio_pll1_out",
>     +                                            "video_pll1_out",
>     "sys_pll3_out", };
>     +
>     +static const char *imx8mq_enet_ref_sels[] = {"clock-osc-25m",
>     "sys_pll2_125m", "sys_pll2_50m",
>     +                                            "sys_pll2_100m",
>     "sys_pll1_160m", "audio_pll1_out",
>     +                                            "video_pll1_out",
>     "clk_ext4", };
>     +
>     +static const char *imx8mq_enet_timer_sels[] = {"clock-osc-25m",
>     "sys_pll2_100m", "audio_pll1_out",
>     +                                              "clk_ext1",
>     "clk_ext2", "clk_ext3", "clk_ext4",
>     +                                              "video_pll1_out", };
>     +
>     +static const char *imx8mq_enet_phy_sels[] = {"clock-osc-25m",
>     "sys_pll2_50m", "sys_pll2_125m",
>     +                                            "sys_pll2_200m",
>     "sys_pll2_500m", "video_pll1_out",
>     +                                            "audio_pll2_out", };
>     +
>     +static const char *imx8mq_nand_usdhc_sels[] = {"clock-osc-25m",
>     "sys_pll1_266m", "sys_pll1_800m",
>     +                                              "sys_pll2_200m",
>     "sys_pll1_133m", "sys_pll3_out",
>     +                                              "sys_pll2_250m",
>     "audio_pll1_out", };
>     +
>     +static const char *imx8mq_usb_bus_sels[] = {"clock-osc-25m",
>     "sys_pll2_500m", "sys_pll1_800m",
>     +                                           "sys_pll2_100m",
>     "sys_pll2_200m", "clk_ext2",
>     +                                           "clk_ext4",
>     "audio_pll2_out", };
>     +
>     +static const char *imx8mq_usdhc1_sels[] = {"clock-osc-25m",
>     "sys_pll1_400m", "sys_pll1_800m",
>     +                                          "sys_pll2_500m",
>     "sys_pll3_out", "sys_pll1_266m",
>     +                                          "audio_pll2_out",
>     "sys_pll1_100m", };
>     +
>     +static const char *imx8mq_usdhc2_sels[] = {"clock-osc-25m",
>     "sys_pll1_400m", "sys_pll1_800m",
>     +                                          "sys_pll2_500m",
>     "sys_pll3_out", "sys_pll1_266m",
>     +                                          "audio_pll2_out",
>     "sys_pll1_100m", };
>     +
>     +static const char *imx8mq_i2c1_sels[] = {"clock-osc-25m",
>     "sys_pll1_160m", "sys_pll2_50m",
>     +                                        "sys_pll3_out",
>     "audio_pll1_out", "video_pll1_out",
>     +                                        "audio_pll2_out",
>     "sys_pll1_133m", };
>     +
>     +static const char *imx8mq_i2c2_sels[] = {"clock-osc-25m",
>     "sys_pll1_160m", "sys_pll2_50m",
>     +                                        "sys_pll3_out",
>     "audio_pll1_out", "video_pll1_out",
>     +                                        "audio_pll2_out",
>     "sys_pll1_133m", };
>     +
>     +static const char *imx8mq_i2c3_sels[] = {"clock-osc-25m",
>     "sys_pll1_160m", "sys_pll2_50m",
>     +                                        "sys_pll3_out",
>     "audio_pll1_out", "video_pll1_out",
>     +                                        "audio_pll2_out",
>     "sys_pll1_133m", };
>     +
>     +static const char *imx8mq_i2c4_sels[] = {"clock-osc-25m",
>     "sys_pll1_160m", "sys_pll2_50m",
>     +                                        "sys_pll3_out",
>     "audio_pll1_out", "video_pll1_out",
>     +                                        "audio_pll2_out",
>     "sys_pll1_133m", };
>     +
>     +static const char *imx8mq_wdog_sels[] = {"clock-osc-25m",
>     "sys_pll1_133m", "sys_pll1_160m",
>     +                                        "vpu_pll_out",
>     "sys_pll2_125m", "sys_pll3_out",
>     +                                        "sys_pll1_80m",
>     "sys_pll2_166m", };
>     +
>     +static const char *imx8mq_qspi_sels[] = {"clock-osc-25m",
>     "sys_pll1_400m", "sys_pll2_333m",
>     +                                        "sys_pll2_500m",
>     "audio_pll2_out", "sys_pll1_266m",
>     +                                        "sys_pll3_out",
>     "sys_pll1_100m", };
>     +
>     +static const char *imx8mq_usb_core_sels[] = {"clock-osc-25m",
>     "sys_pll1_100m", "sys_pll1_40m",
>     +                                            "sys_pll2_100m",
>     "sys_pll2_200m", "clk_ext2",
>     +                                            "clk_ext3",
>     "audio_pll2_out", };
>     +
>     +static const char *imx8mq_usb_phy_sels[] = {"clock-osc-25m",
>     "sys_pll1_100m", "sys_pll1_40m",
>     +                                           "sys_pll2_100m",
>     "sys_pll2_200m", "clk_ext2",
>     +                                           "clk_ext3",
>     "audio_pll2_out", };
>     +
>     +static const char *imx8mq_ecspi1_sels[] = {"clock-osc-25m",
>     "sys_pll2_200m", "sys_pll1_40m",
>     +                                          "sys_pll1_160m",
>     "sys_pll1_800m", "sys_pll3_out",
>     +                                          "sys_pll2_250m",
>     "audio_pll2_out", };
>     +
>     +static const char *imx8mq_ecspi2_sels[] = {"clock-osc-25m",
>     "sys_pll2_200m", "sys_pll1_40m",
>     +                                          "sys_pll1_160m",
>     "sys_pll1_800m", "sys_pll3_out",
>     +                                          "sys_pll2_250m",
>     "audio_pll2_out", };
>     +
>     +static const char *imx8mq_ecspi3_sels[] = {"clock-osc-25m",
>     "sys_pll2_200m", "sys_pll1_40m",
>     +                                          "sys_pll1_160m",
>     "sys_pll1_800m", "sys_pll3_out",
>     +                                          "sys_pll2_250m",
>     "audio_pll2_out", };
>     +
>     +static const char *pllout_monitor_sels[] = {"clock-osc-25m",
>     "clock-osc-27m", "clock-phy-27m",
>     +                                           "dummy", "clock-ckil",
>     "audio_pll1_out_monitor",
>     +                                         
>       "audio_pll2_out_monitor", "gpu_pll_out_monitor",
>     +                                           "vpu_pll_out_monitor",
>     "video_pll1_out_monitor",
>     +                                           "arm_pll_out_monitor",
>     "sys_pll1_out_monitor",
>     +                                           "sys_pll2_out_monitor",
>     "sys_pll3_out_monitor",
>     +                                           "dummy",
>     "dram_pll_out_monitor", };
>     +
>     +static ulong imx8mq_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 imx8mq_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 __imx8mq_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) {
>     +               debug("%s: clk_get_by_id failed\n", __func__);
>     +               return ret;
>     +       }
>     +
>     +       if (enable)
>     +               ret = clk_enable(c);
>     +       else
>     +               ret = clk_disable(c);
>     +
>     +       return ret;
>     +}
>     +
>     +static int imx8mq_clk_disable(struct clk *clk)
>     +{
>     +       return __imx8mq_clk_enable(clk, 0);
>     +}
>     +
>     +static int imx8mq_clk_enable(struct clk *clk)
>     +{
>     +       return __imx8mq_clk_enable(clk, 1);
>     +}
>     +
>     +static int imx8mq_clk_set_parent(struct clk *clk, struct clk *parent)
>     +{
>     +       struct clk *c, *cp;
>     +       int ret;
>     +
>     +       debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
>     +
>     +       ret = clk_get_by_id(clk->id, &c);
>     +       if (ret)
>     +               return ret;
>     +
>     +       ret = clk_get_by_id(parent->id, &cp);
>     +       if (ret)
>     +               return ret;
>     +
>     +       ret = clk_set_parent(c, cp);
>     +       c->dev->parent = cp->dev;
>     +
>     +       return ret;
>     +}
>     +
>     +static struct clk_ops imx8mq_clk_ops = {
>     +       .set_rate = imx8mq_clk_set_rate,
>     +       .get_rate = imx8mq_clk_get_rate,
>     +       .enable = imx8mq_clk_enable,
>     +       .disable = imx8mq_clk_disable,
>     +       .set_parent = imx8mq_clk_set_parent,
>     +};
>     +
>     +static int imx8mq_clk_probe(struct udevice *dev)
>     +{
>     +       void __iomem *base;
>     +
>     +       base = (void *)ANATOP_BASE_ADDR;
>     +
>     +       clk_dm(IMX8MQ_CLK_32K, clk_register_fixed_rate(NULL, "ckil",
>     32768));
>     +
>     +       clk_dm(IMX8MQ_DRAM_PLL1_REF_SEL,
>     +              imx_clk_mux("dram_pll_ref_sel", base + 0x60, 0, 2,
>     +                          pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
>     +       clk_dm(IMX8MQ_ARM_PLL_REF_SEL,
>     +              imx_clk_mux("arm_pll_ref_sel", base + 0x28, 0, 2,
>     +                          pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
>     +       clk_dm(IMX8MQ_GPU_PLL_REF_SEL,
>     +              imx_clk_mux("gpu_pll_ref_sel", base + 0x18, 0, 2,
>     +                          pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
>     +       clk_dm(IMX8MQ_VPU_PLL_REF_SEL,
>     +              imx_clk_mux("vpu_pll_ref_sel", base + 0x20, 0, 2,
>     +                          pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
>     +       clk_dm(IMX8MQ_SYS3_PLL1_REF_SEL,
>     +              imx_clk_mux("sys3_pll_ref_sel", base + 0x48, 0, 2,
>     +                          pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
>     +       clk_dm(IMX8MQ_AUDIO_PLL1_REF_SEL,
>     +              imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2,
>     +                          pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
>     +       clk_dm(IMX8MQ_AUDIO_PLL2_REF_SEL,
>     +              imx_clk_mux("audio_pll2_ref_sel", base + 0x8, 0, 2,
>     +                          pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
>     +       clk_dm(IMX8MQ_VIDEO_PLL1_REF_SEL,
>     +              imx_clk_mux("video_pll1_ref_sel", base + 0x10, 0, 2,
>     +                          pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
>     +
>     +       clk_dm(IMX8MQ_ARM_PLL,
>     +              imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel",
>     +                              base + 0x28, &imx8mq_1416x_pll));
>     +       clk_dm(IMX8MQ_GPU_PLL,
>     +              imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel",
>     +                              base + 0x18, &imx8mq_1416x_pll));
>     +       clk_dm(IMX8MQ_VPU_PLL,
>     +              imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel",
>     +                              base + 0x20, &imx8mq_1416x_pll));
>     +
>     +       clk_dm(IMX8MQ_SYS1_PLL1,
>     +              clk_register_fixed_rate(NULL, "sys1_pll", 800000000));
>     +       clk_dm(IMX8MQ_SYS2_PLL1,
>     +              clk_register_fixed_rate(NULL, "sys2_pll", 1000000000));
>     +       clk_dm(IMX8MQ_SYS2_PLL1,
>     +              clk_register_fixed_rate(NULL, "sys3_pll", 1000000000));
>     +       clk_dm(IMX8MQ_AUDIO_PLL1,
>     +              imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel",
>     +                              base + 0x0, &imx8mq_1443x_pll));
>     +       clk_dm(IMX8MQ_AUDIO_PLL2,
>     +              imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel",
>     +                              base + 0x8, &imx8mq_1443x_pll));
>     +       clk_dm(IMX8MQ_VIDEO_PLL1,
>     +              imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel",
>     +                              base + 0x10, &imx8mq_1443x_pll));
>     +
>     +       /* PLL bypass out */
>     +       clk_dm(IMX8MQ_ARM_PLL_BYPASS,
>     +              imx_clk_mux_flags("arm_pll_bypass", base + 0x28, 4, 1,
>     +                                arm_pll_bypass_sels,
>     +                                ARRAY_SIZE(arm_pll_bypass_sels),
>     +                                CLK_SET_RATE_PARENT));
>     +       clk_dm(IMX8MQ_GPU_PLL_BYPASS,
>     +              imx_clk_mux_flags("gpu_pll_bypass", base + 0x18, 4, 1,
>     +                                gpu_pll_bypass_sels,
>     +                                ARRAY_SIZE(gpu_pll_bypass_sels),
>     +                                CLK_SET_RATE_PARENT));
>     +       clk_dm(IMX8MQ_VPU_PLL_BYPASS,
>     +              imx_clk_mux_flags("vpu_pll_bypass", base + 0x20, 4, 1,
>     +                                vpu_pll_bypass_sels,
>     +                                ARRAY_SIZE(vpu_pll_bypass_sels),
>     +                                CLK_SET_RATE_PARENT));
>     +       clk_dm(IMX8MQ_AUDIO_PLL1_BYPASS,
>     +              imx_clk_mux_flags("audio_pll1_bypass", base + 0x0, 4, 1,
>     +                                audio_pll1_bypass_sels,
>     +                                ARRAY_SIZE(audio_pll1_bypass_sels),
>     +                                CLK_SET_RATE_PARENT));
>     +       clk_dm(IMX8MQ_AUDIO_PLL2_BYPASS,
>     +              imx_clk_mux_flags("audio_pll2_bypass", base + 0x8, 4, 1,
>     +                                audio_pll2_bypass_sels,
>     +                                ARRAY_SIZE(audio_pll2_bypass_sels),
>     +                                CLK_SET_RATE_PARENT));
>     +       clk_dm(IMX8MQ_VIDEO_PLL1_BYPASS,
>     +              imx_clk_mux_flags("video_pll1_bypass", base + 0x10, 4, 1,
>     +                                video_pll1_bypass_sels,
>     +                                ARRAY_SIZE(video_pll1_bypass_sels),
>     +                                CLK_SET_RATE_PARENT));
>     +
>     +       /* PLL out gate */
>     +       clk_dm(IMX8MQ_DRAM_PLL_OUT,
>     +              imx_clk_gate("dram_pll_out", "dram_pll_ref_sel",
>     +                           base + 0x60, 13));
>     +       clk_dm(IMX8MQ_ARM_PLL_OUT,
>     +              imx_clk_gate("arm_pll_out", "arm_pll_bypass",
>     +                           base + 0x28, 11));
>     +       clk_dm(IMX8MQ_GPU_PLL_OUT,
>     +              imx_clk_gate("gpu_pll_out", "gpu_pll_bypass",
>     +                           base + 0x18, 11));
>     +       clk_dm(IMX8MQ_VPU_PLL_OUT,
>     +              imx_clk_gate("vpu_pll_out", "vpu_pll_bypass",
>     +                           base + 0x20, 11));
>     +       clk_dm(IMX8MQ_AUDIO_PLL1_OUT,
>     +              imx_clk_gate("audio_pll1_out", "audio_pll1_bypass",
>     +                           base + 0x0, 11));
>     +       clk_dm(IMX8MQ_AUDIO_PLL2_OUT,
>     +              imx_clk_gate("audio_pll2_out", "audio_pll2_bypass",
>     +                           base + 0x8, 11));
>     +       clk_dm(IMX8MQ_VIDEO_PLL1_OUT,
>     +              imx_clk_gate("video_pll1_out", "video_pll1_bypass",
>     +                           base + 0x10, 11));
>     +
>     +       clk_dm(IMX8MQ_SYS1_PLL_OUT,
>     +              imx_clk_gate("sys_pll1_out", "sys1_pll",
>     +                           base + 0x30, 11));
>     +       clk_dm(IMX8MQ_SYS2_PLL_OUT,
>     +              imx_clk_gate("sys_pll2_out", "sys2_pll",
>     +                           base + 0x3c, 11));
>     +       clk_dm(IMX8MQ_SYS3_PLL_OUT,
>     +              imx_clk_gate("sys_pll3_out", "sys3_pll",
>     +                           base + 0x48, 11));
>     +
>     +       /* SYS PLL fixed output */
>     +       clk_dm(IMX8MQ_SYS1_PLL_40M,
>     +              imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out",
>     1, 20));
>     +       clk_dm(IMX8MQ_SYS1_PLL_80M,
>     +              imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out",
>     1, 10));
>     +       clk_dm(IMX8MQ_SYS1_PLL_100M,
>     +              imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out",
>     1, 8));
>     +       clk_dm(IMX8MQ_SYS1_PLL_133M,
>     +              imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out",
>     1, 6));
>     +       clk_dm(IMX8MQ_SYS1_PLL_160M,
>     +              imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out",
>     1, 5));
>     +       clk_dm(IMX8MQ_SYS1_PLL_200M,
>     +              imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out",
>     1, 4));
>     +       clk_dm(IMX8MQ_SYS1_PLL_266M,
>     +              imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out",
>     1, 3));
>     +       clk_dm(IMX8MQ_SYS1_PLL_400M,
>     +              imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out",
>     1, 2));
>     +       clk_dm(IMX8MQ_SYS1_PLL_800M,
>     +              imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out",
>     1, 1));
>     +
>     +       clk_dm(IMX8MQ_SYS2_PLL_50M,
>     +              imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out",
>     1, 20));
>     +       clk_dm(IMX8MQ_SYS2_PLL_100M,
>     +              imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out",
>     1, 10));
>     +       clk_dm(IMX8MQ_SYS2_PLL_125M,
>     +              imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out",
>     1, 8));
>     +       clk_dm(IMX8MQ_SYS2_PLL_166M,
>     +              imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out",
>     1, 6));
>     +       clk_dm(IMX8MQ_SYS2_PLL_200M,
>     +              imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out",
>     1, 5));
>     +       clk_dm(IMX8MQ_SYS2_PLL_250M,
>     +              imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out",
>     1, 4));
>     +       clk_dm(IMX8MQ_SYS2_PLL_333M,
>     +              imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out",
>     1, 3));
>     +       clk_dm(IMX8MQ_SYS2_PLL_500M,
>     +              imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out",
>     1, 2));
>     +       clk_dm(IMX8MQ_SYS2_PLL_1000M,
>     +              imx_clk_fixed_factor("sys_pll2_1000m",
>     "sys_pll2_out", 1, 1));
>     +
>     +       clk_dm(IMX8MQ_CLK_MON_AUDIO_PLL1_DIV,
>     +              imx_clk_divider("audio_pll1_out_monitor",
>     "audio_pll1_bypass", base + 0x78, 0, 3));
>     +       clk_dm(IMX8MQ_CLK_MON_AUDIO_PLL2_DIV,
>     +              imx_clk_divider("audio_pll2_out_monitor",
>     "audio_pll2_bypass", base + 0x78, 4, 3));
>     +       clk_dm(IMX8MQ_CLK_MON_VIDEO_PLL1_DIV,
>     +              imx_clk_divider("video_pll1_out_monitor",
>     "video_pll1_bypass", base + 0x78, 8, 3));
>     +       clk_dm(IMX8MQ_CLK_MON_GPU_PLL_DIV,
>     +              imx_clk_divider("gpu_pll_out_monitor",
>     "gpu_pll_bypass", base + 0x78, 12, 3));
>     +       clk_dm(IMX8MQ_CLK_MON_VPU_PLL_DIV,
>     +              imx_clk_divider("vpu_pll_out_monitor",
>     "vpu_pll_bypass", base + 0x78, 16, 3));
>     +       clk_dm(IMX8MQ_CLK_MON_ARM_PLL_DIV,
>     +              imx_clk_divider("arm_pll_out_monitor",
>     "arm_pll_bypass", base + 0x78, 20, 3));
>     +       clk_dm(IMX8MQ_CLK_MON_SYS_PLL1_DIV,
>     +              imx_clk_divider("sys_pll1_out_monitor",
>     "sys_pll1_out", base + 0x7c, 0, 3));
>     +       clk_dm(IMX8MQ_CLK_MON_SYS_PLL2_DIV,
>     +              imx_clk_divider("sys_pll2_out_monitor",
>     "sys_pll2_out", base + 0x7c, 4, 3));
>     +       clk_dm(IMX8MQ_CLK_MON_SYS_PLL3_DIV,
>     +              imx_clk_divider("sys_pll3_out_monitor",
>     "sys_pll3_out", base + 0x7c, 8, 3));
>     +       clk_dm(IMX8MQ_CLK_MON_DRAM_PLL_DIV,
>     +              imx_clk_divider("dram_pll_out_monitor",
>     "dram_pll_out", base + 0x7c, 12, 3));
>     +       clk_dm(IMX8MQ_CLK_MON_SEL,
>     +              imx_clk_mux_flags("pllout_monitor_sel", base + 0x74,
>     0, 4,
>     +                                pllout_monitor_sels,
>     +                                ARRAY_SIZE(pllout_monitor_sels),
>     +                                CLK_SET_RATE_PARENT));
>     +       clk_dm(IMX8MQ_CLK_MON_CLK2_OUT,
>     +              imx_clk_gate4("pllout_monitor_clk2",
>     "pllout_monitor_sel", base + 0x74, 4));
>     +
>     +       base = dev_read_addr_ptr(dev);
>     +       if (!base) {
>     +               printf("%s : base failed\n", __func__);
>     +               return -EINVAL;
>     +       }
>     +
>     +       clk_dm(IMX8MQ_CLK_A53_SRC,
>     +              imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3,
>     +                           imx8mq_a53_sels,
>     ARRAY_SIZE(imx8mq_a53_sels)));
>     +       clk_dm(IMX8MQ_CLK_A53_CG,
>     +              imx_clk_gate3("arm_a53_cg", "arm_a53_src", base +
>     0x8000, 28));
>     +       clk_dm(IMX8MQ_CLK_A53_DIV,
>     +              imx_clk_divider2("arm_a53_div", "arm_a53_cg",
>     +                               base + 0x8000, 0, 3));
>     +       clk_dm(IMX8MQ_CLK_A53_CORE,
>     +              imx_clk_mux2("arm_a53_src", base + 0x9880, 24, 1,
>     +                           imx8mq_a53_core_sels,
>     ARRAY_SIZE(imx8mq_a53_core_sels)));
>     +
>     +       clk_dm(IMX8MQ_CLK_AHB,
>     +              imx8m_clk_composite_critical("ahb", imx8mq_ahb_sels,
>     +                                           base + 0x9000));
>     +       clk_dm(IMX8MQ_CLK_IPG_ROOT,
>     +              imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0,
>     1));
>     +
>     +       clk_dm(IMX8MQ_CLK_ENET_AXI,
>     +              imx8m_clk_composite("enet_axi", imx8mq_enet_axi_sels,
>     +                                  base + 0x8880));
>     +       clk_dm(IMX8MQ_CLK_NAND_USDHC_BUS,
>     +              imx8m_clk_composite_critical("nand_usdhc_bus",
>     +                                           imx8mq_nand_usdhc_sels,
>     +                                           base + 0x8900));
>     +       clk_dm(IMX8MQ_CLK_USB_BUS,
>     +              imx8m_clk_composite("usb_bus", imx8mq_usb_bus_sels,
>     base + 0x8b80));
>     +
>     +       /* IP */
>     +       clk_dm(IMX8MQ_CLK_USDHC1,
>     +              imx8m_clk_composite("usdhc1", imx8mq_usdhc1_sels,
>     +                                  base + 0xac00));
>     +       clk_dm(IMX8MQ_CLK_USDHC2,
>     +              imx8m_clk_composite("usdhc2", imx8mq_usdhc2_sels,
>     +                                  base + 0xac80));
>     +       clk_dm(IMX8MQ_CLK_I2C1,
>     +              imx8m_clk_composite("i2c1", imx8mq_i2c1_sels, base +
>     0xad00));
>     +       clk_dm(IMX8MQ_CLK_I2C2,
>     +              imx8m_clk_composite("i2c2", imx8mq_i2c2_sels, base +
>     0xad80));
>     +       clk_dm(IMX8MQ_CLK_I2C3,
>     +              imx8m_clk_composite("i2c3", imx8mq_i2c3_sels, base +
>     0xae00));
>     +       clk_dm(IMX8MQ_CLK_I2C4,
>     +              imx8m_clk_composite("i2c4", imx8mq_i2c4_sels, base +
>     0xae80));
>     +       clk_dm(IMX8MQ_CLK_WDOG,
>     +              imx8m_clk_composite("wdog", imx8mq_wdog_sels, base +
>     0xb900));
>     +       clk_dm(IMX8MQ_CLK_QSPI,
>     +              imx8m_clk_composite("qspi", imx8mq_qspi_sels, base +
>     0xab80));
>     +       clk_dm(IMX8MQ_CLK_USB_CORE_REF,
>     +              imx8m_clk_composite("usb_core_ref",
>     imx8mq_usb_core_sels, base + 0xb100));
>     +       clk_dm(IMX8MQ_CLK_USB_PHY_REF,
>     +              imx8m_clk_composite("usb_phy_ref",
>     imx8mq_usb_phy_sels, base + 0xb180));
>     +       clk_dm(IMX8MQ_CLK_ECSPI1,
>     +              imx8m_clk_composite("ecspi1", imx8mq_ecspi1_sels,
>     base + 0xb280));
>     +       clk_dm(IMX8MQ_CLK_ECSPI2,
>     +              imx8m_clk_composite("ecspi2", imx8mq_ecspi2_sels,
>     base + 0xb300));
>     +       clk_dm(IMX8MQ_CLK_ECSPI3,
>     +              imx8m_clk_composite("ecspi3", imx8mq_ecspi3_sels,
>     base + 0xc180));
>     +
>     +       clk_dm(IMX8MQ_CLK_ECSPI1_ROOT,
>     +              imx_clk_gate4("ecspi1_root_clk", "ecspi1", base +
>     0x4070, 0));
>     +       clk_dm(IMX8MQ_CLK_ECSPI2_ROOT,
>     +              imx_clk_gate4("ecspi2_root_clk", "ecspi2", base +
>     0x4080, 0));
>     +       clk_dm(IMX8MQ_CLK_ECSPI3_ROOT,
>     +              imx_clk_gate4("ecspi3_root_clk", "ecspi3", base +
>     0x4090, 0));
>     +       clk_dm(IMX8MQ_CLK_I2C1_ROOT,
>     +              imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170,
>     0));
>     +       clk_dm(IMX8MQ_CLK_I2C2_ROOT,
>     +              imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180,
>     0));
>     +       clk_dm(IMX8MQ_CLK_I2C3_ROOT,
>     +              imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190,
>     0));
>     +       clk_dm(IMX8MQ_CLK_I2C4_ROOT,
>     +              imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0,
>     0));
>     +       clk_dm(IMX8MQ_CLK_OCOTP_ROOT,
>     +              imx_clk_gate4("ocotp_root_clk", "ipg_root", base +
>     0x4220, 0));
>     +       clk_dm(IMX8MQ_CLK_USDHC1_ROOT,
>     +              imx_clk_gate4("usdhc1_root_clk", "usdhc1", base +
>     0x4510, 0));
>     +       clk_dm(IMX8MQ_CLK_USDHC2_ROOT,
>     +              imx_clk_gate4("usdhc2_root_clk", "usdhc2", base +
>     0x4520, 0));
>     +       clk_dm(IMX8MQ_CLK_WDOG1_ROOT,
>     +              imx_clk_gate4("wdog1_root_clk", "wdog", base +
>     0x4530, 0));
>     +       clk_dm(IMX8MQ_CLK_WDOG2_ROOT,
>     +              imx_clk_gate4("wdog2_root_clk", "wdog", base +
>     0x4540, 0));
>     +       clk_dm(IMX8MQ_CLK_WDOG3_ROOT,
>     +              imx_clk_gate4("wdog3_root_clk", "wdog", base +
>     0x4550, 0));
>     +       clk_dm(IMX8MQ_CLK_QSPI_ROOT,
>     +              imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0,
>     0));
>     +       clk_dm(IMX8MQ_CLK_USB1_CTRL_ROOT,
>     +              imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base +
>     0x44d0, 0));
>     +       clk_dm(IMX8MQ_CLK_USB2_CTRL_ROOT,
>     +              imx_clk_gate4("usb2_ctrl_root_clk", "usb_bus", base +
>     0x44e0, 0));
>     +       clk_dm(IMX8MQ_CLK_USB1_PHY_ROOT,
>     +              imx_clk_gate4("usb1_phy_root_clk", "usb_phy_ref",
>     base + 0x44f0, 0));
>     +       clk_dm(IMX8MQ_CLK_USB2_PHY_ROOT,
>     +              imx_clk_gate4("usb2_phy_root_clk", "usb_phy_ref",
>     base + 0x4500, 0));
>     +
>     +       clk_dm(IMX8MQ_CLK_ENET_REF,
>     +              imx8m_clk_composite("enet_ref", imx8mq_enet_ref_sels,
>     +                                  base + 0xa980));
>     +       clk_dm(IMX8MQ_CLK_ENET_TIMER,
>     +              imx8m_clk_composite("enet_timer", imx8mq_enet_timer_sels,
>     +                                  base + 0xaa00));
>     +       clk_dm(IMX8MQ_CLK_ENET_PHY_REF,
>     +              imx8m_clk_composite("enet_phy", imx8mq_enet_phy_sels,
>     +                                  base + 0xaa80));
>     +       clk_dm(IMX8MQ_CLK_ENET1_ROOT,
>     +              imx_clk_gate4("enet1_root_clk", "enet_axi",
>     +                            base + 0x40a0, 0));
>     +
>     +       return 0;
>     +}
>     +
>     +static const struct udevice_id imx8mq_clk_ids[] = {
>     +       { .compatible = "fsl,imx8mq-ccm" },
>     +       { },
>     +};
>     +
>     +U_BOOT_DRIVER(imx8mq_clk) = {
>     +       .name = "clk_imx8mq",
>     +       .id = UCLASS_CLK,
>     +       .of_match = imx8mq_clk_ids,
>     +       .ops = &imx8mq_clk_ops,
>     +       .probe = imx8mq_clk_probe,
>     +       .flags = DM_FLAG_PRE_RELOC,
>     +};
>     -- 
>     2.25.1
> 
> 
> when adding this patch and enabling CLK_IMX8MQ I see the following on my 
> board .. Any idea what I missed here?
> 
> --- >8 ---
> U-Boot SPL 2022.04-rc4-00008-g390d9bf9a1 (Mar 15 2022 - 16:26:59 +0100)
> Trying to boot from SD card
> 
> 
> U-Boot 2022.04-rc4-00008-g390d9bf9a1 (Mar 15 2022 - 16:26:59 +0100)
> 
> CPU:   Freescale i.MX8MQ rev2.1 at 800 MHz
> Reset cause: POR
> Model: Kontron pITX-imx8m
> DRAM:  alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted
> alloc space exhausted

There maybe not enough space with MALLOC_F_LEN

Regards,
Peng.

> 4 GiB
> clk_register: failed to get <NULL> device (parent of ckil)
> clk_register: failed to get <NULL> device (parent of sys1_pll)
> clk_register: failed to get <NULL> device (parent of sys2_pll)
> clk_register: failed to get <NULL> device (parent of sys3_pll)
> No serial driver found
> resetting ...
> 
> --- >8 ---
> 
> -- 
> Heiko

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-16 15:55                   ` Heiko Thiery
  2022-03-16 16:00                     ` Angus Ainslie
@ 2022-03-21  1:38                     ` Peng Fan (OSS)
  1 sibling, 0 replies; 26+ messages in thread
From: Peng Fan (OSS) @ 2022-03-21  1:38 UTC (permalink / raw)
  To: Heiko Thiery, Angus Ainslie
  Cc: Angus Ainslie, u-boot, Marek Vasut, lukma, seanga2, sbabic,
	festevam, kernel, dl-uboot-imx, Peng Fan, Michael Walle



On 2022/3/16 23:55, Heiko Thiery wrote:
> Hi Angus,
> 
> [snip]
>>>> But then something went wrong when probing uart3 ... the baudrate
>>>> switched for the uart2 (console) and the serial output became broken.
>>>> Later when the kernel starts the output becomes correct again. So the
>>>> kernel seems to configure it correctly.
>>>>
>>>> see here: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpastebin.com%2Fraw%2FqXVShb3Q&amp;data=04%7C01%7Cpeng.fan%40nxp.com%7C7f70ec10fbe643a9dc8808da07656eef%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637830429481235934%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=KYnwAT%2Bw2Vnc559Ff3QYcqjKCjpEo6mdG8lyzaeGBZo%3D&amp;reserved=0
>>>>
>>>> When I remove the "assigned-clock-parents = <&clk
>>>> IMX8MQ_SYS1_PLL_80M>;" for uart3 the output of uart2 (console) keeps
>>>> ok.
>>>
>>> If that "fixes" it then it means that the parent IMX8MQ_SYS1_PLL_80M
>>> clock rate is getting changed by the uart3 stanza.
>>>
>>> Are you using the mainline devicetree file for your board ? If not could
>>> you provide a link ?
>>
>> I use the mainline u-boot/linux one.
> 
> We (thanks to Michael) found the issue. For the imx8mq the
> imx_get_uartclk() returns always the values for UART1_CLK_ROOT [1].
> This is wrong. Here we have to get the value dependent on the used
> UART.

Yes, this needs to be fixed! Previously in U-Boot, we suppose
people not configure CCM for Uart, so all uart works at 25M OSC
if not configure CCM to other mux. Since you have CLK DM with
assigned clock parents, so this needs update.

Regards,
Peng.

> 
> [1] https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.denx.de%2Fu-boot%2Fu-boot%2F-%2Fblob%2Fmaster%2Farch%2Farm%2Fmach-imx%2Fimx8m%2Fclock_imx8mq.c%23L381&amp;data=04%7C01%7Cpeng.fan%40nxp.com%7C7f70ec10fbe643a9dc8808da07656eef%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637830429481235934%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=e8CrijnqZVy2P8aVViYeiZm8jJcD6NjLqAhIriJRrt8%3D&amp;reserved=0
> 

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-15 13:08 ` [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq Angus Ainslie
                     ` (2 preceding siblings ...)
  2022-03-20 23:57   ` Sean Anderson
@ 2022-03-24  8:28   ` Heiko Thiery
  2022-03-24 12:06     ` Angus Ainslie
  3 siblings, 1 reply; 26+ messages in thread
From: Heiko Thiery @ 2022-03-24  8:28 UTC (permalink / raw)
  To: Angus Ainslie
  Cc: u-boot, Marek Vasut, lukma, seanga2, sbabic, festevam, kernel,
	uboot-imx, peng.fan

Hi Angus,

could you include the UART clocks?

Am Di., 15. März 2022 um 14:09 Uhr schrieb Angus Ainslie <angus@akkea.ca>:
>
> This is a DM clock driver based off the imx8mm u-boot driver and the linux
> kernel driver.
>
> All of the PLLs and clocks are initialized so the subsystems below are
> functional and tested.
>
> 1) USB host and peripheral
> 2) ECSPI
> 3) UART
> 4) I2C all busses
> 5) USDHC for eMMC support
> 6) USB storage
> 7) GPIO
> 8) DRAM
>
> Signed-off-by: Angus Ainslie <angus@akkea.ca>
> ---

Could you include the UART clocks? Or should I wait until your patch
is accepted and then send this one after?

diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
index c3b685dbaa..b2d92f4776 100644
--- a/drivers/clk/imx/clk-imx8mq.c
+++ b/drivers/clk/imx/clk-imx8mq.c
@@ -82,6 +82,23 @@ static const char *imx8mq_i2c4_sels[] =
{"clock-osc-25m", "sys_pll1_160m", "sys_
                                         "sys_pll3_out",
"audio_pll1_out", "video_pll1_out",
                                         "audio_pll2_out", "sys_pll1_133m", };

+static const char * const imx8mq_uart1_sels[] = {"clock-osc-25m",
"sys_pll1_80m", "sys_pll2_200m",
+                                                "sys_pll2_100m",
"sys_pll3_out", "clk_ext2",
+                                                "clk_ext4",
"audio_pll2_out", };
+
+static const char * const imx8mq_uart2_sels[] = {"clock-osc-25m",
"sys_pll1_80m", "sys_pll2_200m",
+                                                "sys_pll2_100m",
"sys_pll3_out", "clk_ext2",
+                                                "clk_ext3",
"audio_pll2_out", };
+
+static const char * const imx8mq_uart3_sels[] = {"clock-osc-25m",
"sys_pll1_80m", "sys_pll2_200m",
+                                                "sys_pll2_100m",
"sys_pll3_out", "clk_ext2",
+                                                "clk_ext4",
"audio_pll2_out", };
+
+static const char * const imx8mq_uart4_sels[] = {"clock-osc-25m",
"sys_pll1_80m", "sys_pll2_200m",
+                                                "sys_pll2_100m",
"sys_pll3_out", "clk_ext2",
+                                                "clk_ext3",
"audio_pll2_out", };
+
+
 static const char *imx8mq_wdog_sels[] = {"clock-osc-25m",
"sys_pll1_133m", "sys_pll1_160m",
                                         "vpu_pll_out",
"sys_pll2_125m", "sys_pll3_out",
                                         "sys_pll1_80m", "sys_pll2_166m", };
@@ -358,6 +375,16 @@ static int imx8mq_clk_probe(struct udevice *dev)
               imx8m_clk_composite("i2c3", imx8mq_i2c3_sels, base + 0xae00));
        clk_dm(IMX8MQ_CLK_I2C4,
               imx8m_clk_composite("i2c4", imx8mq_i2c4_sels, base + 0xae80));
+
+       clk_dm(IMX8MQ_CLK_UART1,
+              imx8m_clk_composite("uart1", imx8mq_uart1_sels, base + 0xaf00));
+       clk_dm(IMX8MQ_CLK_UART2,
+              imx8m_clk_composite("uart2", imx8mq_uart2_sels, base + 0xaf80));
+       clk_dm(IMX8MQ_CLK_UART3,
+              imx8m_clk_composite("uart3", imx8mq_uart3_sels, base + 0xb000));
+       clk_dm(IMX8MQ_CLK_UART4,
+              imx8m_clk_composite("uart4", imx8mq_uart4_sels, base + 0xb080));
+
        clk_dm(IMX8MQ_CLK_WDOG,
               imx8m_clk_composite("wdog", imx8mq_wdog_sels, base + 0xb900));
        clk_dm(IMX8MQ_CLK_QSPI,
@@ -387,6 +414,16 @@ static int imx8mq_clk_probe(struct udevice *dev)
               imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0));
        clk_dm(IMX8MQ_CLK_I2C4_ROOT,
               imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0));
+
+       clk_dm(IMX8MQ_CLK_UART1_ROOT,
+              imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0));
+       clk_dm(IMX8MQ_CLK_UART2_ROOT,
+              imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0));
+       clk_dm(IMX8MQ_CLK_UART3_ROOT,
+              imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0));
+       clk_dm(IMX8MQ_CLK_UART4_ROOT,
+              imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0));
+
        clk_dm(IMX8MQ_CLK_OCOTP_ROOT,
               imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0));
        clk_dm(IMX8MQ_CLK_USDHC1_ROOT,

[SNIP]

-- 
Heiko

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

* Re: [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq
  2022-03-24  8:28   ` Heiko Thiery
@ 2022-03-24 12:06     ` Angus Ainslie
  0 siblings, 0 replies; 26+ messages in thread
From: Angus Ainslie @ 2022-03-24 12:06 UTC (permalink / raw)
  To: Heiko Thiery, Angus Ainslie
  Cc: u-boot, Marek Vasut, lukma, seanga2, sbabic, festevam, kernel,
	uboot-imx, peng.fan

Hi Heiko,

On 2022-03-24 01:28, Heiko Thiery wrote:
> Hi Angus,
>
> could you include the UART clocks?

Sure I can add the UART clocks.

We've also found an issue with devfreq using the current setup so it 
might be a few days before I send an update.

Angus


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

end of thread, other threads:[~2022-03-24 12:07 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-15 13:08 [PATCH v4 0/4] Add a clock driver for the imx8mq Angus Ainslie
2022-03-15 13:08 ` [PATCH v4 1/4] dt-bindings: imx8mq-clock: add mainline definitions Angus Ainslie
2022-03-15 13:08 ` [PATCH v4 2/4] clk: imx8mq: Add a clock driver for the imx8mq Angus Ainslie
2022-03-15 15:12   ` Heiko Thiery
2022-03-15 15:35   ` Heiko Thiery
2022-03-15 15:46     ` Angus Ainslie
2022-03-15 16:13       ` Angus Ainslie
2022-03-16  7:14       ` Heiko Thiery
2022-03-16 12:26         ` Heiko Thiery
2022-03-16 12:35           ` Angus Ainslie
2022-03-16 14:02             ` Heiko Thiery
2022-03-16 14:15               ` Angus Ainslie
2022-03-16 14:21                 ` Heiko Thiery
2022-03-16 15:55                   ` Heiko Thiery
2022-03-16 16:00                     ` Angus Ainslie
2022-03-16 16:20                       ` Michael Walle
2022-03-21  1:38                     ` Peng Fan (OSS)
2022-03-15 19:01     ` Marek Vasut
2022-03-16  7:02       ` Heiko Thiery
2022-03-21  1:32     ` Peng Fan (OSS)
2022-03-20 23:57   ` Sean Anderson
2022-03-24  8:28   ` Heiko Thiery
2022-03-24 12:06     ` Angus Ainslie
2022-03-15 13:08 ` [PATCH v4 3/4] clk: imx8m: reduce rate table duplication Angus Ainslie
2022-03-15 13:08 ` [PATCH v4 4/4] clk: imx8m: remove code duplication Angus Ainslie
2022-03-20 23:58   ` Sean Anderson

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.