mbox series

[v2,0/7] PM / devfreq: Add initial imx support

Message ID cover.1566315740.git.leonard.crestez@nxp.com
Headers show
Series PM / devfreq: Add initial imx support | expand

Message

Leonard Crestez Aug. 20, 2019, 3:45 p.m. UTC
This adds devfreq support for imx8mm, covering dynamic scaling of
internal NOC and DDR Controller

Scaling for simple busses (NIC/NOC) is done through the clk framework
while DRAM scaling is performed in firmware with an "imx-ddrc" wrapper
for devfreq.

Changes since v1:
 * bindings: Stop using "contains" for "compatible"
 * bindings: Set "additionalProperties: false" and document missing stuff.
 * Remove (c) from NXP copyright notice
 * Fix various checkpatch issues
 * Remove unused dram_alt_root clk from imx-ddrc
Link to v1: https://patchwork.kernel.org/project/linux-arm-kernel/list/?series=158773

Changes since RFC v3:
 * Implement passive support and set NOC's parent to DDRC
 * Drop scaling AHB/AXI for now (NOC/DDRC use most power anyway)
 * Stop relying on clk_min_rate
 * Split into two devreq drivers (and bindings) because the ddrc is
really a distinct piece of hardware.
 * Perform DRAM frequency inside devfreq instead of clk, mostly due to
objections to earlier RFCs for imx8m-dram-clk.
 * Fetch info about dram clk parents from firmware instead of
hardcoding in driver. This can more easily support additional rates.
 * Link: https://patchwork.kernel.org/cover/11056779/
 * Link: https://patchwork.kernel.org/patch/11049429/

Scaling buses can cause problems for devices with realtime bandwith
requirements such as display, the intention is to use the interconnect
framework to make DEV_PM_QOS_MIN_FREQUENCY to devfreq. There are
separate patches for that:

* https://patchwork.kernel.org/cover/11104055/
* https://patchwork.kernel.org/cover/11078671/

Leonard Crestez (7):
  clk: imx8m: Set CLK_GET_RATE_NOCACHE on dram_alt/apb
  dt-bindings: devfreq: Add bindings for generic imx buses
  PM / devfreq: Add generic imx bus driver
  dt-bindings: devfreq: Add bindings for imx ddr controller
  PM / devfreq: Add dynamic scaling for imx ddr controller
  PM / devfreq: imx-ddrc: Measure bandwidth with perf
  arm64: dts: imx8mm: Add devfreq nodes

 .../devicetree/bindings/devfreq/imx-ddrc.yaml |  60 ++
 .../devicetree/bindings/devfreq/imx.yaml      |  68 +++
 arch/arm64/boot/dts/freescale/imx8mm.dtsi     |  53 +-
 drivers/clk/imx/clk-imx8mm.c                  |   6 +-
 drivers/clk/imx/clk-imx8mn.c                  |   6 +-
 drivers/clk/imx/clk-imx8mq.c                  |   7 +-
 drivers/devfreq/Kconfig                       |  12 +
 drivers/devfreq/Makefile                      |   1 +
 drivers/devfreq/imx-ddrc.c                    | 514 ++++++++++++++++++
 drivers/devfreq/imx-devfreq.c                 | 148 +++++
 10 files changed, 867 insertions(+), 8 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/devfreq/imx-ddrc.yaml
 create mode 100644 Documentation/devicetree/bindings/devfreq/imx.yaml
 create mode 100644 drivers/devfreq/imx-ddrc.c
 create mode 100644 drivers/devfreq/imx-devfreq.c

Comments

Leonard Crestez Sept. 16, 2019, 11:03 p.m. UTC | #1
On 2019-09-16 11:33 PM, Stephen Boyd wrote:
> Quoting Leonard Crestez (2019-08-20 08:45:06)
>> Dram frequency changes required modifying these clocks outside the
>> control of clk framework. Mark them as CLK_GET_RATE_NOCACHE so that
>> rates are always read back from registers.
> 
> Why can't we control the clks from the clk framework? Please add that
> information in the commit text here.

