Message ID | 20220401071424.2869057-3-vladimir.zapolskiy@linaro.org |
---|---|
State | Accepted |
Commit | f84ccad5f5660f86a642a3d7e2bfdc4e7a8a2d49 |
Headers | show |
Series | cpufreq: qcom-cpufreq-hw: Fixes to DCVS interrupt handling on EPSS | expand |
On Fri 01 Apr 00:14 PDT 2022, Vladimir Zapolskiy wrote: > 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> This could have been picked up by the maintainer already in the previous version, if it wasn't the second patch in the series. Please send it separately, or as the first patch of the two, so we can ask Viresh to pick it up (just in case we don't reach an agreement of your next version of the other patch). Regards, Bjorn > --- > Changes from v1 to v2: > * added a comment about a replaced 19200 number in the code, thanks > to Bjorn for suggestion and review. > > 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 e17413a6f120..d5ede769b09a 100644 > --- a/drivers/cpufreq/qcom-cpufreq-hw.c > +++ b/drivers/cpufreq/qcom-cpufreq-hw.c > @@ -30,6 +30,7 @@ > > struct qcom_cpufreq_soc_data { > u32 reg_enable; > + u32 reg_domain_state; > u32 reg_dcvs_ctrl; > u32 reg_freq_lut; > u32 reg_volt_lut; > @@ -284,11 +285,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) > @@ -298,14 +304,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) > @@ -377,6 +381,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_dcvs_ctrl = 0xb0, > .reg_freq_lut = 0x100, > .reg_volt_lut = 0x200, > -- > 2.33.0 >
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index e17413a6f120..d5ede769b09a 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -30,6 +30,7 @@ struct qcom_cpufreq_soc_data { u32 reg_enable; + u32 reg_domain_state; u32 reg_dcvs_ctrl; u32 reg_freq_lut; u32 reg_volt_lut; @@ -284,11 +285,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) @@ -298,14 +304,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) @@ -377,6 +381,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_dcvs_ctrl = 0xb0, .reg_freq_lut = 0x100, .reg_volt_lut = 0x200,