thermal: cooldev: update cpucore cooldev for multi cluster chip [1/1]
authorHuan Biao <huan.biao@amlogic.com>
Mon, 4 Mar 2019 05:45:05 +0000 (13:45 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Thu, 14 Mar 2019 07:28:17 +0000 (23:28 -0800)
PD#SWPL-5366

Problem:
g12b cpucore cooling devices hotplug a little core and a big
when hot trippoint trigger, need to update cooling devices that
hotplug one core one hotstep for big core to little core.

Solution:
1.modify cpucore cooling for new solution.
2.modify hotplug core for can hotplug all big core.
3.ipa dts no cluster id, all cpucore is one cooling device
  dts have cluster id, one cluster is one cooling devices.

Verify:
test on g12b w400.

Change-Id: I3320b007e35e7ac415cf7623f74f0a5153fed9b5
Signed-off-by: Huan Biao <huan.biao@amlogic.com>
arch/arm/boot/dts/amlogic/mesong12b.dtsi
arch/arm/boot/dts/amlogic/mesong12b_a.dtsi
arch/arm64/boot/dts/amlogic/mesong12b.dtsi
arch/arm64/boot/dts/amlogic/mesong12b_a.dtsi
drivers/amlogic/cpu_hotplug/cpu_hotplug.c
drivers/amlogic/thermal/cpucore_cooling.c
drivers/amlogic/thermal/meson_cooldev.c
include/linux/amlogic/cpucore_cooling.h

index 558797f..07e019d 100644 (file)
                                        node_name = "cpufreq_cool1";
                                        device_type = "cpufreq";
                                };