OK, I will update commit message and comments

These clocks are only modified for DRAM frequency switches during which 
DRAM is briefly inaccessible. The switch is performed with a SMC call to 
by TF-A which runs from a SRAM area. Upon returning to linux several 
clocks bits are modified and we need to update them.

For rate bits an easy solution is to just mark with 
CLK_GET_RATE_NOCACHE, muxes are handled explicitly.

Linux code performing the SMC call is also part of this series:

     https://patchwork.kernel.org/patch/11104145/

>> Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
>> ---
>>   drivers/clk/imx/clk-imx8mm.c | 6 ++++--
>>   drivers/clk/imx/clk-imx8mn.c | 6 ++++--
>>   drivers/clk/imx/clk-imx8mq.c | 7 ++++---
>>   3 files changed, 12 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
>> index 4ead3ea2713c..6cac80550f43 100644
>> --- a/drivers/clk/imx/clk-imx8mm.c
>> +++ b/drivers/clk/imx/clk-imx8mm.c
>> @@ -526,12 +526,14 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
>>          /* IPG */
>>          clks[IMX8MM_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
>>          clks[IMX8MM_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
>>   
>>          /* IP */
>> -       clks[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000);
>> -       clks[IMX8MM_CLK_DRAM_APB] = imx8m_clk_composite_critical("dram_apb", imx8mm_dram_apb_sels, base + 0xa080);
>> +       clks[IMX8MM_CLK_DRAM_ALT] = __imx8m_clk_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000,
>> +                       CLK_GET_RATE_NOCACHE);
>> +       clks[IMX8MM_CLK_DRAM_APB] = __imx8m_clk_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080,
>> +                       CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
> 
> Also, add a comment to this effect about why it can't be done from the
> clk framework wherever the CLK_GET_RATE_NOCACHE flag is set. Basically
> this flag is a hack and is an example of something that we need to fix.

DRAM freq switch requires multiple clk changes to be performed 
atomically while DRAM itself is not accessible so it's not something to 
"fix".

--
Regards,
Leonard
Leonard Crestez Sept. 17, 2019, 4:59 p.m. UTC | #2
On 2019-09-17 7:32 PM, Stephen Boyd wrote:
> Quoting Leonard Crestez (2019-09-16 16:03:53)
>> On 2019-09-16 11:33 PM, Stephen Boyd wrote:
>>> Quoting Leonard Crestez (2019-08-20 08:45:06)
>>>> Dram frequency changes required modifying these clocks outside the
>>>> control of clk framework. Mark them as CLK_GET_RATE_NOCACHE so that
>>>> rates are always read back from registers.
>>>
>>> Why can't we control the clks from the clk framework? Please add that
>>> information in the commit text here.
>>
>> OK, I will update commit message and comments
>>
>> These clocks are only modified for DRAM frequency switches during which
>> DRAM is briefly inaccessible. The switch is performed with a SMC call to
>> by TF-A which runs from a SRAM area. Upon returning to linux several
>> clocks bits are modified and we need to update them.
>>
>> For rate bits an easy solution is to just mark with
>> CLK_GET_RATE_NOCACHE, muxes are handled explicitly.
> 
> Is there any reason to expose or control these clks from Linux then? It
> might be easier to just make any children clks of the DRAM frequency clk
> "root" clks and then ignore any frequency that they might have.
> Similarly, because the SMC call is used to change the frequency, it may
> be simpler to handle that completely outside of the clk framework (it
> may already be this way in this patch series but I haven't read
> everything here).

The dram alt/apb clocks are real imx8m composite clocks with the same HW 
implementation as used for peripherals. They also have mux parents which 
are under the control of the clock framework so the freq switching code 
takes care to properly enable the new parents before calling SMC.

See imx_ddrc_set_freq: https://patchwork.kernel.org/patch/11104145/

Removing dram alt/apb clocks from the tree would still require keeping 
possible parents enabled somehow. It wouldn't be simpler but a lot uglier.

--
Regards,
Leonard