From: maxime.ripard@free-electrons.com (Maxime Ripard)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 06/14] ARM: sun8i: clk: Add clk-factor rate application method
Date: Thu, 21 Jul 2016 11:48:52 +0200 [thread overview]
Message-ID: <20160721094852.GI5993@lukather> (raw)
In-Reply-To: <085e185a-ac76-dd3f-9b0e-a7dc9c0c09f3@megous.com>
On Fri, Jul 15, 2016 at 12:38:54PM +0200, Ond?ej Jirman wrote:
> On 15.7.2016 10:53, Maxime Ripard wrote:
> > On Fri, Jul 01, 2016 at 02:50:57AM +0200, Ond?ej Jirman wrote:
> >>>> /**
> >>>> + * sun8i_h3_apply_pll1_factors() - applies n, k, m, p factors to the
> >>>> + * register using an algorithm that tries to reserve the PLL lock
> >>>> + */
> >>>> +
> >>>> +static void sun8i_h3_apply_pll1_factors(struct clk_factors *factors, struct factors_request *req)
> >>>> +{
> >>>> + const struct clk_factors_config *config = factors->config;
> >>>> + u32 reg;
> >>>> +
> >>>> + /* Fetch the register value */
> >>>> + reg = readl(factors->reg);
> >>>> +
> >>>> + if (FACTOR_GET(config->pshift, config->pwidth, reg) < req->p) {
> >>>> + reg = FACTOR_SET(config->pshift, config->pwidth, reg, req->p);
> >>>> +
> >>>> + writel(reg, factors->reg);
> >>>> + __delay(2000);
> >>>> + }
> >>>
> >>> So there was some doubts about the fact that P was being used, or at
> >>> least that it was useful.
> >>
> >> p is necessary to reduce frequencies below 288 MHz according to the
> >> datasheet.
> >
> > Yes, but you could reach those frequencies without P, too, and it's
> > not part of any OPP provided by Allwinner.
>
> The arisc firmware for H3 contains table of factors for frequences from
> 0 to 2GHz and, P is used below 240MHz. M is never used, BTW. (other
> datasheets specify M as for testing use only, whatever that means - not
> H3, but it seems it's the same PLL block)
Interesting. Which SoCs in particular?
> >>>> + if (FACTOR_GET(config->mshift, config->mwidth, reg) < req->m) {
> >>>> + reg = FACTOR_SET(config->mshift, config->mwidth, reg, req->m);
> >>>> +
> >>>> + writel(reg, factors->reg);
> >>>> + __delay(2000);
> >>>> + }
> >>>> +
> >>>> + reg = FACTOR_SET(config->nshift, config->nwidth, reg, req->n);
> >>>> + reg = FACTOR_SET(config->kshift, config->kwidth, reg, req->k);
> >>>> +
> >>>> + writel(reg, factors->reg);
> >>>> + __delay(20);
> >>>> +
> >>>> + while (!(readl(factors->reg) & (1 << config->lock)));
> >>>
> >>> So, they are applying the dividers first, and then applying the
> >>> multipliers, and then wait for the PLL to stabilize.
> >>
> >> Not exactly, first we are increasing dividers if the new dividers are
> >> higher that that what's already set. This ensures that because
> >> application of dividers is immediate by the design of the PLL, the
> >> application of multipliers isn't. So the VCO would still run at the same
> >> frequency for a while gradually rising to a new value for example,
> >> while the dividers would be reduced immediately. Leading to crash.
> >>
> >> PLL
> >> --------------------------
> >> PRE DIV(f0) -> VCO(f1) -> POST DIV(f2)
> >> P K,N M
> >>
> >> Example: (we set all factors at once, reducing dividers and multipliers
> >> at the same time at 0ms - this should lead to no change in the output
> >> frequency, but...)
> >>
> >> -1ms: f0 = 24MHz, f1 = 2GHz, f2 = 1GHz
> >> 0ms: f0 = 24MHz, f1 = 2GHz, f2 = 2GHz - boom
> >> 1ms: f0 = 24MHz, f1 = 1.5GHz, f2 = 1.5GHz
> >> 2ms: f0 = 24MHz, f1 = 1GHz, f2 = 1GHz
> >>
> >> The current code crashes exactly at boom, you don't get any more
> >> instructions to execute.
> >>
> >> See.
> >>
> >> So this patch first increases dividers (only if necessary), changes
> >> multipliers and waits for change to happen (takes around 2000 cycles),
> >> and then decreases dividers (only if necessary).
> >>
> >> So we get:
> >>
> >> -1ms: f0 = 24MHz, f1 = 2GHz, f2 = 1GHz
> >> 0ms: f0 = 24MHz, f1 = 2GHz, f2 = 1GHz - no boom, multiplier
> >> reduced
> >> 1ms: f0 = 24MHz, f1 = 1.5GHz, f2 = 0.75GHz
> >> 1.9ms: f0 = 24MHz, f1 = 1GHz, f2 = 0.5GHz - we got PLL sync
> >> 2ms: f0 = 24MHz, f1 = 1GHz, f2 = 1GHz - and here we reduce divider
> >> at last
> >
> > Awesome explanation, thanks!
> >
> > So I guess it really all boils down to the fact that the CPU is
> > clocked way outside of it's operating frequency while the PLL
> > stabilizes, right?
>
> It may be, depending on the factors before and after change. I haven't
> tested what factors the mainline kernel calculates for each frequency.
> The arisc never uses M, and only uses P at frequencies that would not
> allow for this behavior.
>
> I created a test program for arisc that runs a loop on the main CPU
> using msgbox to send pings to the arisc CPU, and the vary the PLL1
> randomly from the arisc, and haven't been able to lockup the main CPU
> yet with either method.
>
> There's also AXI clock, that depends on PLL1. Arisc firmware uses the
> same method to change it while changing CPUX clock. If the clock would
> rise above certain frequency, AXI divider is increased before the PLL1
> change. If it would fall below certain frequency it is decreased after
> the PLL1 change.
If we ever need to change that, we can always rely on a clock notifier
to adjust the divider before the change happen (and support all the
scenarios, like the clock change has been aborted).
> > If so, then yes, trying to switch to the 24MHz oscillator before
> > applying the factors, and then switching back when the PLL is stable
> > would be a nice solution.
> >
> > I just checked, and all the SoCs we've had so far have that
> > possibility, so if it works, for now, I'd like to stick to that.
>
> It would need to be tested. U-boot does the change only once, while the
> kernel would be doing it all the time and between various frequencies
> and PLL settings. So the issues may show up with this solution too.
That would have the benefit of being quite easy to document, not be a
huge amount of code and it would work on all the CPUs PLLs we have so
far, so still, a pretty big win. If it doesn't, of course, we don't
really have the choice.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160721/de014597/attachment.sig>
next prev parent reply other threads:[~2016-07-21 9:48 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-25 3:44 [PATCH v2] Thermal regulation for Orange Pi PC and Orange Pi One megous at megous.com
2016-06-25 3:44 ` [PATCH v2 01/14] ARM: clk: sunxi: Add driver for the H3 THS clock megous at megous.com
2016-06-25 7:13 ` Maxime Ripard
2016-06-25 15:23 ` Ondřej Jirman
2016-06-28 11:52 ` Maxime Ripard
2016-06-25 3:44 ` [PATCH v2 02/14] thermal: sun8i_ths: Add support for the thermal sensor on Allwinner H3 megous at megous.com
2016-06-25 7:10 ` Maxime Ripard
2016-06-25 15:12 ` Ondřej Jirman
2016-06-28 11:39 ` Maxime Ripard
2016-06-25 3:45 ` [PATCH v2 03/14] dt-bindings: document sun8i_ths - H3 thermal sensor driver megous at megous.com
2016-06-28 20:56 ` Rob Herring
2016-06-25 3:45 ` [PATCH v2 04/14] regulator: SY8106A regulator driver megous at megous.com
2016-06-26 11:26 ` Mark Brown
2016-06-26 15:07 ` Ondřej Jirman
2016-06-27 14:54 ` Mark Brown
2016-06-28 16:27 ` Ondřej Jirman
2016-06-27 15:10 ` Mark Brown
2016-06-25 3:45 ` [PATCH v2 05/14] dt-bindings: document " megous at megous.com
2016-06-26 11:27 ` Mark Brown
2016-06-26 15:10 ` Ondřej Jirman
2016-06-26 18:52 ` Mark Brown
2016-06-25 3:45 ` [PATCH v2 06/14] ARM: sun8i: clk: Add clk-factor rate application method megous at megous.com
2016-06-30 20:40 ` Maxime Ripard
2016-07-01 0:50 ` Ondřej Jirman
2016-07-01 5:37 ` Jean-Francois Moine
2016-07-01 6:34 ` Ondřej Jirman
2016-07-01 7:47 ` Jean-Francois Moine
2016-07-15 8:53 ` Maxime Ripard
2016-07-15 10:38 ` Ondřej Jirman
2016-07-15 13:27 ` Jean-Francois Moine
2016-07-15 13:48 ` Ondřej Jirman
2016-07-15 14:22 ` [linux-sunxi] " Michal Suchanek
2016-07-15 16:33 ` Ondřej Jirman
2016-07-21 9:51 ` Maxime Ripard
2016-07-21 9:48 ` Maxime Ripard [this message]
2016-07-21 9:52 ` Ondřej Jirman
2016-07-26 6:32 ` Maxime Ripard
2016-07-28 11:27 ` Changed: sunxi-ng clock code - NKMP clock implementation is wrong Ondřej Jirman
2016-07-28 11:38 ` [linux-sunxi] " Chen-Yu Tsai
2016-07-28 21:00 ` Maxime Ripard
2016-07-28 22:01 ` Ondřej Jirman
2016-07-31 10:31 ` Maxime Ripard
2016-07-31 22:01 ` Ondřej Jirman
2016-08-31 20:25 ` Maxime Ripard
2016-07-01 0:53 ` [PATCH v2 06/14] ARM: sun8i: clk: Add clk-factor rate application method Ondřej Jirman
2016-07-15 8:19 ` Maxime Ripard
2016-06-25 3:45 ` [PATCH v2 07/14] ARM: dts: sun8i: Use sun8i-h3-pll1-clk for pll1 in H3 megous at megous.com
2016-06-25 3:45 ` [PATCH v2 08/14] ARM: dts: sun8i: Add thermal sensor node to the sun8i-h3.dtsi megous at megous.com
2016-06-25 3:45 ` [PATCH v2 09/14] ARM: dts: sun8i: Add cpu0 label to sun8i-h3.dtsi megous at megous.com
2016-06-25 3:45 ` [PATCH v2 10/14] ARM: dts: sun8i: Add r_twi I2C controller megous at megous.com
2016-06-25 7:16 ` Maxime Ripard
2016-06-25 3:45 ` [PATCH v2 11/14] ARM: dts: sun8i: Add sy8106a regulator to Orange Pi PC megous at megous.com
2016-06-25 3:45 ` [PATCH v2 12/14] ARM: dts: sun8i: Setup CPU operating points for Onrage PI PC megous at megous.com
2016-06-25 3:45 ` [PATCH v2 13/14] ARM: dts: sun8i: Add gpio-regulator used on Orange Pi One megous at megous.com
2016-06-25 7:18 ` Maxime Ripard
2016-06-25 3:45 ` [PATCH v2 14/14] ARM: dts: sun8i: Enable DVFS " megous at megous.com
2016-06-30 11:13 ` [linux-sunxi] " Michal Suchanek
2016-06-30 14:19 ` Ondřej Jirman
2016-06-30 15:16 ` Michal Suchanek
2016-06-30 15:32 ` Ondřej Jirman
2016-06-30 15:50 ` Michal Suchanek
2016-06-30 15:53 ` Ondřej Jirman
2016-07-01 10:54 ` Michal Suchanek
2016-06-30 14:23 ` Siarhei Siamashka
2016-07-01 1:17 ` Ondřej Jirman
2016-07-22 0:41 ` Ondřej Jirman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160721094852.GI5993@lukather \
--to=maxime.ripard@free-electrons.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).