Commit 815fb87b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pm-6.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management fixes from Rafael Wysocki:
 "These fix issues in two cpufreq drivers, in the AMD P-state driver and
  in the power-capping DTPM framework.

  Specifics:

   - Fix the AMD P-state driver's EPP sysfs interface in the cases when
     the performance governor is in use (Ayush Jain)

   - Make the ->fast_switch() callback in the AMD P-state driver return
     the target frequency as expected (Gautham R. Shenoy)

   - Allow user space to control the range of frequencies to use via
     scaling_min_freq and scaling_max_freq when AMD P-state driver is in
     use (Wyes Karny)

   - Prevent power domains needed for wakeup signaling from being turned
     off during system suspend on Qualcomm systems and prevent
     performance states votes from runtime-suspended devices from being
     lost across a system suspend-resume cycle in qcom-cpufreq-nvmem
     (Stephan Gerhold)

   - Fix disabling the 792 Mhz OPP in the imx6q cpufreq driver for the
     i.MX6ULL types that can run at that frequency (Christoph
     Niedermaier)

   - Eliminate unnecessary and harmful conversions to uW from the DTPM
     (dynamic thermal and power management) framework (Lukasz Luba)"

* tag 'pm-6.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  cpufreq/amd-pstate: Only print supported EPP values for performance governor
  cpufreq/amd-pstate: Fix scaling_min_freq and scaling_max_freq update
  powercap: DTPM: Fix unneeded conversions to micro-Watts
  cpufreq/amd-pstate: Fix the return value of amd_pstate_fast_switch()
  pmdomain: qcom: rpmpd: Set GENPD_FLAG_ACTIVE_WAKEUP
  cpufreq: qcom-nvmem: Preserve PM domain votes in system suspend
  cpufreq: qcom-nvmem: Enable virtual power domain devices
  cpufreq: imx6q: Don't disable 792 Mhz OPP unnecessarily
