[COMMON] thermal: samsung: Added ECT parsing function
authorHyeonseong Gil <hs.gil@samsung.com>
Fri, 24 Mar 2017 02:02:47 +0000 (11:02 +0900)
committerChungwoo Park <cww.park@samsung.com>
Mon, 21 May 2018 08:18:39 +0000 (17:18 +0900)
Resolved migration conflicts from kernel 4.9 to 4.14.

Change-Id: I565316644978e42ccf1aab7532651701df915185
Signed-off-by: Hyeonseong Gil <hs.gil@samsung.com>
drivers/thermal/cpu_cooling.c
drivers/thermal/gpu_cooling.c
drivers/thermal/isp_cooling.c
drivers/thermal/of-thermal.c
drivers/thermal/samsung/exynos_tmu.c
include/linux/thermal.h

index e4b41a60412478d6d0590e551436d041a10d8e43..62edf361912e5fd13bc1529c1097cce01b0d340f 100644 (file)
@@ -575,6 +575,14 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
        return 0;
 }
 
+static int exynos_cpufreq_cooling_get_level(struct thermal_cooling_device *cdev,
+                                unsigned long value)
+{
+       struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
+
+       return get_level(cpufreq_cdev, value);
+}
+
 /**
  * cpufreq_get_requested_power() - get the current power
  * @cdev:      &thermal_cooling_device pointer
@@ -790,6 +798,7 @@ static struct thermal_cooling_device_ops cpufreq_cooling_ops = {
        .get_max_state = cpufreq_get_max_state,
        .get_cur_state = cpufreq_get_cur_state,
        .set_cur_state = cpufreq_set_cur_state,
+       .get_cooling_level = exynos_cpufreq_cooling_get_level,
 };
 
 static struct thermal_cooling_device_ops cpufreq_power_cooling_ops = {
index d69b494a577ef987211f64dc1cf8f0a324725e6d..e54cf71865ab49a5093c2b45bf2edcd6df998aa5 100644 (file)
@@ -267,7 +267,7 @@ static u32 gpufreq_cooling_get_freq(unsigned int gpu, unsigned long level)
 
        return val;
 }
-EXPORT_SYMBOL_GPL(gpufreq_cooling_get_level);
+EXPORT_SYMBOL_GPL(gpufreq_cooling_get_freq);
 
 /**
  * build_dyn_power_table() - create a dynamic power to frequency table
@@ -635,6 +635,12 @@ static int gpufreq_set_cur_state(struct thermal_cooling_device *cdev,
        return gpufreq_apply_cooling(gpufreq_cdev, state);
 }
 
+static int exynos_gpufreq_cooling_get_level(struct thermal_cooling_device *cdev,
+                                unsigned long value)
+{
+       return gpufreq_cooling_get_level(0, value);
+}
+
 static enum gpu_noti_state_t gpu_tstate = GPU_COLD;
 
 static int gpufreq_set_cur_temp(struct thermal_cooling_device *cdev,
@@ -806,6 +812,7 @@ static struct thermal_cooling_device_ops gpufreq_cooling_ops = {
        .get_cur_state = gpufreq_get_cur_state,
        .set_cur_state = gpufreq_set_cur_state,
        .set_cur_temp = gpufreq_set_cur_temp,
+       .get_cooling_level = exynos_gpufreq_cooling_get_level,
 };
 
 int exynos_gpu_add_notifier(struct notifier_block *n)
@@ -1058,6 +1065,7 @@ static int gpu_cooling_table_init(void)
 
                pr_info("[GPU cooling] index : %d, frequency : %d\n",
                        gpu_freq_table[count].driver_data, gpu_freq_table[count].frequency);
+
                count++;
        }
 
@@ -1078,7 +1086,6 @@ static int __init exynos_gpu_cooling_init(void)
        if (ret) {
                pr_err("Fail to initialize gpu_cooling_table\n");
                return ret;
-
        }
 
        np = of_find_node_by_name(NULL, "mali");
index 0df3cf1f5a5ace3a3f9a0ef521141633c26dbe41..8f2100d0d57445aac1bbd0c81b691aa0e6d969e1 100644 (file)
@@ -217,6 +217,12 @@ unsigned long isp_cooling_get_level(unsigned int isp, unsigned int fps)
 }
 EXPORT_SYMBOL_GPL(isp_cooling_get_level);
 
+static int exynos_isp_cooling_get_level(struct thermal_cooling_device *cdev,
+                                unsigned long value)
+{
+       return isp_cooling_get_level(0, value);
+}
+
 /**
  * isp_cooling_get_fps - for a give isp, return the fps value corresponding to cooling level.
  * @isp: isp for which the level is required
@@ -355,6 +361,7 @@ static struct thermal_cooling_device_ops const isp_cooling_ops = {
        .get_cur_state = isp_get_cur_state,
        .set_cur_state = isp_set_cur_state,
        .set_cur_temp = isp_set_cur_temp,
+       .get_cooling_level = exynos_isp_cooling_get_level,
 };
 
 
index 4ff9bc26970c7ad13bfbc2566d051b8b32dd2719..04c48f5512a8adb1e31e24e2da9263d24af4aa5d 100644 (file)
@@ -191,6 +191,21 @@ static int of_thermal_bind(struct thermal_zone_device *thermal,
                if (tbp->cooling_device == cdev->np) {
                        int ret;
 
+#if defined(CONFIG_EXYNOS_THERMAL)
+                       /* if governor is not power_allocator */
+                       if (strncasecmp(thermal->tzp->governor_name, "power_allocator",
+                                               THERMAL_NAME_LENGTH)) {
+                               unsigned long max_level = 0, level = 0;
+
+                               cdev->ops->get_max_state(cdev, &max_level);
+                               level = cdev->ops->get_cooling_level(cdev, tbp->value);
+
+                               if (level == THERMAL_CSTATE_INVALID)
+                                       level = max_level;
+
+                               tbp->max = level;
+                       }
+#endif
                        ret = thermal_zone_bind_cooling_device(thermal,
                                                tbp->trip_id, cdev,
                                                tbp->max,
index 8ec8450f695ecc8bc12b68f94069cf53018626a8..f7d4a5f39c9453cf1832ddfd2dd907e2228b0876 100644 (file)
@@ -1615,6 +1615,72 @@ static const struct attribute_group exynos_tmu_attr_group = {
        .attrs = exynos_tmu_attrs,
 };
 
+static int exynos_tmu_parse_ect(struct exynos_tmu_data *data)
+{
+       struct thermal_zone_device *tz = data->tzd;
+       struct __thermal_zone *__tz;
+       void *thermal_block;
+       struct ect_ap_thermal_function *function;
+       int i, temperature;
+       int hotplug_threshold_temp = 0, hotplug_flag = 0;
+       unsigned int freq;
+
+       if (!tz)
+               return -EINVAL;
+
+       __tz = (struct __thermal_zone *)tz->devdata;
+
+       thermal_block = ect_get_block(BLOCK_AP_THERMAL);
+       if (thermal_block == NULL) {
+               pr_err("Failed to get thermal block");
+               return -EINVAL;
+       }
+
+       pr_info("%s %d thermal zone_name = %s\n", __func__, __LINE__, tz->type);
+
+       function = ect_ap_thermal_get_function(thermal_block, tz->type);
+       if (function == NULL) {
+               pr_err("Failed to get thermal block %s", tz->type);
+               return -EINVAL;
+       }
+
+       __tz->ntrips = __tz->num_tbps = function->num_of_range;
+       pr_info("Trip count parsed from ECT : %d, zone : %s", function->num_of_range, tz->type);
+
+
+       for (i = 0; i < function->num_of_range; ++i) {
+               temperature = function->range_list[i].lower_bound_temperature;
+               freq = function->range_list[i].max_frequency;
+               __tz->trips[i].temperature = temperature  * MCELSIUS;
+               __tz->tbps[i].value = freq;
+
+               pr_info("Parsed From ECT : [%d] Temperature : %d, frequency : %u\n",
+                       i, temperature, freq);
+
+               if (function->range_list[i].flag != hotplug_flag) {
+                       if (function->range_list[i].flag != hotplug_flag) {
+                               hotplug_threshold_temp = temperature;
+                               hotplug_flag = function->range_list[i].flag;
+                               data->hotplug_out_threshold = temperature;
+
+                               if (i)
+                                       data->hotplug_in_threshold = function->range_list[i-1].lower_bound_temperature;
+
+                               pr_info("[ECT]hotplug_threshold : %d\n", hotplug_threshold_temp);
+                               pr_info("[ECT]hotplug_in_threshold : %d\n", data->hotplug_in_threshold);
+                               pr_info("[ECT]hotplug_out_threshold : %d\n", data->hotplug_out_threshold);
+                       }
+               }
+
+               if (hotplug_threshold_temp != 0)
+                       data->hotplug_enable = true;
+               else
+                       data->hotplug_enable = false;
+
+       }
+       return 0;
+};
+
 #ifdef CONFIG_MALI_DEBUG_KERNEL_SYSFS
 struct exynos_tmu_data *gpu_thermal_data;
 #endif
@@ -1657,6 +1723,10 @@ static int exynos_tmu_probe(struct platform_device *pdev)
                goto err_sensor;
        }
 
