msm: dcvs: Add thermal interfaces.
The algorithm needs thermal inputs for all the cores. Create members in
the internal core_info strucutre and platform data/device tree to pass
in the sensors they use.
Update the dcvs code to notify the temperature to TZ.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
(cherry picked from commit fc7dca4c325725492af997fa282e07b9d03154d1)
Signed-off-by: Ram Kumar Chakravarthy Chebathini <rcheba@codeaurora.org>
(cherry picked from commit eb478c5b7b55ea8a57e0336e4cf9979be935b289)
Change-Id: I505903eb8b9779f2065aebfab5b3f2aefc874200
Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/arm/msm/dcvs-core-info.txt b/Documentation/devicetree/bindings/arm/msm/dcvs-core-info.txt
index 5b4d3cf..b7dd427 100644
--- a/Documentation/devicetree/bindings/arm/msm/dcvs-core-info.txt
+++ b/Documentation/devicetree/bindings/arm/msm/dcvs-core-info.txt
@@ -7,10 +7,14 @@
- qcom,core-core-type: indicates whether this core is a CPU(0) or a GPU(1)
+- qcom,num-cores: The number of cores this entry represents
+- qcom,sensors: The vector of sensor ids for the cores
+
- qcom,algo-disable-pc-threshold: sets highest frequency at which DCVS
will allow the CPU to power collapse.
- qcom,algo-em-win-size-min-us: sets minimum Energy Minimization(EM)
window size.
+
- qcom,algo-em-win-size-max-us: sets maximum EM window size.
- qcom,algo-em-max-util-pct: sets maximum CPU utilization that will
not be exceeded by any core when
@@ -67,7 +71,7 @@
compatible = "qcom,dcvs-core-info";
- qcom,num_cores = <1>;
+ qcom,num-cores = <1>;
qcom,sensors = <0>;
qcom,core-core-type = <1>;
diff --git a/arch/arm/boot/dts/msm8974-gpu.dtsi b/arch/arm/boot/dts/msm8974-gpu.dtsi
index 88eeb33..2a69c81 100644
--- a/arch/arm/boot/dts/msm8974-gpu.dtsi
+++ b/arch/arm/boot/dts/msm8974-gpu.dtsi
@@ -85,6 +85,9 @@
compatible = "qcom,dcvs-core-info";
+ qcom,num-cores = <1>;
+ qcom,sensors = <0>;
+
qcom,core-core-type = <1>;
qcom,algo-disable-pc-threshold = <0>;
diff --git a/arch/arm/mach-msm/board-8064-gpu.c b/arch/arm/mach-msm/board-8064-gpu.c
index 26d4c27..940517f 100644
--- a/arch/arm/mach-msm/board-8064-gpu.c
+++ b/arch/arm/mach-msm/board-8064-gpu.c
@@ -32,6 +32,8 @@
static struct msm_dcvs_core_info grp3d_core_info = {
.freq_tbl = &grp3d_freq[0],
+ .num_cores = 1,
+ .sensors = (int[]){0},
.core_param = {
.core_type = MSM_DCVS_CORE_TYPE_GPU,
},
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 4032af6..99ce77d 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -2610,6 +2610,8 @@
static struct msm_dcvs_core_info apq8064_core_info = {
.freq_tbl = &apq8064_freq[0],
+ .num_cores = 4,
+ .sensors = (int[]){7, 8, 9, 10},
.core_param = {
.core_type = MSM_DCVS_CORE_TYPE_CPU,
},
diff --git a/arch/arm/mach-msm/include/mach/msm_dcvs.h b/arch/arm/mach-msm/include/mach/msm_dcvs.h
index 490a34b..e8908e8 100644
--- a/arch/arm/mach-msm/include/mach/msm_dcvs.h
+++ b/arch/arm/mach-msm/include/mach/msm_dcvs.h
@@ -90,6 +90,8 @@
* before the sink driver can be registered.
*/
struct msm_dcvs_core_info {
+ int num_cores;
+ int *sensors;
struct msm_dcvs_freq_entry *freq_tbl;
struct msm_dcvs_core_param core_param;
struct msm_dcvs_algo_param algo_param;
@@ -101,6 +103,7 @@
* msm_dcvs_register_core
* @core_name: Unique name identifier for the core.
* @info: The core specific algorithm parameters.
+ * @sensor: The thermal sensor number of the core in question
* @return :
* 0 on success,
* -ENOSYS,
@@ -111,7 +114,7 @@
* Cores that need to run synchronously must share the same group id.
*/
extern int msm_dcvs_register_core(const char *core_name,
- struct msm_dcvs_core_info *info);
+ struct msm_dcvs_core_info *info, int sensor);
/**
* struct msm_dcvs_freq
diff --git a/arch/arm/mach-msm/msm_dcvs.c b/arch/arm/mach-msm/msm_dcvs.c
index 9601b7e..0505d44 100644
--- a/arch/arm/mach-msm/msm_dcvs.c
+++ b/arch/arm/mach-msm/msm_dcvs.c
@@ -23,6 +23,7 @@
#include <linux/spinlock.h>
#include <linux/stringify.h>
#include <linux/debugfs.h>
+#include <linux/msm_tsens.h>
#include <asm/atomic.h>
#include <asm/page.h>
#include <mach/msm_dcvs.h>
@@ -97,13 +98,14 @@
/* track if kthread for change_freq is active */
int32_t change_freq_activated;
struct msm_dcvs_core_info *info;
+ int sensor;
};
static int msm_dcvs_debug;
static int msm_dcvs_enabled = 1;
module_param_named(enable, msm_dcvs_enabled, int, S_IRUGO | S_IWUSR | S_IWGRP);
-static struct dentry *debugfs_base;
+static struct dentry *debugfs_base;
static struct dcvs_core core_list[CORES_MAX];
static DEFINE_MUTEX(core_list_lock);
@@ -240,6 +242,27 @@
return ret;
}
+static int __msm_dcvs_report_temp(struct dcvs_core *core)
+{
+ struct msm_dcvs_core_info *info = core->info;
+ struct tsens_device tsens_dev;
+ int ret;
+ unsigned long temp = 0;
+
+ tsens_dev.sensor_num = core->sensor;
+ ret = tsens_get_temp(&tsens_dev, &temp);
+ if (!ret) {
+ tsens_dev.sensor_num = 0;
+ ret = tsens_get_temp(&tsens_dev, &temp);
+ if (!ret)
+ return -ENODEV;
+ }
+
+ ret = msm_dcvs_scm_set_power_params(core->handle, &info->power_param,
+ &info->freq_tbl[0], &core->coeffs);
+ return ret;
+}
+
static int msm_dcvs_do_freq(void *data)
{
struct dcvs_core *core = (struct dcvs_core *)data;
@@ -251,6 +274,7 @@
while (!kthread_should_stop()) {
mutex_lock(&core->lock);
__msm_dcvs_change_freq(core);
+ __msm_dcvs_report_temp(core);
mutex_unlock(&core->lock);
schedule();
@@ -571,7 +595,7 @@
}
int msm_dcvs_register_core(const char *core_name,
- struct msm_dcvs_core_info *info)
+ struct msm_dcvs_core_info *info, int sensor)
{
int ret = -EINVAL;
struct dcvs_core *core = NULL;
@@ -594,7 +618,10 @@
memcpy(&core->coeffs, &info->energy_coeffs,
sizeof(struct msm_dcvs_energy_curve_coeffs));
- ret = msm_dcvs_scm_register_core(core->handle, &info->core_param);
+ pr_debug("registering core with sensor %d\n", sensor);
+ core->sensor = sensor;
+ ret = msm_dcvs_scm_register_core(core->handle,
+ &info->core_param);
if (ret)
goto bail;
diff --git a/drivers/cpufreq/cpufreq_gov_msm.c b/drivers/cpufreq/cpufreq_gov_msm.c
index 4eeff35..f7bfe17 100644
--- a/drivers/cpufreq/cpufreq_gov_msm.c
+++ b/drivers/cpufreq/cpufreq_gov_msm.c
@@ -139,13 +139,16 @@
int ret = 0;
int cpu;
struct msm_dcvs_core_info *core = NULL;
+ int sensor = 0;
core = pdev->dev.platform_data;
for_each_possible_cpu(cpu) {
mutex_init(&per_cpu(gov_mutex, cpu));
snprintf(core_name[cpu], 10, "cpu%d", cpu);
- ret = msm_dcvs_register_core(core_name[cpu], core);
+ if (cpu < core->num_cores)
+ sensor = core->sensors[cpu];
+ ret = msm_dcvs_register_core(core_name[cpu], core, sensor);
if (ret)
pr_err("Unable to register core for %d\n", cpu);
}
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 8361430..fb67fc1 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -912,6 +912,19 @@
info->freq_tbl[index].leakage_energy_offset = 0;
}
+ if (adreno_of_read_property(node, "qcom,num-cores", &info->num_cores))
+ goto err;
+
+ info->sensors = kzalloc(info->num_cores *
+ sizeof(int),
+ GFP_KERNEL);
+
+ for (count = 0; count < info->num_cores; count++) {
+ if (adreno_of_read_property(node, "qcom,sensors",
+ &(info->sensors[count])))
+ goto err;
+ }
+
if (adreno_of_read_property(node, "qcom,core-core-type",
&info->core_param.core_type))
goto err;
diff --git a/drivers/gpu/msm/kgsl_pwrscale_msm.c b/drivers/gpu/msm/kgsl_pwrscale_msm.c
index 4b08e52..ae34d22 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_msm.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_msm.c
@@ -149,7 +149,8 @@
low_level = pwr->num_pwrlevels - KGSL_PWRLEVEL_LAST_OFFSET;
for (i = 0; i <= low_level; i++)
tbl[i].freq = pwr->pwrlevels[low_level - i].gpu_freq / 1000;
- ret = msm_dcvs_register_core(device->name, priv->core_info);
+ ret = msm_dcvs_register_core(device->name, priv->core_info,
+ priv->core_info->sensors[0]);
if (ret) {
KGSL_PWR_ERR(device, "msm_dcvs_register_core failed");
goto err;