From 69365540cf607d5212ebd014869e4f55c1de8044 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Sat, 16 May 2020 22:34:19 +0200 Subject: [PATCH 1/3] cpu: imx8: fix type and rate detection CPU type and rate detection is broken, for A35 cpu we get A53: ... sc_pm_get_clock_rate: resource:0 clk:2: res:3 Could not read CPU frequency: -22 CPU: NXP i.MX8QXP RevB A53 at 0 MHz at 47C Fixes: 55bc96f3b675 ("cpu: imx8: fix get core name and rate") Signed-off-by: Anatolij Gustschin Reviewed-by: Peng Fan --- drivers/cpu/imx8_cpu.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index dddd12d1e4..8b297b2b0f 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -54,11 +54,11 @@ const char *get_imx8_rev(u32 rev) const char *get_core_name(struct udevice *dev) { - if (!device_is_compatible(dev, "arm,cortex-a35")) + if (device_is_compatible(dev, "arm,cortex-a35")) return "A35"; - else if (!device_is_compatible(dev, "arm,cortex-a53")) + else if (device_is_compatible(dev, "arm,cortex-a53")) return "A53"; - else if (!device_is_compatible(dev, "arm,cortex-a72")) + else if (device_is_compatible(dev, "arm,cortex-a72")) return "A72"; else return "?"; @@ -185,11 +185,11 @@ static ulong imx8_get_cpu_rate(struct udevice *dev) ulong rate; int ret, type; - if (!device_is_compatible(dev, "arm,cortex-a35")) + if (device_is_compatible(dev, "arm,cortex-a35")) type = SC_R_A35; - else if (!device_is_compatible(dev, "arm,cortex-a53")) + else if (device_is_compatible(dev, "arm,cortex-a53")) type = SC_R_A53; - else if (!device_is_compatible(dev, "arm,cortex-a72")) + else if (device_is_compatible(dev, "arm,cortex-a72")) type = SC_R_A72; else return 0; From 74e8fb03bdafd096bcfaa36268376874dfb5c7d4 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Wed, 20 May 2020 01:31:44 +0200 Subject: [PATCH 2/3] cpu: imx8: use intended cpu-thermal device when getting temp value This fixes getting DT alert and critical pdata values in imx_scu_thermal driver. On i.MX8QXP using not initialized alert pdata value resulted in boot hang and endless loop outputting: CPU Temperature (47200C) has beyond alert (0C), close to critical (0C) waiting... While at it, preset CPU type values once to avoid multiple calls of device_is_compatible() for same property. Fixes: 3ee6ea443eb4 ("cpu: imx_cpu: Print the CPU temperature for iMX8QM A72") Signed-off-by: Anatolij Gustschin Reviewed-by: Peng Fan --- drivers/cpu/imx8_cpu.c | 50 +++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index 8b297b2b0f..6345cd0815 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -20,6 +20,7 @@ struct cpu_imx_platdata { const char *name; const char *rev; const char *type; + u32 cpu_rsrc; u32 cpurev; u32 freq_mhz; u32 mpidr; @@ -52,16 +53,23 @@ const char *get_imx8_rev(u32 rev) } } -const char *get_core_name(struct udevice *dev) +static void set_core_data(struct udevice *dev) { - if (device_is_compatible(dev, "arm,cortex-a35")) - return "A35"; - else if (device_is_compatible(dev, "arm,cortex-a53")) - return "A53"; - else if (device_is_compatible(dev, "arm,cortex-a72")) - return "A72"; - else - return "?"; + struct cpu_imx_platdata *plat = dev_get_platdata(dev); + + if (device_is_compatible(dev, "arm,cortex-a35")) { + plat->cpu_rsrc = SC_R_A35; + plat->name = "A35"; + } else if (device_is_compatible(dev, "arm,cortex-a53")) { + plat->cpu_rsrc = SC_R_A53; + plat->name = "A53"; + } else if (device_is_compatible(dev, "arm,cortex-a72")) { + plat->cpu_rsrc = SC_R_A72; + plat->name = "A72"; + } else { + plat->cpu_rsrc = SC_R_A53; + plat->name = "?"; + } } #if IS_ENABLED(CONFIG_IMX_SCU_THERMAL) @@ -69,12 +77,12 @@ static int cpu_imx_get_temp(struct cpu_imx_platdata *plat) { struct udevice *thermal_dev; int cpu_tmp, ret; + int idx = 1; /* use "cpu-thermal0" device */ - if (!strcmp(plat->name, "A72")) - ret = uclass_get_device(UCLASS_THERMAL, 1, &thermal_dev); - else - ret = uclass_get_device(UCLASS_THERMAL, 0, &thermal_dev); + if (plat->cpu_rsrc == SC_R_A72) + idx = 2; /* use "cpu-thermal1" device */ + ret = uclass_get_device(UCLASS_THERMAL, idx, &thermal_dev); if (!ret) { ret = thermal_get_temp(thermal_dev, &cpu_tmp); if (ret) @@ -182,19 +190,11 @@ static const struct udevice_id cpu_imx8_ids[] = { static ulong imx8_get_cpu_rate(struct udevice *dev) { + struct cpu_imx_platdata *plat = dev_get_platdata(dev); ulong rate; - int ret, type; + int ret; - if (device_is_compatible(dev, "arm,cortex-a35")) - type = SC_R_A35; - else if (device_is_compatible(dev, "arm,cortex-a53")) - type = SC_R_A53; - else if (device_is_compatible(dev, "arm,cortex-a72")) - type = SC_R_A72; - else - return 0; - - ret = sc_pm_get_clock_rate(-1, type, SC_PM_CLK_CPU, + ret = sc_pm_get_clock_rate(-1, plat->cpu_rsrc, SC_PM_CLK_CPU, (sc_pm_clock_rate_t *)&rate); if (ret) { printf("Could not read CPU frequency: %d\n", ret); @@ -209,9 +209,9 @@ static int imx8_cpu_probe(struct udevice *dev) struct cpu_imx_platdata *plat = dev_get_platdata(dev); u32 cpurev; + set_core_data(dev); cpurev = get_cpu_rev(); plat->cpurev = cpurev; - plat->name = get_core_name(dev); plat->rev = get_imx8_rev(cpurev & 0xFFF); plat->type = get_imx8_type((cpurev & 0xFF000) >> 12); plat->freq_mhz = imx8_get_cpu_rate(dev) / 1000000; From 4e7413a998ba5666aa4ee0b4f49789f52b1281b1 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Wed, 20 May 2020 10:21:53 +0200 Subject: [PATCH 3/3] thermal: imx_scu_thermal: prevent boot hang with zero pdata Should initialization of pdata values have failed for some reason, we end up in endless loop when getting the CPU temperature value and can not boot. Check alert value in pdata and only retry reading temperature if alert value is not zero. Also shorten the temperature info string. Signed-off-by: Anatolij Gustschin --- drivers/thermal/imx_scu_thermal.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/imx_scu_thermal.c b/drivers/thermal/imx_scu_thermal.c index 321f905e3a..83ec753802 100644 --- a/drivers/thermal/imx_scu_thermal.c +++ b/drivers/thermal/imx_scu_thermal.c @@ -61,13 +61,15 @@ int imx_sc_thermal_get_temp(struct udevice *dev, int *temp) return ret; while (cpu_temp >= pdata->alert) { - printf("CPU Temperature (%dC) has beyond alert (%dC), close to critical (%dC)", + printf("CPU Temperature (%dC) beyond alert (%dC), close to critical (%dC)", cpu_temp, pdata->alert, pdata->critical); puts(" waiting...\n"); mdelay(pdata->polling_delay); ret = read_temperature(dev, &cpu_temp); if (ret) return ret; + if (cpu_temp >= pdata->alert && !pdata->alert) + break; } *temp = cpu_temp / 1000;