parents ce474ae7 a6b31256
...@@ -307,11 +307,11 @@ static int pstate_init_perf(struct amd_cpudata *cpudata) ...@@ -307,11 +307,11 @@ static int pstate_init_perf(struct amd_cpudata *cpudata)
highest_perf = AMD_CPPC_HIGHEST_PERF(cap1); highest_perf = AMD_CPPC_HIGHEST_PERF(cap1);
WRITE_ONCE(cpudata->highest_perf, highest_perf); WRITE_ONCE(cpudata->highest_perf, highest_perf);
WRITE_ONCE(cpudata->max_limit_perf, highest_perf);
WRITE_ONCE(cpudata->nominal_perf, AMD_CPPC_NOMINAL_PERF(cap1)); WRITE_ONCE(cpudata->nominal_perf, AMD_CPPC_NOMINAL_PERF(cap1));
WRITE_ONCE(cpudata->lowest_nonlinear_perf, AMD_CPPC_LOWNONLIN_PERF(cap1)); WRITE_ONCE(cpudata->lowest_nonlinear_perf, AMD_CPPC_LOWNONLIN_PERF(cap1));
WRITE_ONCE(cpudata->lowest_perf, AMD_CPPC_LOWEST_PERF(cap1)); WRITE_ONCE(cpudata->lowest_perf, AMD_CPPC_LOWEST_PERF(cap1));
WRITE_ONCE(cpudata->min_limit_perf, AMD_CPPC_LOWEST_PERF(cap1));
return 0; return 0;
} }
...@@ -329,11 +329,12 @@ static int cppc_init_perf(struct amd_cpudata *cpudata) ...@@ -329,11 +329,12 @@ static int cppc_init_perf(struct amd_cpudata *cpudata)
highest_perf = cppc_perf.highest_perf; highest_perf = cppc_perf.highest_perf;
WRITE_ONCE(cpudata->highest_perf, highest_perf); WRITE_ONCE(cpudata->highest_perf, highest_perf);
WRITE_ONCE(cpudata->max_limit_perf, highest_perf);
WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf); WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf);
WRITE_ONCE(cpudata->lowest_nonlinear_perf, WRITE_ONCE(cpudata->lowest_nonlinear_perf,
cppc_perf.lowest_nonlinear_perf); cppc_perf.lowest_nonlinear_perf);
WRITE_ONCE(cpudata->lowest_perf, cppc_perf.lowest_perf); WRITE_ONCE(cpudata->lowest_perf, cppc_perf.lowest_perf);
WRITE_ONCE(cpudata->min_limit_perf, cppc_perf.lowest_perf);
if (cppc_state == AMD_PSTATE_ACTIVE) if (cppc_state == AMD_PSTATE_ACTIVE)
return 0; return 0;
...@@ -432,6 +433,10 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf, ...@@ -432,6 +433,10 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
u64 prev = READ_ONCE(cpudata->cppc_req_cached); u64 prev = READ_ONCE(cpudata->cppc_req_cached);
u64 value = prev; u64 value = prev;
min_perf = clamp_t(unsigned long, min_perf, cpudata->min_limit_perf,
cpudata->max_limit_perf);
max_perf = clamp_t(unsigned long, max_perf, cpudata->min_limit_perf,
cpudata->max_limit_perf);
des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf); des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf);
if ((cppc_state == AMD_PSTATE_GUIDED) && (gov_flags & CPUFREQ_GOV_DYNAMIC_SWITCHING)) { if ((cppc_state == AMD_PSTATE_GUIDED) && (gov_flags & CPUFREQ_GOV_DYNAMIC_SWITCHING)) {
...@@ -470,6 +475,22 @@ static int amd_pstate_verify(struct cpufreq_policy_data *policy) ...@@ -470,6 +475,22 @@ static int amd_pstate_verify(struct cpufreq_policy_data *policy)
return 0; return 0;
} }
static int amd_pstate_update_min_max_limit(struct cpufreq_policy *policy)
{
u32 max_limit_perf, min_limit_perf;
struct amd_cpudata *cpudata = policy->driver_data;
max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq);
min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq);
WRITE_ONCE(cpudata->max_limit_perf, max_limit_perf);
WRITE_ONCE(cpudata->min_limit_perf, min_limit_perf);
WRITE_ONCE(cpudata->max_limit_freq, policy->max);
WRITE_ONCE(cpudata->min_limit_freq, policy->min);
return 0;
}
static int amd_pstate_update_freq(struct cpufreq_policy *policy, static int amd_pstate_update_freq(struct cpufreq_policy *policy,
unsigned int target_freq, bool fast_switch) unsigned int target_freq, bool fast_switch)
{ {
...@@ -480,6 +501,9 @@ static int amd_pstate_update_freq(struct cpufreq_policy *policy, ...@@ -480,6 +501,9 @@ static int amd_pstate_update_freq(struct cpufreq_policy *policy,
if (!cpudata->max_freq) if (!cpudata->max_freq)
return -ENODEV; return -ENODEV;
if (policy->min != cpudata->min_limit_freq || policy->max != cpudata->max_limit_freq)
amd_pstate_update_min_max_limit(policy);
cap_perf = READ_ONCE(cpudata->highest_perf); cap_perf = READ_ONCE(cpudata->highest_perf);
min_perf = READ_ONCE(cpudata->lowest_perf); min_perf = READ_ONCE(cpudata->lowest_perf);
max_perf = cap_perf; max_perf = cap_perf;
...@@ -518,7 +542,9 @@ static int amd_pstate_target(struct cpufreq_policy *policy, ...@@ -518,7 +542,9 @@ static int amd_pstate_target(struct cpufreq_policy *policy,
static unsigned int amd_pstate_fast_switch(struct cpufreq_policy *policy, static unsigned int amd_pstate_fast_switch(struct cpufreq_policy *policy,
unsigned int target_freq) unsigned int target_freq)
{ {
return amd_pstate_update_freq(policy, target_freq, true); if (!amd_pstate_update_freq(policy, target_freq, true))
return target_freq;
return policy->cur;
} }
static void amd_pstate_adjust_perf(unsigned int cpu, static void amd_pstate_adjust_perf(unsigned int cpu,
...@@ -532,6 +558,10 @@ static void amd_pstate_adjust_perf(unsigned int cpu, ...@@ -532,6 +558,10 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
struct amd_cpudata *cpudata = policy->driver_data; struct amd_cpudata *cpudata = policy->driver_data;
unsigned int target_freq; unsigned int target_freq;
if (policy->min != cpudata->min_limit_freq || policy->max != cpudata->max_limit_freq)
amd_pstate_update_min_max_limit(policy);
cap_perf = READ_ONCE(cpudata->highest_perf); cap_perf = READ_ONCE(cpudata->highest_perf);
lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf); lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
max_freq = READ_ONCE(cpudata->max_freq); max_freq = READ_ONCE(cpudata->max_freq);
...@@ -745,6 +775,8 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy) ...@@ -745,6 +775,8 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
/* Initial processor data capability frequencies */ /* Initial processor data capability frequencies */
cpudata->max_freq = max_freq; cpudata->max_freq = max_freq;
cpudata->min_freq = min_freq; cpudata->min_freq = min_freq;
cpudata->max_limit_freq = max_freq;
cpudata->min_limit_freq = min_freq;
cpudata->nominal_freq = nominal_freq; cpudata->nominal_freq = nominal_freq;
cpudata->lowest_nonlinear_freq = lowest_nonlinear_freq; cpudata->lowest_nonlinear_freq = lowest_nonlinear_freq;
...@@ -850,11 +882,16 @@ static ssize_t show_energy_performance_available_preferences( ...@@ -850,11 +882,16 @@ static ssize_t show_energy_performance_available_preferences(
{ {
int i = 0; int i = 0;
int offset = 0; int offset = 0;
struct amd_cpudata *cpudata = policy->driver_data;
if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
return sysfs_emit_at(buf, offset, "%s\n",
energy_perf_strings[EPP_INDEX_PERFORMANCE]);
while (energy_perf_strings[i] != NULL) while (energy_perf_strings[i] != NULL)
offset += sysfs_emit_at(buf, offset, "%s ", energy_perf_strings[i++]); offset += sysfs_emit_at(buf, offset, "%s ", energy_perf_strings[i++]);
sysfs_emit_at(buf, offset, "\n"); offset += sysfs_emit_at(buf, offset, "\n");
return offset; return offset;
} }
...@@ -1183,16 +1220,25 @@ static int amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy) ...@@ -1183,16 +1220,25 @@ static int amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
return 0; return 0;
} }
static void amd_pstate_epp_init(unsigned int cpu) static void amd_pstate_epp_update_limit(struct cpufreq_policy *policy)
{ {
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
struct amd_cpudata *cpudata = policy->driver_data; struct amd_cpudata *cpudata = policy->driver_data;
u32 max_perf, min_perf; u32 max_perf, min_perf, min_limit_perf, max_limit_perf;
u64 value; u64 value;
s16 epp; s16 epp;
max_perf = READ_ONCE(cpudata->highest_perf); max_perf = READ_ONCE(cpudata->highest_perf);
min_perf = READ_ONCE(cpudata->lowest_perf); min_perf = READ_ONCE(cpudata->lowest_perf);
max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq);
min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq);
max_perf = clamp_t(unsigned long, max_perf, cpudata->min_limit_perf,
cpudata->max_limit_perf);
min_perf = clamp_t(unsigned long, min_perf, cpudata->min_limit_perf,
cpudata->max_limit_perf);
WRITE_ONCE(cpudata->max_limit_perf, max_limit_perf);
WRITE_ONCE(cpudata->min_limit_perf, min_limit_perf);
value = READ_ONCE(cpudata->cppc_req_cached); value = READ_ONCE(cpudata->cppc_req_cached);
...@@ -1210,9 +1256,6 @@ static void amd_pstate_epp_init(unsigned int cpu) ...@@ -1210,9 +1256,6 @@ static void amd_pstate_epp_init(unsigned int cpu)
value &= ~AMD_CPPC_DES_PERF(~0L); value &= ~AMD_CPPC_DES_PERF(~0L);
value |= AMD_CPPC_DES_PERF(0); value |= AMD_CPPC_DES_PERF(0);
if (cpudata->epp_policy == cpudata->policy)
goto skip_epp;
cpudata->epp_policy = cpudata->policy; cpudata->epp_policy = cpudata->policy;
/* Get BIOS pre-defined epp value */ /* Get BIOS pre-defined epp value */
...@@ -1222,7 +1265,7 @@ static void amd_pstate_epp_init(unsigned int cpu) ...@@ -1222,7 +1265,7 @@ static void amd_pstate_epp_init(unsigned int cpu)
* This return value can only be negative for shared_memory * This return value can only be negative for shared_memory
* systems where EPP register read/write not supported. * systems where EPP register read/write not supported.
*/ */
goto skip_epp; return;
} }
if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
...@@ -1236,8 +1279,6 @@ static void amd_pstate_epp_init(unsigned int cpu) ...@@ -1236,8 +1279,6 @@ static void amd_pstate_epp_init(unsigned int cpu)
WRITE_ONCE(cpudata->cppc_req_cached, value); WRITE_ONCE(cpudata->cppc_req_cached, value);
amd_pstate_set_epp(cpudata, epp); amd_pstate_set_epp(cpudata, epp);
skip_epp:
cpufreq_cpu_put(policy);
} }
static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy) static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
...@@ -1252,7 +1293,7 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy) ...@@ -1252,7 +1293,7 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
cpudata->policy = policy->policy; cpudata->policy = policy->policy;
amd_pstate_epp_init(policy->cpu); amd_pstate_epp_update_limit(policy);
return 0; return 0;
} }
......
...@@ -327,7 +327,7 @@ static int imx6ul_opp_check_speed_grading(struct device *dev) ...@@ -327,7 +327,7 @@ static int imx6ul_opp_check_speed_grading(struct device *dev)
imx6x_disable_freq_in_opp(dev, 696000000); imx6x_disable_freq_in_opp(dev, 696000000);
if (of_machine_is_compatible("fsl,imx6ull")) { if (of_machine_is_compatible("fsl,imx6ull")) {
if (val != OCOTP_CFG3_6ULL_SPEED_792MHZ) if (val < OCOTP_CFG3_6ULL_SPEED_792MHZ)
imx6x_disable_freq_in_opp(dev, 792000000); imx6x_disable_freq_in_opp(dev, 792000000);
if (val != OCOTP_CFG3_6ULL_SPEED_900MHZ) if (val != OCOTP_CFG3_6ULL_SPEED_900MHZ)
......
...@@ -23,8 +23,10 @@ ...@@ -23,8 +23,10 @@
#include <linux/nvmem-consumer.h> #include <linux/nvmem-consumer.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_domain.h> #include <linux/pm_domain.h>
#include <linux/pm_opp.h> #include <linux/pm_opp.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/soc/qcom/smem.h> #include <linux/soc/qcom/smem.h>
...@@ -55,6 +57,7 @@ struct qcom_cpufreq_match_data { ...@@ -55,6 +57,7 @@ struct qcom_cpufreq_match_data {
struct qcom_cpufreq_drv_cpu { struct qcom_cpufreq_drv_cpu {
int opp_token; int opp_token;
struct device **virt_devs;
}; };
struct qcom_cpufreq_drv { struct qcom_cpufreq_drv {
...@@ -424,6 +427,30 @@ static const struct qcom_cpufreq_match_data match_data_ipq8074 = { ...@@ -424,6 +427,30 @@ static const struct qcom_cpufreq_match_data match_data_ipq8074 = {
.get_version = qcom_cpufreq_ipq8074_name_version, .get_version = qcom_cpufreq_ipq8074_name_version,
}; };
static void qcom_cpufreq_suspend_virt_devs(struct qcom_cpufreq_drv *drv, unsigned int cpu)
{
const char * const *name = drv->data->genpd_names;
int i;
if (!drv->cpus[cpu].virt_devs)
return;
for (i = 0; *name; i++, name++)
device_set_awake_path(drv->cpus[cpu].virt_devs[i]);
}
static void qcom_cpufreq_put_virt_devs(struct qcom_cpufreq_drv *drv, unsigned int cpu)
{
const char * const *name = drv->data->genpd_names;
int i;
if (!drv->cpus[cpu].virt_devs)
return;
for (i = 0; *name; i++, name++)
pm_runtime_put(drv->cpus[cpu].virt_devs[i]);
}
static int qcom_cpufreq_probe(struct platform_device *pdev) static int qcom_cpufreq_probe(struct platform_device *pdev)
{ {
struct qcom_cpufreq_drv *drv; struct qcom_cpufreq_drv *drv;
...@@ -478,6 +505,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) ...@@ -478,6 +505,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
of_node_put(np); of_node_put(np);
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
struct device **virt_devs = NULL;
struct dev_pm_opp_config config = { struct dev_pm_opp_config config = {
.supported_hw = NULL, .supported_hw = NULL,
}; };
...@@ -498,7 +526,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) ...@@ -498,7 +526,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
if (drv->data->genpd_names) { if (drv->data->genpd_names) {
config.genpd_names = drv->data->genpd_names; config.genpd_names = drv->data->genpd_names;
config.virt_devs = NULL; config.virt_devs = &virt_devs;
} }
if (config.supported_hw || config.genpd_names) { if (config.supported_hw || config.genpd_names) {
...@@ -509,6 +537,27 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) ...@@ -509,6 +537,27 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
goto free_opp; goto free_opp;
} }
} }
if (virt_devs) {
const char * const *name = config.genpd_names;
int i, j;
for (i = 0; *name; i++, name++) {
ret = pm_runtime_resume_and_get(virt_devs[i]);
if (ret) {
dev_err(cpu_dev, "failed to resume %s: %d\n",
*name, ret);
/* Rollback previous PM runtime calls */
name = config.genpd_names;
for (j = 0; *name && j < i; j++, name++)
pm_runtime_put(virt_devs[j]);
goto free_opp;
}
}
drv->cpus[cpu].virt_devs = virt_devs;
}
} }
cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1, cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1,
...@@ -522,8 +571,10 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) ...@@ -522,8 +571,10 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
dev_err(cpu_dev, "Failed to register platform device\n"); dev_err(cpu_dev, "Failed to register platform device\n");
free_opp: free_opp:
for_each_possible_cpu(cpu) for_each_possible_cpu(cpu) {
qcom_cpufreq_put_virt_devs(drv, cpu);
dev_pm_opp_clear_config(drv->cpus[cpu].opp_token); dev_pm_opp_clear_config(drv->cpus[cpu].opp_token);
}
return ret; return ret;
} }
...@@ -534,15 +585,31 @@ static void qcom_cpufreq_remove(struct platform_device *pdev) ...@@ -534,15 +585,31 @@ static void qcom_cpufreq_remove(struct platform_device *pdev)
platform_device_unregister(cpufreq_dt_pdev); platform_device_unregister(cpufreq_dt_pdev);
for_each_possible_cpu(cpu) for_each_possible_cpu(cpu) {
qcom_cpufreq_put_virt_devs(drv, cpu);
dev_pm_opp_clear_config(drv->cpus[cpu].opp_token); dev_pm_opp_clear_config(drv->cpus[cpu].opp_token);
}
} }
static int qcom_cpufreq_suspend(struct device *dev)
{
struct qcom_cpufreq_drv *drv = dev_get_drvdata(dev);
unsigned int cpu;
for_each_possible_cpu(cpu)
qcom_cpufreq_suspend_virt_devs(drv, cpu);
return 0;
}
static DEFINE_SIMPLE_DEV_PM_OPS(qcom_cpufreq_pm_ops, qcom_cpufreq_suspend, NULL);
static struct platform_driver qcom_cpufreq_driver = { static struct platform_driver qcom_cpufreq_driver = {
.probe = qcom_cpufreq_probe, .probe = qcom_cpufreq_probe,
.remove_new = qcom_cpufreq_remove, .remove_new = qcom_cpufreq_remove,
.driver = { .driver = {
.name = "qcom-cpufreq-nvmem", .name = "qcom-cpufreq-nvmem",
.pm = pm_sleep_ptr(&qcom_cpufreq_pm_ops),
}, },
}; };
......
...@@ -1044,6 +1044,7 @@ static int rpmpd_probe(struct platform_device *pdev) ...@@ -1044,6 +1044,7 @@ static int rpmpd_probe(struct platform_device *pdev)
rpmpds[i]->pd.power_off = rpmpd_power_off; rpmpds[i]->pd.power_off = rpmpd_power_off;
rpmpds[i]->pd.power_on = rpmpd_power_on; rpmpds[i]->pd.power_on = rpmpd_power_on;
rpmpds[i]->pd.set_performance_state = rpmpd_set_performance; rpmpds[i]->pd.set_performance_state = rpmpd_set_performance;
rpmpds[i]->pd.flags = GENPD_FLAG_ACTIVE_WAKEUP;
pm_genpd_init(&rpmpds[i]->pd, NULL, true); pm_genpd_init(&rpmpds[i]->pd, NULL, true);
data->domains[i] = &rpmpds[i]->pd; data->domains[i] = &rpmpds[i]->pd;
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/pm_qos.h> #include <linux/pm_qos.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/units.h>
struct dtpm_cpu { struct dtpm_cpu {
struct dtpm dtpm; struct dtpm dtpm;
...@@ -104,8 +103,7 @@ static u64 get_pd_power_uw(struct dtpm *dtpm) ...@@ -104,8 +103,7 @@ static u64 get_pd_power_uw(struct dtpm *dtpm)
if (pd->table[i].frequency < freq) if (pd->table[i].frequency < freq)
continue; continue;
return scale_pd_power_uw(pd_mask, pd->table[i].power * return scale_pd_power_uw(pd_mask, pd->table[i].power);
MICROWATT_PER_MILLIWATT);
} }
return 0; return 0;
...@@ -122,11 +120,9 @@ static int update_pd_power_uw(struct dtpm *dtpm) ...@@ -122,11 +120,9 @@ static int update_pd_power_uw(struct dtpm *dtpm)
nr_cpus = cpumask_weight(&cpus); nr_cpus = cpumask_weight(&cpus);
dtpm->power_min = em->table[0].power; dtpm->power_min = em->table[0].power;
dtpm->power_min *= MICROWATT_PER_MILLIWATT;
dtpm->power_min *= nr_cpus; dtpm->power_min *= nr_cpus;
dtpm->power_max = em->table[em->nr_perf_states - 1].power; dtpm->power_max = em->table[em->nr_perf_states - 1].power;
dtpm->power_max *= MICROWATT_PER_MILLIWATT;
dtpm->power_max *= nr_cpus; dtpm->power_max *= nr_cpus;
return 0; return 0;
......
...@@ -39,10 +39,8 @@ static int update_pd_power_uw(struct dtpm *dtpm) ...@@ -39,10 +39,8 @@ static int update_pd_power_uw(struct dtpm *dtpm)
struct em_perf_domain *pd = em_pd_get(dev); struct em_perf_domain *pd = em_pd_get(dev);
dtpm->power_min = pd->table[0].power; dtpm->power_min = pd->table[0].power;
dtpm->power_min *= MICROWATT_PER_MILLIWATT;
dtpm->power_max = pd->table[pd->nr_perf_states - 1].power; dtpm->power_max = pd->table[pd->nr_perf_states - 1].power;
dtpm->power_max *= MICROWATT_PER_MILLIWATT;
return 0; return 0;
} }
...@@ -54,13 +52,10 @@ static u64 set_pd_power_limit(struct dtpm *dtpm, u64 power_limit) ...@@ -54,13 +52,10 @@ static u64 set_pd_power_limit(struct dtpm *dtpm, u64 power_limit)
struct device *dev = devfreq->dev.parent; struct device *dev = devfreq->dev.parent;
struct em_perf_domain *pd = em_pd_get(dev); struct em_perf_domain *pd = em_pd_get(dev);
unsigned long freq; unsigned long freq;
u64 power;
int i; int i;
for (i = 0; i < pd->nr_perf_states; i++) { for (i = 0; i < pd->nr_perf_states; i++) {
if (pd->table[i].power > power_limit)
power = pd->table[i].power * MICROWATT_PER_MILLIWATT;
if (power > power_limit)
break; break;
} }
...@@ -68,7 +63,7 @@ static u64 set_pd_power_limit(struct dtpm *dtpm, u64 power_limit) ...@@ -68,7 +63,7 @@ static u64 set_pd_power_limit(struct dtpm *dtpm, u64 power_limit)
dev_pm_qos_update_request(&dtpm_devfreq->qos_req, freq); dev_pm_qos_update_request(&dtpm_devfreq->qos_req, freq);
power_limit = pd->table[i - 1].power * MICROWATT_PER_MILLIWATT; power_limit = pd->table[i - 1].power;
return power_limit; return power_limit;
} }
...@@ -110,7 +105,7 @@ static u64 get_pd_power_uw(struct dtpm *dtpm) ...@@ -110,7 +105,7 @@ static u64 get_pd_power_uw(struct dtpm *dtpm)
if (pd->table[i].frequency < freq) if (pd->table[i].frequency < freq)
continue; continue;
power = pd->table[i].power * MICROWATT_PER_MILLIWATT; power = pd->table[i].power;
power *= status.busy_time; power *= status.busy_time;
power >>= 10; power >>= 10;
......
...@@ -70,6 +70,10 @@ struct amd_cpudata { ...@@ -70,6 +70,10 @@ struct amd_cpudata {
u32 nominal_perf; u32 nominal_perf;
u32 lowest_nonlinear_perf; u32 lowest_nonlinear_perf;
u32 lowest_perf; u32 lowest_perf;
u32 min_limit_perf;
u32 max_limit_perf;
u32 min_limit_freq;
u32 max_limit_freq;
u32 max_freq; u32 max_freq;
u32 min_freq; u32 min_freq;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment