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

Add CPU_IMX Kconfig
Support imx8_cpu driver for i.MX9

Signed-off-by: Peng Fan <peng....@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

Reply via email to