All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] opp: fix dev_pm_opp_set_rate for different frequency at the same opp level
@ 2021-02-16 20:10 Jonathan Marek
  2021-02-17  4:53 ` Viresh Kumar
  2021-02-18  7:11 ` Viresh Kumar
  0 siblings, 2 replies; 4+ messages in thread
From: Jonathan Marek @ 2021-02-16 20:10 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: Viresh Kumar, Nishanth Menon, Stephen Boyd,
	open list:OPERATING PERFORMANCE POINTS (OPP),
	open list

There is not "nothing to do" when the opp is the same. The frequency can
be different from opp->rate.

Fixes: 81c4d8a3c414 ("opp: Keep track of currently programmed OPP")
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
---
 drivers/opp/core.c | 7 +++++--
 drivers/opp/opp.h  | 1 +
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index c3f3d9249cc5..f82cf72f433e 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -986,6 +986,7 @@ static int _set_opp(struct device *dev, struct opp_table *opp_table,
 		    struct dev_pm_opp *opp, unsigned long freq)
 {
 	struct dev_pm_opp *old_opp;
+	unsigned long old_freq;
 	int scaling_down, ret;
 
 	if (unlikely(!opp))
@@ -996,15 +997,16 @@ static int _set_opp(struct device *dev, struct opp_table *opp_table,
 		_find_current_opp(dev, opp_table);
 
 	old_opp = opp_table->current_opp;
+	old_freq = opp_table->current_freq;
 
 	/* Return early if nothing to do */
-	if (opp_table->enabled && old_opp == opp) {
+	if (opp_table->enabled && old_opp == opp && old_freq == freq) {
 		dev_dbg(dev, "%s: OPPs are same, nothing to do\n", __func__);
 		return 0;
 	}
 
 	dev_dbg(dev, "%s: switching OPP: Freq %lu -> %lu Hz, Level %u -> %u, Bw %u -> %u\n",
-		__func__, old_opp->rate, freq, old_opp->level, opp->level,
+		__func__, old_freq, freq, old_opp->level, opp->level,
 		old_opp->bandwidth ? old_opp->bandwidth[0].peak : 0,
 		opp->bandwidth ? opp->bandwidth[0].peak : 0);
 
@@ -1061,6 +1063,7 @@ static int _set_opp(struct device *dev, struct opp_table *opp_table,
 	/* Make sure current_opp doesn't get freed */
 	dev_pm_opp_get(opp);
 	opp_table->current_opp = opp;
+	opp_table->current_freq = freq;
 
 	return ret;
 }
diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h
index 9b9daf83b074..9f1d9c877380 100644
--- a/drivers/opp/opp.h
+++ b/drivers/opp/opp.h
@@ -186,6 +186,7 @@ struct opp_table {
 	enum opp_table_access shared_opp;
 	struct dev_pm_opp *current_opp;
 	struct dev_pm_opp *suspend_opp;
+	unsigned long current_freq;
 
 	struct mutex genpd_virt_dev_lock;
 	struct device **genpd_virt_devs;
-- 
2.26.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] opp: fix dev_pm_opp_set_rate for different frequency at the same opp level
  2021-02-16 20:10 [PATCH] opp: fix dev_pm_opp_set_rate for different frequency at the same opp level Jonathan Marek
@ 2021-02-17  4:53 ` Viresh Kumar
  2021-02-17 13:29   ` Jonathan Marek
  2021-02-18  7:11 ` Viresh Kumar
  1 sibling, 1 reply; 4+ messages in thread
From: Viresh Kumar @ 2021-02-17  4:53 UTC (permalink / raw)
  To: Jonathan Marek
  Cc: linux-arm-msm, Viresh Kumar, Nishanth Menon, Stephen Boyd,
	open list:OPERATING PERFORMANCE POINTS (OPP),
	open list

On 16-02-21, 15:10, Jonathan Marek wrote:
> There is not "nothing to do" when the opp is the same. The frequency can
> be different from opp->rate.

I am sorry but I am not sure what are you trying to fix here and what exactly is
broken here. Can you provide a usecase for your platform where this doesn't work
like it used to ?

> Fixes: 81c4d8a3c414 ("opp: Keep track of currently programmed OPP")
> Signed-off-by: Jonathan Marek <jonathan@marek.ca>
> ---
>  drivers/opp/core.c | 7 +++++--
>  drivers/opp/opp.h  | 1 +
>  2 files changed, 6 insertions(+), 2 deletions(-)

-- 
viresh

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] opp: fix dev_pm_opp_set_rate for different frequency at the same opp level
  2021-02-17  4:53 ` Viresh Kumar
@ 2021-02-17 13:29   ` Jonathan Marek
  0 siblings, 0 replies; 4+ messages in thread
From: Jonathan Marek @ 2021-02-17 13:29 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: linux-arm-msm, Viresh Kumar, Nishanth Menon, Stephen Boyd,
	open list:OPERATING PERFORMANCE POINTS (OPP),
	open list

On 2/16/21 11:53 PM, Viresh Kumar wrote:
> On 16-02-21, 15:10, Jonathan Marek wrote:
>> There is not "nothing to do" when the opp is the same. The frequency can
>> be different from opp->rate.
> 
> I am sorry but I am not sure what are you trying to fix here and what exactly is
> broken here. Can you provide a usecase for your platform where this doesn't work
> like it used to ?
> 

The specific case is this opp table:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/qcom/sm8250.dtsi#n439

It does not define every possible clock frequency, it only defines the 
rates at which a higher rpmhpd level must be used. Which is the intended 
use of opp.

Your change broke this completely: the clock rate change can be silently 
ignored because the opp level is the same. In particular it breaks 
bluetooth for this platform.

>> Fixes: 81c4d8a3c414 ("opp: Keep track of currently programmed OPP")
>> Signed-off-by: Jonathan Marek <jonathan@marek.ca>
>> ---
>>   drivers/opp/core.c | 7 +++++--
>>   drivers/opp/opp.h  | 1 +
>>   2 files changed, 6 insertions(+), 2 deletions(-)
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] opp: fix dev_pm_opp_set_rate for different frequency at the same opp level
  2021-02-16 20:10 [PATCH] opp: fix dev_pm_opp_set_rate for different frequency at the same opp level Jonathan Marek
  2021-02-17  4:53 ` Viresh Kumar
@ 2021-02-18  7:11 ` Viresh Kumar
  1 sibling, 0 replies; 4+ messages in thread
From: Viresh Kumar @ 2021-02-18  7:11 UTC (permalink / raw)
  To: Jonathan Marek
  Cc: linux-arm-msm, Viresh Kumar, Nishanth Menon, Stephen Boyd,
	open list:OPERATING PERFORMANCE POINTS (OPP),
	open list

On 16-02-21, 15:10, Jonathan Marek wrote:
> There is not "nothing to do" when the opp is the same. The frequency can
> be different from opp->rate.
> 
> Fixes: 81c4d8a3c414 ("opp: Keep track of currently programmed OPP")
> Signed-off-by: Jonathan Marek <jonathan@marek.ca>
> ---
>  drivers/opp/core.c | 7 +++++--
>  drivers/opp/opp.h  | 1 +
>  2 files changed, 6 insertions(+), 2 deletions(-)

Thanks, I have updated it a bit and applied, thanks.

-- 
viresh

-------------------------8<-------------------------

From: Jonathan Marek <jonathan@marek.ca>
Date: Tue, 16 Feb 2021 15:10:29 -0500
Subject: [PATCH] opp: Don't skip freq update for different frequency

We skip the OPP update if the current and target OPPs are same. This is
fine for the devices that don't support frequency but may cause issues
for the ones that need to program frequency.

An OPP entry doesn't really signify a single operating frequency but
rather the highest frequency at which the other properties of the OPP
entry apply. And we may reach here with different frequency values,
while all of them would point to the same OPP entry in the OPP table.

We just need to update the clock frequency in that case, though in order
to not add special exit points we reuse the code flow from a normal
path.

While at it, rearrange the conditionals in the 'if' statement to check
'enabled' flag at the end.

Fixes: 81c4d8a3c414 ("opp: Keep track of currently programmed OPP")
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
[ Viresh: Improved commit log and subject, rename current_freq as
	  current_rate, document it, remove local variable and rearrange
	  code. ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/opp/core.c | 8 +++++---
 drivers/opp/opp.h  | 2 ++
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index c3f3d9249cc5..c2689386a906 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -998,14 +998,15 @@ static int _set_opp(struct device *dev, struct opp_table *opp_table,
 	old_opp = opp_table->current_opp;
 
 	/* Return early if nothing to do */
-	if (opp_table->enabled && old_opp == opp) {
+	if (old_opp == opp && opp_table->current_rate == freq &&
+	    opp_table->enabled) {
 		dev_dbg(dev, "%s: OPPs are same, nothing to do\n", __func__);
 		return 0;
 	}
 
 	dev_dbg(dev, "%s: switching OPP: Freq %lu -> %lu Hz, Level %u -> %u, Bw %u -> %u\n",
-		__func__, old_opp->rate, freq, old_opp->level, opp->level,
-		old_opp->bandwidth ? old_opp->bandwidth[0].peak : 0,
+		__func__, opp_table->current_rate, freq, old_opp->level,
+		opp->level, old_opp->bandwidth ? old_opp->bandwidth[0].peak : 0,
 		opp->bandwidth ? opp->bandwidth[0].peak : 0);
 
 	scaling_down = _opp_compare_key(old_opp, opp);
@@ -1061,6 +1062,7 @@ static int _set_opp(struct device *dev, struct opp_table *opp_table,
 	/* Make sure current_opp doesn't get freed */
 	dev_pm_opp_get(opp);
 	opp_table->current_opp = opp;
+	opp_table->current_rate = freq;
 
 	return ret;
 }
diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h
index 9b9daf83b074..50fb9dced3c5 100644
--- a/drivers/opp/opp.h
+++ b/drivers/opp/opp.h
@@ -135,6 +135,7 @@ enum opp_table_access {
  * @clock_latency_ns_max: Max clock latency in nanoseconds.
  * @parsed_static_opps: Count of devices for which OPPs are initialized from DT.
  * @shared_opp: OPP is shared between multiple devices.
+ * @current_rate: Currently configured frequency.
  * @current_opp: Currently configured OPP for the table.
  * @suspend_opp: Pointer to OPP to be used during device suspend.
  * @genpd_virt_dev_lock: Mutex protecting the genpd virtual device pointers.
@@ -184,6 +185,7 @@ struct opp_table {
 
 	unsigned int parsed_static_opps;
 	enum opp_table_access shared_opp;
+	unsigned long current_rate;
 	struct dev_pm_opp *current_opp;
 	struct dev_pm_opp *suspend_opp;
 

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-02-18  7:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-16 20:10 [PATCH] opp: fix dev_pm_opp_set_rate for different frequency at the same opp level Jonathan Marek
2021-02-17  4:53 ` Viresh Kumar
2021-02-17 13:29   ` Jonathan Marek
2021-02-18  7:11 ` Viresh Kumar

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.