• Pierre Gondois's avatar
    cpufreq: CPPC: Fix performance/frequency conversion · ec1c7ad4
    Pierre Gondois authored
    CPUfreq governors request CPU frequencies using information
    on current CPU usage. The CPPC driver converts them to
    performance requests. Frequency targets are computed as:
    	target_freq = (util / cpu_capacity) * max_freq
    target_freq is then clamped between [policy->min, policy->max].
    
    The CPPC driver converts performance values to frequencies
    (and vice-versa) using cppc_cpufreq_perf_to_khz() and
    cppc_cpufreq_khz_to_perf(). These functions both use two different
    factors depending on the range of the input value. For
    cppc_cpufreq_khz_to_perf():
    - (NOMINAL_PERF / NOMINAL_FREQ) or
    - (LOWEST_PERF / LOWEST_FREQ)
    and for cppc_cpufreq_perf_to_khz():
    - (NOMINAL_FREQ / NOMINAL_PERF) or
    - ((NOMINAL_PERF - LOWEST_FREQ) / (NOMINAL_PERF - LOWEST_PERF))
    
    This means:
    1- the functions are not inverse for some values:
       (perf_to_khz(khz_to_perf(x)) != x)
    2- cppc_cpufreq_perf_to_khz(LOWEST_PERF) can sometimes give
       a different value from LOWEST_FREQ due to integer approximation
    3- it is implied that performance and frequency are proportional
       (NOMINAL_FREQ / NOMINAL_PERF) == (LOWEST_PERF / LOWEST_FREQ)
    
    This patch changes the conversion functions to an affine function.
    This fixes the 3 points above.
    Suggested-by: default avatarLukasz Luba <lukasz.luba@arm.com>
    Suggested-by: default avatarMorten Rasmussen <morten.rasmussen@arm.com>
    Signed-off-by: default avatarPierre Gondois <Pierre.Gondois@arm.com>
    Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
    ec1c7ad4
cppc_cpufreq.c 20.2 KB