-                               cpucore_cool_cluster0 {
+                               cpucore_cool_cluster {
                                        min_state = <1>;
                                        dyn_coeff = <0>;
-                                       cluster_id = <0>;
-                                       gpu_pp = <2>;
-                                       node_name = "cpucore_cool0";
-                                       device_type = "cpucore";
-                               };
-                               cpucore_cool_cluster1 {
-                                       min_state = <0>;
-                                       dyn_coeff = <0>;
-                                       cluster_id = <1>;
                                        gpu_pp = <2>;
-                                       node_name = "cpucore_cool1";
+                                       node_name = "cpucore_cool";
                                        device_type = "cpucore";
                                };
                                gpufreq_cool {
                        cpufreq_cool1:cpufreq_cool1 {
                                #cooling-cells = <2>; /* min followed by max */
                        };
-                       cpucore_cool0:cpucore_cool0 {
-                               #cooling-cells = <2>; /* min followed by max */
-                       };
-                       cpucore_cool1:cpucore_cool1 {
+                       cpucore_cool:cpucore_cool {
                                #cooling-cells = <2>; /* min followed by max */
                        };
                        gpufreq_cool0:gpufreq_cool0 {
                                        cooling-device = <&cpufreq_cool1 0 9>;
                                        contribution = <1024>;
                                };
-                               cpucore_cooling_map0 {
-                                       trip = <&pcontrol>;
-                                       cooling-device = <&cpucore_cool0 0 1>;
-                                       contribution = <1024>;
-                               };
-                               cpucore_cooling_map1 {
+                               cpucore_cooling_map {
                                        trip = <&pcontrol>;
-                                       cooling-device = <&cpucore_cool1 0 4>;
+                                       cooling-device = <&cpucore_cool 0 5>;
                                        contribution = <1024>;
                                };
                                gpufreq_cooling_map {
index a397cf8..4adebb6 100644 (file)
                                        node_name = "cpufreq_cool1";
                                        device_type = "cpufreq";
                                };
-                               cpucore_cool_cluster0 {
+                               cpucore_cool_cluster {
                                        min_state = <1>;
                                        dyn_coeff = <0>;
-                                       cluster_id = <0>;
-                                       gpu_pp = <2>;
-                                       node_name = "cpucore_cool0";
-                                       device_type = "cpucore";
-                               };
-                               cpucore_cool_cluster1 {
-                                       min_state = <0>;
-                                       dyn_coeff = <0>;
-                                       cluster_id = <1>;
                                        gpu_pp = <2>;
-                                       node_name = "cpucore_cool1";
+                                       node_name = "cpucore_cool";
                                        device_type = "cpucore";
                                };
                                gpufreq_cool {
                        cpufreq_cool1:cpufreq_cool1 {
                                #cooling-cells = <2>; /* min followed by max */
                        };
-                       cpucore_cool0:cpucore_cool0 {
-                               #cooling-cells = <2>; /* min followed by max */
-                       };
-                       cpucore_cool1:cpucore_cool1 {
+                       cpucore_cool:cpucore_cool {
                                #cooling-cells = <2>; /* min followed by max */
                        };
                        gpufreq_cool0:gpufreq_cool0 {
                                        cooling-device = <&cpufreq_cool1 0 9>;
                                        contribution = <1024>;
                                };
-                               cpucore_cooling_map0 {
-                                       trip = <&pcontrol>;
-                                       cooling-device = <&cpucore_cool0 0 1>;
-                                       contribution = <1024>;
-                               };
-                               cpucore_cooling_map1 {
+                               cpucore_cooling_map {
                                        trip = <&pcontrol>;
-                                       cooling-device = <&cpucore_cool1 0 4>;
+                                       cooling-device = <&cpucore_cool 0 5>;
                                        contribution = <1024>;
                                };
                                gpufreq_cooling_map {
index 40935e5..afbf50e 100644 (file)
                                        node_name = "cpufreq_cool1";
                                        device_type = "cpufreq";
                                };
-                               cpucore_cool_cluster0 {
+                               cpucore_cool_cluster {
                                        min_state = <1>;
                                        dyn_coeff = <0>;
-                                       cluster_id = <0>;
-                                       gpu_pp = <2>;
-                                       node_name = "cpucore_cool0";
-                                       device_type = "cpucore";
-                               };
-                               cpucore_cool_cluster1 {
-                                       min_state = <0>;
-                                       dyn_coeff = <0>;
-                                       cluster_id = <1>;
                                        gpu_pp = <2>;
-                                       node_name = "cpucore_cool1";
+                                       node_name = "cpucore_cool";
                                        device_type = "cpucore";
                                };
                                gpufreq_cool {
                        cpufreq_cool1:cpufreq_cool1 {
                                #cooling-cells = <2>; /* min followed by max */
                        };
-                       cpucore_cool0:cpucore_cool0 {
-                               #cooling-cells = <2>; /* min followed by max */
-                       };
-                       cpucore_cool1:cpucore_cool1 {
+                       cpucore_cool:cpucore_cool {
                                #cooling-cells = <2>; /* min followed by max */
                        };
                        gpufreq_cool0:gpufreq_cool0 {
                                };
                                cpucore_cooling_map0 {
                                        trip = <&pcontrol>;
-                                       cooling-device = <&cpucore_cool0 0 1>;
-                                       contribution = <1024>;
-                               };
-                               cpucore_cooling_map1 {
-                                       trip = <&pcontrol>;
-                                       cooling-device = <&cpucore_cool1 0 4>;
+                                       cooling-device = <&cpucore_cool 0 5>;
                                        contribution = <1024>;
                                };
                                gpufreq_cooling_map {
index d76692b..3529767 100644 (file)
                                        node_name = "cpufreq_cool1";
                                        device_type = "cpufreq";
                                };
-                               cpucore_cool_cluster0 {
+                               cpucore_cool_cluster {
                                        min_state = <1>;
                                        dyn_coeff = <0>;
-                                       cluster_id = <0>;
-                                       gpu_pp = <2>;
-                                       node_name = "cpucore_cool0";
-                                       device_type = "cpucore";
-                               };
-                               cpucore_cool_cluster1 {
-                                       min_state = <0>;
-                                       dyn_coeff = <0>;
-                                       cluster_id = <1>;
                                        gpu_pp = <2>;
-                                       node_name = "cpucore_cool1";
+                                       node_name = "cpucore_cool";
                                        device_type = "cpucore";
                                };
                                gpufreq_cool {
                        cpufreq_cool1:cpufreq_cool1 {
                                #cooling-cells = <2>; /* min followed by max */
                        };
-                       cpucore_cool0:cpucore_cool0 {
-                               #cooling-cells = <2>; /* min followed by max */
-                       };
-                       cpucore_cool1:cpucore_cool1 {
+                       cpucore_cool:cpucore_cool {
                                #cooling-cells = <2>; /* min followed by max */
                        };
                        gpufreq_cool0:gpufreq_cool0 {
                                        cooling-device = <&cpufreq_cool1 0 9>;
                                        contribution = <1024>;
                                };
-                               cpucore_cooling_map0 {
-                                       trip = <&pcontrol>;
-                                       cooling-device = <&cpucore_cool0 0 1>;
-                                       contribution = <1024>;
-                               };
-                               cpucore_cooling_map1 {
+                               cpucore_cooling_map {
                                        trip = <&pcontrol>;
-                                       cooling-device = <&cpucore_cool1 0 4>;
+                                       cooling-device = <&cpucore_cool 0 5>;
                                        contribution = <1024>;
                                };
                                gpufreq_cooling_map {
index c8cb0d9..8010e88 100644 (file)
@@ -97,7 +97,7 @@ void cpu_hotplug_set_max(unsigned int num, int clustr)
 {
        unsigned int cpu_online;
 
-       if (!num || clustr > hpg.clusters) {
+       if (clustr > hpg.clusters) {
                dev_err(NULL, " %s <:%d %d>\n", __func__, num, clustr);
                return;
        }
@@ -177,7 +177,7 @@ static int __ref cpu_hotplug_thread(void *data)
                                }
                        } else if (flg == CPU_HOTPLUG_UNPLUG) {
                                cnt = 0;
-                               while ((online = cpu_num_online(clustr)) > 1) {
+                               while ((online = cpu_num_online(clustr)) > 0) {
                                        if (online <= hpg.gov_num[clustr] &&
                                                online <= hpg.max_num[clustr])
                                                break;
@@ -200,7 +200,8 @@ static int __ref cpu_hotplug_thread(void *data)
                                                goto clear_cpu;
                                        }
                                        if (!cpu_online(target) ||
-                                       cpumask_first(hpg.cpumask) == target)
+                                       (cpumask_first(hpg.cpumask) == target &&
+                                       clustr == 0))
                                                goto clear_cpu;
                                        device_offline(get_cpu_device(target));
 clear_cpu:
@@ -250,8 +251,7 @@ static ssize_t store_hotplug_max_cpus(struct kobject *kobj,
 
        for (c = 0; c < hpg.clusters; c++)      {
                max = input & 0xff;
-               if (max)
-                       cpu_hotplug_set_max(max, c);
+               cpu_hotplug_set_max(max, c);
                input = input >> 8;
        }
        return count;
index 0b0c7fc..99502fd 100644 (file)
@@ -140,7 +140,7 @@ static int cpucore_set_cur_state(struct thermal_cooling_device *cdev,
                                 unsigned long state)
 {
        struct cpucore_cooling_device *cpucore_device = cdev->devdata;
-       int set_max_num, id;
+       int set_max_num, id, i, core_num;
 
        mutex_lock(&cooling_cpucore_lock);
        if (cpucore_device->stop_flag) {
@@ -156,8 +156,24 @@ static int cpucore_set_cur_state(struct thermal_cooling_device *cdev,
                cpucore_device->cpucore_state = state;
                set_max_num = cpucore_device->max_cpu_core_num - state;
                id = cpucore_device->cluster_id;
-               pr_debug("set max cpu num=%d,state=%ld\n", set_max_num, state);
-               cpufreq_set_max_cpu_num(set_max_num, id);
+               if (id != CLUSTER_FLAG) {
+                       pr_debug("set max cpu num=%d,state=%ld\n",
+                               set_max_num, state);
+                       cpufreq_set_max_cpu_num(set_max_num, id);
+               } else {
+                       for (i = 0; i < MAX_CLUSTER; i++) {
+                               pr_debug("%s, set max num: %d, cluster: %d\n",
+                                       __func__, set_max_num, i);
+                               core_num = cpucore_device->core_num[i];
+                               if (set_max_num < core_num) {
+                                       cpufreq_set_max_cpu_num(set_max_num, i);
+                                       set_max_num = 0;
+                               } else {
+                                       set_max_num = set_max_num - core_num;
+                                       cpufreq_set_max_cpu_num(core_num, i);
+                               }
+                       }
+               }
        }
 
        return 0;
@@ -256,7 +272,7 @@ cpucore_cooling_register(struct device_node *np, int cluster_id)
        struct thermal_cooling_device *cool_dev;
        struct cpucore_cooling_device *cpucore_dev = NULL;
        char dev_name[THERMAL_NAME_LENGTH];
-       int ret = 0, cpu;
+       int ret = 0, cpu, i;
        int cores = 0;
 
        cpucore_dev = kzalloc(sizeof(struct cpucore_cooling_device),
@@ -270,7 +286,8 @@ cpucore_cooling_register(struct device_node *np, int cluster_id)
                return ERR_PTR(-EINVAL);
        }
 
-       if (mc_capable()) {
+       if ((topology_physical_package_id(0) != -1)
+               && (cluster_id != CLUSTER_FLAG)) {
                for_each_possible_cpu(cpu) {
                        if (topology_physical_package_id(cpu) == cluster_id)
                                cores++;
@@ -283,6 +300,17 @@ cpucore_cooling_register(struct device_node *np, int cluster_id)
        snprintf(dev_name, sizeof(dev_name), "thermal-cpucore-%d",
                 cpucore_dev->id);
 
+       if (cluster_id == CLUSTER_FLAG) {
+               for (i = MAX_CLUSTER - 1; i >= 0; i--) {
+                       cores = 0;
+                       for_each_possible_cpu(cpu) {
+                               if (topology_physical_package_id(cpu) == i)
+                                       cores++;
+                       }
+               cpucore_dev->core_num[i] = cores;
+               pr_info("%s, clutser[%d] core num:%d\n", __func__, i, cores);
+               }
+       }
        cool_dev = thermal_of_cooling_device_register(np, dev_name, cpucore_dev,
                                                      &cpucore_cooling_ops);
        if (!cool_dev) {
index db2c9e4..b12bdd9 100644 (file)
@@ -232,7 +232,7 @@ int meson_cooldev_min_update(struct platform_device *pdev, int index)
 
        case COOL_DEV_TYPE_CPU_FREQ:
                for_each_possible_cpu(cpu) {
-                       if (mc_capable())
+                       if (topology_physical_package_id(0) != -1)
                                c_id = topology_physical_package_id(cpu);
                        else
                                c_id = 0; /* force cluster 0 if no MC */
@@ -349,10 +349,12 @@ static int parse_cool_device(struct platform_device *pdev)
                else
                        cool->gpupp = temp;
 
-               if (of_property_read_u32(child, "cluster_id", &temp))
-                       pr_err("thermal: read cluster_id failed\n");
-               else
+               if (of_property_read_u32(child, "cluster_id", &temp)) {
+                       pr_info("thermal: no cluster id, cpucore as one cooldev\n");
+                       cool->cluster_id = CLUSTER_FLAG;
+               } else {
                        cool->cluster_id = temp;
+               }
 
                if (of_property_read_string(child, "device_type", &str))
                        pr_err("thermal: read device_type failed\n");
index 9039455..4399741 100644 (file)
@@ -20,6 +20,9 @@
 
 #include <linux/thermal.h>
 #include <linux/cpumask.h>
+
+#define MAX_CLUSTER    2
+#define CLUSTER_FLAG    0xF
 struct cpucore_cooling_device {
        int id;
        struct thermal_cooling_device *cool_dev;
@@ -29,6 +32,7 @@ struct cpucore_cooling_device {
        int max_cpu_core_num;
        int cluster_id;
        int stop_flag;
+       int core_num[MAX_CLUSTER];
 };
 #define CPU_STOP 0x80000000
 #ifdef CONFIG_AMLOGIC_CPUCORE_THERMAL