Linux-Clk Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support
@ 2020-07-29  8:00 Dong Aisheng
  2020-07-29  8:00 ` [PATCH v7 01/11] dt-bindings: firmware: imx-scu: new binding to parse clocks from device tree Dong Aisheng
                   ` (11 more replies)
  0 siblings, 12 replies; 17+ messages in thread
From: Dong Aisheng @ 2020-07-29  8:00 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

This patch series is a preparation for the MX8 Architecture improvement.
As for IMX SCU based platforms like MX8QM and MX8QXP, they are comprised
of a couple of SS(Subsystems) while most of them within the same SS
can be shared. e.g. Clocks, Devices and etc.

However, current clock binding is using SW IDs for device tree to use
which can cause troubles in writing the common <soc>-ss-xx.dtsi file for
different SoCs.

This patch series aims to introduce a new binding which is more close to
hardware and platform independent and can makes us write a more general
drivers for different SCU based SoCs.

Another important thing is that on MX8, each Clock resource is associated
with a power domain. So we have to attach that clock device to the power
domain in order to make it work properly. Further more, the clock state
will be lost when its power domain is completely off during suspend/resume,
so we also introduce the clock state save&restore mechanism.

It's based on latest shanw/for-next branch.

The top commit is:
3c1a41dab7b8 Merge branch 'imx/defconfig' into for-next

ChangeLog:
v6->v7:
 * addressed all comments from Stephen
 * rebased to latest shawn/for-next
v5->v6:
 * add scu clk unregister if add provider failed
v4->v5:
 * Address all comments from Stephen
v3->v4:
 * use clk-indices for LPCG to fetch each clks offset from dt
v2->v3:
 * change scu clk into two cells binding
 * add clk pm patches to ease the understand of the changes
v1->v2:
 * SCU clock changed to one cell clock binding inspired by arm,scpi.txt
   Documentation/devicetree/bindings/arm/arm,scpi.txt
 * Add required power domain property
 * Dropped PATCH 3&4 first, will send the updated version accordingly
   after the binding is finally determined,

Dong Aisheng (11):
  dt-bindings: firmware: imx-scu: new binding to parse clocks from
    device tree
  dt-bindings: clock: imx-lpcg: add support to parse clocks from device
    tree
  clk: imx: scu: add two cells binding support
  clk: imx: scu: bypass cpu power domains
  clk: imx: scu: allow scu clk to take device pointer
  clk: imx: scu: add runtime pm support
  clk: imx: scu: add suspend/resume support
  clk: imx: imx8qxp-lpcg: add parsing clocks from device tree
  clk: imx: lpcg: allow lpcg clk to take device pointer
  clk: imx: clk-imx8qxp-lpcg: add runtime pm support
  clk: imx: lpcg: add suspend/resume support

 .../bindings/arm/freescale/fsl,scu.txt        |  12 +-
 .../bindings/clock/imx8qxp-lpcg.yaml          |  79 ++++--
 drivers/clk/imx/clk-imx8qxp-lpcg.c            | 139 +++++++++++
 drivers/clk/imx/clk-imx8qxp.c                 | 136 +++++-----
 drivers/clk/imx/clk-lpcg-scu.c                |  53 +++-
 drivers/clk/imx/clk-scu.c                     | 234 +++++++++++++++++-
 drivers/clk/imx/clk-scu.h                     |  56 ++++-
 include/dt-bindings/clock/imx8-lpcg.h         |  14 ++
 8 files changed, 620 insertions(+), 103 deletions(-)
 create mode 100644 include/dt-bindings/clock/imx8-lpcg.h

-- 
2.23.0


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

