drivers: lmh_dcvsh: Provide CPU frequency in Hz for opp interface

The frequency requested by LMH DCVSh hardware may not match an actual
frequency in the CPU clock plan. LMH DCVSh driver uses OPP framework to
match the hardware frequency request to a nearest valid CPU frequency. OPP
interface expects the frequency input in Hz and DCVSh driver is passing the
frequency value in kHz, which will result in error. So the hardware
mitigation frequency reported by the driver may not reflect the actual
frequency that the CPU is mitigated to.

Provide the hardware frequency input in Hz for OPP interface in LMH DCVSh
driver. Hardware mitigation frequency can be lower than the lowest
possible CPU frequency. In that case freq floor call will fail. So call
dev_pm_opp_find_freq_ceil to match to the lowest CPU frequency.

Change-Id: I6e9f7f5129320c37d41e20ca9735129f25440134
Signed-off-by: Ram Chandrasekar <rkumbako@codeaurora.org>
This commit is contained in:
Ram Chandrasekar 2017-01-25 17:05:11 -07:00
parent 110e102fe3
commit 6f9814c90a

View file

@ -68,6 +68,8 @@
_max = (_val) & 0x3FF; \
_max *= 19200; \
} while (0)
#define FREQ_KHZ_TO_HZ(_val) ((_val) * 1000)
#define FREQ_HZ_TO_KHZ(_val) ((_val) / 1000)
enum lmh_hw_trips {
LIMITS_TRIP_LO,
@ -114,6 +116,7 @@ static uint32_t msm_lmh_mitigation_notify(struct msm_lmh_dcvs_hw *hw)
uint32_t max_limit = 0, val = 0;
struct device *cpu_dev = NULL;
unsigned long freq_val;
struct dev_pm_opp *opp_entry;
val = readl_relaxed(hw->osm_hw_reg);
dcvsh_get_frequency(val, max_limit);
@ -124,11 +127,23 @@ static uint32_t msm_lmh_mitigation_notify(struct msm_lmh_dcvs_hw *hw)
goto notify_exit;
}
freq_val = max_limit;
freq_val = FREQ_KHZ_TO_HZ(max_limit);
rcu_read_lock();
dev_pm_opp_find_freq_floor(cpu_dev, &freq_val);
opp_entry = dev_pm_opp_find_freq_floor(cpu_dev, &freq_val);
/*
* Hardware mitigation frequency can be lower than the lowest
* possible CPU frequency. In that case freq floor call will
* fail with -ERANGE and we need to match to the lowest
* frequency using freq_ceil.
*/
if (IS_ERR(opp_entry) && PTR_ERR(opp_entry) == -ERANGE) {
opp_entry = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_val);
if (IS_ERR(opp_entry))
dev_err(cpu_dev, "frequency:%lu. opp error:%ld\n",
freq_val, PTR_ERR(opp_entry));
}
rcu_read_unlock();
max_limit = freq_val;
max_limit = FREQ_HZ_TO_KHZ(freq_val);
sched_update_cpu_freq_min_max(&hw->core_map, 0, max_limit);
trace_lmh_dcvs_freq(cpumask_first(&hw->core_map), max_limit);