Merge "drivers: thermal: Use FCAP scm call instead of DMAX in LMH DCVSh"
This commit is contained in:
commit
54d23a97a0
2 changed files with 51 additions and 40 deletions
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -54,7 +54,7 @@
|
|||
#define MSM_LIMITS_CLUSTER_0 0x6370302D
|
||||
#define MSM_LIMITS_CLUSTER_1 0x6370312D
|
||||
|
||||
#define MSM_LIMITS_DOMAIN_MAX 0x444D4158
|
||||
#define MSM_LIMIT_FREQ_CAP 0x46434150
|
||||
|
||||
#define MSM_LIMITS_HIGH_THRESHOLD_VAL 95000
|
||||
#define MSM_LIMITS_ARM_THRESHOLD_VAL 65000
|
||||
|
@ -194,34 +194,40 @@ static irqreturn_t lmh_dcvs_handle_isr(int irq, void *data)
|
|||
}
|
||||
|
||||
static int msm_lmh_dcvs_write(uint32_t node_id, uint32_t fn,
|
||||
uint32_t setting, uint32_t val)
|
||||
uint32_t setting, uint32_t val, uint32_t val1,
|
||||
bool enable_val1)
|
||||
{
|
||||
int ret;
|
||||
struct scm_desc desc_arg;
|
||||
uint32_t *payload = NULL;
|
||||
uint32_t payload_len;
|
||||
|
||||
payload = kzalloc(sizeof(uint32_t) * 5, GFP_KERNEL);
|
||||
payload_len = ((enable_val1) ? 6 : 5) * sizeof(uint32_t);
|
||||
payload = kcalloc((enable_val1) ? 6 : 5, sizeof(uint32_t), GFP_KERNEL);
|
||||
if (!payload)
|
||||
return -ENOMEM;
|
||||
|
||||
payload[0] = fn; /* algorithm */
|
||||
payload[1] = 0; /* unused sub-algorithm */
|
||||
payload[2] = setting;
|
||||
payload[3] = 1; /* number of values */
|
||||
payload[3] = enable_val1 ? 2 : 1; /* number of values */
|
||||
payload[4] = val;
|
||||
if (enable_val1)
|
||||
payload[5] = val1;
|
||||
|
||||
desc_arg.args[0] = SCM_BUFFER_PHYS(payload);
|
||||
desc_arg.args[1] = sizeof(uint32_t) * 5;
|
||||
desc_arg.args[1] = payload_len;
|
||||
desc_arg.args[2] = MSM_LIMITS_NODE_DCVS;
|
||||
desc_arg.args[3] = node_id;
|
||||
desc_arg.args[4] = 0; /* version */
|
||||
desc_arg.arginfo = SCM_ARGS(5, SCM_RO, SCM_VAL, SCM_VAL,
|
||||
SCM_VAL, SCM_VAL);
|
||||
|
||||
dmac_flush_range(payload, (void *)payload + 5 * (sizeof(uint32_t)));
|
||||
dmac_flush_range(payload, (void *)payload + payload_len);
|
||||
ret = scm_call2(SCM_SIP_FNID(SCM_SVC_LMH, MSM_LIMITS_DCVSH), &desc_arg);
|
||||
|
||||
kfree(payload);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -265,7 +271,7 @@ static int lmh_activate_trip(struct thermal_zone_device *dev,
|
|||
case LIMITS_TRIP_LO:
|
||||
ret = msm_lmh_dcvs_write(hw->affinity,
|
||||
MSM_LIMITS_SUB_FN_THERMAL,
|
||||
MSM_LIMITS_ARM_THRESHOLD, temp);
|
||||
MSM_LIMITS_ARM_THRESHOLD, temp, 0, 0);
|
||||
break;
|
||||
case LIMITS_TRIP_HI:
|
||||
/*
|
||||
|
@ -276,13 +282,13 @@ static int lmh_activate_trip(struct thermal_zone_device *dev,
|
|||
return -EINVAL;
|
||||
ret = msm_lmh_dcvs_write(hw->affinity,
|
||||
MSM_LIMITS_SUB_FN_THERMAL,
|
||||
MSM_LIMITS_HI_THRESHOLD, temp);
|
||||
MSM_LIMITS_HI_THRESHOLD, temp, 0, 0);
|
||||
if (ret)
|
||||
break;
|
||||
ret = msm_lmh_dcvs_write(hw->affinity,
|
||||
MSM_LIMITS_SUB_FN_THERMAL,
|
||||
MSM_LIMITS_LOW_THRESHOLD, temp -
|
||||
MSM_LIMITS_LOW_THRESHOLD_OFFSET);
|
||||
MSM_LIMITS_LOW_THRESHOLD_OFFSET, 0, 0);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
@ -347,8 +353,9 @@ static int lmh_set_max_limit(int cpu, u32 freq)
|
|||
if (!hw)
|
||||
return -EINVAL;
|
||||
|
||||
return msm_lmh_dcvs_write(hw->affinity, MSM_LIMITS_SUB_FN_GENERAL,
|
||||
MSM_LIMITS_DOMAIN_MAX, freq);
|
||||
return msm_lmh_dcvs_write(hw->affinity, MSM_LIMITS_SUB_FN_THERMAL,
|
||||
MSM_LIMIT_FREQ_CAP, freq,
|
||||
freq >= hw->max_freq ? 0 : 1, 1);
|
||||
}
|
||||
|
||||
static int lmh_get_cur_limit(int cpu, unsigned long *freq)
|
||||
|
@ -457,7 +464,7 @@ static int msm_lmh_dcvs_probe(struct platform_device *pdev)
|
|||
|
||||
/* Enable the thermal algorithm early */
|
||||
ret = msm_lmh_dcvs_write(hw->affinity, MSM_LIMITS_SUB_FN_THERMAL,
|
||||
MSM_LIMITS_ALGO_MODE_ENABLE, 1);
|
||||
MSM_LIMITS_ALGO_MODE_ENABLE, 1, 0, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -59,11 +59,11 @@
|
|||
|
||||
#define MSM_LIMITS_DCVSH 0x10
|
||||
#define MSM_LIMITS_NODE_DCVS 0x44435653
|
||||
#define MSM_LIMITS_SUB_FN_THERMAL 0x54484D4C
|
||||
#define MSM_LIMITS_SUB_FN_GENERAL 0x47454E00
|
||||
#define MSM_LIMITS_SUB_FN_CRNT 0x43524E54
|
||||
#define MSM_LIMITS_SUB_FN_REL 0x52454C00
|
||||
#define MSM_LIMITS_DOMAIN_MAX 0x444D4158
|
||||
#define MSM_LIMITS_DOMAIN_MIN 0x444D494E
|
||||
#define MSM_LIMITS_FREQ_CAP 0x46434150
|
||||
#define MSM_LIMITS_CLUSTER_0 0x6370302D
|
||||
#define MSM_LIMITS_CLUSTER_1 0x6370312D
|
||||
#define MSM_LIMITS_ALGO_MODE_ENABLE 0x454E424C
|
||||
|
@ -1018,55 +1018,58 @@ static struct notifier_block msm_thermal_cpufreq_notifier = {
|
|||
.notifier_call = msm_thermal_cpufreq_callback,
|
||||
};
|
||||
|
||||
static int msm_lmh_dcvs_write(uint32_t node_id, uint32_t fn, uint32_t setting,
|
||||
uint32_t val)
|
||||
static int msm_lmh_dcvs_write(uint32_t node_id, uint32_t fn,
|
||||
uint32_t setting, uint32_t val, uint32_t val1,
|
||||
bool enable_val1)
|
||||
{
|
||||
int ret;
|
||||
struct scm_desc desc_arg;
|
||||
uint32_t *payload = NULL;
|
||||
uint32_t payload_len;
|
||||
|
||||
payload = kzalloc(sizeof(uint32_t) * 5, GFP_KERNEL);
|
||||
payload_len = ((enable_val1) ? 6 : 5) * sizeof(uint32_t);
|
||||
payload = kcalloc((enable_val1) ? 6 : 5, sizeof(uint32_t), GFP_KERNEL);
|
||||
if (!payload)
|
||||
return -ENOMEM;
|
||||
|
||||
payload[0] = fn;
|
||||
payload[0] = fn; /* algorithm */
|
||||
payload[1] = 0; /* unused sub-algorithm */
|
||||
payload[2] = setting;
|
||||
payload[3] = 1; /* number of values */
|
||||
payload[3] = enable_val1 ? 2 : 1; /* number of values */
|
||||
payload[4] = val;
|
||||
if (enable_val1)
|
||||
payload[5] = val1;
|
||||
|
||||
desc_arg.args[0] = SCM_BUFFER_PHYS(payload);
|
||||
desc_arg.args[1] = sizeof(uint32_t) * 5;
|
||||
desc_arg.args[1] = payload_len;
|
||||
desc_arg.args[2] = MSM_LIMITS_NODE_DCVS;
|
||||
desc_arg.args[3] = node_id;
|
||||
desc_arg.args[4] = 0; /* version */
|
||||
desc_arg.arginfo = SCM_ARGS(5, SCM_RO, SCM_VAL, SCM_VAL,
|
||||
SCM_VAL, SCM_VAL);
|
||||
|
||||
dmac_flush_range(payload, (void *)payload + 5 * (sizeof(uint32_t)));
|
||||
dmac_flush_range(payload, (void *)payload + payload_len);
|
||||
ret = scm_call2(SCM_SIP_FNID(SCM_SVC_LMH, MSM_LIMITS_DCVSH), &desc_arg);
|
||||
|
||||
kfree(payload);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int msm_lmh_dcvs_update(int cpu)
|
||||
{
|
||||
uint32_t id = cpus[cpu].parent_ptr->cluster_id;
|
||||
uint32_t max_freq = cpus[cpu].limited_max_freq;
|
||||
uint32_t min_freq = cpus[cpu].limited_min_freq;
|
||||
uint32_t max_freq = cpus[cpu].limited_max_freq, hw_max_freq = U32_MAX;
|
||||
uint32_t affinity;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* It is better to use max/min limits of cluster for given
|
||||
* It is better to use max limits of cluster for given
|
||||
* cpu if cluster mitigation is supported. It ensures that it
|
||||
* requests aggregated max/min limits of all cpus in that cluster.
|
||||
* requests aggregated max limits of all cpus in that cluster.
|
||||
*/
|
||||
if (core_ptr) {
|
||||
if (core_ptr)
|
||||
max_freq = cpus[cpu].parent_ptr->limited_max_freq;
|
||||
min_freq = cpus[cpu].parent_ptr->limited_min_freq;
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case 0:
|
||||
|
@ -1080,13 +1083,14 @@ static int msm_lmh_dcvs_update(int cpu)
|
|||
return -EINVAL;
|
||||
};
|
||||
|
||||
ret = msm_lmh_dcvs_write(affinity, MSM_LIMITS_SUB_FN_GENERAL,
|
||||
MSM_LIMITS_DOMAIN_MAX, max_freq);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (cpus[cpu].parent_ptr->freq_table)
|
||||
hw_max_freq =
|
||||
cpus[cpu].parent_ptr->freq_table[
|
||||
cpus[cpu].parent_ptr->freq_idx_high].frequency;
|
||||
|
||||
ret = msm_lmh_dcvs_write(affinity, MSM_LIMITS_SUB_FN_GENERAL,
|
||||
MSM_LIMITS_DOMAIN_MIN, min_freq);
|
||||
ret = msm_lmh_dcvs_write(affinity, MSM_LIMITS_SUB_FN_THERMAL,
|
||||
MSM_LIMITS_FREQ_CAP, max_freq,
|
||||
max_freq >= hw_max_freq ? 0 : 1, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
/*
|
||||
|
@ -1729,23 +1733,23 @@ static int msm_thermal_lmh_dcvs_init(struct platform_device *pdev)
|
|||
*/
|
||||
ret = msm_lmh_dcvs_write(MSM_LIMITS_CLUSTER_0,
|
||||
MSM_LIMITS_SUB_FN_REL,
|
||||
MSM_LIMITS_ALGO_MODE_ENABLE, 1);
|
||||
MSM_LIMITS_ALGO_MODE_ENABLE, 1, 0, 0);
|
||||
if (ret)
|
||||
pr_err("Unable to enable REL algo for cluster0\n");
|
||||
ret = msm_lmh_dcvs_write(MSM_LIMITS_CLUSTER_1,
|
||||
MSM_LIMITS_SUB_FN_REL,
|
||||
MSM_LIMITS_ALGO_MODE_ENABLE, 1);
|
||||
MSM_LIMITS_ALGO_MODE_ENABLE, 1, 0, 0);
|
||||
if (ret)
|
||||
pr_err("Unable to enable REL algo for cluster1\n");
|
||||
|
||||
ret = msm_lmh_dcvs_write(MSM_LIMITS_CLUSTER_0,
|
||||
MSM_LIMITS_SUB_FN_CRNT,
|
||||
MSM_LIMITS_ALGO_MODE_ENABLE, 1);
|
||||
MSM_LIMITS_ALGO_MODE_ENABLE, 1, 0, 0);
|
||||
if (ret)
|
||||
pr_err("Unable enable CRNT algo for cluster0\n");
|
||||
ret = msm_lmh_dcvs_write(MSM_LIMITS_CLUSTER_1,
|
||||
MSM_LIMITS_SUB_FN_CRNT,
|
||||
MSM_LIMITS_ALGO_MODE_ENABLE, 1);
|
||||
MSM_LIMITS_ALGO_MODE_ENABLE, 1, 0, 0);
|
||||
if (ret)
|
||||
pr_err("Unable enable CRNT algo for cluster1\n");
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue