Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 07098af5 authored by Junjie Wu's avatar Junjie Wu
Browse files

qcom-cpufreq: Allow all CPUs to get cpu_clk on targets with sync CPUs



For targets with synchronous CPU clocks, only CPU0 has a clock pointer in
cpu_clks[]. This forces CPU0 to be the last CPU to be hotplugged out, or go
to certain low power mode that needs to disable CPU clocks.

Remove this requirement by adding clock pointer for all CPUs. Drivers
that ask for CPU clocks will get same clock for CPUs in sync.

Change-Id: Ib97af2c3b0fdbc8dbb78364178225cc64ed02036
Signed-off-by: default avatarJunjie Wu <junjiew@codeaurora.org>
parent b638af72
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/io.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/cpu.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
@@ -50,6 +51,9 @@ static struct mux_div_clk a7ssmux = {

static struct clk_lookup clock_tbl_a7[] = {
	CLK_LOOKUP("cpu0_clk",	a7ssmux.c, "0.qcom,msm-cpufreq"),
	CLK_LOOKUP("cpu1_clk",	a7ssmux.c, "0.qcom,msm-cpufreq"),
	CLK_LOOKUP("cpu2_clk",	a7ssmux.c, "0.qcom,msm-cpufreq"),
	CLK_LOOKUP("cpu3_clk",	a7ssmux.c, "0.qcom,msm-cpufreq"),
	CLK_LOOKUP("cpu0_clk",	a7ssmux.c, "fe805664.qcom,pm"),
	CLK_LOOKUP("cpu0_clk",   a7ssmux.c, "8600664.qcom,pm"),
};
@@ -223,7 +227,7 @@ static int of_get_clk_src(struct platform_device *pdev, struct clk_src *parents)
static int clock_a7_probe(struct platform_device *pdev)
{
	struct resource *res;
	int speed_bin = 0, version = 0, rc;
	int speed_bin = 0, version = 0, rc, cpu;
	unsigned long rate, aux_rate;
	struct clk *aux_clk, *main_pll;
	char prop_name[] = "qcom,speedX-bin-vX";
@@ -307,8 +311,11 @@ static int clock_a7_probe(struct platform_device *pdev)
	 * that the clocks have already been prepared and enabled by the time
	 * they take over.
	 */
	get_online_cpus();
	for_each_online_cpu(cpu)
		WARN(clk_prepare_enable(&a7ssmux.c),
			"Unable to turn on CPU clock");
	put_online_cpus();
	return 0;
}

+11 −19
Original line number Diff line number Diff line
@@ -48,7 +48,6 @@ static unsigned int freq_index[NR_CPUS];
static unsigned int max_freq_index;
static struct cpufreq_frequency_table *freq_table;
static unsigned int *l2_khz;
static bool is_sync;
static unsigned long *mem_bw;
static bool hotplug_ready;

@@ -221,8 +220,6 @@ static int msm_cpufreq_verify(struct cpufreq_policy *policy)

static unsigned int msm_cpufreq_get_freq(unsigned int cpu)
{
	if (is_sync)
		cpu = 0;
	return clk_get_rate(cpu_clk[cpu]) / 1000;
}

@@ -233,26 +230,25 @@ static int msm_cpufreq_init(struct cpufreq_policy *policy)
	int ret = 0;
	struct cpufreq_frequency_table *table;
	struct cpufreq_work_struct *cpu_work = NULL;
	int cpu;

	table = cpufreq_frequency_get_table(policy->cpu);
	if (table == NULL)
		return -ENODEV;
	/*
	 * In some SoC, cpu cores' frequencies can not
	 * be changed independently. Each cpu is bound to
	 * same frequency. Hence set the cpumask to all cpu.
	 * In some SoC, some cores are clocked by same source, and their
	 * frequencies can not be changed independently. Find all other
	 * CPUs that share same clock, and mark them as controlled by
	 * same policy.
	 */
	if (is_sync)
		cpumask_setall(policy->cpus);
	for_each_possible_cpu(cpu)
		if (cpu_clk[cpu] == cpu_clk[policy->cpu])
			cpumask_set_cpu(cpu, policy->cpus);

	cpu_work = &per_cpu(cpufreq_work, policy->cpu);
	INIT_WORK(&cpu_work->work, set_cpu_work);
	init_completion(&cpu_work->complete);

	/* synchronous cpus share the same policy */
	if (!cpu_clk[policy->cpu])
		return 0;

	if (cpufreq_frequency_table_cpuinfo(policy, table)) {
#ifdef CONFIG_MSM_CPU_FREQ_SET_MIN_MAX
		policy->cpuinfo.min_freq = CONFIG_MSM_CPU_FREQ_MIN;
@@ -561,14 +557,10 @@ static int __init msm_cpufreq_probe(struct platform_device *pdev)
	for_each_possible_cpu(cpu) {
		snprintf(clk_name, sizeof(clk_name), "cpu%d_clk", cpu);
		c = devm_clk_get(dev, clk_name);
		if (!IS_ERR(c))
		if (IS_ERR(c))
			return PTR_ERR(c);
		cpu_clk[cpu] = c;
		else
			is_sync = true;
	}

	if (!cpu_clk[0])
		return -ENODEV;
	hotplug_ready = true;

	ret = cpufreq_parse_dt(dev);