Unified cpufreq support

From Omni
Jump to: navigation, search

Unified cpufreq support for MSM kernels

This allows settings cpufreq governor scaling_min_freq and scaling_max_freq unified for all cores and make them persistent across core activation So if a core come sonline again it will use the same cpufreq parameters automatically

e.g. echo ondemand > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

will set the governor for all online cores and if a core comes online it will automatically use this value

Example implementation for N1

https://github.com/omnirom/android_kernel_oppo_apq8064/blob/android-4.4/arch/arm/mach-msm/cpufreq.c

https://github.com/omnirom/android_kernel_oppo_apq8064/blob/android-4.4/drivers/cpufreq/cpufreq.c

Commits

https://github.com/omnirom/android_kernel_oppo_apq8064/commit/2f27d2e02b154ec590c856d15d9af0472c627cc8

https://github.com/omnirom/android_kernel_oppo_apq8064/commit/0d0ed91fe62f348080f5485e2c23d61562bd44c9

https://github.com/omnirom/android_kernel_oppo_apq8064/commit/77fc819df3f6f6fa9eed07c4ae97f97e04b02b74

https://github.com/omnirom/android_kernel_oppo_apq8064/commit/3c3865d0182bc0fe4ad7d4de52231a9d6ae67a99


Details

arch/arm/mach-msm/cpufreq.c

       policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
       cpumask_copy(policy->related_cpus, cpu_possible_mask);

This enables the "related_cpus" information. So the following code will always "find" cpu0 which is the "reference" core

https://github.com/omnirom/android_kernel_oppo_apq8064/blob/android-4.4/drivers/cpufreq/cpufreq.c#L1245

       for_each_online_cpu(sibling) {
               cp = per_cpu(cpufreq_cpu_data, sibling);
               if (cp && cp->governor &&
                (cpumask_test_cpu(cpu, cp->related_cpus))) {
                       policy->governor = cp->governor;
                       found = 1;
                       break;
               }
       }

drivers/cpufreq/cpufreq.c

Adds new syfs functions which will iterate over all currently online cpus to apply the value

static ssize_t store_scaling_governor(struct cpufreq_policy *policy, const char *buf, size_t count)

static ssize_t store_scaling_max_freq(struct cpufreq_policy *policy, const char *buf, size_t count)

static ssize_t store_scaling_min_freq(struct cpufreq_policy *policy, const char *buf, size_t count)

This works the same way for all three parameters e.g.

https://github.com/omnirom/android_kernel_oppo_apq8064/blob/android-4.4/drivers/cpufreq/cpufreq.c#L478


Applying values for cpus when the come online

Sets policy values to the same as for the cpu "found" by cp->related_cpus

static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)

https://github.com/omnirom/android_kernel_oppo_apq8064/blob/android-4.4/drivers/cpufreq/cpufreq.c#L1269

       if (found) {
               /* Calling the driver can overwrite policy frequencies */
               policy->min = cp->min;
               policy->max = cp->max;
               policy->user_policy.min = cp->user_policy.min;
               policy->user_policy.max = cp->user_policy.max;
       }

Disable policy overwriting again in cpufreq_add_dev_policy

static int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy, struct device *dev)

https://github.com/omnirom/android_kernel_oppo_apq8064/blob/android-4.4/drivers/cpufreq/cpufreq.c#L993

This is simply unneeded because we have set all required in cpufreq_add_dev