[COMMON] thermal: samsung: add limited frequency for power allocator
authorEunseok Choi <es10.choi@samsung.com>
Thu, 23 Nov 2017 15:43:35 +0000 (00:43 +0900)
committerChungwoo Park <cww.park@samsung.com>
Mon, 21 May 2018 08:22:08 +0000 (17:22 +0900)
Change-Id: I73817be52303a29f75e491e11c0902198a5ca316
Signed-off-by: Eunseok Choi <es10.choi@samsung.com>
drivers/thermal/samsung/exynos_acpm_tmu.c
drivers/thermal/samsung/exynos_acpm_tmu.h
drivers/thermal/samsung/exynos_tmu.c
drivers/thermal/samsung/exynos_tmu.h

index 5f90faea08d067c9796be5fc458049a5affe55da..e03707a5985893f21b75341ca458d4550f36fe9b 100644 (file)
@@ -31,7 +31,6 @@
 #include <soc/samsung/acpm_ipc_ctrl.h>
 #include "exynos_acpm_tmu.h"
 
-static bool cold_comp;
 static unsigned int acpm_tmu_ch_num, acpm_tmu_size;
 
 static bool acpm_tmu_test_mode;
@@ -111,15 +110,13 @@ int exynos_acpm_tmu_set_init(struct acpm_tmu_cap *cap)
  *
  * - tz: thermal zone index registered in device tree
  */
-int exynos_acpm_tmu_set_read_temp(int tz, int *cur_temp)
+int exynos_acpm_tmu_set_read_temp(int tz, int *temp, int *stat)
 {
        struct ipc_config config;
        union tmu_ipc_message message;
        int ret;
        unsigned long long before, after, latency;
 
-       *cur_temp = 0;
-
        if (acpm_tmu_test_mode)
                return -1;
 
@@ -149,8 +146,8 @@ int exynos_acpm_tmu_set_read_temp(int tz, int *cur_temp)
                                message.data[3]);
        }
 
-       cold_comp = message.resp.cold;
-       *cur_temp = message.resp.temp;
+       *temp = message.resp.temp;
+       *stat = message.resp.stat;
 
        return 0;
 }
@@ -190,8 +187,6 @@ int exynos_acpm_tmu_set_suspend(void)
                                message.data[3]);
        }
 
-       cold_comp = message.resp.cold;
-
        return 0;
 }
 
