* RE: [PATCH v3 1/2] dt-bindings: mailbox: add binding doc for the ARM SMC/HVC mailbox
From: Peng Fan @ 2019-07-18 1:42 UTC (permalink / raw)
To: Rob Herring
Cc: mark.rutland@arm.com, jassisinghbrar@gmail.com,
sudeep.holla@arm.com, andre.przywara@arm.com,
f.fainelli@gmail.com, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, dl-linux-imx
In-Reply-To: <CAL_JsqJkt7pX9F9NggL2EXxS=2oiF07VJCOqVTvF-Zwz=cjmvg@mail.gmail.com>
Hi Rob,
> Subject: Re: [PATCH v3 1/2] dt-bindings: mailbox: add binding doc for the ARM
> SMC/HVC mailbox
>
> On Mon, Jul 15, 2019 at 4:10 AM Peng Fan <peng.fan@nxp.com> wrote:
> >
> > From: Peng Fan <peng.fan@nxp.com>
> >
> > The ARM SMC/HVC mailbox binding describes a firmware interface to
> > trigger actions in software layers running in the EL2 or EL3 exception levels.
> > The term "ARM" here relates to the SMC instruction as part of the ARM
> > instruction set, not as a standard endorsed by ARM Ltd.
> >
> > Signed-off-by: Peng Fan <peng.fan@nxp.com>
> > ---
> >
> > V3:
> > Convert to yaml
> > Drop interrupt
> > Introudce transports to indicate mem/reg The func id is still kept
> > as optional, because like SCMI it only cares about message.
> >
> > V2:
> > Introduce interrupts as a property.
> >
> > .../devicetree/bindings/mailbox/arm-smc.yaml | 124
> +++++++++++++++++++++
> > 1 file changed, 124 insertions(+)
> > create mode 100644
> > Documentation/devicetree/bindings/mailbox/arm-smc.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/mailbox/arm-smc.yaml
> > b/Documentation/devicetree/bindings/mailbox/arm-smc.yaml
> > new file mode 100644
> > index 000000000000..da9b1a03bc4e
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/mailbox/arm-smc.yaml
> > @@ -0,0 +1,124 @@
> > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2
> > +---
> > +$id:
> > +https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevi
> >
> +cetree.org%2Fschemas%2Fmailbox%2Farm-smc.yaml%23&data=02%7
> C01%7Cp
> >
> +eng.fan%40nxp.com%7C424e0d1c19c344406b6008d709465591%7C686ea1
> d3bc2b4c
> >
> +6fa92cd99c5c301635%7C0%7C0%7C636988070002772705&sdata=DV
> stQ%2FhuN
> > +c67%2Bt08yXibQrX7sIeocHziYp3dkkeRoJ4%3D&reserved=0
> > +$schema:
> > +https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevi
> >
> +cetree.org%2Fmeta-schemas%2Fcore.yaml%23&data=02%7C01%7Cpe
> ng.fan%
> >
> +40nxp.com%7C424e0d1c19c344406b6008d709465591%7C686ea1d3bc2b4
> c6fa92cd9
> >
> +9c5c301635%7C0%7C0%7C636988070002782698&sdata=D%2Fa2SU
> W%2FCqclJdy
> > +RbFggqqL%2BAEumER0K3rAaisY2bMc%3D&reserved=0
> > +
> > +title: ARM SMC Mailbox Interface
> > +
> > +maintainers:
> > + - Peng Fan <peng.fan@nxp.com>
> > +
> > +description: |
> > + This mailbox uses the ARM smc (secure monitor call) and hvc
> > +(hypervisor
> > + call) instruction to trigger a mailbox-connected activity in
> > +firmware,
> > + executing on the very same core as the caller. By nature this
> > +operation
> > + is synchronous and this mailbox provides no way for asynchronous
> > +messages
> > + to be delivered the other way round, from firmware to the OS, but
> > + asynchronous notification could also be supported. However the
> > +value of
> > + r0/w0/x0 the firmware returns after the smc call is delivered as a
> > +received
> > + message to the mailbox framework, so a synchronous communication
> > +can be
> > + established, for a asynchronous notification, no value will be returned.
> > + The exact meaning of both the action the mailbox triggers as well
> > +as the
> > + return value is defined by their users and is not subject to this binding.
> > +
> > + One use case of this mailbox is the SCMI interface, which uses
> > + shared memory to transfer commands and parameters, and a mailbox
> to
> > + trigger a function call. This allows SoCs without a separate
> > + management processor (or when such a processor is not available or
> > + used) to use this standardized interface anyway.
> > +
> > + This binding describes no hardware, but establishes a firmware
> interface.
> > + Upon receiving an SMC using one of the described SMC function
> > + identifiers, the firmware is expected to trigger some mailbox connected
> functionality.
> > + The communication follows the ARM SMC calling convention.
> > + Firmware expects an SMC function identifier in r0 or w0. The
> > + supported identifiers are passed from consumers, or listed in the
> > + the arm,func-ids properties as described below. The firmware can
> > + return one value in the first SMC result register, it is expected
> > + to be an error value, which shall be propagated to the mailbox client.
> > +
> > + Any core which supports the SMC or HVC instruction can be used, as
> > + long as a firmware component running in EL3 or EL2 is handling these
> calls.
> > +
> > +properties:
> > + compatible:
> > + const: arm,smc-mbox
> > +
> > + "#mbox-cells":
> > + const: 1
> > +
> > + arm,num-chans:
> > + description: The number of channels supported.
> > + $ref: /schemas/types.yaml#/definitions/uint32
>
> Constraints? 0 is valid? 2^32?
0 is not valid. There should be limited channels, but depends on firmware design.
>
> > +
> > + method:
> > + items:
> > + - enum:
> > + - smc
> > + - hvc
> > +
> > + transports:
> > + items:
> > + - enum:
> > + - mem
> > + - reg
>
> What if someone wants to configure this per channel? Perhaps #mbox-cells
> should be 2 and this can be a client parameter.
I need to check. Currently I only use one type. There might be people
want to use different transports for each channels.
>
> Minimally, this needs a 'arm' vendor prefix if it stays.
"arm,transports" in v4.
>
> > +
> > + arm,func-ids:
> > + description: |
> > + An array of 32-bit values specifying the function IDs used by each
> > + mailbox channel. Those function IDs follow the ARM SMC calling
> > + convention standard [1].
>
> What's the default if not specified? Or this should be required?
If not specified, it means the client firmware driver will pass it to mailbox driver.
Thanks,
Peng.
>
> > +
> > + There is one identifier per channel and the number of supported
> > + channels is determined by the length of this array.
> > + minItems: 0
> > + maxItems: 4096 # Should be enough?
> > +
> > +required:
> > + - compatible
> > + - "#mbox-cells"
> > + - arm,num-chans
> > + - transports
> > + - method
> > +
> > +examples:
> > + - |
> > + sram@910000 {
> > + compatible = "mmio-sram";
> > + reg = <0x0 0x93f000 0x0 0x1000>;
> > + #address-cells = <1>;
> > + #size-cells = <1>;
> > + ranges = <0 0x0 0x93f000 0x1000>;
> > +
> > + cpu_scp_lpri: scp-shmem@0 {
> > + compatible = "arm,scmi-shmem";
> > + reg = <0x0 0x200>;
> > + };
> > +
> > + cpu_scp_hpri: scp-shmem@200 {
> > + compatible = "arm,scmi-shmem";
> > + reg = <0x200 0x200>;
> > + };
> > + };
> > +
> > + firmware {
> > + smc_mbox: mailbox {
> > + #mbox-cells = <1>;
> > + compatible = "arm,smc-mbox";
> > + method = "smc";
> > + arm,num-chans = <0x2>;
> > + transports = "mem";
> > + /* Optional */
> > + arm,func-ids = <0xc20000fe>, <0xc20000ff>;
> > + };
> > +
> > + scmi {
> > + compatible = "arm,scmi";
> > + mboxes = <&mailbox 0 &mailbox 1>;
> > + mbox-names = "tx", "rx";
> > + shmem = <&cpu_scp_lpri &cpu_scp_hpri>;
> > + };
> > + };
> > +
> > +...
> > --
> > 2.16.4
> >
^ permalink raw reply
* Re: [PATCH V5 11/18] clk: tegra210: Add support for Tegra210 clocks
From: Sowjanya Komatineni @ 2019-07-18 1:15 UTC (permalink / raw)
To: Dmitry Osipenko, sboyd, Michael Turquette
Cc: Peter De Schrijver, Joseph Lo, thierry.reding, jonathanh, tglx,
jason, marc.zyngier, linus.walleij, stefan, mark.rutland,
pgaikwad, linux-clk, linux-gpio, jckuo, talho, linux-tegra,
linux-kernel, mperttunen, spatra, robh+dt, devicetree
In-Reply-To: <c759d71b-1549-2562-f0cf-db5f9e51329e@nvidia.com>
On 7/17/19 5:25 PM, Sowjanya Komatineni wrote:
>
> On 7/17/19 4:44 PM, Dmitry Osipenko wrote:
>> 18.07.2019 2:36, Sowjanya Komatineni пишет:
>>> On 7/17/19 3:48 PM, Dmitry Osipenko wrote:
>>>> 18.07.2019 0:57, Sowjanya Komatineni пишет:
>>>>> On 7/17/19 2:51 PM, Sowjanya Komatineni wrote:
>>>>>> On 7/17/19 2:30 PM, Dmitry Osipenko wrote:
>>>>>>> 17.07.2019 23:11, Sowjanya Komatineni пишет:
>>>>>>>> On 7/17/19 1:01 PM, Sowjanya Komatineni wrote:
>>>>>>>>> On 7/17/19 12:43 PM, Dmitry Osipenko wrote:
>>>>>>>>>> 17.07.2019 21:54, Sowjanya Komatineni пишет:
>>>>>>>>>>> On 7/17/19 11:51 AM, Sowjanya Komatineni wrote:
>>>>>>>>>>>> On 7/17/19 11:32 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>> 17.07.2019 20:29, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>> On 7/17/19 8:17 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>> 17.07.2019 9:36, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>> On 7/16/19 11:33 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>> В Tue, 16 Jul 2019 22:55:52 -0700
>>>>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> On 7/16/19 10:42 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>> В Tue, 16 Jul 2019 22:25:25 -0700
>>>>>>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>>>>>>> On 7/16/19 9:11 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>> В Tue, 16 Jul 2019 19:35:49 -0700
>>>>>>>>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 7:18 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 3:06 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 3:00 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>> 17.07.2019 0:35, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 2:21 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>> 17.07.2019 0:12, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 1:47 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 22:26, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:43 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:30, Sowjanya Komatineni
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:25 AM, Dmitry Osipenko
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:19, Sowjanya Komatineni
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 9:50 AM, Sowjanya Komatineni
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 8:00 AM, Dmitry Osipenko
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 11:06, Peter De Schrijver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2019 at 03:24:26PM
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +0800,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Joseph
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Lo wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OK, Will add to CPUFreq driver...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The other thing that also need
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> attention is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> that T124 CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicitly relies on DFLL driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to be
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> first, which is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> icky.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Should I add check for successful
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> register explicitly in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver probe and defer till
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> registers?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Probably you should use the "device
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> links".
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> See
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1][2] for the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> example.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/gpu/drm/tegra/dc.c#L2383
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [2]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://www.kernel.org/doc/html/latest/driver-api/device_link.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Return EPROBE_DEFER instead of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> EINVAL if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device_link_add() fails.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use of_find_device_by_node() to get
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device, see [3].
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [3]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/devfreq/tegra20-devfreq.c#n100
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Will go thru and add...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Looks like I initially confused this case
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getting
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> orphaned clock.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'm now seeing that the DFLL driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> registers the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock and then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk_get(dfll) should be returning
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> EPROBE_DEFER
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> until
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL driver is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probed, hence everything should be fine
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as-is and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> there is no real
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for the 'device link'. Sorry for the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> confusion!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, I didn't follow the mail
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> thread. Just
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regarding the DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> part.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> As you know it, the DFLL clock is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> one
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock sources and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integrated with DVFS control logic
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator. We will not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to other clock sources once we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switched to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL. Because the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU has
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> been regulated by the DFLL HW
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DVFS
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (CVB or OPP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> you see
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> in the driver.). We shouldn't
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> reparent
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> other sources with
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unknew
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> freq/volt pair. That's not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> guaranteed to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> work. We
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allow switching to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> open-loop mode but different
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sources.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay, then the CPUFreq driver will
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rate before switching to PLLP in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> order to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper CPU voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP freq is safe to work for any CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> So no
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to PLLP rate before changing
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK_G
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to PLLP during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, please ignore my above comment.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> During
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend, need to change
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK_G source to PLLP when dfll is in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> closed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode first and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll need to be set to open loop.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And I don't exactly understand
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> why we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to PLLP in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> idle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver. Just keep it on CL-DVFS mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> time.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 entry, the dfll suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> function
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moves it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the open-loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode. That's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all. The sc7-entryfirmware will
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the rest
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn off
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU power.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 resume, the warmboot code
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator and power up the CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cluster. And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> leave
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it on PLL_P.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> After
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resuming to the kernel, we re-init
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> policy (CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> runs on DFLL open-loop mode) and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moving to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> close-loop mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL is re-inited after switching
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> early clocks-state restoring by CaR
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hence
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> instead of having
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> odd
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hacks in the CaR driver, it is much
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> nicer to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper suspend-resume sequencing of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> drivers. In this case
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver is the driver that enables DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switches
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to that
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source, which means that this
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> also
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> be responsible for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> management of the DFLL's state
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend/resume process. If
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver disables DFLL during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> re-enables it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resume, then looks like the CaR driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hacks
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> around
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL are not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> needed.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL part looks good to me. BTW,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> change the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> patch subject to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "Add
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend-resume support" seems more
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> me.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> To clarify this, the sequences for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> are as
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> follows (assuming
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> required DFLL hw configuration has
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> been
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> done)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch to DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Save current parent and frequency
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2) Enable DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3) Change cclk_g parent to DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For OVR regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Change PWM output pin from
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> tristate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 5) Enable DFLL PWM output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For I2C regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Enable DFLL I2C output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 6) Program DFLL to closed loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch away from DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Change cclk_g parent to PLLP so
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> frequency is ok for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> any
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> vdd_cpu voltage
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I see during switch away from DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (suspend),
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cclk_g
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent is not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> changed to PLLP before changing dfll to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> open
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Will add this ...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The CPUFreq driver switches parent to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probe, similar
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should be done on suspend.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'm also wondering if it's always safe to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP in the probe.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> If CPU is running on a lower freq than
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP, then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> some
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> other more
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate intermediate parent should be
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> selected.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU parents are PLL_X, PLL_P, and dfll.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLL_X
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> always
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> runs at higher
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rate
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> so switching to PLL_P during CPUFreq probe
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> prior to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll clock enable
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should be safe.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AFAIK, PLLX could run at ~200MHz. There is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> also a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> divided output of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> which CCLKG supports, the PLLP_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Probably, realistically, CPU is always
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> running
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> off a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> fast PLLX during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> boot, but I'm wondering what may happen on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> KEXEC. I
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> guess ideally CPUFreq driver should also
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'shutdown' callback to teardown DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> on a reboot, but likely that there are
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> other
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock-related problems as
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> well that may break KEXEC and thus it is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> very
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> important at the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moment.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [snip]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> During bootup CPUG sources from PLL_X. By
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLL_P
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> above I meant
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLL_P_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> As per clock policies, PLL_X is always used
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for high
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> freq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 800Mhz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and for low frequency it will be sourced
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> from
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Alright, then please don't forget to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pre-initialize
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate to a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> reasonable value using
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> tegra_clk_init_table or
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> assigned-clocks.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate update is not needed as it is
>>>>>>>>>>>>>>>>>>>>>>>>>>>> safe to
>>>>>>>>>>>>>>>>>>>>>>>>>>>> run at
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 408Mhz because it is below fmax @ Vmin
>>>>>>>>>>>>>>>>>>>>>>>>>>> So even 204MHz CVB entries are having the same
>>>>>>>>>>>>>>>>>>>>>>>>>>> voltage as
>>>>>>>>>>>>>>>>>>>>>>>>>>> 408MHz, correct? It's not instantly obvious
>>>>>>>>>>>>>>>>>>>>>>>>>>> to me
>>>>>>>>>>>>>>>>>>>>>>>>>>> from the
>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL driver's code where the fmax @ Vmin is
>>>>>>>>>>>>>>>>>>>>>>>>>>> defined,
>>>>>>>>>>>>>>>>>>>>>>>>>>> I see
>>>>>>>>>>>>>>>>>>>>>>>>>>> that there is the min_millivolts
>>>>>>>>>>>>>>>>>>>>>>>>>>> and frequency entries starting from 204MHZ
>>>>>>>>>>>>>>>>>>>>>>>>>>> defined
>>>>>>>>>>>>>>>>>>>>>>>>>>> per-table.
>>>>>>>>>>>>>>>>>>>>>>>>>> Yes at Vmin CPU Fmax is ~800Mhz. So anything
>>>>>>>>>>>>>>>>>>>>>>>>>> below
>>>>>>>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>>>>>>>>>>>>> work at Vmin voltage and PLLP max is 408Mhz.
>>>>>>>>>>>>>>>>>>>>>>>>> Thank you for the clarification. It would be good
>>>>>>>>>>>>>>>>>>>>>>>>> to have
>>>>>>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>>>>>>> commented
>>>>>>>>>>>>>>>>>>>>>>>>> in the code as well.
>>>>>>>>>>>>>>>>>>>>>>>> OK, Will add...
>>>>>>>>>>>>>>>>>>>>>>> Regarding, adding suspend/resume to CPUFreq,
>>>>>>>>>>>>>>>>>>>>>>> CPUFreq
>>>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>>>> happens very early even before disabling non-boot
>>>>>>>>>>>>>>>>>>>>>>> CPUs and
>>>>>>>>>>>>>>>>>>>>>>> also
>>>>>>>>>>>>>>>>>>>>>>> need to export clock driver APIs to CPUFreq.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Was thinking of below way of implementing this...
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Clock DFLL driver Suspend:
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> - Save CPU clock policy
>>>>>>>>>>>>>>>>>>>>>>> registers, and
>>>>>>>>>>>>>>>>>>>>>>> Perform
>>>>>>>>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>>>>>>>>> suspend which sets in open loop mode
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> CPU Freq driver Suspend: does nothing
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Clock DFLL driver Resume:
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> - Re-init DFLL, Set in
>>>>>>>>>>>>>>>>>>>>>>> Open-Loop mode,
>>>>>>>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>> Clock policy registers which actually sets
>>>>>>>>>>>>>>>>>>>>>>> source to
>>>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>>>> along
>>>>>>>>>>>>>>>>>>>>>>> with other CPU Policy register restore.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> CPU Freq driver Resume:
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> - do clk_prepare_enable which
>>>>>>>>>>>>>>>>>>>>>>> acutally
>>>>>>>>>>>>>>>>>>>>>>> sets
>>>>>>>>>>>>>>>>>>>>>>> DFLL in
>>>>>>>>>>>>>>>>>>>>>>> Closed loop mode
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Adding one more note: Switching CPU Clock to PLLP
>>>>>>>>>>>>>>>>>>>>>>> is not
>>>>>>>>>>>>>>>>>>>>>>> needed
>>>>>>>>>>>>>>>>>>>>>>> as CPU CLock can be from dfll in open-loop mode as
>>>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>>>> is not
>>>>>>>>>>>>>>>>>>>>>>> disabled anywhere throught the suspend/resume path
>>>>>>>>>>>>>>>>>>>>>>> and SC7
>>>>>>>>>>>>>>>>>>>>>>> entry
>>>>>>>>>>>>>>>>>>>>>>> FW and Warm boot code will switch CPU source to
>>>>>>>>>>>>>>>>>>>>>>> PLLP.
>>>>>>>>>>>>>>>>>>>>> Since CPU resumes on PLLP, it will be cleaner to
>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>> it on
>>>>>>>>>>>>>>>>>>>>> PLLP as well. And besides, seems that currently
>>>>>>>>>>>>>>>>>>>>> disabling
>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>> clock will disable DFLL completely and then you'd
>>>>>>>>>>>>>>>>>>>>> want to
>>>>>>>>>>>>>>>>>>>>> re-init
>>>>>>>>>>>>>>>>>>>>> the DFLL on resume any ways. So better to just
>>>>>>>>>>>>>>>>>>>>> disable
>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>> completely on suspend, which should happen on
>>>>>>>>>>>>>>>>>>>>> clk_disable(dfll).
>>>>>>>>>>>>>>>>>>>> Will switch to PLLP during CPUFreq suspend. With
>>>>>>>>>>>>>>>>>>>> decision of
>>>>>>>>>>>>>>>>>>>> using
>>>>>>>>>>>>>>>>>>>> clk_disable during suspend, its mandatory to switch to
>>>>>>>>>>>>>>>>>>>> PLLP as
>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>> is completely disabled.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> My earlier concern was on restoring CPU policy as we
>>>>>>>>>>>>>>>>>>>> can't do
>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>> from CPUFreq driver and need export from clock driver.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Clear now and will do CPU clock policy restore in
>>>>>>>>>>>>>>>>>>>> after
>>>>>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>>>>>> re-init.
>>>>>>>>>>>>>>>>>>> Why the policy can't be saved/restored by the CaR
>>>>>>>>>>>>>>>>>>> driver
>>>>>>>>>>>>>>>>>>> as a
>>>>>>>>>>>>>>>>>>> context of any other clock?
>>>>>>>>>>>>>>>>>> restoring cpu clock policy involves programming
>>>>>>>>>>>>>>>>>> source and
>>>>>>>>>>>>>>>>>> super_cclkg_divider.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> cclk_g is registered as clk_super_mux and it doesn't use
>>>>>>>>>>>>>>>>>> frac_div ops
>>>>>>>>>>>>>>>>>> to do save/restore its divider.
>>>>>>>>>>>>>>>>> That can be changed of course and I guess it also could
>>>>>>>>>>>>>>>>> be as
>>>>>>>>>>>>>>>>> simple as
>>>>>>>>>>>>>>>>> saving and restoring of two raw u32 values of the
>>>>>>>>>>>>>>>>> policy/divider
>>>>>>>>>>>>>>>>> registers.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Also, during clock context we cant restore cclk_g as
>>>>>>>>>>>>>>>>>> cclk_g
>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>> will be dfll and dfll will not be resumed/re-initialized
>>>>>>>>>>>>>>>>>> by the
>>>>>>>>>>>>>>>>>> time
>>>>>>>>>>>>>>>>>> clk_super_mux save/restore happens.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> we can't use save/restore context for dfll clk_ops
>>>>>>>>>>>>>>>>>> because
>>>>>>>>>>>>>>>>>> dfllCPU_out parent to CCLK_G is first in the clock
>>>>>>>>>>>>>>>>>> tree and
>>>>>>>>>>>>>>>>>> dfll_ref
>>>>>>>>>>>>>>>>>> and dfll_soc peripheral clocks are not restored by the
>>>>>>>>>>>>>>>>>> time dfll
>>>>>>>>>>>>>>>>>> restore happens. Also dfll peripheral clock enables need
>>>>>>>>>>>>>>>>>> to be
>>>>>>>>>>>>>>>>>> restored before dfll restore happens which involves
>>>>>>>>>>>>>>>>>> programming
>>>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>>>> controller for re-initialization.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> So dfll resume/re-init is done in clk-tegra210 at end of
>>>>>>>>>>>>>>>>>> all
>>>>>>>>>>>>>>>>>> clocks
>>>>>>>>>>>>>>>>>> restore in V5 series but instead of in clk-tegra210
>>>>>>>>>>>>>>>>>> driver I
>>>>>>>>>>>>>>>>>> moved
>>>>>>>>>>>>>>>>>> now to dfll-fcpu driver pm_ops as all dfll dependencies
>>>>>>>>>>>>>>>>>> will be
>>>>>>>>>>>>>>>>>> restored thru clk_restore_context by then. This will
>>>>>>>>>>>>>>>>>> be in
>>>>>>>>>>>>>>>>>> V6.
>>>>>>>>>>>>>>>>> Since DFLL is now guaranteed to be disabled across CaR
>>>>>>>>>>>>>>>>> suspend/resume
>>>>>>>>>>>>>>>>> (hence it has nothing to do in regards to CCLK) and given
>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>> PLLs
>>>>>>>>>>>>>>>>> state is restored before the rest of the clocks, I don't
>>>>>>>>>>>>>>>>> see why
>>>>>>>>>>>>>>>>> not to
>>>>>>>>>>>>>>>>> implement CCLK save/restore in a generic fasion. CPU
>>>>>>>>>>>>>>>>> policy
>>>>>>>>>>>>>>>>> wull be
>>>>>>>>>>>>>>>>> restored to either PLLP or PLLX (if CPUFreq driver is
>>>>>>>>>>>>>>>>> disabled).
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> CCLK_G save/restore should happen in clk_super_mux ops
>>>>>>>>>>>>>>>> save/context and
>>>>>>>>>>>>>>>> clk_super_mux save/restore happens very early as cclk_g is
>>>>>>>>>>>>>>>> first
>>>>>>>>>>>>>>>> in the
>>>>>>>>>>>>>>>> clock tree and save/restore traverses through the tree
>>>>>>>>>>>>>>>> top-bottom
>>>>>>>>>>>>>>>> order.
>>>>>>>>>>>>>>> If CCLK_G is restored before the PLLs, then just change the
>>>>>>>>>>>>>>> clocks
>>>>>>>>>>>>>>> order
>>>>>>>>>>>>>>> such that it won't happen.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I dont think we can change clocks order for CCLK_G.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> During bootup, cclk_g is registered after all pll's and
>>>>>>>>>>>>>> peripheral
>>>>>>>>>>>>>> clocks which is the way we wanted, So cclk_g will be the
>>>>>>>>>>>>>> first
>>>>>>>>>>>>>> one in
>>>>>>>>>>>>>> the clk list as clk_register adds new clock first in the
>>>>>>>>>>>>>> list.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> When clk_save_context and clk_restore_context APIs iterates
>>>>>>>>>>>>>> over the
>>>>>>>>>>>>>> list, cclk_g is the first
>>>>>>>>>>>>> Looking at clk_core_restore_context(), I see that it walks up
>>>>>>>>>>>>> CLKs
>>>>>>>>>>>>> list
>>>>>>>>>>>>> from parent to children, hence I don't understand how it can
>>>>>>>>>>>>> ever
>>>>>>>>>>>>> happen
>>>>>>>>>>>>> that CCLK will be restored before the parent. The clocks
>>>>>>>>>>>>> registration
>>>>>>>>>>>>> order doesn't matter at all in that case.
>>>>>>>>>>>> yes from parent to children and dfllCPU_out is the top in the
>>>>>>>>>>>> list and
>>>>>>>>>>>> its child is cclk_g.
>>>>>>>>>>>>
>>>>>>>>>>>> the way clocks are registered is the order I see in the clock
>>>>>>>>>>>> list and
>>>>>>>>>>>> looking into clk_register API it adds new node first in the
>>>>>>>>>>>> list.
>>>>>>>>>>>>
>>>>>>>>>>> cclkg_g & dfll register happens after all plls and peripheral
>>>>>>>>>>> clocks as
>>>>>>>>>>> it need ref, soc and peripheral clocks to be enabled.
>>>>>>>>>>>> So they are the last to get registered and so becomes first in
>>>>>>>>>>>> the
>>>>>>>>>>>> list.
>>>>>>>>>>>>
>>>>>>>>>>>> During save/restore context, it traverses thru this list and
>>>>>>>>>>>> first in
>>>>>>>>>>>> the list is dfllcpu_OUT (parent) and its child (cclk_g)
>>>>>>>>>>>>
>>>>>>>>>>>> saving should not be an issue at all but we cant restore
>>>>>>>>>>>> cclk_g/dfll
>>>>>>>>>>>> in normal way thru clk_ops restore as plls and peripherals
>>>>>>>>>>>> restore
>>>>>>>>>>>> doesn't happen by that time.
>>>>>>>>>>>>
>>>>>>>>>>> I was referring to clk_restore_context where it iterates thru
>>>>>>>>>>> root list
>>>>>>>>>>> and for each core from the root list clk_core_restore does
>>>>>>>>>>> restore of
>>>>>>>>>>> parent and children.
>>>>>>>>>>>
>>>>>>>>>>> dfllCPU_Out gets first in the list and its child is cclk_g
>>>>>>>>>>>
>>>>>>>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/clk/clk.c#L1105
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>> What list you're talking about? clk_summary? It shows current
>>>>>>>>>> *active*
>>>>>>>>>> clocks configuration, if you'll try to disable CPUFreq driver
>>>>>>>>>> then
>>>>>>>>>> the
>>>>>>>>>> parent of CCLK_G should be PLLX. Similarly when CPU is
>>>>>>>>>> reparented to
>>>>>>>>>> PLLP on driver's suspend, then PLLP is the parent.
>>>>>>>>>>
>>>>>>>>>>>>>>>> DFLL enable thru CPUFreq resume happens after all
>>>>>>>>>>>>>>>> clk_restore_context
>>>>>>>>>>>>>>>> happens. So during clk_restore_context, dfll re-init
>>>>>>>>>>>>>>>> doesnt
>>>>>>>>>>>>>>>> happen
>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>> doing cpu clock policy restore during super_mux clk_ops
>>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>>> crash as
>>>>>>>>>>>>>>>> DFLL is not initialized and its clock is not enabled
>>>>>>>>>>>>>>>> but CPU
>>>>>>>>>>>>>>>> clock
>>>>>>>>>>>>>>>> restore sets source to DFLL if we restore during
>>>>>>>>>>>>>>>> super_clk_mux
>>>>>>>>>>>>>>> If CPU was suspended on PLLP, then it will be restored on
>>>>>>>>>>>>>>> PLLP by
>>>>>>>>>>>>>>> CaR. I
>>>>>>>>>>>>>>> don't understand what DFLL has to do with the CCLK in that
>>>>>>>>>>>>>>> case
>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>> the clocks restore.
>>>>>>>>>>>>>> My above comment is in reference to your request of doing
>>>>>>>>>>>>>> save/restore
>>>>>>>>>>>>>> for cclk_g in normal fashion thru save/restore context.
>>>>>>>>>>>>>> Because
>>>>>>>>>>>>>> of the
>>>>>>>>>>>>>> clk order I mentioned above, we cclk_g will be the first
>>>>>>>>>>>>>> one to
>>>>>>>>>>>>>> go thru
>>>>>>>>>>>>>> save/context.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> During save_context of cclk_g, source can be from PLLX,
>>>>>>>>>>>>>> dfll.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Issue will be when we do restore during
>>>>>>>>>>>>>> clk_restore_context of
>>>>>>>>>>>>>> cclk_g as
>>>>>>>>>>>>>> by that time PLLX/dfll will not be restored.
>>>>>>>>>>>>>>
>>>>>>>>>>>>> Seems we already agreed that DFLL will be disabled by the
>>>>>>>>>>>>> CPUFreq
>>>>>>>>>>>>> driver
>>>>>>>>>>>>> on suspend. Hence CCLK can't be from DFLL if CPU is
>>>>>>>>>>>>> reparented to
>>>>>>>>>>>>> PLLP
>>>>>>>>>>>>> on CPUFreq driver's suspend, otherwise CPU keeps running
>>>>>>>>>>>>> from a
>>>>>>>>>>>>> boot-state PLLX if CPUFreq driver is disabled.
>>>>>>>>>>>> Yes suspend should not be an issue but issue will be during
>>>>>>>>>>>> resume
>>>>>>>>>>>> where if we do cclk_g restore in normal way thru
>>>>>>>>>>>> clk_restore_context,
>>>>>>>>>>>> cclk_g restore happens very early as dfllCPU out is the first
>>>>>>>>>>>> one that
>>>>>>>>>>>> goes thru restore context and plls/peripherals are not
>>>>>>>>>>>> resumed by
>>>>>>>>>>>> then.
>>>>>>>>>>>>
>>>>>>>>>>>> CPU runs from PLLX if dfll clock enable fails during boot. So
>>>>>>>>>>>> when it
>>>>>>>>>>>> gets to suspend, we save CPU running clock source as either
>>>>>>>>>>>> PLLX or
>>>>>>>>>>>> DFLL and then we switch to PLLP.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On resume, CPU runs from PLLP by warm boot code and we need to
>>>>>>>>>>>> restore
>>>>>>>>>>>> back its source to the one it was using from saved source
>>>>>>>>>>>> context
>>>>>>>>>>>> (which can be either PLLX or DFLL)
>>>>>>>>>>>>
>>>>>>>>>>>> So PLLs & DFLL resume need to happen before CCLKG
>>>>>>>>>>>> restore/resume.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> With all above discussions, we do DFLL disable in CPUFreq
>>>>>>>>>>>> driver on
>>>>>>>>>>>> suspend and on CPUFreq resume we enable DFLL back and
>>>>>>>>>>>> restore CPU
>>>>>>>>>>>> clock source it was using during suspend (which will be either
>>>>>>>>>>>> PLLX if
>>>>>>>>>>>> dfll enable fails during probe or it will be using DFLL).
>>>>>>>>>> During suspend CPU's parent shall be PLLP and not DFLL (note
>>>>>>>>>> that
>>>>>>>>>> it is
>>>>>>>>>> disabled) after reparenting to PLLP by the CPUFreq driver.
>>>>>>>>>>
>>>>>>>>> CPU source context should be saved before switching to safe
>>>>>>>>> source of
>>>>>>>>> PLLP as on resume we need to restore back to source it was using
>>>>>>>>> before we switch to safe source during suspend entry.
>>>>>>>>>
>>>>>>>>> So saved context for CPU Source will be either dfll or PLLX
>>>>>>>>>
>>>>>>>> PLLP reparenting is only during suspend/entry to have it as safe
>>>>>>>> source
>>>>>>>> but actual CPU source it was running from before suspending is
>>>>>>>> either
>>>>>>>> dfll/pllx which should be the one to be restored on CPUFreq
>>>>>>>> resume.
>>>>>>>> Resume happens with CPU running from PLLP till it gets to the
>>>>>>>> point of
>>>>>>>> restoring its original source (dfll or pllx)
>>>>>>> CaR should restore CPU to PLLP or PLLX, while CPUFreq driver
>>>>>>> restores
>>>>>>> CPU to DFLL. Please see more comments below.
>>>>>>>
>>>>>>>>>>>> So i was trying to say dfll/cclk_g restore can't be done in
>>>>>>>>>>>> normal way
>>>>>>>>>>>> thru clk_ops save/restore context
>>>>>>>>>> Let's see what happens if CPUFreq is active:
>>>>>>>>>>
>>>>>>>>>> 1. CPUFreq driver probe happens
>>>>>>>>>> 2. CPU is reparented to PLLP
>>>>>>>>>> 3. DFLL inited
>>>>>>>>>> 4. CPU is reparented to DFLL
>>>>>>>>>>
>>>>>>>>>> 5. CPUFreq driver suspend happens
>>>>>>>>>> 6. CPU is reparented to PLLP
>>>>>>>>>> 7. DFLL is disabled
>>>>>>>>>>
>>>>>>>>>> 8. Car suspend happens
>>>>>>>>>> 9. DFLL context saved
>>>>>>>>>> 10. PLLP/PLLX context saved
>>>>>>>>>> 11. CCLK context saved
>>>>>>>>>>
>>>>>>>>>> 12. Car resume happens
>>>>>>>>>> 13. DFLL context restored
>>>>>>>>>> 14. PLLP/PLLX context restored
>>>>>>>>>> 15. CCLK context restored
>>>>>>>>>>
>>>>>>>>>> 16. CPUFreq driver resume happens
>>>>>>>>>> 17. DFLL re-inited
>>>>>>>>>> 18. CPU is reparented to DFLL
>>>>>>>>> Below is the order of sequence it should be based on the order of
>>>>>>>>> clk
>>>>>>>>> register.
>>>>>>>>>
>>>>>>>>> My comments inline in this sequence.
>>>>>>>>>
>>>>>>>>> 1. CPUFreq driver probe happens
>>>>>>>>> 2. CPU is reparented to PLLP
>>>>>>>>> 3. DFLL inited
>>>>>>>>> 4. CPU is reparented to DFLL
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> 5. CPUFreq driver suspend happens
>>>>>>>>> 6. Save CPU source which could be either dfll or pllx
>>>>>>> Please see my next comment.
>>>>>>>
>>>>>>>>> 7. CPU is reparented to safe known source PLLP
>>>>>>>>> 8. DFLL is disabled
>>>>>>>>>
>>>>>>>>> 8. Car suspend happens
>>>>>>>>> 9. DFLL context saved (With DFLL disabled in CPUFreq
>>>>>>>>> suspend,
>>>>>>>>> nothing to be saved here as last freq req will always be saved).
>>>>>>>>> 10. CCLK context saved (CPU clock source will be saved in
>>>>>>>>> CPUFreq
>>>>>>>>> driver suspend which could be either dfll or pllx)
>>>>>>> That I don't understand. The CPU's clock source state should be
>>>>>>> saved at
>>>>>>> the moment of the CaR's suspending (i.e. CCLK policy will be set to
>>>>>>> PLLP
>>>>>>> or PLLX) and then CCLK state should be also restored by the CaR in
>>>>>>> step 14.
>>>>>> CPU clock to be saved and restored should be the source used
>>>>>> before we
>>>>>> switch it to safe PLLP for suspend/resume operation.
>>>>>>
>>>>>> This original source could be either PLLX or DFLL which it was using
>>>>>> before we disable DFLL during CPU Freq suspend.
>>>>>>
>>>>>> If we save CPU clock source at moment of CAR suspending, it will be
>>>>>> PLLP as we switch to safe PLLP in CPUFreq driver suspend.
>>>>>>
>>>>>> Infact, we dont need to restore CPU clock source to PLLP anywhere in
>>>>>> resume as it comes up with PLLP source from warm boot code itself.
>>>> You must always maintain proper suspend/resume encapsulation,
>>>> otherwise
>>>> it's a total mess. It doesn't matter that CCLK is restored to PLLP
>>>> even
>>>> that CPU is already running off PLLP after warmboot.
>>>>
>>>>>> But we need to restore CPU source to original source it was using
>>>>>> before we switch to safe PLLP source for suspend operation. This
>>>>>> original source could be PLLX/DFLL and this should be re-stored in
>>>>>> CPUFreq resume as by this time PLLs and peripherals are restored and
>>>>>> dfll is re-initialized.
>>>>>>
>>>>>> So saving actual CPU source before switching to intermediate safe
>>>>>> PLLP
>>>>>> in CPUFreq driver and then restoring back during CPUFreq resume
>>>>>> should
>>>>>> be good as CPUFreq resume happens right after all clocks (plls
>>>>>> restore, peripherals restore, dfll resume)>>
>>>>>>> CPUFreq driver should only switch CPU to PLLP and disable DFLL on
>>>>>>> suspend in step 5, that's it. On resume CPUFreq driver will restore
>>>>>>> CPU
>>>>>>> to DFLL in step 18.
>>>>>> Also I don't think we should hard-code to force CPU source to
>>>>>> DFLL on
>>>>>> CPUFreq resume.
>>>>>>
>>>>>> Reason is during CPU Probe when it tries to switch to dfll
>>>>>> source, for
>>>>>> some reason if dfll enable fails it sets CPU to its original source
>>>>>> which will be PLLX.
>>>> No!
>>>>
>>>> 1. CPU voltage could be too low for PLLX
>>>> 2. PLLX rate can't be changed without manual reparenting CPU to
>>>> intermediate clock
>>>> 3. CPUFreq can't manually manage CPU voltage
>>>>
>>>> DFLL-restoring failure is an extreme case. CPU must be kept on a safe
>>>> PLLP in that case and disable_cpufreq() must be invoked as well.
>>> OK, PLLX option was also in my mind. So If we just consider sources as
>>> DFLL or PLLP, then we can save source in CCLK save context and restore
>>> in CCLK restore basically it will be PLLP.
>>>
>>> Later during CPUFreq resume we can just switch to DFLL and if DFLL
>>> enable fails we will keep source as PLLP. Yes will invoke
>>> disable_cpufreq as well in case of dfll enable failure for some reason.
>> Sounds good!
>>
>>>>>> So CPU source could be either DFLL or PLLX in CPUFreq
>>>>>> tegra124_cpu_switch_to_dfll
>>>>>>
>>>>>>>>> 11. PLLP/PLLX context saved
>>>>>>>>> 12. Peripheral Clock saved
>>>>>>>>>
>>>>>>>>> 12. Car resume happens
>>>>>>>>> 13. DFLL context restored : No DFLL context to be restored
>>>>>>>>> and we
>>>>>>>>> only need to reinitialize DFLL and re-initialize can't be done
>>>>>>>>> here as
>>>>>>>>> this is the 1st to get restored and PLL/Peripheral clocks are not
>>>>>>>>> restored by this time. So we can't use clk_ops restore for DFLL
>>>>>>> It looks to me that clk_core_restore_context() should just do
>>>>>>> hlist_for_each_entry *_reverse*. Don't you think so?
>>>>>> Thought of that but this is in core driver and is used by other
>>>>>> non-tegra clock driver and not sure if that impacts for those.
>>>> The reverse ordering should be correct, I think it's just a
>>>> shortcoming
>>>> of the CCF that need to be fixed. But will better to make a more
>>>> thorough research, asking Stephen and Michael for the clarification.
>>>>
>>>>>> But with decision of switching CPUFreq with dfll clock
>>>>>> enable/disable
>>>>>> during CPUFreq suspend/resume, we can re-init dfll during dfll-fcpu
>>>>>> driver resume and we don't need CCLK save/restore.
>>>>>>
>> Actually CPUFreq driver should implement suspend/resume regardless of
>> CaR ability to restore DFLL or whatever, simply to properly handle
>> possible clock restoring failure on resume as we just found out.
>>
>>>>> the way of all clocks order is good except cclk_g which has
>>>>> dependency
>>>>> on multiple clocks.
>>>> CCLK_G has a single parent at a time. What "multiple clocks" you're
>>>> talking about? Please explain.
>>> dependencies I am referring are dfll_ref, dfll_soc, and DVFS peripheral
>>> clocks which need to be restored prior to DFLL reinit.
>> Okay, but that shouldn't be a problem if clock dependencies are set up
>> properly.
>>
>>>>> reverse list order during restore might not work as all other
>>>>> clocks are
>>>>> in proper order no with any ref clocks for plls getting restored
>>>>> prior
>>>>> to their clients
>>>> Why? The ref clocks should be registered first and be the roots for
>>>> PLLs
>>>> and the rest. If it's not currently the case, then this need to be
>>>> fixed. You need to ensure that each clock is modeled properly. If some
>>>> child clock really depends on multiple parents, then the parents
>>>> need to
>>>> in the correct order or CCF need to be taught about such
>>>> multi-dependencies.
>>>>
>>>> If some required feature is missed, then you have to implement it
>>>> properly and for all, that's how things are done in upstream.
>>>> Sometimes
>>>> it's quite a lot of extra work that everyone are benefiting from in
>>>> the end.
>>>>
>>>> [snip]
>>> Yes, we should register ref/parents before their clients.
>>>
>>> cclk_g clk is registered last after all pll and peripheral clocks are
>>> registers during clock init.
>>>
>>> dfllCPU_out clk is registered later during dfll-fcpu driver probe and
>>> gets added to the clock list.
>>>
>>> Probably the issue seems to be not linking dfll_ref and dfll_soc
>>> dependencies for dfllCPU_out thru clock list.
>>>
>>> clk-dfll driver during dfll_init_clks gets ref_clk and soc_clk
>>> reference
>>> thru DT.
>> Please try to fix all missing dependencies and orderings.
>
> Peter,
>
> dfllCPU_OUT is the first one to go thru restore when
> clk_restore_context traverses thru the list.
>
> dfllCPU_OUT has dependency on DFLL_ref and DFLL_SOC but this
> dependency is unknown to clock-tree.
>
> We can add DFLL_REF and DFLL_SOC as parents to dfllCPU_OUT during
> register so dfllCPU_OUT save/restore happens after their parents are
> restored.
>
> But DFLL needs both of these to be restored before DFLLCPU_Out and as
> DFLL_SOC restore always happens after the REF, thinking to add
> DFLL_SOC as parent to dfllCPU_OUT so save/restore follows after their
> dependencies.
>
> Please comment.
>
Did quick try and I see by adding dfll-soc as parent to dfllCPU_OUT, its
in proper order after all its dependencies.
Can now add dfll save/restore to do dfll reinit during restore..
^ permalink raw reply
* Re: [PATCH v5 2/2] dt-bindings: mtd: Document Macronix raw NAND controller bindings
From: masonccyang @ 2019-07-18 0:59 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: mark.rutland, devicetree, christophe.kerello, richard, bbrezillon,
juliensu, lee.jones, linux-kernel, robh+dt, paul, marek.vasut,
paul.burton, liang.yang, linux-mtd, stefan, miquel.raynal,
anders.roxell, computersforpeace, dwmw2, vigneshr
In-Reply-To: <93e86083-7f8a-402d-db4b-26263719be25@cogentembedded.com>
Hi Sergei,
> > Document the bindings used by the Macronix raw NAND controller.
> >
> > Signed-off-by: Mason Yang <masonccyang@mxic.com.tw>
> > ---
> > Documentation/devicetree/bindings/mtd/mxic-nand.txt | 20
++++++++++++++++++++
> > 1 file changed, 20 insertions(+)
> > create mode 100644
Documentation/devicetree/bindings/mtd/mxic-nand.txt
> >
> > diff --git a/Documentation/devicetree/bindings/mtd/mxic-nand.txt b/
> Documentation/devicetree/bindings/mtd/mxic-nand.txt
> > new file mode 100644
> > index 0000000..ddd7660
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/mtd/mxic-nand.txt
> > @@ -0,0 +1,20 @@
> > +Macronix Raw NAND Controller Device Tree Bindings
> > +-------------------------------------------------
> > +
> > +Required properties:
> > +- compatible: should be "macronix,nand-controller"
> > +- reg: should contain 1 entrie for the registers
> > +- interrupts: interrupt line connected to this raw NAND controller
> > +- clock-names: should contain "ps_clk", "send_clk" and "send_dly_clk"
> > +- clocks: should contain 3 phandles for the "ps_clk", "send_clk" and
> > + "send_dly_clk" clocks
> > +
> > +Example:
> > +
> > + nand: mxic-nfc@43c30000 {
>
> The node names should be generic, and the DT spec 0.2 (section
2.2.2) even
> has documented "nand-controller", please rename.
okay, will fix it to
nand: nand-controller@43c30000 {
}
>
> > + compatible = "macronix,nand-controller";
> > + reg = <0x43c30000 0x10000>;
> > + reg-names = "regs";
> > + clocks = <&clkwizard 0>, <&clkwizard 1>, <&clkc 15>;
> > + clock-names = "send_clk", "send_dly_clk", "ps_clk";
> > + };
> >
>
> MBR, Sergei
thanks & best regards,
Mason
CONFIDENTIALITY NOTE:
This e-mail and any attachments may contain confidential information
and/or personal data, which is protected by applicable laws. Please be
reminded that duplication, disclosure, distribution, or use of this e-mail
(and/or its attachments) or any part thereof is prohibited. If you receive
this e-mail in error, please notify us immediately and delete this mail as
well as its attachment(s) from your system. In addition, please be
informed that collection, processing, and/or use of personal data is
prohibited unless expressly permitted by personal data protection laws.
Thank you for your attention and cooperation.
Macronix International Co., Ltd.
=====================================================================
============================================================================
CONFIDENTIALITY NOTE:
This e-mail and any attachments may contain confidential information and/or personal data, which is protected by applicable laws. Please be reminded that duplication, disclosure, distribution, or use of this e-mail (and/or its attachments) or any part thereof is prohibited. If you receive this e-mail in error, please notify us immediately and delete this mail as well as its attachment(s) from your system. In addition, please be informed that collection, processing, and/or use of personal data is prohibited unless expressly permitted by personal data protection laws. Thank you for your attention and cooperation.
Macronix International Co., Ltd.
=====================================================================
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply
* Re: [PATCH V5 11/18] clk: tegra210: Add support for Tegra210 clocks
From: Sowjanya Komatineni @ 2019-07-18 0:25 UTC (permalink / raw)
To: Dmitry Osipenko, sboyd, Michael Turquette
Cc: Peter De Schrijver, Joseph Lo, thierry.reding, jonathanh, tglx,
jason, marc.zyngier, linus.walleij, stefan, mark.rutland,
pgaikwad, linux-clk, linux-gpio, jckuo, talho, linux-tegra,
linux-kernel, mperttunen, spatra, robh+dt, devicetree
In-Reply-To: <89f23878-d4b2-2305-03e5-8a3e781c2b02@gmail.com>
On 7/17/19 4:44 PM, Dmitry Osipenko wrote:
> 18.07.2019 2:36, Sowjanya Komatineni пишет:
>> On 7/17/19 3:48 PM, Dmitry Osipenko wrote:
>>> 18.07.2019 0:57, Sowjanya Komatineni пишет:
>>>> On 7/17/19 2:51 PM, Sowjanya Komatineni wrote:
>>>>> On 7/17/19 2:30 PM, Dmitry Osipenko wrote:
>>>>>> 17.07.2019 23:11, Sowjanya Komatineni пишет:
>>>>>>> On 7/17/19 1:01 PM, Sowjanya Komatineni wrote:
>>>>>>>> On 7/17/19 12:43 PM, Dmitry Osipenko wrote:
>>>>>>>>> 17.07.2019 21:54, Sowjanya Komatineni пишет:
>>>>>>>>>> On 7/17/19 11:51 AM, Sowjanya Komatineni wrote:
>>>>>>>>>>> On 7/17/19 11:32 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>> 17.07.2019 20:29, Sowjanya Komatineni пишет:
>>>>>>>>>>>>> On 7/17/19 8:17 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>> 17.07.2019 9:36, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>> On 7/16/19 11:33 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>> В Tue, 16 Jul 2019 22:55:52 -0700
>>>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On 7/16/19 10:42 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>> В Tue, 16 Jul 2019 22:25:25 -0700
>>>>>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>>>>>> On 7/16/19 9:11 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>> В Tue, 16 Jul 2019 19:35:49 -0700
>>>>>>>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>>>>>>>> On 7/16/19 7:18 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 3:06 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 3:00 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>> 17.07.2019 0:35, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 2:21 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>> 17.07.2019 0:12, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 1:47 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 22:26, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:43 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:30, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:25 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:19, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 9:50 AM, Sowjanya Komatineni
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 8:00 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 11:06, Peter De Schrijver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2019 at 03:24:26PM
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +0800,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Joseph
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Lo wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OK, Will add to CPUFreq driver...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The other thing that also need
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> attention is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> that T124 CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicitly relies on DFLL driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to be
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> first, which is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> icky.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Should I add check for successful
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> register explicitly in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver probe and defer till
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> registers?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Probably you should use the "device
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> links".
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> See
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1][2] for the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> example.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/gpu/drm/tegra/dc.c#L2383
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [2]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://www.kernel.org/doc/html/latest/driver-api/device_link.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Return EPROBE_DEFER instead of EINVAL if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device_link_add() fails.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use of_find_device_by_node() to get the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device, see [3].
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [3]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/devfreq/tegra20-devfreq.c#n100
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Will go thru and add...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Looks like I initially confused this case
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getting
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> orphaned clock.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'm now seeing that the DFLL driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> registers the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock and then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk_get(dfll) should be returning
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> EPROBE_DEFER
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> until
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL driver is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probed, hence everything should be fine
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as-is and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> there is no real
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for the 'device link'. Sorry for the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> confusion!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, I didn't follow the mail
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> thread. Just
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regarding the DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> part.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> As you know it, the DFLL clock is one
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock sources and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integrated with DVFS control logic
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator. We will not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to other clock sources once we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switched to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL. Because the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU has
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> been regulated by the DFLL HW with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DVFS
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (CVB or OPP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> you see
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> in the driver.). We shouldn't reparent
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> other sources with
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unknew
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> freq/volt pair. That's not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> guaranteed to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> work. We
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allow switching to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> open-loop mode but different sources.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay, then the CPUFreq driver will
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rate before switching to PLLP in order to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper CPU voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP freq is safe to work for any CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> So no
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to PLLP rate before changing
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK_G
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to PLLP during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, please ignore my above comment.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> During
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend, need to change
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK_G source to PLLP when dfll is in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> closed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode first and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll need to be set to open loop.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And I don't exactly understand why we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to PLLP in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> idle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver. Just keep it on CL-DVFS mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> time.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 entry, the dfll suspend function
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moves it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the open-loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode. That's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all. The sc7-entryfirmware will handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the rest
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn off
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU power.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 resume, the warmboot code will
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator and power up the CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cluster. And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> leave
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it on PLL_P.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> After
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resuming to the kernel, we re-init
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> policy (CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> runs on DFLL open-loop mode) and then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moving to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> close-loop mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL is re-inited after switching
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> early clocks-state restoring by CaR
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hence
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> instead of having
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> odd
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hacks in the CaR driver, it is much
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> nicer to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper suspend-resume sequencing of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> drivers. In this case
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver is the driver that enables DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switches
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to that
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source, which means that this driver is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> also
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> be responsible for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> management of the DFLL's state during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend/resume process. If
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver disables DFLL during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> re-enables it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resume, then looks like the CaR driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hacks
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> around
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL are not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> needed.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL part looks good to me. BTW,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> change the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> patch subject to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "Add
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend-resume support" seems more
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> me.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> To clarify this, the sequences for DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> are as
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> follows (assuming
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> required DFLL hw configuration has been
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> done)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch to DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Save current parent and frequency
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2) Enable DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3) Change cclk_g parent to DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For OVR regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Change PWM output pin from
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> tristate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 5) Enable DFLL PWM output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For I2C regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Enable DFLL I2C output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 6) Program DFLL to closed loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch away from DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Change cclk_g parent to PLLP so
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> frequency is ok for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> any
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> vdd_cpu voltage
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I see during switch away from DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (suspend),
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cclk_g
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent is not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> changed to PLLP before changing dfll to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> open
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Will add this ...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The CPUFreq driver switches parent to PLLP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probe, similar
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should be done on suspend.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'm also wondering if it's always safe to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP in the probe.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> If CPU is running on a lower freq than
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP, then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> some
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> other more
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate intermediate parent should be
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> selected.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU parents are PLL_X, PLL_P, and dfll. PLL_X
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> always
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> runs at higher
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rate
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> so switching to PLL_P during CPUFreq probe
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> prior to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll clock enable
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should be safe.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AFAIK, PLLX could run at ~200MHz. There is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> also a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> divided output of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> which CCLKG supports, the PLLP_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Probably, realistically, CPU is always running
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> off a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> fast PLLX during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> boot, but I'm wondering what may happen on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> KEXEC. I
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> guess ideally CPUFreq driver should also
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'shutdown' callback to teardown DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> on a reboot, but likely that there are other
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock-related problems as
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> well that may break KEXEC and thus it is not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> very
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> important at the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moment.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [snip]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> During bootup CPUG sources from PLL_X. By PLL_P
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> above I meant
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLL_P_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> As per clock policies, PLL_X is always used
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for high
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> freq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 800Mhz
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and for low frequency it will be sourced from
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Alright, then please don't forget to
>>>>>>>>>>>>>>>>>>>>>>>>>>>> pre-initialize
>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate to a
>>>>>>>>>>>>>>>>>>>>>>>>>>>> reasonable value using tegra_clk_init_table or
>>>>>>>>>>>>>>>>>>>>>>>>>>>> assigned-clocks.
>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate update is not needed as it is
>>>>>>>>>>>>>>>>>>>>>>>>>>> safe to
>>>>>>>>>>>>>>>>>>>>>>>>>>> run at
>>>>>>>>>>>>>>>>>>>>>>>>>>> 408Mhz because it is below fmax @ Vmin
>>>>>>>>>>>>>>>>>>>>>>>>>> So even 204MHz CVB entries are having the same
>>>>>>>>>>>>>>>>>>>>>>>>>> voltage as
>>>>>>>>>>>>>>>>>>>>>>>>>> 408MHz, correct? It's not instantly obvious to me
>>>>>>>>>>>>>>>>>>>>>>>>>> from the
>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL driver's code where the fmax @ Vmin is
>>>>>>>>>>>>>>>>>>>>>>>>>> defined,
>>>>>>>>>>>>>>>>>>>>>>>>>> I see
>>>>>>>>>>>>>>>>>>>>>>>>>> that there is the min_millivolts
>>>>>>>>>>>>>>>>>>>>>>>>>> and frequency entries starting from 204MHZ defined
>>>>>>>>>>>>>>>>>>>>>>>>>> per-table.
>>>>>>>>>>>>>>>>>>>>>>>>> Yes at Vmin CPU Fmax is ~800Mhz. So anything below
>>>>>>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>>>>>>>>>>>> work at Vmin voltage and PLLP max is 408Mhz.
>>>>>>>>>>>>>>>>>>>>>>>> Thank you for the clarification. It would be good
>>>>>>>>>>>>>>>>>>>>>>>> to have
>>>>>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>>>>>> commented
>>>>>>>>>>>>>>>>>>>>>>>> in the code as well.
>>>>>>>>>>>>>>>>>>>>>>> OK, Will add...
>>>>>>>>>>>>>>>>>>>>>> Regarding, adding suspend/resume to CPUFreq, CPUFreq
>>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>>> happens very early even before disabling non-boot
>>>>>>>>>>>>>>>>>>>>>> CPUs and
>>>>>>>>>>>>>>>>>>>>>> also
>>>>>>>>>>>>>>>>>>>>>> need to export clock driver APIs to CPUFreq.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Was thinking of below way of implementing this...
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Clock DFLL driver Suspend:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> - Save CPU clock policy registers, and
>>>>>>>>>>>>>>>>>>>>>> Perform
>>>>>>>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>>>>>>>> suspend which sets in open loop mode
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> CPU Freq driver Suspend: does nothing
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Clock DFLL driver Resume:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> - Re-init DFLL, Set in Open-Loop mode,
>>>>>>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>> Clock policy registers which actually sets source to
>>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>>> along
>>>>>>>>>>>>>>>>>>>>>> with other CPU Policy register restore.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> CPU Freq driver Resume:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> - do clk_prepare_enable which acutally
>>>>>>>>>>>>>>>>>>>>>> sets
>>>>>>>>>>>>>>>>>>>>>> DFLL in
>>>>>>>>>>>>>>>>>>>>>> Closed loop mode
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Adding one more note: Switching CPU Clock to PLLP
>>>>>>>>>>>>>>>>>>>>>> is not
>>>>>>>>>>>>>>>>>>>>>> needed
>>>>>>>>>>>>>>>>>>>>>> as CPU CLock can be from dfll in open-loop mode as
>>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>>> is not
>>>>>>>>>>>>>>>>>>>>>> disabled anywhere throught the suspend/resume path
>>>>>>>>>>>>>>>>>>>>>> and SC7
>>>>>>>>>>>>>>>>>>>>>> entry
>>>>>>>>>>>>>>>>>>>>>> FW and Warm boot code will switch CPU source to PLLP.
>>>>>>>>>>>>>>>>>>>> Since CPU resumes on PLLP, it will be cleaner to suspend
>>>>>>>>>>>>>>>>>>>> it on
>>>>>>>>>>>>>>>>>>>> PLLP as well. And besides, seems that currently
>>>>>>>>>>>>>>>>>>>> disabling
>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>> clock will disable DFLL completely and then you'd
>>>>>>>>>>>>>>>>>>>> want to
>>>>>>>>>>>>>>>>>>>> re-init
>>>>>>>>>>>>>>>>>>>> the DFLL on resume any ways. So better to just disable
>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>> completely on suspend, which should happen on
>>>>>>>>>>>>>>>>>>>> clk_disable(dfll).
>>>>>>>>>>>>>>>>>>> Will switch to PLLP during CPUFreq suspend. With
>>>>>>>>>>>>>>>>>>> decision of
>>>>>>>>>>>>>>>>>>> using
>>>>>>>>>>>>>>>>>>> clk_disable during suspend, its mandatory to switch to
>>>>>>>>>>>>>>>>>>> PLLP as
>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>> is completely disabled.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> My earlier concern was on restoring CPU policy as we
>>>>>>>>>>>>>>>>>>> can't do
>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>> from CPUFreq driver and need export from clock driver.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Clear now and will do CPU clock policy restore in after
>>>>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>>>>> re-init.
>>>>>>>>>>>>>>>>>> Why the policy can't be saved/restored by the CaR driver
>>>>>>>>>>>>>>>>>> as a
>>>>>>>>>>>>>>>>>> context of any other clock?
>>>>>>>>>>>>>>>>> restoring cpu clock policy involves programming source and
>>>>>>>>>>>>>>>>> super_cclkg_divider.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> cclk_g is registered as clk_super_mux and it doesn't use
>>>>>>>>>>>>>>>>> frac_div ops
>>>>>>>>>>>>>>>>> to do save/restore its divider.
>>>>>>>>>>>>>>>> That can be changed of course and I guess it also could
>>>>>>>>>>>>>>>> be as
>>>>>>>>>>>>>>>> simple as
>>>>>>>>>>>>>>>> saving and restoring of two raw u32 values of the
>>>>>>>>>>>>>>>> policy/divider
>>>>>>>>>>>>>>>> registers.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Also, during clock context we cant restore cclk_g as cclk_g
>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>> will be dfll and dfll will not be resumed/re-initialized
>>>>>>>>>>>>>>>>> by the
>>>>>>>>>>>>>>>>> time
>>>>>>>>>>>>>>>>> clk_super_mux save/restore happens.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> we can't use save/restore context for dfll clk_ops because
>>>>>>>>>>>>>>>>> dfllCPU_out parent to CCLK_G is first in the clock tree and
>>>>>>>>>>>>>>>>> dfll_ref
>>>>>>>>>>>>>>>>> and dfll_soc peripheral clocks are not restored by the
>>>>>>>>>>>>>>>>> time dfll
>>>>>>>>>>>>>>>>> restore happens. Also dfll peripheral clock enables need
>>>>>>>>>>>>>>>>> to be
>>>>>>>>>>>>>>>>> restored before dfll restore happens which involves
>>>>>>>>>>>>>>>>> programming
>>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>>> controller for re-initialization.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> So dfll resume/re-init is done in clk-tegra210 at end of
>>>>>>>>>>>>>>>>> all
>>>>>>>>>>>>>>>>> clocks
>>>>>>>>>>>>>>>>> restore in V5 series but instead of in clk-tegra210
>>>>>>>>>>>>>>>>> driver I
>>>>>>>>>>>>>>>>> moved
>>>>>>>>>>>>>>>>> now to dfll-fcpu driver pm_ops as all dfll dependencies
>>>>>>>>>>>>>>>>> will be
>>>>>>>>>>>>>>>>> restored thru clk_restore_context by then. This will be in
>>>>>>>>>>>>>>>>> V6.
>>>>>>>>>>>>>>>> Since DFLL is now guaranteed to be disabled across CaR
>>>>>>>>>>>>>>>> suspend/resume
>>>>>>>>>>>>>>>> (hence it has nothing to do in regards to CCLK) and given
>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>> PLLs
>>>>>>>>>>>>>>>> state is restored before the rest of the clocks, I don't
>>>>>>>>>>>>>>>> see why
>>>>>>>>>>>>>>>> not to
>>>>>>>>>>>>>>>> implement CCLK save/restore in a generic fasion. CPU policy
>>>>>>>>>>>>>>>> wull be
>>>>>>>>>>>>>>>> restored to either PLLP or PLLX (if CPUFreq driver is
>>>>>>>>>>>>>>>> disabled).
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> CCLK_G save/restore should happen in clk_super_mux ops
>>>>>>>>>>>>>>> save/context and
>>>>>>>>>>>>>>> clk_super_mux save/restore happens very early as cclk_g is
>>>>>>>>>>>>>>> first
>>>>>>>>>>>>>>> in the
>>>>>>>>>>>>>>> clock tree and save/restore traverses through the tree
>>>>>>>>>>>>>>> top-bottom
>>>>>>>>>>>>>>> order.
>>>>>>>>>>>>>> If CCLK_G is restored before the PLLs, then just change the
>>>>>>>>>>>>>> clocks
>>>>>>>>>>>>>> order
>>>>>>>>>>>>>> such that it won't happen.
>>>>>>>>>>>>>>
>>>>>>>>>>>>> I dont think we can change clocks order for CCLK_G.
>>>>>>>>>>>>>
>>>>>>>>>>>>> During bootup, cclk_g is registered after all pll's and
>>>>>>>>>>>>> peripheral
>>>>>>>>>>>>> clocks which is the way we wanted, So cclk_g will be the first
>>>>>>>>>>>>> one in
>>>>>>>>>>>>> the clk list as clk_register adds new clock first in the list.
>>>>>>>>>>>>>
>>>>>>>>>>>>> When clk_save_context and clk_restore_context APIs iterates
>>>>>>>>>>>>> over the
>>>>>>>>>>>>> list, cclk_g is the first
>>>>>>>>>>>> Looking at clk_core_restore_context(), I see that it walks up
>>>>>>>>>>>> CLKs
>>>>>>>>>>>> list
>>>>>>>>>>>> from parent to children, hence I don't understand how it can
>>>>>>>>>>>> ever
>>>>>>>>>>>> happen
>>>>>>>>>>>> that CCLK will be restored before the parent. The clocks
>>>>>>>>>>>> registration
>>>>>>>>>>>> order doesn't matter at all in that case.
>>>>>>>>>>> yes from parent to children and dfllCPU_out is the top in the
>>>>>>>>>>> list and
>>>>>>>>>>> its child is cclk_g.
>>>>>>>>>>>
>>>>>>>>>>> the way clocks are registered is the order I see in the clock
>>>>>>>>>>> list and
>>>>>>>>>>> looking into clk_register API it adds new node first in the list.
>>>>>>>>>>>
>>>>>>>>>> cclkg_g & dfll register happens after all plls and peripheral
>>>>>>>>>> clocks as
>>>>>>>>>> it need ref, soc and peripheral clocks to be enabled.
>>>>>>>>>>> So they are the last to get registered and so becomes first in
>>>>>>>>>>> the
>>>>>>>>>>> list.
>>>>>>>>>>>
>>>>>>>>>>> During save/restore context, it traverses thru this list and
>>>>>>>>>>> first in
>>>>>>>>>>> the list is dfllcpu_OUT (parent) and its child (cclk_g)
>>>>>>>>>>>
>>>>>>>>>>> saving should not be an issue at all but we cant restore
>>>>>>>>>>> cclk_g/dfll
>>>>>>>>>>> in normal way thru clk_ops restore as plls and peripherals
>>>>>>>>>>> restore
>>>>>>>>>>> doesn't happen by that time.
>>>>>>>>>>>
>>>>>>>>>> I was referring to clk_restore_context where it iterates thru
>>>>>>>>>> root list
>>>>>>>>>> and for each core from the root list clk_core_restore does
>>>>>>>>>> restore of
>>>>>>>>>> parent and children.
>>>>>>>>>>
>>>>>>>>>> dfllCPU_Out gets first in the list and its child is cclk_g
>>>>>>>>>>
>>>>>>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/clk/clk.c#L1105
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>> What list you're talking about? clk_summary? It shows current
>>>>>>>>> *active*
>>>>>>>>> clocks configuration, if you'll try to disable CPUFreq driver then
>>>>>>>>> the
>>>>>>>>> parent of CCLK_G should be PLLX. Similarly when CPU is
>>>>>>>>> reparented to
>>>>>>>>> PLLP on driver's suspend, then PLLP is the parent.
>>>>>>>>>
>>>>>>>>>>>>>>> DFLL enable thru CPUFreq resume happens after all
>>>>>>>>>>>>>>> clk_restore_context
>>>>>>>>>>>>>>> happens. So during clk_restore_context, dfll re-init doesnt
>>>>>>>>>>>>>>> happen
>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>> doing cpu clock policy restore during super_mux clk_ops will
>>>>>>>>>>>>>>> crash as
>>>>>>>>>>>>>>> DFLL is not initialized and its clock is not enabled but CPU
>>>>>>>>>>>>>>> clock
>>>>>>>>>>>>>>> restore sets source to DFLL if we restore during
>>>>>>>>>>>>>>> super_clk_mux
>>>>>>>>>>>>>> If CPU was suspended on PLLP, then it will be restored on
>>>>>>>>>>>>>> PLLP by
>>>>>>>>>>>>>> CaR. I
>>>>>>>>>>>>>> don't understand what DFLL has to do with the CCLK in that
>>>>>>>>>>>>>> case
>>>>>>>>>>>>>> during
>>>>>>>>>>>>>> the clocks restore.
>>>>>>>>>>>>> My above comment is in reference to your request of doing
>>>>>>>>>>>>> save/restore
>>>>>>>>>>>>> for cclk_g in normal fashion thru save/restore context. Because
>>>>>>>>>>>>> of the
>>>>>>>>>>>>> clk order I mentioned above, we cclk_g will be the first one to
>>>>>>>>>>>>> go thru
>>>>>>>>>>>>> save/context.
>>>>>>>>>>>>>
>>>>>>>>>>>>> During save_context of cclk_g, source can be from PLLX, dfll.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Issue will be when we do restore during clk_restore_context of
>>>>>>>>>>>>> cclk_g as
>>>>>>>>>>>>> by that time PLLX/dfll will not be restored.
>>>>>>>>>>>>>
>>>>>>>>>>>> Seems we already agreed that DFLL will be disabled by the
>>>>>>>>>>>> CPUFreq
>>>>>>>>>>>> driver
>>>>>>>>>>>> on suspend. Hence CCLK can't be from DFLL if CPU is
>>>>>>>>>>>> reparented to
>>>>>>>>>>>> PLLP
>>>>>>>>>>>> on CPUFreq driver's suspend, otherwise CPU keeps running from a
>>>>>>>>>>>> boot-state PLLX if CPUFreq driver is disabled.
>>>>>>>>>>> Yes suspend should not be an issue but issue will be during
>>>>>>>>>>> resume
>>>>>>>>>>> where if we do cclk_g restore in normal way thru
>>>>>>>>>>> clk_restore_context,
>>>>>>>>>>> cclk_g restore happens very early as dfllCPU out is the first
>>>>>>>>>>> one that
>>>>>>>>>>> goes thru restore context and plls/peripherals are not resumed by
>>>>>>>>>>> then.
>>>>>>>>>>>
>>>>>>>>>>> CPU runs from PLLX if dfll clock enable fails during boot. So
>>>>>>>>>>> when it
>>>>>>>>>>> gets to suspend, we save CPU running clock source as either
>>>>>>>>>>> PLLX or
>>>>>>>>>>> DFLL and then we switch to PLLP.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On resume, CPU runs from PLLP by warm boot code and we need to
>>>>>>>>>>> restore
>>>>>>>>>>> back its source to the one it was using from saved source context
>>>>>>>>>>> (which can be either PLLX or DFLL)
>>>>>>>>>>>
>>>>>>>>>>> So PLLs & DFLL resume need to happen before CCLKG restore/resume.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> With all above discussions, we do DFLL disable in CPUFreq
>>>>>>>>>>> driver on
>>>>>>>>>>> suspend and on CPUFreq resume we enable DFLL back and restore CPU
>>>>>>>>>>> clock source it was using during suspend (which will be either
>>>>>>>>>>> PLLX if
>>>>>>>>>>> dfll enable fails during probe or it will be using DFLL).
>>>>>>>>> During suspend CPU's parent shall be PLLP and not DFLL (note that
>>>>>>>>> it is
>>>>>>>>> disabled) after reparenting to PLLP by the CPUFreq driver.
>>>>>>>>>
>>>>>>>> CPU source context should be saved before switching to safe
>>>>>>>> source of
>>>>>>>> PLLP as on resume we need to restore back to source it was using
>>>>>>>> before we switch to safe source during suspend entry.
>>>>>>>>
>>>>>>>> So saved context for CPU Source will be either dfll or PLLX
>>>>>>>>
>>>>>>> PLLP reparenting is only during suspend/entry to have it as safe
>>>>>>> source
>>>>>>> but actual CPU source it was running from before suspending is either
>>>>>>> dfll/pllx which should be the one to be restored on CPUFreq resume.
>>>>>>> Resume happens with CPU running from PLLP till it gets to the
>>>>>>> point of
>>>>>>> restoring its original source (dfll or pllx)
>>>>>> CaR should restore CPU to PLLP or PLLX, while CPUFreq driver restores
>>>>>> CPU to DFLL. Please see more comments below.
>>>>>>
>>>>>>>>>>> So i was trying to say dfll/cclk_g restore can't be done in
>>>>>>>>>>> normal way
>>>>>>>>>>> thru clk_ops save/restore context
>>>>>>>>> Let's see what happens if CPUFreq is active:
>>>>>>>>>
>>>>>>>>> 1. CPUFreq driver probe happens
>>>>>>>>> 2. CPU is reparented to PLLP
>>>>>>>>> 3. DFLL inited
>>>>>>>>> 4. CPU is reparented to DFLL
>>>>>>>>>
>>>>>>>>> 5. CPUFreq driver suspend happens
>>>>>>>>> 6. CPU is reparented to PLLP
>>>>>>>>> 7. DFLL is disabled
>>>>>>>>>
>>>>>>>>> 8. Car suspend happens
>>>>>>>>> 9. DFLL context saved
>>>>>>>>> 10. PLLP/PLLX context saved
>>>>>>>>> 11. CCLK context saved
>>>>>>>>>
>>>>>>>>> 12. Car resume happens
>>>>>>>>> 13. DFLL context restored
>>>>>>>>> 14. PLLP/PLLX context restored
>>>>>>>>> 15. CCLK context restored
>>>>>>>>>
>>>>>>>>> 16. CPUFreq driver resume happens
>>>>>>>>> 17. DFLL re-inited
>>>>>>>>> 18. CPU is reparented to DFLL
>>>>>>>> Below is the order of sequence it should be based on the order of
>>>>>>>> clk
>>>>>>>> register.
>>>>>>>>
>>>>>>>> My comments inline in this sequence.
>>>>>>>>
>>>>>>>> 1. CPUFreq driver probe happens
>>>>>>>> 2. CPU is reparented to PLLP
>>>>>>>> 3. DFLL inited
>>>>>>>> 4. CPU is reparented to DFLL
>>>>>>>>
>>>>>>>>
>>>>>>>> 5. CPUFreq driver suspend happens
>>>>>>>> 6. Save CPU source which could be either dfll or pllx
>>>>>> Please see my next comment.
>>>>>>
>>>>>>>> 7. CPU is reparented to safe known source PLLP
>>>>>>>> 8. DFLL is disabled
>>>>>>>>
>>>>>>>> 8. Car suspend happens
>>>>>>>> 9. DFLL context saved (With DFLL disabled in CPUFreq suspend,
>>>>>>>> nothing to be saved here as last freq req will always be saved).
>>>>>>>> 10. CCLK context saved (CPU clock source will be saved in
>>>>>>>> CPUFreq
>>>>>>>> driver suspend which could be either dfll or pllx)
>>>>>> That I don't understand. The CPU's clock source state should be
>>>>>> saved at
>>>>>> the moment of the CaR's suspending (i.e. CCLK policy will be set to
>>>>>> PLLP
>>>>>> or PLLX) and then CCLK state should be also restored by the CaR in
>>>>>> step 14.
>>>>> CPU clock to be saved and restored should be the source used before we
>>>>> switch it to safe PLLP for suspend/resume operation.
>>>>>
>>>>> This original source could be either PLLX or DFLL which it was using
>>>>> before we disable DFLL during CPU Freq suspend.
>>>>>
>>>>> If we save CPU clock source at moment of CAR suspending, it will be
>>>>> PLLP as we switch to safe PLLP in CPUFreq driver suspend.
>>>>>
>>>>> Infact, we dont need to restore CPU clock source to PLLP anywhere in
>>>>> resume as it comes up with PLLP source from warm boot code itself.
>>> You must always maintain proper suspend/resume encapsulation, otherwise
>>> it's a total mess. It doesn't matter that CCLK is restored to PLLP even
>>> that CPU is already running off PLLP after warmboot.
>>>
>>>>> But we need to restore CPU source to original source it was using
>>>>> before we switch to safe PLLP source for suspend operation. This
>>>>> original source could be PLLX/DFLL and this should be re-stored in
>>>>> CPUFreq resume as by this time PLLs and peripherals are restored and
>>>>> dfll is re-initialized.
>>>>>
>>>>> So saving actual CPU source before switching to intermediate safe PLLP
>>>>> in CPUFreq driver and then restoring back during CPUFreq resume should
>>>>> be good as CPUFreq resume happens right after all clocks (plls
>>>>> restore, peripherals restore, dfll resume)>>
>>>>>> CPUFreq driver should only switch CPU to PLLP and disable DFLL on
>>>>>> suspend in step 5, that's it. On resume CPUFreq driver will restore
>>>>>> CPU
>>>>>> to DFLL in step 18.
>>>>> Also I don't think we should hard-code to force CPU source to DFLL on
>>>>> CPUFreq resume.
>>>>>
>>>>> Reason is during CPU Probe when it tries to switch to dfll source, for
>>>>> some reason if dfll enable fails it sets CPU to its original source
>>>>> which will be PLLX.
>>> No!
>>>
>>> 1. CPU voltage could be too low for PLLX
>>> 2. PLLX rate can't be changed without manual reparenting CPU to
>>> intermediate clock
>>> 3. CPUFreq can't manually manage CPU voltage
>>>
>>> DFLL-restoring failure is an extreme case. CPU must be kept on a safe
>>> PLLP in that case and disable_cpufreq() must be invoked as well.
>> OK, PLLX option was also in my mind. So If we just consider sources as
>> DFLL or PLLP, then we can save source in CCLK save context and restore
>> in CCLK restore basically it will be PLLP.
>>
>> Later during CPUFreq resume we can just switch to DFLL and if DFLL
>> enable fails we will keep source as PLLP. Yes will invoke
>> disable_cpufreq as well in case of dfll enable failure for some reason.
> Sounds good!
>
>>>>> So CPU source could be either DFLL or PLLX in CPUFreq
>>>>> tegra124_cpu_switch_to_dfll
>>>>>
>>>>>>>> 11. PLLP/PLLX context saved
>>>>>>>> 12. Peripheral Clock saved
>>>>>>>>
>>>>>>>> 12. Car resume happens
>>>>>>>> 13. DFLL context restored : No DFLL context to be restored
>>>>>>>> and we
>>>>>>>> only need to reinitialize DFLL and re-initialize can't be done
>>>>>>>> here as
>>>>>>>> this is the 1st to get restored and PLL/Peripheral clocks are not
>>>>>>>> restored by this time. So we can't use clk_ops restore for DFLL
>>>>>> It looks to me that clk_core_restore_context() should just do
>>>>>> hlist_for_each_entry *_reverse*. Don't you think so?
>>>>> Thought of that but this is in core driver and is used by other
>>>>> non-tegra clock driver and not sure if that impacts for those.
>>> The reverse ordering should be correct, I think it's just a shortcoming
>>> of the CCF that need to be fixed. But will better to make a more
>>> thorough research, asking Stephen and Michael for the clarification.
>>>
>>>>> But with decision of switching CPUFreq with dfll clock enable/disable
>>>>> during CPUFreq suspend/resume, we can re-init dfll during dfll-fcpu
>>>>> driver resume and we don't need CCLK save/restore.
>>>>>
> Actually CPUFreq driver should implement suspend/resume regardless of
> CaR ability to restore DFLL or whatever, simply to properly handle
> possible clock restoring failure on resume as we just found out.
>
>>>> the way of all clocks order is good except cclk_g which has dependency
>>>> on multiple clocks.
>>> CCLK_G has a single parent at a time. What "multiple clocks" you're
>>> talking about? Please explain.
>> dependencies I am referring are dfll_ref, dfll_soc, and DVFS peripheral
>> clocks which need to be restored prior to DFLL reinit.
> Okay, but that shouldn't be a problem if clock dependencies are set up
> properly.
>
>>>> reverse list order during restore might not work as all other clocks are
>>>> in proper order no with any ref clocks for plls getting restored prior
>>>> to their clients
>>> Why? The ref clocks should be registered first and be the roots for PLLs
>>> and the rest. If it's not currently the case, then this need to be
>>> fixed. You need to ensure that each clock is modeled properly. If some
>>> child clock really depends on multiple parents, then the parents need to
>>> in the correct order or CCF need to be taught about such
>>> multi-dependencies.
>>>
>>> If some required feature is missed, then you have to implement it
>>> properly and for all, that's how things are done in upstream. Sometimes
>>> it's quite a lot of extra work that everyone are benefiting from in
>>> the end.
>>>
>>> [snip]
>> Yes, we should register ref/parents before their clients.
>>
>> cclk_g clk is registered last after all pll and peripheral clocks are
>> registers during clock init.
>>
>> dfllCPU_out clk is registered later during dfll-fcpu driver probe and
>> gets added to the clock list.
>>
>> Probably the issue seems to be not linking dfll_ref and dfll_soc
>> dependencies for dfllCPU_out thru clock list.
>>
>> clk-dfll driver during dfll_init_clks gets ref_clk and soc_clk reference
>> thru DT.
> Please try to fix all missing dependencies and orderings.
Peter,
dfllCPU_OUT is the first one to go thru restore when clk_restore_context
traverses thru the list.
dfllCPU_OUT has dependency on DFLL_ref and DFLL_SOC but this dependency
is unknown to clock-tree.
We can add DFLL_REF and DFLL_SOC as parents to dfllCPU_OUT during
register so dfllCPU_OUT save/restore happens after their parents are
restored.
But DFLL needs both of these to be restored before DFLLCPU_Out and as
DFLL_SOC restore always happens after the REF, thinking to add DFLL_SOC
as parent to dfllCPU_OUT so save/restore follows after their dependencies.
Please comment.
^ permalink raw reply
* Re: [PATCH V5 11/18] clk: tegra210: Add support for Tegra210 clocks
From: Dmitry Osipenko @ 2019-07-17 23:44 UTC (permalink / raw)
To: Sowjanya Komatineni, sboyd, Michael Turquette
Cc: Peter De Schrijver, Joseph Lo, thierry.reding, jonathanh, tglx,
jason, marc.zyngier, linus.walleij, stefan, mark.rutland,
pgaikwad, linux-clk, linux-gpio, jckuo, talho, linux-tegra,
linux-kernel, mperttunen, spatra, robh+dt, devicetree
In-Reply-To: <5eedd224-77b0-1fc9-4e5e-d884b41a64ed@nvidia.com>
18.07.2019 2:36, Sowjanya Komatineni пишет:
>
> On 7/17/19 3:48 PM, Dmitry Osipenko wrote:
>> 18.07.2019 0:57, Sowjanya Komatineni пишет:
>>> On 7/17/19 2:51 PM, Sowjanya Komatineni wrote:
>>>> On 7/17/19 2:30 PM, Dmitry Osipenko wrote:
>>>>> 17.07.2019 23:11, Sowjanya Komatineni пишет:
>>>>>> On 7/17/19 1:01 PM, Sowjanya Komatineni wrote:
>>>>>>> On 7/17/19 12:43 PM, Dmitry Osipenko wrote:
>>>>>>>> 17.07.2019 21:54, Sowjanya Komatineni пишет:
>>>>>>>>> On 7/17/19 11:51 AM, Sowjanya Komatineni wrote:
>>>>>>>>>> On 7/17/19 11:32 AM, Dmitry Osipenko wrote:
>>>>>>>>>>> 17.07.2019 20:29, Sowjanya Komatineni пишет:
>>>>>>>>>>>> On 7/17/19 8:17 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>> 17.07.2019 9:36, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>> On 7/16/19 11:33 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>> В Tue, 16 Jul 2019 22:55:52 -0700
>>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On 7/16/19 10:42 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>> В Tue, 16 Jul 2019 22:25:25 -0700
>>>>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>>>>> On 7/16/19 9:11 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>> В Tue, 16 Jul 2019 19:35:49 -0700
>>>>>>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>>>>>>> On 7/16/19 7:18 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>>>> On 7/16/19 3:06 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 3:00 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>> 17.07.2019 0:35, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 2:21 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>> 17.07.2019 0:12, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 1:47 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 22:26, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:43 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:30, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:25 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:19, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 9:50 AM, Sowjanya Komatineni
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 8:00 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 11:06, Peter De Schrijver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2019 at 03:24:26PM
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +0800,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Joseph
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Lo wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OK, Will add to CPUFreq driver...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The other thing that also need
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> attention is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> that T124 CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicitly relies on DFLL driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to be
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> first, which is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> icky.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Should I add check for successful
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> register explicitly in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver probe and defer till
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> registers?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Probably you should use the "device
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> links".
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> See
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1][2] for the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> example.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/gpu/drm/tegra/dc.c#L2383
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [2]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://www.kernel.org/doc/html/latest/driver-api/device_link.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Return EPROBE_DEFER instead of EINVAL if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device_link_add() fails.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use of_find_device_by_node() to get the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device, see [3].
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [3]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/devfreq/tegra20-devfreq.c#n100
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Will go thru and add...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Looks like I initially confused this case
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getting
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> orphaned clock.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'm now seeing that the DFLL driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> registers the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock and then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk_get(dfll) should be returning
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> EPROBE_DEFER
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> until
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL driver is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probed, hence everything should be fine
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as-is and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> there is no real
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for the 'device link'. Sorry for the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> confusion!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, I didn't follow the mail
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> thread. Just
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regarding the DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> part.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> As you know it, the DFLL clock is one
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock sources and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integrated with DVFS control logic
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator. We will not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to other clock sources once we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switched to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL. Because the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU has
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> been regulated by the DFLL HW with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DVFS
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (CVB or OPP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> you see
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> in the driver.). We shouldn't reparent
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> other sources with
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unknew
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> freq/volt pair. That's not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> guaranteed to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> work. We
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allow switching to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> open-loop mode but different sources.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay, then the CPUFreq driver will
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rate before switching to PLLP in order to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper CPU voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP freq is safe to work for any CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> So no
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to PLLP rate before changing
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK_G
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to PLLP during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, please ignore my above comment.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> During
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend, need to change
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK_G source to PLLP when dfll is in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> closed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode first and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll need to be set to open loop.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And I don't exactly understand why we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to PLLP in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> idle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver. Just keep it on CL-DVFS mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> time.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 entry, the dfll suspend function
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moves it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the open-loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode. That's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all. The sc7-entryfirmware will handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the rest
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn off
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU power.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 resume, the warmboot code will
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator and power up the CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cluster. And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> leave
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it on PLL_P.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> After
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resuming to the kernel, we re-init
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> policy (CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> runs on DFLL open-loop mode) and then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moving to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> close-loop mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL is re-inited after switching
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> early clocks-state restoring by CaR
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hence
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> instead of having
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> odd
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hacks in the CaR driver, it is much
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> nicer to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper suspend-resume sequencing of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> drivers. In this case
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver is the driver that enables DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switches
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to that
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source, which means that this driver is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> also
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> be responsible for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> management of the DFLL's state during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend/resume process. If
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver disables DFLL during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> re-enables it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resume, then looks like the CaR driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hacks
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> around
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL are not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> needed.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL part looks good to me. BTW,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> change the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> patch subject to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "Add
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend-resume support" seems more
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> me.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> To clarify this, the sequences for DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> are as
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> follows (assuming
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> required DFLL hw configuration has been
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> done)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch to DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Save current parent and frequency
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2) Enable DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3) Change cclk_g parent to DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For OVR regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Change PWM output pin from
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> tristate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 5) Enable DFLL PWM output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For I2C regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Enable DFLL I2C output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 6) Program DFLL to closed loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch away from DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Change cclk_g parent to PLLP so
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> frequency is ok for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> any
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> vdd_cpu voltage
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I see during switch away from DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (suspend),
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cclk_g
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent is not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> changed to PLLP before changing dfll to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> open
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Will add this ...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The CPUFreq driver switches parent to PLLP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probe, similar
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should be done on suspend.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'm also wondering if it's always safe to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP in the probe.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> If CPU is running on a lower freq than
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP, then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> some
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> other more
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate intermediate parent should be
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> selected.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU parents are PLL_X, PLL_P, and dfll. PLL_X
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> always
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> runs at higher
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rate
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> so switching to PLL_P during CPUFreq probe
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> prior to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll clock enable
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should be safe.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AFAIK, PLLX could run at ~200MHz. There is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> also a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> divided output of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> which CCLKG supports, the PLLP_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Probably, realistically, CPU is always running
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> off a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> fast PLLX during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> boot, but I'm wondering what may happen on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> KEXEC. I
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> guess ideally CPUFreq driver should also
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'shutdown' callback to teardown DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> on a reboot, but likely that there are other
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock-related problems as
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> well that may break KEXEC and thus it is not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> very
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> important at the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moment.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [snip]
>>>>>>>>>>>>>>>>>>>>>>>>>>>> During bootup CPUG sources from PLL_X. By PLL_P
>>>>>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>>>>>> above I meant
>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLL_P_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> As per clock policies, PLL_X is always used
>>>>>>>>>>>>>>>>>>>>>>>>>>>> for high
>>>>>>>>>>>>>>>>>>>>>>>>>>>> freq
>>>>>>>>>>>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 800Mhz
>>>>>>>>>>>>>>>>>>>>>>>>>>>> and for low frequency it will be sourced from
>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP.
>>>>>>>>>>>>>>>>>>>>>>>>>>> Alright, then please don't forget to
>>>>>>>>>>>>>>>>>>>>>>>>>>> pre-initialize
>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate to a
>>>>>>>>>>>>>>>>>>>>>>>>>>> reasonable value using tegra_clk_init_table or
>>>>>>>>>>>>>>>>>>>>>>>>>>> assigned-clocks.
>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate update is not needed as it is
>>>>>>>>>>>>>>>>>>>>>>>>>> safe to
>>>>>>>>>>>>>>>>>>>>>>>>>> run at
>>>>>>>>>>>>>>>>>>>>>>>>>> 408Mhz because it is below fmax @ Vmin
>>>>>>>>>>>>>>>>>>>>>>>>> So even 204MHz CVB entries are having the same
>>>>>>>>>>>>>>>>>>>>>>>>> voltage as
>>>>>>>>>>>>>>>>>>>>>>>>> 408MHz, correct? It's not instantly obvious to me
>>>>>>>>>>>>>>>>>>>>>>>>> from the
>>>>>>>>>>>>>>>>>>>>>>>>> DFLL driver's code where the fmax @ Vmin is
>>>>>>>>>>>>>>>>>>>>>>>>> defined,
>>>>>>>>>>>>>>>>>>>>>>>>> I see
>>>>>>>>>>>>>>>>>>>>>>>>> that there is the min_millivolts
>>>>>>>>>>>>>>>>>>>>>>>>> and frequency entries starting from 204MHZ defined
>>>>>>>>>>>>>>>>>>>>>>>>> per-table.
>>>>>>>>>>>>>>>>>>>>>>>> Yes at Vmin CPU Fmax is ~800Mhz. So anything below
>>>>>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>>>>>>>>>>> work at Vmin voltage and PLLP max is 408Mhz.
>>>>>>>>>>>>>>>>>>>>>>> Thank you for the clarification. It would be good
>>>>>>>>>>>>>>>>>>>>>>> to have
>>>>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>>>>> commented
>>>>>>>>>>>>>>>>>>>>>>> in the code as well.
>>>>>>>>>>>>>>>>>>>>>> OK, Will add...
>>>>>>>>>>>>>>>>>>>>> Regarding, adding suspend/resume to CPUFreq, CPUFreq
>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>> happens very early even before disabling non-boot
>>>>>>>>>>>>>>>>>>>>> CPUs and
>>>>>>>>>>>>>>>>>>>>> also
>>>>>>>>>>>>>>>>>>>>> need to export clock driver APIs to CPUFreq.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Was thinking of below way of implementing this...
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Clock DFLL driver Suspend:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> - Save CPU clock policy registers, and
>>>>>>>>>>>>>>>>>>>>> Perform
>>>>>>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>>>>>>> suspend which sets in open loop mode
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> CPU Freq driver Suspend: does nothing
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Clock DFLL driver Resume:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> - Re-init DFLL, Set in Open-Loop mode,
>>>>>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>> Clock policy registers which actually sets source to
>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>> along
>>>>>>>>>>>>>>>>>>>>> with other CPU Policy register restore.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> CPU Freq driver Resume:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> - do clk_prepare_enable which acutally
>>>>>>>>>>>>>>>>>>>>> sets
>>>>>>>>>>>>>>>>>>>>> DFLL in
>>>>>>>>>>>>>>>>>>>>> Closed loop mode
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Adding one more note: Switching CPU Clock to PLLP
>>>>>>>>>>>>>>>>>>>>> is not
>>>>>>>>>>>>>>>>>>>>> needed
>>>>>>>>>>>>>>>>>>>>> as CPU CLock can be from dfll in open-loop mode as
>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>> is not
>>>>>>>>>>>>>>>>>>>>> disabled anywhere throught the suspend/resume path
>>>>>>>>>>>>>>>>>>>>> and SC7
>>>>>>>>>>>>>>>>>>>>> entry
>>>>>>>>>>>>>>>>>>>>> FW and Warm boot code will switch CPU source to PLLP.
>>>>>>>>>>>>>>>>>>> Since CPU resumes on PLLP, it will be cleaner to suspend
>>>>>>>>>>>>>>>>>>> it on
>>>>>>>>>>>>>>>>>>> PLLP as well. And besides, seems that currently
>>>>>>>>>>>>>>>>>>> disabling
>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>> clock will disable DFLL completely and then you'd
>>>>>>>>>>>>>>>>>>> want to
>>>>>>>>>>>>>>>>>>> re-init
>>>>>>>>>>>>>>>>>>> the DFLL on resume any ways. So better to just disable
>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>> completely on suspend, which should happen on
>>>>>>>>>>>>>>>>>>> clk_disable(dfll).
>>>>>>>>>>>>>>>>>> Will switch to PLLP during CPUFreq suspend. With
>>>>>>>>>>>>>>>>>> decision of
>>>>>>>>>>>>>>>>>> using
>>>>>>>>>>>>>>>>>> clk_disable during suspend, its mandatory to switch to
>>>>>>>>>>>>>>>>>> PLLP as
>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>> is completely disabled.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> My earlier concern was on restoring CPU policy as we
>>>>>>>>>>>>>>>>>> can't do
>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>> from CPUFreq driver and need export from clock driver.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Clear now and will do CPU clock policy restore in after
>>>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>>>> re-init.
>>>>>>>>>>>>>>>>> Why the policy can't be saved/restored by the CaR driver
>>>>>>>>>>>>>>>>> as a
>>>>>>>>>>>>>>>>> context of any other clock?
>>>>>>>>>>>>>>>> restoring cpu clock policy involves programming source and
>>>>>>>>>>>>>>>> super_cclkg_divider.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> cclk_g is registered as clk_super_mux and it doesn't use
>>>>>>>>>>>>>>>> frac_div ops
>>>>>>>>>>>>>>>> to do save/restore its divider.
>>>>>>>>>>>>>>> That can be changed of course and I guess it also could
>>>>>>>>>>>>>>> be as
>>>>>>>>>>>>>>> simple as
>>>>>>>>>>>>>>> saving and restoring of two raw u32 values of the
>>>>>>>>>>>>>>> policy/divider
>>>>>>>>>>>>>>> registers.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Also, during clock context we cant restore cclk_g as cclk_g
>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>> will be dfll and dfll will not be resumed/re-initialized
>>>>>>>>>>>>>>>> by the
>>>>>>>>>>>>>>>> time
>>>>>>>>>>>>>>>> clk_super_mux save/restore happens.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> we can't use save/restore context for dfll clk_ops because
>>>>>>>>>>>>>>>> dfllCPU_out parent to CCLK_G is first in the clock tree and
>>>>>>>>>>>>>>>> dfll_ref
>>>>>>>>>>>>>>>> and dfll_soc peripheral clocks are not restored by the
>>>>>>>>>>>>>>>> time dfll
>>>>>>>>>>>>>>>> restore happens. Also dfll peripheral clock enables need
>>>>>>>>>>>>>>>> to be
>>>>>>>>>>>>>>>> restored before dfll restore happens which involves
>>>>>>>>>>>>>>>> programming
>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>> controller for re-initialization.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> So dfll resume/re-init is done in clk-tegra210 at end of
>>>>>>>>>>>>>>>> all
>>>>>>>>>>>>>>>> clocks
>>>>>>>>>>>>>>>> restore in V5 series but instead of in clk-tegra210
>>>>>>>>>>>>>>>> driver I
>>>>>>>>>>>>>>>> moved
>>>>>>>>>>>>>>>> now to dfll-fcpu driver pm_ops as all dfll dependencies
>>>>>>>>>>>>>>>> will be
>>>>>>>>>>>>>>>> restored thru clk_restore_context by then. This will be in
>>>>>>>>>>>>>>>> V6.
>>>>>>>>>>>>>>> Since DFLL is now guaranteed to be disabled across CaR
>>>>>>>>>>>>>>> suspend/resume
>>>>>>>>>>>>>>> (hence it has nothing to do in regards to CCLK) and given
>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>> PLLs
>>>>>>>>>>>>>>> state is restored before the rest of the clocks, I don't
>>>>>>>>>>>>>>> see why
>>>>>>>>>>>>>>> not to
>>>>>>>>>>>>>>> implement CCLK save/restore in a generic fasion. CPU policy
>>>>>>>>>>>>>>> wull be
>>>>>>>>>>>>>>> restored to either PLLP or PLLX (if CPUFreq driver is
>>>>>>>>>>>>>>> disabled).
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>> CCLK_G save/restore should happen in clk_super_mux ops
>>>>>>>>>>>>>> save/context and
>>>>>>>>>>>>>> clk_super_mux save/restore happens very early as cclk_g is
>>>>>>>>>>>>>> first
>>>>>>>>>>>>>> in the
>>>>>>>>>>>>>> clock tree and save/restore traverses through the tree
>>>>>>>>>>>>>> top-bottom
>>>>>>>>>>>>>> order.
>>>>>>>>>>>>> If CCLK_G is restored before the PLLs, then just change the
>>>>>>>>>>>>> clocks
>>>>>>>>>>>>> order
>>>>>>>>>>>>> such that it won't happen.
>>>>>>>>>>>>>
>>>>>>>>>>>> I dont think we can change clocks order for CCLK_G.
>>>>>>>>>>>>
>>>>>>>>>>>> During bootup, cclk_g is registered after all pll's and
>>>>>>>>>>>> peripheral
>>>>>>>>>>>> clocks which is the way we wanted, So cclk_g will be the first
>>>>>>>>>>>> one in
>>>>>>>>>>>> the clk list as clk_register adds new clock first in the list.
>>>>>>>>>>>>
>>>>>>>>>>>> When clk_save_context and clk_restore_context APIs iterates
>>>>>>>>>>>> over the
>>>>>>>>>>>> list, cclk_g is the first
>>>>>>>>>>> Looking at clk_core_restore_context(), I see that it walks up
>>>>>>>>>>> CLKs
>>>>>>>>>>> list
>>>>>>>>>>> from parent to children, hence I don't understand how it can
>>>>>>>>>>> ever
>>>>>>>>>>> happen
>>>>>>>>>>> that CCLK will be restored before the parent. The clocks
>>>>>>>>>>> registration
>>>>>>>>>>> order doesn't matter at all in that case.
>>>>>>>>>> yes from parent to children and dfllCPU_out is the top in the
>>>>>>>>>> list and
>>>>>>>>>> its child is cclk_g.
>>>>>>>>>>
>>>>>>>>>> the way clocks are registered is the order I see in the clock
>>>>>>>>>> list and
>>>>>>>>>> looking into clk_register API it adds new node first in the list.
>>>>>>>>>>
>>>>>>>>> cclkg_g & dfll register happens after all plls and peripheral
>>>>>>>>> clocks as
>>>>>>>>> it need ref, soc and peripheral clocks to be enabled.
>>>>>>>>>> So they are the last to get registered and so becomes first in
>>>>>>>>>> the
>>>>>>>>>> list.
>>>>>>>>>>
>>>>>>>>>> During save/restore context, it traverses thru this list and
>>>>>>>>>> first in
>>>>>>>>>> the list is dfllcpu_OUT (parent) and its child (cclk_g)
>>>>>>>>>>
>>>>>>>>>> saving should not be an issue at all but we cant restore
>>>>>>>>>> cclk_g/dfll
>>>>>>>>>> in normal way thru clk_ops restore as plls and peripherals
>>>>>>>>>> restore
>>>>>>>>>> doesn't happen by that time.
>>>>>>>>>>
>>>>>>>>> I was referring to clk_restore_context where it iterates thru
>>>>>>>>> root list
>>>>>>>>> and for each core from the root list clk_core_restore does
>>>>>>>>> restore of
>>>>>>>>> parent and children.
>>>>>>>>>
>>>>>>>>> dfllCPU_Out gets first in the list and its child is cclk_g
>>>>>>>>>
>>>>>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/clk/clk.c#L1105
>>>>>>>>>
>>>>>>>>>
>>>>>>>> What list you're talking about? clk_summary? It shows current
>>>>>>>> *active*
>>>>>>>> clocks configuration, if you'll try to disable CPUFreq driver then
>>>>>>>> the
>>>>>>>> parent of CCLK_G should be PLLX. Similarly when CPU is
>>>>>>>> reparented to
>>>>>>>> PLLP on driver's suspend, then PLLP is the parent.
>>>>>>>>
>>>>>>>>>>>>>> DFLL enable thru CPUFreq resume happens after all
>>>>>>>>>>>>>> clk_restore_context
>>>>>>>>>>>>>> happens. So during clk_restore_context, dfll re-init doesnt
>>>>>>>>>>>>>> happen
>>>>>>>>>>>>>> and
>>>>>>>>>>>>>> doing cpu clock policy restore during super_mux clk_ops will
>>>>>>>>>>>>>> crash as
>>>>>>>>>>>>>> DFLL is not initialized and its clock is not enabled but CPU
>>>>>>>>>>>>>> clock
>>>>>>>>>>>>>> restore sets source to DFLL if we restore during
>>>>>>>>>>>>>> super_clk_mux
>>>>>>>>>>>>> If CPU was suspended on PLLP, then it will be restored on
>>>>>>>>>>>>> PLLP by
>>>>>>>>>>>>> CaR. I
>>>>>>>>>>>>> don't understand what DFLL has to do with the CCLK in that
>>>>>>>>>>>>> case
>>>>>>>>>>>>> during
>>>>>>>>>>>>> the clocks restore.
>>>>>>>>>>>> My above comment is in reference to your request of doing
>>>>>>>>>>>> save/restore
>>>>>>>>>>>> for cclk_g in normal fashion thru save/restore context. Because
>>>>>>>>>>>> of the
>>>>>>>>>>>> clk order I mentioned above, we cclk_g will be the first one to
>>>>>>>>>>>> go thru
>>>>>>>>>>>> save/context.
>>>>>>>>>>>>
>>>>>>>>>>>> During save_context of cclk_g, source can be from PLLX, dfll.
>>>>>>>>>>>>
>>>>>>>>>>>> Issue will be when we do restore during clk_restore_context of
>>>>>>>>>>>> cclk_g as
>>>>>>>>>>>> by that time PLLX/dfll will not be restored.
>>>>>>>>>>>>
>>>>>>>>>>> Seems we already agreed that DFLL will be disabled by the
>>>>>>>>>>> CPUFreq
>>>>>>>>>>> driver
>>>>>>>>>>> on suspend. Hence CCLK can't be from DFLL if CPU is
>>>>>>>>>>> reparented to
>>>>>>>>>>> PLLP
>>>>>>>>>>> on CPUFreq driver's suspend, otherwise CPU keeps running from a
>>>>>>>>>>> boot-state PLLX if CPUFreq driver is disabled.
>>>>>>>>>> Yes suspend should not be an issue but issue will be during
>>>>>>>>>> resume
>>>>>>>>>> where if we do cclk_g restore in normal way thru
>>>>>>>>>> clk_restore_context,
>>>>>>>>>> cclk_g restore happens very early as dfllCPU out is the first
>>>>>>>>>> one that
>>>>>>>>>> goes thru restore context and plls/peripherals are not resumed by
>>>>>>>>>> then.
>>>>>>>>>>
>>>>>>>>>> CPU runs from PLLX if dfll clock enable fails during boot. So
>>>>>>>>>> when it
>>>>>>>>>> gets to suspend, we save CPU running clock source as either
>>>>>>>>>> PLLX or
>>>>>>>>>> DFLL and then we switch to PLLP.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On resume, CPU runs from PLLP by warm boot code and we need to
>>>>>>>>>> restore
>>>>>>>>>> back its source to the one it was using from saved source context
>>>>>>>>>> (which can be either PLLX or DFLL)
>>>>>>>>>>
>>>>>>>>>> So PLLs & DFLL resume need to happen before CCLKG restore/resume.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> With all above discussions, we do DFLL disable in CPUFreq
>>>>>>>>>> driver on
>>>>>>>>>> suspend and on CPUFreq resume we enable DFLL back and restore CPU
>>>>>>>>>> clock source it was using during suspend (which will be either
>>>>>>>>>> PLLX if
>>>>>>>>>> dfll enable fails during probe or it will be using DFLL).
>>>>>>>> During suspend CPU's parent shall be PLLP and not DFLL (note that
>>>>>>>> it is
>>>>>>>> disabled) after reparenting to PLLP by the CPUFreq driver.
>>>>>>>>
>>>>>>> CPU source context should be saved before switching to safe
>>>>>>> source of
>>>>>>> PLLP as on resume we need to restore back to source it was using
>>>>>>> before we switch to safe source during suspend entry.
>>>>>>>
>>>>>>> So saved context for CPU Source will be either dfll or PLLX
>>>>>>>
>>>>>> PLLP reparenting is only during suspend/entry to have it as safe
>>>>>> source
>>>>>> but actual CPU source it was running from before suspending is either
>>>>>> dfll/pllx which should be the one to be restored on CPUFreq resume.
>>>>>> Resume happens with CPU running from PLLP till it gets to the
>>>>>> point of
>>>>>> restoring its original source (dfll or pllx)
>>>>> CaR should restore CPU to PLLP or PLLX, while CPUFreq driver restores
>>>>> CPU to DFLL. Please see more comments below.
>>>>>
>>>>>>>>>> So i was trying to say dfll/cclk_g restore can't be done in
>>>>>>>>>> normal way
>>>>>>>>>> thru clk_ops save/restore context
>>>>>>>> Let's see what happens if CPUFreq is active:
>>>>>>>>
>>>>>>>> 1. CPUFreq driver probe happens
>>>>>>>> 2. CPU is reparented to PLLP
>>>>>>>> 3. DFLL inited
>>>>>>>> 4. CPU is reparented to DFLL
>>>>>>>>
>>>>>>>> 5. CPUFreq driver suspend happens
>>>>>>>> 6. CPU is reparented to PLLP
>>>>>>>> 7. DFLL is disabled
>>>>>>>>
>>>>>>>> 8. Car suspend happens
>>>>>>>> 9. DFLL context saved
>>>>>>>> 10. PLLP/PLLX context saved
>>>>>>>> 11. CCLK context saved
>>>>>>>>
>>>>>>>> 12. Car resume happens
>>>>>>>> 13. DFLL context restored
>>>>>>>> 14. PLLP/PLLX context restored
>>>>>>>> 15. CCLK context restored
>>>>>>>>
>>>>>>>> 16. CPUFreq driver resume happens
>>>>>>>> 17. DFLL re-inited
>>>>>>>> 18. CPU is reparented to DFLL
>>>>>>> Below is the order of sequence it should be based on the order of
>>>>>>> clk
>>>>>>> register.
>>>>>>>
>>>>>>> My comments inline in this sequence.
>>>>>>>
>>>>>>> 1. CPUFreq driver probe happens
>>>>>>> 2. CPU is reparented to PLLP
>>>>>>> 3. DFLL inited
>>>>>>> 4. CPU is reparented to DFLL
>>>>>>>
>>>>>>>
>>>>>>> 5. CPUFreq driver suspend happens
>>>>>>> 6. Save CPU source which could be either dfll or pllx
>>>>> Please see my next comment.
>>>>>
>>>>>>> 7. CPU is reparented to safe known source PLLP
>>>>>>> 8. DFLL is disabled
>>>>>>>
>>>>>>> 8. Car suspend happens
>>>>>>> 9. DFLL context saved (With DFLL disabled in CPUFreq suspend,
>>>>>>> nothing to be saved here as last freq req will always be saved).
>>>>>>> 10. CCLK context saved (CPU clock source will be saved in
>>>>>>> CPUFreq
>>>>>>> driver suspend which could be either dfll or pllx)
>>>>> That I don't understand. The CPU's clock source state should be
>>>>> saved at
>>>>> the moment of the CaR's suspending (i.e. CCLK policy will be set to
>>>>> PLLP
>>>>> or PLLX) and then CCLK state should be also restored by the CaR in
>>>>> step 14.
>>>> CPU clock to be saved and restored should be the source used before we
>>>> switch it to safe PLLP for suspend/resume operation.
>>>>
>>>> This original source could be either PLLX or DFLL which it was using
>>>> before we disable DFLL during CPU Freq suspend.
>>>>
>>>> If we save CPU clock source at moment of CAR suspending, it will be
>>>> PLLP as we switch to safe PLLP in CPUFreq driver suspend.
>>>>
>>>> Infact, we dont need to restore CPU clock source to PLLP anywhere in
>>>> resume as it comes up with PLLP source from warm boot code itself.
>> You must always maintain proper suspend/resume encapsulation, otherwise
>> it's a total mess. It doesn't matter that CCLK is restored to PLLP even
>> that CPU is already running off PLLP after warmboot.
>>
>>>> But we need to restore CPU source to original source it was using
>>>> before we switch to safe PLLP source for suspend operation. This
>>>> original source could be PLLX/DFLL and this should be re-stored in
>>>> CPUFreq resume as by this time PLLs and peripherals are restored and
>>>> dfll is re-initialized.
>>>>
>>>> So saving actual CPU source before switching to intermediate safe PLLP
>>>> in CPUFreq driver and then restoring back during CPUFreq resume should
>>>> be good as CPUFreq resume happens right after all clocks (plls
>>>> restore, peripherals restore, dfll resume)>>
>>>>> CPUFreq driver should only switch CPU to PLLP and disable DFLL on
>>>>> suspend in step 5, that's it. On resume CPUFreq driver will restore
>>>>> CPU
>>>>> to DFLL in step 18.
>>>> Also I don't think we should hard-code to force CPU source to DFLL on
>>>> CPUFreq resume.
>>>>
>>>> Reason is during CPU Probe when it tries to switch to dfll source, for
>>>> some reason if dfll enable fails it sets CPU to its original source
>>>> which will be PLLX.
>> No!
>>
>> 1. CPU voltage could be too low for PLLX
>> 2. PLLX rate can't be changed without manual reparenting CPU to
>> intermediate clock
>> 3. CPUFreq can't manually manage CPU voltage
>>
>> DFLL-restoring failure is an extreme case. CPU must be kept on a safe
>> PLLP in that case and disable_cpufreq() must be invoked as well.
>
> OK, PLLX option was also in my mind. So If we just consider sources as
> DFLL or PLLP, then we can save source in CCLK save context and restore
> in CCLK restore basically it will be PLLP.
>
> Later during CPUFreq resume we can just switch to DFLL and if DFLL
> enable fails we will keep source as PLLP. Yes will invoke
> disable_cpufreq as well in case of dfll enable failure for some reason.
Sounds good!
>>>> So CPU source could be either DFLL or PLLX in CPUFreq
>>>> tegra124_cpu_switch_to_dfll
>>>>
>>>>>>> 11. PLLP/PLLX context saved
>>>>>>> 12. Peripheral Clock saved
>>>>>>>
>>>>>>> 12. Car resume happens
>>>>>>> 13. DFLL context restored : No DFLL context to be restored
>>>>>>> and we
>>>>>>> only need to reinitialize DFLL and re-initialize can't be done
>>>>>>> here as
>>>>>>> this is the 1st to get restored and PLL/Peripheral clocks are not
>>>>>>> restored by this time. So we can't use clk_ops restore for DFLL
>>>>> It looks to me that clk_core_restore_context() should just do
>>>>> hlist_for_each_entry *_reverse*. Don't you think so?
>>>> Thought of that but this is in core driver and is used by other
>>>> non-tegra clock driver and not sure if that impacts for those.
>> The reverse ordering should be correct, I think it's just a shortcoming
>> of the CCF that need to be fixed. But will better to make a more
>> thorough research, asking Stephen and Michael for the clarification.
>>
>>>> But with decision of switching CPUFreq with dfll clock enable/disable
>>>> during CPUFreq suspend/resume, we can re-init dfll during dfll-fcpu
>>>> driver resume and we don't need CCLK save/restore.
>>>>
Actually CPUFreq driver should implement suspend/resume regardless of
CaR ability to restore DFLL or whatever, simply to properly handle
possible clock restoring failure on resume as we just found out.
>>> the way of all clocks order is good except cclk_g which has dependency
>>> on multiple clocks.
>> CCLK_G has a single parent at a time. What "multiple clocks" you're
>> talking about? Please explain.
>
> dependencies I am referring are dfll_ref, dfll_soc, and DVFS peripheral
> clocks which need to be restored prior to DFLL reinit.
Okay, but that shouldn't be a problem if clock dependencies are set up
properly.
>>> reverse list order during restore might not work as all other clocks are
>>> in proper order no with any ref clocks for plls getting restored prior
>>> to their clients
>> Why? The ref clocks should be registered first and be the roots for PLLs
>> and the rest. If it's not currently the case, then this need to be
>> fixed. You need to ensure that each clock is modeled properly. If some
>> child clock really depends on multiple parents, then the parents need to
>> in the correct order or CCF need to be taught about such
>> multi-dependencies.
>>
>> If some required feature is missed, then you have to implement it
>> properly and for all, that's how things are done in upstream. Sometimes
>> it's quite a lot of extra work that everyone are benefiting from in
>> the end.
>>
>> [snip]
>
> Yes, we should register ref/parents before their clients.
>
> cclk_g clk is registered last after all pll and peripheral clocks are
> registers during clock init.
>
> dfllCPU_out clk is registered later during dfll-fcpu driver probe and
> gets added to the clock list.
>
> Probably the issue seems to be not linking dfll_ref and dfll_soc
> dependencies for dfllCPU_out thru clock list.
>
> clk-dfll driver during dfll_init_clks gets ref_clk and soc_clk reference
> thru DT.
Please try to fix all missing dependencies and orderings.
^ permalink raw reply
* Re: [PATCH V5 11/18] clk: tegra210: Add support for Tegra210 clocks
From: Sowjanya Komatineni @ 2019-07-17 23:36 UTC (permalink / raw)
To: Dmitry Osipenko, sboyd, Michael Turquette
Cc: Peter De Schrijver, Joseph Lo, thierry.reding, jonathanh, tglx,
jason, marc.zyngier, linus.walleij, stefan, mark.rutland,
pgaikwad, linux-clk, linux-gpio, jckuo, talho, linux-tegra,
linux-kernel, mperttunen, spatra, robh+dt, devicetree
In-Reply-To: <bff3e9c0-727d-9aef-a0e2-583e53c39afd@gmail.com>
On 7/17/19 3:48 PM, Dmitry Osipenko wrote:
> 18.07.2019 0:57, Sowjanya Komatineni пишет:
>> On 7/17/19 2:51 PM, Sowjanya Komatineni wrote:
>>> On 7/17/19 2:30 PM, Dmitry Osipenko wrote:
>>>> 17.07.2019 23:11, Sowjanya Komatineni пишет:
>>>>> On 7/17/19 1:01 PM, Sowjanya Komatineni wrote:
>>>>>> On 7/17/19 12:43 PM, Dmitry Osipenko wrote:
>>>>>>> 17.07.2019 21:54, Sowjanya Komatineni пишет:
>>>>>>>> On 7/17/19 11:51 AM, Sowjanya Komatineni wrote:
>>>>>>>>> On 7/17/19 11:32 AM, Dmitry Osipenko wrote:
>>>>>>>>>> 17.07.2019 20:29, Sowjanya Komatineni пишет:
>>>>>>>>>>> On 7/17/19 8:17 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>> 17.07.2019 9:36, Sowjanya Komatineni пишет:
>>>>>>>>>>>>> On 7/16/19 11:33 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>> В Tue, 16 Jul 2019 22:55:52 -0700
>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On 7/16/19 10:42 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>> В Tue, 16 Jul 2019 22:25:25 -0700
>>>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>>>> On 7/16/19 9:11 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>> В Tue, 16 Jul 2019 19:35:49 -0700
>>>>>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>>>>>> On 7/16/19 7:18 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>>> On 7/16/19 3:06 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>>>> On 7/16/19 3:00 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>> 17.07.2019 0:35, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 2:21 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>> 17.07.2019 0:12, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 1:47 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 22:26, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:43 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:30, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:25 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:19, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 9:50 AM, Sowjanya Komatineni
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 8:00 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 11:06, Peter De Schrijver пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2019 at 03:24:26PM +0800,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Joseph
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Lo wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OK, Will add to CPUFreq driver...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The other thing that also need
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> attention is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> that T124 CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicitly relies on DFLL driver to be
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> first, which is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> icky.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Should I add check for successful
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> register explicitly in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver probe and defer till dfll
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> registers?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Probably you should use the "device links".
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> See
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1][2] for the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> example.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/gpu/drm/tegra/dc.c#L2383
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [2]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://www.kernel.org/doc/html/latest/driver-api/device_link.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Return EPROBE_DEFER instead of EINVAL if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device_link_add() fails.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use of_find_device_by_node() to get the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device, see [3].
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [3]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/devfreq/tegra20-devfreq.c#n100
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Will go thru and add...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Looks like I initially confused this case with
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getting
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> orphaned clock.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'm now seeing that the DFLL driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> registers the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock and then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk_get(dfll) should be returning EPROBE_DEFER
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> until
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL driver is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probed, hence everything should be fine
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as-is and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> there is no real
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for the 'device link'. Sorry for the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> confusion!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, I didn't follow the mail
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> thread. Just
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regarding the DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> part.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> As you know it, the DFLL clock is one
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock sources and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integrated with DVFS control logic
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator. We will not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to other clock sources once we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switched to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL. Because the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU has
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> been regulated by the DFLL HW with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DVFS
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (CVB or OPP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> you see
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> in the driver.). We shouldn't reparent
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> other sources with
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unknew
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> freq/volt pair. That's not guaranteed to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> work. We
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allow switching to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> open-loop mode but different sources.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay, then the CPUFreq driver will have to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rate before switching to PLLP in order to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper CPU voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP freq is safe to work for any CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> So no
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to PLLP rate before changing
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK_G
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to PLLP during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, please ignore my above comment. During
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend, need to change
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK_G source to PLLP when dfll is in closed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode first and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll need to be set to open loop.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And I don't exactly understand why we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to PLLP in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> idle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver. Just keep it on CL-DVFS mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> time.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 entry, the dfll suspend function
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moves it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the open-loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode. That's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all. The sc7-entryfirmware will handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the rest
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn off
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU power.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 resume, the warmboot code will
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator and power up the CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cluster. And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> leave
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it on PLL_P.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> After
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resuming to the kernel, we re-init DFLL,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> policy (CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> runs on DFLL open-loop mode) and then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moving to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> close-loop mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL is re-inited after switching
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> early clocks-state restoring by CaR driver.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hence
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> instead of having
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> odd
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hacks in the CaR driver, it is much
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> nicer to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper suspend-resume sequencing of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> drivers. In this case
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver is the driver that enables DFLL and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switches
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to that
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source, which means that this driver is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> also
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> be responsible for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> management of the DFLL's state during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend/resume process. If
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver disables DFLL during suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> re-enables it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resume, then looks like the CaR driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hacks
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> around
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL are not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> needed.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL part looks good to me. BTW,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> change the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> patch subject to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "Add
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend-resume support" seems more
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> me.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> To clarify this, the sequences for DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> are as
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> follows (assuming
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> required DFLL hw configuration has been
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> done)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch to DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Save current parent and frequency
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2) Enable DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3) Change cclk_g parent to DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For OVR regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Change PWM output pin from tristate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 5) Enable DFLL PWM output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For I2C regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Enable DFLL I2C output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 6) Program DFLL to closed loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch away from DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Change cclk_g parent to PLLP so the CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> frequency is ok for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> any
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> vdd_cpu voltage
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I see during switch away from DFLL (suspend),
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cclk_g
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent is not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> changed to PLLP before changing dfll to open
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Will add this ...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The CPUFreq driver switches parent to PLLP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probe, similar
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should be done on suspend.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'm also wondering if it's always safe to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP in the probe.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> If CPU is running on a lower freq than
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP, then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> some
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> other more
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate intermediate parent should be
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> selected.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU parents are PLL_X, PLL_P, and dfll. PLL_X
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> always
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> runs at higher
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rate
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> so switching to PLL_P during CPUFreq probe
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> prior to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll clock enable
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should be safe.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> AFAIK, PLLX could run at ~200MHz. There is
>>>>>>>>>>>>>>>>>>>>>>>>>>>> also a
>>>>>>>>>>>>>>>>>>>>>>>>>>>> divided output of
>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP
>>>>>>>>>>>>>>>>>>>>>>>>>>>> which CCLKG supports, the PLLP_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Probably, realistically, CPU is always running
>>>>>>>>>>>>>>>>>>>>>>>>>>>> off a
>>>>>>>>>>>>>>>>>>>>>>>>>>>> fast PLLX during
>>>>>>>>>>>>>>>>>>>>>>>>>>>> boot, but I'm wondering what may happen on
>>>>>>>>>>>>>>>>>>>>>>>>>>>> KEXEC. I
>>>>>>>>>>>>>>>>>>>>>>>>>>>> guess ideally CPUFreq driver should also have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'shutdown' callback to teardown DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>> on a reboot, but likely that there are other
>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock-related problems as
>>>>>>>>>>>>>>>>>>>>>>>>>>>> well that may break KEXEC and thus it is not
>>>>>>>>>>>>>>>>>>>>>>>>>>>> very
>>>>>>>>>>>>>>>>>>>>>>>>>>>> important at the
>>>>>>>>>>>>>>>>>>>>>>>>>>>> moment.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> [snip]
>>>>>>>>>>>>>>>>>>>>>>>>>>> During bootup CPUG sources from PLL_X. By PLL_P
>>>>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>>>>> above I meant
>>>>>>>>>>>>>>>>>>>>>>>>>>> PLL_P_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> As per clock policies, PLL_X is always used
>>>>>>>>>>>>>>>>>>>>>>>>>>> for high
>>>>>>>>>>>>>>>>>>>>>>>>>>> freq
>>>>>>>>>>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 800Mhz
>>>>>>>>>>>>>>>>>>>>>>>>>>> and for low frequency it will be sourced from
>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP.
>>>>>>>>>>>>>>>>>>>>>>>>>> Alright, then please don't forget to
>>>>>>>>>>>>>>>>>>>>>>>>>> pre-initialize
>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate to a
>>>>>>>>>>>>>>>>>>>>>>>>>> reasonable value using tegra_clk_init_table or
>>>>>>>>>>>>>>>>>>>>>>>>>> assigned-clocks.
>>>>>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate update is not needed as it is
>>>>>>>>>>>>>>>>>>>>>>>>> safe to
>>>>>>>>>>>>>>>>>>>>>>>>> run at
>>>>>>>>>>>>>>>>>>>>>>>>> 408Mhz because it is below fmax @ Vmin
>>>>>>>>>>>>>>>>>>>>>>>> So even 204MHz CVB entries are having the same
>>>>>>>>>>>>>>>>>>>>>>>> voltage as
>>>>>>>>>>>>>>>>>>>>>>>> 408MHz, correct? It's not instantly obvious to me
>>>>>>>>>>>>>>>>>>>>>>>> from the
>>>>>>>>>>>>>>>>>>>>>>>> DFLL driver's code where the fmax @ Vmin is defined,
>>>>>>>>>>>>>>>>>>>>>>>> I see
>>>>>>>>>>>>>>>>>>>>>>>> that there is the min_millivolts
>>>>>>>>>>>>>>>>>>>>>>>> and frequency entries starting from 204MHZ defined
>>>>>>>>>>>>>>>>>>>>>>>> per-table.
>>>>>>>>>>>>>>>>>>>>>>> Yes at Vmin CPU Fmax is ~800Mhz. So anything below
>>>>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>>>>>>>>>> work at Vmin voltage and PLLP max is 408Mhz.
>>>>>>>>>>>>>>>>>>>>>> Thank you for the clarification. It would be good
>>>>>>>>>>>>>>>>>>>>>> to have
>>>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>>>> commented
>>>>>>>>>>>>>>>>>>>>>> in the code as well.
>>>>>>>>>>>>>>>>>>>>> OK, Will add...
>>>>>>>>>>>>>>>>>>>> Regarding, adding suspend/resume to CPUFreq, CPUFreq
>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>> happens very early even before disabling non-boot
>>>>>>>>>>>>>>>>>>>> CPUs and
>>>>>>>>>>>>>>>>>>>> also
>>>>>>>>>>>>>>>>>>>> need to export clock driver APIs to CPUFreq.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Was thinking of below way of implementing this...
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Clock DFLL driver Suspend:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> - Save CPU clock policy registers, and
>>>>>>>>>>>>>>>>>>>> Perform
>>>>>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>>>>>> suspend which sets in open loop mode
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> CPU Freq driver Suspend: does nothing
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Clock DFLL driver Resume:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> - Re-init DFLL, Set in Open-Loop mode,
>>>>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>> Clock policy registers which actually sets source to
>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>> along
>>>>>>>>>>>>>>>>>>>> with other CPU Policy register restore.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> CPU Freq driver Resume:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> - do clk_prepare_enable which acutally
>>>>>>>>>>>>>>>>>>>> sets
>>>>>>>>>>>>>>>>>>>> DFLL in
>>>>>>>>>>>>>>>>>>>> Closed loop mode
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Adding one more note: Switching CPU Clock to PLLP is not
>>>>>>>>>>>>>>>>>>>> needed
>>>>>>>>>>>>>>>>>>>> as CPU CLock can be from dfll in open-loop mode as DFLL
>>>>>>>>>>>>>>>>>>>> is not
>>>>>>>>>>>>>>>>>>>> disabled anywhere throught the suspend/resume path
>>>>>>>>>>>>>>>>>>>> and SC7
>>>>>>>>>>>>>>>>>>>> entry
>>>>>>>>>>>>>>>>>>>> FW and Warm boot code will switch CPU source to PLLP.
>>>>>>>>>>>>>>>>>> Since CPU resumes on PLLP, it will be cleaner to suspend
>>>>>>>>>>>>>>>>>> it on
>>>>>>>>>>>>>>>>>> PLLP as well. And besides, seems that currently disabling
>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>> clock will disable DFLL completely and then you'd want to
>>>>>>>>>>>>>>>>>> re-init
>>>>>>>>>>>>>>>>>> the DFLL on resume any ways. So better to just disable
>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>> completely on suspend, which should happen on
>>>>>>>>>>>>>>>>>> clk_disable(dfll).
>>>>>>>>>>>>>>>>> Will switch to PLLP during CPUFreq suspend. With
>>>>>>>>>>>>>>>>> decision of
>>>>>>>>>>>>>>>>> using
>>>>>>>>>>>>>>>>> clk_disable during suspend, its mandatory to switch to
>>>>>>>>>>>>>>>>> PLLP as
>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>> is completely disabled.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> My earlier concern was on restoring CPU policy as we
>>>>>>>>>>>>>>>>> can't do
>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>> from CPUFreq driver and need export from clock driver.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Clear now and will do CPU clock policy restore in after
>>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>>> re-init.
>>>>>>>>>>>>>>>> Why the policy can't be saved/restored by the CaR driver
>>>>>>>>>>>>>>>> as a
>>>>>>>>>>>>>>>> context of any other clock?
>>>>>>>>>>>>>>> restoring cpu clock policy involves programming source and
>>>>>>>>>>>>>>> super_cclkg_divider.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> cclk_g is registered as clk_super_mux and it doesn't use
>>>>>>>>>>>>>>> frac_div ops
>>>>>>>>>>>>>>> to do save/restore its divider.
>>>>>>>>>>>>>> That can be changed of course and I guess it also could be as
>>>>>>>>>>>>>> simple as
>>>>>>>>>>>>>> saving and restoring of two raw u32 values of the
>>>>>>>>>>>>>> policy/divider
>>>>>>>>>>>>>> registers.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Also, during clock context we cant restore cclk_g as cclk_g
>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>> will be dfll and dfll will not be resumed/re-initialized
>>>>>>>>>>>>>>> by the
>>>>>>>>>>>>>>> time
>>>>>>>>>>>>>>> clk_super_mux save/restore happens.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> we can't use save/restore context for dfll clk_ops because
>>>>>>>>>>>>>>> dfllCPU_out parent to CCLK_G is first in the clock tree and
>>>>>>>>>>>>>>> dfll_ref
>>>>>>>>>>>>>>> and dfll_soc peripheral clocks are not restored by the
>>>>>>>>>>>>>>> time dfll
>>>>>>>>>>>>>>> restore happens. Also dfll peripheral clock enables need
>>>>>>>>>>>>>>> to be
>>>>>>>>>>>>>>> restored before dfll restore happens which involves
>>>>>>>>>>>>>>> programming
>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>> controller for re-initialization.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> So dfll resume/re-init is done in clk-tegra210 at end of all
>>>>>>>>>>>>>>> clocks
>>>>>>>>>>>>>>> restore in V5 series but instead of in clk-tegra210 driver I
>>>>>>>>>>>>>>> moved
>>>>>>>>>>>>>>> now to dfll-fcpu driver pm_ops as all dfll dependencies
>>>>>>>>>>>>>>> will be
>>>>>>>>>>>>>>> restored thru clk_restore_context by then. This will be in
>>>>>>>>>>>>>>> V6.
>>>>>>>>>>>>>> Since DFLL is now guaranteed to be disabled across CaR
>>>>>>>>>>>>>> suspend/resume
>>>>>>>>>>>>>> (hence it has nothing to do in regards to CCLK) and given that
>>>>>>>>>>>>>> PLLs
>>>>>>>>>>>>>> state is restored before the rest of the clocks, I don't
>>>>>>>>>>>>>> see why
>>>>>>>>>>>>>> not to
>>>>>>>>>>>>>> implement CCLK save/restore in a generic fasion. CPU policy
>>>>>>>>>>>>>> wull be
>>>>>>>>>>>>>> restored to either PLLP or PLLX (if CPUFreq driver is
>>>>>>>>>>>>>> disabled).
>>>>>>>>>>>>>>
>>>>>>>>>>>>> CCLK_G save/restore should happen in clk_super_mux ops
>>>>>>>>>>>>> save/context and
>>>>>>>>>>>>> clk_super_mux save/restore happens very early as cclk_g is
>>>>>>>>>>>>> first
>>>>>>>>>>>>> in the
>>>>>>>>>>>>> clock tree and save/restore traverses through the tree
>>>>>>>>>>>>> top-bottom
>>>>>>>>>>>>> order.
>>>>>>>>>>>> If CCLK_G is restored before the PLLs, then just change the
>>>>>>>>>>>> clocks
>>>>>>>>>>>> order
>>>>>>>>>>>> such that it won't happen.
>>>>>>>>>>>>
>>>>>>>>>>> I dont think we can change clocks order for CCLK_G.
>>>>>>>>>>>
>>>>>>>>>>> During bootup, cclk_g is registered after all pll's and
>>>>>>>>>>> peripheral
>>>>>>>>>>> clocks which is the way we wanted, So cclk_g will be the first
>>>>>>>>>>> one in
>>>>>>>>>>> the clk list as clk_register adds new clock first in the list.
>>>>>>>>>>>
>>>>>>>>>>> When clk_save_context and clk_restore_context APIs iterates
>>>>>>>>>>> over the
>>>>>>>>>>> list, cclk_g is the first
>>>>>>>>>> Looking at clk_core_restore_context(), I see that it walks up CLKs
>>>>>>>>>> list
>>>>>>>>>> from parent to children, hence I don't understand how it can ever
>>>>>>>>>> happen
>>>>>>>>>> that CCLK will be restored before the parent. The clocks
>>>>>>>>>> registration
>>>>>>>>>> order doesn't matter at all in that case.
>>>>>>>>> yes from parent to children and dfllCPU_out is the top in the
>>>>>>>>> list and
>>>>>>>>> its child is cclk_g.
>>>>>>>>>
>>>>>>>>> the way clocks are registered is the order I see in the clock
>>>>>>>>> list and
>>>>>>>>> looking into clk_register API it adds new node first in the list.
>>>>>>>>>
>>>>>>>> cclkg_g & dfll register happens after all plls and peripheral
>>>>>>>> clocks as
>>>>>>>> it need ref, soc and peripheral clocks to be enabled.
>>>>>>>>> So they are the last to get registered and so becomes first in the
>>>>>>>>> list.
>>>>>>>>>
>>>>>>>>> During save/restore context, it traverses thru this list and
>>>>>>>>> first in
>>>>>>>>> the list is dfllcpu_OUT (parent) and its child (cclk_g)
>>>>>>>>>
>>>>>>>>> saving should not be an issue at all but we cant restore
>>>>>>>>> cclk_g/dfll
>>>>>>>>> in normal way thru clk_ops restore as plls and peripherals restore
>>>>>>>>> doesn't happen by that time.
>>>>>>>>>
>>>>>>>> I was referring to clk_restore_context where it iterates thru
>>>>>>>> root list
>>>>>>>> and for each core from the root list clk_core_restore does
>>>>>>>> restore of
>>>>>>>> parent and children.
>>>>>>>>
>>>>>>>> dfllCPU_Out gets first in the list and its child is cclk_g
>>>>>>>>
>>>>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/clk/clk.c#L1105
>>>>>>>>
>>>>>>> What list you're talking about? clk_summary? It shows current
>>>>>>> *active*
>>>>>>> clocks configuration, if you'll try to disable CPUFreq driver then
>>>>>>> the
>>>>>>> parent of CCLK_G should be PLLX. Similarly when CPU is reparented to
>>>>>>> PLLP on driver's suspend, then PLLP is the parent.
>>>>>>>
>>>>>>>>>>>>> DFLL enable thru CPUFreq resume happens after all
>>>>>>>>>>>>> clk_restore_context
>>>>>>>>>>>>> happens. So during clk_restore_context, dfll re-init doesnt
>>>>>>>>>>>>> happen
>>>>>>>>>>>>> and
>>>>>>>>>>>>> doing cpu clock policy restore during super_mux clk_ops will
>>>>>>>>>>>>> crash as
>>>>>>>>>>>>> DFLL is not initialized and its clock is not enabled but CPU
>>>>>>>>>>>>> clock
>>>>>>>>>>>>> restore sets source to DFLL if we restore during super_clk_mux
>>>>>>>>>>>> If CPU was suspended on PLLP, then it will be restored on
>>>>>>>>>>>> PLLP by
>>>>>>>>>>>> CaR. I
>>>>>>>>>>>> don't understand what DFLL has to do with the CCLK in that case
>>>>>>>>>>>> during
>>>>>>>>>>>> the clocks restore.
>>>>>>>>>>> My above comment is in reference to your request of doing
>>>>>>>>>>> save/restore
>>>>>>>>>>> for cclk_g in normal fashion thru save/restore context. Because
>>>>>>>>>>> of the
>>>>>>>>>>> clk order I mentioned above, we cclk_g will be the first one to
>>>>>>>>>>> go thru
>>>>>>>>>>> save/context.
>>>>>>>>>>>
>>>>>>>>>>> During save_context of cclk_g, source can be from PLLX, dfll.
>>>>>>>>>>>
>>>>>>>>>>> Issue will be when we do restore during clk_restore_context of
>>>>>>>>>>> cclk_g as
>>>>>>>>>>> by that time PLLX/dfll will not be restored.
>>>>>>>>>>>
>>>>>>>>>> Seems we already agreed that DFLL will be disabled by the CPUFreq
>>>>>>>>>> driver
>>>>>>>>>> on suspend. Hence CCLK can't be from DFLL if CPU is reparented to
>>>>>>>>>> PLLP
>>>>>>>>>> on CPUFreq driver's suspend, otherwise CPU keeps running from a
>>>>>>>>>> boot-state PLLX if CPUFreq driver is disabled.
>>>>>>>>> Yes suspend should not be an issue but issue will be during resume
>>>>>>>>> where if we do cclk_g restore in normal way thru
>>>>>>>>> clk_restore_context,
>>>>>>>>> cclk_g restore happens very early as dfllCPU out is the first
>>>>>>>>> one that
>>>>>>>>> goes thru restore context and plls/peripherals are not resumed by
>>>>>>>>> then.
>>>>>>>>>
>>>>>>>>> CPU runs from PLLX if dfll clock enable fails during boot. So
>>>>>>>>> when it
>>>>>>>>> gets to suspend, we save CPU running clock source as either PLLX or
>>>>>>>>> DFLL and then we switch to PLLP.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On resume, CPU runs from PLLP by warm boot code and we need to
>>>>>>>>> restore
>>>>>>>>> back its source to the one it was using from saved source context
>>>>>>>>> (which can be either PLLX or DFLL)
>>>>>>>>>
>>>>>>>>> So PLLs & DFLL resume need to happen before CCLKG restore/resume.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> With all above discussions, we do DFLL disable in CPUFreq driver on
>>>>>>>>> suspend and on CPUFreq resume we enable DFLL back and restore CPU
>>>>>>>>> clock source it was using during suspend (which will be either
>>>>>>>>> PLLX if
>>>>>>>>> dfll enable fails during probe or it will be using DFLL).
>>>>>>> During suspend CPU's parent shall be PLLP and not DFLL (note that
>>>>>>> it is
>>>>>>> disabled) after reparenting to PLLP by the CPUFreq driver.
>>>>>>>
>>>>>> CPU source context should be saved before switching to safe source of
>>>>>> PLLP as on resume we need to restore back to source it was using
>>>>>> before we switch to safe source during suspend entry.
>>>>>>
>>>>>> So saved context for CPU Source will be either dfll or PLLX
>>>>>>
>>>>> PLLP reparenting is only during suspend/entry to have it as safe source
>>>>> but actual CPU source it was running from before suspending is either
>>>>> dfll/pllx which should be the one to be restored on CPUFreq resume.
>>>>> Resume happens with CPU running from PLLP till it gets to the point of
>>>>> restoring its original source (dfll or pllx)
>>>> CaR should restore CPU to PLLP or PLLX, while CPUFreq driver restores
>>>> CPU to DFLL. Please see more comments below.
>>>>
>>>>>>>>> So i was trying to say dfll/cclk_g restore can't be done in
>>>>>>>>> normal way
>>>>>>>>> thru clk_ops save/restore context
>>>>>>> Let's see what happens if CPUFreq is active:
>>>>>>>
>>>>>>> 1. CPUFreq driver probe happens
>>>>>>> 2. CPU is reparented to PLLP
>>>>>>> 3. DFLL inited
>>>>>>> 4. CPU is reparented to DFLL
>>>>>>>
>>>>>>> 5. CPUFreq driver suspend happens
>>>>>>> 6. CPU is reparented to PLLP
>>>>>>> 7. DFLL is disabled
>>>>>>>
>>>>>>> 8. Car suspend happens
>>>>>>> 9. DFLL context saved
>>>>>>> 10. PLLP/PLLX context saved
>>>>>>> 11. CCLK context saved
>>>>>>>
>>>>>>> 12. Car resume happens
>>>>>>> 13. DFLL context restored
>>>>>>> 14. PLLP/PLLX context restored
>>>>>>> 15. CCLK context restored
>>>>>>>
>>>>>>> 16. CPUFreq driver resume happens
>>>>>>> 17. DFLL re-inited
>>>>>>> 18. CPU is reparented to DFLL
>>>>>> Below is the order of sequence it should be based on the order of clk
>>>>>> register.
>>>>>>
>>>>>> My comments inline in this sequence.
>>>>>>
>>>>>> 1. CPUFreq driver probe happens
>>>>>> 2. CPU is reparented to PLLP
>>>>>> 3. DFLL inited
>>>>>> 4. CPU is reparented to DFLL
>>>>>>
>>>>>>
>>>>>> 5. CPUFreq driver suspend happens
>>>>>> 6. Save CPU source which could be either dfll or pllx
>>>> Please see my next comment.
>>>>
>>>>>> 7. CPU is reparented to safe known source PLLP
>>>>>> 8. DFLL is disabled
>>>>>>
>>>>>> 8. Car suspend happens
>>>>>> 9. DFLL context saved (With DFLL disabled in CPUFreq suspend,
>>>>>> nothing to be saved here as last freq req will always be saved).
>>>>>> 10. CCLK context saved (CPU clock source will be saved in CPUFreq
>>>>>> driver suspend which could be either dfll or pllx)
>>>> That I don't understand. The CPU's clock source state should be saved at
>>>> the moment of the CaR's suspending (i.e. CCLK policy will be set to PLLP
>>>> or PLLX) and then CCLK state should be also restored by the CaR in
>>>> step 14.
>>> CPU clock to be saved and restored should be the source used before we
>>> switch it to safe PLLP for suspend/resume operation.
>>>
>>> This original source could be either PLLX or DFLL which it was using
>>> before we disable DFLL during CPU Freq suspend.
>>>
>>> If we save CPU clock source at moment of CAR suspending, it will be
>>> PLLP as we switch to safe PLLP in CPUFreq driver suspend.
>>>
>>> Infact, we dont need to restore CPU clock source to PLLP anywhere in
>>> resume as it comes up with PLLP source from warm boot code itself.
> You must always maintain proper suspend/resume encapsulation, otherwise
> it's a total mess. It doesn't matter that CCLK is restored to PLLP even
> that CPU is already running off PLLP after warmboot.
>
>>> But we need to restore CPU source to original source it was using
>>> before we switch to safe PLLP source for suspend operation. This
>>> original source could be PLLX/DFLL and this should be re-stored in
>>> CPUFreq resume as by this time PLLs and peripherals are restored and
>>> dfll is re-initialized.
>>>
>>> So saving actual CPU source before switching to intermediate safe PLLP
>>> in CPUFreq driver and then restoring back during CPUFreq resume should
>>> be good as CPUFreq resume happens right after all clocks (plls
>>> restore, peripherals restore, dfll resume)>>
>>>> CPUFreq driver should only switch CPU to PLLP and disable DFLL on
>>>> suspend in step 5, that's it. On resume CPUFreq driver will restore CPU
>>>> to DFLL in step 18.
>>> Also I don't think we should hard-code to force CPU source to DFLL on
>>> CPUFreq resume.
>>>
>>> Reason is during CPU Probe when it tries to switch to dfll source, for
>>> some reason if dfll enable fails it sets CPU to its original source
>>> which will be PLLX.
> No!
>
> 1. CPU voltage could be too low for PLLX
> 2. PLLX rate can't be changed without manual reparenting CPU to
> intermediate clock
> 3. CPUFreq can't manually manage CPU voltage
>
> DFLL-restoring failure is an extreme case. CPU must be kept on a safe
> PLLP in that case and disable_cpufreq() must be invoked as well.
OK, PLLX option was also in my mind. So If we just consider sources as
DFLL or PLLP, then we can save source in CCLK save context and restore
in CCLK restore basically it will be PLLP.
Later during CPUFreq resume we can just switch to DFLL and if DFLL
enable fails we will keep source as PLLP. Yes will invoke
disable_cpufreq as well in case of dfll enable failure for some reason.
>>> So CPU source could be either DFLL or PLLX in CPUFreq
>>> tegra124_cpu_switch_to_dfll
>>>
>>>>>> 11. PLLP/PLLX context saved
>>>>>> 12. Peripheral Clock saved
>>>>>>
>>>>>> 12. Car resume happens
>>>>>> 13. DFLL context restored : No DFLL context to be restored and we
>>>>>> only need to reinitialize DFLL and re-initialize can't be done here as
>>>>>> this is the 1st to get restored and PLL/Peripheral clocks are not
>>>>>> restored by this time. So we can't use clk_ops restore for DFLL
>>>> It looks to me that clk_core_restore_context() should just do
>>>> hlist_for_each_entry *_reverse*. Don't you think so?
>>> Thought of that but this is in core driver and is used by other
>>> non-tegra clock driver and not sure if that impacts for those.
> The reverse ordering should be correct, I think it's just a shortcoming
> of the CCF that need to be fixed. But will better to make a more
> thorough research, asking Stephen and Michael for the clarification.
>
>>> But with decision of switching CPUFreq with dfll clock enable/disable
>>> during CPUFreq suspend/resume, we can re-init dfll during dfll-fcpu
>>> driver resume and we don't need CCLK save/restore.
>>>
>> the way of all clocks order is good except cclk_g which has dependency
>> on multiple clocks.
> CCLK_G has a single parent at a time. What "multiple clocks" you're
> talking about? Please explain.
dependencies I am referring are dfll_ref, dfll_soc, and DVFS peripheral
clocks which need to be restored prior to DFLL reinit.
>> reverse list order during restore might not work as all other clocks are
>> in proper order no with any ref clocks for plls getting restored prior
>> to their clients
> Why? The ref clocks should be registered first and be the roots for PLLs
> and the rest. If it's not currently the case, then this need to be
> fixed. You need to ensure that each clock is modeled properly. If some
> child clock really depends on multiple parents, then the parents need to
> in the correct order or CCF need to be taught about such multi-dependencies.
>
> If some required feature is missed, then you have to implement it
> properly and for all, that's how things are done in upstream. Sometimes
> it's quite a lot of extra work that everyone are benefiting from in the end.
>
> [snip]
Yes, we should register ref/parents before their clients.
cclk_g clk is registered last after all pll and peripheral clocks are
registers during clock init.
dfllCPU_out clk is registered later during dfll-fcpu driver probe and
gets added to the clock list.
Probably the issue seems to be not linking dfll_ref and dfll_soc
dependencies for dfllCPU_out thru clock list.
clk-dfll driver during dfll_init_clks gets ref_clk and soc_clk reference
thru DT.
^ permalink raw reply
* Re: [PATCH V5 11/18] clk: tegra210: Add support for Tegra210 clocks
From: Dmitry Osipenko @ 2019-07-17 22:48 UTC (permalink / raw)
To: Sowjanya Komatineni, sboyd, Michael Turquette
Cc: Peter De Schrijver, Joseph Lo, thierry.reding, jonathanh, tglx,
jason, marc.zyngier, linus.walleij, stefan, mark.rutland,
pgaikwad, linux-clk, linux-gpio, jckuo, talho, linux-tegra,
linux-kernel, mperttunen, spatra, robh+dt, devicetree
In-Reply-To: <2de9a608-cf38-f56c-b192-7ffed65092f8@nvidia.com>
18.07.2019 0:57, Sowjanya Komatineni пишет:
>
> On 7/17/19 2:51 PM, Sowjanya Komatineni wrote:
>>
>> On 7/17/19 2:30 PM, Dmitry Osipenko wrote:
>>> 17.07.2019 23:11, Sowjanya Komatineni пишет:
>>>> On 7/17/19 1:01 PM, Sowjanya Komatineni wrote:
>>>>> On 7/17/19 12:43 PM, Dmitry Osipenko wrote:
>>>>>> 17.07.2019 21:54, Sowjanya Komatineni пишет:
>>>>>>> On 7/17/19 11:51 AM, Sowjanya Komatineni wrote:
>>>>>>>> On 7/17/19 11:32 AM, Dmitry Osipenko wrote:
>>>>>>>>> 17.07.2019 20:29, Sowjanya Komatineni пишет:
>>>>>>>>>> On 7/17/19 8:17 AM, Dmitry Osipenko wrote:
>>>>>>>>>>> 17.07.2019 9:36, Sowjanya Komatineni пишет:
>>>>>>>>>>>> On 7/16/19 11:33 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>> В Tue, 16 Jul 2019 22:55:52 -0700
>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> On 7/16/19 10:42 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>> В Tue, 16 Jul 2019 22:25:25 -0700
>>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>>> On 7/16/19 9:11 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>> В Tue, 16 Jul 2019 19:35:49 -0700
>>>>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>>>>> On 7/16/19 7:18 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>> On 7/16/19 3:06 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>>> On 7/16/19 3:00 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>> 17.07.2019 0:35, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 2:21 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>> 17.07.2019 0:12, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 1:47 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 22:26, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:43 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:30, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:25 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:19, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 9:50 AM, Sowjanya Komatineni
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 8:00 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 11:06, Peter De Schrijver пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2019 at 03:24:26PM +0800,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Joseph
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Lo wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OK, Will add to CPUFreq driver...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The other thing that also need
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> attention is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> that T124 CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicitly relies on DFLL driver to be
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> first, which is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> icky.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Should I add check for successful
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> register explicitly in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver probe and defer till dfll
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> registers?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Probably you should use the "device links".
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> See
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1][2] for the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> example.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/gpu/drm/tegra/dc.c#L2383
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [2]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://www.kernel.org/doc/html/latest/driver-api/device_link.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Return EPROBE_DEFER instead of EINVAL if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device_link_add() fails.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use of_find_device_by_node() to get the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device, see [3].
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [3]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/devfreq/tegra20-devfreq.c#n100
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Will go thru and add...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Looks like I initially confused this case with
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> getting
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> orphaned clock.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'm now seeing that the DFLL driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> registers the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock and then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk_get(dfll) should be returning EPROBE_DEFER
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> until
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL driver is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probed, hence everything should be fine
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as-is and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> there is no real
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for the 'device link'. Sorry for the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> confusion!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, I didn't follow the mail
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> thread. Just
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regarding the DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> part.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> As you know it, the DFLL clock is one
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock sources and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integrated with DVFS control logic
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator. We will not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to other clock sources once we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switched to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL. Because the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU has
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> been regulated by the DFLL HW with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DVFS
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (CVB or OPP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> you see
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> in the driver.). We shouldn't reparent
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> other sources with
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unknew
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> freq/volt pair. That's not guaranteed to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> work. We
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allow switching to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> open-loop mode but different sources.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay, then the CPUFreq driver will have to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rate before switching to PLLP in order to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper CPU voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP freq is safe to work for any CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> So no
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to PLLP rate before changing
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK_G
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to PLLP during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, please ignore my above comment. During
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend, need to change
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK_G source to PLLP when dfll is in closed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode first and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll need to be set to open loop.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And I don't exactly understand why we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to PLLP in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> idle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver. Just keep it on CL-DVFS mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> time.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 entry, the dfll suspend function
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moves it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the open-loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode. That's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all. The sc7-entryfirmware will handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the rest
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn off
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU power.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 resume, the warmboot code will
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator and power up the CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cluster. And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> leave
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it on PLL_P.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> After
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resuming to the kernel, we re-init DFLL,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> policy (CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> runs on DFLL open-loop mode) and then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moving to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> close-loop mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL is re-inited after switching
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> early clocks-state restoring by CaR driver.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hence
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> instead of having
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> odd
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hacks in the CaR driver, it is much
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> nicer to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper suspend-resume sequencing of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> drivers. In this case
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver is the driver that enables DFLL and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switches
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to that
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source, which means that this driver is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> also
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> be responsible for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> management of the DFLL's state during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend/resume process. If
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver disables DFLL during suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> re-enables it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resume, then looks like the CaR driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hacks
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> around
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL are not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> needed.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL part looks good to me. BTW,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> change the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> patch subject to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "Add
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend-resume support" seems more
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> me.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> To clarify this, the sequences for DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> are as
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> follows (assuming
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> required DFLL hw configuration has been
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> done)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch to DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Save current parent and frequency
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2) Enable DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3) Change cclk_g parent to DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For OVR regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Change PWM output pin from tristate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 5) Enable DFLL PWM output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For I2C regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Enable DFLL I2C output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 6) Program DFLL to closed loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch away from DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Change cclk_g parent to PLLP so the CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> frequency is ok for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> any
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> vdd_cpu voltage
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I see during switch away from DFLL (suspend),
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cclk_g
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent is not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> changed to PLLP before changing dfll to open
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Will add this ...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The CPUFreq driver switches parent to PLLP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probe, similar
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should be done on suspend.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'm also wondering if it's always safe to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP in the probe.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> If CPU is running on a lower freq than
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP, then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> some
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> other more
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate intermediate parent should be
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> selected.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU parents are PLL_X, PLL_P, and dfll. PLL_X
>>>>>>>>>>>>>>>>>>>>>>>>>>>> always
>>>>>>>>>>>>>>>>>>>>>>>>>>>> runs at higher
>>>>>>>>>>>>>>>>>>>>>>>>>>>> rate
>>>>>>>>>>>>>>>>>>>>>>>>>>>> so switching to PLL_P during CPUFreq probe
>>>>>>>>>>>>>>>>>>>>>>>>>>>> prior to
>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll clock enable
>>>>>>>>>>>>>>>>>>>>>>>>>>>> should be safe.
>>>>>>>>>>>>>>>>>>>>>>>>>>> AFAIK, PLLX could run at ~200MHz. There is
>>>>>>>>>>>>>>>>>>>>>>>>>>> also a
>>>>>>>>>>>>>>>>>>>>>>>>>>> divided output of
>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP
>>>>>>>>>>>>>>>>>>>>>>>>>>> which CCLKG supports, the PLLP_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Probably, realistically, CPU is always running
>>>>>>>>>>>>>>>>>>>>>>>>>>> off a
>>>>>>>>>>>>>>>>>>>>>>>>>>> fast PLLX during
>>>>>>>>>>>>>>>>>>>>>>>>>>> boot, but I'm wondering what may happen on
>>>>>>>>>>>>>>>>>>>>>>>>>>> KEXEC. I
>>>>>>>>>>>>>>>>>>>>>>>>>>> guess ideally CPUFreq driver should also have a
>>>>>>>>>>>>>>>>>>>>>>>>>>> 'shutdown' callback to teardown DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>> on a reboot, but likely that there are other
>>>>>>>>>>>>>>>>>>>>>>>>>>> clock-related problems as
>>>>>>>>>>>>>>>>>>>>>>>>>>> well that may break KEXEC and thus it is not
>>>>>>>>>>>>>>>>>>>>>>>>>>> very
>>>>>>>>>>>>>>>>>>>>>>>>>>> important at the
>>>>>>>>>>>>>>>>>>>>>>>>>>> moment.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> [snip]
>>>>>>>>>>>>>>>>>>>>>>>>>> During bootup CPUG sources from PLL_X. By PLL_P
>>>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>>>> above I meant
>>>>>>>>>>>>>>>>>>>>>>>>>> PLL_P_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> As per clock policies, PLL_X is always used
>>>>>>>>>>>>>>>>>>>>>>>>>> for high
>>>>>>>>>>>>>>>>>>>>>>>>>> freq
>>>>>>>>>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>>>>>>>>>>> 800Mhz
>>>>>>>>>>>>>>>>>>>>>>>>>> and for low frequency it will be sourced from
>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP.
>>>>>>>>>>>>>>>>>>>>>>>>> Alright, then please don't forget to
>>>>>>>>>>>>>>>>>>>>>>>>> pre-initialize
>>>>>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate to a
>>>>>>>>>>>>>>>>>>>>>>>>> reasonable value using tegra_clk_init_table or
>>>>>>>>>>>>>>>>>>>>>>>>> assigned-clocks.
>>>>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate update is not needed as it is
>>>>>>>>>>>>>>>>>>>>>>>> safe to
>>>>>>>>>>>>>>>>>>>>>>>> run at
>>>>>>>>>>>>>>>>>>>>>>>> 408Mhz because it is below fmax @ Vmin
>>>>>>>>>>>>>>>>>>>>>>> So even 204MHz CVB entries are having the same
>>>>>>>>>>>>>>>>>>>>>>> voltage as
>>>>>>>>>>>>>>>>>>>>>>> 408MHz, correct? It's not instantly obvious to me
>>>>>>>>>>>>>>>>>>>>>>> from the
>>>>>>>>>>>>>>>>>>>>>>> DFLL driver's code where the fmax @ Vmin is defined,
>>>>>>>>>>>>>>>>>>>>>>> I see
>>>>>>>>>>>>>>>>>>>>>>> that there is the min_millivolts
>>>>>>>>>>>>>>>>>>>>>>> and frequency entries starting from 204MHZ defined
>>>>>>>>>>>>>>>>>>>>>>> per-table.
>>>>>>>>>>>>>>>>>>>>>> Yes at Vmin CPU Fmax is ~800Mhz. So anything below
>>>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>>>>>>>>> work at Vmin voltage and PLLP max is 408Mhz.
>>>>>>>>>>>>>>>>>>>>> Thank you for the clarification. It would be good
>>>>>>>>>>>>>>>>>>>>> to have
>>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>>> commented
>>>>>>>>>>>>>>>>>>>>> in the code as well.
>>>>>>>>>>>>>>>>>>>> OK, Will add...
>>>>>>>>>>>>>>>>>>> Regarding, adding suspend/resume to CPUFreq, CPUFreq
>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>> happens very early even before disabling non-boot
>>>>>>>>>>>>>>>>>>> CPUs and
>>>>>>>>>>>>>>>>>>> also
>>>>>>>>>>>>>>>>>>> need to export clock driver APIs to CPUFreq.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Was thinking of below way of implementing this...
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Clock DFLL driver Suspend:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> - Save CPU clock policy registers, and
>>>>>>>>>>>>>>>>>>> Perform
>>>>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>>>>> suspend which sets in open loop mode
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> CPU Freq driver Suspend: does nothing
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Clock DFLL driver Resume:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> - Re-init DFLL, Set in Open-Loop mode,
>>>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>> Clock policy registers which actually sets source to
>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>> along
>>>>>>>>>>>>>>>>>>> with other CPU Policy register restore.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> CPU Freq driver Resume:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> - do clk_prepare_enable which acutally
>>>>>>>>>>>>>>>>>>> sets
>>>>>>>>>>>>>>>>>>> DFLL in
>>>>>>>>>>>>>>>>>>> Closed loop mode
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Adding one more note: Switching CPU Clock to PLLP is not
>>>>>>>>>>>>>>>>>>> needed
>>>>>>>>>>>>>>>>>>> as CPU CLock can be from dfll in open-loop mode as DFLL
>>>>>>>>>>>>>>>>>>> is not
>>>>>>>>>>>>>>>>>>> disabled anywhere throught the suspend/resume path
>>>>>>>>>>>>>>>>>>> and SC7
>>>>>>>>>>>>>>>>>>> entry
>>>>>>>>>>>>>>>>>>> FW and Warm boot code will switch CPU source to PLLP.
>>>>>>>>>>>>>>>>> Since CPU resumes on PLLP, it will be cleaner to suspend
>>>>>>>>>>>>>>>>> it on
>>>>>>>>>>>>>>>>> PLLP as well. And besides, seems that currently disabling
>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>> clock will disable DFLL completely and then you'd want to
>>>>>>>>>>>>>>>>> re-init
>>>>>>>>>>>>>>>>> the DFLL on resume any ways. So better to just disable
>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>> completely on suspend, which should happen on
>>>>>>>>>>>>>>>>> clk_disable(dfll).
>>>>>>>>>>>>>>>> Will switch to PLLP during CPUFreq suspend. With
>>>>>>>>>>>>>>>> decision of
>>>>>>>>>>>>>>>> using
>>>>>>>>>>>>>>>> clk_disable during suspend, its mandatory to switch to
>>>>>>>>>>>>>>>> PLLP as
>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>> is completely disabled.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> My earlier concern was on restoring CPU policy as we
>>>>>>>>>>>>>>>> can't do
>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>> from CPUFreq driver and need export from clock driver.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Clear now and will do CPU clock policy restore in after
>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>> re-init.
>>>>>>>>>>>>>>> Why the policy can't be saved/restored by the CaR driver
>>>>>>>>>>>>>>> as a
>>>>>>>>>>>>>>> context of any other clock?
>>>>>>>>>>>>>> restoring cpu clock policy involves programming source and
>>>>>>>>>>>>>> super_cclkg_divider.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> cclk_g is registered as clk_super_mux and it doesn't use
>>>>>>>>>>>>>> frac_div ops
>>>>>>>>>>>>>> to do save/restore its divider.
>>>>>>>>>>>>> That can be changed of course and I guess it also could be as
>>>>>>>>>>>>> simple as
>>>>>>>>>>>>> saving and restoring of two raw u32 values of the
>>>>>>>>>>>>> policy/divider
>>>>>>>>>>>>> registers.
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Also, during clock context we cant restore cclk_g as cclk_g
>>>>>>>>>>>>>> source
>>>>>>>>>>>>>> will be dfll and dfll will not be resumed/re-initialized
>>>>>>>>>>>>>> by the
>>>>>>>>>>>>>> time
>>>>>>>>>>>>>> clk_super_mux save/restore happens.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> we can't use save/restore context for dfll clk_ops because
>>>>>>>>>>>>>> dfllCPU_out parent to CCLK_G is first in the clock tree and
>>>>>>>>>>>>>> dfll_ref
>>>>>>>>>>>>>> and dfll_soc peripheral clocks are not restored by the
>>>>>>>>>>>>>> time dfll
>>>>>>>>>>>>>> restore happens. Also dfll peripheral clock enables need
>>>>>>>>>>>>>> to be
>>>>>>>>>>>>>> restored before dfll restore happens which involves
>>>>>>>>>>>>>> programming
>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>> controller for re-initialization.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> So dfll resume/re-init is done in clk-tegra210 at end of all
>>>>>>>>>>>>>> clocks
>>>>>>>>>>>>>> restore in V5 series but instead of in clk-tegra210 driver I
>>>>>>>>>>>>>> moved
>>>>>>>>>>>>>> now to dfll-fcpu driver pm_ops as all dfll dependencies
>>>>>>>>>>>>>> will be
>>>>>>>>>>>>>> restored thru clk_restore_context by then. This will be in
>>>>>>>>>>>>>> V6.
>>>>>>>>>>>>> Since DFLL is now guaranteed to be disabled across CaR
>>>>>>>>>>>>> suspend/resume
>>>>>>>>>>>>> (hence it has nothing to do in regards to CCLK) and given that
>>>>>>>>>>>>> PLLs
>>>>>>>>>>>>> state is restored before the rest of the clocks, I don't
>>>>>>>>>>>>> see why
>>>>>>>>>>>>> not to
>>>>>>>>>>>>> implement CCLK save/restore in a generic fasion. CPU policy
>>>>>>>>>>>>> wull be
>>>>>>>>>>>>> restored to either PLLP or PLLX (if CPUFreq driver is
>>>>>>>>>>>>> disabled).
>>>>>>>>>>>>>
>>>>>>>>>>>> CCLK_G save/restore should happen in clk_super_mux ops
>>>>>>>>>>>> save/context and
>>>>>>>>>>>> clk_super_mux save/restore happens very early as cclk_g is
>>>>>>>>>>>> first
>>>>>>>>>>>> in the
>>>>>>>>>>>> clock tree and save/restore traverses through the tree
>>>>>>>>>>>> top-bottom
>>>>>>>>>>>> order.
>>>>>>>>>>> If CCLK_G is restored before the PLLs, then just change the
>>>>>>>>>>> clocks
>>>>>>>>>>> order
>>>>>>>>>>> such that it won't happen.
>>>>>>>>>>>
>>>>>>>>>> I dont think we can change clocks order for CCLK_G.
>>>>>>>>>>
>>>>>>>>>> During bootup, cclk_g is registered after all pll's and
>>>>>>>>>> peripheral
>>>>>>>>>> clocks which is the way we wanted, So cclk_g will be the first
>>>>>>>>>> one in
>>>>>>>>>> the clk list as clk_register adds new clock first in the list.
>>>>>>>>>>
>>>>>>>>>> When clk_save_context and clk_restore_context APIs iterates
>>>>>>>>>> over the
>>>>>>>>>> list, cclk_g is the first
>>>>>>>>> Looking at clk_core_restore_context(), I see that it walks up CLKs
>>>>>>>>> list
>>>>>>>>> from parent to children, hence I don't understand how it can ever
>>>>>>>>> happen
>>>>>>>>> that CCLK will be restored before the parent. The clocks
>>>>>>>>> registration
>>>>>>>>> order doesn't matter at all in that case.
>>>>>>>> yes from parent to children and dfllCPU_out is the top in the
>>>>>>>> list and
>>>>>>>> its child is cclk_g.
>>>>>>>>
>>>>>>>> the way clocks are registered is the order I see in the clock
>>>>>>>> list and
>>>>>>>> looking into clk_register API it adds new node first in the list.
>>>>>>>>
>>>>>>> cclkg_g & dfll register happens after all plls and peripheral
>>>>>>> clocks as
>>>>>>> it need ref, soc and peripheral clocks to be enabled.
>>>>>>>> So they are the last to get registered and so becomes first in the
>>>>>>>> list.
>>>>>>>>
>>>>>>>> During save/restore context, it traverses thru this list and
>>>>>>>> first in
>>>>>>>> the list is dfllcpu_OUT (parent) and its child (cclk_g)
>>>>>>>>
>>>>>>>> saving should not be an issue at all but we cant restore
>>>>>>>> cclk_g/dfll
>>>>>>>> in normal way thru clk_ops restore as plls and peripherals restore
>>>>>>>> doesn't happen by that time.
>>>>>>>>
>>>>>>> I was referring to clk_restore_context where it iterates thru
>>>>>>> root list
>>>>>>> and for each core from the root list clk_core_restore does
>>>>>>> restore of
>>>>>>> parent and children.
>>>>>>>
>>>>>>> dfllCPU_Out gets first in the list and its child is cclk_g
>>>>>>>
>>>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/clk/clk.c#L1105
>>>>>>>
>>>>>> What list you're talking about? clk_summary? It shows current
>>>>>> *active*
>>>>>> clocks configuration, if you'll try to disable CPUFreq driver then
>>>>>> the
>>>>>> parent of CCLK_G should be PLLX. Similarly when CPU is reparented to
>>>>>> PLLP on driver's suspend, then PLLP is the parent.
>>>>>>
>>>>>>>>>>>> DFLL enable thru CPUFreq resume happens after all
>>>>>>>>>>>> clk_restore_context
>>>>>>>>>>>> happens. So during clk_restore_context, dfll re-init doesnt
>>>>>>>>>>>> happen
>>>>>>>>>>>> and
>>>>>>>>>>>> doing cpu clock policy restore during super_mux clk_ops will
>>>>>>>>>>>> crash as
>>>>>>>>>>>> DFLL is not initialized and its clock is not enabled but CPU
>>>>>>>>>>>> clock
>>>>>>>>>>>> restore sets source to DFLL if we restore during super_clk_mux
>>>>>>>>>>> If CPU was suspended on PLLP, then it will be restored on
>>>>>>>>>>> PLLP by
>>>>>>>>>>> CaR. I
>>>>>>>>>>> don't understand what DFLL has to do with the CCLK in that case
>>>>>>>>>>> during
>>>>>>>>>>> the clocks restore.
>>>>>>>>>> My above comment is in reference to your request of doing
>>>>>>>>>> save/restore
>>>>>>>>>> for cclk_g in normal fashion thru save/restore context. Because
>>>>>>>>>> of the
>>>>>>>>>> clk order I mentioned above, we cclk_g will be the first one to
>>>>>>>>>> go thru
>>>>>>>>>> save/context.
>>>>>>>>>>
>>>>>>>>>> During save_context of cclk_g, source can be from PLLX, dfll.
>>>>>>>>>>
>>>>>>>>>> Issue will be when we do restore during clk_restore_context of
>>>>>>>>>> cclk_g as
>>>>>>>>>> by that time PLLX/dfll will not be restored.
>>>>>>>>>>
>>>>>>>>> Seems we already agreed that DFLL will be disabled by the CPUFreq
>>>>>>>>> driver
>>>>>>>>> on suspend. Hence CCLK can't be from DFLL if CPU is reparented to
>>>>>>>>> PLLP
>>>>>>>>> on CPUFreq driver's suspend, otherwise CPU keeps running from a
>>>>>>>>> boot-state PLLX if CPUFreq driver is disabled.
>>>>>>>> Yes suspend should not be an issue but issue will be during resume
>>>>>>>> where if we do cclk_g restore in normal way thru
>>>>>>>> clk_restore_context,
>>>>>>>> cclk_g restore happens very early as dfllCPU out is the first
>>>>>>>> one that
>>>>>>>> goes thru restore context and plls/peripherals are not resumed by
>>>>>>>> then.
>>>>>>>>
>>>>>>>> CPU runs from PLLX if dfll clock enable fails during boot. So
>>>>>>>> when it
>>>>>>>> gets to suspend, we save CPU running clock source as either PLLX or
>>>>>>>> DFLL and then we switch to PLLP.
>>>>>>>>
>>>>>>>>
>>>>>>>> On resume, CPU runs from PLLP by warm boot code and we need to
>>>>>>>> restore
>>>>>>>> back its source to the one it was using from saved source context
>>>>>>>> (which can be either PLLX or DFLL)
>>>>>>>>
>>>>>>>> So PLLs & DFLL resume need to happen before CCLKG restore/resume.
>>>>>>>>
>>>>>>>>
>>>>>>>> With all above discussions, we do DFLL disable in CPUFreq driver on
>>>>>>>> suspend and on CPUFreq resume we enable DFLL back and restore CPU
>>>>>>>> clock source it was using during suspend (which will be either
>>>>>>>> PLLX if
>>>>>>>> dfll enable fails during probe or it will be using DFLL).
>>>>>> During suspend CPU's parent shall be PLLP and not DFLL (note that
>>>>>> it is
>>>>>> disabled) after reparenting to PLLP by the CPUFreq driver.
>>>>>>
>>>>> CPU source context should be saved before switching to safe source of
>>>>> PLLP as on resume we need to restore back to source it was using
>>>>> before we switch to safe source during suspend entry.
>>>>>
>>>>> So saved context for CPU Source will be either dfll or PLLX
>>>>>
>>>> PLLP reparenting is only during suspend/entry to have it as safe source
>>>> but actual CPU source it was running from before suspending is either
>>>> dfll/pllx which should be the one to be restored on CPUFreq resume.
>>>> Resume happens with CPU running from PLLP till it gets to the point of
>>>> restoring its original source (dfll or pllx)
>>> CaR should restore CPU to PLLP or PLLX, while CPUFreq driver restores
>>> CPU to DFLL. Please see more comments below.
>>>
>>>>>>>> So i was trying to say dfll/cclk_g restore can't be done in
>>>>>>>> normal way
>>>>>>>> thru clk_ops save/restore context
>>>>>> Let's see what happens if CPUFreq is active:
>>>>>>
>>>>>> 1. CPUFreq driver probe happens
>>>>>> 2. CPU is reparented to PLLP
>>>>>> 3. DFLL inited
>>>>>> 4. CPU is reparented to DFLL
>>>>>>
>>>>>> 5. CPUFreq driver suspend happens
>>>>>> 6. CPU is reparented to PLLP
>>>>>> 7. DFLL is disabled
>>>>>>
>>>>>> 8. Car suspend happens
>>>>>> 9. DFLL context saved
>>>>>> 10. PLLP/PLLX context saved
>>>>>> 11. CCLK context saved
>>>>>>
>>>>>> 12. Car resume happens
>>>>>> 13. DFLL context restored
>>>>>> 14. PLLP/PLLX context restored
>>>>>> 15. CCLK context restored
>>>>>>
>>>>>> 16. CPUFreq driver resume happens
>>>>>> 17. DFLL re-inited
>>>>>> 18. CPU is reparented to DFLL
>>>>>
>>>>> Below is the order of sequence it should be based on the order of clk
>>>>> register.
>>>>>
>>>>> My comments inline in this sequence.
>>>>>
>>>>> 1. CPUFreq driver probe happens
>>>>> 2. CPU is reparented to PLLP
>>>>> 3. DFLL inited
>>>>> 4. CPU is reparented to DFLL
>>>>>
>>>>>
>>>>> 5. CPUFreq driver suspend happens
>>>>> 6. Save CPU source which could be either dfll or pllx
>>> Please see my next comment.
>>>
>>>>> 7. CPU is reparented to safe known source PLLP
>>>>> 8. DFLL is disabled
>>>>>
>>>>> 8. Car suspend happens
>>>>> 9. DFLL context saved (With DFLL disabled in CPUFreq suspend,
>>>>> nothing to be saved here as last freq req will always be saved).
>>>>> 10. CCLK context saved (CPU clock source will be saved in CPUFreq
>>>>> driver suspend which could be either dfll or pllx)
>>> That I don't understand. The CPU's clock source state should be saved at
>>> the moment of the CaR's suspending (i.e. CCLK policy will be set to PLLP
>>> or PLLX) and then CCLK state should be also restored by the CaR in
>>> step 14.
>>
>> CPU clock to be saved and restored should be the source used before we
>> switch it to safe PLLP for suspend/resume operation.
>>
>> This original source could be either PLLX or DFLL which it was using
>> before we disable DFLL during CPU Freq suspend.
>>
>> If we save CPU clock source at moment of CAR suspending, it will be
>> PLLP as we switch to safe PLLP in CPUFreq driver suspend.
>>
>> Infact, we dont need to restore CPU clock source to PLLP anywhere in
>> resume as it comes up with PLLP source from warm boot code itself.
You must always maintain proper suspend/resume encapsulation, otherwise
it's a total mess. It doesn't matter that CCLK is restored to PLLP even
that CPU is already running off PLLP after warmboot.
>> But we need to restore CPU source to original source it was using
>> before we switch to safe PLLP source for suspend operation. This
>> original source could be PLLX/DFLL and this should be re-stored in
>> CPUFreq resume as by this time PLLs and peripherals are restored and
>> dfll is re-initialized.
>>
>> So saving actual CPU source before switching to intermediate safe PLLP
>> in CPUFreq driver and then restoring back during CPUFreq resume should
>> be good as CPUFreq resume happens right after all clocks (plls
>> restore, peripherals restore, dfll resume)>>
>>> CPUFreq driver should only switch CPU to PLLP and disable DFLL on
>>> suspend in step 5, that's it. On resume CPUFreq driver will restore CPU
>>> to DFLL in step 18.
>> Also I don't think we should hard-code to force CPU source to DFLL on
>> CPUFreq resume.
>>
>> Reason is during CPU Probe when it tries to switch to dfll source, for
>> some reason if dfll enable fails it sets CPU to its original source
>> which will be PLLX.
No!
1. CPU voltage could be too low for PLLX
2. PLLX rate can't be changed without manual reparenting CPU to
intermediate clock
3. CPUFreq can't manually manage CPU voltage
DFLL-restoring failure is an extreme case. CPU must be kept on a safe
PLLP in that case and disable_cpufreq() must be invoked as well.
>> So CPU source could be either DFLL or PLLX in CPUFreq
>> tegra124_cpu_switch_to_dfll
>>
>>>>> 11. PLLP/PLLX context saved
>>>>> 12. Peripheral Clock saved
>>>>>
>>>>> 12. Car resume happens
>>>>> 13. DFLL context restored : No DFLL context to be restored and we
>>>>> only need to reinitialize DFLL and re-initialize can't be done here as
>>>>> this is the 1st to get restored and PLL/Peripheral clocks are not
>>>>> restored by this time. So we can't use clk_ops restore for DFLL
>>> It looks to me that clk_core_restore_context() should just do
>>> hlist_for_each_entry *_reverse*. Don't you think so?
>>
>> Thought of that but this is in core driver and is used by other
>> non-tegra clock driver and not sure if that impacts for those.
The reverse ordering should be correct, I think it's just a shortcoming
of the CCF that need to be fixed. But will better to make a more
thorough research, asking Stephen and Michael for the clarification.
>> But with decision of switching CPUFreq with dfll clock enable/disable
>> during CPUFreq suspend/resume, we can re-init dfll during dfll-fcpu
>> driver resume and we don't need CCLK save/restore.
>>
> the way of all clocks order is good except cclk_g which has dependency
> on multiple clocks.
CCLK_G has a single parent at a time. What "multiple clocks" you're
talking about? Please explain.
> reverse list order during restore might not work as all other clocks are
> in proper order no with any ref clocks for plls getting restored prior
> to their clients
Why? The ref clocks should be registered first and be the roots for PLLs
and the rest. If it's not currently the case, then this need to be
fixed. You need to ensure that each clock is modeled properly. If some
child clock really depends on multiple parents, then the parents need to
in the correct order or CCF need to be taught about such multi-dependencies.
If some required feature is missed, then you have to implement it
properly and for all, that's how things are done in upstream. Sometimes
it's quite a lot of extra work that everyone are benefiting from in the end.
[snip]
^ permalink raw reply
* Re: [v5 6/7] drm/mediatek: change the dsi phytiming calculate method
From: Ryan Case @ 2019-07-17 22:03 UTC (permalink / raw)
To: CK Hu
Cc: Mark Rutland, devicetree, David Airlie, stonea168, dri-devel,
yingjoe.chen, Ajay Kumar, Vincent Palatin, cawa.cheng,
bibby.hsieh, Russell King, Thierry Reding, linux-pwm, Jitao Shi,
Sascha Hauer, Pawel Moll, Ian Campbell, Inki Dae, Rob Herring,
linux-mediatek, Andy Yan, Matthias Brugger, eddie.huang,
linux-arm-kernel, Rahul Sharma, srv_heupstream
In-Reply-To: <1561945387.17120.4.camel@mtksdaap41>
On Sun, Jun 30, 2019 at 6:43 PM CK Hu <ck.hu@mediatek.com> wrote:
>
> Hi, Jitao:
>
> On Thu, 2019-06-27 at 16:01 +0800, Jitao Shi wrote:
> > Change the method of frame rate calc which can get more accurate
> > frame rate.
> >
> > data rate = pixel_clock * bit_per_pixel / lanes
> > Adjust hfp_wc to adapt the additional phy_data
> >
> > if MIPI_DSI_MODE_VIDEO_BURST
> > hfp_wc = hfp * bpp - data_phy_cycles * lanes - 12 - 6;
> > else
> > hfp_wc = hfp * bpp - data_phy_cycles * lanes - 12;
> >
> > Note:
> > //(2: 1 for sync, 1 for phy idle)
> > data_phy_cycles = T_hs_exit + T_lpx + T_hs_prepare + T_hs_zero + 2;
> >
> > bpp: bit per pixel
> >
> > Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
> > Tested-by: Ryan Case <ryandcase@chromium.org>
> > Reviewed-by: CK Hu <ck.hu@mediatek.com>
>
> This version is different than previous version, so you should remove
> Reviewed-by tag. For this version, I still give you a
>
> Reviewed-by: CK Hu <ck.hu@mediatek.com>
>
> > ---
> > drivers/gpu/drm/mediatek/mtk_dsi.c | 117 ++++++++++++++++++++---------
> > 1 file changed, 80 insertions(+), 37 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > index 1621e8cdacc2..cefdcb1509cb 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > @@ -144,12 +144,6 @@
> > #define DATA_0 (0xff << 16)
> > #define DATA_1 (0xff << 24)
> >
> > -#define T_LPX 5
> > -#define T_HS_PREP 6
> > -#define T_HS_TRAIL 8
> > -#define T_HS_EXIT 7
> > -#define T_HS_ZERO 10
> > -
> > #define NS_TO_CYCLE(n, c) ((n) / (c) + (((n) % (c)) ? 1 : 0))
> >
> > #define MTK_DSI_HOST_IS_READ(type) \
> > @@ -158,6 +152,25 @@
> > (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
> > (type == MIPI_DSI_DCS_READ))
> >
> > +struct mtk_phy_timing {
> > + u32 lpx;
> > + u32 da_hs_prepare;
> > + u32 da_hs_zero;
> > + u32 da_hs_trail;
> > +
> > + u32 ta_go;
> > + u32 ta_sure;
> > + u32 ta_get;
> > + u32 da_hs_exit;
> > +
> > + u32 clk_hs_zero;
> > + u32 clk_hs_trail;
> > +
> > + u32 clk_hs_prepare;
> > + u32 clk_hs_post;
> > + u32 clk_hs_exit;
> > +};
> > +
> > struct phy;
> >
> > struct mtk_dsi_driver_data {
> > @@ -188,6 +201,7 @@ struct mtk_dsi {
> > enum mipi_dsi_pixel_format format;
> > unsigned int lanes;
> > struct videomode vm;
> > + struct mtk_phy_timing phy_timing;
> > int refcount;
> > bool enabled;
> > u32 irq_data;
> > @@ -221,17 +235,36 @@ static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
> > {
> > u32 timcon0, timcon1, timcon2, timcon3;
> > u32 ui, cycle_time;
> > + struct mtk_phy_timing *timing = &dsi->phy_timing;
> > +
> > + ui = 1000000000 / dsi->data_rate;
> > + cycle_time = div_u64(8000000000ULL, dsi->data_rate);
> > +
> > + timing->lpx = NS_TO_CYCLE(60, cycle_time);
> > + timing->da_hs_prepare = NS_TO_CYCLE(40 + 5 * ui, cycle_time);
> > + timing->da_hs_zero = NS_TO_CYCLE(110 + 6 * ui, cycle_time);
> > + timing->da_hs_trail = NS_TO_CYCLE(80 + 4 * ui, cycle_time);
> >
> > - ui = 1000 / dsi->data_rate + 0x01;
> > - cycle_time = 8000 / dsi->data_rate + 0x01;
> > + timing->ta_go = 4 * timing->lpx;
> > + timing->ta_sure = 3 * timing->lpx / 2;
> > + timing->ta_get = 5 * timing->lpx;
> > + timing->da_hs_exit = 2 * timing->lpx;
> >
> > - timcon0 = T_LPX | T_HS_PREP << 8 | T_HS_ZERO << 16 | T_HS_TRAIL << 24;
> > - timcon1 = 4 * T_LPX | (3 * T_LPX / 2) << 8 | 5 * T_LPX << 16 |
> > - T_HS_EXIT << 24;
> > - timcon2 = ((NS_TO_CYCLE(0x64, cycle_time) + 0xa) << 24) |
> > - (NS_TO_CYCLE(0x150, cycle_time) << 16);
> > - timcon3 = NS_TO_CYCLE(0x40, cycle_time) | (2 * T_LPX) << 16 |
> > - NS_TO_CYCLE(80 + 52 * ui, cycle_time) << 8;
> > + timing->clk_hs_zero = NS_TO_CYCLE(336, cycle_time);
> > + timing->clk_hs_trail = NS_TO_CYCLE(100, cycle_time) + 10;
> > +
> > + timing->clk_hs_prepare = NS_TO_CYCLE(64, cycle_time);
> > + timing->clk_hs_post = NS_TO_CYCLE(80 + 52 * ui, cycle_time);
> > + timing->clk_hs_exit = 2 * timing->lpx;
> > +
> > + timcon0 = timing->lpx | timing->da_hs_prepare << 8 |
> > + timing->da_hs_zero << 16 | timing->da_hs_trail << 24;
> > + timcon1 = timing->ta_go | timing->ta_sure << 8 |
> > + timing->ta_get << 16 | timing->da_hs_exit << 24;
> > + timcon2 = 1 << 8 | timing->clk_hs_zero << 16 |
> > + timing->clk_hs_trail << 24;
> > + timcon3 = timing->clk_hs_prepare | timing->clk_hs_post << 8 |
> > + timing->clk_hs_exit << 16;
> >
> > writel(timcon0, dsi->regs + DSI_PHY_TIMECON0);
> > writel(timcon1, dsi->regs + DSI_PHY_TIMECON1);
> > @@ -418,7 +451,8 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
> > u32 horizontal_sync_active_byte;
> > u32 horizontal_backporch_byte;
> > u32 horizontal_frontporch_byte;
> > - u32 dsi_tmp_buf_bpp;
> > + u32 dsi_tmp_buf_bpp, data_phy_cycles;
> > + struct mtk_phy_timing *timing = &dsi->phy_timing;
> >
> > struct videomode *vm = &dsi->vm;
> >
> > @@ -445,7 +479,34 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
> > horizontal_backporch_byte = ((vm->hback_porch + vm->hsync_len) *
> > dsi_tmp_buf_bpp - 10);
> >
> > - horizontal_frontporch_byte = (vm->hfront_porch * dsi_tmp_buf_bpp - 12);
> > + data_phy_cycles = timing->lpx + timing->da_hs_prepare +
> > + timing->da_hs_zero + timing->da_hs_exit + 2;
> > +
> > + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {
> > + if (vm->hfront_porch * dsi_tmp_buf_bpp >
> > + data_phy_cycles * dsi->lanes + 18) {
> > + horizontal_frontporch_byte = vm->hfront_porch *
> > + dsi_tmp_buf_bpp -
> > + data_phy_cycles *
> > + dsi->lanes - 18;
> > + } else {
> > + DRM_WARN("HFP less than d-phy, FPS will under 60Hz\n");
> > + horizontal_frontporch_byte = vm->hfront_porch *
> > + dsi_tmp_buf_bpp;
> > + }
> > + } else {
> > + if (vm->hfront_porch * dsi_tmp_buf_bpp >
> > + data_phy_cycles * dsi->lanes + 12) {
> > + horizontal_frontporch_byte = vm->hfront_porch *
> > + dsi_tmp_buf_bpp -
> > + data_phy_cycles *
> > + dsi->lanes - 12;
> > + } else {
> > + DRM_WARN("HFP less than d-phy, FPS will under 60Hz\n");
> > + horizontal_frontporch_byte = vm->hfront_porch *
> > + dsi_tmp_buf_bpp;
> > + }
> > + }
> >
> > writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC);
> > writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
> > @@ -545,8 +606,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
> > {
> > struct device *dev = dsi->->host.dev;
> > int ret;
> > - u64 pixel_clock, total_bits;
> > - u32 htotal, htotal_bits, bit_per_pixel, overhead_cycles, overhead_bits;
> > + u32 bit_per_pixel;
> >
> > if (++dsi->refcount != 1)
> > return 0;
> > @@ -565,24 +625,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
> > break;
> > }
> >
> > - /**
> > - * htotal_time = htotal * byte_per_pixel / num_lanes
> > - * overhead_time = lpx + hs_prepare + hs_zero + hs_trail + hs_exit
> > - * mipi_ratio = (htotal_time + overhead_time) / htotal_time
> > - * data_rate = pixel_clock * bit_per_pixel * mipi_ratio / num_lanes;
> > - */
> > - pixel_clock = dsi->vm.pixelclock;
> > - htotal = dsi->vm.hactive + dsi->vm.hback_porch + dsi->vm.hfront_porch +
> > - dsi->vm.hsync_len;
> > - htotal_bits = htotal * bit_per_pixel;
> > -
> > - overhead_cycles = T_LPX + T_HS_PREP + T_HS_ZERO + T_HS_TRAIL +
> > - T_HS_EXIT;
> > - overhead_bits = overhead_cycles * dsi->lanes * 8;
> > - total_bits = htotal_bits + overhead_bits;
> > -
> > - dsi->data_rate = DIV_ROUND_UP_ULL(pixel_clock * total_bits,
> > - htotal * dsi->lanes);
> > + dsi->data_rate = DIV_ROUND_UP_ULL(dsi->vm.pixelclock * bit_per_pixel, dsi->lanes);
nit: Wrap this line, it's over 80 characters.
> >
> > ret = clk_set_rate(dsi->hs_clk, dsi->data_rate);
> > if (ret < 0) {
>
>
^ permalink raw reply
* Re: [PATCH V5 11/18] clk: tegra210: Add support for Tegra210 clocks
From: Sowjanya Komatineni @ 2019-07-17 21:57 UTC (permalink / raw)
To: Dmitry Osipenko
Cc: Peter De Schrijver, Joseph Lo, thierry.reding, jonathanh, tglx,
jason, marc.zyngier, linus.walleij, stefan, mark.rutland,
pgaikwad, sboyd, linux-clk, linux-gpio, jckuo, talho, linux-tegra,
linux-kernel, mperttunen, spatra, robh+dt, devicetree
In-Reply-To: <46b55527-da5d-c0b7-1c14-43b5c6d49dfa@nvidia.com>
On 7/17/19 2:51 PM, Sowjanya Komatineni wrote:
>
> On 7/17/19 2:30 PM, Dmitry Osipenko wrote:
>> 17.07.2019 23:11, Sowjanya Komatineni пишет:
>>> On 7/17/19 1:01 PM, Sowjanya Komatineni wrote:
>>>> On 7/17/19 12:43 PM, Dmitry Osipenko wrote:
>>>>> 17.07.2019 21:54, Sowjanya Komatineni пишет:
>>>>>> On 7/17/19 11:51 AM, Sowjanya Komatineni wrote:
>>>>>>> On 7/17/19 11:32 AM, Dmitry Osipenko wrote:
>>>>>>>> 17.07.2019 20:29, Sowjanya Komatineni пишет:
>>>>>>>>> On 7/17/19 8:17 AM, Dmitry Osipenko wrote:
>>>>>>>>>> 17.07.2019 9:36, Sowjanya Komatineni пишет:
>>>>>>>>>>> On 7/16/19 11:33 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>> В Tue, 16 Jul 2019 22:55:52 -0700
>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>
>>>>>>>>>>>>> On 7/16/19 10:42 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>> В Tue, 16 Jul 2019 22:25:25 -0700
>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>> On 7/16/19 9:11 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>> В Tue, 16 Jul 2019 19:35:49 -0700
>>>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>>>> On 7/16/19 7:18 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>> On 7/16/19 3:06 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>> On 7/16/19 3:00 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>> 17.07.2019 0:35, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>> On 7/16/19 2:21 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>> 17.07.2019 0:12, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 1:47 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 22:26, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:43 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:30, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:25 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:19, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 9:50 AM, Sowjanya Komatineni
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 8:00 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 11:06, Peter De Schrijver пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2019 at 03:24:26PM +0800,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Joseph
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Lo wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OK, Will add to CPUFreq driver...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The other thing that also need
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> attention is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> that T124 CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicitly relies on DFLL driver to be
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> first, which is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> icky.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Should I add check for successful
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> register explicitly in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver probe and defer till dfll
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> registers?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Probably you should use the "device links".
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> See
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1][2] for the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> example.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/gpu/drm/tegra/dc.c#L2383
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [2]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://www.kernel.org/doc/html/latest/driver-api/device_link.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Return EPROBE_DEFER instead of EINVAL if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device_link_add() fails.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use of_find_device_by_node() to get the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device, see [3].
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [3]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/devfreq/tegra20-devfreq.c#n100
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Will go thru and add...
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Looks like I initially confused this case with
>>>>>>>>>>>>>>>>>>>>>>>>>>>> getting
>>>>>>>>>>>>>>>>>>>>>>>>>>>> orphaned clock.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'm now seeing that the DFLL driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>> registers the
>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock and then
>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk_get(dfll) should be returning EPROBE_DEFER
>>>>>>>>>>>>>>>>>>>>>>>>>>>> until
>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL driver is
>>>>>>>>>>>>>>>>>>>>>>>>>>>> probed, hence everything should be fine
>>>>>>>>>>>>>>>>>>>>>>>>>>>> as-is and
>>>>>>>>>>>>>>>>>>>>>>>>>>>> there is no real
>>>>>>>>>>>>>>>>>>>>>>>>>>>> need
>>>>>>>>>>>>>>>>>>>>>>>>>>>> for the 'device link'. Sorry for the
>>>>>>>>>>>>>>>>>>>>>>>>>>>> confusion!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, I didn't follow the mail
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> thread. Just
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regarding the DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> part.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> As you know it, the DFLL clock is one
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock sources and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integrated with DVFS control logic
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator. We will not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to other clock sources once we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switched to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL. Because the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU has
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> been regulated by the DFLL HW with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DVFS
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (CVB or OPP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> you see
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> in the driver.). We shouldn't reparent
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> other sources with
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unknew
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> freq/volt pair. That's not guaranteed to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> work. We
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allow switching to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> open-loop mode but different sources.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay, then the CPUFreq driver will have to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rate before switching to PLLP in order to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper CPU voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP freq is safe to work for any CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> So no
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to PLLP rate before changing
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK_G
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to PLLP during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, please ignore my above comment. During
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend, need to change
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK_G source to PLLP when dfll is in closed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode first and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll need to be set to open loop.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And I don't exactly understand why we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to PLLP in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> idle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver. Just keep it on CL-DVFS mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> time.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 entry, the dfll suspend function
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moves it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the open-loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode. That's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all. The sc7-entryfirmware will handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the rest
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn off
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU power.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 resume, the warmboot code will
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator and power up the CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cluster. And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> leave
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it on PLL_P.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> After
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resuming to the kernel, we re-init DFLL,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> policy (CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> runs on DFLL open-loop mode) and then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moving to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> close-loop mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL is re-inited after switching
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> early clocks-state restoring by CaR driver.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hence
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> instead of having
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> odd
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hacks in the CaR driver, it is much
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> nicer to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper suspend-resume sequencing of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> drivers. In this case
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver is the driver that enables DFLL and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switches
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to that
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source, which means that this driver is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> also
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> be responsible for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> management of the DFLL's state during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend/resume process. If
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver disables DFLL during suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> re-enables it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resume, then looks like the CaR driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hacks
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> around
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL are not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> needed.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL part looks good to me. BTW,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> change the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> patch subject to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "Add
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend-resume support" seems more
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> me.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> To clarify this, the sequences for DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> are as
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> follows (assuming
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> required DFLL hw configuration has been
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> done)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch to DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Save current parent and frequency
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2) Enable DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3) Change cclk_g parent to DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For OVR regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Change PWM output pin from tristate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 5) Enable DFLL PWM output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For I2C regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Enable DFLL I2C output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 6) Program DFLL to closed loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch away from DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Change cclk_g parent to PLLP so the CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> frequency is ok for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> any
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> vdd_cpu voltage
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> I see during switch away from DFLL (suspend),
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> cclk_g
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent is not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> changed to PLLP before changing dfll to open
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Will add this ...
>>>>>>>>>>>>>>>>>>>>>>>>>>>> The CPUFreq driver switches parent to PLLP
>>>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>> probe, similar
>>>>>>>>>>>>>>>>>>>>>>>>>>>> should be done on suspend.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> I'm also wondering if it's always safe to
>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to
>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP in the probe.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> If CPU is running on a lower freq than
>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP, then
>>>>>>>>>>>>>>>>>>>>>>>>>>>> some
>>>>>>>>>>>>>>>>>>>>>>>>>>>> other more
>>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate intermediate parent should be
>>>>>>>>>>>>>>>>>>>>>>>>>>>> selected.
>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU parents are PLL_X, PLL_P, and dfll. PLL_X
>>>>>>>>>>>>>>>>>>>>>>>>>>> always
>>>>>>>>>>>>>>>>>>>>>>>>>>> runs at higher
>>>>>>>>>>>>>>>>>>>>>>>>>>> rate
>>>>>>>>>>>>>>>>>>>>>>>>>>> so switching to PLL_P during CPUFreq probe
>>>>>>>>>>>>>>>>>>>>>>>>>>> prior to
>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll clock enable
>>>>>>>>>>>>>>>>>>>>>>>>>>> should be safe.
>>>>>>>>>>>>>>>>>>>>>>>>>> AFAIK, PLLX could run at ~200MHz. There is
>>>>>>>>>>>>>>>>>>>>>>>>>> also a
>>>>>>>>>>>>>>>>>>>>>>>>>> divided output of
>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP
>>>>>>>>>>>>>>>>>>>>>>>>>> which CCLKG supports, the PLLP_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Probably, realistically, CPU is always running
>>>>>>>>>>>>>>>>>>>>>>>>>> off a
>>>>>>>>>>>>>>>>>>>>>>>>>> fast PLLX during
>>>>>>>>>>>>>>>>>>>>>>>>>> boot, but I'm wondering what may happen on
>>>>>>>>>>>>>>>>>>>>>>>>>> KEXEC. I
>>>>>>>>>>>>>>>>>>>>>>>>>> guess ideally CPUFreq driver should also have a
>>>>>>>>>>>>>>>>>>>>>>>>>> 'shutdown' callback to teardown DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>> on a reboot, but likely that there are other
>>>>>>>>>>>>>>>>>>>>>>>>>> clock-related problems as
>>>>>>>>>>>>>>>>>>>>>>>>>> well that may break KEXEC and thus it is not
>>>>>>>>>>>>>>>>>>>>>>>>>> very
>>>>>>>>>>>>>>>>>>>>>>>>>> important at the
>>>>>>>>>>>>>>>>>>>>>>>>>> moment.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> [snip]
>>>>>>>>>>>>>>>>>>>>>>>>> During bootup CPUG sources from PLL_X. By PLL_P
>>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>>> above I meant
>>>>>>>>>>>>>>>>>>>>>>>>> PLL_P_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> As per clock policies, PLL_X is always used
>>>>>>>>>>>>>>>>>>>>>>>>> for high
>>>>>>>>>>>>>>>>>>>>>>>>> freq
>>>>>>>>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>>>>>>>>>> 800Mhz
>>>>>>>>>>>>>>>>>>>>>>>>> and for low frequency it will be sourced from
>>>>>>>>>>>>>>>>>>>>>>>>> PLLP.
>>>>>>>>>>>>>>>>>>>>>>>> Alright, then please don't forget to
>>>>>>>>>>>>>>>>>>>>>>>> pre-initialize
>>>>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate to a
>>>>>>>>>>>>>>>>>>>>>>>> reasonable value using tegra_clk_init_table or
>>>>>>>>>>>>>>>>>>>>>>>> assigned-clocks.
>>>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate update is not needed as it is
>>>>>>>>>>>>>>>>>>>>>>> safe to
>>>>>>>>>>>>>>>>>>>>>>> run at
>>>>>>>>>>>>>>>>>>>>>>> 408Mhz because it is below fmax @ Vmin
>>>>>>>>>>>>>>>>>>>>>> So even 204MHz CVB entries are having the same
>>>>>>>>>>>>>>>>>>>>>> voltage as
>>>>>>>>>>>>>>>>>>>>>> 408MHz, correct? It's not instantly obvious to me
>>>>>>>>>>>>>>>>>>>>>> from the
>>>>>>>>>>>>>>>>>>>>>> DFLL driver's code where the fmax @ Vmin is defined,
>>>>>>>>>>>>>>>>>>>>>> I see
>>>>>>>>>>>>>>>>>>>>>> that there is the min_millivolts
>>>>>>>>>>>>>>>>>>>>>> and frequency entries starting from 204MHZ defined
>>>>>>>>>>>>>>>>>>>>>> per-table.
>>>>>>>>>>>>>>>>>>>>> Yes at Vmin CPU Fmax is ~800Mhz. So anything below
>>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>>>>>>>> work at Vmin voltage and PLLP max is 408Mhz.
>>>>>>>>>>>>>>>>>>>> Thank you for the clarification. It would be good
>>>>>>>>>>>>>>>>>>>> to have
>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>> commented
>>>>>>>>>>>>>>>>>>>> in the code as well.
>>>>>>>>>>>>>>>>>>> OK, Will add...
>>>>>>>>>>>>>>>>>> Regarding, adding suspend/resume to CPUFreq, CPUFreq
>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>> happens very early even before disabling non-boot
>>>>>>>>>>>>>>>>>> CPUs and
>>>>>>>>>>>>>>>>>> also
>>>>>>>>>>>>>>>>>> need to export clock driver APIs to CPUFreq.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Was thinking of below way of implementing this...
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Clock DFLL driver Suspend:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> - Save CPU clock policy registers, and
>>>>>>>>>>>>>>>>>> Perform
>>>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>>>> suspend which sets in open loop mode
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> CPU Freq driver Suspend: does nothing
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Clock DFLL driver Resume:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> - Re-init DFLL, Set in Open-Loop mode,
>>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>> Clock policy registers which actually sets source to
>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>> along
>>>>>>>>>>>>>>>>>> with other CPU Policy register restore.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> CPU Freq driver Resume:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> - do clk_prepare_enable which acutally
>>>>>>>>>>>>>>>>>> sets
>>>>>>>>>>>>>>>>>> DFLL in
>>>>>>>>>>>>>>>>>> Closed loop mode
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Adding one more note: Switching CPU Clock to PLLP is not
>>>>>>>>>>>>>>>>>> needed
>>>>>>>>>>>>>>>>>> as CPU CLock can be from dfll in open-loop mode as DFLL
>>>>>>>>>>>>>>>>>> is not
>>>>>>>>>>>>>>>>>> disabled anywhere throught the suspend/resume path
>>>>>>>>>>>>>>>>>> and SC7
>>>>>>>>>>>>>>>>>> entry
>>>>>>>>>>>>>>>>>> FW and Warm boot code will switch CPU source to PLLP.
>>>>>>>>>>>>>>>> Since CPU resumes on PLLP, it will be cleaner to suspend
>>>>>>>>>>>>>>>> it on
>>>>>>>>>>>>>>>> PLLP as well. And besides, seems that currently disabling
>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>> clock will disable DFLL completely and then you'd want to
>>>>>>>>>>>>>>>> re-init
>>>>>>>>>>>>>>>> the DFLL on resume any ways. So better to just disable
>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>> completely on suspend, which should happen on
>>>>>>>>>>>>>>>> clk_disable(dfll).
>>>>>>>>>>>>>>> Will switch to PLLP during CPUFreq suspend. With
>>>>>>>>>>>>>>> decision of
>>>>>>>>>>>>>>> using
>>>>>>>>>>>>>>> clk_disable during suspend, its mandatory to switch to
>>>>>>>>>>>>>>> PLLP as
>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>> is completely disabled.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> My earlier concern was on restoring CPU policy as we
>>>>>>>>>>>>>>> can't do
>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>> from CPUFreq driver and need export from clock driver.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Clear now and will do CPU clock policy restore in after
>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>> re-init.
>>>>>>>>>>>>>> Why the policy can't be saved/restored by the CaR driver
>>>>>>>>>>>>>> as a
>>>>>>>>>>>>>> context of any other clock?
>>>>>>>>>>>>> restoring cpu clock policy involves programming source and
>>>>>>>>>>>>> super_cclkg_divider.
>>>>>>>>>>>>>
>>>>>>>>>>>>> cclk_g is registered as clk_super_mux and it doesn't use
>>>>>>>>>>>>> frac_div ops
>>>>>>>>>>>>> to do save/restore its divider.
>>>>>>>>>>>> That can be changed of course and I guess it also could be as
>>>>>>>>>>>> simple as
>>>>>>>>>>>> saving and restoring of two raw u32 values of the
>>>>>>>>>>>> policy/divider
>>>>>>>>>>>> registers.
>>>>>>>>>>>>
>>>>>>>>>>>>> Also, during clock context we cant restore cclk_g as cclk_g
>>>>>>>>>>>>> source
>>>>>>>>>>>>> will be dfll and dfll will not be resumed/re-initialized
>>>>>>>>>>>>> by the
>>>>>>>>>>>>> time
>>>>>>>>>>>>> clk_super_mux save/restore happens.
>>>>>>>>>>>>>
>>>>>>>>>>>>> we can't use save/restore context for dfll clk_ops because
>>>>>>>>>>>>> dfllCPU_out parent to CCLK_G is first in the clock tree and
>>>>>>>>>>>>> dfll_ref
>>>>>>>>>>>>> and dfll_soc peripheral clocks are not restored by the
>>>>>>>>>>>>> time dfll
>>>>>>>>>>>>> restore happens. Also dfll peripheral clock enables need
>>>>>>>>>>>>> to be
>>>>>>>>>>>>> restored before dfll restore happens which involves
>>>>>>>>>>>>> programming
>>>>>>>>>>>>> dfll
>>>>>>>>>>>>> controller for re-initialization.
>>>>>>>>>>>>>
>>>>>>>>>>>>> So dfll resume/re-init is done in clk-tegra210 at end of all
>>>>>>>>>>>>> clocks
>>>>>>>>>>>>> restore in V5 series but instead of in clk-tegra210 driver I
>>>>>>>>>>>>> moved
>>>>>>>>>>>>> now to dfll-fcpu driver pm_ops as all dfll dependencies
>>>>>>>>>>>>> will be
>>>>>>>>>>>>> restored thru clk_restore_context by then. This will be in
>>>>>>>>>>>>> V6.
>>>>>>>>>>>> Since DFLL is now guaranteed to be disabled across CaR
>>>>>>>>>>>> suspend/resume
>>>>>>>>>>>> (hence it has nothing to do in regards to CCLK) and given that
>>>>>>>>>>>> PLLs
>>>>>>>>>>>> state is restored before the rest of the clocks, I don't
>>>>>>>>>>>> see why
>>>>>>>>>>>> not to
>>>>>>>>>>>> implement CCLK save/restore in a generic fasion. CPU policy
>>>>>>>>>>>> wull be
>>>>>>>>>>>> restored to either PLLP or PLLX (if CPUFreq driver is
>>>>>>>>>>>> disabled).
>>>>>>>>>>>>
>>>>>>>>>>> CCLK_G save/restore should happen in clk_super_mux ops
>>>>>>>>>>> save/context and
>>>>>>>>>>> clk_super_mux save/restore happens very early as cclk_g is
>>>>>>>>>>> first
>>>>>>>>>>> in the
>>>>>>>>>>> clock tree and save/restore traverses through the tree
>>>>>>>>>>> top-bottom
>>>>>>>>>>> order.
>>>>>>>>>> If CCLK_G is restored before the PLLs, then just change the
>>>>>>>>>> clocks
>>>>>>>>>> order
>>>>>>>>>> such that it won't happen.
>>>>>>>>>>
>>>>>>>>> I dont think we can change clocks order for CCLK_G.
>>>>>>>>>
>>>>>>>>> During bootup, cclk_g is registered after all pll's and
>>>>>>>>> peripheral
>>>>>>>>> clocks which is the way we wanted, So cclk_g will be the first
>>>>>>>>> one in
>>>>>>>>> the clk list as clk_register adds new clock first in the list.
>>>>>>>>>
>>>>>>>>> When clk_save_context and clk_restore_context APIs iterates
>>>>>>>>> over the
>>>>>>>>> list, cclk_g is the first
>>>>>>>> Looking at clk_core_restore_context(), I see that it walks up CLKs
>>>>>>>> list
>>>>>>>> from parent to children, hence I don't understand how it can ever
>>>>>>>> happen
>>>>>>>> that CCLK will be restored before the parent. The clocks
>>>>>>>> registration
>>>>>>>> order doesn't matter at all in that case.
>>>>>>> yes from parent to children and dfllCPU_out is the top in the
>>>>>>> list and
>>>>>>> its child is cclk_g.
>>>>>>>
>>>>>>> the way clocks are registered is the order I see in the clock
>>>>>>> list and
>>>>>>> looking into clk_register API it adds new node first in the list.
>>>>>>>
>>>>>> cclkg_g & dfll register happens after all plls and peripheral
>>>>>> clocks as
>>>>>> it need ref, soc and peripheral clocks to be enabled.
>>>>>>> So they are the last to get registered and so becomes first in the
>>>>>>> list.
>>>>>>>
>>>>>>> During save/restore context, it traverses thru this list and
>>>>>>> first in
>>>>>>> the list is dfllcpu_OUT (parent) and its child (cclk_g)
>>>>>>>
>>>>>>> saving should not be an issue at all but we cant restore
>>>>>>> cclk_g/dfll
>>>>>>> in normal way thru clk_ops restore as plls and peripherals restore
>>>>>>> doesn't happen by that time.
>>>>>>>
>>>>>> I was referring to clk_restore_context where it iterates thru
>>>>>> root list
>>>>>> and for each core from the root list clk_core_restore does
>>>>>> restore of
>>>>>> parent and children.
>>>>>>
>>>>>> dfllCPU_Out gets first in the list and its child is cclk_g
>>>>>>
>>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/clk/clk.c#L1105
>>>>>>
>>>>> What list you're talking about? clk_summary? It shows current
>>>>> *active*
>>>>> clocks configuration, if you'll try to disable CPUFreq driver then
>>>>> the
>>>>> parent of CCLK_G should be PLLX. Similarly when CPU is reparented to
>>>>> PLLP on driver's suspend, then PLLP is the parent.
>>>>>
>>>>>>>>>>> DFLL enable thru CPUFreq resume happens after all
>>>>>>>>>>> clk_restore_context
>>>>>>>>>>> happens. So during clk_restore_context, dfll re-init doesnt
>>>>>>>>>>> happen
>>>>>>>>>>> and
>>>>>>>>>>> doing cpu clock policy restore during super_mux clk_ops will
>>>>>>>>>>> crash as
>>>>>>>>>>> DFLL is not initialized and its clock is not enabled but CPU
>>>>>>>>>>> clock
>>>>>>>>>>> restore sets source to DFLL if we restore during super_clk_mux
>>>>>>>>>> If CPU was suspended on PLLP, then it will be restored on
>>>>>>>>>> PLLP by
>>>>>>>>>> CaR. I
>>>>>>>>>> don't understand what DFLL has to do with the CCLK in that case
>>>>>>>>>> during
>>>>>>>>>> the clocks restore.
>>>>>>>>> My above comment is in reference to your request of doing
>>>>>>>>> save/restore
>>>>>>>>> for cclk_g in normal fashion thru save/restore context. Because
>>>>>>>>> of the
>>>>>>>>> clk order I mentioned above, we cclk_g will be the first one to
>>>>>>>>> go thru
>>>>>>>>> save/context.
>>>>>>>>>
>>>>>>>>> During save_context of cclk_g, source can be from PLLX, dfll.
>>>>>>>>>
>>>>>>>>> Issue will be when we do restore during clk_restore_context of
>>>>>>>>> cclk_g as
>>>>>>>>> by that time PLLX/dfll will not be restored.
>>>>>>>>>
>>>>>>>> Seems we already agreed that DFLL will be disabled by the CPUFreq
>>>>>>>> driver
>>>>>>>> on suspend. Hence CCLK can't be from DFLL if CPU is reparented to
>>>>>>>> PLLP
>>>>>>>> on CPUFreq driver's suspend, otherwise CPU keeps running from a
>>>>>>>> boot-state PLLX if CPUFreq driver is disabled.
>>>>>>> Yes suspend should not be an issue but issue will be during resume
>>>>>>> where if we do cclk_g restore in normal way thru
>>>>>>> clk_restore_context,
>>>>>>> cclk_g restore happens very early as dfllCPU out is the first
>>>>>>> one that
>>>>>>> goes thru restore context and plls/peripherals are not resumed by
>>>>>>> then.
>>>>>>>
>>>>>>> CPU runs from PLLX if dfll clock enable fails during boot. So
>>>>>>> when it
>>>>>>> gets to suspend, we save CPU running clock source as either PLLX or
>>>>>>> DFLL and then we switch to PLLP.
>>>>>>>
>>>>>>>
>>>>>>> On resume, CPU runs from PLLP by warm boot code and we need to
>>>>>>> restore
>>>>>>> back its source to the one it was using from saved source context
>>>>>>> (which can be either PLLX or DFLL)
>>>>>>>
>>>>>>> So PLLs & DFLL resume need to happen before CCLKG restore/resume.
>>>>>>>
>>>>>>>
>>>>>>> With all above discussions, we do DFLL disable in CPUFreq driver on
>>>>>>> suspend and on CPUFreq resume we enable DFLL back and restore CPU
>>>>>>> clock source it was using during suspend (which will be either
>>>>>>> PLLX if
>>>>>>> dfll enable fails during probe or it will be using DFLL).
>>>>> During suspend CPU's parent shall be PLLP and not DFLL (note that
>>>>> it is
>>>>> disabled) after reparenting to PLLP by the CPUFreq driver.
>>>>>
>>>> CPU source context should be saved before switching to safe source of
>>>> PLLP as on resume we need to restore back to source it was using
>>>> before we switch to safe source during suspend entry.
>>>>
>>>> So saved context for CPU Source will be either dfll or PLLX
>>>>
>>> PLLP reparenting is only during suspend/entry to have it as safe source
>>> but actual CPU source it was running from before suspending is either
>>> dfll/pllx which should be the one to be restored on CPUFreq resume.
>>> Resume happens with CPU running from PLLP till it gets to the point of
>>> restoring its original source (dfll or pllx)
>> CaR should restore CPU to PLLP or PLLX, while CPUFreq driver restores
>> CPU to DFLL. Please see more comments below.
>>
>>>>>>> So i was trying to say dfll/cclk_g restore can't be done in
>>>>>>> normal way
>>>>>>> thru clk_ops save/restore context
>>>>> Let's see what happens if CPUFreq is active:
>>>>>
>>>>> 1. CPUFreq driver probe happens
>>>>> 2. CPU is reparented to PLLP
>>>>> 3. DFLL inited
>>>>> 4. CPU is reparented to DFLL
>>>>>
>>>>> 5. CPUFreq driver suspend happens
>>>>> 6. CPU is reparented to PLLP
>>>>> 7. DFLL is disabled
>>>>>
>>>>> 8. Car suspend happens
>>>>> 9. DFLL context saved
>>>>> 10. PLLP/PLLX context saved
>>>>> 11. CCLK context saved
>>>>>
>>>>> 12. Car resume happens
>>>>> 13. DFLL context restored
>>>>> 14. PLLP/PLLX context restored
>>>>> 15. CCLK context restored
>>>>>
>>>>> 16. CPUFreq driver resume happens
>>>>> 17. DFLL re-inited
>>>>> 18. CPU is reparented to DFLL
>>>>
>>>> Below is the order of sequence it should be based on the order of clk
>>>> register.
>>>>
>>>> My comments inline in this sequence.
>>>>
>>>> 1. CPUFreq driver probe happens
>>>> 2. CPU is reparented to PLLP
>>>> 3. DFLL inited
>>>> 4. CPU is reparented to DFLL
>>>>
>>>>
>>>> 5. CPUFreq driver suspend happens
>>>> 6. Save CPU source which could be either dfll or pllx
>> Please see my next comment.
>>
>>>> 7. CPU is reparented to safe known source PLLP
>>>> 8. DFLL is disabled
>>>>
>>>> 8. Car suspend happens
>>>> 9. DFLL context saved (With DFLL disabled in CPUFreq suspend,
>>>> nothing to be saved here as last freq req will always be saved).
>>>> 10. CCLK context saved (CPU clock source will be saved in CPUFreq
>>>> driver suspend which could be either dfll or pllx)
>> That I don't understand. The CPU's clock source state should be saved at
>> the moment of the CaR's suspending (i.e. CCLK policy will be set to PLLP
>> or PLLX) and then CCLK state should be also restored by the CaR in
>> step 14.
>
> CPU clock to be saved and restored should be the source used before we
> switch it to safe PLLP for suspend/resume operation.
>
> This original source could be either PLLX or DFLL which it was using
> before we disable DFLL during CPU Freq suspend.
>
> If we save CPU clock source at moment of CAR suspending, it will be
> PLLP as we switch to safe PLLP in CPUFreq driver suspend.
>
> Infact, we dont need to restore CPU clock source to PLLP anywhere in
> resume as it comes up with PLLP source from warm boot code itself.
>
> But we need to restore CPU source to original source it was using
> before we switch to safe PLLP source for suspend operation. This
> original source could be PLLX/DFLL and this should be re-stored in
> CPUFreq resume as by this time PLLs and peripherals are restored and
> dfll is re-initialized.
>
> So saving actual CPU source before switching to intermediate safe PLLP
> in CPUFreq driver and then restoring back during CPUFreq resume should
> be good as CPUFreq resume happens right after all clocks (plls
> restore, peripherals restore, dfll resume)
>> CPUFreq driver should only switch CPU to PLLP and disable DFLL on
>> suspend in step 5, that's it. On resume CPUFreq driver will restore CPU
>> to DFLL in step 18.
> Also I don't think we should hard-code to force CPU source to DFLL on
> CPUFreq resume.
>
> Reason is during CPU Probe when it tries to switch to dfll source, for
> some reason if dfll enable fails it sets CPU to its original source
> which will be PLLX.
>
> So CPU source could be either DFLL or PLLX in CPUFreq
> tegra124_cpu_switch_to_dfll
>
>>>> 11. PLLP/PLLX context saved
>>>> 12. Peripheral Clock saved
>>>>
>>>> 12. Car resume happens
>>>> 13. DFLL context restored : No DFLL context to be restored and we
>>>> only need to reinitialize DFLL and re-initialize can't be done here as
>>>> this is the 1st to get restored and PLL/Peripheral clocks are not
>>>> restored by this time. So we can't use clk_ops restore for DFLL
>> It looks to me that clk_core_restore_context() should just do
>> hlist_for_each_entry *_reverse*. Don't you think so?
>
> Thought of that but this is in core driver and is used by other
> non-tegra clock driver and not sure if that impacts for those.
>
> But with decision of switching CPUFreq with dfll clock enable/disable
> during CPUFreq suspend/resume, we can re-init dfll during dfll-fcpu
> driver resume and we don't need CCLK save/restore.
>
the way of all clocks order is good except cclk_g which has dependency
on multiple clocks.
reverse list order during restore might not work as all other clocks are
in proper order no with any ref clocks for plls getting restored prior
to their clients
>>>> 14. CCLK context restored
>>>> CCLK cant be restored here as context could be either dfll or pllx
>>>> which is the source orginally it was actually using before we force
>>>> switch to safe PLLP for suspend entry. So we can't use clk_ops restore
>>>> for DFLL
>> See my comment to step 10. CCLK should be restored to the *CaR's saved*
>> context, which is either PLLX or PLLP policy.
>>
>>>> 15. PLLP/PLLX context restored
>>>> 16. Peripheral context restored
>>>>
>>>> 16. CPUFreq driver resume happens
>>>> 17. DFLL re-inited (Invoking DFLL re-init in CPUFreq resume need
>>>> exporting DFLL reinit from Clock driver to CPUFreq driver)
>> Will be nice if clk_enable(dfll) could be enough to re-init DFLL. That
>> should achievable with my next comment to step 18.
>>
>>>> 18. CPU is reparented to DFLL or PLLX based on saved context from
>>>> step 9.
>>>>
>>>> Note: instead of exporting, we can do DFLL re-init from clock-dfll
>>>> driver itself thru dfll-fcpu pm_ops resume. So dfll will be
>>>> re-initialized by the time CPUFreq driver resumes and switches to use
>>>> DFLL source.
>>>>
>> Yes, I guess DFLL hardware should be fully reset on DFLL's driver resume
>> to be on a safe side any ways.
>>
>> But(!) we could probably just fix clk_core_restore_context(), like I
>> suggested in step 13. Then DFLL clock could use generic save / restore
>> context and CPUFreq driver won't have to do anything at all because DFLL
>> clock will be saved first and resumed *after* all of the peripherals by
>> the CCF. In the end CCLK will be switched to DFLL by the CCF restore as
>> well.
>
^ permalink raw reply
* Re: [PATCH V5 11/18] clk: tegra210: Add support for Tegra210 clocks
From: Sowjanya Komatineni @ 2019-07-17 21:51 UTC (permalink / raw)
To: Dmitry Osipenko
Cc: Peter De Schrijver, Joseph Lo, thierry.reding, jonathanh, tglx,
jason, marc.zyngier, linus.walleij, stefan, mark.rutland,
pgaikwad, sboyd, linux-clk, linux-gpio, jckuo, talho, linux-tegra,
linux-kernel, mperttunen, spatra, robh+dt, devicetree
In-Reply-To: <b01e37aa-f14e-e628-ceef-b25a845c6359@gmail.com>
On 7/17/19 2:30 PM, Dmitry Osipenko wrote:
> 17.07.2019 23:11, Sowjanya Komatineni пишет:
>> On 7/17/19 1:01 PM, Sowjanya Komatineni wrote:
>>> On 7/17/19 12:43 PM, Dmitry Osipenko wrote:
>>>> 17.07.2019 21:54, Sowjanya Komatineni пишет:
>>>>> On 7/17/19 11:51 AM, Sowjanya Komatineni wrote:
>>>>>> On 7/17/19 11:32 AM, Dmitry Osipenko wrote:
>>>>>>> 17.07.2019 20:29, Sowjanya Komatineni пишет:
>>>>>>>> On 7/17/19 8:17 AM, Dmitry Osipenko wrote:
>>>>>>>>> 17.07.2019 9:36, Sowjanya Komatineni пишет:
>>>>>>>>>> On 7/16/19 11:33 PM, Dmitry Osipenko wrote:
>>>>>>>>>>> В Tue, 16 Jul 2019 22:55:52 -0700
>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>
>>>>>>>>>>>> On 7/16/19 10:42 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>> В Tue, 16 Jul 2019 22:25:25 -0700
>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>> On 7/16/19 9:11 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>> В Tue, 16 Jul 2019 19:35:49 -0700
>>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>>> On 7/16/19 7:18 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>> On 7/16/19 3:06 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>> On 7/16/19 3:00 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>> 17.07.2019 0:35, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>> On 7/16/19 2:21 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>> 17.07.2019 0:12, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 1:47 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 22:26, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:43 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:30, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:25 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:19, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 9:50 AM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 8:00 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 11:06, Peter De Schrijver пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2019 at 03:24:26PM +0800,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Joseph
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Lo wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OK, Will add to CPUFreq driver...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The other thing that also need
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> attention is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> that T124 CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicitly relies on DFLL driver to be
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> first, which is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> icky.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Should I add check for successful dfll clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> register explicitly in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver probe and defer till dfll
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> registers?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Probably you should use the "device links".
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> See
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1][2] for the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> example.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/gpu/drm/tegra/dc.c#L2383
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [2]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://www.kernel.org/doc/html/latest/driver-api/device_link.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Return EPROBE_DEFER instead of EINVAL if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device_link_add() fails.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use of_find_device_by_node() to get the DFLL's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device, see [3].
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [3]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/devfreq/tegra20-devfreq.c#n100
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Will go thru and add...
>>>>>>>>>>>>>>>>>>>>>>>>>>> Looks like I initially confused this case with
>>>>>>>>>>>>>>>>>>>>>>>>>>> getting
>>>>>>>>>>>>>>>>>>>>>>>>>>> orphaned clock.
>>>>>>>>>>>>>>>>>>>>>>>>>>> I'm now seeing that the DFLL driver registers the
>>>>>>>>>>>>>>>>>>>>>>>>>>> clock and then
>>>>>>>>>>>>>>>>>>>>>>>>>>> clk_get(dfll) should be returning EPROBE_DEFER
>>>>>>>>>>>>>>>>>>>>>>>>>>> until
>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL driver is
>>>>>>>>>>>>>>>>>>>>>>>>>>> probed, hence everything should be fine as-is and
>>>>>>>>>>>>>>>>>>>>>>>>>>> there is no real
>>>>>>>>>>>>>>>>>>>>>>>>>>> need
>>>>>>>>>>>>>>>>>>>>>>>>>>> for the 'device link'. Sorry for the confusion!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, I didn't follow the mail thread. Just
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regarding the DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> part.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> As you know it, the DFLL clock is one of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock sources and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integrated with DVFS control logic with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator. We will not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to other clock sources once we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switched to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL. Because the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU has
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> been regulated by the DFLL HW with the DVFS
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (CVB or OPP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> you see
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> in the driver.). We shouldn't reparent it to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> other sources with
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unknew
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> freq/volt pair. That's not guaranteed to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> work. We
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allow switching to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> open-loop mode but different sources.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay, then the CPUFreq driver will have to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rate before switching to PLLP in order to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper CPU voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP freq is safe to work for any CPU voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> So no
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to PLLP rate before changing CCLK_G
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> to PLLP during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, please ignore my above comment. During
>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend, need to change
>>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK_G source to PLLP when dfll is in closed
>>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode first and
>>>>>>>>>>>>>>>>>>>>>>>>>>>> then
>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll need to be set to open loop.
>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And I don't exactly understand why we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to PLLP in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> idle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver. Just keep it on CL-DVFS mode all the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> time.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 entry, the dfll suspend function
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moves it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the open-loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode. That's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all. The sc7-entryfirmware will handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the rest
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn off
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU power.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 resume, the warmboot code will handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator and power up the CPU cluster. And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> leave
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it on PLL_P.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> After
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resuming to the kernel, we re-init DFLL,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> policy (CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> runs on DFLL open-loop mode) and then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moving to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> close-loop mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL is re-inited after switching CCLK to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> early clocks-state restoring by CaR driver.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hence
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> instead of having
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> odd
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hacks in the CaR driver, it is much nicer to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper suspend-resume sequencing of the device
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> drivers. In this case
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver is the driver that enables DFLL and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switches
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to that
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source, which means that this driver is also
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> be responsible for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> management of the DFLL's state during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend/resume process. If
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver disables DFLL during suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> re-enables it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resume, then looks like the CaR driver hacks
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> around
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL are not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> needed.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL part looks good to me. BTW,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> change the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> patch subject to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "Add
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend-resume support" seems more
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> me.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> To clarify this, the sequences for DFLL use
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> are as
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> follows (assuming
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> required DFLL hw configuration has been done)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch to DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Save current parent and frequency
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2) Enable DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3) Change cclk_g parent to DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For OVR regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Change PWM output pin from tristate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 5) Enable DFLL PWM output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For I2C regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Enable DFLL I2C output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 6) Program DFLL to closed loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch away from DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Change cclk_g parent to PLLP so the CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> frequency is ok for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> any
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> vdd_cpu voltage
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>> I see during switch away from DFLL (suspend),
>>>>>>>>>>>>>>>>>>>>>>>>>>>> cclk_g
>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent is not
>>>>>>>>>>>>>>>>>>>>>>>>>>>> changed to PLLP before changing dfll to open
>>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Will add this ...
>>>>>>>>>>>>>>>>>>>>>>>>>>> The CPUFreq driver switches parent to PLLP during
>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>> probe, similar
>>>>>>>>>>>>>>>>>>>>>>>>>>> should be done on suspend.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> I'm also wondering if it's always safe to
>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to
>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP in the probe.
>>>>>>>>>>>>>>>>>>>>>>>>>>> If CPU is running on a lower freq than PLLP, then
>>>>>>>>>>>>>>>>>>>>>>>>>>> some
>>>>>>>>>>>>>>>>>>>>>>>>>>> other more
>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate intermediate parent should be
>>>>>>>>>>>>>>>>>>>>>>>>>>> selected.
>>>>>>>>>>>>>>>>>>>>>>>>>> CPU parents are PLL_X, PLL_P, and dfll. PLL_X
>>>>>>>>>>>>>>>>>>>>>>>>>> always
>>>>>>>>>>>>>>>>>>>>>>>>>> runs at higher
>>>>>>>>>>>>>>>>>>>>>>>>>> rate
>>>>>>>>>>>>>>>>>>>>>>>>>> so switching to PLL_P during CPUFreq probe
>>>>>>>>>>>>>>>>>>>>>>>>>> prior to
>>>>>>>>>>>>>>>>>>>>>>>>>> dfll clock enable
>>>>>>>>>>>>>>>>>>>>>>>>>> should be safe.
>>>>>>>>>>>>>>>>>>>>>>>>> AFAIK, PLLX could run at ~200MHz. There is also a
>>>>>>>>>>>>>>>>>>>>>>>>> divided output of
>>>>>>>>>>>>>>>>>>>>>>>>> PLLP
>>>>>>>>>>>>>>>>>>>>>>>>> which CCLKG supports, the PLLP_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Probably, realistically, CPU is always running
>>>>>>>>>>>>>>>>>>>>>>>>> off a
>>>>>>>>>>>>>>>>>>>>>>>>> fast PLLX during
>>>>>>>>>>>>>>>>>>>>>>>>> boot, but I'm wondering what may happen on KEXEC. I
>>>>>>>>>>>>>>>>>>>>>>>>> guess ideally CPUFreq driver should also have a
>>>>>>>>>>>>>>>>>>>>>>>>> 'shutdown' callback to teardown DFLL
>>>>>>>>>>>>>>>>>>>>>>>>> on a reboot, but likely that there are other
>>>>>>>>>>>>>>>>>>>>>>>>> clock-related problems as
>>>>>>>>>>>>>>>>>>>>>>>>> well that may break KEXEC and thus it is not very
>>>>>>>>>>>>>>>>>>>>>>>>> important at the
>>>>>>>>>>>>>>>>>>>>>>>>> moment.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> [snip]
>>>>>>>>>>>>>>>>>>>>>>>> During bootup CPUG sources from PLL_X. By PLL_P
>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>> above I meant
>>>>>>>>>>>>>>>>>>>>>>>> PLL_P_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> As per clock policies, PLL_X is always used for high
>>>>>>>>>>>>>>>>>>>>>>>> freq
>>>>>>>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>>>>>>>>> 800Mhz
>>>>>>>>>>>>>>>>>>>>>>>> and for low frequency it will be sourced from PLLP.
>>>>>>>>>>>>>>>>>>>>>>> Alright, then please don't forget to pre-initialize
>>>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate to a
>>>>>>>>>>>>>>>>>>>>>>> reasonable value using tegra_clk_init_table or
>>>>>>>>>>>>>>>>>>>>>>> assigned-clocks.
>>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate update is not needed as it is safe to
>>>>>>>>>>>>>>>>>>>>>> run at
>>>>>>>>>>>>>>>>>>>>>> 408Mhz because it is below fmax @ Vmin
>>>>>>>>>>>>>>>>>>>>> So even 204MHz CVB entries are having the same
>>>>>>>>>>>>>>>>>>>>> voltage as
>>>>>>>>>>>>>>>>>>>>> 408MHz, correct? It's not instantly obvious to me
>>>>>>>>>>>>>>>>>>>>> from the
>>>>>>>>>>>>>>>>>>>>> DFLL driver's code where the fmax @ Vmin is defined,
>>>>>>>>>>>>>>>>>>>>> I see
>>>>>>>>>>>>>>>>>>>>> that there is the min_millivolts
>>>>>>>>>>>>>>>>>>>>> and frequency entries starting from 204MHZ defined
>>>>>>>>>>>>>>>>>>>>> per-table.
>>>>>>>>>>>>>>>>>>>> Yes at Vmin CPU Fmax is ~800Mhz. So anything below that
>>>>>>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>>>>>>> work at Vmin voltage and PLLP max is 408Mhz.
>>>>>>>>>>>>>>>>>>> Thank you for the clarification. It would be good to have
>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>> commented
>>>>>>>>>>>>>>>>>>> in the code as well.
>>>>>>>>>>>>>>>>>> OK, Will add...
>>>>>>>>>>>>>>>>> Regarding, adding suspend/resume to CPUFreq, CPUFreq
>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>> happens very early even before disabling non-boot CPUs and
>>>>>>>>>>>>>>>>> also
>>>>>>>>>>>>>>>>> need to export clock driver APIs to CPUFreq.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Was thinking of below way of implementing this...
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Clock DFLL driver Suspend:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> - Save CPU clock policy registers, and
>>>>>>>>>>>>>>>>> Perform
>>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>>> suspend which sets in open loop mode
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> CPU Freq driver Suspend: does nothing
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Clock DFLL driver Resume:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> - Re-init DFLL, Set in Open-Loop mode,
>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>> Clock policy registers which actually sets source to DFLL
>>>>>>>>>>>>>>>>> along
>>>>>>>>>>>>>>>>> with other CPU Policy register restore.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> CPU Freq driver Resume:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> - do clk_prepare_enable which acutally sets
>>>>>>>>>>>>>>>>> DFLL in
>>>>>>>>>>>>>>>>> Closed loop mode
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Adding one more note: Switching CPU Clock to PLLP is not
>>>>>>>>>>>>>>>>> needed
>>>>>>>>>>>>>>>>> as CPU CLock can be from dfll in open-loop mode as DFLL
>>>>>>>>>>>>>>>>> is not
>>>>>>>>>>>>>>>>> disabled anywhere throught the suspend/resume path and SC7
>>>>>>>>>>>>>>>>> entry
>>>>>>>>>>>>>>>>> FW and Warm boot code will switch CPU source to PLLP.
>>>>>>>>>>>>>>> Since CPU resumes on PLLP, it will be cleaner to suspend
>>>>>>>>>>>>>>> it on
>>>>>>>>>>>>>>> PLLP as well. And besides, seems that currently disabling
>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>> clock will disable DFLL completely and then you'd want to
>>>>>>>>>>>>>>> re-init
>>>>>>>>>>>>>>> the DFLL on resume any ways. So better to just disable DFLL
>>>>>>>>>>>>>>> completely on suspend, which should happen on
>>>>>>>>>>>>>>> clk_disable(dfll).
>>>>>>>>>>>>>> Will switch to PLLP during CPUFreq suspend. With decision of
>>>>>>>>>>>>>> using
>>>>>>>>>>>>>> clk_disable during suspend, its mandatory to switch to PLLP as
>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>> is completely disabled.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> My earlier concern was on restoring CPU policy as we can't do
>>>>>>>>>>>>>> that
>>>>>>>>>>>>>> from CPUFreq driver and need export from clock driver.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Clear now and will do CPU clock policy restore in after dfll
>>>>>>>>>>>>>> re-init.
>>>>>>>>>>>>> Why the policy can't be saved/restored by the CaR driver as a
>>>>>>>>>>>>> context of any other clock?
>>>>>>>>>>>> restoring cpu clock policy involves programming source and
>>>>>>>>>>>> super_cclkg_divider.
>>>>>>>>>>>>
>>>>>>>>>>>> cclk_g is registered as clk_super_mux and it doesn't use
>>>>>>>>>>>> frac_div ops
>>>>>>>>>>>> to do save/restore its divider.
>>>>>>>>>>> That can be changed of course and I guess it also could be as
>>>>>>>>>>> simple as
>>>>>>>>>>> saving and restoring of two raw u32 values of the policy/divider
>>>>>>>>>>> registers.
>>>>>>>>>>>
>>>>>>>>>>>> Also, during clock context we cant restore cclk_g as cclk_g
>>>>>>>>>>>> source
>>>>>>>>>>>> will be dfll and dfll will not be resumed/re-initialized by the
>>>>>>>>>>>> time
>>>>>>>>>>>> clk_super_mux save/restore happens.
>>>>>>>>>>>>
>>>>>>>>>>>> we can't use save/restore context for dfll clk_ops because
>>>>>>>>>>>> dfllCPU_out parent to CCLK_G is first in the clock tree and
>>>>>>>>>>>> dfll_ref
>>>>>>>>>>>> and dfll_soc peripheral clocks are not restored by the time dfll
>>>>>>>>>>>> restore happens. Also dfll peripheral clock enables need to be
>>>>>>>>>>>> restored before dfll restore happens which involves programming
>>>>>>>>>>>> dfll
>>>>>>>>>>>> controller for re-initialization.
>>>>>>>>>>>>
>>>>>>>>>>>> So dfll resume/re-init is done in clk-tegra210 at end of all
>>>>>>>>>>>> clocks
>>>>>>>>>>>> restore in V5 series but instead of in clk-tegra210 driver I
>>>>>>>>>>>> moved
>>>>>>>>>>>> now to dfll-fcpu driver pm_ops as all dfll dependencies will be
>>>>>>>>>>>> restored thru clk_restore_context by then. This will be in V6.
>>>>>>>>>>> Since DFLL is now guaranteed to be disabled across CaR
>>>>>>>>>>> suspend/resume
>>>>>>>>>>> (hence it has nothing to do in regards to CCLK) and given that
>>>>>>>>>>> PLLs
>>>>>>>>>>> state is restored before the rest of the clocks, I don't see why
>>>>>>>>>>> not to
>>>>>>>>>>> implement CCLK save/restore in a generic fasion. CPU policy
>>>>>>>>>>> wull be
>>>>>>>>>>> restored to either PLLP or PLLX (if CPUFreq driver is disabled).
>>>>>>>>>>>
>>>>>>>>>> CCLK_G save/restore should happen in clk_super_mux ops
>>>>>>>>>> save/context and
>>>>>>>>>> clk_super_mux save/restore happens very early as cclk_g is first
>>>>>>>>>> in the
>>>>>>>>>> clock tree and save/restore traverses through the tree top-bottom
>>>>>>>>>> order.
>>>>>>>>> If CCLK_G is restored before the PLLs, then just change the clocks
>>>>>>>>> order
>>>>>>>>> such that it won't happen.
>>>>>>>>>
>>>>>>>> I dont think we can change clocks order for CCLK_G.
>>>>>>>>
>>>>>>>> During bootup, cclk_g is registered after all pll's and peripheral
>>>>>>>> clocks which is the way we wanted, So cclk_g will be the first
>>>>>>>> one in
>>>>>>>> the clk list as clk_register adds new clock first in the list.
>>>>>>>>
>>>>>>>> When clk_save_context and clk_restore_context APIs iterates over the
>>>>>>>> list, cclk_g is the first
>>>>>>> Looking at clk_core_restore_context(), I see that it walks up CLKs
>>>>>>> list
>>>>>>> from parent to children, hence I don't understand how it can ever
>>>>>>> happen
>>>>>>> that CCLK will be restored before the parent. The clocks registration
>>>>>>> order doesn't matter at all in that case.
>>>>>> yes from parent to children and dfllCPU_out is the top in the list and
>>>>>> its child is cclk_g.
>>>>>>
>>>>>> the way clocks are registered is the order I see in the clock list and
>>>>>> looking into clk_register API it adds new node first in the list.
>>>>>>
>>>>> cclkg_g & dfll register happens after all plls and peripheral clocks as
>>>>> it need ref, soc and peripheral clocks to be enabled.
>>>>>> So they are the last to get registered and so becomes first in the
>>>>>> list.
>>>>>>
>>>>>> During save/restore context, it traverses thru this list and first in
>>>>>> the list is dfllcpu_OUT (parent) and its child (cclk_g)
>>>>>>
>>>>>> saving should not be an issue at all but we cant restore cclk_g/dfll
>>>>>> in normal way thru clk_ops restore as plls and peripherals restore
>>>>>> doesn't happen by that time.
>>>>>>
>>>>> I was referring to clk_restore_context where it iterates thru root list
>>>>> and for each core from the root list clk_core_restore does restore of
>>>>> parent and children.
>>>>>
>>>>> dfllCPU_Out gets first in the list and its child is cclk_g
>>>>>
>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/clk/clk.c#L1105
>>>> What list you're talking about? clk_summary? It shows current *active*
>>>> clocks configuration, if you'll try to disable CPUFreq driver then the
>>>> parent of CCLK_G should be PLLX. Similarly when CPU is reparented to
>>>> PLLP on driver's suspend, then PLLP is the parent.
>>>>
>>>>>>>>>> DFLL enable thru CPUFreq resume happens after all
>>>>>>>>>> clk_restore_context
>>>>>>>>>> happens. So during clk_restore_context, dfll re-init doesnt happen
>>>>>>>>>> and
>>>>>>>>>> doing cpu clock policy restore during super_mux clk_ops will
>>>>>>>>>> crash as
>>>>>>>>>> DFLL is not initialized and its clock is not enabled but CPU clock
>>>>>>>>>> restore sets source to DFLL if we restore during super_clk_mux
>>>>>>>>> If CPU was suspended on PLLP, then it will be restored on PLLP by
>>>>>>>>> CaR. I
>>>>>>>>> don't understand what DFLL has to do with the CCLK in that case
>>>>>>>>> during
>>>>>>>>> the clocks restore.
>>>>>>>> My above comment is in reference to your request of doing
>>>>>>>> save/restore
>>>>>>>> for cclk_g in normal fashion thru save/restore context. Because
>>>>>>>> of the
>>>>>>>> clk order I mentioned above, we cclk_g will be the first one to
>>>>>>>> go thru
>>>>>>>> save/context.
>>>>>>>>
>>>>>>>> During save_context of cclk_g, source can be from PLLX, dfll.
>>>>>>>>
>>>>>>>> Issue will be when we do restore during clk_restore_context of
>>>>>>>> cclk_g as
>>>>>>>> by that time PLLX/dfll will not be restored.
>>>>>>>>
>>>>>>> Seems we already agreed that DFLL will be disabled by the CPUFreq
>>>>>>> driver
>>>>>>> on suspend. Hence CCLK can't be from DFLL if CPU is reparented to
>>>>>>> PLLP
>>>>>>> on CPUFreq driver's suspend, otherwise CPU keeps running from a
>>>>>>> boot-state PLLX if CPUFreq driver is disabled.
>>>>>> Yes suspend should not be an issue but issue will be during resume
>>>>>> where if we do cclk_g restore in normal way thru clk_restore_context,
>>>>>> cclk_g restore happens very early as dfllCPU out is the first one that
>>>>>> goes thru restore context and plls/peripherals are not resumed by
>>>>>> then.
>>>>>>
>>>>>> CPU runs from PLLX if dfll clock enable fails during boot. So when it
>>>>>> gets to suspend, we save CPU running clock source as either PLLX or
>>>>>> DFLL and then we switch to PLLP.
>>>>>>
>>>>>>
>>>>>> On resume, CPU runs from PLLP by warm boot code and we need to restore
>>>>>> back its source to the one it was using from saved source context
>>>>>> (which can be either PLLX or DFLL)
>>>>>>
>>>>>> So PLLs & DFLL resume need to happen before CCLKG restore/resume.
>>>>>>
>>>>>>
>>>>>> With all above discussions, we do DFLL disable in CPUFreq driver on
>>>>>> suspend and on CPUFreq resume we enable DFLL back and restore CPU
>>>>>> clock source it was using during suspend (which will be either PLLX if
>>>>>> dfll enable fails during probe or it will be using DFLL).
>>>> During suspend CPU's parent shall be PLLP and not DFLL (note that it is
>>>> disabled) after reparenting to PLLP by the CPUFreq driver.
>>>>
>>> CPU source context should be saved before switching to safe source of
>>> PLLP as on resume we need to restore back to source it was using
>>> before we switch to safe source during suspend entry.
>>>
>>> So saved context for CPU Source will be either dfll or PLLX
>>>
>> PLLP reparenting is only during suspend/entry to have it as safe source
>> but actual CPU source it was running from before suspending is either
>> dfll/pllx which should be the one to be restored on CPUFreq resume.
>> Resume happens with CPU running from PLLP till it gets to the point of
>> restoring its original source (dfll or pllx)
> CaR should restore CPU to PLLP or PLLX, while CPUFreq driver restores
> CPU to DFLL. Please see more comments below.
>
>>>>>> So i was trying to say dfll/cclk_g restore can't be done in normal way
>>>>>> thru clk_ops save/restore context
>>>> Let's see what happens if CPUFreq is active:
>>>>
>>>> 1. CPUFreq driver probe happens
>>>> 2. CPU is reparented to PLLP
>>>> 3. DFLL inited
>>>> 4. CPU is reparented to DFLL
>>>>
>>>> 5. CPUFreq driver suspend happens
>>>> 6. CPU is reparented to PLLP
>>>> 7. DFLL is disabled
>>>>
>>>> 8. Car suspend happens
>>>> 9. DFLL context saved
>>>> 10. PLLP/PLLX context saved
>>>> 11. CCLK context saved
>>>>
>>>> 12. Car resume happens
>>>> 13. DFLL context restored
>>>> 14. PLLP/PLLX context restored
>>>> 15. CCLK context restored
>>>>
>>>> 16. CPUFreq driver resume happens
>>>> 17. DFLL re-inited
>>>> 18. CPU is reparented to DFLL
>>>
>>> Below is the order of sequence it should be based on the order of clk
>>> register.
>>>
>>> My comments inline in this sequence.
>>>
>>> 1. CPUFreq driver probe happens
>>> 2. CPU is reparented to PLLP
>>> 3. DFLL inited
>>> 4. CPU is reparented to DFLL
>>>
>>>
>>> 5. CPUFreq driver suspend happens
>>> 6. Save CPU source which could be either dfll or pllx
> Please see my next comment.
>
>>> 7. CPU is reparented to safe known source PLLP
>>> 8. DFLL is disabled
>>>
>>> 8. Car suspend happens
>>> 9. DFLL context saved (With DFLL disabled in CPUFreq suspend,
>>> nothing to be saved here as last freq req will always be saved).
>>> 10. CCLK context saved (CPU clock source will be saved in CPUFreq
>>> driver suspend which could be either dfll or pllx)
> That I don't understand. The CPU's clock source state should be saved at
> the moment of the CaR's suspending (i.e. CCLK policy will be set to PLLP
> or PLLX) and then CCLK state should be also restored by the CaR in step 14.
CPU clock to be saved and restored should be the source used before we
switch it to safe PLLP for suspend/resume operation.
This original source could be either PLLX or DFLL which it was using
before we disable DFLL during CPU Freq suspend.
If we save CPU clock source at moment of CAR suspending, it will be PLLP
as we switch to safe PLLP in CPUFreq driver suspend.
Infact, we dont need to restore CPU clock source to PLLP anywhere in
resume as it comes up with PLLP source from warm boot code itself.
But we need to restore CPU source to original source it was using before
we switch to safe PLLP source for suspend operation. This original
source could be PLLX/DFLL and this should be re-stored in CPUFreq resume
as by this time PLLs and peripherals are restored and dfll is
re-initialized.
So saving actual CPU source before switching to intermediate safe PLLP
in CPUFreq driver and then restoring back during CPUFreq resume should
be good as CPUFreq resume happens right after all clocks (plls restore,
peripherals restore, dfll resume)
> CPUFreq driver should only switch CPU to PLLP and disable DFLL on
> suspend in step 5, that's it. On resume CPUFreq driver will restore CPU
> to DFLL in step 18.
Also I don't think we should hard-code to force CPU source to DFLL on
CPUFreq resume.
Reason is during CPU Probe when it tries to switch to dfll source, for
some reason if dfll enable fails it sets CPU to its original source
which will be PLLX.
So CPU source could be either DFLL or PLLX in CPUFreq
tegra124_cpu_switch_to_dfll
>>> 11. PLLP/PLLX context saved
>>> 12. Peripheral Clock saved
>>>
>>> 12. Car resume happens
>>> 13. DFLL context restored : No DFLL context to be restored and we
>>> only need to reinitialize DFLL and re-initialize can't be done here as
>>> this is the 1st to get restored and PLL/Peripheral clocks are not
>>> restored by this time. So we can't use clk_ops restore for DFLL
> It looks to me that clk_core_restore_context() should just do
> hlist_for_each_entry *_reverse*. Don't you think so?
Thought of that but this is in core driver and is used by other
non-tegra clock driver and not sure if that impacts for those.
But with decision of switching CPUFreq with dfll clock enable/disable
during CPUFreq suspend/resume, we can re-init dfll during dfll-fcpu
driver resume and we don't need CCLK save/restore.
>>> 14. CCLK context restored
>>> CCLK cant be restored here as context could be either dfll or pllx
>>> which is the source orginally it was actually using before we force
>>> switch to safe PLLP for suspend entry. So we can't use clk_ops restore
>>> for DFLL
> See my comment to step 10. CCLK should be restored to the *CaR's saved*
> context, which is either PLLX or PLLP policy.
>
>>> 15. PLLP/PLLX context restored
>>> 16. Peripheral context restored
>>>
>>> 16. CPUFreq driver resume happens
>>> 17. DFLL re-inited (Invoking DFLL re-init in CPUFreq resume need
>>> exporting DFLL reinit from Clock driver to CPUFreq driver)
> Will be nice if clk_enable(dfll) could be enough to re-init DFLL. That
> should achievable with my next comment to step 18.
>
>>> 18. CPU is reparented to DFLL or PLLX based on saved context from
>>> step 9.
>>>
>>> Note: instead of exporting, we can do DFLL re-init from clock-dfll
>>> driver itself thru dfll-fcpu pm_ops resume. So dfll will be
>>> re-initialized by the time CPUFreq driver resumes and switches to use
>>> DFLL source.
>>>
> Yes, I guess DFLL hardware should be fully reset on DFLL's driver resume
> to be on a safe side any ways.
>
> But(!) we could probably just fix clk_core_restore_context(), like I
> suggested in step 13. Then DFLL clock could use generic save / restore
> context and CPUFreq driver won't have to do anything at all because DFLL
> clock will be saved first and resumed *after* all of the peripherals by
> the CCF. In the end CCLK will be switched to DFLL by the CCF restore as
> well.
^ permalink raw reply
* Re: [v5 1/7] drm/mediatek: move mipi_dsi_host_register to probe
From: Ryan Case @ 2019-07-17 21:48 UTC (permalink / raw)
To: CK Hu
Cc: Jitao Shi, Mark Rutland, devicetree, David Airlie, stonea168,
dri-devel, yingjoe.chen, Ajay Kumar, Vincent Palatin, cawa.cheng,
bibby.hsieh, Russell King, Thierry Reding, linux-pwm,
Sascha Hauer, Pawel Moll, Ian Campbell, Inki Dae, Rob Herring,
linux-mediatek, Andy Yan, Matthias Brugger, eddie.hua
In-Reply-To: <1561702259.18399.7.camel@mtksdaap41>
On Thu, Jun 27, 2019 at 11:11 PM CK Hu <ck.hu@mediatek.com> wrote:
>
> Hi, Jitao:
>
> On Thu, 2019-06-27 at 16:01 +0800, Jitao Shi wrote:
> > DSI panel driver need attach function which is inculde in
> > mipi_dsi_host_ops.
> >
> > If mipi_dsi_host_register is not in probe, dsi panel will
> > probe more delay.
> >
> > So move the mipi_dsi_host_register to probe from bind.
> >
> > Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
> > Reviewed-by: CK Hu <ck.hu@mediatek.com>
>
> This version is different than v4, so please remove reviewed-by tag when
> this patch change. When I see a reviewed-by tag of mine, I would just
> skip review it again because I assume this patch is the same as previous
> version.
>
> For this version, I give still give it a
>
> Reviewed-by: CK Hu <ck.hu@mediatek.com>
>
> > ---
> > drivers/gpu/drm/mediatek/mtk_dsi.c | 53 +++++++++++++++++-------------
> > 1 file changed, 31 insertions(+), 22 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > index b00eb2d2e086..595b3b047c7b 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > @@ -528,7 +528,7 @@ static s32 mtk_dsi_switch_to_cmd_mode(struct mtk_dsi *dsi, u8 irq_flag, u32 t)
> >
> > static int mtk_dsi_poweron(struct mtk_dsi *dsi)
> > {
> > - struct device *dev = dsi->dev;
> > + struct device *dev = dsi->->host.dev;
single -> here
> > int ret;
> > u64 pixel_clock, total_bits;
> > u32 htotal, htotal_bits, bit_per_pixel, overhead_cycles, overhead_bits;
> > @@ -1045,12 +1045,6 @@ static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
> > return ret;
> > }
> >
> > - ret = mipi_dsi_host_register(&dsi->host);
> > - if (ret < 0) {
> > - dev_err(dev, "failed to register DSI host: %d\n", ret);
> > - goto err_ddp_comp_unregister;
> > - }
> > -
> > ret = mtk_dsi_create_conn_enc(drm, dsi);
> > if (ret) {
> > DRM_ERROR("Encoder create failed with %d\n", ret);
> > @@ -1060,8 +1054,6 @@ static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
> > return 0;
> >
> > err_unregister:
> > - mipi_dsi_host_unregister(&dsi->host);
> > -err_ddp_comp_unregister:
> > mtk_ddp_comp_unregister(drm, &dsi->ddp_comp);
> > return ret;
> > }
> > @@ -1073,7 +1065,6 @@ static void mtk_dsi_unbind(struct device *dev, struct device *master,
> > struct mtk_dsi *dsi = dev_get_drvdata(dev);
> >
> > mtk_dsi_destroy_conn_enc(dsi);
> > - mipi_dsi_host_unregister(&dsi->host);
> > mtk_ddp_comp_unregister(drm, &dsi->ddp_comp);
> > }
> >
> > @@ -1097,31 +1088,36 @@ static int mtk_dsi_probe(struct platform_device *pdev)
> >
> > dsi->host.ops = &mtk_dsi_ops;
> > dsi->host.dev = dev;
> > + ret = mipi_dsi_host_register(&dsi->host);
> > + if (ret < 0) {
> > + dev_err(dev, "failed to register DSI host: %d\n", ret);
> > + return ret;
> > + }
> >
> > ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
> > &dsi->panel, &dsi->bridge);
> > if (ret)
> > - return ret;
> > + goto err_unregister_host;
> >
> > dsi->engine_clk = devm_clk_get(dev, "engine");
> > if (IS_ERR(dsi->engine_clk)) {
> > ret = PTR_ERR(dsi->engine_clk);
> > dev_err(dev, "Failed to get engine clock: %d\n", ret);
> > - return ret;
> > + goto err_unregister_host;
> > }
> >
> > dsi->digital_clk = devm_clk_get(dev, "digital");
> > if (IS_ERR(dsi->digital_clk)) {
> > ret = PTR_ERR(dsi->digital_clk);
> > dev_err(dev, "Failed to get digital clock: %d\n", ret);
> > - return ret;
> > + goto err_unregister_host;
> > }
> >
> > dsi->hs_clk = devm_clk_get(dev, "hs");
> > if (IS_ERR(dsi->hs_clk)) {
> > ret = PTR_ERR(dsi->hs_clk);
> > dev_err(dev, "Failed to get hs clock: %d\n", ret);
> > - return ret;
> > + goto err_unregister_host;
> > }
> >
> > regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > @@ -1129,33 +1125,35 @@ static int mtk_dsi_probe(struct platform_device *pdev)
> > if (IS_ERR(dsi->regs)) {
> > ret = PTR_ERR(dsi->regs);
> > dev_err(dev, "Failed to ioremap memory: %d\n", ret);
> > - return ret;
> > + goto err_unregister_host;
> > }
> >
> > dsi->phy = devm_phy_get(dev, "dphy");
> > if (IS_ERR(dsi->phy)) {
> > ret = PTR_ERR(dsi->phy);
> > dev_err(dev, "Failed to get MIPI-DPHY: %d\n", ret);
> > - return ret;
> > + goto err_unregister_host;
> > }
> >
> > comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DSI);
> > if (comp_id < 0) {
> > dev_err(dev, "Failed to identify by alias: %d\n", comp_id);
> > - return comp_id;
> > + ret = comp_id;
> > + goto err_unregister_host;
> > }
> >
> > ret = mtk_ddp_comp_init(dev, dev->of_node, &dsi->ddp_comp, comp_id,
> > &mtk_dsi_funcs);
> > if (ret) {
> > dev_err(dev, "Failed to initialize component: %d\n", ret);
> > - return ret;
> > + goto err_unregister_host;
> > }
> >
> > irq_num = platform_get_irq(pdev, 0);
> > if (irq_num < 0) {
> > - dev_err(&pdev->dev, "failed to request dsi irq resource\n");
> > - return -EPROBE_DEFER;
> > + dev_err(&pdev->dev, "failed to get dsi irq_num: %d\n", irq_num);
> > + ret = irq_num;
> > + goto err_unregister_host;
> > }
> >
> > irq_set_status_flags(irq_num, IRQ_TYPE_LEVEL_LOW);
> > @@ -1163,14 +1161,24 @@ static int mtk_dsi_probe(struct platform_device *pdev)
> > IRQF_TRIGGER_LOW, dev_name(&pdev->dev), dsi);
> > if (ret) {
> > dev_err(&pdev->dev, "failed to request mediatek dsi irq\n");
> > - return -EPROBE_DEFER;
> > + goto err_unregister_host;
> > }
> >
> > init_waitqueue_head(&dsi->irq_wait_queue);
> >
> > platform_set_drvdata(pdev, dsi);
> >
> > - return component_add(&pdev->dev, &mtk_dsi_component_ops);
> > + ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
> > + if (ret) {
> > + dev_err(&pdev->dev, "failed to add component: %d\n", ret);
> > + goto err_unregister_host;
> > + }
> > +
> > + return 0;
> > +
> > +err_unregister_host:
> > + mipi_dsi_host_unregister(&dsi->host);
> > + return ret;
> > }
> >
> > static int mtk_dsi_remove(struct platform_device *pdev)
> > @@ -1179,6 +1187,7 @@ static int mtk_dsi_remove(struct platform_device *pdev)
> >
> > mtk_output_dsi_disable(dsi);
> > component_del(&pdev->dev, &mtk_dsi_component_ops);
> > + mipi_dsi_host_unregister(&dsi->host);
> >
> > return 0;
> > }
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH V5 11/18] clk: tegra210: Add support for Tegra210 clocks
From: Dmitry Osipenko @ 2019-07-17 21:30 UTC (permalink / raw)
To: Sowjanya Komatineni
Cc: Peter De Schrijver, Joseph Lo, thierry.reding, jonathanh, tglx,
jason, marc.zyngier, linus.walleij, stefan, mark.rutland,
pgaikwad, sboyd, linux-clk, linux-gpio, jckuo, talho, linux-tegra,
linux-kernel, mperttunen, spatra, robh+dt, devicetree
In-Reply-To: <7ae3df9a-c0e9-cf71-8e90-4284db8df82f@nvidia.com>
17.07.2019 23:11, Sowjanya Komatineni пишет:
>
> On 7/17/19 1:01 PM, Sowjanya Komatineni wrote:
>>
>> On 7/17/19 12:43 PM, Dmitry Osipenko wrote:
>>> 17.07.2019 21:54, Sowjanya Komatineni пишет:
>>>> On 7/17/19 11:51 AM, Sowjanya Komatineni wrote:
>>>>> On 7/17/19 11:32 AM, Dmitry Osipenko wrote:
>>>>>> 17.07.2019 20:29, Sowjanya Komatineni пишет:
>>>>>>> On 7/17/19 8:17 AM, Dmitry Osipenko wrote:
>>>>>>>> 17.07.2019 9:36, Sowjanya Komatineni пишет:
>>>>>>>>> On 7/16/19 11:33 PM, Dmitry Osipenko wrote:
>>>>>>>>>> В Tue, 16 Jul 2019 22:55:52 -0700
>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>
>>>>>>>>>>> On 7/16/19 10:42 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>> В Tue, 16 Jul 2019 22:25:25 -0700
>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>> On 7/16/19 9:11 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>> В Tue, 16 Jul 2019 19:35:49 -0700
>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>> On 7/16/19 7:18 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>> On 7/16/19 3:06 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>> On 7/16/19 3:00 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>> 17.07.2019 0:35, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>> On 7/16/19 2:21 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>> 17.07.2019 0:12, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>> On 7/16/19 1:47 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 22:26, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:43 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:30, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:25 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:19, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 9:50 AM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 8:00 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 11:06, Peter De Schrijver пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2019 at 03:24:26PM +0800,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Joseph
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Lo wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OK, Will add to CPUFreq driver...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The other thing that also need
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> attention is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> that T124 CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicitly relies on DFLL driver to be
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> first, which is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> icky.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Should I add check for successful dfll clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> register explicitly in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver probe and defer till dfll
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> registers?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Probably you should use the "device links".
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> See
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1][2] for the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> example.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/gpu/drm/tegra/dc.c#L2383
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [2]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://www.kernel.org/doc/html/latest/driver-api/device_link.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Return EPROBE_DEFER instead of EINVAL if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device_link_add() fails.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use of_find_device_by_node() to get the DFLL's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device, see [3].
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [3]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/devfreq/tegra20-devfreq.c#n100
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Will go thru and add...
>>>>>>>>>>>>>>>>>>>>>>>>>> Looks like I initially confused this case with
>>>>>>>>>>>>>>>>>>>>>>>>>> getting
>>>>>>>>>>>>>>>>>>>>>>>>>> orphaned clock.
>>>>>>>>>>>>>>>>>>>>>>>>>> I'm now seeing that the DFLL driver registers the
>>>>>>>>>>>>>>>>>>>>>>>>>> clock and then
>>>>>>>>>>>>>>>>>>>>>>>>>> clk_get(dfll) should be returning EPROBE_DEFER
>>>>>>>>>>>>>>>>>>>>>>>>>> until
>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL driver is
>>>>>>>>>>>>>>>>>>>>>>>>>> probed, hence everything should be fine as-is and
>>>>>>>>>>>>>>>>>>>>>>>>>> there is no real
>>>>>>>>>>>>>>>>>>>>>>>>>> need
>>>>>>>>>>>>>>>>>>>>>>>>>> for the 'device link'. Sorry for the confusion!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, I didn't follow the mail thread. Just
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regarding the DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> part.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> As you know it, the DFLL clock is one of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock sources and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integrated with DVFS control logic with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator. We will not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to other clock sources once we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switched to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL. Because the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU has
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> been regulated by the DFLL HW with the DVFS
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (CVB or OPP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> you see
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> in the driver.). We shouldn't reparent it to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> other sources with
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unknew
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> freq/volt pair. That's not guaranteed to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> work. We
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allow switching to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> open-loop mode but different sources.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay, then the CPUFreq driver will have to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rate before switching to PLLP in order to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper CPU voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP freq is safe to work for any CPU voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> So no
>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to PLLP rate before changing CCLK_G
>>>>>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>>>>>> to PLLP during
>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, please ignore my above comment. During
>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend, need to change
>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK_G source to PLLP when dfll is in closed
>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>> mode first and
>>>>>>>>>>>>>>>>>>>>>>>>>>> then
>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll need to be set to open loop.
>>>>>>>>>>>>>>>>>>>>>>>>>> Okay.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And I don't exactly understand why we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to PLLP in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> idle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver. Just keep it on CL-DVFS mode all the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> time.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 entry, the dfll suspend function
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moves it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the open-loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode. That's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all. The sc7-entryfirmware will handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the rest
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn off
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU power.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 resume, the warmboot code will handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator and power up the CPU cluster. And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> leave
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it on PLL_P.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> After
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resuming to the kernel, we re-init DFLL,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> policy (CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> runs on DFLL open-loop mode) and then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moving to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> close-loop mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL is re-inited after switching CCLK to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> early clocks-state restoring by CaR driver.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hence
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> instead of having
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> odd
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hacks in the CaR driver, it is much nicer to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper suspend-resume sequencing of the device
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> drivers. In this case
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver is the driver that enables DFLL and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switches
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to that
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source, which means that this driver is also
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> be responsible for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> management of the DFLL's state during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend/resume process. If
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver disables DFLL during suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> re-enables it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resume, then looks like the CaR driver hacks
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> around
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL are not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> needed.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL part looks good to me. BTW,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> change the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> patch subject to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "Add
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend-resume support" seems more
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> me.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> To clarify this, the sequences for DFLL use
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> are as
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> follows (assuming
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> required DFLL hw configuration has been done)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch to DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Save current parent and frequency
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2) Enable DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3) Change cclk_g parent to DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For OVR regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Change PWM output pin from tristate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 5) Enable DFLL PWM output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For I2C regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Enable DFLL I2C output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 6) Program DFLL to closed loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch away from DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Change cclk_g parent to PLLP so the CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> frequency is ok for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> any
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> vdd_cpu voltage
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>> I see during switch away from DFLL (suspend),
>>>>>>>>>>>>>>>>>>>>>>>>>>> cclk_g
>>>>>>>>>>>>>>>>>>>>>>>>>>> parent is not
>>>>>>>>>>>>>>>>>>>>>>>>>>> changed to PLLP before changing dfll to open
>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>> mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Will add this ...
>>>>>>>>>>>>>>>>>>>>>>>>>> The CPUFreq driver switches parent to PLLP during
>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>> probe, similar
>>>>>>>>>>>>>>>>>>>>>>>>>> should be done on suspend.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> I'm also wondering if it's always safe to
>>>>>>>>>>>>>>>>>>>>>>>>>> switch to
>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP in the probe.
>>>>>>>>>>>>>>>>>>>>>>>>>> If CPU is running on a lower freq than PLLP, then
>>>>>>>>>>>>>>>>>>>>>>>>>> some
>>>>>>>>>>>>>>>>>>>>>>>>>> other more
>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate intermediate parent should be
>>>>>>>>>>>>>>>>>>>>>>>>>> selected.
>>>>>>>>>>>>>>>>>>>>>>>>> CPU parents are PLL_X, PLL_P, and dfll. PLL_X
>>>>>>>>>>>>>>>>>>>>>>>>> always
>>>>>>>>>>>>>>>>>>>>>>>>> runs at higher
>>>>>>>>>>>>>>>>>>>>>>>>> rate
>>>>>>>>>>>>>>>>>>>>>>>>> so switching to PLL_P during CPUFreq probe
>>>>>>>>>>>>>>>>>>>>>>>>> prior to
>>>>>>>>>>>>>>>>>>>>>>>>> dfll clock enable
>>>>>>>>>>>>>>>>>>>>>>>>> should be safe.
>>>>>>>>>>>>>>>>>>>>>>>> AFAIK, PLLX could run at ~200MHz. There is also a
>>>>>>>>>>>>>>>>>>>>>>>> divided output of
>>>>>>>>>>>>>>>>>>>>>>>> PLLP
>>>>>>>>>>>>>>>>>>>>>>>> which CCLKG supports, the PLLP_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Probably, realistically, CPU is always running
>>>>>>>>>>>>>>>>>>>>>>>> off a
>>>>>>>>>>>>>>>>>>>>>>>> fast PLLX during
>>>>>>>>>>>>>>>>>>>>>>>> boot, but I'm wondering what may happen on KEXEC. I
>>>>>>>>>>>>>>>>>>>>>>>> guess ideally CPUFreq driver should also have a
>>>>>>>>>>>>>>>>>>>>>>>> 'shutdown' callback to teardown DFLL
>>>>>>>>>>>>>>>>>>>>>>>> on a reboot, but likely that there are other
>>>>>>>>>>>>>>>>>>>>>>>> clock-related problems as
>>>>>>>>>>>>>>>>>>>>>>>> well that may break KEXEC and thus it is not very
>>>>>>>>>>>>>>>>>>>>>>>> important at the
>>>>>>>>>>>>>>>>>>>>>>>> moment.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> [snip]
>>>>>>>>>>>>>>>>>>>>>>> During bootup CPUG sources from PLL_X. By PLL_P
>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>> above I meant
>>>>>>>>>>>>>>>>>>>>>>> PLL_P_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> As per clock policies, PLL_X is always used for high
>>>>>>>>>>>>>>>>>>>>>>> freq
>>>>>>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>>>>>>>> 800Mhz
>>>>>>>>>>>>>>>>>>>>>>> and for low frequency it will be sourced from PLLP.
>>>>>>>>>>>>>>>>>>>>>> Alright, then please don't forget to pre-initialize
>>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate to a
>>>>>>>>>>>>>>>>>>>>>> reasonable value using tegra_clk_init_table or
>>>>>>>>>>>>>>>>>>>>>> assigned-clocks.
>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate update is not needed as it is safe to
>>>>>>>>>>>>>>>>>>>>> run at
>>>>>>>>>>>>>>>>>>>>> 408Mhz because it is below fmax @ Vmin
>>>>>>>>>>>>>>>>>>>> So even 204MHz CVB entries are having the same
>>>>>>>>>>>>>>>>>>>> voltage as
>>>>>>>>>>>>>>>>>>>> 408MHz, correct? It's not instantly obvious to me
>>>>>>>>>>>>>>>>>>>> from the
>>>>>>>>>>>>>>>>>>>> DFLL driver's code where the fmax @ Vmin is defined,
>>>>>>>>>>>>>>>>>>>> I see
>>>>>>>>>>>>>>>>>>>> that there is the min_millivolts
>>>>>>>>>>>>>>>>>>>> and frequency entries starting from 204MHZ defined
>>>>>>>>>>>>>>>>>>>> per-table.
>>>>>>>>>>>>>>>>>>> Yes at Vmin CPU Fmax is ~800Mhz. So anything below that
>>>>>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>>>>>> work at Vmin voltage and PLLP max is 408Mhz.
>>>>>>>>>>>>>>>>>> Thank you for the clarification. It would be good to have
>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>> commented
>>>>>>>>>>>>>>>>>> in the code as well.
>>>>>>>>>>>>>>>>> OK, Will add...
>>>>>>>>>>>>>>>> Regarding, adding suspend/resume to CPUFreq, CPUFreq
>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>> happens very early even before disabling non-boot CPUs and
>>>>>>>>>>>>>>>> also
>>>>>>>>>>>>>>>> need to export clock driver APIs to CPUFreq.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Was thinking of below way of implementing this...
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Clock DFLL driver Suspend:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> - Save CPU clock policy registers, and
>>>>>>>>>>>>>>>> Perform
>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>> suspend which sets in open loop mode
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> CPU Freq driver Suspend: does nothing
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Clock DFLL driver Resume:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> - Re-init DFLL, Set in Open-Loop mode,
>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>> Clock policy registers which actually sets source to DFLL
>>>>>>>>>>>>>>>> along
>>>>>>>>>>>>>>>> with other CPU Policy register restore.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> CPU Freq driver Resume:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> - do clk_prepare_enable which acutally sets
>>>>>>>>>>>>>>>> DFLL in
>>>>>>>>>>>>>>>> Closed loop mode
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Adding one more note: Switching CPU Clock to PLLP is not
>>>>>>>>>>>>>>>> needed
>>>>>>>>>>>>>>>> as CPU CLock can be from dfll in open-loop mode as DFLL
>>>>>>>>>>>>>>>> is not
>>>>>>>>>>>>>>>> disabled anywhere throught the suspend/resume path and SC7
>>>>>>>>>>>>>>>> entry
>>>>>>>>>>>>>>>> FW and Warm boot code will switch CPU source to PLLP.
>>>>>>>>>>>>>> Since CPU resumes on PLLP, it will be cleaner to suspend
>>>>>>>>>>>>>> it on
>>>>>>>>>>>>>> PLLP as well. And besides, seems that currently disabling
>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>> clock will disable DFLL completely and then you'd want to
>>>>>>>>>>>>>> re-init
>>>>>>>>>>>>>> the DFLL on resume any ways. So better to just disable DFLL
>>>>>>>>>>>>>> completely on suspend, which should happen on
>>>>>>>>>>>>>> clk_disable(dfll).
>>>>>>>>>>>>> Will switch to PLLP during CPUFreq suspend. With decision of
>>>>>>>>>>>>> using
>>>>>>>>>>>>> clk_disable during suspend, its mandatory to switch to PLLP as
>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>> is completely disabled.
>>>>>>>>>>>>>
>>>>>>>>>>>>> My earlier concern was on restoring CPU policy as we can't do
>>>>>>>>>>>>> that
>>>>>>>>>>>>> from CPUFreq driver and need export from clock driver.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Clear now and will do CPU clock policy restore in after dfll
>>>>>>>>>>>>> re-init.
>>>>>>>>>>>> Why the policy can't be saved/restored by the CaR driver as a
>>>>>>>>>>>> context of any other clock?
>>>>>>>>>>> restoring cpu clock policy involves programming source and
>>>>>>>>>>> super_cclkg_divider.
>>>>>>>>>>>
>>>>>>>>>>> cclk_g is registered as clk_super_mux and it doesn't use
>>>>>>>>>>> frac_div ops
>>>>>>>>>>> to do save/restore its divider.
>>>>>>>>>> That can be changed of course and I guess it also could be as
>>>>>>>>>> simple as
>>>>>>>>>> saving and restoring of two raw u32 values of the policy/divider
>>>>>>>>>> registers.
>>>>>>>>>>
>>>>>>>>>>> Also, during clock context we cant restore cclk_g as cclk_g
>>>>>>>>>>> source
>>>>>>>>>>> will be dfll and dfll will not be resumed/re-initialized by the
>>>>>>>>>>> time
>>>>>>>>>>> clk_super_mux save/restore happens.
>>>>>>>>>>>
>>>>>>>>>>> we can't use save/restore context for dfll clk_ops because
>>>>>>>>>>> dfllCPU_out parent to CCLK_G is first in the clock tree and
>>>>>>>>>>> dfll_ref
>>>>>>>>>>> and dfll_soc peripheral clocks are not restored by the time dfll
>>>>>>>>>>> restore happens. Also dfll peripheral clock enables need to be
>>>>>>>>>>> restored before dfll restore happens which involves programming
>>>>>>>>>>> dfll
>>>>>>>>>>> controller for re-initialization.
>>>>>>>>>>>
>>>>>>>>>>> So dfll resume/re-init is done in clk-tegra210 at end of all
>>>>>>>>>>> clocks
>>>>>>>>>>> restore in V5 series but instead of in clk-tegra210 driver I
>>>>>>>>>>> moved
>>>>>>>>>>> now to dfll-fcpu driver pm_ops as all dfll dependencies will be
>>>>>>>>>>> restored thru clk_restore_context by then. This will be in V6.
>>>>>>>>>> Since DFLL is now guaranteed to be disabled across CaR
>>>>>>>>>> suspend/resume
>>>>>>>>>> (hence it has nothing to do in regards to CCLK) and given that
>>>>>>>>>> PLLs
>>>>>>>>>> state is restored before the rest of the clocks, I don't see why
>>>>>>>>>> not to
>>>>>>>>>> implement CCLK save/restore in a generic fasion. CPU policy
>>>>>>>>>> wull be
>>>>>>>>>> restored to either PLLP or PLLX (if CPUFreq driver is disabled).
>>>>>>>>>>
>>>>>>>>> CCLK_G save/restore should happen in clk_super_mux ops
>>>>>>>>> save/context and
>>>>>>>>> clk_super_mux save/restore happens very early as cclk_g is first
>>>>>>>>> in the
>>>>>>>>> clock tree and save/restore traverses through the tree top-bottom
>>>>>>>>> order.
>>>>>>>> If CCLK_G is restored before the PLLs, then just change the clocks
>>>>>>>> order
>>>>>>>> such that it won't happen.
>>>>>>>>
>>>>>>> I dont think we can change clocks order for CCLK_G.
>>>>>>>
>>>>>>> During bootup, cclk_g is registered after all pll's and peripheral
>>>>>>> clocks which is the way we wanted, So cclk_g will be the first
>>>>>>> one in
>>>>>>> the clk list as clk_register adds new clock first in the list.
>>>>>>>
>>>>>>> When clk_save_context and clk_restore_context APIs iterates over the
>>>>>>> list, cclk_g is the first
>>>>>> Looking at clk_core_restore_context(), I see that it walks up CLKs
>>>>>> list
>>>>>> from parent to children, hence I don't understand how it can ever
>>>>>> happen
>>>>>> that CCLK will be restored before the parent. The clocks registration
>>>>>> order doesn't matter at all in that case.
>>>>> yes from parent to children and dfllCPU_out is the top in the list and
>>>>> its child is cclk_g.
>>>>>
>>>>> the way clocks are registered is the order I see in the clock list and
>>>>> looking into clk_register API it adds new node first in the list.
>>>>>
>>>> cclkg_g & dfll register happens after all plls and peripheral clocks as
>>>> it need ref, soc and peripheral clocks to be enabled.
>>>>> So they are the last to get registered and so becomes first in the
>>>>> list.
>>>>>
>>>>> During save/restore context, it traverses thru this list and first in
>>>>> the list is dfllcpu_OUT (parent) and its child (cclk_g)
>>>>>
>>>>> saving should not be an issue at all but we cant restore cclk_g/dfll
>>>>> in normal way thru clk_ops restore as plls and peripherals restore
>>>>> doesn't happen by that time.
>>>>>
>>>> I was referring to clk_restore_context where it iterates thru root list
>>>> and for each core from the root list clk_core_restore does restore of
>>>> parent and children.
>>>>
>>>> dfllCPU_Out gets first in the list and its child is cclk_g
>>>>
>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/clk/clk.c#L1105
>>> What list you're talking about? clk_summary? It shows current *active*
>>> clocks configuration, if you'll try to disable CPUFreq driver then the
>>> parent of CCLK_G should be PLLX. Similarly when CPU is reparented to
>>> PLLP on driver's suspend, then PLLP is the parent.
>>>
>>>>>>>>> DFLL enable thru CPUFreq resume happens after all
>>>>>>>>> clk_restore_context
>>>>>>>>> happens. So during clk_restore_context, dfll re-init doesnt happen
>>>>>>>>> and
>>>>>>>>> doing cpu clock policy restore during super_mux clk_ops will
>>>>>>>>> crash as
>>>>>>>>> DFLL is not initialized and its clock is not enabled but CPU clock
>>>>>>>>> restore sets source to DFLL if we restore during super_clk_mux
>>>>>>>> If CPU was suspended on PLLP, then it will be restored on PLLP by
>>>>>>>> CaR. I
>>>>>>>> don't understand what DFLL has to do with the CCLK in that case
>>>>>>>> during
>>>>>>>> the clocks restore.
>>>>>>> My above comment is in reference to your request of doing
>>>>>>> save/restore
>>>>>>> for cclk_g in normal fashion thru save/restore context. Because
>>>>>>> of the
>>>>>>> clk order I mentioned above, we cclk_g will be the first one to
>>>>>>> go thru
>>>>>>> save/context.
>>>>>>>
>>>>>>> During save_context of cclk_g, source can be from PLLX, dfll.
>>>>>>>
>>>>>>> Issue will be when we do restore during clk_restore_context of
>>>>>>> cclk_g as
>>>>>>> by that time PLLX/dfll will not be restored.
>>>>>>>
>>>>>> Seems we already agreed that DFLL will be disabled by the CPUFreq
>>>>>> driver
>>>>>> on suspend. Hence CCLK can't be from DFLL if CPU is reparented to
>>>>>> PLLP
>>>>>> on CPUFreq driver's suspend, otherwise CPU keeps running from a
>>>>>> boot-state PLLX if CPUFreq driver is disabled.
>>>>> Yes suspend should not be an issue but issue will be during resume
>>>>> where if we do cclk_g restore in normal way thru clk_restore_context,
>>>>> cclk_g restore happens very early as dfllCPU out is the first one that
>>>>> goes thru restore context and plls/peripherals are not resumed by
>>>>> then.
>>>>>
>>>>> CPU runs from PLLX if dfll clock enable fails during boot. So when it
>>>>> gets to suspend, we save CPU running clock source as either PLLX or
>>>>> DFLL and then we switch to PLLP.
>>>>>
>>>>>
>>>>> On resume, CPU runs from PLLP by warm boot code and we need to restore
>>>>> back its source to the one it was using from saved source context
>>>>> (which can be either PLLX or DFLL)
>>>>>
>>>>> So PLLs & DFLL resume need to happen before CCLKG restore/resume.
>>>>>
>>>>>
>>>>> With all above discussions, we do DFLL disable in CPUFreq driver on
>>>>> suspend and on CPUFreq resume we enable DFLL back and restore CPU
>>>>> clock source it was using during suspend (which will be either PLLX if
>>>>> dfll enable fails during probe or it will be using DFLL).
>>> During suspend CPU's parent shall be PLLP and not DFLL (note that it is
>>> disabled) after reparenting to PLLP by the CPUFreq driver.
>>>
>> CPU source context should be saved before switching to safe source of
>> PLLP as on resume we need to restore back to source it was using
>> before we switch to safe source during suspend entry.
>>
>> So saved context for CPU Source will be either dfll or PLLX
>>
> PLLP reparenting is only during suspend/entry to have it as safe source
> but actual CPU source it was running from before suspending is either
> dfll/pllx which should be the one to be restored on CPUFreq resume.
> Resume happens with CPU running from PLLP till it gets to the point of
> restoring its original source (dfll or pllx)
CaR should restore CPU to PLLP or PLLX, while CPUFreq driver restores
CPU to DFLL. Please see more comments below.
>>>>> So i was trying to say dfll/cclk_g restore can't be done in normal way
>>>>> thru clk_ops save/restore context
>>> Let's see what happens if CPUFreq is active:
>>>
>>> 1. CPUFreq driver probe happens
>>> 2. CPU is reparented to PLLP
>>> 3. DFLL inited
>>> 4. CPU is reparented to DFLL
>>>
>>> 5. CPUFreq driver suspend happens
>>> 6. CPU is reparented to PLLP
>>> 7. DFLL is disabled
>>>
>>> 8. Car suspend happens
>>> 9. DFLL context saved
>>> 10. PLLP/PLLX context saved
>>> 11. CCLK context saved
>>>
>>> 12. Car resume happens
>>> 13. DFLL context restored
>>> 14. PLLP/PLLX context restored
>>> 15. CCLK context restored
>>>
>>> 16. CPUFreq driver resume happens
>>> 17. DFLL re-inited
>>> 18. CPU is reparented to DFLL
>>
>>
>> Below is the order of sequence it should be based on the order of clk
>> register.
>>
>> My comments inline in this sequence.
>>
>> 1. CPUFreq driver probe happens
>> 2. CPU is reparented to PLLP
>> 3. DFLL inited
>> 4. CPU is reparented to DFLL
>>
>>
>> 5. CPUFreq driver suspend happens
>> 6. Save CPU source which could be either dfll or pllx
Please see my next comment.
>> 7. CPU is reparented to safe known source PLLP
>> 8. DFLL is disabled
>>
>> 8. Car suspend happens
>> 9. DFLL context saved (With DFLL disabled in CPUFreq suspend,
>> nothing to be saved here as last freq req will always be saved).
>> 10. CCLK context saved (CPU clock source will be saved in CPUFreq
>> driver suspend which could be either dfll or pllx)
That I don't understand. The CPU's clock source state should be saved at
the moment of the CaR's suspending (i.e. CCLK policy will be set to PLLP
or PLLX) and then CCLK state should be also restored by the CaR in step 14.
CPUFreq driver should only switch CPU to PLLP and disable DFLL on
suspend in step 5, that's it. On resume CPUFreq driver will restore CPU
to DFLL in step 18.
>> 11. PLLP/PLLX context saved
>> 12. Peripheral Clock saved
>>
>> 12. Car resume happens
>> 13. DFLL context restored : No DFLL context to be restored and we
>> only need to reinitialize DFLL and re-initialize can't be done here as
>> this is the 1st to get restored and PLL/Peripheral clocks are not
>> restored by this time. So we can't use clk_ops restore for DFLL
It looks to me that clk_core_restore_context() should just do
hlist_for_each_entry *_reverse*. Don't you think so?
>> 14. CCLK context restored
>> CCLK cant be restored here as context could be either dfll or pllx
>> which is the source orginally it was actually using before we force
>> switch to safe PLLP for suspend entry. So we can't use clk_ops restore
>> for DFLL
See my comment to step 10. CCLK should be restored to the *CaR's saved*
context, which is either PLLX or PLLP policy.
>> 15. PLLP/PLLX context restored
>> 16. Peripheral context restored
>>
>> 16. CPUFreq driver resume happens
>> 17. DFLL re-inited (Invoking DFLL re-init in CPUFreq resume need
>> exporting DFLL reinit from Clock driver to CPUFreq driver)
Will be nice if clk_enable(dfll) could be enough to re-init DFLL. That
should achievable with my next comment to step 18.
>> 18. CPU is reparented to DFLL or PLLX based on saved context from
>> step 9.
>>
>> Note: instead of exporting, we can do DFLL re-init from clock-dfll
>> driver itself thru dfll-fcpu pm_ops resume. So dfll will be
>> re-initialized by the time CPUFreq driver resumes and switches to use
>> DFLL source.
>>
Yes, I guess DFLL hardware should be fully reset on DFLL's driver resume
to be on a safe side any ways.
But(!) we could probably just fix clk_core_restore_context(), like I
suggested in step 13. Then DFLL clock could use generic save / restore
context and CPUFreq driver won't have to do anything at all because DFLL
clock will be saved first and resumed *after* all of the peripherals by
the CCF. In the end CCLK will be switched to DFLL by the CCF restore as
well.
^ permalink raw reply
* RE: [PATCH 2/3 v3] dt-bindings: gpio: aspeed: Add SGPIO support
From: Hongwei Zhang @ 2019-07-17 21:30 UTC (permalink / raw)
To: Andrew Jeffery, Joel Stanley, Linus Walleij,
devicetree@vger.kernel.org
Cc: Rob Herring, Mark Rutland, Bartosz Golaszewski,
linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org
In-Reply-To: <91ebb817-3cc6-4b87-8c2b-cfcd66f4c284@www.fastmail.com>
Hello Andrew,
Thanks for your review, please find the v4 in separate email. We merged all your suggestion in v4.
Best Regards,
--Hongwei
-----Original Message-----
> From: Andrew Jeffery <andrew@aj.id.au>
> Sent: Tuesday, July 16, 2019 11:26 PM
> To: Hongwei Zhang; Bartosz Golaszewski; Joel Stanley; Linus Walleij
> Cc: linux-gpio@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-aspeed@lists.ozlabs.org;
> linux-kernel@vger.kernel.org
> Subject: Re: [PATCH 2/3 v3] ARM: dts: aspeed: Add SGPIO driver
>
> Hello Hongwei,
>
> Please send patches and feedback on prior iterations separately. Please send the output of `git format-
> patch ...`directly; format-patch spits the patch out in email form ready to go and can be fed straight to
> `git send-email`.
>
> On Wed, 17 Jul 2019, at 06:54, Hongwei Zhang wrote:
> > Add SGPIO driver support for Aspeed AST2500 SoC.
> >
> > Signed-off-by: Hongwei Zhang <hongweiz@ami.com>
> > ---
> > drivers/gpio/sgpio-aspeed.c | 487
> > ++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 487 insertions(+)
> > create mode 100644 drivers/gpio/sgpio-aspeed.c
> >
> > diff --git a/drivers/gpio/sgpio-aspeed.c b/drivers/gpio/sgpio-aspeed.c
> > new file mode 100644 index 0000000..ade2cb7
> > --- /dev/null
> > +++ b/drivers/gpio/sgpio-aspeed.c
> > @@ -0,0 +1,487 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright 2019 American Megatrends International LLC.
> > + *
> > + * Author: Karthikeyan Mani <karthikeyanm@amiindia.co.in> */
> > +
> > +#include <linux/gpio/driver.h>
> > +#include <linux/gpio/aspeed.h>
>
> linux/gpio/aspeed.h is specific to the parallel GPIO driver, please drop this include.
>
Removed it.
> > +#include <linux/hashtable.h>
> > +#include <linux/bitfield.h>
> > +#include <linux/init.h>
> > +#include <linux/clk.h>
> > +#include <linux/io.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/pinctrl/consumer.h>
>
> This driver doesn't have any direct interaction with pinctrl, so I think we can remove this header
>
Removed it.
> > +#include <linux/platform_device.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/string.h>
> > +#include <linux/gpio.h>
> > +
> > +#define MAX_NR_SGPIO 80
> > +
> > +#define ASPEED_SGPIO_CTRL 0x54
> > +
> > +#define ASPEED_SGPIO_PINS_MASK GENMASK(9, 6)
> > +#define ASPEED_SGPIO_CLK_DIV_MASK GENMASK(31, 16)
> > +#define ASPEED_SGPIO_ENABLE BIT(0)
> > +
> > +// default sgpio direction is input.
> > +static uint32_t sgpio_dir_val[3] = {0xffffffff, 0xffffffff,
> > +0xffffffff
> > };
>
> Why not make it a member of struct aspeed_sgpio (below)? I'd prefer we encode the comment in the
> variable name as well, e.g.
> sgpio_dir_in`- this way when reading the code that uses it we know which bit state means what (set is
> input, clear is output).
>
Done.
> > +
> > +struct aspeed_sgpio {
> > + struct gpio_chip chip;
> > + struct clk *pclk;
> > + spinlock_t lock;
> > + void __iomem *base;
> > + int irq;
> > +};
> > +
> > +struct aspeed_sgpio_bank {
> > + uint16_t val_regs;
> > + uint16_t rdata_reg;
> > + uint16_t irq_regs;
> > + const char names[4][3];
> > +};
> > +
> > +/*
> > + * Note: The "value" register returns the input value sampled on the
> > + * line even when the GPIO is configured as an output. Since
> > + * that input goes through synchronizers, writing, then reading
> > + * back may not return the written value right away.
>
> The paragraph above is somewhat specific to the parallel GPIO driver.
> It would be good to rework it for the context of the SGPIO driver.
> Documenting the split of the "value" and "rdata" register is a good thing.
>
> > + *
> > + * The "rdata" register returns the content of the write latch
> > + * and thus can be used to read back what was last written
> > + * reliably.
> > + */
> > +static const struct aspeed_sgpio_bank aspeed_sgpio_banks[] = {
> > + {
> > + .val_regs = 0x0000,
> > + .rdata_reg = 0x0070,
> > + .irq_regs = 0x0004,
> > + .names = { "A", "B", "C", "D" },
> > + },
> > + {
> > + .val_regs = 0x001C,
> > + .rdata_reg = 0x0074,
> > + .irq_regs = 0x0020,
> > + .names = { "E", "F", "G", "H" },
> > + },
> > + {
> > + .val_regs = 0x0038,
> > + .rdata_reg = 0x0078,
> > + .irq_regs = 0x003C,
> > + .names = { "I", "J" },
> > + },
> > +};
> > +
> > +enum aspeed_sgpio_reg {
> > + reg_val,
> > + reg_rdata,
> > + reg_irq_enable,
> > + reg_irq_type0,
> > + reg_irq_type1,
> > + reg_irq_type2,
> > + reg_irq_status,
> > +};
> > +
> > +#define GPIO_VAL_VALUE 0x00
> > +#define GPIO_VAL_DIR 0x04
> > +#define GPIO_IRQ_ENABLE 0x00
> > +#define GPIO_IRQ_TYPE0 0x04
> > +#define GPIO_IRQ_TYPE1 0x08
> > +#define GPIO_IRQ_TYPE2 0x0C
> > +#define GPIO_IRQ_STATUS 0x10
> > +
> > +/* This will be resolved at compile time */ static inline void
> > +__iomem *bank_reg(struct aspeed_sgpio *gpio,
> > + const struct aspeed_sgpio_bank *bank,
> > + const enum aspeed_sgpio_reg reg) {
> > + switch (reg) {
> > + case reg_val:
> > + return gpio->base + bank->val_regs + GPIO_VAL_VALUE;
> > + case reg_rdata:
> > + return gpio->base + bank->rdata_reg;
> > + case reg_irq_enable:
> > + return gpio->base + bank->irq_regs + GPIO_IRQ_ENABLE;
> > + case reg_irq_type0:
> > + return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE0;
> > + case reg_irq_type1:
> > + return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE1;
> > + case reg_irq_type2:
> > + return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE2;
> > + case reg_irq_status:
> > + return gpio->base + bank->irq_regs + GPIO_IRQ_STATUS;
> > + default:
> > + /* acturally if code runs to here, it's an error case */
> > + BUG_ON(1);
> > + }
> > +}
> > +
> > +#define GPIO_BANK(x) ((x) >> 5)
> > +#define GPIO_OFFSET(x) ((x) & 0x1f)
> > +#define GPIO_BIT(x) BIT(GPIO_OFFSET(x))
> > +
> > +static const struct aspeed_sgpio_bank *to_bank(unsigned int offset) {
> > + unsigned int bank = GPIO_BANK(offset);
> > +
> > + WARN_ON(bank >= ARRAY_SIZE(aspeed_sgpio_banks));
> > + return &aspeed_sgpio_banks[bank];
> > +}
> > +
> > +static int aspeed_sgpio_get(struct gpio_chip *gc, unsigned int
> > +offset) {
> > + struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
> > + const struct aspeed_sgpio_bank *bank = to_bank(offset);
> > +
> > + if (sgpio_dir_val[GPIO_BANK(offset)] & GPIO_BIT(offset))
> > + return !!(ioread32(bank_reg(gpio, bank, reg_val)) &
> > GPIO_BIT(offset));
> > + else
> > + return !!(ioread32(bank_reg(gpio, bank, reg_rdata)) &
> > GPIO_BIT(offset));
>
> We don't need the else because we return from the body of the true case,
> and this could be written in a less redundant fashion. Also we need to do
> the read under gpio.lock for consistency with aspeed_sgpio_set().
>
> enum aspeed_sgpio_reg from;
> unsigned long flags;
> bool input;
> int rc;
>
> ...
>
> spin_lock_irqsave(&gpio->lock, flags);
> input = sgpio_dir_val[GPIO_BANK(offset)] & GPIO_BIT(offset);
> from = input ? reg_val : reg_rdata;
> rc = !!(ioread32(bank_reg(gpio, bank, from)) & GPIO_BIT(offset));
> spin_unlock_irqrestore(&gpio->lock, flags);
>
> return rc;
>
Updated code accordingly.
> > +
> > +}
> > +
> > +static void aspeed_sgpio_set(struct gpio_chip *gc, unsigned int
> > offset, int val)
> > +{
> > + struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
> > + const struct aspeed_sgpio_bank *bank = to_bank(offset);
> > + unsigned long flags;
> > + void __iomem *addr;
> > + u32 reg = 0;
> > +
> > + spin_lock_irqsave(&gpio->lock, flags);
> > +
> > + addr = bank_reg(gpio, bank, reg_val);
> > +
> > + if (val)
> > + reg |= GPIO_BIT(offset);
> > + else
> > + reg &= ~GPIO_BIT(offset);
> > +
> > + iowrite32(reg, addr);
> > + spin_unlock_irqrestore(&gpio->lock, flags);
> > +}
> > +
> > +static int aspeed_sgpio_dir_in(struct gpio_chip *gc, unsigned int
> > offset)
> > +{
> > + sgpio_dir_val[GPIO_BANK(offset)] |= GPIO_BIT(offset);
>
> Also do all manipulations of sgpio_dir_val under the spinlock.
>
Added spinlock as you suggested.
> > + return 0;
> > +}
> > +
> > +static int aspeed_sgpio_dir_out(struct gpio_chip *gc, unsigned int
> > offset, int val)
> > +{
> > + sgpio_dir_val[GPIO_BANK(offset)] &= ~GPIO_BIT(offset);
>
> Again here.
>
> > + return 0;
> > +}
> > +
> > +static int aspeed_sgpio_get_direction(struct gpio_chip *gc, unsigned
> > int offset)
> > +{
> > + return sgpio_dir_val[GPIO_BANK(offset)] & GPIO_BIT(offset);
>
> Again here.
>
> > +
> > +}
> > +
> > +static inline int irqd_to_aspeed_sgpio_data(struct irq_data *d,
> > + struct aspeed_sgpio **gpio,
> > + const struct aspeed_sgpio_bank **bank,
> > + u32 *bit, int *offset)
> > +{
> > + struct aspeed_sgpio *internal;
> > +
> > + *offset = irqd_to_hwirq(d);
> > +
> > + internal = irq_data_get_irq_chip_data(d);
> > +
> > + *gpio = internal;
> > + *bank = to_bank(*offset);
> > + *bit = GPIO_BIT(*offset);
> > +
> > + return 0;
>
> It looks like this function could be a void function instead, and we
> could eliminate error checking from the callsites. If you're feeling
> paranoid you could `WARN_ON(!internal);` after the call to
> `irq_data_get_irq_chip_data(d)`.
>
Updated.
> > +}
> > +
> > +static void aspeed_sgpio_irq_ack(struct irq_data *d)
> > +{
> > + const struct aspeed_sgpio_bank *bank;
> > + struct aspeed_sgpio *gpio;
> > + unsigned long flags;
> > + void __iomem *status_addr;
> > + int rc, offset;
> > + u32 bit;
> > +
> > + rc = irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
> > + if (rc)
> > + return;
> > +
> > + status_addr = bank_reg(gpio, bank, reg_irq_status);
> > +
> > + spin_lock_irqsave(&gpio->lock, flags);
> > +
> > + iowrite32(bit, status_addr);
> > +
> > + spin_unlock_irqrestore(&gpio->lock, flags);
> > +}
> > +
> > +static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
> > +{
> > + const struct aspeed_sgpio_bank *bank;
> > + struct aspeed_sgpio *gpio;
> > + unsigned long flags;
> > + u32 reg, bit;
> > + void __iomem *addr;
> > + int rc, offset;
> > +
> > + rc = irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
> > + if (rc)
> > + return;
> > +
> > + addr = bank_reg(gpio, bank, reg_irq_enable);
> > +
> > + spin_lock_irqsave(&gpio->lock, flags);
> > +
> > + reg = ioread32(addr);
> > + if (set)
> > + reg |= bit;
> > + else
> > + reg &= ~bit;
> > +
> > + iowrite32(reg, addr);
> > +
> > + spin_unlock_irqrestore(&gpio->lock, flags);
> > +}
> > +
> > +static void aspeed_sgpio_irq_mask(struct irq_data *d)
> > +{
> > + aspeed_sgpio_irq_set_mask(d, false);
> > +}
> > +
> > +static void aspeed_sgpio_irq_unmask(struct irq_data *d)
> > +{
> > + aspeed_sgpio_irq_set_mask(d, true);
> > +}
> > +
> > +static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type)
> > +{
> > + u32 type0 = 0;
> > + u32 type1 = 0;
> > + u32 type2 = 0;
> > + u32 bit, reg;
> > + const struct aspeed_sgpio_bank *bank;
> > + irq_flow_handler_t handler;
> > + struct aspeed_sgpio *gpio;
> > + unsigned long flags;
> > + void __iomem *addr;
> > + int rc, offset;
> > +
> > + rc = irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
> > + if (rc)
> > + return -EINVAL;
> > +
> > + switch (type & IRQ_TYPE_SENSE_MASK) {
> > + case IRQ_TYPE_EDGE_BOTH:
> > + type2 |= bit;
> > + /* fall through */
> > + case IRQ_TYPE_EDGE_RISING:
> > + type0 |= bit;
> > + /* fall through */
> > + case IRQ_TYPE_EDGE_FALLING:
> > + handler = handle_edge_irq;
> > + break;
> > + case IRQ_TYPE_LEVEL_HIGH:
> > + type0 |= bit;
> > + /* fall through */
> > + case IRQ_TYPE_LEVEL_LOW:
> > + type1 |= bit;
> > + handler = handle_level_irq;
> > + break;
> > + default:
> > + return -EINVAL;
> > + }
> > +
> > + spin_lock_irqsave(&gpio->lock, flags);
> > +
> > + addr = bank_reg(gpio, bank, reg_irq_type0);
> > + reg = ioread32(addr);
> > + reg = (reg & ~bit) | type0;
> > + iowrite32(reg, addr);
> > +
> > + addr = bank_reg(gpio, bank, reg_irq_type1);
> > + reg = ioread32(addr);
> > + reg = (reg & ~bit) | type1;
> > + iowrite32(reg, addr);
> > +
> > + addr = bank_reg(gpio, bank, reg_irq_type2);
> > + reg = ioread32(addr);
> > + reg = (reg & ~bit) | type2;
> > + iowrite32(reg, addr);
> > +
> > + spin_unlock_irqrestore(&gpio->lock, flags);
> > +
> > + irq_set_handler_locked(d, handler);
> > +
> > + return 0;
> > +}
> > +
> > +static void aspeed_sgpio_irq_handler(struct irq_desc *desc)
> > +{
> > + struct gpio_chip *gc = irq_desc_get_handler_data(desc);
> > + struct irq_chip *ic = irq_desc_get_chip(desc);
> > + struct aspeed_sgpio *data = gpiochip_get_data(gc);
> > + unsigned int i, p, girq;
> > + unsigned long reg;
> > +
> > + chained_irq_enter(ic, desc);
> > +
> > + for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) {
> > + const struct aspeed_sgpio_bank *bank = &aspeed_sgpio_banks[i];
> > +
> > + reg = ioread32(bank_reg(data, bank, reg_irq_status));
> > +
> > + for_each_set_bit(p, ®, 32) {
> > + girq = irq_find_mapping(gc->irq.domain, i * 32 + p);
> > + generic_handle_irq(girq);
> > + }
> > +
> > + }
> > +
> > + chained_irq_exit(ic, desc);
> > +}
> > +
> > +static struct irq_chip aspeed_sgpio_irqchip = {
> > + .name = "aspeed-sgpio",
> > + .irq_ack = aspeed_sgpio_irq_ack,
> > + .irq_mask = aspeed_sgpio_irq_mask,
> > + .irq_unmask = aspeed_sgpio_irq_unmask,
> > + .irq_set_type = aspeed_sgpio_set_type,
> > +};
> > +
> > +static int aspeed_sgpio_setup_irqs(struct aspeed_sgpio *gpio,
> > + struct platform_device *pdev)
> > +{
> > + int rc, i;
> > + const struct aspeed_sgpio_bank *bank;
> > +
> > + rc = platform_get_irq(pdev, 0);
> > + if (rc < 0)
> > + return rc;
> > +
> > + gpio->irq = rc;
> > +
> > + /* Disable IRQ and clear Interrupt status registers for all SPGIO
> > Pins. */
> > + for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) {
> > + bank = &aspeed_sgpio_banks[i];
> > + /* disable irq enable bits */
> > + iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_enable));
> > + /* clear status bits */
> > + iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_status));
> > + }
> > +
> > + rc = gpiochip_irqchip_add(&gpio->chip, &aspeed_sgpio_irqchip,
> > + 0, handle_bad_irq, IRQ_TYPE_NONE);
> > + if (rc) {
> > + dev_info(&pdev->dev, "Could not add irqchip\n");
> > + return rc;
> > + }
> > +
> > + gpiochip_set_chained_irqchip(&gpio->chip, &aspeed_sgpio_irqchip,
> > + gpio->irq, aspeed_sgpio_irq_handler);
> > +
> > + /* set IRQ settings and Enable Interrupt */
> > + for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) {
> > + bank = &aspeed_sgpio_banks[i];
> > + /* set falling or level-low irq */
> > + iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_type0));
> > + /* trigger type is edge */
> > + iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_type1));
> > + /* dual edge trigger mode. */
> > + iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_type2));
> > + /* enable irq */
> > + iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_enable));
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static const struct of_device_id aspeed_sgpio_of_table[] = {
> > + { .compatible = "aspeed,ast2400-sgpio" },
> > + { .compatible = "aspeed,ast2500-sgpio" },
> > + {}
> > +};
> > +MODULE_DEVICE_TABLE(of, aspeed_sgpio_of_table);
> > +
> > +static int __init aspeed_sgpio_probe(struct platform_device *pdev)
> > +{
> > + struct aspeed_sgpio *gpio;
> > + struct resource *res;
> > + u32 nr_gpios, sgpio_freq;
> > + int rc;
> > + u16 sgpio_clk_div;
>
> Lets make this a u32 as it will help error detection below.
>
> > + unsigned long apb_freq;
> > +
> > + gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
> > + if (!gpio)
> > + return -ENOMEM;
> > +
> > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > + gpio->base = devm_ioremap_resource(&pdev->dev, res);
>
> Please use devm_platform_ioremap_resource() here.
>
> > + if (IS_ERR(gpio->base))
> > + return PTR_ERR(gpio->base);
> > +
> > + rc = of_property_read_u32(pdev->dev.of_node, "nr-gpios", &nr_gpios);
> > + if ((rc < 0) || (nr_gpios > MAX_NR_SGPIO))
> > + nr_gpios = MAX_NR_SGPIO;
>
> This is an error state, not something we should paper over. This should be
> `return -EINVAL;`
>
Updated.
> > +
> > + rc = of_property_read_u32(pdev->dev.of_node, "bus-frequency",
> > &sgpio_freq);
> > + if (rc < 0) {
> > + dev_err(&pdev->dev, "Could not read bus-frequency property\n");
> > + sgpio_freq = 12000000;
>
> Again, I suggested previously that this is a required property, not optional.
> As such there should not be fall-back code here. This is another case of
> `return -EINVAL;`.
>
Updated.
> > + }
> > +
> > + gpio->pclk = devm_clk_get(&pdev->dev, NULL);
> > + if (IS_ERR(gpio->pclk)) {
> > + dev_err(&pdev->dev, "devm_clk_get failed\n");
> > + return PTR_ERR(gpio->pclk);
> > + }
> > +
> > + apb_freq = clk_get_rate(gpio->pclk);
> > + sgpio_clk_div = 2 * ((apb_freq % sgpio_freq == 0) ?
> > + (apb_freq / sgpio_freq) - 1 : (apb_freq / sgpio_freq));
>
> This calculation seems overly complex and possibly incorrect (need to
> multiply the denominator or divide the result, not multiply the result)?
>
> From the datasheet, the SGPM clock period calculation is:
>
> period = 1/PCLK * 2 * (GPIO254[31:16] + 1)
>
> rearranging:
>
> period = 2 * (GPIO254[31:16] + 1) / PCLK
>
> Converting back to bus frequency:
>
> frequency = 1 / (2 * (GPIO254[31:16] + 1) / PCLK)
>
> Which rearranges to:
>
> frequency = PCLK / (2 * (GPIO254[31:16] + 1))
>
> Extracting GPIO254[31:16] in terms of PCLK / frequency from above:
>
> frequency * 2 * (GPIO254[31:16] + 1) = PCLK
>
> And so:
>
> GPIO254[31:16] = PCLK / (frequency * 2) - 1
>
> From that, the code should look something like:
>
> if (sgpio_freq == 0)
> return -EINVAL;
>
> sgpio_clk_div = apb_freq / (sgpio_freq * 2) - 1;
>
> if (sgpio_clk_div > (1 << 16) - 1)
> return -EINVAL;
>
> This seems to work at the extremes (sgpio_clk_div = 0 and
> sgpio_clk_div = 65535), and we get 32766.99 on a round-trip of
> the divider value 32768, which if we truncate gives an error of 0.023Hz
> with an APB of 24.75MHz (value reported from one of our boards).
>
> Andrew
>
Thanks for the formula and detailed suggestion, really appreciated.
> > + iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, sgpio_clk_div) |
> > + FIELD_PREP(ASPEED_SGPIO_PINS_MASK, (nr_gpios / 8)) |
> > + ASPEED_SGPIO_ENABLE,
> > + gpio->base + ASPEED_SGPIO_CTRL);
> > +
> > + spin_lock_init(&gpio->lock);
> > +
> > + gpio->chip.parent = &pdev->dev;
> > + gpio->chip.ngpio = nr_gpios;
> > + gpio->chip.direction_input = aspeed_sgpio_dir_in;
> > + gpio->chip.direction_output = aspeed_sgpio_dir_out;
> > + gpio->chip.get_direction = aspeed_sgpio_get_direction;
> > + gpio->chip.request = NULL;
> > + gpio->chip.free = NULL;
> > + gpio->chip.get = aspeed_sgpio_get;
> > + gpio->chip.set = aspeed_sgpio_set;
> > + gpio->chip.set_config = NULL;
> > + gpio->chip.label = dev_name(&pdev->dev);
> > + gpio->chip.base = ARCH_NR_GPIOS - MAX_NR_SGPIO;
> > +
> > + rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
> > + if (rc < 0)
> > + return rc;
> > +
> > + return aspeed_sgpio_setup_irqs(gpio, pdev);
> > +}
> > +
> > +static struct platform_driver aspeed_sgpio_driver = {
> > + .driver = {
> > + .name = KBUILD_MODNAME,
> > + .of_match_table = aspeed_sgpio_of_table,
> > + },
> > +};
> > +
> > +module_platform_driver_probe(aspeed_sgpio_driver, aspeed_sgpio_probe);
> > +MODULE_DESCRIPTION("Aspeed Serial GPIO Driver");
> > +MODULE_LICENSE("GPL");
> > --
> > 2.7.4
^ permalink raw reply
* Re: [PATCH V5 11/18] clk: tegra210: Add support for Tegra210 clocks
From: Sowjanya Komatineni @ 2019-07-17 21:29 UTC (permalink / raw)
To: Dmitry Osipenko
Cc: Peter De Schrijver, Joseph Lo, thierry.reding, jonathanh, tglx,
jason, marc.zyngier, linus.walleij, stefan, mark.rutland,
pgaikwad, sboyd, linux-clk, linux-gpio, jckuo, talho, linux-tegra,
linux-kernel, mperttunen, spatra, robh+dt, devicetree
In-Reply-To: <7ae3df9a-c0e9-cf71-8e90-4284db8df82f@nvidia.com>
On 7/17/19 1:11 PM, Sowjanya Komatineni wrote:
>
> On 7/17/19 1:01 PM, Sowjanya Komatineni wrote:
>>
>> On 7/17/19 12:43 PM, Dmitry Osipenko wrote:
>>> 17.07.2019 21:54, Sowjanya Komatineni пишет:
>>>> On 7/17/19 11:51 AM, Sowjanya Komatineni wrote:
>>>>> On 7/17/19 11:32 AM, Dmitry Osipenko wrote:
>>>>>> 17.07.2019 20:29, Sowjanya Komatineni пишет:
>>>>>>> On 7/17/19 8:17 AM, Dmitry Osipenko wrote:
>>>>>>>> 17.07.2019 9:36, Sowjanya Komatineni пишет:
>>>>>>>>> On 7/16/19 11:33 PM, Dmitry Osipenko wrote:
>>>>>>>>>> В Tue, 16 Jul 2019 22:55:52 -0700
>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>
>>>>>>>>>>> On 7/16/19 10:42 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>> В Tue, 16 Jul 2019 22:25:25 -0700
>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>> On 7/16/19 9:11 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>> В Tue, 16 Jul 2019 19:35:49 -0700
>>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>>> On 7/16/19 7:18 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>> On 7/16/19 3:06 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>> On 7/16/19 3:00 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>> 17.07.2019 0:35, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>> On 7/16/19 2:21 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>> 17.07.2019 0:12, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>> On 7/16/19 1:47 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 22:26, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:43 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:30, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:25 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:19, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 9:50 AM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 8:00 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 11:06, Peter De Schrijver пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2019 at 03:24:26PM +0800,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Joseph
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Lo wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OK, Will add to CPUFreq driver...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The other thing that also need
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> attention is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> that T124 CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicitly relies on DFLL driver to be
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> first, which is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> icky.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Should I add check for successful dfll clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> register explicitly in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver probe and defer till
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> registers?
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Probably you should use the "device
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> links". See
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1][2] for the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> example.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/gpu/drm/tegra/dc.c#L2383
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [2]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://www.kernel.org/doc/html/latest/driver-api/device_link.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Return EPROBE_DEFER instead of EINVAL if
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device_link_add() fails.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> use of_find_device_by_node() to get the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device, see [3].
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [3]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/devfreq/tegra20-devfreq.c#n100
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Will go thru and add...
>>>>>>>>>>>>>>>>>>>>>>>>>> Looks like I initially confused this case with
>>>>>>>>>>>>>>>>>>>>>>>>>> getting
>>>>>>>>>>>>>>>>>>>>>>>>>> orphaned clock.
>>>>>>>>>>>>>>>>>>>>>>>>>> I'm now seeing that the DFLL driver registers
>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>> clock and then
>>>>>>>>>>>>>>>>>>>>>>>>>> clk_get(dfll) should be returning
>>>>>>>>>>>>>>>>>>>>>>>>>> EPROBE_DEFER until
>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL driver is
>>>>>>>>>>>>>>>>>>>>>>>>>> probed, hence everything should be fine as-is
>>>>>>>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>>>>>>>> there is no real
>>>>>>>>>>>>>>>>>>>>>>>>>> need
>>>>>>>>>>>>>>>>>>>>>>>>>> for the 'device link'. Sorry for the confusion!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, I didn't follow the mail thread.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Just
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regarding the DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> part.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> As you know it, the DFLL clock is one of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock sources and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integrated with DVFS control logic with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator. We will not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to other clock sources once we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switched to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL. Because the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU has
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> been regulated by the DFLL HW with the DVFS
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (CVB or OPP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> you see
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> in the driver.). We shouldn't reparent
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> other sources with
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unknew
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> freq/volt pair. That's not guaranteed to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> work. We
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allow switching to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> open-loop mode but different sources.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay, then the CPUFreq driver will have to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rate before switching to PLLP in order to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper CPU voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP freq is safe to work for any CPU voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> So no
>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to PLLP rate before changing CCLK_G
>>>>>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>>>>>> to PLLP during
>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, please ignore my above comment. During
>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend, need to change
>>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK_G source to PLLP when dfll is in closed
>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>> mode first and
>>>>>>>>>>>>>>>>>>>>>>>>>>> then
>>>>>>>>>>>>>>>>>>>>>>>>>>> dfll need to be set to open loop.
>>>>>>>>>>>>>>>>>>>>>>>>>> Okay.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And I don't exactly understand why we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to PLLP in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> idle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver. Just keep it on CL-DVFS mode all
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> time.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 entry, the dfll suspend function
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moves it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the open-loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode. That's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all. The sc7-entryfirmware will handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the rest
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn off
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU power.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 resume, the warmboot code will
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator and power up the CPU cluster. And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> leave
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it on PLL_P.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> After
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resuming to the kernel, we re-init DFLL,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> policy (CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> runs on DFLL open-loop mode) and then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moving to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> close-loop mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL is re-inited after switching CCLK to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> early clocks-state restoring by CaR
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver. Hence
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> instead of having
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> odd
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> hacks in the CaR driver, it is much nicer to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper suspend-resume sequencing of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> device
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> drivers. In this case
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver is the driver that enables DFLL and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switches
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to that
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> source, which means that this driver is also
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> should
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> be responsible for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> management of the DFLL's state during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend/resume process. If
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver disables DFLL during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> re-enables it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resume, then looks like the CaR driver hacks
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> around
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL are not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> needed.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL part looks good to me. BTW,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> change the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> patch subject to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "Add
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend-resume support" seems more
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> me.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> To clarify this, the sequences for DFLL use
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> are as
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> follows (assuming
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> required DFLL hw configuration has been
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> done)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch to DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Save current parent and frequency
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2) Enable DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3) Change cclk_g parent to DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For OVR regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Change PWM output pin from tristate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 5) Enable DFLL PWM output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For I2C regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Enable DFLL I2C output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 6) Program DFLL to closed loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch away from DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Change cclk_g parent to PLLP so the CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> frequency is ok for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> any
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> vdd_cpu voltage
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>> I see during switch away from DFLL (suspend),
>>>>>>>>>>>>>>>>>>>>>>>>>>> cclk_g
>>>>>>>>>>>>>>>>>>>>>>>>>>> parent is not
>>>>>>>>>>>>>>>>>>>>>>>>>>> changed to PLLP before changing dfll to open
>>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>>> mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Will add this ...
>>>>>>>>>>>>>>>>>>>>>>>>>> The CPUFreq driver switches parent to PLLP
>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>> probe, similar
>>>>>>>>>>>>>>>>>>>>>>>>>> should be done on suspend.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> I'm also wondering if it's always safe to
>>>>>>>>>>>>>>>>>>>>>>>>>> switch to
>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP in the probe.
>>>>>>>>>>>>>>>>>>>>>>>>>> If CPU is running on a lower freq than PLLP,
>>>>>>>>>>>>>>>>>>>>>>>>>> then
>>>>>>>>>>>>>>>>>>>>>>>>>> some
>>>>>>>>>>>>>>>>>>>>>>>>>> other more
>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate intermediate parent should be
>>>>>>>>>>>>>>>>>>>>>>>>>> selected.
>>>>>>>>>>>>>>>>>>>>>>>>> CPU parents are PLL_X, PLL_P, and dfll. PLL_X
>>>>>>>>>>>>>>>>>>>>>>>>> always
>>>>>>>>>>>>>>>>>>>>>>>>> runs at higher
>>>>>>>>>>>>>>>>>>>>>>>>> rate
>>>>>>>>>>>>>>>>>>>>>>>>> so switching to PLL_P during CPUFreq probe
>>>>>>>>>>>>>>>>>>>>>>>>> prior to
>>>>>>>>>>>>>>>>>>>>>>>>> dfll clock enable
>>>>>>>>>>>>>>>>>>>>>>>>> should be safe.
>>>>>>>>>>>>>>>>>>>>>>>> AFAIK, PLLX could run at ~200MHz. There is also a
>>>>>>>>>>>>>>>>>>>>>>>> divided output of
>>>>>>>>>>>>>>>>>>>>>>>> PLLP
>>>>>>>>>>>>>>>>>>>>>>>> which CCLKG supports, the PLLP_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Probably, realistically, CPU is always running
>>>>>>>>>>>>>>>>>>>>>>>> off a
>>>>>>>>>>>>>>>>>>>>>>>> fast PLLX during
>>>>>>>>>>>>>>>>>>>>>>>> boot, but I'm wondering what may happen on
>>>>>>>>>>>>>>>>>>>>>>>> KEXEC. I
>>>>>>>>>>>>>>>>>>>>>>>> guess ideally CPUFreq driver should also have a
>>>>>>>>>>>>>>>>>>>>>>>> 'shutdown' callback to teardown DFLL
>>>>>>>>>>>>>>>>>>>>>>>> on a reboot, but likely that there are other
>>>>>>>>>>>>>>>>>>>>>>>> clock-related problems as
>>>>>>>>>>>>>>>>>>>>>>>> well that may break KEXEC and thus it is not very
>>>>>>>>>>>>>>>>>>>>>>>> important at the
>>>>>>>>>>>>>>>>>>>>>>>> moment.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> [snip]
>>>>>>>>>>>>>>>>>>>>>>> During bootup CPUG sources from PLL_X. By PLL_P
>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>> above I meant
>>>>>>>>>>>>>>>>>>>>>>> PLL_P_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> As per clock policies, PLL_X is always used for
>>>>>>>>>>>>>>>>>>>>>>> high
>>>>>>>>>>>>>>>>>>>>>>> freq
>>>>>>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>>>>>>>> 800Mhz
>>>>>>>>>>>>>>>>>>>>>>> and for low frequency it will be sourced from PLLP.
>>>>>>>>>>>>>>>>>>>>>> Alright, then please don't forget to pre-initialize
>>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate to a
>>>>>>>>>>>>>>>>>>>>>> reasonable value using tegra_clk_init_table or
>>>>>>>>>>>>>>>>>>>>>> assigned-clocks.
>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate update is not needed as it is safe to
>>>>>>>>>>>>>>>>>>>>> run at
>>>>>>>>>>>>>>>>>>>>> 408Mhz because it is below fmax @ Vmin
>>>>>>>>>>>>>>>>>>>> So even 204MHz CVB entries are having the same
>>>>>>>>>>>>>>>>>>>> voltage as
>>>>>>>>>>>>>>>>>>>> 408MHz, correct? It's not instantly obvious to me
>>>>>>>>>>>>>>>>>>>> from the
>>>>>>>>>>>>>>>>>>>> DFLL driver's code where the fmax @ Vmin is
>>>>>>>>>>>>>>>>>>>> defined, I see
>>>>>>>>>>>>>>>>>>>> that there is the min_millivolts
>>>>>>>>>>>>>>>>>>>> and frequency entries starting from 204MHZ defined
>>>>>>>>>>>>>>>>>>>> per-table.
>>>>>>>>>>>>>>>>>>> Yes at Vmin CPU Fmax is ~800Mhz. So anything below that
>>>>>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>>>>>> work at Vmin voltage and PLLP max is 408Mhz.
>>>>>>>>>>>>>>>>>> Thank you for the clarification. It would be good to
>>>>>>>>>>>>>>>>>> have
>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>> commented
>>>>>>>>>>>>>>>>>> in the code as well.
>>>>>>>>>>>>>>>>> OK, Will add...
>>>>>>>>>>>>>>>> Regarding, adding suspend/resume to CPUFreq, CPUFreq
>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>> happens very early even before disabling non-boot CPUs and
>>>>>>>>>>>>>>>> also
>>>>>>>>>>>>>>>> need to export clock driver APIs to CPUFreq.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Was thinking of below way of implementing this...
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Clock DFLL driver Suspend:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> - Save CPU clock policy registers, and
>>>>>>>>>>>>>>>> Perform
>>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>>> suspend which sets in open loop mode
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> CPU Freq driver Suspend: does nothing
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Clock DFLL driver Resume:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> - Re-init DFLL, Set in Open-Loop mode,
>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>> Clock policy registers which actually sets source to DFLL
>>>>>>>>>>>>>>>> along
>>>>>>>>>>>>>>>> with other CPU Policy register restore.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> CPU Freq driver Resume:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> - do clk_prepare_enable which acutally sets
>>>>>>>>>>>>>>>> DFLL in
>>>>>>>>>>>>>>>> Closed loop mode
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Adding one more note: Switching CPU Clock to PLLP is not
>>>>>>>>>>>>>>>> needed
>>>>>>>>>>>>>>>> as CPU CLock can be from dfll in open-loop mode as DFLL
>>>>>>>>>>>>>>>> is not
>>>>>>>>>>>>>>>> disabled anywhere throught the suspend/resume path and SC7
>>>>>>>>>>>>>>>> entry
>>>>>>>>>>>>>>>> FW and Warm boot code will switch CPU source to PLLP.
>>>>>>>>>>>>>> Since CPU resumes on PLLP, it will be cleaner to suspend
>>>>>>>>>>>>>> it on
>>>>>>>>>>>>>> PLLP as well. And besides, seems that currently disabling
>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>> clock will disable DFLL completely and then you'd want to
>>>>>>>>>>>>>> re-init
>>>>>>>>>>>>>> the DFLL on resume any ways. So better to just disable DFLL
>>>>>>>>>>>>>> completely on suspend, which should happen on
>>>>>>>>>>>>>> clk_disable(dfll).
>>>>>>>>>>>>> Will switch to PLLP during CPUFreq suspend. With decision of
>>>>>>>>>>>>> using
>>>>>>>>>>>>> clk_disable during suspend, its mandatory to switch to
>>>>>>>>>>>>> PLLP as
>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>> is completely disabled.
>>>>>>>>>>>>>
>>>>>>>>>>>>> My earlier concern was on restoring CPU policy as we can't do
>>>>>>>>>>>>> that
>>>>>>>>>>>>> from CPUFreq driver and need export from clock driver.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Clear now and will do CPU clock policy restore in after dfll
>>>>>>>>>>>>> re-init.
>>>>>>>>>>>> Why the policy can't be saved/restored by the CaR driver as a
>>>>>>>>>>>> context of any other clock?
>>>>>>>>>>> restoring cpu clock policy involves programming source and
>>>>>>>>>>> super_cclkg_divider.
>>>>>>>>>>>
>>>>>>>>>>> cclk_g is registered as clk_super_mux and it doesn't use
>>>>>>>>>>> frac_div ops
>>>>>>>>>>> to do save/restore its divider.
>>>>>>>>>> That can be changed of course and I guess it also could be as
>>>>>>>>>> simple as
>>>>>>>>>> saving and restoring of two raw u32 values of the policy/divider
>>>>>>>>>> registers.
>>>>>>>>>>
>>>>>>>>>>> Also, during clock context we cant restore cclk_g as cclk_g
>>>>>>>>>>> source
>>>>>>>>>>> will be dfll and dfll will not be resumed/re-initialized by the
>>>>>>>>>>> time
>>>>>>>>>>> clk_super_mux save/restore happens.
>>>>>>>>>>>
>>>>>>>>>>> we can't use save/restore context for dfll clk_ops because
>>>>>>>>>>> dfllCPU_out parent to CCLK_G is first in the clock tree and
>>>>>>>>>>> dfll_ref
>>>>>>>>>>> and dfll_soc peripheral clocks are not restored by the time
>>>>>>>>>>> dfll
>>>>>>>>>>> restore happens. Also dfll peripheral clock enables need to be
>>>>>>>>>>> restored before dfll restore happens which involves programming
>>>>>>>>>>> dfll
>>>>>>>>>>> controller for re-initialization.
>>>>>>>>>>>
>>>>>>>>>>> So dfll resume/re-init is done in clk-tegra210 at end of all
>>>>>>>>>>> clocks
>>>>>>>>>>> restore in V5 series but instead of in clk-tegra210 driver I
>>>>>>>>>>> moved
>>>>>>>>>>> now to dfll-fcpu driver pm_ops as all dfll dependencies will be
>>>>>>>>>>> restored thru clk_restore_context by then. This will be in V6.
>>>>>>>>>> Since DFLL is now guaranteed to be disabled across CaR
>>>>>>>>>> suspend/resume
>>>>>>>>>> (hence it has nothing to do in regards to CCLK) and given
>>>>>>>>>> that PLLs
>>>>>>>>>> state is restored before the rest of the clocks, I don't see why
>>>>>>>>>> not to
>>>>>>>>>> implement CCLK save/restore in a generic fasion. CPU policy
>>>>>>>>>> wull be
>>>>>>>>>> restored to either PLLP or PLLX (if CPUFreq driver is disabled).
>>>>>>>>>>
>>>>>>>>> CCLK_G save/restore should happen in clk_super_mux ops
>>>>>>>>> save/context and
>>>>>>>>> clk_super_mux save/restore happens very early as cclk_g is first
>>>>>>>>> in the
>>>>>>>>> clock tree and save/restore traverses through the tree top-bottom
>>>>>>>>> order.
>>>>>>>> If CCLK_G is restored before the PLLs, then just change the clocks
>>>>>>>> order
>>>>>>>> such that it won't happen.
>>>>>>>>
>>>>>>> I dont think we can change clocks order for CCLK_G.
>>>>>>>
>>>>>>> During bootup, cclk_g is registered after all pll's and peripheral
>>>>>>> clocks which is the way we wanted, So cclk_g will be the first
>>>>>>> one in
>>>>>>> the clk list as clk_register adds new clock first in the list.
>>>>>>>
>>>>>>> When clk_save_context and clk_restore_context APIs iterates over
>>>>>>> the
>>>>>>> list, cclk_g is the first
>>>>>> Looking at clk_core_restore_context(), I see that it walks up
>>>>>> CLKs list
>>>>>> from parent to children, hence I don't understand how it can ever
>>>>>> happen
>>>>>> that CCLK will be restored before the parent. The clocks
>>>>>> registration
>>>>>> order doesn't matter at all in that case.
>>>>> yes from parent to children and dfllCPU_out is the top in the list
>>>>> and
>>>>> its child is cclk_g.
>>>>>
>>>>> the way clocks are registered is the order I see in the clock list
>>>>> and
>>>>> looking into clk_register API it adds new node first in the list.
>>>>>
>>>> cclkg_g & dfll register happens after all plls and peripheral
>>>> clocks as
>>>> it need ref, soc and peripheral clocks to be enabled.
>>>>> So they are the last to get registered and so becomes first in the
>>>>> list.
>>>>>
>>>>> During save/restore context, it traverses thru this list and first in
>>>>> the list is dfllcpu_OUT (parent) and its child (cclk_g)
>>>>>
>>>>> saving should not be an issue at all but we cant restore cclk_g/dfll
>>>>> in normal way thru clk_ops restore as plls and peripherals restore
>>>>> doesn't happen by that time.
>>>>>
>>>> I was referring to clk_restore_context where it iterates thru root
>>>> list
>>>> and for each core from the root list clk_core_restore does restore of
>>>> parent and children.
>>>>
>>>> dfllCPU_Out gets first in the list and its child is cclk_g
>>>>
>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/clk/clk.c#L1105
>>> What list you're talking about? clk_summary? It shows current *active*
>>> clocks configuration, if you'll try to disable CPUFreq driver then the
>>> parent of CCLK_G should be PLLX. Similarly when CPU is reparented to
>>> PLLP on driver's suspend, then PLLP is the parent.
>>>
>>>>>>>>> DFLL enable thru CPUFreq resume happens after all
>>>>>>>>> clk_restore_context
>>>>>>>>> happens. So during clk_restore_context, dfll re-init doesnt
>>>>>>>>> happen
>>>>>>>>> and
>>>>>>>>> doing cpu clock policy restore during super_mux clk_ops will
>>>>>>>>> crash as
>>>>>>>>> DFLL is not initialized and its clock is not enabled but CPU
>>>>>>>>> clock
>>>>>>>>> restore sets source to DFLL if we restore during super_clk_mux
>>>>>>>> If CPU was suspended on PLLP, then it will be restored on PLLP by
>>>>>>>> CaR. I
>>>>>>>> don't understand what DFLL has to do with the CCLK in that case
>>>>>>>> during
>>>>>>>> the clocks restore.
>>>>>>> My above comment is in reference to your request of doing
>>>>>>> save/restore
>>>>>>> for cclk_g in normal fashion thru save/restore context. Because
>>>>>>> of the
>>>>>>> clk order I mentioned above, we cclk_g will be the first one to
>>>>>>> go thru
>>>>>>> save/context.
>>>>>>>
>>>>>>> During save_context of cclk_g, source can be from PLLX, dfll.
>>>>>>>
>>>>>>> Issue will be when we do restore during clk_restore_context of
>>>>>>> cclk_g as
>>>>>>> by that time PLLX/dfll will not be restored.
>>>>>>>
>>>>>> Seems we already agreed that DFLL will be disabled by the CPUFreq
>>>>>> driver
>>>>>> on suspend. Hence CCLK can't be from DFLL if CPU is reparented to
>>>>>> PLLP
>>>>>> on CPUFreq driver's suspend, otherwise CPU keeps running from a
>>>>>> boot-state PLLX if CPUFreq driver is disabled.
>>>>> Yes suspend should not be an issue but issue will be during resume
>>>>> where if we do cclk_g restore in normal way thru clk_restore_context,
>>>>> cclk_g restore happens very early as dfllCPU out is the first one
>>>>> that
>>>>> goes thru restore context and plls/peripherals are not resumed by
>>>>> then.
>>>>>
>>>>> CPU runs from PLLX if dfll clock enable fails during boot. So when it
>>>>> gets to suspend, we save CPU running clock source as either PLLX or
>>>>> DFLL and then we switch to PLLP.
>>>>>
>>>>>
>>>>> On resume, CPU runs from PLLP by warm boot code and we need to
>>>>> restore
>>>>> back its source to the one it was using from saved source context
>>>>> (which can be either PLLX or DFLL)
>>>>>
>>>>> So PLLs & DFLL resume need to happen before CCLKG restore/resume.
>>>>>
>>>>>
>>>>> With all above discussions, we do DFLL disable in CPUFreq driver on
>>>>> suspend and on CPUFreq resume we enable DFLL back and restore CPU
>>>>> clock source it was using during suspend (which will be either
>>>>> PLLX if
>>>>> dfll enable fails during probe or it will be using DFLL).
>>> During suspend CPU's parent shall be PLLP and not DFLL (note that it is
>>> disabled) after reparenting to PLLP by the CPUFreq driver.
>>>
>> CPU source context should be saved before switching to safe source of
>> PLLP as on resume we need to restore back to source it was using
>> before we switch to safe source during suspend entry.
>>
>> So saved context for CPU Source will be either dfll or PLLX
>>
> PLLP reparenting is only during suspend/entry to have it as safe
> source but actual CPU source it was running from before suspending is
> either dfll/pllx which should be the one to be restored on CPUFreq
> resume. Resume happens with CPU running from PLLP till it gets to the
> point of restoring its original source (dfll or pllx)
>>>>> So i was trying to say dfll/cclk_g restore can't be done in normal
>>>>> way
>>>>> thru clk_ops save/restore context
>>> Let's see what happens if CPUFreq is active:
>>>
>>> 1. CPUFreq driver probe happens
>>> 2. CPU is reparented to PLLP
>>> 3. DFLL inited
>>> 4. CPU is reparented to DFLL
>>>
>>> 5. CPUFreq driver suspend happens
>>> 6. CPU is reparented to PLLP
>>> 7. DFLL is disabled
>>>
>>> 8. Car suspend happens
>>> 9. DFLL context saved
>>> 10. PLLP/PLLX context saved
>>> 11. CCLK context saved
>>>
>>> 12. Car resume happens
>>> 13. DFLL context restored
>>> 14. PLLP/PLLX context restored
>>> 15. CCLK context restored
>>>
>>> 16. CPUFreq driver resume happens
>>> 17. DFLL re-inited
>>> 18. CPU is reparented to DFLL
>>
>>
>> Below is the order of sequence it should be based on the order of clk
>> register.
>>
>> My comments inline in this sequence.
>>
>> 1. CPUFreq driver probe happens
>> 2. CPU is reparented to PLLP
>> 3. DFLL inited
>> 4. CPU is reparented to DFLL
>>
>>
>> 5. CPUFreq driver suspend happens
>> 6. Save CPU source which could be either dfll or pllx
>> 7. CPU is reparented to safe known source PLLP
>> 8. DFLL is disabled
>>
>> 8. Car suspend happens
>> 9. DFLL context saved (With DFLL disabled in CPUFreq suspend,
>> nothing to be saved here as last freq req will always be saved).
>> 10. CCLK context saved (CPU clock source will be saved in CPUFreq
>> driver suspend which could be either dfll or pllx)
>> 11. PLLP/PLLX context saved
>> 12. Peripheral Clock saved
>>
>> 12. Car resume happens
>> 13. DFLL context restored : No DFLL context to be restored and we
>> only need to reinitialize DFLL and re-initialize can't be done here
>> as this is the 1st to get restored and PLL/Peripheral clocks are not
>> restored by this time. So we can't use clk_ops restore for DFLL
>> 14. CCLK context restored
>> CCLK cant be restored here as context could be either dfll or pllx
>> which is the source orginally it was actually using before we force
>> switch to safe PLLP for suspend entry. So we can't use clk_ops
>> restore for DFLL
>>
>> 15. PLLP/PLLX context restored
>> 16. Peripheral context restored
>>
>> 16. CPUFreq driver resume happens
>> 17. DFLL re-inited (Invoking DFLL re-init in CPUFreq resume need
>> exporting DFLL reinit from Clock driver to CPUFreq driver)
>> 18. CPU is reparented to DFLL or PLLX based on saved context from
>> step 9.
>>
>> Note: instead of exporting, we can do DFLL re-init from clock-dfll
>> driver itself thru dfll-fcpu pm_ops resume. So dfll will be
>> re-initialized by the time CPUFreq driver resumes and switches to use
>> DFLL source.
>>
Tested above commented sequence and looks as expected. Will send V6
after addressing other comments of V5 patch series for further review...
^ permalink raw reply
* Re: [PATCH v5 00/26] Add generic support for composing LED class device name
From: Jacek Anaszewski @ 2019-07-17 21:14 UTC (permalink / raw)
To: linux-leds, pavel, dmurphy; +Cc: devicetree, linux-kernel, robh, dtor, linux
In-Reply-To: <20190609190803.14815-1-jacek.anaszewski@gmail.com>
Hi all,
I need explicit acks for some patches from this series, that
were either requested improvements or I modified them by myself
after v4.
The patches I am talking about are the following:
1/26
21/26
23/26
25/26
26/26 would be nice to have but I presume it needs more discussion
and analysis.
Best regards,
Jacek Anaszewski
On 6/9/19 9:07 PM, Jacek Anaszewski wrote:
> Changes from v4:
>
> - switched "charge" function name to "charging"
> - added "cpu", "mute", "micmute", "disk-activity", "panic", "mtd" LED functions
> to cover all existing triggers and removed now redundant "nand" and "mmc"
> - added "capslock", "scrollock", "numlock" LED functions
> - removed now redundant "keyboard" and "keypad" since there is "kbd_backlight"
> already available
> - removed "tv" LED function as depreciated
> - switched LED_COLOR_ID_COUNT to LED_COLOR_ID_MAX
> - fixed led_classdev_register_ext() to not leave struct led_classdev's
> name pointing to no longer existing composed_name stack variable
> - fixed leds-as3645 and leds-aat1290 to no longer rely on struct led_classdev's
> name property
> - added basic LED class device name validation to get_led_device_info.sh
> - tweaked LED naming section in leds_class.txt to allow devicename section
> also for non hot-pluggable devices
> - always initialize all fields of struct led_init_data to zero on declaration
> in drivers
> - fix leds-gpio to avoid overwriting the LED name coming from platform_data
> - add description of LED function names with regard to whether devicename
> section is initialized or not
>
> Changes from v3:
>
> - allow for devicename section for hot-pluggable devices
> - move led_colors array to led-core.c to avoid build break
> due to Kconfig dependency issue
> - add a patch fixing led_colors array name clash with ALSA driver
> - change led-enumerator DT property name to more meaningful function-enumerator
> - add LED_FUNCTION_KBD_BACKLIGHT
> - change naming and add new proprties to struct led_init_data
> and struct led_properties
>
> Changes from v2:
>
> - removed from drivers the responsibility of calling led_compose_name()
> - added struct device* argument to led_compose_name() to allow using
> dev_<level> logging functions for more informative logs
> - adjusted the list of LED_FUNCTION definitions according to the v2 review
> remarks
> - renamed default_desc to default_label in the struct led_init_data
> - added led-enumerator DT property to the common LED bindings
> - removed LED_COLOR_NAME definitions from include/dt-bindings/leds/common.h
> - change DT color property type from string to integer
> - change struct initialization list to explicit property assignment in leds-sc27xx-bltc.c
> - use led->client->name for led_hw_name in leds-lm3692x.c
> - few other minor improvements to docs etc.
>
> Changes from v1:
>
> - improved led_parse_properties() to parse label property at first
> and return immediately after parsing succeeds
> - added tool get_led_device_info.sh for retrieving LED class device's
> parent device related information
> - extended LED naming section of Documentation/leds/leds-class.txt
> - adjusted the list of LED_FUNCTION definitions according to the v1 review
> remarks
> - added standard LED_COLOR_NAME definitions
> - removed functions.h and moved both LED_FUNCTION and LED_COLOR_NAME
> definitions to include/dt-bindings/common.h
> - rebased leds-as3645a changes on top of the patch switching to fwnode
> property API
> - updated DT bindings to use new LED_COLOR_NAME definitions
> - improved common LED bindings to not use address unit for sub-nodes
> without reg property
>
> Generally I still insist on deprecating label property and devicename
> section of LED name. The tool I added for obtaining LED device name
> proves availability of the related information in other places in
> the sysfs. Other discussed use cases are covered in the updated
> Documentation/leds/leds-class.txt.
>
> Beside that, I tried also to create macros for automatic composition
> of "-N" suffixed LED functions, so that it would not be necessary
> to pollute common.h with plenty repetitions of the same function,
> differing only with the postfix. Unfortunately, the preprocessor
> of the dtc compiler seems not to accept string concatenetation.
> I.e. it is not possible to to the following assighment:
>
> function = "hdd""-1"
>
> If anyone knows how to obviate this shortocoming please let me know.
>
> Original cover letter:
>
> LED class device naming pattern included devicename section, which had
> unpleasant effect of varying userspace interface dependent on underlaying
> hardware. Moreover, this information was redundant in the LED name, since
> the LED controller name could have been obtained from sysfs device group
>
> This patch set introduces a led_compose_name() function in the LED core,
> which unifies and simplifies LED class device name composition. This
> change is accompanied by the improvements in the common LED DT bindings
> where two new properties are introduced: "function" and "color" . The two
> deprecate the old "label" property which was leaving too much room for
> interpretation, leading to inconsistent LED naming.
>
> There are also changes in LED DT node naming, which are in line with
> DT maintainer's request from [0].
>
> Since some DT LED naming unification, related to not including devicename
> section in "label" DT property, is being requested during reviews of new
> LED class drivers for almost a year now, then those drivers are the first
> candidates for optimalization and the first users of the new
> led_compose_name() API. The modifications were tested with Qemu,
> by stubbing the driver internals where hardware interaction was needed
> for proper probing.
>
> Thanks,
> Jacek Anaszewski
>
> Jacek Anaszewski (26):
> leds: class: Improve LED and LED flash class registration API
> dt-bindings: leds: Add LED_COLOR_ID definitions
> dt-bindings: leds: Add LED_FUNCTION definitions
> dt-bindings: leds: Add properties for LED name construction
> leds: core: Add support for composing LED class device names
> dt-bindings: sc27xx-blt: Add function and color properties
> leds: sc27xx-blt: Use generic support for composing LED names
> dt-bindings: lt3593: Add function and color properties
> leds: lt3593: Use generic support for composing LED names
> dt-bindings: lp8860: Add function and color properties
> leds: lp8860: Use generic support for composing LED names
> dt-bindings: lm3692x: Add function and color properties
> leds: lm3692x: Use generic support for composing LED names
> dt-bindings: lm36010: Add function and color properties
> leds: lm3601x: Use generic support for composing LED names
> dt-bindings: cr0014114: Add function and color properties
> leds: cr0014114: Use generic support for composing LED names
> dt-bindings: aat1290: Add function and color properties
> leds: aat1290: Use generic support for composing LED names
> dt-bindings: as3645a: Add function and color properties
> leds: as3645a: Use generic support for composing LED names
> dt-bindings: leds-gpio: Add function and color properties
> leds: gpio: Use generic support for composing LED names
> dt-bindings: an30259a: Add function and color properties
> leds: an30259a: Use generic support for composing LED names
> leds: Document standard LED functions
>
> .../devicetree/bindings/leds/ams,as3645a.txt | 22 +-
> Documentation/devicetree/bindings/leds/common.txt | 62 +++++-
> .../devicetree/bindings/leds/leds-aat1290.txt | 12 +-
> .../devicetree/bindings/leds/leds-an30259a.txt | 22 +-
> .../devicetree/bindings/leds/leds-cr0014114.txt | 26 ++-
> .../devicetree/bindings/leds/leds-gpio.txt | 23 ++-
> .../devicetree/bindings/leds/leds-lm3601x.txt | 10 +-
> .../devicetree/bindings/leds/leds-lm3692x.txt | 9 +-
> .../devicetree/bindings/leds/leds-lp8860.txt | 9 +-
> .../devicetree/bindings/leds/leds-lt3593.txt | 11 +-
> .../devicetree/bindings/leds/leds-sc27xx-bltc.txt | 10 +-
> Documentation/leds/led-functions.txt | 223 +++++++++++++++++++++
> Documentation/leds/leds-class.txt | 70 ++++++-
> drivers/leds/led-class-flash.c | 9 +-
> drivers/leds/led-class.c | 49 +++--
> drivers/leds/led-core.c | 127 ++++++++++++
> drivers/leds/leds-aat1290.c | 16 +-
> drivers/leds/leds-an30259a.c | 25 +--
> drivers/leds/leds-as3645a.c | 74 +++----
> drivers/leds/leds-cr0014114.c | 33 +--
> drivers/leds/leds-gpio.c | 26 +--
> drivers/leds/leds-lm3601x.c | 38 ++--
> drivers/leds/leds-lm3692x.c | 22 +-
> drivers/leds/leds-lp8860.c | 35 ++--
> drivers/leds/leds-lt3593.c | 20 +-
> drivers/leds/leds-pwm.c | 2 +-
> drivers/leds/leds-sc27xx-bltc.c | 22 +-
> drivers/leds/leds.h | 1 +
> include/dt-bindings/leds/common.h | 55 ++++-
> include/linux/led-class-flash.h | 15 +-
> include/linux/leds.h | 79 +++++++-
> tools/leds/get_led_device_info.sh | 201 +++++++++++++++++++
> 32 files changed, 1086 insertions(+), 272 deletions(-)
> create mode 100644 Documentation/leds/led-functions.txt
> create mode 100755 tools/leds/get_led_device_info.sh
>
^ permalink raw reply
* Re: [PATCH v5 05/26] leds: core: Add support for composing LED class device names
From: Jacek Anaszewski @ 2019-07-17 21:03 UTC (permalink / raw)
To: Pavel Machek
Cc: linux-leds, devicetree, linux-kernel, robh, dtor, linux, dmurphy,
Baolin Wang, Daniel Mack, Linus Walleij, Oleh Kravchenko,
Sakari Ailus, Simon Shields
In-Reply-To: <20190703220043.GA876@amd>
Hi Pavel,
On 7/4/19 12:00 AM, Pavel Machek wrote:
> Hi!
>
> Sorry for the delay.
No problem.
>> @@ -27,6 +29,18 @@ EXPORT_SYMBOL_GPL(leds_list_lock);
>> LIST_HEAD(leds_list);
>> EXPORT_SYMBOL_GPL(leds_list);
>>
>> +const char *led_colors[LED_COLOR_ID_MAX] = {
>
> const char * const , if we want to play that game?
Ack.
>> + [LED_COLOR_ID_WHITE] = "white",
>> + [LED_COLOR_ID_RED] = "red",
>> + [LED_COLOR_ID_GREEN] = "green",
>> + [LED_COLOR_ID_BLUE] = "blue",
>> + [LED_COLOR_ID_AMBER] = "amber",
>> + [LED_COLOR_ID_VIOLET] = "violet",
>> + [LED_COLOR_ID_YELLOW] = "yellow",
>> + [LED_COLOR_ID_IR] = "ir",
>> +};
>> +EXPORT_SYMBOL_GPL(led_colors);
>> +
>
>> + if (fwnode_property_present(fwnode, "label")) {
>> + ret = fwnode_property_read_string(fwnode, "label", &props->label);
>> + if (ret)
>> + dev_err(dev, "Error parsing \'label\' property (%d)\n", ret);
>> + return;
>
> I don't think you need to escape ' with \.
Right.
>> + if (fwnode_property_present(fwnode, "function")) {
>> + ret = fwnode_property_read_string(fwnode, "function", &props->function);
>> + if (ret) {
>> + dev_err(dev,
>> + "Error parsing \'function\' property (%d)\n",
>> + ret);
>> + }
>> + } else {
>> + return;
>> + }
>
>> +
>> + if (fwnode_property_present(fwnode, "function-enumerator")) {
>
> I'd do if (!fwnode_property_present()) return; in both occasions, to
> save an indentation level; but that's nitpicking.
Ack.
>> + if (props.label) {
>> + /*
>> + * If init_data.devicename is NULL, then it indicates that
>> + * DT label should be used as-is for LED class device name.
>> + * Otherwise the label is prepended with devicename to compose
>> + * the final LED class device name.
>> + */
>> + if (!devicename) {
>> + strncpy(led_classdev_name, props.label,
>> + LED_MAX_NAME_SIZE);
>> + } else {
>> + snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s",
>> + devicename, props.label);
>> + }
>
> Unlike snprintf(), strncpy() does not guarantee NULL termination.
Indeed. I'll change strncpy to strscpy.
> I did not check the shell script.
>
> With that fixed,
>
> Acked-by: Pavel Machek <pavel@ucw.cz>
Thanks!
--
Best regards,
Jacek Anaszewski
^ permalink raw reply
* Re: [PATCH v5 02/11] of/platform: Add functional dependency link from DT bindings
From: Saravana Kannan @ 2019-07-17 20:38 UTC (permalink / raw)
To: Rob Herring
Cc: Mark Rutland, Greg Kroah-Hartman, Rafael J. Wysocki, Frank Rowand,
Jonathan Corbet,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
linux-kernel@vger.kernel.org, David Collins, Android Kernel Team,
Linux Doc Mailing List
In-Reply-To: <CAL_Jsq+Dfm8ng1OVcB+1N2ack05v8+u1VydfxM4Ukefqd9XK2w@mail.gmail.com>
On Wed, Jul 17, 2019 at 7:35 AM Rob Herring <robh+dt@kernel.org> wrote:
>
> On Tue, Jul 16, 2019 at 5:54 PM Saravana Kannan <saravanak@google.com> wrote:
> >
> > On Tue, Jul 16, 2019 at 4:43 PM Rob Herring <robh+dt@kernel.org> wrote:
> > >
> > > On Fri, Jul 12, 2019 at 5:52 PM Saravana Kannan <saravanak@google.com> wrote:
> > > >
> > > > Add device-links after the devices are created (but before they are
> > > > probed) by looking at common DT bindings like clocks and
> > > > interconnects.
> > > >
> > > > Automatically adding device-links for functional dependencies at the
> > > > framework level provides the following benefits:
> > > >
> > > > - Optimizes device probe order and avoids the useless work of
> > > > attempting probes of devices that will not probe successfully
> > > > (because their suppliers aren't present or haven't probed yet).
> > > >
> > > > For example, in a commonly available mobile SoC, registering just
> > > > one consumer device's driver at an initcall level earlier than the
> > > > supplier device's driver causes 11 failed probe attempts before the
> > > > consumer device probes successfully. This was with a kernel with all
> > > > the drivers statically compiled in. This problem gets a lot worse if
> > > > all the drivers are loaded as modules without direct symbol
> > > > dependencies.
> > > >
> > > > - Supplier devices like clock providers, interconnect providers, etc
> > > > need to keep the resources they provide active and at a particular
> > > > state(s) during boot up even if their current set of consumers don't
> > > > request the resource to be active. This is because the rest of the
> > > > consumers might not have probed yet and turning off the resource
> > > > before all the consumers have probed could lead to a hang or
> > > > undesired user experience.
> > > >
> > > > Some frameworks (Eg: regulator) handle this today by turning off
> > > > "unused" resources at late_initcall_sync and hoping all the devices
> > > > have probed by then. This is not a valid assumption for systems with
> > > > loadable modules. Other frameworks (Eg: clock) just don't handle
> > > > this due to the lack of a clear signal for when they can turn off
> > > > resources. This leads to downstream hacks to handle cases like this
> > > > that can easily be solved in the upstream kernel.
> > > >
> > > > By linking devices before they are probed, we give suppliers a clear
> > > > count of the number of dependent consumers. Once all of the
> > > > consumers are active, the suppliers can turn off the unused
> > > > resources without making assumptions about the number of consumers.
> > > >
> > > > By default we just add device-links to track "driver presence" (probe
> > > > succeeded) of the supplier device. If any other functionality provided
> > > > by device-links are needed, it is left to the consumer/supplier
> > > > devices to change the link when they probe.
> > > >
> > > > Signed-off-by: Saravana Kannan <saravanak@google.com>
> > > > ---
> > > > .../admin-guide/kernel-parameters.txt | 5 ++
> > > > drivers/of/platform.c | 57 +++++++++++++++++++
> > > > 2 files changed, 62 insertions(+)
> > > >
> > > > diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> > > > index 138f6664b2e2..109b4310844f 100644
> > > > --- a/Documentation/admin-guide/kernel-parameters.txt
> > > > +++ b/Documentation/admin-guide/kernel-parameters.txt
> > > > @@ -3141,6 +3141,11 @@
> > > > This can be set from sysctl after boot.
> > > > See Documentation/sysctl/vm.txt for details.
> > > >
> > > > + of_devlink [KNL] Make device links from common DT bindings. Useful
> > > > + for optimizing probe order and making sure resources
> > > > + aren't turned off before the consumer devices have
> > > > + probed.
> > > > +
> > > > ohci1394_dma=early [HW] enable debugging via the ohci1394 driver.
> > > > See Documentation/debugging-via-ohci1394.txt for more
> > > > info.
> > > > diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> > > > index 04ad312fd85b..0930f9f89571 100644
> > > > --- a/drivers/of/platform.c
> > > > +++ b/drivers/of/platform.c
> > > > @@ -509,6 +509,62 @@ int of_platform_default_populate(struct device_node *root,
> > > > }
> > > > EXPORT_SYMBOL_GPL(of_platform_default_populate);
> > > >
> > > > +static int of_link_binding(struct device *dev,
> > > > + const char *binding, const char *cell)
> > > > +{
> > > > + struct of_phandle_args sup_args;
> > > > + struct platform_device *sup_dev;
> > > > + unsigned int i = 0, links = 0;
> > > > + u32 dl_flags = DL_FLAG_AUTOPROBE_CONSUMER;
> > > > +
> > > > + while (!of_parse_phandle_with_args(dev->of_node, binding, cell, i,
> > > > + &sup_args)) {
> > > > + i++;
> > > > + sup_dev = of_find_device_by_node(sup_args.np);
> > > > + of_node_put(sup_args.np);
> > > > + if (!sup_dev)
> > > > + continue;
> > > > + if (device_link_add(dev, &sup_dev->dev, dl_flags))
> > > > + links++;
> > > > + put_device(&sup_dev->dev);
> > > > + }
> > > > + if (links < i)
> > > > + return -ENODEV;
> > > > + return 0;
> > > > +}
> > > > +
> > > > +static bool of_devlink;
> > > > +core_param(of_devlink, of_devlink, bool, 0);
> > > > +
> > > > +/*
> > > > + * List of bindings and their cell names (use NULL if no cell names) from which
> > > > + * device links need to be created.
> > > > + */
> > > > +static const char * const link_bindings[] = {
> > > > + "clocks", "#clock-cells",
> > > > + "interconnects", "#interconnect-cells",
> > > > +};
> > > > +
> > > > +static int of_link_to_suppliers(struct device *dev)
> > > > +{
> > > > + unsigned int i = 0;
> > > > + bool done = true;
> > > > +
> > > > + if (!of_devlink)
> > > > + return 0;
> > > > + if (unlikely(!dev->of_node))
> > > > + return 0;
> > > > +
> > > > + for (i = 0; i < ARRAY_SIZE(link_bindings) / 2; i++)
> > > > + if (of_link_binding(dev, link_bindings[i * 2],
> > > > + link_bindings[i * 2 + 1]))
> > > > + done = false;
> > >
> > > Given the pending addition of regulators I think this should be
> > > structured a bit differently so that we abstract out the matching and
> > > phandle look-up so there's a clean separation of binding specifics.
> > > It's kind of messy with 2 patterns to parse already and if we added a
> > > 3rd? I would iterate over the properties as you do for regulators in
> > > both cases and for each property call a binding specific match
> > > function. The common pattern can of course be a common function. Let
> > > me know if that makes sense. If not I can try to flesh it out some
> > > more.
> >
> > I've added regulator support in this series and I've refactored this
> > code as I went along. I fully expect to squash some of the refactors
> > once the final result of the series is acceptable.
>
> It would be easier to review the final result than incremental changes
> which change the prior patches especially if the latter patches are
> ultimately required.
>
> > It's not clear to me if you got to the end of the series and still
> > think the final result needs to be refactored. Let me know what you
> > think about this towards the end of the series and I can clean it up
> > if you still think it needs some clean up.
>
> I probably should have replied on the regulator addition, but yes,
> looking at that is what prompted my concerns here.
Sounds good. Let me refactor the series and send it out again. Btw, if
you have other issues you noticed, I'd be happy to fix those too
before sending out the v6 of the series again.
-Saravana
^ permalink raw reply
* Re: [PATCH v3 0/6] Introduce Bandwidth OPPs for interconnect paths
From: Saravana Kannan @ 2019-07-17 20:34 UTC (permalink / raw)
To: Viresh Kumar
Cc: Georgi Djakov, Rob Herring, Mark Rutland, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, Vincent Guittot,
Sweeney, Sean, daidavid1, Rajendra Nayak, Sibi Sankar,
Bjorn Andersson, Evan Green, Android Kernel Team, Linux PM,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, LKML
In-Reply-To: <20190717103220.f7cys267hq23fbsb@vireshk-i7>
On Wed, Jul 17, 2019 at 3:32 AM Viresh Kumar <viresh.kumar@linaro.org> wrote:
>
> On 02-07-19, 18:10, Saravana Kannan wrote:
> > Interconnects and interconnect paths quantify their performance levels in
> > terms of bandwidth and not in terms of frequency. So similar to how we have
> > frequency based OPP tables in DT and in the OPP framework, we need
> > bandwidth OPP table support in the OPP framework and in DT. Since there can
> > be more than one interconnect path used by a device, we also need a way to
> > assign a bandwidth OPP table to an interconnect path.
> >
> > This patch series:
> > - Adds opp-peak-KBps and opp-avg-KBps properties to OPP DT bindings
> > - Adds interconnect-opp-table property to interconnect DT bindings
> > - Adds OPP helper functions for bandwidth OPP tables
> > - Adds icc_get_opp_table() to get the OPP table for an interconnect path
> >
> > So with the DT bindings added in this patch series, the DT for a GPU
> > that does bandwidth voting from GPU to Cache and GPU to DDR would look
> > something like this:
> >
> > gpu_cache_opp_table: gpu_cache_opp_table {
> > compatible = "operating-points-v2";
> >
> > gpu_cache_3000: opp-3000 {
> > opp-peak-KBps = <3000>;
> > opp-avg-KBps = <1000>;
> > };
> > gpu_cache_6000: opp-6000 {
> > opp-peak-KBps = <6000>;
> > opp-avg-KBps = <2000>;
> > };
> > gpu_cache_9000: opp-9000 {
> > opp-peak-KBps = <9000>;
> > opp-avg-KBps = <9000>;
> > };
> > };
> >
> > gpu_ddr_opp_table: gpu_ddr_opp_table {
> > compatible = "operating-points-v2";
> >
> > gpu_ddr_1525: opp-1525 {
> > opp-peak-KBps = <1525>;
> > opp-avg-KBps = <452>;
> > };
> > gpu_ddr_3051: opp-3051 {
> > opp-peak-KBps = <3051>;
> > opp-avg-KBps = <915>;
> > };
> > gpu_ddr_7500: opp-7500 {
> > opp-peak-KBps = <7500>;
> > opp-avg-KBps = <3000>;
> > };
> > };
>
> Who is going to use the above tables and how ?
In this example the GPU driver would use these. It'll go through these
and then decide what peak and average bw to pick based on whatever
criteria.
> These are the maximum
> BW available over these paths, right ?
I wouldn't call them "maximum" because there can't be multiple
maximums :) But yes, these are the meaningful bandwidth from the GPU's
perspective to use over these paths.
>
> > gpu_opp_table: gpu_opp_table {
> > compatible = "operating-points-v2";
> > opp-shared;
> >
> > opp-200000000 {
> > opp-hz = /bits/ 64 <200000000>;
> > };
> > opp-400000000 {
> > opp-hz = /bits/ 64 <400000000>;
> > };
> > };
>
> Shouldn't this link back to the above tables via required-opp, etc ?
> How will we know how much BW is required by the GPU device for all the
> paths ?
If that's what the GPU driver wants to do, then yes. But the GPU
driver could also choose to scale the bandwidth for these paths based
on multiple other signals. Eg: bus port busy percentage, measure
bandwidth, etc.
Or they might even decide to pick the BW OPP that matches the index of
their GPU OPP. It's up to them how they actually do the heuristic.
-Saravana
^ permalink raw reply
* Re: [PATCH v3 1/6] dt-bindings: opp: Introduce opp-peak-KBps and opp-avg-KBps bindings
From: Saravana Kannan @ 2019-07-17 20:29 UTC (permalink / raw)
To: Viresh Kumar
Cc: Georgi Djakov, Rob Herring, Mark Rutland, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, Vincent Guittot,
Sweeney, Sean, daidavid1, Rajendra Nayak, Sibi Sankar,
Bjorn Andersson, Evan Green, Android Kernel Team, Linux PM,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, LKML
In-Reply-To: <20190717075448.xlyg2ddewlci3abg@vireshk-i7>
On Wed, Jul 17, 2019 at 12:54 AM Viresh Kumar <viresh.kumar@linaro.org> wrote:
>
> On 02-07-19, 18:10, Saravana Kannan wrote:
> > Interconnects often quantify their performance points in terms of
> > bandwidth. So, add opp-peak-KBps (required) and opp-avg-KBps (optional) to
> > allow specifying Bandwidth OPP tables in DT.
> >
> > opp-peak-KBps is a required property that replace opp-hz for Bandwidth OPP
> > tables.
> >
> > opp-avg-KBps is an optional property that can be used in Bandwidth OPP
> > tables.
> >
> > Signed-off-by: Saravana Kannan <saravanak@google.com>
> > ---
> > Documentation/devicetree/bindings/opp/opp.txt | 15 ++++++++++++---
> > 1 file changed, 12 insertions(+), 3 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/opp/opp.txt b/Documentation/devicetree/bindings/opp/opp.txt
> > index 76b6c79604a5..c869e87caa2a 100644
> > --- a/Documentation/devicetree/bindings/opp/opp.txt
> > +++ b/Documentation/devicetree/bindings/opp/opp.txt
> > @@ -83,9 +83,14 @@ properties.
> >
> > Required properties:
> > - opp-hz: Frequency in Hz, expressed as a 64-bit big-endian integer. This is a
> > - required property for all device nodes but devices like power domains. The
> > - power domain nodes must have another (implementation dependent) property which
> > - uniquely identifies the OPP nodes.
> > + required property for all device nodes but for devices like power domains or
> > + bandwidth opp tables. The power domain nodes must have another (implementation
> > + dependent) property which uniquely identifies the OPP nodes. The interconnect
> > + opps are required to have the opp-peak-bw property.
>
> ??
Sorry, what's the question? Was this an accidental email?
-Saravana
>
> > +
> > +- opp-peak-KBps: Peak bandwidth in kilobytes per second, expressed as a 32-bit
> > + big-endian integer. This is a required property for all devices that don't
> > + have opp-hz. For example, bandwidth OPP tables for interconnect paths.
> >
> > Optional properties:
> > - opp-microvolt: voltage in micro Volts.
> > @@ -132,6 +137,10 @@ Optional properties:
> > - opp-level: A value representing the performance level of the device,
> > expressed as a 32-bit integer.
> >
> > +- opp-avg-KBps: Average bandwidth in kilobytes per second, expressed as a
> > + 32-bit big-endian integer. This property is only meaningful in OPP tables
> > + where opp-peak-KBps is present.
> > +
> > - clock-latency-ns: Specifies the maximum possible transition latency (in
> > nanoseconds) for switching to this OPP from any other OPP.
> >
> > --
> > 2.22.0.410.gd8fdbe21b5-goog
>
> --
> viresh
>
> --
> To unsubscribe from this group and stop receiving emails from it, send an email to kernel-team+unsubscribe@android.com.
>
^ permalink raw reply
* Re: [PATCH] clk: imx8: Add DSP related clocks
From: Daniel Baluta @ 2019-07-17 20:17 UTC (permalink / raw)
To: Daniel Baluta, Jacky Bai
Cc: Shawn Guo, Michael Turquette, Stephen Boyd, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, dl-linux-imx, Rob Herring,
Mark Rutland, Aisheng Dong, weiyongjun1, linux-clk,
linux-arm-kernel, Linux Kernel Mailing List, Devicetree List,
S.j. Wang
In-Reply-To: <20190702152007.12190-1-daniel.baluta@nxp.com>
Aisheng/Jacky,
Can you help with review on this?
On Tue, Jul 2, 2019 at 6:22 PM Daniel Baluta <daniel.baluta@nxp.com> wrote:
>
> i.MX8QXP contains Hifi4 DSP. There are four clocks
> associated with DSP:
> * dsp_lpcg_core_clk
> * dsp_lpcg_ipg_clk
> * dsp_lpcg_adb_aclk
> * ocram_lpcg_ipg_clk
>
> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
> ---
> drivers/clk/imx/clk-imx8qxp-lpcg.c | 5 +++++
> include/dt-bindings/clock/imx8-clock.h | 6 +++++-
> 2 files changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/imx/clk-imx8qxp-lpcg.c b/drivers/clk/imx/clk-imx8qxp-lpcg.c
> index fb6edf1b8aa2..c0aff7ca6374 100644
> --- a/drivers/clk/imx/clk-imx8qxp-lpcg.c
> +++ b/drivers/clk/imx/clk-imx8qxp-lpcg.c
> @@ -72,6 +72,11 @@ static const struct imx8qxp_lpcg_data imx8qxp_lpcg_adma[] = {
> { IMX_ADMA_LPCG_I2C2_CLK, "i2c2_lpcg_clk", "i2c2_clk", 0, ADMA_LPI2C_2_LPCG, 0, 0, },
> { IMX_ADMA_LPCG_I2C3_IPG_CLK, "i2c3_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPI2C_3_LPCG, 16, 0, },
> { IMX_ADMA_LPCG_I2C3_CLK, "i2c3_lpcg_clk", "i2c3_clk", 0, ADMA_LPI2C_3_LPCG, 0, 0, },
> +
> + { IMX_ADMA_LPCG_DSP_CORE_CLK, "dsp_lpcg_core_clk", "dma_ipg_clk_root", 0, ADMA_HIFI_LPCG, 28, 0, },
> + { IMX_ADMA_LPCG_DSP_IPG_CLK, "dsp_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_HIFI_LPCG, 20, 0, },
> + { IMX_ADMA_LPCG_DSP_ADB_CLK, "dsp_lpcg_adb_clk", "dma_ipg_clk_root", 0, ADMA_HIFI_LPCG, 16, 0, },
> + { IMX_ADMA_LPCG_OCRAM_IPG_CLK, "ocram_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_OCRAM_LPCG, 16, 0, },
> };
>
> static const struct imx8qxp_ss_lpcg imx8qxp_ss_adma = {
> diff --git a/include/dt-bindings/clock/imx8-clock.h b/include/dt-bindings/clock/imx8-clock.h
> index 4236818e3be5..673a8c662340 100644
> --- a/include/dt-bindings/clock/imx8-clock.h
> +++ b/include/dt-bindings/clock/imx8-clock.h
> @@ -283,7 +283,11 @@
> #define IMX_ADMA_LPCG_PWM_IPG_CLK 38
> #define IMX_ADMA_LPCG_LCD_PIX_CLK 39
> #define IMX_ADMA_LPCG_LCD_APB_CLK 40
> +#define IMX_ADMA_LPCG_DSP_ADB_CLK 41
> +#define IMX_ADMA_LPCG_DSP_IPG_CLK 42
> +#define IMX_ADMA_LPCG_DSP_CORE_CLK 43
> +#define IMX_ADMA_LPCG_OCRAM_IPG_CLK 44
>
> -#define IMX_ADMA_LPCG_CLK_END 41
> +#define IMX_ADMA_LPCG_CLK_END 45
>
> #endif /* __DT_BINDINGS_CLOCK_IMX_H */
> --
> 2.17.1
>
^ permalink raw reply
* Re: [PATCH 12/12] arm64: dts: qcom: Enable Q6v5 WCSS for ipq8074 SoC
From: Stephen Boyd @ 2019-07-17 20:13 UTC (permalink / raw)
To: agross, bjorn.andersson, david.brown, devicetree, gokulsri,
jassisinghbrar, linux-arm-msm, linux-clk, linux-kernel,
linux-remoteproc, mark.rutland, mturquette, ohad, robh+dt,
sricharan
In-Reply-To: <1562859668-14209-13-git-send-email-gokulsri@codeaurora.org>
Quoting Gokul Sriram Palanisamy (2019-07-11 08:41:08)
> diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
> index 6a61a63..c24e3f6 100644
> --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
> +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
> @@ -10,6 +10,22 @@
> model = "Qualcomm Technologies, Inc. IPQ8074";
> compatible = "qcom,ipq8074";
>
> + reserved-memory {
> + #address-cells = <2>;
> + #size-cells = <2>;
> + ranges;
> +
> + smem_region:smem@4ab00000 {
Put a space between the colon and the node name. Also, just call it
memory@4ab00000.
smem_region: memory@4ab00000 {
> + no-map;
> + reg = <0x0 0x4ab00000 0x0 0x00100000>;
> + };
> +
> + q6_region: q6@4b000000 {
memory@
> + no-map;
> + reg = <0x0 0x4b000000 0x0 0x05f00000>;
> + };
> + };
> +
> firmware {
> scm {
> compatible = "qcom,scm-ipq8074", "qcom,scm";
> @@ -431,6 +447,115 @@
> "axi_m_sticky";
> status = "disabled";
> };
> + apcs: syscon@b111000 {
Add a newline between nodes please.
> + compatible = "syscon";
> + reg = <0x0B111000 0x1000>;
> + };
> +
> + wcss: smp2p-wcss {
This node should be outside the soc node because it doesn't have a reg
property
> + compatible = "qcom,smp2p";
> + qcom,smem = <435>, <428>;
> +
> + interrupt-parent = <&intc>;
> + interrupts = <0 322 1>;
> +
> + qcom,ipc = <&apcs 8 9>;
> +
> + qcom,local-pid = <0>;
> + qcom,remote-pid = <1>;
> +
> + wcss_smp2p_out: master-kernel {
> + qcom,entry-name = "master-kernel";
> + qcom,smp2p-feature-ssr-ack;
> + #qcom,smem-state-cells = <1>;
> + };
> +
> + wcss_smp2p_in: slave-kernel {
> + qcom,entry-name = "slave-kernel";
> +
> + interrupt-controller;
> + #interrupt-cells = <2>;
> + };
> + };
> +
> + tcsr_q6_block: syscon@1945000 {
Do you really need _block in these aliases?
> + compatible = "syscon";
> + reg = <0x1945000 0xE000>;
> + };
> +
> + tcsr_mutex_block: syscon@193d000 {
> + compatible = "syscon";
> + reg = <0x1905000 0x8000>;
> + };
> +
> + tcsr_mutex: hwlock@193d000 {
> + compatible = "qcom,tcsr-mutex";
> + syscon = <&tcsr_mutex_block 0 0x80>;
> + #hwlock-cells = <1>;
> + };
> +
> + smem: qcom,smem@4AB00000 {
lowercase please. And just 'smem' I guess.
> + compatible = "qcom,smem";
> + memory-region = <&smem_region>;
> + hwlocks = <&tcsr_mutex 0>;
> + };
> +
> + apcs_glb: mailbox@b111000 {
> + compatible = "qcom,ipq8074-apcs-apps-global";
> + reg = <0xb111000 0x1000>;
These addresses should be padded out to 8 digits for the address part
(not the size).
> +
> + #mbox-cells = <1>;
> + };
> +
> + q6v5_wcss: q6v5_wcss@CD00000 {
lowercase.
> + compatible = "qcom,ipq8074-wcss-pil";
> + reg = <0xCD00000 0x4040>,
> + <0x4AB000 0x20>;
^ permalink raw reply
* [PATCH 2/3 v4] dt-bindings: gpio: aspeed: Add SGPIO support
From: Hongwei Zhang @ 2019-07-17 20:12 UTC (permalink / raw)
To: Joel Stanley, Andrew Jeffery, Linus Walleij, devicetree
Cc: Hongwei Zhang, Rob Herring, Mark Rutland, Bartosz Golaszewski,
linux-aspeed, linux-kernel, linux-arm-kernel, linux-gpio
Add bindings to support SGPIO on AST2400 or AST2500.
Signed-off-by: Hongwei Zhang <hongweiz@ami.com>
---
.../devicetree/bindings/gpio/sgpio-aspeed.txt | 55 ++++++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt
diff --git a/Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt b/Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt
new file mode 100644
index 0000000..2d6305e
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt
@@ -0,0 +1,55 @@
+Aspeed SGPIO controller Device Tree Bindings
+-------------------------------------------
+
+This SGPIO controller is for ASPEED AST2500 SoC, it supports up to 80 full
+featured Serial GPIOs. Each of the Serial GPIO pins can be programmed to
+support the following options:
+- Support interrupt option for each input port and various interrupt
+ sensitivity option (level-high, level-low, edge-high, edge-low)
+- Support reset tolerance option for each output port
+- Directly connected to APB bus and its shift clock is from APB bus clock
+ divided by a programmable value.
+- Co-work with external signal-chained TTL components (74LV165/74LV595)
+
+
+Required properties:
+
+- compatible : Either "aspeed,ast2400-sgpio" or "aspeed,ast2500-sgpio"
+
+- #gpio-cells : Should be two
+ - First cell is the GPIO line number
+ - Second cell is used to specify optional
+ parameters (unused)
+
+- reg : Address and length of the register set for the device
+- gpio-controller : Marks the device node as a GPIO controller
+- interrupts : Interrupt specifier (see interrupt bindings for
+ details)
+
+- interrupt-controller : Mark the GPIO controller as an interrupt-controller
+
+- nr-gpios : number of GPIO pins to serialise.
+ (should be multiple of 8, up to 80 pins)
+
+- clocks : A phandle to the APB clock for SGPM clock division
+
+- bus-frequency : SGPM CLK frequency
+
+
+The sgpio and interrupt properties are further described in their respective bindings documentation:
+
+- Documentation/devicetree/bindings/sgpio/gpio.txt
+- Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+ Example:
+ sgpio: sgpio@1e780200 {
+ #gpio-cells = <2>;
+ compatible = "aspeed,ast2500-sgpio";
+ gpio-controller;
+ interrupts = <40>;
+ reg = <0x1e780200 0x0100>;
+ clocks = <&syscon ASPEED_CLK_APB>;
+ interrupt-controller;
+ nr-gpios = <8>;
+ bus-frequency = <12000000>;
+ };
--
2.7.4
^ permalink raw reply related
* Re: [PATCH V5 11/18] clk: tegra210: Add support for Tegra210 clocks
From: Sowjanya Komatineni @ 2019-07-17 20:11 UTC (permalink / raw)
To: Dmitry Osipenko
Cc: Peter De Schrijver, Joseph Lo, thierry.reding, jonathanh, tglx,
jason, marc.zyngier, linus.walleij, stefan, mark.rutland,
pgaikwad, sboyd, linux-clk, linux-gpio, jckuo, talho, linux-tegra,
linux-kernel, mperttunen, spatra, robh+dt, devicetree
In-Reply-To: <9271ae75-5663-e26e-df26-57cba94dab75@nvidia.com>
On 7/17/19 1:01 PM, Sowjanya Komatineni wrote:
>
> On 7/17/19 12:43 PM, Dmitry Osipenko wrote:
>> 17.07.2019 21:54, Sowjanya Komatineni пишет:
>>> On 7/17/19 11:51 AM, Sowjanya Komatineni wrote:
>>>> On 7/17/19 11:32 AM, Dmitry Osipenko wrote:
>>>>> 17.07.2019 20:29, Sowjanya Komatineni пишет:
>>>>>> On 7/17/19 8:17 AM, Dmitry Osipenko wrote:
>>>>>>> 17.07.2019 9:36, Sowjanya Komatineni пишет:
>>>>>>>> On 7/16/19 11:33 PM, Dmitry Osipenko wrote:
>>>>>>>>> В Tue, 16 Jul 2019 22:55:52 -0700
>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>
>>>>>>>>>> On 7/16/19 10:42 PM, Dmitry Osipenko wrote:
>>>>>>>>>>> В Tue, 16 Jul 2019 22:25:25 -0700
>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>> On 7/16/19 9:11 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>> В Tue, 16 Jul 2019 19:35:49 -0700
>>>>>>>>>>>>> Sowjanya Komatineni <skomatineni@nvidia.com> пишет:
>>>>>>>>>>>>>> On 7/16/19 7:18 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>> On 7/16/19 3:06 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>> On 7/16/19 3:00 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>> 17.07.2019 0:35, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>> On 7/16/19 2:21 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>> 17.07.2019 0:12, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>> On 7/16/19 1:47 PM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>> 16.07.2019 22:26, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:43 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:30, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 11:25 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 21:19, Sowjanya Komatineni пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 9:50 AM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>> On 7/16/19 8:00 AM, Dmitry Osipenko wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 16.07.2019 11:06, Peter De Schrijver пишет:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2019 at 03:24:26PM +0800,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Joseph
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Lo wrote:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OK, Will add to CPUFreq driver...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The other thing that also need
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> attention is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> that T124 CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> implicitly relies on DFLL driver to be
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> probed
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> first, which is
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> icky.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Should I add check for successful dfll clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> register explicitly in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver probe and defer till dfll
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clk
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> registers?
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Probably you should use the "device links".
>>>>>>>>>>>>>>>>>>>>>>>>>>>> See
>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1][2] for the
>>>>>>>>>>>>>>>>>>>>>>>>>>>> example.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> [1]
>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/gpu/drm/tegra/dc.c#L2383
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> [2]
>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://www.kernel.org/doc/html/latest/driver-api/device_link.html
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Return EPROBE_DEFER instead of EINVAL if
>>>>>>>>>>>>>>>>>>>>>>>>>>>> device_link_add() fails.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> And
>>>>>>>>>>>>>>>>>>>>>>>>>>>> use of_find_device_by_node() to get the DFLL's
>>>>>>>>>>>>>>>>>>>>>>>>>>>> device, see [3].
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>> [3]
>>>>>>>>>>>>>>>>>>>>>>>>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/devfreq/tegra20-devfreq.c#n100
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>> Will go thru and add...
>>>>>>>>>>>>>>>>>>>>>>>>> Looks like I initially confused this case with
>>>>>>>>>>>>>>>>>>>>>>>>> getting
>>>>>>>>>>>>>>>>>>>>>>>>> orphaned clock.
>>>>>>>>>>>>>>>>>>>>>>>>> I'm now seeing that the DFLL driver registers the
>>>>>>>>>>>>>>>>>>>>>>>>> clock and then
>>>>>>>>>>>>>>>>>>>>>>>>> clk_get(dfll) should be returning EPROBE_DEFER
>>>>>>>>>>>>>>>>>>>>>>>>> until
>>>>>>>>>>>>>>>>>>>>>>>>> DFLL driver is
>>>>>>>>>>>>>>>>>>>>>>>>> probed, hence everything should be fine as-is and
>>>>>>>>>>>>>>>>>>>>>>>>> there is no real
>>>>>>>>>>>>>>>>>>>>>>>>> need
>>>>>>>>>>>>>>>>>>>>>>>>> for the 'device link'. Sorry for the confusion!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, I didn't follow the mail thread. Just
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regarding the DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> part.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> As you know it, the DFLL clock is one of the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock sources and
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> integrated with DVFS control logic with the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator. We will not
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to other clock sources once we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switched to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL. Because the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU has
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> been regulated by the DFLL HW with the DVFS
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (CVB or OPP
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> table
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> you see
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> in the driver.). We shouldn't reparent it to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> other sources with
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> unknew
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> freq/volt pair. That's not guaranteed to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> work. We
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> allow switching to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> open-loop mode but different sources.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Okay, then the CPUFreq driver will have to
>>>>>>>>>>>>>>>>>>>>>>>>>>>> enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to
>>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP's
>>>>>>>>>>>>>>>>>>>>>>>>>>>> rate before switching to PLLP in order to
>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper CPU voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>> PLLP freq is safe to work for any CPU voltage.
>>>>>>>>>>>>>>>>>>>>>>>>>>> So no
>>>>>>>>>>>>>>>>>>>>>>>>>>> need to enforce
>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL freq to PLLP rate before changing CCLK_G
>>>>>>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>>>>>>> to PLLP during
>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>>>>>>>>>>>>> Sorry, please ignore my above comment. During
>>>>>>>>>>>>>>>>>>>>>>>>>> suspend, need to change
>>>>>>>>>>>>>>>>>>>>>>>>>> CCLK_G source to PLLP when dfll is in closed
>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>> mode first and
>>>>>>>>>>>>>>>>>>>>>>>>>> then
>>>>>>>>>>>>>>>>>>>>>>>>>> dfll need to be set to open loop.
>>>>>>>>>>>>>>>>>>>>>>>>> Okay.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And I don't exactly understand why we
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> need to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch to PLLP in
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> idle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver. Just keep it on CL-DVFS mode all the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> time.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 entry, the dfll suspend function
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moves it
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the open-loop
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mode. That's
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all. The sc7-entryfirmware will handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the rest
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> of the sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn off
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU power.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> In SC7 resume, the warmboot code will handle
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> sequence to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> turn on
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> regulator and power up the CPU cluster. And
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> leave
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> it on PLL_P.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> After
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> resuming to the kernel, we re-init DFLL,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> the CPU clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> policy (CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> runs on DFLL open-loop mode) and then
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> moving to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> close-loop mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL is re-inited after switching CCLK to
>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>> parent during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>>>>> early clocks-state restoring by CaR driver.
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Hence
>>>>>>>>>>>>>>>>>>>>>>>>>>>> instead of having
>>>>>>>>>>>>>>>>>>>>>>>>>>>> odd
>>>>>>>>>>>>>>>>>>>>>>>>>>>> hacks in the CaR driver, it is much nicer to
>>>>>>>>>>>>>>>>>>>>>>>>>>>> have a
>>>>>>>>>>>>>>>>>>>>>>>>>>>> proper suspend-resume sequencing of the device
>>>>>>>>>>>>>>>>>>>>>>>>>>>> drivers. In this case
>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq
>>>>>>>>>>>>>>>>>>>>>>>>>>>> driver is the driver that enables DFLL and
>>>>>>>>>>>>>>>>>>>>>>>>>>>> switches
>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPU to that
>>>>>>>>>>>>>>>>>>>>>>>>>>>> clock
>>>>>>>>>>>>>>>>>>>>>>>>>>>> source, which means that this driver is also
>>>>>>>>>>>>>>>>>>>>>>>>>>>> should
>>>>>>>>>>>>>>>>>>>>>>>>>>>> be responsible for
>>>>>>>>>>>>>>>>>>>>>>>>>>>> management of the DFLL's state during of
>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend/resume process. If
>>>>>>>>>>>>>>>>>>>>>>>>>>>> CPUFreq driver disables DFLL during suspend
>>>>>>>>>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>>>>>>>>>> re-enables it
>>>>>>>>>>>>>>>>>>>>>>>>>>>> during
>>>>>>>>>>>>>>>>>>>>>>>>>>>> resume, then looks like the CaR driver hacks
>>>>>>>>>>>>>>>>>>>>>>>>>>>> around
>>>>>>>>>>>>>>>>>>>>>>>>>>>> DFLL are not
>>>>>>>>>>>>>>>>>>>>>>>>>>>> needed.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> The DFLL part looks good to me. BTW,
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> change the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> patch subject to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "Add
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> suspend-resume support" seems more
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> appropriate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> me.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> To clarify this, the sequences for DFLL use
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> are as
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> follows (assuming
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> required DFLL hw configuration has been done)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch to DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Save current parent and frequency
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2) Enable DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3) Change cclk_g parent to DFLL
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For OVR regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Change PWM output pin from tristate to
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 5) Enable DFLL PWM output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> For I2C regulator:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4) Enable DFLL I2C output
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 6) Program DFLL to closed loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Switch away from DFLL:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0) Change cclk_g parent to PLLP so the CPU
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> frequency is ok for
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> any
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> vdd_cpu voltage
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1) Program DFLL to open loop mode
>>>>>>>>>>>>>>>>>>>>>>>>>> I see during switch away from DFLL (suspend),
>>>>>>>>>>>>>>>>>>>>>>>>>> cclk_g
>>>>>>>>>>>>>>>>>>>>>>>>>> parent is not
>>>>>>>>>>>>>>>>>>>>>>>>>> changed to PLLP before changing dfll to open
>>>>>>>>>>>>>>>>>>>>>>>>>> loop
>>>>>>>>>>>>>>>>>>>>>>>>>> mode.
>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>> Will add this ...
>>>>>>>>>>>>>>>>>>>>>>>>> The CPUFreq driver switches parent to PLLP during
>>>>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>>>>> probe, similar
>>>>>>>>>>>>>>>>>>>>>>>>> should be done on suspend.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> I'm also wondering if it's always safe to
>>>>>>>>>>>>>>>>>>>>>>>>> switch to
>>>>>>>>>>>>>>>>>>>>>>>>> PLLP in the probe.
>>>>>>>>>>>>>>>>>>>>>>>>> If CPU is running on a lower freq than PLLP, then
>>>>>>>>>>>>>>>>>>>>>>>>> some
>>>>>>>>>>>>>>>>>>>>>>>>> other more
>>>>>>>>>>>>>>>>>>>>>>>>> appropriate intermediate parent should be
>>>>>>>>>>>>>>>>>>>>>>>>> selected.
>>>>>>>>>>>>>>>>>>>>>>>> CPU parents are PLL_X, PLL_P, and dfll. PLL_X
>>>>>>>>>>>>>>>>>>>>>>>> always
>>>>>>>>>>>>>>>>>>>>>>>> runs at higher
>>>>>>>>>>>>>>>>>>>>>>>> rate
>>>>>>>>>>>>>>>>>>>>>>>> so switching to PLL_P during CPUFreq probe
>>>>>>>>>>>>>>>>>>>>>>>> prior to
>>>>>>>>>>>>>>>>>>>>>>>> dfll clock enable
>>>>>>>>>>>>>>>>>>>>>>>> should be safe.
>>>>>>>>>>>>>>>>>>>>>>> AFAIK, PLLX could run at ~200MHz. There is also a
>>>>>>>>>>>>>>>>>>>>>>> divided output of
>>>>>>>>>>>>>>>>>>>>>>> PLLP
>>>>>>>>>>>>>>>>>>>>>>> which CCLKG supports, the PLLP_OUT4.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Probably, realistically, CPU is always running
>>>>>>>>>>>>>>>>>>>>>>> off a
>>>>>>>>>>>>>>>>>>>>>>> fast PLLX during
>>>>>>>>>>>>>>>>>>>>>>> boot, but I'm wondering what may happen on KEXEC. I
>>>>>>>>>>>>>>>>>>>>>>> guess ideally CPUFreq driver should also have a
>>>>>>>>>>>>>>>>>>>>>>> 'shutdown' callback to teardown DFLL
>>>>>>>>>>>>>>>>>>>>>>> on a reboot, but likely that there are other
>>>>>>>>>>>>>>>>>>>>>>> clock-related problems as
>>>>>>>>>>>>>>>>>>>>>>> well that may break KEXEC and thus it is not very
>>>>>>>>>>>>>>>>>>>>>>> important at the
>>>>>>>>>>>>>>>>>>>>>>> moment.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> [snip]
>>>>>>>>>>>>>>>>>>>>>> During bootup CPUG sources from PLL_X. By PLL_P
>>>>>>>>>>>>>>>>>>>>>> source
>>>>>>>>>>>>>>>>>>>>>> above I meant
>>>>>>>>>>>>>>>>>>>>>> PLL_P_OUT4.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> As per clock policies, PLL_X is always used for high
>>>>>>>>>>>>>>>>>>>>>> freq
>>>>>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>>>>>>> 800Mhz
>>>>>>>>>>>>>>>>>>>>>> and for low frequency it will be sourced from PLLP.
>>>>>>>>>>>>>>>>>>>>> Alright, then please don't forget to pre-initialize
>>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate to a
>>>>>>>>>>>>>>>>>>>>> reasonable value using tegra_clk_init_table or
>>>>>>>>>>>>>>>>>>>>> assigned-clocks.
>>>>>>>>>>>>>>>>>>>> PLLP_OUT4 rate update is not needed as it is safe to
>>>>>>>>>>>>>>>>>>>> run at
>>>>>>>>>>>>>>>>>>>> 408Mhz because it is below fmax @ Vmin
>>>>>>>>>>>>>>>>>>> So even 204MHz CVB entries are having the same
>>>>>>>>>>>>>>>>>>> voltage as
>>>>>>>>>>>>>>>>>>> 408MHz, correct? It's not instantly obvious to me
>>>>>>>>>>>>>>>>>>> from the
>>>>>>>>>>>>>>>>>>> DFLL driver's code where the fmax @ Vmin is defined,
>>>>>>>>>>>>>>>>>>> I see
>>>>>>>>>>>>>>>>>>> that there is the min_millivolts
>>>>>>>>>>>>>>>>>>> and frequency entries starting from 204MHZ defined
>>>>>>>>>>>>>>>>>>> per-table.
>>>>>>>>>>>>>>>>>> Yes at Vmin CPU Fmax is ~800Mhz. So anything below that
>>>>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>>>>> work at Vmin voltage and PLLP max is 408Mhz.
>>>>>>>>>>>>>>>>> Thank you for the clarification. It would be good to have
>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>> commented
>>>>>>>>>>>>>>>>> in the code as well.
>>>>>>>>>>>>>>>> OK, Will add...
>>>>>>>>>>>>>>> Regarding, adding suspend/resume to CPUFreq, CPUFreq
>>>>>>>>>>>>>>> suspend
>>>>>>>>>>>>>>> happens very early even before disabling non-boot CPUs and
>>>>>>>>>>>>>>> also
>>>>>>>>>>>>>>> need to export clock driver APIs to CPUFreq.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Was thinking of below way of implementing this...
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Clock DFLL driver Suspend:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> - Save CPU clock policy registers, and
>>>>>>>>>>>>>>> Perform
>>>>>>>>>>>>>>> dfll
>>>>>>>>>>>>>>> suspend which sets in open loop mode
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> CPU Freq driver Suspend: does nothing
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Clock DFLL driver Resume:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> - Re-init DFLL, Set in Open-Loop mode,
>>>>>>>>>>>>>>> restore
>>>>>>>>>>>>>>> CPU
>>>>>>>>>>>>>>> Clock policy registers which actually sets source to DFLL
>>>>>>>>>>>>>>> along
>>>>>>>>>>>>>>> with other CPU Policy register restore.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> CPU Freq driver Resume:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> - do clk_prepare_enable which acutally sets
>>>>>>>>>>>>>>> DFLL in
>>>>>>>>>>>>>>> Closed loop mode
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Adding one more note: Switching CPU Clock to PLLP is not
>>>>>>>>>>>>>>> needed
>>>>>>>>>>>>>>> as CPU CLock can be from dfll in open-loop mode as DFLL
>>>>>>>>>>>>>>> is not
>>>>>>>>>>>>>>> disabled anywhere throught the suspend/resume path and SC7
>>>>>>>>>>>>>>> entry
>>>>>>>>>>>>>>> FW and Warm boot code will switch CPU source to PLLP.
>>>>>>>>>>>>> Since CPU resumes on PLLP, it will be cleaner to suspend
>>>>>>>>>>>>> it on
>>>>>>>>>>>>> PLLP as well. And besides, seems that currently disabling
>>>>>>>>>>>>> DFLL
>>>>>>>>>>>>> clock will disable DFLL completely and then you'd want to
>>>>>>>>>>>>> re-init
>>>>>>>>>>>>> the DFLL on resume any ways. So better to just disable DFLL
>>>>>>>>>>>>> completely on suspend, which should happen on
>>>>>>>>>>>>> clk_disable(dfll).
>>>>>>>>>>>> Will switch to PLLP during CPUFreq suspend. With decision of
>>>>>>>>>>>> using
>>>>>>>>>>>> clk_disable during suspend, its mandatory to switch to PLLP as
>>>>>>>>>>>> DFLL
>>>>>>>>>>>> is completely disabled.
>>>>>>>>>>>>
>>>>>>>>>>>> My earlier concern was on restoring CPU policy as we can't do
>>>>>>>>>>>> that
>>>>>>>>>>>> from CPUFreq driver and need export from clock driver.
>>>>>>>>>>>>
>>>>>>>>>>>> Clear now and will do CPU clock policy restore in after dfll
>>>>>>>>>>>> re-init.
>>>>>>>>>>> Why the policy can't be saved/restored by the CaR driver as a
>>>>>>>>>>> context of any other clock?
>>>>>>>>>> restoring cpu clock policy involves programming source and
>>>>>>>>>> super_cclkg_divider.
>>>>>>>>>>
>>>>>>>>>> cclk_g is registered as clk_super_mux and it doesn't use
>>>>>>>>>> frac_div ops
>>>>>>>>>> to do save/restore its divider.
>>>>>>>>> That can be changed of course and I guess it also could be as
>>>>>>>>> simple as
>>>>>>>>> saving and restoring of two raw u32 values of the policy/divider
>>>>>>>>> registers.
>>>>>>>>>
>>>>>>>>>> Also, during clock context we cant restore cclk_g as cclk_g
>>>>>>>>>> source
>>>>>>>>>> will be dfll and dfll will not be resumed/re-initialized by the
>>>>>>>>>> time
>>>>>>>>>> clk_super_mux save/restore happens.
>>>>>>>>>>
>>>>>>>>>> we can't use save/restore context for dfll clk_ops because
>>>>>>>>>> dfllCPU_out parent to CCLK_G is first in the clock tree and
>>>>>>>>>> dfll_ref
>>>>>>>>>> and dfll_soc peripheral clocks are not restored by the time dfll
>>>>>>>>>> restore happens. Also dfll peripheral clock enables need to be
>>>>>>>>>> restored before dfll restore happens which involves programming
>>>>>>>>>> dfll
>>>>>>>>>> controller for re-initialization.
>>>>>>>>>>
>>>>>>>>>> So dfll resume/re-init is done in clk-tegra210 at end of all
>>>>>>>>>> clocks
>>>>>>>>>> restore in V5 series but instead of in clk-tegra210 driver I
>>>>>>>>>> moved
>>>>>>>>>> now to dfll-fcpu driver pm_ops as all dfll dependencies will be
>>>>>>>>>> restored thru clk_restore_context by then. This will be in V6.
>>>>>>>>> Since DFLL is now guaranteed to be disabled across CaR
>>>>>>>>> suspend/resume
>>>>>>>>> (hence it has nothing to do in regards to CCLK) and given that
>>>>>>>>> PLLs
>>>>>>>>> state is restored before the rest of the clocks, I don't see why
>>>>>>>>> not to
>>>>>>>>> implement CCLK save/restore in a generic fasion. CPU policy
>>>>>>>>> wull be
>>>>>>>>> restored to either PLLP or PLLX (if CPUFreq driver is disabled).
>>>>>>>>>
>>>>>>>> CCLK_G save/restore should happen in clk_super_mux ops
>>>>>>>> save/context and
>>>>>>>> clk_super_mux save/restore happens very early as cclk_g is first
>>>>>>>> in the
>>>>>>>> clock tree and save/restore traverses through the tree top-bottom
>>>>>>>> order.
>>>>>>> If CCLK_G is restored before the PLLs, then just change the clocks
>>>>>>> order
>>>>>>> such that it won't happen.
>>>>>>>
>>>>>> I dont think we can change clocks order for CCLK_G.
>>>>>>
>>>>>> During bootup, cclk_g is registered after all pll's and peripheral
>>>>>> clocks which is the way we wanted, So cclk_g will be the first
>>>>>> one in
>>>>>> the clk list as clk_register adds new clock first in the list.
>>>>>>
>>>>>> When clk_save_context and clk_restore_context APIs iterates over the
>>>>>> list, cclk_g is the first
>>>>> Looking at clk_core_restore_context(), I see that it walks up CLKs
>>>>> list
>>>>> from parent to children, hence I don't understand how it can ever
>>>>> happen
>>>>> that CCLK will be restored before the parent. The clocks registration
>>>>> order doesn't matter at all in that case.
>>>> yes from parent to children and dfllCPU_out is the top in the list and
>>>> its child is cclk_g.
>>>>
>>>> the way clocks are registered is the order I see in the clock list and
>>>> looking into clk_register API it adds new node first in the list.
>>>>
>>> cclkg_g & dfll register happens after all plls and peripheral clocks as
>>> it need ref, soc and peripheral clocks to be enabled.
>>>> So they are the last to get registered and so becomes first in the
>>>> list.
>>>>
>>>> During save/restore context, it traverses thru this list and first in
>>>> the list is dfllcpu_OUT (parent) and its child (cclk_g)
>>>>
>>>> saving should not be an issue at all but we cant restore cclk_g/dfll
>>>> in normal way thru clk_ops restore as plls and peripherals restore
>>>> doesn't happen by that time.
>>>>
>>> I was referring to clk_restore_context where it iterates thru root list
>>> and for each core from the root list clk_core_restore does restore of
>>> parent and children.
>>>
>>> dfllCPU_Out gets first in the list and its child is cclk_g
>>>
>>> https://elixir.bootlin.com/linux/v5.2.1/source/drivers/clk/clk.c#L1105
>> What list you're talking about? clk_summary? It shows current *active*
>> clocks configuration, if you'll try to disable CPUFreq driver then the
>> parent of CCLK_G should be PLLX. Similarly when CPU is reparented to
>> PLLP on driver's suspend, then PLLP is the parent.
>>
>>>>>>>> DFLL enable thru CPUFreq resume happens after all
>>>>>>>> clk_restore_context
>>>>>>>> happens. So during clk_restore_context, dfll re-init doesnt happen
>>>>>>>> and
>>>>>>>> doing cpu clock policy restore during super_mux clk_ops will
>>>>>>>> crash as
>>>>>>>> DFLL is not initialized and its clock is not enabled but CPU clock
>>>>>>>> restore sets source to DFLL if we restore during super_clk_mux
>>>>>>> If CPU was suspended on PLLP, then it will be restored on PLLP by
>>>>>>> CaR. I
>>>>>>> don't understand what DFLL has to do with the CCLK in that case
>>>>>>> during
>>>>>>> the clocks restore.
>>>>>> My above comment is in reference to your request of doing
>>>>>> save/restore
>>>>>> for cclk_g in normal fashion thru save/restore context. Because
>>>>>> of the
>>>>>> clk order I mentioned above, we cclk_g will be the first one to
>>>>>> go thru
>>>>>> save/context.
>>>>>>
>>>>>> During save_context of cclk_g, source can be from PLLX, dfll.
>>>>>>
>>>>>> Issue will be when we do restore during clk_restore_context of
>>>>>> cclk_g as
>>>>>> by that time PLLX/dfll will not be restored.
>>>>>>
>>>>> Seems we already agreed that DFLL will be disabled by the CPUFreq
>>>>> driver
>>>>> on suspend. Hence CCLK can't be from DFLL if CPU is reparented to
>>>>> PLLP
>>>>> on CPUFreq driver's suspend, otherwise CPU keeps running from a
>>>>> boot-state PLLX if CPUFreq driver is disabled.
>>>> Yes suspend should not be an issue but issue will be during resume
>>>> where if we do cclk_g restore in normal way thru clk_restore_context,
>>>> cclk_g restore happens very early as dfllCPU out is the first one that
>>>> goes thru restore context and plls/peripherals are not resumed by
>>>> then.
>>>>
>>>> CPU runs from PLLX if dfll clock enable fails during boot. So when it
>>>> gets to suspend, we save CPU running clock source as either PLLX or
>>>> DFLL and then we switch to PLLP.
>>>>
>>>>
>>>> On resume, CPU runs from PLLP by warm boot code and we need to restore
>>>> back its source to the one it was using from saved source context
>>>> (which can be either PLLX or DFLL)
>>>>
>>>> So PLLs & DFLL resume need to happen before CCLKG restore/resume.
>>>>
>>>>
>>>> With all above discussions, we do DFLL disable in CPUFreq driver on
>>>> suspend and on CPUFreq resume we enable DFLL back and restore CPU
>>>> clock source it was using during suspend (which will be either PLLX if
>>>> dfll enable fails during probe or it will be using DFLL).
>> During suspend CPU's parent shall be PLLP and not DFLL (note that it is
>> disabled) after reparenting to PLLP by the CPUFreq driver.
>>
> CPU source context should be saved before switching to safe source of
> PLLP as on resume we need to restore back to source it was using
> before we switch to safe source during suspend entry.
>
> So saved context for CPU Source will be either dfll or PLLX
>
PLLP reparenting is only during suspend/entry to have it as safe source
but actual CPU source it was running from before suspending is either
dfll/pllx which should be the one to be restored on CPUFreq resume.
Resume happens with CPU running from PLLP till it gets to the point of
restoring its original source (dfll or pllx)
>>>> So i was trying to say dfll/cclk_g restore can't be done in normal way
>>>> thru clk_ops save/restore context
>> Let's see what happens if CPUFreq is active:
>>
>> 1. CPUFreq driver probe happens
>> 2. CPU is reparented to PLLP
>> 3. DFLL inited
>> 4. CPU is reparented to DFLL
>>
>> 5. CPUFreq driver suspend happens
>> 6. CPU is reparented to PLLP
>> 7. DFLL is disabled
>>
>> 8. Car suspend happens
>> 9. DFLL context saved
>> 10. PLLP/PLLX context saved
>> 11. CCLK context saved
>>
>> 12. Car resume happens
>> 13. DFLL context restored
>> 14. PLLP/PLLX context restored
>> 15. CCLK context restored
>>
>> 16. CPUFreq driver resume happens
>> 17. DFLL re-inited
>> 18. CPU is reparented to DFLL
>
>
> Below is the order of sequence it should be based on the order of clk
> register.
>
> My comments inline in this sequence.
>
> 1. CPUFreq driver probe happens
> 2. CPU is reparented to PLLP
> 3. DFLL inited
> 4. CPU is reparented to DFLL
>
>
> 5. CPUFreq driver suspend happens
> 6. Save CPU source which could be either dfll or pllx
> 7. CPU is reparented to safe known source PLLP
> 8. DFLL is disabled
>
> 8. Car suspend happens
> 9. DFLL context saved (With DFLL disabled in CPUFreq suspend,
> nothing to be saved here as last freq req will always be saved).
> 10. CCLK context saved (CPU clock source will be saved in CPUFreq
> driver suspend which could be either dfll or pllx)
> 11. PLLP/PLLX context saved
> 12. Peripheral Clock saved
>
> 12. Car resume happens
> 13. DFLL context restored : No DFLL context to be restored and we
> only need to reinitialize DFLL and re-initialize can't be done here as
> this is the 1st to get restored and PLL/Peripheral clocks are not
> restored by this time. So we can't use clk_ops restore for DFLL
> 14. CCLK context restored
> CCLK cant be restored here as context could be either dfll or pllx
> which is the source orginally it was actually using before we force
> switch to safe PLLP for suspend entry. So we can't use clk_ops restore
> for DFLL
>
> 15. PLLP/PLLX context restored
> 16. Peripheral context restored
>
> 16. CPUFreq driver resume happens
> 17. DFLL re-inited (Invoking DFLL re-init in CPUFreq resume need
> exporting DFLL reinit from Clock driver to CPUFreq driver)
> 18. CPU is reparented to DFLL or PLLX based on saved context from
> step 9.
>
> Note: instead of exporting, we can do DFLL re-init from clock-dfll
> driver itself thru dfll-fcpu pm_ops resume. So dfll will be
> re-initialized by the time CPUFreq driver resumes and switches to use
> DFLL source.
>
^ permalink raw reply
* Re: [PATCH 07/12] clk: qcom: Add WCSSAON reset
From: Stephen Boyd @ 2019-07-17 20:09 UTC (permalink / raw)
To: agross, bjorn.andersson, david.brown, devicetree, gokulsri,
jassisinghbrar, linux-arm-msm, linux-clk, linux-kernel,
linux-remoteproc, mark.rutland, mturquette, ohad, robh+dt,
sricharan
In-Reply-To: <1562859668-14209-8-git-send-email-gokulsri@codeaurora.org>
Quoting Gokul Sriram Palanisamy (2019-07-11 08:41:03)
> Add WCSSAON reset required for Q6v5 on IPQ8074 SoC.
>
> Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
> ---
Acked-by: Stephen Boyd <sboyd@kernel.org>
^ permalink raw reply
* Re: [PATCH 06/12] dt-bindings: clock: qcom: Add reset for WCSSAON
From: Stephen Boyd @ 2019-07-17 20:08 UTC (permalink / raw)
To: agross, bjorn.andersson, david.brown, devicetree, gokulsri,
jassisinghbrar, linux-arm-msm, linux-clk, linux-kernel,
linux-remoteproc, mark.rutland, mturquette, ohad, robh+dt,
sricharan
In-Reply-To: <1562859668-14209-7-git-send-email-gokulsri@codeaurora.org>
Quoting Gokul Sriram Palanisamy (2019-07-11 08:41:02)
> Add binding for WCSSAON reset required for Q6v5 reset on IPQ8074 SoC.
>
> Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
> ---
Acked-by: Stephen Boyd <sboyd@kernel.org>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox