[PATCH 07/42] imx: imx8_cpu: support i.MX9

Peng Fan (OSS) peng.fan at oss.nxp.com
Fri Apr 28 06:08:12 CEST 2023


From: Peng Fan <peng.fan at nxp.com>

Add CPU_IMX Kconfig
Support imx8_cpu driver for i.MX9

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/cpu/Kconfig    |  6 +++
 drivers/cpu/Makefile   |  1 +
 drivers/cpu/imx8_cpu.c | 83 ++++++++++++++++++++++++++++--------------
 3 files changed, 62 insertions(+), 28 deletions(-)

diff --git a/drivers/cpu/Kconfig b/drivers/cpu/Kconfig
index 3bf04105e5e..1c3c810651e 100644
--- a/drivers/cpu/Kconfig
+++ b/drivers/cpu/Kconfig
@@ -7,6 +7,12 @@ config CPU
 	  they can work correctly in the OS. This provides a framework for
 	  finding out information about available CPUs and making changes.
 
+config CPU_IMX
+	bool "Enable i.MX CPU driver"
+	depends on CPU && ARM64
+	help
+	  Support CPU cores for SoCs of the i.MX series.
+
 config CPU_MPC83XX
 	bool "Enable MPC83xx CPU driver"
 	depends on CPU && MPC83xx
diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile
index 3b38ba9c589..d4bbf6fa5e0 100644
--- a/drivers/cpu/Makefile
+++ b/drivers/cpu/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_ARCH_BMIPS) += bmips_cpu.o
 obj-$(CONFIG_ARCH_IMX8) += imx8_cpu.o
 obj-$(CONFIG_ARCH_AT91) += at91_cpu.o
 obj-$(CONFIG_ARCH_MEDIATEK) += mtk_cpu.o
+obj-$(CONFIG_CPU_IMX) += imx8_cpu.o
 obj-$(CONFIG_CPU_MPC83XX) += mpc83xx_cpu.o
 obj-$(CONFIG_CPU_RISCV) += riscv_cpu.o
 obj-$(CONFIG_CPU_MICROBLAZE) += microblaze_cpu.o
diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c
index e7f45e60dbd..2d3df419f1c 100644
--- a/drivers/cpu/imx8_cpu.c
+++ b/drivers/cpu/imx8_cpu.c
@@ -14,6 +14,7 @@
 #include <asm/arch-imx/cpu.h>
 #include <asm/armv8/cpu.h>
 #include <linux/bitops.h>
+#include <linux/clk-provider.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -27,30 +28,43 @@ struct cpu_imx_plat {
 	u32 mpidr;
 };
 
-static const char *get_imx8_type(u32 imxtype)
+static const char *get_imx_type_str(u32 imxtype)
 {
 	switch (imxtype) {
 	case MXC_CPU_IMX8QXP:
 	case MXC_CPU_IMX8QXP_A0:
-		return "QXP";
+		return "8QXP";
 	case MXC_CPU_IMX8QM:
-		return "QM";
+		return "8QM";
+	case MXC_CPU_IMX93:
+		return "93(52)";/* iMX93 Dual core with NPU */
 	default:
 		return "??";
 	}
 }
 
-static const char *get_imx8_rev(u32 rev)
+static const char *get_imx_rev_str(u32 rev)
 {
-	switch (rev) {
-	case CHIP_REV_A:
-		return "A";
-	case CHIP_REV_B:
-		return "B";
-	case CHIP_REV_C:
-		return "C";
-	default:
-		return "?";
+	static char revision[4];
+
+	if (IS_ENABLED(CONFIG_IMX8)) {
+		switch (rev) {
+		case CHIP_REV_A:
+			return "A";
+		case CHIP_REV_B:
+			return "B";
+		case CHIP_REV_C:
+			return "C";
+		default:
+			return "?";
+		}
+	} else {
+		revision[0] = '1' + (((rev & 0xf0) - CHIP_REV_1_0) >> 4);
+		revision[1] = '.';
+		revision[2] = '0' + (rev & 0xf);
+		revision[3] = '\0';
+
+		return revision;
 	}
 }
 
@@ -67,6 +81,8 @@ static void set_core_data(struct udevice *dev)
 	} else if (device_is_compatible(dev, "arm,cortex-a72")) {
 		plat->cpu_rsrc = SC_R_A72;
 		plat->name = "A72";
+	} else if (device_is_compatible(dev, "arm,cortex-a55")) {
+		plat->name = "A55";
 	} else {
 		plat->cpu_rsrc = SC_R_A53;
 		plat->name = "?";
@@ -109,7 +125,7 @@ static int cpu_imx_get_desc(const struct udevice *dev, char *buf, int size)
 	if (size < 100)
 		return -ENOSPC;
 
-	ret = snprintf(buf, size, "NXP i.MX8%s Rev%s %s at %u MHz",
+	ret = snprintf(buf, size, "NXP i.MX%s Rev%s %s at %u MHz",
 		       plat->type, plat->rev, plat->name, plat->freq_mhz);
 
 	if (IS_ENABLED(CONFIG_IMX_SCU_THERMAL)) {
@@ -174,7 +190,7 @@ static int cpu_imx_is_current(struct udevice *dev)
 	return 0;
 }
 
-static const struct cpu_ops cpu_imx8_ops = {
+static const struct cpu_ops cpu_imx_ops = {
 	.get_desc	= cpu_imx_get_desc,
 	.get_info	= cpu_imx_get_info,
 	.get_count	= cpu_imx_get_count,
@@ -182,21 +198,32 @@ static const struct cpu_ops cpu_imx8_ops = {
 	.is_current	= cpu_imx_is_current,
 };
 
-static const struct udevice_id cpu_imx8_ids[] = {
+static const struct udevice_id cpu_imx_ids[] = {
 	{ .compatible = "arm,cortex-a35" },
 	{ .compatible = "arm,cortex-a53" },
+	{ .compatible = "arm,cortex-a55" },
 	{ .compatible = "arm,cortex-a72" },
 	{ }
 };
 
-static ulong imx8_get_cpu_rate(struct udevice *dev)
+static ulong imx_get_cpu_rate(struct udevice *dev)
 {
 	struct cpu_imx_plat *plat = dev_get_plat(dev);
+	struct clk clk;
 	ulong rate;
 	int ret;
 
-	ret = sc_pm_get_clock_rate(-1, plat->cpu_rsrc, SC_PM_CLK_CPU,
-				   (sc_pm_clock_rate_t *)&rate);
+	if (IS_ENABLED(CONFIG_IMX8)) {
+		ret = sc_pm_get_clock_rate(-1, plat->cpu_rsrc, SC_PM_CLK_CPU,
+					   (sc_pm_clock_rate_t *)&rate);
+	} else {
+		ret = clk_get_by_index(dev, 0, &clk);
+		if (!ret) {
+			rate = clk_get_rate(&clk);
+			if (!rate)
+				ret = -EOPNOTSUPP;
+		}
+	}
 	if (ret) {
 		printf("Could not read CPU frequency: %d\n", ret);
 		return 0;
@@ -205,7 +232,7 @@ static ulong imx8_get_cpu_rate(struct udevice *dev)
 	return rate;
 }
 
-static int imx8_cpu_probe(struct udevice *dev)
+static int imx_cpu_probe(struct udevice *dev)
 {
 	struct cpu_imx_plat *plat = dev_get_plat(dev);
 	u32 cpurev;
@@ -213,9 +240,9 @@ static int imx8_cpu_probe(struct udevice *dev)
 	set_core_data(dev);
 	cpurev = get_cpu_rev();
 	plat->cpurev = cpurev;
-	plat->rev = get_imx8_rev(cpurev & 0xFFF);
-	plat->type = get_imx8_type((cpurev & 0xFF000) >> 12);
-	plat->freq_mhz = imx8_get_cpu_rate(dev) / 1000000;
+	plat->rev = get_imx_rev_str(cpurev & 0xFFF);
+	plat->type = get_imx_type_str((cpurev & 0xFF000) >> 12);
+	plat->freq_mhz = imx_get_cpu_rate(dev) / 1000000;
 	plat->mpidr = dev_read_addr(dev);
 	if (plat->mpidr == FDT_ADDR_T_NONE) {
 		printf("%s: Failed to get CPU reg property\n", __func__);
@@ -225,12 +252,12 @@ static int imx8_cpu_probe(struct udevice *dev)
 	return 0;
 }
 
-U_BOOT_DRIVER(cpu_imx8_drv) = {
-	.name		= "imx8x_cpu",
+U_BOOT_DRIVER(cpu_imx_drv) = {
+	.name		= "imx_cpu",
 	.id		= UCLASS_CPU,
-	.of_match	= cpu_imx8_ids,
-	.ops		= &cpu_imx8_ops,
-	.probe		= imx8_cpu_probe,
+	.of_match	= cpu_imx_ids,
+	.ops		= &cpu_imx_ops,
+	.probe		= imx_cpu_probe,
 	.plat_auto	= sizeof(struct cpu_imx_plat),
 	.flags		= DM_FLAG_PRE_RELOC,
 };
-- 
2.40.0



More information about the U-Boot mailing list