+#if defined(CONFIG_ECT)
+       exynos_tmu_parse_ect(data);
+#endif
+
        data->num_probe = (readl(data->base + EXYNOS_TMU_REG_CONTROL1) >> EXYNOS_TMU_NUM_PROBE_SHIFT)
                                & EXYNOS_TMU_NUM_PROBE_MASK;
 
index 1bee5d04cfcea8f267e0a0232609a88069b1a6fe..edb4c69d8b81280561abe241b8af9ecd97306f8f 100644 (file)
@@ -144,7 +144,8 @@ struct thermal_cooling_device_ops {
                           struct thermal_zone_device *, unsigned long, u32 *);
        int (*power2state)(struct thermal_cooling_device *,
                           struct thermal_zone_device *, u32, unsigned long *);
-       int (*set_cur_temp) (struct thermal_cooling_device *, bool, int);
+       int (*set_cur_temp)(struct thermal_cooling_device *, bool, int);
+       int (*get_cooling_level)(struct thermal_cooling_device *, unsigned long);
 };
 
 struct thermal_cooling_device {
@@ -405,6 +406,7 @@ struct thermal_trip {
  * @usage: the percentage (from 0 to 100) of cooling contribution
  * @min: minimum cooling state used at this trip point
  * @max: maximum cooling state used at this trip point
+ * @value: cooling value corresponding to max state
  */
 
 struct __thermal_bind_params {
@@ -413,6 +415,7 @@ struct __thermal_bind_params {
        unsigned int usage;
        unsigned long min;
        unsigned long max;
+       unsigned long value;
 };
 
 /**