cpu: imx8: show RevC instead of Rev? at boot log
[oweals/u-boot.git] / drivers / cpu / imx8_cpu.c
index 95653683ac2ddc99dc4101770709134cf0d91c92..95c14c98d861172da766f3a2939df274eb71a95e 100644 (file)
@@ -20,6 +20,7 @@ struct cpu_imx_platdata {
        const char *type;
        u32 cpurev;
        u32 freq_mhz;
+       u32 mpidr;
 };
 
 const char *get_imx8_type(u32 imxtype)
@@ -42,31 +43,35 @@ const char *get_imx8_rev(u32 rev)
                return "A";
        case CHIP_REV_B:
                return "B";
+       case CHIP_REV_C:
+               return "C";
        default:
                return "?";
        }
 }
 
-const char *get_core_name(void)
+const char *get_core_name(struct udevice *dev)
 {
-       if (is_cortex_a35())
+       if (!device_is_compatible(dev, "arm,cortex-a35"))
                return "A35";
-       else if (is_cortex_a53())
+       else if (!device_is_compatible(dev, "arm,cortex-a53"))
                return "A53";
-       else if (is_cortex_a72())
+       else if (!device_is_compatible(dev, "arm,cortex-a72"))
                return "A72";
        else
                return "?";
 }
 
 #if IS_ENABLED(CONFIG_IMX_SCU_THERMAL)
-static int cpu_imx_get_temp(void)
+static int cpu_imx_get_temp(struct cpu_imx_platdata *plat)
 {
        struct udevice *thermal_dev;
        int cpu_tmp, ret;
 
-       ret = uclass_get_device_by_name(UCLASS_THERMAL, "cpu-thermal0",
-                                       &thermal_dev);
+       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 (!ret) {
                ret = thermal_get_temp(thermal_dev, &cpu_tmp);
@@ -79,7 +84,7 @@ static int cpu_imx_get_temp(void)
        return cpu_tmp;
 }
 #else
-static int cpu_imx_get_temp(void)
+static int cpu_imx_get_temp(struct cpu_imx_platdata *plat)
 {
        return 0;
 }
@@ -88,7 +93,7 @@ static int cpu_imx_get_temp(void)
 int cpu_imx_get_desc(struct udevice *dev, char *buf, int size)
 {
        struct cpu_imx_platdata *plat = dev_get_platdata(dev);
-       int ret;
+       int ret, temp;
 
        if (size < 100)
                return -ENOSPC;
@@ -97,9 +102,13 @@ int cpu_imx_get_desc(struct udevice *dev, char *buf, int size)
                       plat->type, plat->rev, plat->name, plat->freq_mhz);
 
        if (IS_ENABLED(CONFIG_IMX_SCU_THERMAL)) {
+               temp = cpu_imx_get_temp(plat);
                buf = buf + ret;
                size = size - ret;
-               ret = snprintf(buf, size, " at %dC", cpu_imx_get_temp());
+               if (temp != 0xdeadbeef)
+                       ret = snprintf(buf, size, " at %dC", temp);
+               else
+                       ret = snprintf(buf, size, " - invalid sensor data");
        }
 
        snprintf(buf + ret, size - ret, "\n");
@@ -118,7 +127,24 @@ static int cpu_imx_get_info(struct udevice *dev, struct cpu_info *info)
 
 static int cpu_imx_get_count(struct udevice *dev)
 {
-       return 4;
+       ofnode node;
+       int num = 0;
+
+       ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) {
+               const char *device_type;
+
+               if (!ofnode_is_available(node))
+                       continue;
+
+               device_type = ofnode_read_string(node, "device_type");
+               if (!device_type)
+                       continue;
+
+               if (!strcmp(device_type, "cpu"))
+                       num++;
+       }
+
+       return num;
 }
 
 static int cpu_imx_get_vendor(struct udevice *dev,  char *buf, int size)
@@ -127,25 +153,44 @@ static int cpu_imx_get_vendor(struct udevice *dev,  char *buf, int size)
        return 0;
 }
 
+static int cpu_imx_is_current(struct udevice *dev)
+{
+       struct cpu_imx_platdata *plat = dev_get_platdata(dev);
+
+       if (plat->mpidr == (read_mpidr() & 0xffff))
+               return 1;
+
+       return 0;
+}
+
 static const struct cpu_ops cpu_imx8_ops = {
        .get_desc       = cpu_imx_get_desc,
        .get_info       = cpu_imx_get_info,
        .get_count      = cpu_imx_get_count,
        .get_vendor     = cpu_imx_get_vendor,
+       .is_current     = cpu_imx_is_current,
 };
 
 static const struct udevice_id cpu_imx8_ids[] = {
        { .compatible = "arm,cortex-a35" },
        { .compatible = "arm,cortex-a53" },
+       { .compatible = "arm,cortex-a72" },
        { }
 };
 
-static ulong imx8_get_cpu_rate(void)
+static ulong imx8_get_cpu_rate(struct udevice *dev)
 {
        ulong rate;
-       int ret;
-       int type = is_cortex_a35() ? SC_R_A35 : is_cortex_a53() ?
-                  SC_R_A53 : SC_R_A72;
+       int ret, type;
+
+       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,
                                   (sc_pm_clock_rate_t *)&rate);
@@ -164,10 +209,16 @@ static int imx8_cpu_probe(struct udevice *dev)
 
        cpurev = get_cpu_rev();
        plat->cpurev = cpurev;
-       plat->name = get_core_name();
+       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() / 1000000;
+       plat->freq_mhz = imx8_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__);
+               return -EINVAL;
+       }
+
        return 0;
 }