| From 84879a09efef0abcde8eedcf7cb5da672b1822e4 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 1 Apr 2022 10:14:24 +0300 |
| Subject: cpufreq: qcom-cpufreq-hw: Fix throttle frequency value on EPSS |
| platforms |
| |
| From: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org> |
| |
| [ Upstream commit f84ccad5f5660f86a642a3d7e2bfdc4e7a8a2d49 ] |
| |
| On QCOM platforms with EPSS flavour of cpufreq IP a throttled frequency is |
| obtained from another register REG_DOMAIN_STATE, thus the helper function |
| qcom_lmh_get_throttle_freq() should be modified accordingly, as for now |
| it returns gibberish since .reg_current_vote is unset for EPSS hardware. |
| |
| To exclude a hardcoded magic number 19200 it is replaced by "xo" clock rate |
| in KHz. |
| |
| Fixes: 275157b367f4 ("cpufreq: qcom-cpufreq-hw: Add dcvs interrupt support") |
| Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org> |
| Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org> |
| Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/cpufreq/qcom-cpufreq-hw.c | 17 +++++++++++------ |
| 1 file changed, 11 insertions(+), 6 deletions(-) |
| |
| diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c |
| index 60d38f62308a..1e99b71e7844 100644 |
| --- a/drivers/cpufreq/qcom-cpufreq-hw.c |
| +++ b/drivers/cpufreq/qcom-cpufreq-hw.c |
| @@ -28,6 +28,7 @@ |
| |
| struct qcom_cpufreq_soc_data { |
| u32 reg_enable; |
| + u32 reg_domain_state; |
| u32 reg_freq_lut; |
| u32 reg_volt_lut; |
| u32 reg_current_vote; |
| @@ -267,11 +268,16 @@ static void qcom_get_related_cpus(int index, struct cpumask *m) |
| } |
| } |
| |
| -static unsigned int qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data) |
| +static unsigned long qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data) |
| { |
| - unsigned int val = readl_relaxed(data->base + data->soc_data->reg_current_vote); |
| + unsigned int lval; |
| |
| - return (val & 0x3FF) * 19200; |
| + if (data->soc_data->reg_current_vote) |
| + lval = readl_relaxed(data->base + data->soc_data->reg_current_vote) & 0x3ff; |
| + else |
| + lval = readl_relaxed(data->base + data->soc_data->reg_domain_state) & 0xff; |
| + |
| + return lval * xo_rate; |
| } |
| |
| static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data) |
| @@ -281,14 +287,12 @@ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data) |
| struct device *dev = get_cpu_device(cpu); |
| unsigned long freq_hz, throttled_freq; |
| struct dev_pm_opp *opp; |
| - unsigned int freq; |
| |
| /* |
| * Get the h/w throttled frequency, normalize it using the |
| * registered opp table and use it to calculate thermal pressure. |
| */ |
| - freq = qcom_lmh_get_throttle_freq(data); |
| - freq_hz = freq * HZ_PER_KHZ; |
| + freq_hz = qcom_lmh_get_throttle_freq(data); |
| |
| opp = dev_pm_opp_find_freq_floor(dev, &freq_hz); |
| if (IS_ERR(opp) && PTR_ERR(opp) == -ERANGE) |
| @@ -357,6 +361,7 @@ static const struct qcom_cpufreq_soc_data qcom_soc_data = { |
| |
| static const struct qcom_cpufreq_soc_data epss_soc_data = { |
| .reg_enable = 0x0, |
| + .reg_domain_state = 0x20, |
| .reg_freq_lut = 0x100, |
| .reg_volt_lut = 0x200, |
| .reg_perf_state = 0x320, |
| -- |
| 2.35.1 |
| |