diff options
author | Tom Rini <trini@konsulko.com> | 2023-06-12 14:55:33 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-06-12 14:55:33 -0400 |
commit | 260d4962e06c0a7d2713523c131416a3f70d7f2c (patch) | |
tree | 14b9d414810e97f1ffdfdaf099db57a5bbf45a79 /drivers/cpu/imx8_cpu.c | |
parent | 5b589e139620214f26eb83c9fb7bbd62b5f8fc1d (diff) | |
parent | 19b77d3d23966a0d6dbb3c86187765f11100fb6f (diff) |
Merge tag v2023.07-rc4 into next
Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'drivers/cpu/imx8_cpu.c')
-rw-r--r-- | drivers/cpu/imx8_cpu.c | 142 |
1 files changed, 108 insertions, 34 deletions
diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index b8eb2d28006..98ff95f5ff5 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -9,11 +9,13 @@ #include <thermal.h> #include <asm/global_data.h> #include <asm/system.h> -#include <asm/arch/sci/sci.h> +#include <firmware/imx/sci/sci.h> #include <asm/arch/sys_proto.h> #include <asm/arch-imx/cpu.h> #include <asm/armv8/cpu.h> +#include <imx_thermal.h> #include <linux/bitops.h> +#include <linux/clk-provider.h> DECLARE_GLOBAL_DATA_PTR; @@ -27,30 +29,57 @@ struct cpu_imx_plat { u32 mpidr; }; -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 */ + case MXC_CPU_IMX9351: + return "93(51)";/* iMX93 Single core with NPU */ + case MXC_CPU_IMX9332: + return "93(32)";/* iMX93 Dual core without NPU */ + case MXC_CPU_IMX9331: + return "93(31)";/* iMX93 Single core without NPU */ + case MXC_CPU_IMX9322: + return "93(22)";/* iMX93 9x9 Dual core */ + case MXC_CPU_IMX9321: + return "93(21)";/* iMX93 9x9 Single core */ + case MXC_CPU_IMX9312: + return "93(12)";/* iMX93 9x9 Dual core without NPU */ + case MXC_CPU_IMX9311: + return "93(11)";/* iMX93 9x9 Single core without NPU */ default: return "??"; } } -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,21 +96,27 @@ 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 = "?"; } } -#if IS_ENABLED(CONFIG_IMX_SCU_THERMAL) +#if IS_ENABLED(CONFIG_DM_THERMAL) static int cpu_imx_get_temp(struct cpu_imx_plat *plat) { struct udevice *thermal_dev; int cpu_tmp, ret; int idx = 1; /* use "cpu-thermal0" device */ - if (plat->cpu_rsrc == SC_R_A72) - idx = 2; /* use "cpu-thermal1" device */ + if (IS_ENABLED(CONFIG_IMX8)) { + if (plat->cpu_rsrc == SC_R_A72) + idx = 2; /* use "cpu-thermal1" device */ + } else { + idx = 1; + } ret = uclass_get_device(UCLASS_THERMAL, idx, &thermal_dev); if (!ret) { @@ -101,18 +136,46 @@ static int cpu_imx_get_temp(struct cpu_imx_plat *plat) } #endif -int cpu_imx_get_desc(const struct udevice *dev, char *buf, int size) +__weak u32 get_cpu_temp_grade(int *minc, int *maxc) +{ + return 0; +} + +static int cpu_imx_get_desc(const struct udevice *dev, char *buf, int size) { struct cpu_imx_plat *plat = dev_get_plat(dev); + const char *grade; int ret, temp; + int minc, maxc; 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)) { + if (IS_ENABLED(CONFIG_IMX9)) { + switch (get_cpu_temp_grade(&minc, &maxc)) { + case TEMP_AUTOMOTIVE: + grade = "Automotive temperature grade "; + break; + case TEMP_INDUSTRIAL: + grade = "Industrial temperature grade "; + break; + case TEMP_EXTCOMMERCIAL: + grade = "Extended Consumer temperature grade "; + break; + default: + grade = "Consumer temperature grade "; + break; + } + + buf = buf + ret; + size = size - ret; + ret = snprintf(buf, size, "\nCPU: %s (%dC to %dC)", grade, minc, maxc); + } + + if (IS_ENABLED(CONFIG_DM_THERMAL)) { temp = cpu_imx_get_temp(plat); buf = buf + ret; size = size - ret; @@ -174,7 +237,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 +245,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 +279,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 +287,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 +299,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, }; |