index 1243706ffe020444527a39e7e6535e6df7191976..99607087c150eebc4807ca7b84641a6d69241703 100644 (file)
@@ -77,7 +77,7 @@ struct tmu_ipc_request {
  * ---------------------------------------------
  * | temp     |  tz_id   | ret      | type     |
  * ---------------------------------------------
- * |          |          |          | cold     |
+ * |          |          |          | stat     |
  * ---------------------------------------------
  * |          |          |          |          |
  * ---------------------------------------------
@@ -89,7 +89,7 @@ struct tmu_ipc_response {
        s8 ret;
        u8 tzid;
        u8 temp;
-       u8 cold;
+       u8 stat;
        u8 rsvd;
        u8 rsvd2;
        u8 rsvd3;
@@ -108,7 +108,7 @@ struct acpm_tmu_cap {
 };
 
 int exynos_acpm_tmu_set_init(struct acpm_tmu_cap *cap);
-int exynos_acpm_tmu_set_read_temp(int tz, int *temp);
+int exynos_acpm_tmu_set_read_temp(int tz, int *temp, int *stat);
 int exynos_acpm_tmu_set_suspend(void);
 int exynos_acpm_tmu_set_cp_call(void);
 int exynos_acpm_tmu_set_resume(void);
index 6bd064771b3199eb23d2a8d7af90275bae577bdf..966a120d041e2f4c663d516d233cd7e858e2128f 100644 (file)
@@ -725,14 +725,29 @@ static int exynos_tmu_set_emulation(void *drv_data, int temp)
        { return -EINVAL; }
 #endif /* CONFIG_THERMAL_EMULATION */
 
+static bool cpufreq_limited;
+static struct pm_qos_request thermal_cpu_limit_request;
+
 static int exynos9810_tmu_read(struct exynos_tmu_data *data)
 {
-       int temp = 0;
+       int temp = 0, stat = 0;
 
 #ifdef CONFIG_EXYNOS_ACPM_THERMAL
-       exynos_acpm_tmu_set_read_temp(data->tzd->id, &temp);
+       exynos_acpm_tmu_set_read_temp(data->tzd->id, &temp, &stat);
 #endif
 
+       if (data->hotplug_enable) {
+               if ((stat & 0x2) && !cpufreq_limited) {
+                       pm_qos_update_request(&thermal_cpu_limit_request,
+                                       data->limited_frequency);
+                       cpufreq_limited = true;
+               } else if (!(stat & 0x2) && cpufreq_limited) {
+                       pm_qos_update_request(&thermal_cpu_limit_request,
+                                       PM_QOS_CPU_FREQ_MAX_DEFAULT_VALUE);
+                       cpufreq_limited = false;
+               }
+       }
+
        return temp;
 }
 
@@ -1291,7 +1306,7 @@ static int exynos_tmu_parse_ect(struct exynos_tmu_data *data)
                void *block;
                struct ect_pidtm_block *pidtm_block;
                int i, temperature, value;
-               int hotplug_out_threshold = 0, hotplug_in_threshold = 0;
+               int hotplug_out_threshold = 0, hotplug_in_threshold = 0, limited_frequency = 0;
 
                block = ect_get_block(BLOCK_PIDTM);
                if (block == NULL) {
@@ -1362,9 +1377,15 @@ static int exynos_tmu_parse_ect(struct exynos_tmu_data *data)
                        hotplug_in_threshold = value;
                }
 
+               if ((value = exynos_tmu_ect_get_param(pidtm_block, "limited_frequency")) != -1) {
+                       pr_info("Parse from ECT limited_frequency: %d\n", value);
+                       limited_frequency = value;
+               }
+
                if (hotplug_out_threshold != 0 && hotplug_in_threshold != 0) {
                        data->hotplug_out_threshold = hotplug_out_threshold;
                        data->hotplug_in_threshold = hotplug_in_threshold;
+                       data->limited_frequency = limited_frequency;
                        data->hotplug_enable = true;
                } else
                        data->hotplug_enable = false;
@@ -1405,6 +1426,9 @@ static int exynos_tmu_probe(struct platform_device *pdev)
                pm_qos_add_request(&thermal_cpu_hotplug_request,
                                        PM_QOS_CPU_ONLINE_MAX,
                                        PM_QOS_CPU_ONLINE_MAX_DEFAULT_VALUE);
+               pm_qos_add_request(&thermal_cpu_limit_request,
+                                       PM_QOS_CLUSTER1_FREQ_MAX,
+                                       PM_QOS_CPU_FREQ_MAX_DEFAULT_VALUE);
                exynos_cpuhotplug_register_notifier(&thermal_cpu_hotplug_notifier, 0);
        }
 
@@ -1545,7 +1569,7 @@ static int exynos_tmu_resume(struct device *dev)
        struct platform_device *pdev = to_platform_device(dev);
 #ifdef CONFIG_EXYNOS_ACPM_THERMAL
        struct exynos_tmu_data *data = platform_get_drvdata(pdev);
-       int temp;
+       int temp, stat;
 
        if (suspended_count == num_of_devices)
                exynos_acpm_tmu_set_resume();
@@ -1555,7 +1579,7 @@ static int exynos_tmu_resume(struct device *dev)
                exynos_tmu_control(pdev, true);
        }
 
-       exynos_acpm_tmu_set_read_temp(data->tzd->id, &temp);
+       exynos_acpm_tmu_set_read_temp(data->tzd->id, &temp, &stat);
 
        enable_irq(data->irq);
        suspended_count--;
index aebb6102ee6f94ac6ad6edf9cd8db0fa73e5008f..f63f16829a3f718ca00c9ac9ec4fee4261e7c8f5 100644 (file)
@@ -144,6 +144,7 @@ struct exynos_tmu_data {
        bool hotplug_enable;
        int hotplug_in_threshold;
        int hotplug_out_threshold;
+       int limited_frequency;
        struct exynos_tmu_platform_data *pdata;
        void __iomem *base;
        int irq;