All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] RESEND: clk: Avoid sending high rates to downstream clocks during set_rate
@ 2017-10-04  2:30 Linus Walleij
  2017-10-30 14:23 ` Linus Walleij
  2017-11-02  7:00 ` Stephen Boyd
  0 siblings, 2 replies; 6+ messages in thread
From: Linus Walleij @ 2017-10-04  2:30 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Opera, John Stultz

From: Stephen Boyd <sboyd@codeaurora.org>

If a clock is on and we call clk_set_rate() on it we may get into
a situation where the clock temporarily increases in rate
dramatically while we walk the tree and call .set_rate() ops. For
example, consider a case where a PLL feeds into a divider.
Initially the divider is set to divide by 1 and the PLL is
running fairly slow (100MHz). The downstream consumer of the
divider output can only handle rates =< 400 MHz, but the divider
can only choose between divisors of 1 and 4.

 +-----+   +----------------+
 | PLL |-->| div 1 or div 4 |---> consumer device
 +-----+   +----------------+

To achieve a rate of 400MHz on the output of the divider, we
would have to set the rate of the PLL to 1.6 GHz and then divide
it by 4. The current code would set the PLL to 1.6GHz first while
the divider is still set to 1, thus causing the downstream
consumer of the clock to receive a few clock cycles of 1.6GHz
clock (far beyond it's maximum acceptable rate). We should be
changing the divider first before increasing the PLL rate to
avoid this problem.

Therefore, set the rate of any child clocks that are increasing
in rate from their current rate so that they can increase their
dividers if necessary. We assume that there isn't such a thing as
minimum rate requirements.

Cc: Opera <montvid@gmail.com>
Cc: John Stultz <john.stultz@linaro.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
Stephen: just wanted to check what's up with this patch.
When I apply it on my kernel I get graphics on the Nexus7,
when I don't, I don't.

OpenWRT has started to carry the patch in their tree I noticed.
I found it in John Stultz patch stack.

Is there some similar patch floating in some other series, is
it fundamentally wrong or something else?

Just wanted to reboot the discussion so we know where this is
standing.
---
 drivers/clk/clk.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index c8d83acda006..324e4fa11802 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1468,12 +1468,12 @@ static struct clk_core *clk_propagate_rate_change(struct clk_core *core,
  * walk down a subtree and set the new rates notifying the rate
  * change on the way
  */
-static void clk_change_rate(struct clk_core *core)
+static void
+clk_change_rate(struct clk_core *core, unsigned long best_parent_rate)
 {
 	struct clk_core *child;
 	struct hlist_node *tmp;
 	unsigned long old_rate;
-	unsigned long best_parent_rate = 0;
 	bool skip_set_rate = false;
 	struct clk_core *old_parent;
 	struct clk_core *parent = NULL;
@@ -1525,6 +1525,7 @@ static void clk_change_rate(struct clk_core *core)
 	trace_clk_set_rate_complete(core, core->new_rate);
 
 	core->rate = clk_recalc(core, best_parent_rate);
+	core->rate = core->new_rate;
 
 	if (core->flags & CLK_SET_RATE_UNGATE) {
 		unsigned long flags;
@@ -1552,12 +1553,13 @@ static void clk_change_rate(struct clk_core *core)
 		/* Skip children who will be reparented to another clock */
 		if (child->new_parent && child->new_parent != core)
 			continue;
-		clk_change_rate(child);
+		if (child->new_rate != child->rate)
+			clk_change_rate(child, core->new_rate);
 	}
 
-	/* handle the new child who might not be in core->children yet */
-	if (core->new_child)
-		clk_change_rate(core->new_child);
+	/* handle the new child who might not be in clk->children yet */
+	if (core->new_child && core->new_child->new_rate != core->new_child->rate)
+		clk_change_rate(core->new_child, core->new_rate);
 }
 
 static int clk_core_set_rate_nolock(struct clk_core *core,
@@ -1565,6 +1567,7 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
 {
 	struct clk_core *top, *fail_clk;
 	unsigned long rate = req_rate;
+	unsigned long parent_rate;
 
 	if (!core)
 		return 0;
@@ -1590,8 +1593,13 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
 		return -EBUSY;
 	}
 
+	if (top->parent)
+		parent_rate = top->parent->rate;
+	else
+		parent_rate = 0;
+
 	/* change the rates */
-	clk_change_rate(top);
+	clk_change_rate(top, parent_rate);
 
 	core->req_rate = req_rate;
 
-- 
2.13.5

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

* Re: [PATCH] RESEND: clk: Avoid sending high rates to downstream clocks during set_rate
  2017-10-04  2:30 [PATCH] RESEND: clk: Avoid sending high rates to downstream clocks during set_rate Linus Walleij
@ 2017-10-30 14:23 ` Linus Walleij
  2017-11-02  7:00 ` Stephen Boyd
  1 sibling, 0 replies; 6+ messages in thread
From: Linus Walleij @ 2017-10-30 14:23 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Opera, John Stultz

On Wed, Oct 4, 2017 at 4:30 AM, Linus Walleij <linus.walleij@linaro.org> wrote:

> From: Stephen Boyd <sboyd@codeaurora.org>
>
> If a clock is on and we call clk_set_rate() on it we may get into
> a situation where the clock temporarily increases in rate
> dramatically while we walk the tree and call .set_rate() ops. For
> example, consider a case where a PLL feeds into a divider.
> Initially the divider is set to divide by 1 and the PLL is
> running fairly slow (100MHz). The downstream consumer of the
> divider output can only handle rates =< 400 MHz, but the divider
> can only choose between divisors of 1 and 4.
>
>  +-----+   +----------------+
>  | PLL |-->| div 1 or div 4 |---> consumer device
>  +-----+   +----------------+
>
> To achieve a rate of 400MHz on the output of the divider, we
> would have to set the rate of the PLL to 1.6 GHz and then divide
> it by 4. The current code would set the PLL to 1.6GHz first while
> the divider is still set to 1, thus causing the downstream
> consumer of the clock to receive a few clock cycles of 1.6GHz
> clock (far beyond it's maximum acceptable rate). We should be
> changing the divider first before increasing the PLL rate to
> avoid this problem.
>
> Therefore, set the rate of any child clocks that are increasing
> in rate from their current rate so that they can increase their
> dividers if necessary. We assume that there isn't such a thing as
> minimum rate requirements.
>
> Cc: Opera <montvid@gmail.com>
> Cc: John Stultz <john.stultz@linaro.org>
> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> ---
> Stephen: just wanted to check what's up with this patch.
> When I apply it on my kernel I get graphics on the Nexus7,
> when I don't, I don't.
>
> OpenWRT has started to carry the patch in their tree I noticed.
> I found it in John Stultz patch stack.
>
> Is there some similar patch floating in some other series, is
> it fundamentally wrong or something else?
>
> Just wanted to reboot the discussion so we know where this is
> standing.

Gentle ping on this patch too.

Sorry for pushing, it's just so nice to have graphics working
out-of-the-box on Nexus 7.

Yours,
Linus Walleij

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

* Re: [PATCH] RESEND: clk: Avoid sending high rates to downstream clocks during set_rate
  2017-10-04  2:30 [PATCH] RESEND: clk: Avoid sending high rates to downstream clocks during set_rate Linus Walleij
  2017-10-30 14:23 ` Linus Walleij
@ 2017-11-02  7:00 ` Stephen Boyd
  1 sibling, 0 replies; 6+ messages in thread
From: Stephen Boyd @ 2017-11-02  7:00 UTC (permalink / raw)
  To: Linus Walleij; +Cc: Michael Turquette, linux-clk, Opera, John Stultz

On 10/04, Linus Walleij wrote:
> From: Stephen Boyd <sboyd@codeaurora.org>
> 
> If a clock is on and we call clk_set_rate() on it we may get into
> a situation where the clock temporarily increases in rate
> dramatically while we walk the tree and call .set_rate() ops. For
> example, consider a case where a PLL feeds into a divider.
> Initially the divider is set to divide by 1 and the PLL is
> running fairly slow (100MHz). The downstream consumer of the
> divider output can only handle rates =< 400 MHz, but the divider
> can only choose between divisors of 1 and 4.
> 
>  +-----+   +----------------+
>  | PLL |-->| div 1 or div 4 |---> consumer device
>  +-----+   +----------------+
> 
> To achieve a rate of 400MHz on the output of the divider, we
> would have to set the rate of the PLL to 1.6 GHz and then divide
> it by 4. The current code would set the PLL to 1.6GHz first while
> the divider is still set to 1, thus causing the downstream
> consumer of the clock to receive a few clock cycles of 1.6GHz
> clock (far beyond it's maximum acceptable rate). We should be
> changing the divider first before increasing the PLL rate to
> avoid this problem.
> 
> Therefore, set the rate of any child clocks that are increasing
> in rate from their current rate so that they can increase their
> dividers if necessary. We assume that there isn't such a thing as
> minimum rate requirements.
> 
> Cc: Opera <montvid@gmail.com>
> Cc: John Stultz <john.stultz@linaro.org>
> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> ---
> Stephen: just wanted to check what's up with this patch.
> When I apply it on my kernel I get graphics on the Nexus7,
> when I don't, I don't.
> 
> OpenWRT has started to carry the patch in their tree I noticed.
> I found it in John Stultz patch stack.
> 
> Is there some similar patch floating in some other series, is
> it fundamentally wrong or something else?
> 
> Just wanted to reboot the discussion so we know where this is
> standing.

This patch wants to go away and be replaced with coordinated clk
rates code. So far, nothing has appeared for that though, so this
problem is stuck in limbo, blocking Krait CPUfreq.

I have no idea why it matters for your Nexus7 graphics stuff. As
far as I know the GPU clk on Nexus7 is a plain old dynamic rcg
that can switch rates glitch free and we don't do anything odd
like reprogramming the parent PLL of the rcg to use faster rates,
which is mostly what this patch is for.

I wrote this patch for Krait CPUfreq originally. In that case we
reprogram PLLs higher up in tree and then have to adjust dividers
below that and doing that in the wrong order causes high
frequencies to come down the tree into the CPU that we can't turn
off.

I suspect OpenWRT has pulled in the patch for Krait CPUfreq. It
could be that you also need it for that. Or it could be that odd
line where we don't look at the result of clk_recalc, and just
blast in the calculated new rate into core->rate somehow fixes
something.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* [PATCH] RESEND: clk: Avoid sending high rates to downstream clocks     during set_rate
@ 2017-11-02  7:38 Modestas
  0 siblings, 0 replies; 6+ messages in thread
From: Modestas @ 2017-11-02  7:38 UTC (permalink / raw)
  To: linux-clk

Thanks for the information=2E As I understand there is no @ when this will =
be upstreamed=2E My Krait device can not boot the linux kernel to login wit=
hout this patch so this patch is critical=2E Without it i just see a blank =
screen without any dmesg info=2E=C2=A0

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

* Re: [PATCH] RESEND: clk: Avoid sending high rates to downstream clocks during set_rate
       [not found] <24C08A61-4CBD-4890-8C7A-DEC665A04E9A@gmail.com>
  2017-11-02  7:19 ` Modestas
@ 2017-11-02  7:22 ` Modestas
  1 sibling, 0 replies; 6+ messages in thread
From: Modestas @ 2017-11-02  7:22 UTC (permalink / raw)
  To: linux-clk



Thanks for the information=2E As I understand there is no @ when this will=
 be upstreamed=2E My Krait device can not boot the linux kernel to login wi=
thout this patch so this patch is critical=2E Without it i just see a blank=
 screen without any dmesg info=2E=C2=A0

On November 2, 2017 9:00:03 AM GMT+02:00, Stephen Boyd <sboyd@codeaurora=
=2Eorg> wrote:

On 10/04, Linus Walleij wrote:

From: Stephen Boyd <sboyd@codeaurora=2Eorg>

If a clock is on and we call clk_set_rate() on it we may get into
a situation where the clock temporarily increases in rate
dramatically while we walk the tree and call =2Eset_rate() ops=2E For
example, consider a case where a PLL feeds into a divider=2E
Initially the divider is set to divide by 1 and the PLL is
running fairly slow (100MHz)=2E The downstream consumer of the
divider output can only handle rates =3D< 400 MHz, but the divider
can only choose between divisors of 1 and 4=2E

+-----+ +----------------+
| PLL |-->| div 1 or div 4 |---> consumer device
+-----+ +----------------+

To achieve a rate of 400MHz on the output of the divider, we
would have to set the rate of the PLL to 1=2E6 GHz and then divide
it by 4=2E The current code would set the PLL to 1=2E6GHz first while
the divider is still set to 1, thus causing the downstream
consumer of the clock to receive a few clock cycles of 1=2E6GHz
clock (far beyond it's maximum acceptable rate)=2E We should be
changing the divider first before increasing the PLL rate to
avoid this problem=2E

Therefore, set the rate of any child clocks that are increasing
in rate from their current rate so that they can increase their
dividers if necessary=2E We assume that there isn't such a thing as
minimum rate requirements=2E

Cc: Opera <montvid@gmail=2Ecom>
Cc: John Stultz <john=2Estultz@linaro=2Eorg>
Signed-off-by: Stephen Boyd <sboyd@codeaurora=2Eorg>
---
Stephen: just wanted to check what's up with this patch=2E
When I apply it on my kernel I get graphics on the Nexus7,
when I don't, I don't=2E

OpenWRT has started to carry the patch in their tree I noticed=2E
I found it in John Stultz patch stack=2E

Is there some similar patch floating in some other series, is
it fundamentally wrong or something else?

Just wanted to reboot the discussion so we know where this is
standing=2E


This patch wants to go away and be replaced with coordinated clk
rates code=2E So far, nothing has appeared for that though, so this
problem is stuck in limbo, blocking Krait CPUfreq=2E

I have no idea why it matters for your Nexus7 graphics stuff=2E As
far as I know the GPU clk on Nexus7 is a plain old dynamic rcg
that can switch rates glitch free and we don't do anything odd
like reprogramming the parent PLL of the rcg to use faster rates,
which is mostly what this patch is for=2E

I wrote this patch for Krait CPUfreq originally=2E In that case we
reprogram PLLs higher up in tree and then have to adjust dividers
below that and doing that in the wrong order causes high
frequencies to come down the tree into the CPU that we can't turn
off=2E

I suspect OpenWRT has pulled in the patch for Krait CPUfreq=2E It
could be that you also need it for that=2E Or it could be that odd
line where we don't look at the result of clk_recalc, and just
blast in the calculated new rate into core->rate somehow fixes
--=20
Sent from my Android device with K-9 Mail=2E Please excuse my brevity=2E
--=20
Sent from my Android device with K-9 Mail=2E Please excuse my brevity=2E

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

* Re: [PATCH] RESEND: clk: Avoid sending high rates to downstream clocks during set_rate
       [not found] <24C08A61-4CBD-4890-8C7A-DEC665A04E9A@gmail.com>
@ 2017-11-02  7:19 ` Modestas
  2017-11-02  7:22 ` Modestas
  1 sibling, 0 replies; 6+ messages in thread
From: Modestas @ 2017-11-02  7:19 UTC (permalink / raw)
  To: linux-clk



Thanks for the information=2E As I understand there is no @ when this will=
 be upstreamed=2E My Krait device can not boot the linux kernel to login wi=
thout this patch so this patch is critical=2E Without it i just see a blank=
 screen without any dmesg info=2E=C2=A0

On November 2, 2017 9:00:03 AM GMT+02:00, Stephen Boyd <sboyd@codeaurora=
=2Eorg> wrote:

On 10/04, Linus Walleij wrote:

From: Stephen Boyd <sboyd@codeaurora=2Eorg>

If a clock is on and we call clk_set_rate() on it we may get into
a situation where the clock temporarily increases in rate
dramatically while we walk the tree and call =2Eset_rate() ops=2E For
example, consider a case where a PLL feeds into a divider=2E
Initially the divider is set to divide by 1 and the PLL is
running fairly slow (100MHz)=2E The downstream consumer of the
divider output can only handle rates =3D< 400 MHz, but the divider
can only choose between divisors of 1 and 4=2E

+-----+ +----------------+
| PLL |-->| div 1 or div 4 |---> consumer device
+-----+ +----------------+

To achieve a rate of 400MHz on the output of the divider, we
would have to set the rate of the PLL to 1=2E6 GHz and then divide
it by 4=2E The current code would set the PLL to 1=2E6GHz first while
the divider is still set to 1, thus causing the downstream
consumer of the clock to receive a few clock cycles of 1=2E6GHz
clock (far beyond it's maximum acceptable rate)=2E We should be
changing the divider first before increasing the PLL rate to
avoid this problem=2E

Therefore, set the rate of any child clocks that are increasing
in rate from their current rate so that they can increase their
dividers if necessary=2E We assume that there isn't such a thing as
minimum rate requirements=2E

Cc: Opera <montvid@gmail=2Ecom>
Cc: John Stultz <john=2Estultz@linaro=2Eorg>
Signed-off-by: Stephen Boyd <sboyd@codeaurora=2Eorg>
---
Stephen: just wanted to check what's up with this patch=2E
When I apply it on my kernel I get graphics on the Nexus7,
when I don't, I don't=2E

OpenWRT has started to carry the patch in their tree I noticed=2E
I found it in John Stultz patch stack=2E

Is there some similar patch floating in some other series, is
it fundamentally wrong or something else?

Just wanted to reboot the discussion so we know where this is
standing=2E


This patch wants to go away and be replaced with coordinated clk
rates code=2E So far, nothing has appeared for that though, so this
problem is stuck in limbo, blocking Krait CPUfreq=2E

I have no idea why it matters for your Nexus7 graphics stuff=2E As
far as I know the GPU clk on Nexus7 is a plain old dynamic rcg
that can switch rates glitch free and we don't do anything odd
like reprogramming the parent PLL of the rcg to use faster rates,
which is mostly what this patch is for=2E

I wrote this patch for Krait CPUfreq originally=2E In that case we
reprogram PLLs higher up in tree and then have to adjust dividers
below that and doing that in the wrong order causes high
frequencies to come down the tree into the CPU that we can't turn
off=2E

I suspect OpenWRT has pulled in the patch for Krait CPUfreq=2E It
could be that you also need it for that=2E Or it could be that odd
line where we don't look at the result of clk_recalc, and just
blast in the calculated new rate into core->rate somehow fixes
--=20
Sent from my Android device with K-9 Mail=2E Please excuse my brevity=2E

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

end of thread, other threads:[~2017-11-02  7:38 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-04  2:30 [PATCH] RESEND: clk: Avoid sending high rates to downstream clocks during set_rate Linus Walleij
2017-10-30 14:23 ` Linus Walleij
2017-11-02  7:00 ` Stephen Boyd
     [not found] <24C08A61-4CBD-4890-8C7A-DEC665A04E9A@gmail.com>
2017-11-02  7:19 ` Modestas
2017-11-02  7:22 ` Modestas
2017-11-02  7:38 Modestas

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.