* [PATCH v7 01/11] dt-bindings: firmware: imx-scu: new binding to parse clocks from device tree
  2020-07-29  8:00 [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
@ 2020-07-29  8:00 ` Dong Aisheng
  2020-07-29  8:00 ` [PATCH v7 02/11] dt-bindings: clock: imx-lpcg: add support " Dong Aisheng
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Dong Aisheng @ 2020-07-29  8:00 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng, devicetree

There's a few limitations on the original one cell clock binding
(#clock-cells = <1>) that we have to define some SW clock IDs for device
tree to reference. This may cause troubles if we want to use common
clock IDs for multi platforms support when the clock of those platforms
are mostly the same.
e.g. Current clock IDs name are defined with SS prefix.

However the device may reside in different SS across CPUs, that means the
SS prefix may not valid anymore for a new SoC. Furthermore, the device
availability of those clocks may also vary a bit.

For such situation, we want to eliminate the using of SW Clock IDs and
change to use a more close to HW one instead.
For SCU clocks usage, only two params required: Resource id + Clock Type.
Both parameters are platform independent. So we could use two cells binding
to pass those parameters,

Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: devicetree@vger.kernel.org
Acked-by: Shawn Guo <shawnguo@kernel.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v6->v7:
 * dropped SC PM clk definitions which already upstreamed by another patch
v4->v6:
 * no changes
v3->v4:
 * add some comments for various clock types
v2->v3:
 * Changed to two cells binding and register all clocks in driver
   instead of parse from device tree.
v1->v2:
 * changed to one cell binding inspired by arm,scpi.txt
   Documentation/devicetree/bindings/arm/arm,scpi.txt
   Resource ID is encoded in 'reg' property.
   Clock type is encoded in generic clock-indices property.
   Then we don't have to search all the DT nodes to fetch
   those two value to construct clocks which is relatively
   low efficiency.
 * Add required power-domain property as well.
---
 .../devicetree/bindings/arm/freescale/fsl,scu.txt    | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
index 715047444391..d341285d9a58 100644
--- a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
+++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
@@ -89,7 +89,10 @@ Required properties:
 			  "fsl,imx8qm-clock"
 			  "fsl,imx8qxp-clock"
 			followed by "fsl,scu-clk"
-- #clock-cells:		Should be 1. Contains the Clock ID value.
+- #clock-cells:		Should be either
+			2: Contains the Resource and Clock ID value.
+			or
+			1: Contains the Clock ID value. (DEPRECATED)
 - clocks:		List of clock specifiers, must contain an entry for
 			each required entry in clock-names
 - clock-names:		Should include entries "xtal_32KHz", "xtal_24MHz"
@@ -208,7 +211,7 @@ firmware {
 
 		clk: clk {
 			compatible = "fsl,imx8qxp-clk", "fsl,scu-clk";
-			#clock-cells = <1>;
+			#clock-cells = <2>;
 		};
 
 		iomuxc {
@@ -263,8 +266,7 @@ serial@5a060000 {
 	...
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_lpuart0>;
-	clocks = <&clk IMX8QXP_UART0_CLK>,
-		 <&clk IMX8QXP_UART0_IPG_CLK>;
-	clock-names = "per", "ipg";
+	clocks = <&uart0_clk IMX_SC_R_UART_0 IMX_SC_PM_CLK_PER>;
+	clock-names = "ipg";
 	power-domains = <&pd IMX_SC_R_UART_0>;
 };
-- 
2.23.0


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

* [PATCH v7 02/11] dt-bindings: clock: imx-lpcg: add support to parse clocks from device tree
  2020-07-29  8:00 [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
  2020-07-29  8:00 ` [PATCH v7 01/11] dt-bindings: firmware: imx-scu: new binding to parse clocks from device tree Dong Aisheng
@ 2020-07-29  8:00 ` Dong Aisheng
  2020-07-29  8:06   ` Dong Aisheng
  2020-07-31 21:28   ` Rob Herring
  2020-07-29  8:00 ` [PATCH v7 03/11] clk: imx: scu: add two cells binding support Dong Aisheng
                   ` (9 subsequent siblings)
  11 siblings, 2 replies; 17+ messages in thread
From: Dong Aisheng @ 2020-07-29  8:00 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng, devicetree, Rob Herring

MX8QM and MX8QXP LPCG Clocks are mostly the same except they may reside
in different subsystems across CPUs and also vary a bit on the availability.

Same as SCU clock, we want to move the clock definition into device tree
which can fully decouple the dependency of Clock ID definition from device
tree and make us be able to write a fully generic lpcg clock driver.

And we can also use the existence of clock nodes in device tree to address
the device and clock availability differences across different SoCs.

Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: devicetree@vger.kernel.org
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v6->v7:
 * No other changes except converting to json schema based on the former reviewed
   patches due to the lagecy binding file was removed in latests kernel.
   Because the format is different now, i removed the former R-b
   and A-b tags and request a new review.
   See original patch here:
   https://patchwork.kernel.org/patch/11439079/
v4->v6:
 * no changes
v3->v4:
 * change bit-offset property to clock-indices
 * use constant macro to define clock indinces
 * drop hw-autogate property which is still not used by drivers
v2->v3:
 * no changes
v1->v2:
 * Update example
 * Add power domain property
---
 .../bindings/clock/imx8qxp-lpcg.yaml          | 79 ++++++++++++++-----
 include/dt-bindings/clock/imx8-lpcg.h         | 14 ++++
 2 files changed, 74 insertions(+), 19 deletions(-)
 create mode 100644 include/dt-bindings/clock/imx8-lpcg.h

diff --git a/Documentation/devicetree/bindings/clock/imx8qxp-lpcg.yaml b/Documentation/devicetree/bindings/clock/imx8qxp-lpcg.yaml
index 33f3010f48c3..e709e530e17a 100644
--- a/Documentation/devicetree/bindings/clock/imx8qxp-lpcg.yaml
+++ b/Documentation/devicetree/bindings/clock/imx8qxp-lpcg.yaml
@@ -21,27 +21,58 @@ description: |
 
   The clock consumer should specify the desired clock by having the clock
   ID in its "clocks" phandle cell. See the full list of clock IDs from:
-  include/dt-bindings/clock/imx8-clock.h
+  include/dt-bindings/clock/imx8-lpcg.h
 
 properties:
   compatible:
-    enum:
-      - fsl,imx8qxp-lpcg-adma
-      - fsl,imx8qxp-lpcg-conn
-      - fsl,imx8qxp-lpcg-dc
-      - fsl,imx8qxp-lpcg-dsp
-      - fsl,imx8qxp-lpcg-gpu
-      - fsl,imx8qxp-lpcg-hsio
-      - fsl,imx8qxp-lpcg-img
-      - fsl,imx8qxp-lpcg-lsio
-      - fsl,imx8qxp-lpcg-vpu
-
+    oneOf:
+      - const: fsl,imx8qxp-lpcg
+      - items:
+          - enum:
+            - fsl,imx8qm-lpcg
+          - const: fsl,imx8qxp-lpcg
+      - enum:
+        - fsl,imx8qxp-lpcg-adma
+        - fsl,imx8qxp-lpcg-conn
+        - fsl,imx8qxp-lpcg-dc
+        - fsl,imx8qxp-lpcg-dsp
+        - fsl,imx8qxp-lpcg-gpu
+        - fsl,imx8qxp-lpcg-hsio
+        - fsl,imx8qxp-lpcg-img
+        - fsl,imx8qxp-lpcg-lsio
+        - fsl,imx8qxp-lpcg-vpu
+        deprecated: true
   reg:
     maxItems: 1
 
   '#clock-cells':
     const: 1
 
+  clocks:
+    description: |
+      Input parent clocks phandle array for each clock
+    minItems: 1
+    maxItems: 8
+
+  clock-indices:
+    description: |
+      An integer array indicating the bit offset for each clock.
+      Refer to <include/dt-bindings/clock/imx8-lpcg.h> for the
+      supported LPCG clock indices.
+    minItems: 1
+    maxItems: 8
+
+  clock-output-names:
+    description: |
+      Shall be the corresponding names of the outputs.
+      NOTE this property must be specified in the same order
+      as the clock-indices property.
+    minItems: 1
+    maxItems: 8
+
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
@@ -51,23 +82,33 @@ additionalProperties: false
 
 examples:
   - |
-    #include <dt-bindings/clock/imx8-clock.h>
+    #include <dt-bindings/clock/imx8-lpcg.h>
     #include <dt-bindings/firmware/imx/rsrc.h>
     #include <dt-bindings/interrupt-controller/arm-gic.h>
 
-    clock-controller@5b200000 {
-        compatible = "fsl,imx8qxp-lpcg-conn";
-        reg = <0x5b200000 0xb0000>;
+    sdhc0_lpcg: clock-controller@5b200000 {
+        compatible = "fsl,imx8qxp-lpcg";
+        reg = <0x5b200000 0x10000>;
         #clock-cells = <1>;
+        clocks = <&sdhc0_clk IMX_SC_PM_CLK_PER>,
+                 <&conn_ipg_clk>,
+                 <&conn_axi_clk>;
+        clock-indices = <IMX_LPCG_CLK_0>,
+                        <IMX_LPCG_CLK_4>,
+                        <IMX_LPCG_CLK_5>;
+        clock-output-names = "sdhc0_lpcg_per_clk",
+                             "sdhc0_lpcg_ipg_clk",
+                             "sdhc0_lpcg_ahb_clk";
+        power-domains = <&pd IMX_SC_R_SDHC_0>;
     };
 
     mmc@5b010000 {
         compatible = "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
         interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>;
         reg = <0x5b010000 0x10000>;
-        clocks = <&conn_lpcg IMX_CONN_LPCG_SDHC0_IPG_CLK>,
-                 <&conn_lpcg IMX_CONN_LPCG_SDHC0_PER_CLK>,
-                 <&conn_lpcg IMX_CONN_LPCG_SDHC0_HCLK>;
+        clocks = <&sdhc0_lpcg IMX_LPCG_CLK_4>,
+                 <&sdhc0_lpcg IMX_LPCG_CLK_0>,
+                 <&sdhc0_lpcg IMX_LPCG_CLK_5>;
         clock-names = "ipg", "per", "ahb";
         power-domains = <&pd IMX_SC_R_SDHC_0>;
     };
diff --git a/include/dt-bindings/clock/imx8-lpcg.h b/include/dt-bindings/clock/imx8-lpcg.h
new file mode 100644
index 000000000000..d202715652c3
--- /dev/null
+++ b/include/dt-bindings/clock/imx8-lpcg.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2019-2020 NXP
+ *   Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#define IMX_LPCG_CLK_0	0
+#define IMX_LPCG_CLK_1	4
+#define IMX_LPCG_CLK_2	8
+#define IMX_LPCG_CLK_3	12
+#define IMX_LPCG_CLK_4	16
+#define IMX_LPCG_CLK_5	20
+#define IMX_LPCG_CLK_6	24
+#define IMX_LPCG_CLK_7	28
-- 
2.23.0


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

* [PATCH v7 03/11] clk: imx: scu: add two cells binding support
  2020-07-29  8:00 [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
  2020-07-29  8:00 ` [PATCH v7 01/11] dt-bindings: firmware: imx-scu: new binding to parse clocks from device tree Dong Aisheng
  2020-07-29  8:00 ` [PATCH v7 02/11] dt-bindings: clock: imx-lpcg: add support " Dong Aisheng
@ 2020-07-29  8:00 ` Dong Aisheng
  2020-07-29  8:00 ` [PATCH v7 04/11] clk: imx: scu: bypass cpu power domains Dong Aisheng
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Dong Aisheng @ 2020-07-29  8:00 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

This patch implements the new two cells binding for SCU clocks.
The usage is as follows:
clocks = <&uart0_clk IMX_SC_R_UART_0 IMX_SC_PM_CLK_PER>

Due to each SCU clock is associated with a power domain, without power
on the domain, the SCU clock can't work. So we create platform devices
for each domain clock respectively and manually attach the required domain
before register the clock devices, then we can register clocks in the
clock platform driver accordingly.

Note because we do not have power domain info in device tree and the SCU
resource ID is the same for power domain and clock, so we use resource ID
to find power domains.

Later, we will also use this clock platform driver to support suspend/resume
and runtime pm.

Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Michael Turquette <mturquette@baylibre.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v6->v7:
 Addressed all comments from Stephen
 * remove error check of reading #clock-cells
 * add more code comments about the dependency of power domain
 * squash the former [V6,12/12] clk: imx: scu: unregister clocks if add provider failed
   into this patch.
v4->v6:
 * remove global clock_cells
 * put node after using of_find_compatible_node()
 * using ERR_PTR(ret) instead of ERR_PTR(-ENOMEM)
v4: no changes
v3: new patch
---
 drivers/clk/imx/clk-imx8qxp.c | 136 ++++++++++++++++-------------
 drivers/clk/imx/clk-scu.c     | 156 +++++++++++++++++++++++++++++++++-
 drivers/clk/imx/clk-scu.h     |  27 ++++--
 3 files changed, 252 insertions(+), 67 deletions(-)

diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c
index 5e2903efc488..5ed175de4771 100644
--- a/drivers/clk/imx/clk-imx8qxp.c
+++ b/drivers/clk/imx/clk-imx8qxp.c
@@ -22,9 +22,10 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
 	struct device_node *ccm_node = pdev->dev.of_node;
 	struct clk_hw_onecell_data *clk_data;
 	struct clk_hw **clks;
+	u32 clk_cells;
 	int ret, i;
 
-	ret = imx_clk_scu_init();
+	ret = imx_clk_scu_init(ccm_node);
 	if (ret)
 		return ret;
 
@@ -33,6 +34,9 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
 	if (!clk_data)
 		return -ENOMEM;
 
+	if (of_property_read_u32(ccm_node, "#clock-cells", &clk_cells))
+		return -EINVAL;
+
 	clk_data->num = IMX_SCU_CLK_END;
 	clks = clk_data->hws;
 
@@ -55,78 +59,78 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
 	clks[IMX_LSIO_BUS_CLK]		= clk_hw_register_fixed_rate(NULL, "lsio_bus_clk_root", NULL, 0, 100000000);
 
 	/* ARM core */
-	clks[IMX_A35_CLK]		= imx_clk_scu("a35_clk", IMX_SC_R_A35, IMX_SC_PM_CLK_CPU);
+	clks[IMX_A35_CLK]		= imx_clk_scu("a35_clk", IMX_SC_R_A35, IMX_SC_PM_CLK_CPU, clk_cells);
 
 	/* LSIO SS */
-	clks[IMX_LSIO_PWM0_CLK]		= imx_clk_scu("pwm0_clk", IMX_SC_R_PWM_0, IMX_SC_PM_CLK_PER);
-	clks[IMX_LSIO_PWM1_CLK]		= imx_clk_scu("pwm1_clk", IMX_SC_R_PWM_1, IMX_SC_PM_CLK_PER);
-	clks[IMX_LSIO_PWM2_CLK]		= imx_clk_scu("pwm2_clk", IMX_SC_R_PWM_2, IMX_SC_PM_CLK_PER);
-	clks[IMX_LSIO_PWM3_CLK]		= imx_clk_scu("pwm3_clk", IMX_SC_R_PWM_3, IMX_SC_PM_CLK_PER);
-	clks[IMX_LSIO_PWM4_CLK]		= imx_clk_scu("pwm4_clk", IMX_SC_R_PWM_4, IMX_SC_PM_CLK_PER);
-	clks[IMX_LSIO_PWM5_CLK]		= imx_clk_scu("pwm5_clk", IMX_SC_R_PWM_5, IMX_SC_PM_CLK_PER);
-	clks[IMX_LSIO_PWM6_CLK]		= imx_clk_scu("pwm6_clk", IMX_SC_R_PWM_6, IMX_SC_PM_CLK_PER);
-	clks[IMX_LSIO_PWM7_CLK]		= imx_clk_scu("pwm7_clk", IMX_SC_R_PWM_7, IMX_SC_PM_CLK_PER);
-	clks[IMX_LSIO_GPT0_CLK]		= imx_clk_scu("gpt0_clk", IMX_SC_R_GPT_0, IMX_SC_PM_CLK_PER);
-	clks[IMX_LSIO_GPT1_CLK]		= imx_clk_scu("gpt1_clk", IMX_SC_R_GPT_1, IMX_SC_PM_CLK_PER);
-	clks[IMX_LSIO_GPT2_CLK]		= imx_clk_scu("gpt2_clk", IMX_SC_R_GPT_2, IMX_SC_PM_CLK_PER);
-	clks[IMX_LSIO_GPT3_CLK]		= imx_clk_scu("gpt3_clk", IMX_SC_R_GPT_3, IMX_SC_PM_CLK_PER);
-	clks[IMX_LSIO_GPT4_CLK]		= imx_clk_scu("gpt4_clk", IMX_SC_R_GPT_4, IMX_SC_PM_CLK_PER);
-	clks[IMX_LSIO_FSPI0_CLK]	= imx_clk_scu("fspi0_clk", IMX_SC_R_FSPI_0, IMX_SC_PM_CLK_PER);
-	clks[IMX_LSIO_FSPI1_CLK]	= imx_clk_scu("fspi1_clk", IMX_SC_R_FSPI_1, IMX_SC_PM_CLK_PER);
+	clks[IMX_LSIO_PWM0_CLK]		= imx_clk_scu("pwm0_clk", IMX_SC_R_PWM_0, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_LSIO_PWM1_CLK]		= imx_clk_scu("pwm1_clk", IMX_SC_R_PWM_1, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_LSIO_PWM2_CLK]		= imx_clk_scu("pwm2_clk", IMX_SC_R_PWM_2, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_LSIO_PWM3_CLK]		= imx_clk_scu("pwm3_clk", IMX_SC_R_PWM_3, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_LSIO_PWM4_CLK]		= imx_clk_scu("pwm4_clk", IMX_SC_R_PWM_4, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_LSIO_PWM5_CLK]		= imx_clk_scu("pwm5_clk", IMX_SC_R_PWM_5, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_LSIO_PWM6_CLK]		= imx_clk_scu("pwm6_clk", IMX_SC_R_PWM_6, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_LSIO_PWM7_CLK]		= imx_clk_scu("pwm7_clk", IMX_SC_R_PWM_7, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_LSIO_GPT0_CLK]		= imx_clk_scu("gpt0_clk", IMX_SC_R_GPT_0, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_LSIO_GPT1_CLK]		= imx_clk_scu("gpt1_clk", IMX_SC_R_GPT_1, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_LSIO_GPT2_CLK]		= imx_clk_scu("gpt2_clk", IMX_SC_R_GPT_2, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_LSIO_GPT3_CLK]		= imx_clk_scu("gpt3_clk", IMX_SC_R_GPT_3, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_LSIO_GPT4_CLK]		= imx_clk_scu("gpt4_clk", IMX_SC_R_GPT_4, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_LSIO_FSPI0_CLK]	= imx_clk_scu("fspi0_clk", IMX_SC_R_FSPI_0, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_LSIO_FSPI1_CLK]	= imx_clk_scu("fspi1_clk", IMX_SC_R_FSPI_1, IMX_SC_PM_CLK_PER, clk_cells);
 
 	/* ADMA SS */
-	clks[IMX_ADMA_UART0_CLK]	= imx_clk_scu("uart0_clk", IMX_SC_R_UART_0, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_UART1_CLK]	= imx_clk_scu("uart1_clk", IMX_SC_R_UART_1, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_UART2_CLK]	= imx_clk_scu("uart2_clk", IMX_SC_R_UART_2, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_UART3_CLK]	= imx_clk_scu("uart3_clk", IMX_SC_R_UART_3, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_SPI0_CLK]		= imx_clk_scu("spi0_clk",  IMX_SC_R_SPI_0, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_SPI1_CLK]		= imx_clk_scu("spi1_clk",  IMX_SC_R_SPI_1, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_SPI2_CLK]		= imx_clk_scu("spi2_clk",  IMX_SC_R_SPI_2, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_SPI3_CLK]		= imx_clk_scu("spi3_clk",  IMX_SC_R_SPI_3, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_CAN0_CLK]		= imx_clk_scu("can0_clk",  IMX_SC_R_CAN_0, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_I2C0_CLK]		= imx_clk_scu("i2c0_clk",  IMX_SC_R_I2C_0, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_I2C1_CLK]		= imx_clk_scu("i2c1_clk",  IMX_SC_R_I2C_1, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_I2C2_CLK]		= imx_clk_scu("i2c2_clk",  IMX_SC_R_I2C_2, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_I2C3_CLK]		= imx_clk_scu("i2c3_clk",  IMX_SC_R_I2C_3, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_FTM0_CLK]		= imx_clk_scu("ftm0_clk",  IMX_SC_R_FTM_0, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_FTM1_CLK]		= imx_clk_scu("ftm1_clk",  IMX_SC_R_FTM_1, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_ADC0_CLK]		= imx_clk_scu("adc0_clk",  IMX_SC_R_ADC_0, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_PWM_CLK]		= imx_clk_scu("pwm_clk",   IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER);
-	clks[IMX_ADMA_LCD_CLK]		= imx_clk_scu("lcd_clk",   IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER);
+	clks[IMX_ADMA_UART0_CLK]	= imx_clk_scu("uart0_clk", IMX_SC_R_UART_0, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_UART1_CLK]	= imx_clk_scu("uart1_clk", IMX_SC_R_UART_1, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_UART2_CLK]	= imx_clk_scu("uart2_clk", IMX_SC_R_UART_2, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_UART3_CLK]	= imx_clk_scu("uart3_clk", IMX_SC_R_UART_3, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_SPI0_CLK]		= imx_clk_scu("spi0_clk",  IMX_SC_R_SPI_0, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_SPI1_CLK]		= imx_clk_scu("spi1_clk",  IMX_SC_R_SPI_1, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_SPI2_CLK]		= imx_clk_scu("spi2_clk",  IMX_SC_R_SPI_2, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_SPI3_CLK]		= imx_clk_scu("spi3_clk",  IMX_SC_R_SPI_3, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_CAN0_CLK]		= imx_clk_scu("can0_clk",  IMX_SC_R_CAN_0, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_I2C0_CLK]		= imx_clk_scu("i2c0_clk",  IMX_SC_R_I2C_0, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_I2C1_CLK]		= imx_clk_scu("i2c1_clk",  IMX_SC_R_I2C_1, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_I2C2_CLK]		= imx_clk_scu("i2c2_clk",  IMX_SC_R_I2C_2, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_I2C3_CLK]		= imx_clk_scu("i2c3_clk",  IMX_SC_R_I2C_3, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_FTM0_CLK]		= imx_clk_scu("ftm0_clk",  IMX_SC_R_FTM_0, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_FTM1_CLK]		= imx_clk_scu("ftm1_clk",  IMX_SC_R_FTM_1, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_ADC0_CLK]		= imx_clk_scu("adc0_clk",  IMX_SC_R_ADC_0, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_PWM_CLK]		= imx_clk_scu("pwm_clk",   IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_ADMA_LCD_CLK]		= imx_clk_scu("lcd_clk",   IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER, clk_cells);
 
 	/* Connectivity */
-	clks[IMX_CONN_SDHC0_CLK]	= imx_clk_scu("sdhc0_clk", IMX_SC_R_SDHC_0, IMX_SC_PM_CLK_PER);
-	clks[IMX_CONN_SDHC1_CLK]	= imx_clk_scu("sdhc1_clk", IMX_SC_R_SDHC_1, IMX_SC_PM_CLK_PER);
-	clks[IMX_CONN_SDHC2_CLK]	= imx_clk_scu("sdhc2_clk", IMX_SC_R_SDHC_2, IMX_SC_PM_CLK_PER);
-	clks[IMX_CONN_ENET0_ROOT_CLK]	= imx_clk_scu("enet0_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_PER);
-	clks[IMX_CONN_ENET0_BYPASS_CLK]	= imx_clk_scu("enet0_bypass_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_BYPASS);
-	clks[IMX_CONN_ENET0_RGMII_CLK]	= imx_clk_scu("enet0_rgmii_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_MISC0);
-	clks[IMX_CONN_ENET1_ROOT_CLK]	= imx_clk_scu("enet1_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_PER);
-	clks[IMX_CONN_ENET1_BYPASS_CLK]	= imx_clk_scu("enet1_bypass_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_BYPASS);
-	clks[IMX_CONN_ENET1_RGMII_CLK]	= imx_clk_scu("enet1_rgmii_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_MISC0);
-	clks[IMX_CONN_GPMI_BCH_IO_CLK]	= imx_clk_scu("gpmi_io_clk", IMX_SC_R_NAND, IMX_SC_PM_CLK_MST_BUS);
-	clks[IMX_CONN_GPMI_BCH_CLK]	= imx_clk_scu("gpmi_bch_clk", IMX_SC_R_NAND, IMX_SC_PM_CLK_PER);
-	clks[IMX_CONN_USB2_ACLK]	= imx_clk_scu("usb3_aclk_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_PER);
-	clks[IMX_CONN_USB2_BUS_CLK]	= imx_clk_scu("usb3_bus_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MST_BUS);
-	clks[IMX_CONN_USB2_LPM_CLK]	= imx_clk_scu("usb3_lpm_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MISC);
+	clks[IMX_CONN_SDHC0_CLK]	= imx_clk_scu("sdhc0_clk", IMX_SC_R_SDHC_0, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_CONN_SDHC1_CLK]	= imx_clk_scu("sdhc1_clk", IMX_SC_R_SDHC_1, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_CONN_SDHC2_CLK]	= imx_clk_scu("sdhc2_clk", IMX_SC_R_SDHC_2, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_CONN_ENET0_ROOT_CLK]	= imx_clk_scu("enet0_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_CONN_ENET0_BYPASS_CLK]	= imx_clk_scu("enet0_bypass_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_BYPASS, clk_cells);
+	clks[IMX_CONN_ENET0_RGMII_CLK]	= imx_clk_scu("enet0_rgmii_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_MISC0, clk_cells);
+	clks[IMX_CONN_ENET1_ROOT_CLK]	= imx_clk_scu("enet1_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_CONN_ENET1_BYPASS_CLK]	= imx_clk_scu("enet1_bypass_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_BYPASS, clk_cells);
+	clks[IMX_CONN_ENET1_RGMII_CLK]	= imx_clk_scu("enet1_rgmii_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_MISC0, clk_cells);
+	clks[IMX_CONN_GPMI_BCH_IO_CLK]	= imx_clk_scu("gpmi_io_clk", IMX_SC_R_NAND, IMX_SC_PM_CLK_MST_BUS, clk_cells);
+	clks[IMX_CONN_GPMI_BCH_CLK]	= imx_clk_scu("gpmi_bch_clk", IMX_SC_R_NAND, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_CONN_USB2_ACLK]	= imx_clk_scu("usb3_aclk_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_CONN_USB2_BUS_CLK]	= imx_clk_scu("usb3_bus_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MST_BUS, clk_cells);
+	clks[IMX_CONN_USB2_LPM_CLK]	= imx_clk_scu("usb3_lpm_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MISC, clk_cells);
 
 	/* Display controller SS */
-	clks[IMX_DC0_DISP0_CLK]		= imx_clk_scu("dc0_disp0_clk", IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0);
-	clks[IMX_DC0_DISP1_CLK]		= imx_clk_scu("dc0_disp1_clk", IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1);
+	clks[IMX_DC0_DISP0_CLK]		= imx_clk_scu("dc0_disp0_clk", IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0, clk_cells);
+	clks[IMX_DC0_DISP1_CLK]		= imx_clk_scu("dc0_disp1_clk", IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1, clk_cells);
 
 	/* MIPI-LVDS SS */
-	clks[IMX_MIPI0_I2C0_CLK]	= imx_clk_scu("mipi0_i2c0_clk", IMX_SC_R_MIPI_0_I2C_0, IMX_SC_PM_CLK_MISC2);
-	clks[IMX_MIPI0_I2C1_CLK]	= imx_clk_scu("mipi0_i2c1_clk", IMX_SC_R_MIPI_0_I2C_1, IMX_SC_PM_CLK_MISC2);
+	clks[IMX_MIPI0_I2C0_CLK]	= imx_clk_scu("mipi0_i2c0_clk", IMX_SC_R_MIPI_0_I2C_0, IMX_SC_PM_CLK_MISC2, clk_cells);
+	clks[IMX_MIPI0_I2C1_CLK]	= imx_clk_scu("mipi0_i2c1_clk", IMX_SC_R_MIPI_0_I2C_1, IMX_SC_PM_CLK_MISC2, clk_cells);
 
 	/* MIPI CSI SS */
-	clks[IMX_CSI0_CORE_CLK]		= imx_clk_scu("mipi_csi0_core_clk", IMX_SC_R_CSI_0, IMX_SC_PM_CLK_PER);
-	clks[IMX_CSI0_ESC_CLK]		= imx_clk_scu("mipi_csi0_esc_clk",  IMX_SC_R_CSI_0, IMX_SC_PM_CLK_MISC);
-	clks[IMX_CSI0_I2C0_CLK]		= imx_clk_scu("mipi_csi0_i2c0_clk", IMX_SC_R_CSI_0_I2C_0, IMX_SC_PM_CLK_PER);
-	clks[IMX_CSI0_PWM0_CLK]		= imx_clk_scu("mipi_csi0_pwm0_clk", IMX_SC_R_CSI_0_PWM_0, IMX_SC_PM_CLK_PER);
+	clks[IMX_CSI0_CORE_CLK]		= imx_clk_scu("mipi_csi0_core_clk", IMX_SC_R_CSI_0, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_CSI0_ESC_CLK]		= imx_clk_scu("mipi_csi0_esc_clk",  IMX_SC_R_CSI_0, IMX_SC_PM_CLK_MISC, clk_cells);
+	clks[IMX_CSI0_I2C0_CLK]		= imx_clk_scu("mipi_csi0_i2c0_clk", IMX_SC_R_CSI_0_I2C_0, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_CSI0_PWM0_CLK]		= imx_clk_scu("mipi_csi0_pwm0_clk", IMX_SC_R_CSI_0_PWM_0, IMX_SC_PM_CLK_PER, clk_cells);
 
 	/* GPU SS */
-	clks[IMX_GPU0_CORE_CLK]		= imx_clk_scu("gpu_core0_clk",	 IMX_SC_R_GPU_0_PID0, IMX_SC_PM_CLK_PER);
-	clks[IMX_GPU0_SHADER_CLK]	= imx_clk_scu("gpu_shader0_clk", IMX_SC_R_GPU_0_PID0, IMX_SC_PM_CLK_MISC);
+	clks[IMX_GPU0_CORE_CLK]		= imx_clk_scu("gpu_core0_clk",	 IMX_SC_R_GPU_0_PID0, IMX_SC_PM_CLK_PER, clk_cells);
+	clks[IMX_GPU0_SHADER_CLK]	= imx_clk_scu("gpu_shader0_clk", IMX_SC_R_GPU_0_PID0, IMX_SC_PM_CLK_MISC, clk_cells);
 
 	for (i = 0; i < clk_data->num; i++) {
 		if (IS_ERR(clks[i]))
@@ -134,7 +138,19 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
 				i, PTR_ERR(clks[i]));
 	}
 
-	return of_clk_add_hw_provider(ccm_node, of_clk_hw_onecell_get, clk_data);
+	if (clk_cells == 2) {
+		ret = of_clk_add_hw_provider(ccm_node, imx_scu_of_clk_src_get, imx_scu_clks);
+		if (ret)
+			imx_clk_scu_unregister();
+	} else {
+		/*
+		 * legacy binding code path doesn't unregister here because
+		 * it will be removed later.
+		 */
+		ret = of_clk_add_hw_provider(ccm_node, of_clk_hw_onecell_get, clk_data);
+	}
+
+	return ret;
 }
 
 static const struct of_device_id imx8qxp_match[] = {
diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
index b8b2072742a5..e5837e7caa50 100644
--- a/drivers/clk/imx/clk-scu.c
+++ b/drivers/clk/imx/clk-scu.c
@@ -8,6 +8,9 @@
 #include <linux/arm-smccc.h>
 #include <linux/clk-provider.h>
 #include <linux/err.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
 #include <linux/slab.h>
 
 #include "clk-scu.h"
@@ -16,6 +19,20 @@
 #define IMX_SIP_SET_CPUFREQ		0x00
 
 static struct imx_sc_ipc *ccm_ipc_handle;
+struct device_node *pd_np;
+
+struct imx_scu_clk_node {
+	const char *name;
+	u32 rsrc;
+	u8 clk_type;
+	const char * const *parents;
+	int num_parents;
+
+	struct clk_hw *hw;
+	struct list_head node;
+};
+
+struct list_head imx_scu_clks[IMX_SC_R_LAST];
 
 /*
  * struct clk_scu - Description of one SCU clock
@@ -128,9 +145,35 @@ static inline struct clk_scu *to_clk_scu(struct clk_hw *hw)
 	return container_of(hw, struct clk_scu, hw);
 }
 
-int imx_clk_scu_init(void)
+int imx_clk_scu_init(struct device_node *np)
 {
-	return imx_scu_get_handle(&ccm_ipc_handle);
+	struct platform_device *pd_dev;
+	u32 clk_cells;
+	int ret, i;
+
+	ret = imx_scu_get_handle(&ccm_ipc_handle);
+	if (ret)
+		return ret;
+
+	of_property_read_u32(np, "#clock-cells", &clk_cells);
+
+	if (clk_cells == 2) {
+		for (i = 0; i < IMX_SC_R_LAST; i++)
+			INIT_LIST_HEAD(&imx_scu_clks[i]);
+		/*
+		 * Note: SCU clock driver depends on SCU power domain to be ready
+		 * first. As there're no power domains under scu clock node in dts,
+		 * we can't use PROBE_DEFER automatically.
+		 */
+		pd_np = of_find_compatible_node(NULL, NULL, "fsl,scu-pd");
+		pd_dev = of_find_device_by_node(pd_np);
+		if (!pd_dev || !device_is_bound(&pd_dev->dev)) {
+			of_node_put(pd_np);
+			return -EPROBE_DEFER;
+		}
+	}
+
+	return 0;
 }
 
 /*
@@ -387,3 +430,112 @@ struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents,
 
 	return hw;
 }
+
+struct clk_hw *imx_scu_of_clk_src_get(struct of_phandle_args *clkspec,
+				      void *data)
+{
+	unsigned int rsrc = clkspec->args[0];
+	unsigned int idx = clkspec->args[1];
+	struct list_head *scu_clks = data;
+	struct imx_scu_clk_node *clk;
+
+	list_for_each_entry(clk, &scu_clks[rsrc], node) {
+		if (clk->clk_type == idx)
+			return clk->hw;
+	}
+
+	return ERR_PTR(-ENODEV);
+}
+
+static int imx_clk_scu_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct imx_scu_clk_node *clk = dev_get_platdata(dev);
+	struct clk_hw *hw;
+
+	hw = __imx_clk_scu(clk->name, clk->parents, clk->num_parents,
+			   clk->rsrc, clk->clk_type);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	clk->hw = hw;
+	list_add_tail(&clk->node, &imx_scu_clks[clk->rsrc]);
+
+	dev_dbg(dev, "register SCU clock rsrc:%d type:%d\n", clk->rsrc,
+		clk->clk_type);
+
+	return 0;
+}
+
+static struct platform_driver imx_clk_scu_driver = {
+	.driver = {
+		.name = "imx-scu-clk",
+		.suppress_bind_attrs = true,
+	},
+	.probe = imx_clk_scu_probe,
+};
+builtin_platform_driver(imx_clk_scu_driver);
+
+static int imx_clk_scu_attach_pd(struct device *dev, u32 rsrc_id)
+{
+	struct of_phandle_args genpdspec = {
+		.np = pd_np,
+		.args_count = 1,
+		.args[0] = rsrc_id,
+	};
+
+	return of_genpd_add_device(&genpdspec, dev);
+}
+
+struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
+				     const char * const *parents,
+				     int num_parents, u32 rsrc_id, u8 clk_type)
+{
+	struct imx_scu_clk_node clk = {
+		.name = name,
+		.rsrc = rsrc_id,
+		.clk_type = clk_type,
+		.parents = parents,
+		.num_parents = num_parents,
+	};
+	struct platform_device *pdev;
+	int ret;
+
+	pdev = platform_device_alloc(name, PLATFORM_DEVID_NONE);
+	if (!pdev) {
+		pr_err("%s: failed to allocate scu clk dev rsrc %d type %d\n",
+		       name, rsrc_id, clk_type);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	ret = platform_device_add_data(pdev, &clk, sizeof(clk));
+	if (ret) {
+		platform_device_put(pdev);
+		return ERR_PTR(ret);
+	}
+
+	pdev->driver_override = "imx-scu-clk";
+
+	ret = imx_clk_scu_attach_pd(&pdev->dev, rsrc_id);
+	if (ret)
+		pr_warn("%s: failed to attached the power domain %d\n",
+			name, ret);
+
+	platform_device_add(pdev);
+
+	/* For API backwards compatiblilty, simply return NULL for success */
+	return NULL;
+}
+
+void imx_clk_scu_unregister(void)
+{
+	struct imx_scu_clk_node *clk;
+	int i;
+
+	for (i = 0; i < IMX_SC_R_LAST; i++) {
+		list_for_each_entry(clk, &imx_scu_clks[i], node) {
+			clk_hw_unregister(clk->hw);
+			kfree(clk);
+		}
+	}
+}
diff --git a/drivers/clk/imx/clk-scu.h b/drivers/clk/imx/clk-scu.h
index 2bcfaf06a458..f7480898ea74 100644
--- a/drivers/clk/imx/clk-scu.h
+++ b/drivers/clk/imx/clk-scu.h
@@ -8,22 +8,39 @@
 #define __IMX_CLK_SCU_H
 
 #include <linux/firmware/imx/sci.h>
+#include <linux/of.h>
 
-int imx_clk_scu_init(void);
+extern struct list_head imx_scu_clks[];
+
+int imx_clk_scu_init(struct device_node *np);
+struct clk_hw *imx_scu_of_clk_src_get(struct of_phandle_args *clkspec,
+				      void *data);
+struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
+				     const char * const *parents,
+				     int num_parents, u32 rsrc_id, u8 clk_type);
 
 struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents,
 			     int num_parents, u32 rsrc_id, u8 clk_type);
 
+void imx_clk_scu_unregister(void);
+
 static inline struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id,
-					 u8 clk_type)
+					 u8 clk_type, u8 clk_cells)
 {
-	return __imx_clk_scu(name, NULL, 0, rsrc_id, clk_type);
+	if (clk_cells == 2)
+		return imx_clk_scu_alloc_dev(name, NULL, 0, rsrc_id, clk_type);
+	else
+		return __imx_clk_scu(name, NULL, 0, rsrc_id, clk_type);
 }
 
 static inline struct clk_hw *imx_clk_scu2(const char *name, const char * const *parents,
-					  int num_parents, u32 rsrc_id, u8 clk_type)
+					  int num_parents, u32 rsrc_id, u8 clk_type,
+					  u8 clk_cells)
 {
-	return __imx_clk_scu(name, parents, num_parents, rsrc_id, clk_type);
+	if (clk_cells == 2)
+		return imx_clk_scu_alloc_dev(name, parents, num_parents, rsrc_id, clk_type);
+	else
+		return __imx_clk_scu(name, parents, num_parents, rsrc_id, clk_type);
 }
 
 struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name,
-- 
2.23.0


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

* [PATCH v7 04/11] clk: imx: scu: bypass cpu power domains
  2020-07-29  8:00 [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
                   ` (2 preceding siblings ...)
  2020-07-29  8:00 ` [PATCH v7 03/11] clk: imx: scu: add two cells binding support Dong Aisheng
@ 2020-07-29  8:00 ` Dong Aisheng
  2020-07-29  8:00 ` [PATCH v7 05/11] clk: imx: scu: allow scu clk to take device pointer Dong Aisheng
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Dong Aisheng @ 2020-07-29  8:00 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

Bypass cpu power domains which are owned by ATF.

Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v6->v7:
 * no changes
v5:
 * remove unnecessary ()
v4: no changes
v3: new patch
---
 drivers/clk/imx/clk-scu.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
index e5837e7caa50..dae2529bf64e 100644
--- a/drivers/clk/imx/clk-scu.c
+++ b/drivers/clk/imx/clk-scu.c
@@ -484,6 +484,10 @@ static int imx_clk_scu_attach_pd(struct device *dev, u32 rsrc_id)
 		.args[0] = rsrc_id,
 	};
 
+	if (rsrc_id == IMX_SC_R_A35 || rsrc_id == IMX_SC_R_A53 ||
+	    rsrc_id == IMX_SC_R_A72)
+		return 0;
+
 	return of_genpd_add_device(&genpdspec, dev);
 }
 
-- 
2.23.0


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

* [PATCH v7 05/11] clk: imx: scu: allow scu clk to take device pointer
  2020-07-29  8:00 [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
                   ` (3 preceding siblings ...)
  2020-07-29  8:00 ` [PATCH v7 04/11] clk: imx: scu: bypass cpu power domains Dong Aisheng
@ 2020-07-29  8:00 ` Dong Aisheng
  2020-07-29  8:00 ` [PATCH v7 06/11] clk: imx: scu: add runtime pm support Dong Aisheng
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Dong Aisheng @ 2020-07-29  8:00 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

Used to support runtime pm.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Michael Turquette <mturquette@baylibre.com>
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v4->v7:
 * no changes
v3->v4:
 * add the missing dev poninter when call __imx_clk_scu in probe
v3: new patch
---
 drivers/clk/imx/clk-scu.c | 9 +++++----
 drivers/clk/imx/clk-scu.h | 9 +++++----
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
index dae2529bf64e..a67cca0a32ad 100644
--- a/drivers/clk/imx/clk-scu.c
+++ b/drivers/clk/imx/clk-scu.c
@@ -387,8 +387,9 @@ static const struct clk_ops clk_scu_cpu_ops = {
 	.unprepare = clk_scu_unprepare,
 };
 
-struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents,
-			     int num_parents, u32 rsrc_id, u8 clk_type)
+struct clk_hw *__imx_clk_scu(struct device *dev, const char *name,
+			     const char * const *parents, int num_parents,
+			     u32 rsrc_id, u8 clk_type)
 {
 	struct clk_init_data init;
 	struct clk_scu *clk;
@@ -422,7 +423,7 @@ struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents,
 	clk->hw.init = &init;
 
 	hw = &clk->hw;
-	ret = clk_hw_register(NULL, hw);
+	ret = clk_hw_register(dev, hw);
 	if (ret) {
 		kfree(clk);
 		hw = ERR_PTR(ret);
@@ -453,7 +454,7 @@ static int imx_clk_scu_probe(struct platform_device *pdev)
 	struct imx_scu_clk_node *clk = dev_get_platdata(dev);
 	struct clk_hw *hw;
 
-	hw = __imx_clk_scu(clk->name, clk->parents, clk->num_parents,
+	hw = __imx_clk_scu(NULL, clk->name, clk->parents, clk->num_parents,
 			   clk->rsrc, clk->clk_type);
 	if (IS_ERR(hw))
 		return PTR_ERR(hw);
diff --git a/drivers/clk/imx/clk-scu.h b/drivers/clk/imx/clk-scu.h
index f7480898ea74..22976d64a96a 100644
--- a/drivers/clk/imx/clk-scu.h
+++ b/drivers/clk/imx/clk-scu.h
@@ -19,8 +19,9 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
 				     const char * const *parents,
 				     int num_parents, u32 rsrc_id, u8 clk_type);
 
-struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents,
-			     int num_parents, u32 rsrc_id, u8 clk_type);
+struct clk_hw *__imx_clk_scu(struct device *dev, const char *name,
+			     const char * const *parents, int num_parents,
+			     u32 rsrc_id, u8 clk_type);
 
 void imx_clk_scu_unregister(void);
 
@@ -30,7 +31,7 @@ static inline struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id,
 	if (clk_cells == 2)
 		return imx_clk_scu_alloc_dev(name, NULL, 0, rsrc_id, clk_type);
 	else
-		return __imx_clk_scu(name, NULL, 0, rsrc_id, clk_type);
+		return __imx_clk_scu(NULL, name, NULL, 0, rsrc_id, clk_type);
 }
 
 static inline struct clk_hw *imx_clk_scu2(const char *name, const char * const *parents,
@@ -40,7 +41,7 @@ static inline struct clk_hw *imx_clk_scu2(const char *name, const char * const *
 	if (clk_cells == 2)
 		return imx_clk_scu_alloc_dev(name, parents, num_parents, rsrc_id, clk_type);
 	else
-		return __imx_clk_scu(name, parents, num_parents, rsrc_id, clk_type);
+		return __imx_clk_scu(NULL, name, parents, num_parents, rsrc_id, clk_type);
 }
 
 struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name,
-- 
2.23.0


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

* [PATCH v7 06/11] clk: imx: scu: add runtime pm support
  2020-07-29  8:00 [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
                   ` (4 preceding siblings ...)
  2020-07-29  8:00 ` [PATCH v7 05/11] clk: imx: scu: allow scu clk to take device pointer Dong Aisheng
@ 2020-07-29  8:00 ` Dong Aisheng
  2020-07-29  8:00 ` [PATCH v7 07/11] clk: imx: scu: add suspend/resume support Dong Aisheng
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Dong Aisheng @ 2020-07-29  8:00 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

Add runtime pm support

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Michael Turquette <mturquette@baylibre.com>
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v4->v7: no changes
v3: new patch
---
 drivers/clk/imx/clk-scu.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
index a67cca0a32ad..f5dc6731a217 100644
--- a/drivers/clk/imx/clk-scu.c
+++ b/drivers/clk/imx/clk-scu.c
@@ -11,6 +11,7 @@
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 
 #include "clk-scu.h"
@@ -453,15 +454,32 @@ static int imx_clk_scu_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct imx_scu_clk_node *clk = dev_get_platdata(dev);
 	struct clk_hw *hw;
+	int ret;
+
+	pm_runtime_set_suspended(dev);
+	pm_runtime_set_autosuspend_delay(dev, 50);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_enable(dev);
+
+	ret = pm_runtime_get_sync(dev);
+	if (ret) {
+		pm_runtime_disable(dev);
+		return ret;
+	}
 
-	hw = __imx_clk_scu(NULL, clk->name, clk->parents, clk->num_parents,
+	hw = __imx_clk_scu(dev, clk->name, clk->parents, clk->num_parents,
 			   clk->rsrc, clk->clk_type);
-	if (IS_ERR(hw))
+	if (IS_ERR(hw)) {
+		pm_runtime_disable(dev);
 		return PTR_ERR(hw);
+	}
 
 	clk->hw = hw;
 	list_add_tail(&clk->node, &imx_scu_clks[clk->rsrc]);
 
+	pm_runtime_mark_last_busy(&pdev->dev);
+	pm_runtime_put_autosuspend(&pdev->dev);
+
 	dev_dbg(dev, "register SCU clock rsrc:%d type:%d\n", clk->rsrc,
 		clk->clk_type);
 
-- 
2.23.0


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

* [PATCH v7 07/11] clk: imx: scu: add suspend/resume support
  2020-07-29  8:00 [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
                   ` (5 preceding siblings ...)
  2020-07-29  8:00 ` [PATCH v7 06/11] clk: imx: scu: add runtime pm support Dong Aisheng
@ 2020-07-29  8:00 ` Dong Aisheng
  2020-07-29  8:00 ` [PATCH v7 08/11] clk: imx: imx8qxp-lpcg: add parsing clocks from device tree Dong Aisheng
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Dong Aisheng @ 2020-07-29  8:00 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

Clock state will be lost when its power domain is completely off
during system suspend/resume. So we save and restore the state
accordingly in suspend/resume callback.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Michael Turquette <mturquette@baylibre.com>
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v6->v7:
 * no changes
v5:
 * make suspend/resume function static
v4: no changes
v3: new patch
---
 drivers/clk/imx/clk-scu.c | 49 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
index f5dc6731a217..229a290ca5b6 100644
--- a/drivers/clk/imx/clk-scu.c
+++ b/drivers/clk/imx/clk-scu.c
@@ -45,6 +45,10 @@ struct clk_scu {
 	struct clk_hw hw;
 	u16 rsrc_id;
 	u8 clk_type;
+
+	/* for state save&restore */
+	bool is_enabled;
+	u32 rate;
 };
 
 /*
@@ -430,6 +434,9 @@ struct clk_hw *__imx_clk_scu(struct device *dev, const char *name,
 		hw = ERR_PTR(ret);
 	}
 
+	if (dev)
+		dev_set_drvdata(dev, clk);
+
 	return hw;
 }
 
@@ -486,10 +493,52 @@ static int imx_clk_scu_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int __maybe_unused imx_clk_scu_suspend(struct device *dev)
+{
+	struct clk_scu *clk = dev_get_drvdata(dev);
+
+	clk->rate = clk_hw_get_rate(&clk->hw);
+	clk->is_enabled = clk_hw_is_enabled(&clk->hw);
+
+	if (clk->rate)
+		dev_dbg(dev, "save rate %d\n", clk->rate);
+
+	if (clk->is_enabled)
+		dev_dbg(dev, "save enabled state\n");
+
+	return 0;
+}
+
+static int __maybe_unused imx_clk_scu_resume(struct device *dev)
+{
+	struct clk_scu *clk = dev_get_drvdata(dev);
+	int ret = 0;
+
+	if (clk->rate) {
+		ret = clk_scu_set_rate(&clk->hw, clk->rate, 0);
+		dev_dbg(dev, "restore rate %d %s\n", clk->rate,
+			!ret ? "success" : "failed");
+	}
+
+	if (clk->is_enabled) {
+		ret = clk_scu_prepare(&clk->hw);
+		dev_dbg(dev, "restore enabled state %s\n",
+			!ret ? "success" : "failed");
+	}
+
+	return ret;
+}
+
+static const struct dev_pm_ops imx_clk_scu_pm_ops = {
+	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_clk_scu_suspend,
+				      imx_clk_scu_resume)
+};
+
 static struct platform_driver imx_clk_scu_driver = {
 	.driver = {
 		.name = "imx-scu-clk",
 		.suppress_bind_attrs = true,
+		.pm = &imx_clk_scu_pm_ops,
 	},
 	.probe = imx_clk_scu_probe,
 };
-- 
2.23.0


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

* [PATCH v7 08/11] clk: imx: imx8qxp-lpcg: add parsing clocks from device tree
  2020-07-29  8:00 [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
                   ` (6 preceding siblings ...)
  2020-07-29  8:00 ` [PATCH v7 07/11] clk: imx: scu: add suspend/resume support Dong Aisheng
@ 2020-07-29  8:00 ` Dong Aisheng
  2020-07-29  8:00 ` [PATCH v7 09/11] clk: imx: lpcg: allow lpcg clk to take device pointer Dong Aisheng
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Dong Aisheng @ 2020-07-29  8:00 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

One LPCG controller supports up to 8 clock outputs while each of them
is fixed to 4 bits.  It supports only gating function with fixed bits.
So we can use the clk-indices to fetch the corresponding clock idx from
device tree. With this way, we can write a generic LPCG clock drivers.

This patch add that support to parse clocks from device tree.

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Michael Turquette <mturquette@baylibre.com>
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
Changelog:
v5->v7:
 * no changes
v4->v5:
 * add error check for devm_of_clk_add_hw_provider
 * add more commit message
 * a few minor updates
v3->v4:
 * remove hw_autogate which is not still used by driver
 * use clock-indices to indicate LPCG clock bit offset
v1->v3: no changes
---
 drivers/clk/imx/clk-imx8qxp-lpcg.c | 124 +++++++++++++++++++++++++++++
 drivers/clk/imx/clk-lpcg-scu.c     |   8 ++
 drivers/clk/imx/clk-scu.h          |   1 +
 3 files changed, 133 insertions(+)

diff --git a/drivers/clk/imx/clk-imx8qxp-lpcg.c b/drivers/clk/imx/clk-imx8qxp-lpcg.c
index 04c8ee35e14c..1881d7f3ccec 100644
--- a/drivers/clk/imx/clk-imx8qxp-lpcg.c
+++ b/drivers/clk/imx/clk-imx8qxp-lpcg.c
@@ -9,6 +9,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
@@ -157,6 +158,122 @@ static const struct imx8qxp_ss_lpcg imx8qxp_ss_lsio = {
 	.num_max = IMX_LSIO_LPCG_CLK_END,
 };
 
+#define IMX_LPCG_MAX_CLKS	8
+
+static struct clk_hw *imx_lpcg_of_clk_src_get(struct of_phandle_args *clkspec,
+					      void *data)
+{
+	struct clk_hw_onecell_data *hw_data = data;
+	unsigned int idx = clkspec->args[0] / 4;
+
+	if (idx >= hw_data->num) {
+		pr_err("%s: invalid index %u\n", __func__, idx);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return hw_data->hws[idx];
+}
+
+static int imx_lpcg_parse_clks_from_dt(struct platform_device *pdev,
+				       struct device_node *np)
+{
+	const char *output_names[IMX_LPCG_MAX_CLKS];
+	const char *parent_names[IMX_LPCG_MAX_CLKS];
+	unsigned int bit_offset[IMX_LPCG_MAX_CLKS];
+	struct clk_hw_onecell_data *clk_data;
+	struct clk_hw **clk_hws;
+	struct resource *res;
+	void __iomem *base;
+	int count;
+	int idx;
+	int ret;
+	int i;
+
+	if (!of_device_is_compatible(np, "fsl,imx8qxp-lpcg"))
+		return -EINVAL;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	count = of_property_count_u32_elems(np, "clock-indices");
+	if (count < 0) {
+		dev_err(&pdev->dev, "failed to count clocks\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * A trick here is that we set the num of clks to the MAX instead
+	 * of the count from clock-indices because one LPCG supports up to
+	 * 8 clock outputs which each of them is fixed to 4 bits. Then we can
+	 * easily get the clock by clk-indices (bit-offset) / 4.
+	 * And the cost is very limited few pointers.
+	 */
+
+	clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hws,
+				IMX_LPCG_MAX_CLKS), GFP_KERNEL);
+	if (!clk_data)
+		return -ENOMEM;
+
+	clk_data->num = IMX_LPCG_MAX_CLKS;
+	clk_hws = clk_data->hws;
+
+	ret = of_property_read_u32_array(np, "clock-indices", bit_offset,
+					 count);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to read clock-indices\n");
+		return -EINVAL;
+	}
+
+	ret = of_clk_parent_fill(np, parent_names, count);
+	if (ret != count) {
+		dev_err(&pdev->dev, "failed to get clock parent names\n");
+		return count;
+	}
+
+	ret = of_property_read_string_array(np, "clock-output-names",
+					    output_names, count);
+	if (ret != count) {
+		dev_err(&pdev->dev, "failed to read clock-output-names\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < count; i++) {
+		idx = bit_offset[i] / 4;
+		if (idx > IMX_LPCG_MAX_CLKS) {
+			dev_warn(&pdev->dev, "invalid bit offset of clock %d\n",
+				 i);
+			ret = -EINVAL;
+			goto unreg;
+		}
+
+		clk_hws[idx] = imx_clk_lpcg_scu(output_names[i],
+						parent_names[i], 0, base,
+						bit_offset[i], false);
+		if (IS_ERR(clk_hws[idx])) {
+			dev_warn(&pdev->dev, "failed to register clock %d\n",
+				 idx);
+			ret = PTR_ERR(clk_hws[idx]);
+			goto unreg;
+		}
+	}
+
+	ret = devm_of_clk_add_hw_provider(&pdev->dev, imx_lpcg_of_clk_src_get,
+					  clk_data);
+	if (!ret)
+		return 0;
+
+unreg:
+	while (--i >= 0) {
+		idx = bit_offset[i] / 4;
+		if (clk_hws[idx])
+			imx_clk_lpcg_scu_unregister(clk_hws[idx]);
+	}
+
+	return ret;
+}
+
 static int imx8qxp_lpcg_clk_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -167,8 +284,14 @@ static int imx8qxp_lpcg_clk_probe(struct platform_device *pdev)
 	struct resource *res;
 	struct clk_hw **clks;
 	void __iomem *base;
+	int ret;
 	int i;
 
+	/* try new binding to parse clocks from device tree first */
+	ret = imx_lpcg_parse_clks_from_dt(pdev, np);
+	if (!ret)
+		return 0;
+
 	ss_lpcg = of_device_get_match_data(dev);
 	if (!ss_lpcg)
 		return -ENODEV;
@@ -219,6 +342,7 @@ static const struct of_device_id imx8qxp_lpcg_match[] = {
 	{ .compatible = "fsl,imx8qxp-lpcg-adma", &imx8qxp_ss_adma, },
 	{ .compatible = "fsl,imx8qxp-lpcg-conn", &imx8qxp_ss_conn, },
 	{ .compatible = "fsl,imx8qxp-lpcg-lsio", &imx8qxp_ss_lsio, },
+	{ .compatible = "fsl,imx8qxp-lpcg", NULL },
 	{ /* sentinel */ }
 };
 
diff --git a/drivers/clk/imx/clk-lpcg-scu.c b/drivers/clk/imx/clk-lpcg-scu.c
index a73a799fb777..897a4c3c02e2 100644
--- a/drivers/clk/imx/clk-lpcg-scu.c
+++ b/drivers/clk/imx/clk-lpcg-scu.c
@@ -114,3 +114,11 @@ struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name,
 
 	return hw;
 }
+
+void imx_clk_lpcg_scu_unregister(struct clk_hw *hw)
+{
+	struct clk_lpcg_scu *clk = to_clk_lpcg_scu(hw);
+
+	clk_hw_unregister(&clk->hw);
+	kfree(clk);
+}
diff --git a/drivers/clk/imx/clk-scu.h b/drivers/clk/imx/clk-scu.h
index 22976d64a96a..6a879526b3d5 100644
--- a/drivers/clk/imx/clk-scu.h
+++ b/drivers/clk/imx/clk-scu.h
@@ -47,4 +47,5 @@ static inline struct clk_hw *imx_clk_scu2(const char *name, const char * const *
 struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name,
 				unsigned long flags, void __iomem *reg,
 				u8 bit_idx, bool hw_gate);
+void imx_clk_lpcg_scu_unregister(struct clk_hw *hw);
 #endif
-- 
2.23.0


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

* [PATCH v7 09/11] clk: imx: lpcg: allow lpcg clk to take device pointer
  2020-07-29  8:00 [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
                   ` (7 preceding siblings ...)
  2020-07-29  8:00 ` [PATCH v7 08/11] clk: imx: imx8qxp-lpcg: add parsing clocks from device tree Dong Aisheng
@ 2020-07-29  8:00 ` Dong Aisheng
  2020-07-29  8:00 ` [PATCH v7 10/11] clk: imx: clk-imx8qxp-lpcg: add runtime pm support Dong Aisheng
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Dong Aisheng @ 2020-07-29  8:00 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

Used to support runtime pm.

Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v4->v7: no changes
v3: new patch
---
 drivers/clk/imx/clk-lpcg-scu.c |  8 ++++----
 drivers/clk/imx/clk-scu.h      | 24 ++++++++++++++++++++----
 2 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/imx/clk-lpcg-scu.c b/drivers/clk/imx/clk-lpcg-scu.c
index 897a4c3c02e2..2242e5047a0e 100644
--- a/drivers/clk/imx/clk-lpcg-scu.c
+++ b/drivers/clk/imx/clk-lpcg-scu.c
@@ -80,9 +80,9 @@ static const struct clk_ops clk_lpcg_scu_ops = {
 	.disable = clk_lpcg_scu_disable,
 };
 
-struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name,
-				unsigned long flags, void __iomem *reg,
-				u8 bit_idx, bool hw_gate)
+struct clk_hw *__imx_clk_lpcg_scu(struct device *dev, const char *name,
+				  const char *parent_name, unsigned long flags,
+				  void __iomem *reg, u8 bit_idx, bool hw_gate)
 {
 	struct clk_lpcg_scu *clk;
 	struct clk_init_data init;
@@ -106,7 +106,7 @@ struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name,
 	clk->hw.init = &init;
 
 	hw = &clk->hw;
-	ret = clk_hw_register(NULL, hw);
+	ret = clk_hw_register(dev, hw);
 	if (ret) {
 		kfree(clk);
 		hw = ERR_PTR(ret);
diff --git a/drivers/clk/imx/clk-scu.h b/drivers/clk/imx/clk-scu.h
index 6a879526b3d5..faee1ba5c4ee 100644
--- a/drivers/clk/imx/clk-scu.h
+++ b/drivers/clk/imx/clk-scu.h
@@ -25,6 +25,11 @@ struct clk_hw *__imx_clk_scu(struct device *dev, const char *name,
 
 void imx_clk_scu_unregister(void);
 
+struct clk_hw *__imx_clk_lpcg_scu(struct device *dev, const char *name,
+				  const char *parent_name, unsigned long flags,
+				  void __iomem *reg, u8 bit_idx, bool hw_gate);
+void imx_clk_lpcg_scu_unregister(struct clk_hw *hw);
+
 static inline struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id,
 					 u8 clk_type, u8 clk_cells)
 {
@@ -44,8 +49,19 @@ static inline struct clk_hw *imx_clk_scu2(const char *name, const char * const *
 		return __imx_clk_scu(NULL, name, parents, num_parents, rsrc_id, clk_type);
 }
 
-struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name,
-				unsigned long flags, void __iomem *reg,
-				u8 bit_idx, bool hw_gate);
-void imx_clk_lpcg_scu_unregister(struct clk_hw *hw);
+static inline struct clk_hw *imx_clk_lpcg_scu_dev(struct device *dev, const char *name,
+						  const char *parent_name, unsigned long flags,
+						  void __iomem *reg, u8 bit_idx, bool hw_gate)
+{
+	return __imx_clk_lpcg_scu(dev, name, parent_name, flags, reg,
+				  bit_idx, hw_gate);
+}
+
+static inline struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name,
+					      unsigned long flags, void __iomem *reg,
+					      u8 bit_idx, bool hw_gate)
+{
+	return __imx_clk_lpcg_scu(NULL, name, parent_name, flags, reg,
+				  bit_idx, hw_gate);
+}
 #endif
-- 
2.23.0


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

* [PATCH v7 10/11] clk: imx: clk-imx8qxp-lpcg: add runtime pm support
  2020-07-29  8:00 [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
                   ` (8 preceding siblings ...)
  2020-07-29  8:00 ` [PATCH v7 09/11] clk: imx: lpcg: allow lpcg clk to take device pointer Dong Aisheng
@ 2020-07-29  8:00 ` Dong Aisheng
  2020-07-29  8:00 ` [PATCH v7 11/11] clk: imx: lpcg: add suspend/resume support Dong Aisheng
  2020-07-29  8:04 ` [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
  11 siblings, 0 replies; 17+ messages in thread
From: Dong Aisheng @ 2020-07-29  8:00 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

add runtime pm support

Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v5->v7:
 * no changes
v4->v5:
 * minor err check fix
v3->v4:
 * disable rpm when error out
v3: new patch
---
 drivers/clk/imx/clk-imx8qxp-lpcg.c | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/imx/clk-imx8qxp-lpcg.c b/drivers/clk/imx/clk-imx8qxp-lpcg.c
index 1881d7f3ccec..3385de76f6c7 100644
--- a/drivers/clk/imx/clk-imx8qxp-lpcg.c
+++ b/drivers/clk/imx/clk-imx8qxp-lpcg.c
@@ -12,6 +12,7 @@
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 
 #include "clk-scu.h"
@@ -239,6 +240,12 @@ static int imx_lpcg_parse_clks_from_dt(struct platform_device *pdev,
 		return -EINVAL;
 	}
 
+	pm_runtime_get_noresume(&pdev->dev);
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
 	for (i = 0; i < count; i++) {
 		idx = bit_offset[i] / 4;
 		if (idx > IMX_LPCG_MAX_CLKS) {
@@ -248,9 +255,9 @@ static int imx_lpcg_parse_clks_from_dt(struct platform_device *pdev,
 			goto unreg;
 		}
 
-		clk_hws[idx] = imx_clk_lpcg_scu(output_names[i],
-						parent_names[i], 0, base,
-						bit_offset[i], false);
+		clk_hws[idx] = imx_clk_lpcg_scu_dev(&pdev->dev, output_names[i],
+						    parent_names[i], 0, base,
+						    bit_offset[i], false);
 		if (IS_ERR(clk_hws[idx])) {
 			dev_warn(&pdev->dev, "failed to register clock %d\n",
 				 idx);
@@ -261,8 +268,13 @@ static int imx_lpcg_parse_clks_from_dt(struct platform_device *pdev,
 
 	ret = devm_of_clk_add_hw_provider(&pdev->dev, imx_lpcg_of_clk_src_get,
 					  clk_data);
-	if (!ret)
-		return 0;
+	if (ret)
+		goto unreg;
+
+	pm_runtime_mark_last_busy(&pdev->dev);
+	pm_runtime_put_autosuspend(&pdev->dev);
+
+	return 0;
 
 unreg:
 	while (--i >= 0) {
@@ -271,6 +283,8 @@ static int imx_lpcg_parse_clks_from_dt(struct platform_device *pdev,
 			imx_clk_lpcg_scu_unregister(clk_hws[idx]);
 	}
 
+	pm_runtime_disable(&pdev->dev);
+
 	return ret;
 }
 
-- 
2.23.0


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

* [PATCH v7 11/11] clk: imx: lpcg: add suspend/resume support
  2020-07-29  8:00 [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
                   ` (9 preceding siblings ...)
  2020-07-29  8:00 ` [PATCH v7 10/11] clk: imx: clk-imx8qxp-lpcg: add runtime pm support Dong Aisheng
@ 2020-07-29  8:00 ` Dong Aisheng
  2020-07-29  8:04 ` [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
  11 siblings, 0 replies; 17+ messages in thread
From: Dong Aisheng @ 2020-07-29  8:00 UTC (permalink / raw)
  To: linux-clk
  Cc: linux-arm-kernel, sboyd, mturquette, shawnguo, fabio.estevam,
	linux-imx, kernel, Dong Aisheng

LPCG clock state may be lost when it's power domain is completely
off during system suspend/resume and we need save and restore the
state properly.

Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v5->v7:
 * no changes
v5:
 * make suspend/resume function static
 * improve code comments
v4: no changes
v3: new patch
---
 drivers/clk/imx/clk-imx8qxp-lpcg.c |  1 +
 drivers/clk/imx/clk-lpcg-scu.c     | 37 ++++++++++++++++++++++++++++++
 drivers/clk/imx/clk-scu.h          |  1 +
 3 files changed, 39 insertions(+)

diff --git a/drivers/clk/imx/clk-imx8qxp-lpcg.c b/drivers/clk/imx/clk-imx8qxp-lpcg.c
index 3385de76f6c7..4d4a3a65bcec 100644
--- a/drivers/clk/imx/clk-imx8qxp-lpcg.c
+++ b/drivers/clk/imx/clk-imx8qxp-lpcg.c
@@ -364,6 +364,7 @@ static struct platform_driver imx8qxp_lpcg_clk_driver = {
 	.driver = {
 		.name = "imx8qxp-lpcg-clk",
 		.of_match_table = imx8qxp_lpcg_match,
+		.pm = &imx_clk_lpcg_scu_pm_ops,
 		.suppress_bind_attrs = true,
 	},
 	.probe = imx8qxp_lpcg_clk_probe,
diff --git a/drivers/clk/imx/clk-lpcg-scu.c b/drivers/clk/imx/clk-lpcg-scu.c
index 2242e5047a0e..5bd8af371059 100644
--- a/drivers/clk/imx/clk-lpcg-scu.c
+++ b/drivers/clk/imx/clk-lpcg-scu.c
@@ -33,6 +33,9 @@ struct clk_lpcg_scu {
 	void __iomem *reg;
 	u8 bit_idx;
 	bool hw_gate;
+
+	/* for state save&restore */
+	u32 state;
 };
 
 #define to_clk_lpcg_scu(_hw) container_of(_hw, struct clk_lpcg_scu, hw)
@@ -112,6 +115,9 @@ struct clk_hw *__imx_clk_lpcg_scu(struct device *dev, const char *name,
 		hw = ERR_PTR(ret);
 	}
 
+	if (dev)
+		dev_set_drvdata(dev, clk);
+
 	return hw;
 }
 
@@ -122,3 +128,34 @@ void imx_clk_lpcg_scu_unregister(struct clk_hw *hw)
 	clk_hw_unregister(&clk->hw);
 	kfree(clk);
 }
+
+static int __maybe_unused imx_clk_lpcg_scu_suspend(struct device *dev)
+{
+	struct clk_lpcg_scu *clk = dev_get_drvdata(dev);
+
+	clk->state = readl_relaxed(clk->reg);
+	dev_dbg(dev, "save lpcg state 0x%x\n", clk->state);
+
+	return 0;
+}
+
+static int __maybe_unused imx_clk_lpcg_scu_resume(struct device *dev)
+{
+	struct clk_lpcg_scu *clk = dev_get_drvdata(dev);
+
+	/*
+	 * FIXME: Sometimes writes don't work unless the CPU issues
+	 * them twice
+	 */
+
+	writel(clk->state, clk->reg);
+	writel(clk->state, clk->reg);
+	dev_dbg(dev, "restore lpcg state 0x%x\n", clk->state);
+
+	return 0;
+}
+
+const struct dev_pm_ops imx_clk_lpcg_scu_pm_ops = {
+	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_clk_lpcg_scu_suspend,
+				      imx_clk_lpcg_scu_resume)
+};
diff --git a/drivers/clk/imx/clk-scu.h b/drivers/clk/imx/clk-scu.h
index faee1ba5c4ee..e8352164923e 100644
--- a/drivers/clk/imx/clk-scu.h
+++ b/drivers/clk/imx/clk-scu.h
@@ -11,6 +11,7 @@
 #include <linux/of.h>
 
 extern struct list_head imx_scu_clks[];
+extern const struct dev_pm_ops imx_clk_lpcg_scu_pm_ops;
 
 int imx_clk_scu_init(struct device_node *np);
 struct clk_hw *imx_scu_of_clk_src_get(struct of_phandle_args *clkspec,
-- 
2.23.0


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

* Re: [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support
  2020-07-29  8:00 [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
                   ` (10 preceding siblings ...)
  2020-07-29  8:00 ` [PATCH v7 11/11] clk: imx: lpcg: add suspend/resume support Dong Aisheng
@ 2020-07-29  8:04 ` Dong Aisheng
  2020-08-17  7:42   ` Dong Aisheng
  11 siblings, 1 reply; 17+ messages in thread
From: Dong Aisheng @ 2020-07-29  8:04 UTC (permalink / raw)
  To: Dong Aisheng
  Cc: linux-clk,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Stephen Boyd, Michael Turquette, Shawn Guo, Fabio Estevam,
	dl-linux-imx, Sascha Hauer

Hi Stephen,

This patchset addressed all your new comments.
Right now only Patch 2/3 still haven't got any R-b or A-b tags. So
still need your help to review.
All other patches already got the R-b tags.

BTW, for [PATCH v7 02/11] dt-bindings: clock: imx-lpcg: add support to parse
 clocks from device tree.
It was reviewed by Rob/Shawn and you before, however, due to the legacy binding
file has been removed and changed to json format.
So this patch also updated to json format accordingly based on the
former reviewed patch
and need a re-review.

Regards
Aisheng

On Wed, Jul 29, 2020 at 4:04 PM Dong Aisheng <aisheng.dong@nxp.com> wrote:
>
> This patch series is a preparation for the MX8 Architecture improvement.
> As for IMX SCU based platforms like MX8QM and MX8QXP, they are comprised
> of a couple of SS(Subsystems) while most of them within the same SS
> can be shared. e.g. Clocks, Devices and etc.
>
> However, current clock binding is using SW IDs for device tree to use
> which can cause troubles in writing the common <soc>-ss-xx.dtsi file for
> different SoCs.
>
> This patch series aims to introduce a new binding which is more close to
> hardware and platform independent and can makes us write a more general
> drivers for different SCU based SoCs.
>
> Another important thing is that on MX8, each Clock resource is associated
> with a power domain. So we have to attach that clock device to the power
> domain in order to make it work properly. Further more, the clock state
> will be lost when its power domain is completely off during suspend/resume,
> so we also introduce the clock state save&restore mechanism.
>
> It's based on latest shanw/for-next branch.
>
> The top commit is:
> 3c1a41dab7b8 Merge branch 'imx/defconfig' into for-next
>
> ChangeLog:
> v6->v7:
>  * addressed all comments from Stephen
>  * rebased to latest shawn/for-next
> v5->v6:
>  * add scu clk unregister if add provider failed
> v4->v5:
>  * Address all comments from Stephen
> v3->v4:
>  * use clk-indices for LPCG to fetch each clks offset from dt
> v2->v3:
>  * change scu clk into two cells binding
>  * add clk pm patches to ease the understand of the changes
> v1->v2:
>  * SCU clock changed to one cell clock binding inspired by arm,scpi.txt
>    Documentation/devicetree/bindings/arm/arm,scpi.txt
>  * Add required power domain property
>  * Dropped PATCH 3&4 first, will send the updated version accordingly
>    after the binding is finally determined,
>
> Dong Aisheng (11):
>   dt-bindings: firmware: imx-scu: new binding to parse clocks from
>     device tree
>   dt-bindings: clock: imx-lpcg: add support to parse clocks from device
>     tree
>   clk: imx: scu: add two cells binding support
>   clk: imx: scu: bypass cpu power domains
>   clk: imx: scu: allow scu clk to take device pointer
>   clk: imx: scu: add runtime pm support
>   clk: imx: scu: add suspend/resume support
>   clk: imx: imx8qxp-lpcg: add parsing clocks from device tree
>   clk: imx: lpcg: allow lpcg clk to take device pointer
>   clk: imx: clk-imx8qxp-lpcg: add runtime pm support
>   clk: imx: lpcg: add suspend/resume support
>
>  .../bindings/arm/freescale/fsl,scu.txt        |  12 +-
>  .../bindings/clock/imx8qxp-lpcg.yaml          |  79 ++++--
>  drivers/clk/imx/clk-imx8qxp-lpcg.c            | 139 +++++++++++
>  drivers/clk/imx/clk-imx8qxp.c                 | 136 +++++-----
>  drivers/clk/imx/clk-lpcg-scu.c                |  53 +++-
>  drivers/clk/imx/clk-scu.c                     | 234 +++++++++++++++++-
>  drivers/clk/imx/clk-scu.h                     |  56 ++++-
>  include/dt-bindings/clock/imx8-lpcg.h         |  14 ++
>  8 files changed, 620 insertions(+), 103 deletions(-)
>  create mode 100644 include/dt-bindings/clock/imx8-lpcg.h
>
> --
> 2.23.0
>

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

* Re: [PATCH v7 02/11] dt-bindings: clock: imx-lpcg: add support to parse clocks from device tree
  2020-07-29  8:00 ` [PATCH v7 02/11] dt-bindings: clock: imx-lpcg: add support " Dong Aisheng
@ 2020-07-29  8:06   ` Dong Aisheng
  2020-07-31 21:28   ` Rob Herring
  1 sibling, 0 replies; 17+ messages in thread
From: Dong Aisheng @ 2020-07-29  8:06 UTC (permalink / raw)
  To: Dong Aisheng
  Cc: linux-clk,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Stephen Boyd, Michael Turquette, Shawn Guo, Fabio Estevam,
	dl-linux-imx, Sascha Hauer, devicetree, Rob Herring

Hi Rob, Stephen, Shawn,

On Wed, Jul 29, 2020 at 4:05 PM Dong Aisheng <aisheng.dong@nxp.com> wrote:
>
> MX8QM and MX8QXP LPCG Clocks are mostly the same except they may reside
> in different subsystems across CPUs and also vary a bit on the availability.
>
> Same as SCU clock, we want to move the clock definition into device tree
> which can fully decouple the dependency of Clock ID definition from device
> tree and make us be able to write a fully generic lpcg clock driver.
>
> And we can also use the existence of clock nodes in device tree to address
> the device and clock availability differences across different SoCs.
>
> Cc: Sascha Hauer <kernel@pengutronix.de>
> Cc: Michael Turquette <mturquette@baylibre.com>
> Cc: devicetree@vger.kernel.org
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Stephen Boyd <sboyd@kernel.org>
> Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>

This patch has been reviewed before, however, i removed your tags due
to the legacy binding
file was removed and switched to json schema.
So i updated this patch to json schema accordingly and need your
kindly re-review.

The former reviewed patch is here:
https://patchwork.kernel.org/patch/11439079/

Regards
Aisheng

> ---
> ChangeLog:
> v6->v7:
>  * No other changes except converting to json schema based on the former reviewed
>    patches due to the lagecy binding file was removed in latests kernel.
>    Because the format is different now, i removed the former R-b
>    and A-b tags and request a new review.
>    See original patch here:
>    https://patchwork.kernel.org/patch/11439079/
> v4->v6:
>  * no changes
> v3->v4:
>  * change bit-offset property to clock-indices
>  * use constant macro to define clock indinces
>  * drop hw-autogate property which is still not used by drivers
> v2->v3:
>  * no changes
> v1->v2:
>  * Update example
>  * Add power domain property
> ---
>  .../bindings/clock/imx8qxp-lpcg.yaml          | 79 ++++++++++++++-----
>  include/dt-bindings/clock/imx8-lpcg.h         | 14 ++++
>  2 files changed, 74 insertions(+), 19 deletions(-)
>  create mode 100644 include/dt-bindings/clock/imx8-lpcg.h
>
> diff --git a/Documentation/devicetree/bindings/clock/imx8qxp-lpcg.yaml b/Documentation/devicetree/bindings/clock/imx8qxp-lpcg.yaml
> index 33f3010f48c3..e709e530e17a 100644
> --- a/Documentation/devicetree/bindings/clock/imx8qxp-lpcg.yaml
> +++ b/Documentation/devicetree/bindings/clock/imx8qxp-lpcg.yaml
> @@ -21,27 +21,58 @@ description: |
>
>    The clock consumer should specify the desired clock by having the clock
>    ID in its "clocks" phandle cell. See the full list of clock IDs from:
> -  include/dt-bindings/clock/imx8-clock.h
> +  include/dt-bindings/clock/imx8-lpcg.h
>
>  properties:
>    compatible:
> -    enum:
> -      - fsl,imx8qxp-lpcg-adma
> -      - fsl,imx8qxp-lpcg-conn
> -      - fsl,imx8qxp-lpcg-dc
> -      - fsl,imx8qxp-lpcg-dsp
> -      - fsl,imx8qxp-lpcg-gpu
> -      - fsl,imx8qxp-lpcg-hsio
> -      - fsl,imx8qxp-lpcg-img
> -      - fsl,imx8qxp-lpcg-lsio
> -      - fsl,imx8qxp-lpcg-vpu
> -
> +    oneOf:
> +      - const: fsl,imx8qxp-lpcg
> +      - items:
> +          - enum:
> +            - fsl,imx8qm-lpcg
> +          - const: fsl,imx8qxp-lpcg
> +      - enum:
> +        - fsl,imx8qxp-lpcg-adma
> +        - fsl,imx8qxp-lpcg-conn
> +        - fsl,imx8qxp-lpcg-dc
> +        - fsl,imx8qxp-lpcg-dsp
> +        - fsl,imx8qxp-lpcg-gpu
> +        - fsl,imx8qxp-lpcg-hsio
> +        - fsl,imx8qxp-lpcg-img
> +        - fsl,imx8qxp-lpcg-lsio
> +        - fsl,imx8qxp-lpcg-vpu
> +        deprecated: true
>    reg:
>      maxItems: 1
>
>    '#clock-cells':
>      const: 1
>
> +  clocks:
> +    description: |
> +      Input parent clocks phandle array for each clock
> +    minItems: 1
> +    maxItems: 8
> +
> +  clock-indices:
> +    description: |
> +      An integer array indicating the bit offset for each clock.
> +      Refer to <include/dt-bindings/clock/imx8-lpcg.h> for the
> +      supported LPCG clock indices.
> +    minItems: 1
> +    maxItems: 8
> +
> +  clock-output-names:
> +    description: |
> +      Shall be the corresponding names of the outputs.
> +      NOTE this property must be specified in the same order
> +      as the clock-indices property.
> +    minItems: 1
> +    maxItems: 8
> +
> +  power-domains:
> +    maxItems: 1
> +
>  required:
>    - compatible
>    - reg
> @@ -51,23 +82,33 @@ additionalProperties: false
>
>  examples:
>    - |
> -    #include <dt-bindings/clock/imx8-clock.h>
> +    #include <dt-bindings/clock/imx8-lpcg.h>
>      #include <dt-bindings/firmware/imx/rsrc.h>
>      #include <dt-bindings/interrupt-controller/arm-gic.h>
>
> -    clock-controller@5b200000 {
> -        compatible = "fsl,imx8qxp-lpcg-conn";
> -        reg = <0x5b200000 0xb0000>;
> +    sdhc0_lpcg: clock-controller@5b200000 {
> +        compatible = "fsl,imx8qxp-lpcg";
> +        reg = <0x5b200000 0x10000>;
>          #clock-cells = <1>;
> +        clocks = <&sdhc0_clk IMX_SC_PM_CLK_PER>,
> +                 <&conn_ipg_clk>,
> +                 <&conn_axi_clk>;
> +        clock-indices = <IMX_LPCG_CLK_0>,
> +                        <IMX_LPCG_CLK_4>,
> +                        <IMX_LPCG_CLK_5>;
> +        clock-output-names = "sdhc0_lpcg_per_clk",
> +                             "sdhc0_lpcg_ipg_clk",
> +                             "sdhc0_lpcg_ahb_clk";
> +        power-domains = <&pd IMX_SC_R_SDHC_0>;
>      };
>
>      mmc@5b010000 {
>          compatible = "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
>          interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>;
>          reg = <0x5b010000 0x10000>;
> -        clocks = <&conn_lpcg IMX_CONN_LPCG_SDHC0_IPG_CLK>,
> -                 <&conn_lpcg IMX_CONN_LPCG_SDHC0_PER_CLK>,
> -                 <&conn_lpcg IMX_CONN_LPCG_SDHC0_HCLK>;
> +        clocks = <&sdhc0_lpcg IMX_LPCG_CLK_4>,
> +                 <&sdhc0_lpcg IMX_LPCG_CLK_0>,
> +                 <&sdhc0_lpcg IMX_LPCG_CLK_5>;
>          clock-names = "ipg", "per", "ahb";
>          power-domains = <&pd IMX_SC_R_SDHC_0>;
>      };
> diff --git a/include/dt-bindings/clock/imx8-lpcg.h b/include/dt-bindings/clock/imx8-lpcg.h
> new file mode 100644
> index 000000000000..d202715652c3
> --- /dev/null
> +++ b/include/dt-bindings/clock/imx8-lpcg.h
> @@ -0,0 +1,14 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright 2019-2020 NXP
> + *   Dong Aisheng <aisheng.dong@nxp.com>
> + */
> +
> +#define IMX_LPCG_CLK_0 0
> +#define IMX_LPCG_CLK_1 4
> +#define IMX_LPCG_CLK_2 8
> +#define IMX_LPCG_CLK_3 12
> +#define IMX_LPCG_CLK_4 16
> +#define IMX_LPCG_CLK_5 20
> +#define IMX_LPCG_CLK_6 24
> +#define IMX_LPCG_CLK_7 28
> --
> 2.23.0
>

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

* Re: [PATCH v7 02/11] dt-bindings: clock: imx-lpcg: add support to parse clocks from device tree
  2020-07-29  8:00 ` [PATCH v7 02/11] dt-bindings: clock: imx-lpcg: add support " Dong Aisheng
  2020-07-29  8:06   ` Dong Aisheng
@ 2020-07-31 21:28   ` Rob Herring
  1 sibling, 0 replies; 17+ messages in thread
From: Rob Herring @ 2020-07-31 21:28 UTC (permalink / raw)
  To: Dong Aisheng
  Cc: linux-imx, linux-arm-kernel, kernel, fabio.estevam, sboyd,
	mturquette, devicetree, linux-clk, shawnguo

On Wed, 29 Jul 2020 16:00:09 +0800, Dong Aisheng wrote:
> MX8QM and MX8QXP LPCG Clocks are mostly the same except they may reside
> in different subsystems across CPUs and also vary a bit on the availability.
> 
> Same as SCU clock, we want to move the clock definition into device tree
> which can fully decouple the dependency of Clock ID definition from device
> tree and make us be able to write a fully generic lpcg clock driver.
> 
> And we can also use the existence of clock nodes in device tree to address
> the device and clock availability differences across different SoCs.
> 
> Cc: Sascha Hauer <kernel@pengutronix.de>
> Cc: Michael Turquette <mturquette@baylibre.com>
> Cc: devicetree@vger.kernel.org
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Stephen Boyd <sboyd@kernel.org>
> Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
> ---
> ChangeLog:
> v6->v7:
>  * No other changes except converting to json schema based on the former reviewed
>    patches due to the lagecy binding file was removed in latests kernel.
>    Because the format is different now, i removed the former R-b
>    and A-b tags and request a new review.
>    See original patch here:
>    https://patchwork.kernel.org/patch/11439079/
> v4->v6:
>  * no changes
> v3->v4:
>  * change bit-offset property to clock-indices
>  * use constant macro to define clock indinces
>  * drop hw-autogate property which is still not used by drivers
> v2->v3:
>  * no changes
> v1->v2:
>  * Update example
>  * Add power domain property
> ---
>  .../bindings/clock/imx8qxp-lpcg.yaml          | 79 ++++++++++++++-----
>  include/dt-bindings/clock/imx8-lpcg.h         | 14 ++++
>  2 files changed, 74 insertions(+), 19 deletions(-)
>  create mode 100644 include/dt-bindings/clock/imx8-lpcg.h
> 

Reviewed-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support
  2020-07-29  8:04 ` [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
@ 2020-08-17  7:42   ` Dong Aisheng
  2020-09-02  6:35     ` Dong Aisheng
  0 siblings, 1 reply; 17+ messages in thread
From: Dong Aisheng @ 2020-08-17  7:42 UTC (permalink / raw)
  To: Dong Aisheng
  Cc: linux-clk,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Stephen Boyd, Michael Turquette, Shawn Guo, Fabio Estevam,
	dl-linux-imx, Sascha Hauer

Gently ping...

On Wed, Jul 29, 2020 at 4:04 PM Dong Aisheng <dongas86@gmail.com> wrote:
>
> Hi Stephen,
>
> This patchset addressed all your new comments.
> Right now only Patch 2/3 still haven't got any R-b or A-b tags. So
> still need your help to review.
> All other patches already got the R-b tags.
>
> BTW, for [PATCH v7 02/11] dt-bindings: clock: imx-lpcg: add support to parse
>  clocks from device tree.
> It was reviewed by Rob/Shawn and you before, however, due to the legacy binding
> file has been removed and changed to json format.
> So this patch also updated to json format accordingly based on the
> former reviewed patch
> and need a re-review.
>
> Regards
> Aisheng
>
> On Wed, Jul 29, 2020 at 4:04 PM Dong Aisheng <aisheng.dong@nxp.com> wrote:
> >
> > This patch series is a preparation for the MX8 Architecture improvement.
> > As for IMX SCU based platforms like MX8QM and MX8QXP, they are comprised
> > of a couple of SS(Subsystems) while most of them within the same SS
> > can be shared. e.g. Clocks, Devices and etc.
> >
> > However, current clock binding is using SW IDs for device tree to use
> > which can cause troubles in writing the common <soc>-ss-xx.dtsi file for
> > different SoCs.
> >
> > This patch series aims to introduce a new binding which is more close to
> > hardware and platform independent and can makes us write a more general
> > drivers for different SCU based SoCs.
> >
> > Another important thing is that on MX8, each Clock resource is associated
> > with a power domain. So we have to attach that clock device to the power
> > domain in order to make it work properly. Further more, the clock state
> > will be lost when its power domain is completely off during suspend/resume,
> > so we also introduce the clock state save&restore mechanism.
> >
> > It's based on latest shanw/for-next branch.
> >
> > The top commit is:
> > 3c1a41dab7b8 Merge branch 'imx/defconfig' into for-next
> >
> > ChangeLog:
> > v6->v7:
> >  * addressed all comments from Stephen
> >  * rebased to latest shawn/for-next
> > v5->v6:
> >  * add scu clk unregister if add provider failed
> > v4->v5:
> >  * Address all comments from Stephen
> > v3->v4:
> >  * use clk-indices for LPCG to fetch each clks offset from dt
> > v2->v3:
> >  * change scu clk into two cells binding
> >  * add clk pm patches to ease the understand of the changes
> > v1->v2:
> >  * SCU clock changed to one cell clock binding inspired by arm,scpi.txt
> >    Documentation/devicetree/bindings/arm/arm,scpi.txt
> >  * Add required power domain property
> >  * Dropped PATCH 3&4 first, will send the updated version accordingly
> >    after the binding is finally determined,
> >
> > Dong Aisheng (11):
> >   dt-bindings: firmware: imx-scu: new binding to parse clocks from
> >     device tree
> >   dt-bindings: clock: imx-lpcg: add support to parse clocks from device
> >     tree
> >   clk: imx: scu: add two cells binding support
> >   clk: imx: scu: bypass cpu power domains
> >   clk: imx: scu: allow scu clk to take device pointer
> >   clk: imx: scu: add runtime pm support
> >   clk: imx: scu: add suspend/resume support
> >   clk: imx: imx8qxp-lpcg: add parsing clocks from device tree
> >   clk: imx: lpcg: allow lpcg clk to take device pointer
> >   clk: imx: clk-imx8qxp-lpcg: add runtime pm support
> >   clk: imx: lpcg: add suspend/resume support
> >
> >  .../bindings/arm/freescale/fsl,scu.txt        |  12 +-
> >  .../bindings/clock/imx8qxp-lpcg.yaml          |  79 ++++--
> >  drivers/clk/imx/clk-imx8qxp-lpcg.c            | 139 +++++++++++
> >  drivers/clk/imx/clk-imx8qxp.c                 | 136 +++++-----
> >  drivers/clk/imx/clk-lpcg-scu.c                |  53 +++-
> >  drivers/clk/imx/clk-scu.c                     | 234 +++++++++++++++++-
> >  drivers/clk/imx/clk-scu.h                     |  56 ++++-
> >  include/dt-bindings/clock/imx8-lpcg.h         |  14 ++
> >  8 files changed, 620 insertions(+), 103 deletions(-)
> >  create mode 100644 include/dt-bindings/clock/imx8-lpcg.h
> >
> > --
> > 2.23.0
> >

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

* Re: [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support
  2020-08-17  7:42   ` Dong Aisheng
@ 2020-09-02  6:35     ` Dong Aisheng
  0 siblings, 0 replies; 17+ messages in thread
From: Dong Aisheng @ 2020-09-02  6:35 UTC (permalink / raw)
  To: Dong Aisheng
  Cc: linux-clk,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Stephen Boyd, Michael Turquette, Shawn Guo, Fabio Estevam,
	dl-linux-imx, Sascha Hauer

Hi Stephen,

Would you help look at this?
Now only one patch left that still does not have a R-b tag and needs
your review.
[PATCH v7 03/11] clk: imx: scu: add two cells binding support
All other patches already get R-b tags.

Regards
Aisheng

On Mon, Aug 17, 2020 at 3:42 PM Dong Aisheng <dongas86@gmail.com> wrote:
>
> Gently ping...
>
> On Wed, Jul 29, 2020 at 4:04 PM Dong Aisheng <dongas86@gmail.com> wrote:
> >
> > Hi Stephen,
> >
> > This patchset addressed all your new comments.
> > Right now only Patch 2/3 still haven't got any R-b or A-b tags. So
> > still need your help to review.
> > All other patches already got the R-b tags.
> >
> > BTW, for [PATCH v7 02/11] dt-bindings: clock: imx-lpcg: add support to parse
> >  clocks from device tree.
> > It was reviewed by Rob/Shawn and you before, however, due to the legacy binding
> > file has been removed and changed to json format.
> > So this patch also updated to json format accordingly based on the
> > former reviewed patch
> > and need a re-review.
> >
> > Regards
> > Aisheng
> >
> > On Wed, Jul 29, 2020 at 4:04 PM Dong Aisheng <aisheng.dong@nxp.com> wrote:
> > >
> > > This patch series is a preparation for the MX8 Architecture improvement.
> > > As for IMX SCU based platforms like MX8QM and MX8QXP, they are comprised
> > > of a couple of SS(Subsystems) while most of them within the same SS
> > > can be shared. e.g. Clocks, Devices and etc.
> > >
> > > However, current clock binding is using SW IDs for device tree to use
> > > which can cause troubles in writing the common <soc>-ss-xx.dtsi file for
> > > different SoCs.
> > >
> > > This patch series aims to introduce a new binding which is more close to
> > > hardware and platform independent and can makes us write a more general
> > > drivers for different SCU based SoCs.
> > >
> > > Another important thing is that on MX8, each Clock resource is associated
> > > with a power domain. So we have to attach that clock device to the power
> > > domain in order to make it work properly. Further more, the clock state
> > > will be lost when its power domain is completely off during suspend/resume,
> > > so we also introduce the clock state save&restore mechanism.
> > >
> > > It's based on latest shanw/for-next branch.
> > >
> > > The top commit is:
> > > 3c1a41dab7b8 Merge branch 'imx/defconfig' into for-next
> > >
> > > ChangeLog:
> > > v6->v7:
> > >  * addressed all comments from Stephen
> > >  * rebased to latest shawn/for-next
> > > v5->v6:
> > >  * add scu clk unregister if add provider failed
> > > v4->v5:
> > >  * Address all comments from Stephen
> > > v3->v4:
> > >  * use clk-indices for LPCG to fetch each clks offset from dt
> > > v2->v3:
> > >  * change scu clk into two cells binding
> > >  * add clk pm patches to ease the understand of the changes
> > > v1->v2:
> > >  * SCU clock changed to one cell clock binding inspired by arm,scpi.txt
> > >    Documentation/devicetree/bindings/arm/arm,scpi.txt
> > >  * Add required power domain property
> > >  * Dropped PATCH 3&4 first, will send the updated version accordingly
> > >    after the binding is finally determined,
> > >
> > > Dong Aisheng (11):
> > >   dt-bindings: firmware: imx-scu: new binding to parse clocks from
> > >     device tree
> > >   dt-bindings: clock: imx-lpcg: add support to parse clocks from device
> > >     tree
> > >   clk: imx: scu: add two cells binding support
> > >   clk: imx: scu: bypass cpu power domains
> > >   clk: imx: scu: allow scu clk to take device pointer
> > >   clk: imx: scu: add runtime pm support
> > >   clk: imx: scu: add suspend/resume support
> > >   clk: imx: imx8qxp-lpcg: add parsing clocks from device tree
> > >   clk: imx: lpcg: allow lpcg clk to take device pointer
> > >   clk: imx: clk-imx8qxp-lpcg: add runtime pm support
> > >   clk: imx: lpcg: add suspend/resume support
> > >
> > >  .../bindings/arm/freescale/fsl,scu.txt        |  12 +-
> > >  .../bindings/clock/imx8qxp-lpcg.yaml          |  79 ++++--
> > >  drivers/clk/imx/clk-imx8qxp-lpcg.c            | 139 +++++++++++
> > >  drivers/clk/imx/clk-imx8qxp.c                 | 136 +++++-----
> > >  drivers/clk/imx/clk-lpcg-scu.c                |  53 +++-
> > >  drivers/clk/imx/clk-scu.c                     | 234 +++++++++++++++++-
> > >  drivers/clk/imx/clk-scu.h                     |  56 ++++-
> > >  include/dt-bindings/clock/imx8-lpcg.h         |  14 ++
> > >  8 files changed, 620 insertions(+), 103 deletions(-)
> > >  create mode 100644 include/dt-bindings/clock/imx8-lpcg.h
> > >
> > > --
> > > 2.23.0
> > >

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

end of thread, back to index

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-29  8:00 [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
2020-07-29  8:00 ` [PATCH v7 01/11] dt-bindings: firmware: imx-scu: new binding to parse clocks from device tree Dong Aisheng
2020-07-29  8:00 ` [PATCH v7 02/11] dt-bindings: clock: imx-lpcg: add support " Dong Aisheng
2020-07-29  8:06   ` Dong Aisheng
2020-07-31 21:28   ` Rob Herring
2020-07-29  8:00 ` [PATCH v7 03/11] clk: imx: scu: add two cells binding support Dong Aisheng
2020-07-29  8:00 ` [PATCH v7 04/11] clk: imx: scu: bypass cpu power domains Dong Aisheng
2020-07-29  8:00 ` [PATCH v7 05/11] clk: imx: scu: allow scu clk to take device pointer Dong Aisheng
2020-07-29  8:00 ` [PATCH v7 06/11] clk: imx: scu: add runtime pm support Dong Aisheng
2020-07-29  8:00 ` [PATCH v7 07/11] clk: imx: scu: add suspend/resume support Dong Aisheng
2020-07-29  8:00 ` [PATCH v7 08/11] clk: imx: imx8qxp-lpcg: add parsing clocks from device tree Dong Aisheng
2020-07-29  8:00 ` [PATCH v7 09/11] clk: imx: lpcg: allow lpcg clk to take device pointer Dong Aisheng
2020-07-29  8:00 ` [PATCH v7 10/11] clk: imx: clk-imx8qxp-lpcg: add runtime pm support Dong Aisheng
2020-07-29  8:00 ` [PATCH v7 11/11] clk: imx: lpcg: add suspend/resume support Dong Aisheng
2020-07-29  8:04 ` [PATCH v7 00/11] clk: imx8: add new clock binding for better pm support Dong Aisheng
2020-08-17  7:42   ` Dong Aisheng
2020-09-02  6:35     ` Dong Aisheng

Linux-Clk Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-clk/0 linux-clk/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-clk linux-clk/ https://lore.kernel.org/linux-clk \
		linux-clk@vger.kernel.org
	public-inbox-index linux-clk

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-clk


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git