diff mbox

[10/10] cpufreq-dt: Add support for operating-points-v2 bindings

Message ID a486d730c2c2dacd387feee13a4c800fdc641077.1434369079.git.viresh.kumar@linaro.org (mailing list archive)
State New, archived
Headers show

Commit Message

Viresh Kumar June 15, 2015, 11:57 a.m. UTC
Support for parsing operating-points-v2 bindings is in place now, lets
modify cpufreq-dt driver to use them.

For backward compatibility we will continue to support earlier bindings.
Special handling for that is required, to make sure OPPs are initialized
for all the CPUs.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/cpufreq-dt.c | 58 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 47 insertions(+), 11 deletions(-)

Comments

Bartlomiej Zolnierkiewicz July 9, 2015, 4:13 p.m. UTC | #1
Hi,

On Monday, June 15, 2015 05:27:36 PM Viresh Kumar wrote:
> Support for parsing operating-points-v2 bindings is in place now, lets
> modify cpufreq-dt driver to use them.

I believe that following patches:

* [PATCH v2 1/7] opp: add dev_pm_opp_get_turbo_mode_setting() helper
  (http://lkml.org/lkml/2015/7/9/420)

* [PATCH v2 2/7] cpufreq: opp: fix handling of turbo modes
  (http://lkml.org/lkml/2015/7/9/421)

should be integrated into this patch series before patch #10 (the current
one) can be applied.

[ Please see http://lkml.org/lkml/2015/7/9/419 for more details. ]

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics
Bartlomiej Zolnierkiewicz July 9, 2015, 4:44 p.m. UTC | #2
On Thursday, July 09, 2015 06:13:54 PM Bartlomiej Zolnierkiewicz wrote:
> 
> Hi,
> 
> On Monday, June 15, 2015 05:27:36 PM Viresh Kumar wrote:
> > Support for parsing operating-points-v2 bindings is in place now, lets
> > modify cpufreq-dt driver to use them.
> 
> I believe that following patches:
> 
> * [PATCH v2 1/7] opp: add dev_pm_opp_get_turbo_mode_setting() helper
>   (http://lkml.org/lkml/2015/7/9/420)
> 
> * [PATCH v2 2/7] cpufreq: opp: fix handling of turbo modes
>   (http://lkml.org/lkml/2015/7/9/421)
> 
> should be integrated into this patch series before patch #10 (the current
> one) can be applied.
> 
> [ Please see http://lkml.org/lkml/2015/7/9/419 for more details. ]

On the 2nd thought here is the issue description, so people don't
have to search for it:

With the current code the turbo-mode opp-s are not distinguished in
any way in the cpufreq subsystem and once somebody defines them in
their DTS file they are treated as normal modes. I.e. if you define
opp-s using opp-v2 bindings in your DTS file (for use by cpufreq-dt
driver) and some are marked as turbo modes then the freq_table (build
by cpufreq core) will contain turbo mode frequencies and cpufreq-dt
driver will use them as normal frequencies.  This is certainly not
a desired behavior.

To fix it I added opp core helper to check whether opp is a turbo
mode and during build of freq_table turbo mode frequencies are
marked with special flag (CPUFREQ_BOOST_FREQ).  Such frequencies
are ignored by cpufreq core unless 'boost' mode is enabled.
'boost' mode support needs to be explicitly supported & enabled in
a specific cpufreq driver.  For the moment it is only available for
Exynos4x12 cpufreq driver but my patchset (converting Exynos4x12
platforms to use cpufreq-dt driver) makes it available for use in
cpufreq-dt (to be enabled from your platform support when needed).

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics
Viresh Kumar July 15, 2015, 2:59 a.m. UTC | #3
On 09-07-15, 18:13, Bartlomiej Zolnierkiewicz wrote:
> I believe that following patches:
> 
> * [PATCH v2 1/7] opp: add dev_pm_opp_get_turbo_mode_setting() helper
>   (http://lkml.org/lkml/2015/7/9/420)
> 
> * [PATCH v2 2/7] cpufreq: opp: fix handling of turbo modes
>   (http://lkml.org/lkml/2015/7/9/421)
> 
> should be integrated into this patch series before patch #10 (the current
> one) can be applied.

Hi Bartlomiej,

I haven't tried for the complete support yet, I will take care of
boost frequencies as well, but not in this series.
diff mbox

Patch

diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index bab67db54b7e..f7bb2976059a 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -184,7 +184,6 @@  static int allocate_resources(int cpu, struct device **cdev,
 
 static int cpufreq_init(struct cpufreq_policy *policy)
 {
-	struct cpufreq_dt_platform_data *pd;
 	struct cpufreq_frequency_table *freq_table;
 	struct device_node *np;
 	struct private_data *priv;
@@ -192,7 +191,8 @@  static int cpufreq_init(struct cpufreq_policy *policy)
 	struct regulator *cpu_reg;
 	struct clk *cpu_clk;
 	unsigned long min_uV = ~0, max_uV = 0;
-	unsigned int transition_latency;
+	unsigned int transition_latency = 0;
+	bool need_update = false;
 	int ret;
 
 	ret = allocate_resources(policy->cpu, &cpu_dev, &cpu_reg, &cpu_clk);
@@ -208,8 +208,47 @@  static int cpufreq_init(struct cpufreq_policy *policy)
 		goto out_put_reg_clk;
 	}
 
-	/* OPPs might be populated at runtime, don't check for error here */
-	of_init_opp_table(cpu_dev);
+	/* Get OPP-sharing information from "operating-points-v2" bindings */
+	ret = of_get_cpus_sharing_opps(cpu_dev, policy->cpus);
+	if (ret) {
+		/*
+		 * operating-points-v2 not supported, fallback to old method of
+		 * finding shared-OPPs for backward compatibility.
+		 */
+		if (ret == -ENOENT)
+			need_update = true;
+		else
+			goto out_node_put;
+	}
+
+	/*
+	 * Initialize OPP tables for all policy->cpus. They will be shared by
+	 * all CPUs which have marked their CPUs shared with OPP bindings.
+	 *
+	 * For platforms not using operating-points-v2 bindings, we do this
+	 * before updating policy->cpus. Otherwise, we will end up creating
+	 * duplicate OPPs for policy->cpus.
+	 *
+	 * OPPs might be populated at runtime, don't check for error here
+	 */
+	of_cpumask_init_opp_table(policy->cpus);
+
+	if (need_update) {
+		struct cpufreq_dt_platform_data *pd = cpufreq_get_driver_data();
+
+		if (!pd || !pd->independent_clocks)
+			cpumask_setall(policy->cpus);
+
+		/*
+		 * OPP tables are initialized only for policy->cpu, do it for
+		 * others as well.
+		 */
+		set_cpus_sharing_opps(cpu_dev, policy->cpus);
+
+		of_property_read_u32(np, "clock-latency", &transition_latency);
+	} else {
+		transition_latency = dev_pm_opp_get_max_clock_latency(cpu_dev);
+	}
 
 	/*
 	 * But we need OPP table to function so if it is not there let's
@@ -230,7 +269,7 @@  static int cpufreq_init(struct cpufreq_policy *policy)
 
 	of_property_read_u32(np, "voltage-tolerance", &priv->voltage_tolerance);
 
-	if (of_property_read_u32(np, "clock-latency", &transition_latency))
+	if (!transition_latency)
 		transition_latency = CPUFREQ_ETERNAL;
 
 	if (!IS_ERR(cpu_reg)) {
@@ -293,10 +332,6 @@  static int cpufreq_init(struct cpufreq_policy *policy)
 
 	policy->cpuinfo.transition_latency = transition_latency;
 
-	pd = cpufreq_get_driver_data();
-	if (!pd || !pd->independent_clocks)
-		cpumask_setall(policy->cpus);
-
 	of_node_put(np);
 
 	return 0;
@@ -306,7 +341,8 @@  static int cpufreq_init(struct cpufreq_policy *policy)
 out_free_priv:
 	kfree(priv);
 out_free_opp:
-	of_free_opp_table(cpu_dev);
+	of_cpumask_free_opp_table(policy->cpus);
+out_node_put:
 	of_node_put(np);
 out_put_reg_clk:
 	clk_put(cpu_clk);
@@ -322,7 +358,7 @@  static int cpufreq_exit(struct cpufreq_policy *policy)
 
 	cpufreq_cooling_unregister(priv->cdev);
 	dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
-	of_free_opp_table(priv->cpu_dev);
+	of_cpumask_free_opp_table(policy->related_cpus);
 	clk_put(policy->clk);
 	if (!IS_ERR(priv->cpu_reg))
 		regulator_put(priv->cpu_reg);