Merge branches 'clk-renesas', 'clk-rockchip', 'clk-const' and 'clk-simplify' into...
authorStephen Boyd <sboyd@kernel.org>
Thu, 19 Sep 2019 22:31:41 +0000 (15:31 -0700)
committerStephen Boyd <sboyd@kernel.org>
Thu, 19 Sep 2019 22:31:41 +0000 (15:31 -0700)
* clk-renesas:
  clk: renesas: cpg-mssr: Set GENPD_FLAG_ALWAYS_ON for clock domain
  clk: renesas: r9a06g032: Set GENPD_FLAG_ALWAYS_ON for clock domain
  clk: renesas: mstp: Set GENPD_FLAG_ALWAYS_ON for clock domain
  dt-bindings: clk: emev2: Rename bindings documentation file
  clk: renesas: rcar-usb2-clock-sel: Use devm_platform_ioremap_resource() helper

* clk-rockchip:
  clk: rockchip: Add clock controller for the rk3308
  clk: rockchip: Add dt-binding header for rk3308
  dt-bindings: Add bindings for rk3308 clock controller
  clk: rockchip: Fix -Wunused-const-variable in rv1108 clk driver

* clk-const:
  clk: spear: Make structure i2s_sclk_masks constant

* clk-simplify:
  clk/ti: Use kmemdup rather than duplicating its implementation
  clk: fix devm_platform_ioremap_resource.cocci warnings

148 files changed:
Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,ipesys.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt
Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt
Documentation/devicetree/bindings/clock/imx8mn-clock.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,gcc.txt
Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt
Documentation/devicetree/bindings/clock/renesas,emev2-smu.txt [moved from Documentation/devicetree/bindings/clock/emev2-clock.txt with 100% similarity]
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/actions/owl-common.c
drivers/clk/bcm/clk-bcm63xx-gate.c
drivers/clk/clk-aspeed.c
drivers/clk/clk-aspeed.h [new file with mode: 0644]
drivers/clk/clk-ast2600.c [new file with mode: 0644]
drivers/clk/clk-composite.c
drivers/clk/clk-lochnagar.c
drivers/clk/clk-milbeaut.c
drivers/clk/clk-qoriq.c
drivers/clk/clk-si5341.c
drivers/clk/clk.c
drivers/clk/davinci/pll.c
drivers/clk/imx/Kconfig
drivers/clk/imx/Makefile
drivers/clk/imx/clk-imx7ulp.c
drivers/clk/imx/clk-imx8mm.c
drivers/clk/imx/clk-imx8mn.c [new file with mode: 0644]
drivers/clk/imx/clk-imx8mq.c
drivers/clk/imx/clk-imx8qxp-lpcg.c
drivers/clk/imx/clk-pll14xx.c
drivers/clk/imx/clk.c
drivers/clk/imx/clk.h
drivers/clk/ingenic/jz4725b-cgu.c
drivers/clk/ingenic/jz4740-cgu.c
drivers/clk/ingenic/jz4770-cgu.c
drivers/clk/ingenic/jz4780-cgu.c
drivers/clk/mediatek/Kconfig
drivers/clk/mediatek/Makefile
drivers/clk/mediatek/clk-gate.c
drivers/clk/mediatek/clk-gate.h
drivers/clk/mediatek/clk-mt6779-aud.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt6779-cam.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt6779-img.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt6779-ipe.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt6779-mfg.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt6779-mm.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt6779-vdec.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt6779-venc.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt6779.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8183-mfgcfg.c
drivers/clk/mediatek/clk-mt8183.c
drivers/clk/mediatek/clk-mtk.c
drivers/clk/mediatek/clk-mtk.h
drivers/clk/mediatek/reset.c
drivers/clk/meson/Kconfig
drivers/clk/meson/Makefile
drivers/clk/meson/axg-aoclk.c
drivers/clk/meson/axg-audio.c
drivers/clk/meson/axg-audio.h
drivers/clk/meson/axg.c
drivers/clk/meson/clk-cpu-dyndiv.c [new file with mode: 0644]
drivers/clk/meson/clk-cpu-dyndiv.h [new file with mode: 0644]
drivers/clk/meson/clk-input.c [deleted file]
drivers/clk/meson/clk-input.h [deleted file]
drivers/clk/meson/clk-regmap.h
drivers/clk/meson/g12a-aoclk.c
drivers/clk/meson/g12a.c
drivers/clk/meson/g12a.h
drivers/clk/meson/gxbb-aoclk.c
drivers/clk/meson/gxbb.c
drivers/clk/meson/meson-aoclk.c
drivers/clk/meson/meson-aoclk.h
drivers/clk/meson/meson-eeclk.c
drivers/clk/meson/meson-eeclk.h
drivers/clk/meson/meson8b.c
drivers/clk/mvebu/Kconfig
drivers/clk/mvebu/Makefile
drivers/clk/mvebu/ap-cpu-clk.c [new file with mode: 0644]
drivers/clk/mvebu/ap806-system-controller.c
drivers/clk/mvebu/armada_ap_cp_helper.c [new file with mode: 0644]
drivers/clk/mvebu/armada_ap_cp_helper.h [new file with mode: 0644]
drivers/clk/mvebu/cp110-system-controller.c
drivers/clk/qcom/Kconfig
drivers/clk/qcom/Makefile
drivers/clk/qcom/clk-alpha-pll.c
drivers/clk/qcom/clk-alpha-pll.h
drivers/clk/qcom/clk-rcg2.c
drivers/clk/qcom/clk-rpmh.c
drivers/clk/qcom/common.c
drivers/clk/qcom/common.h
drivers/clk/qcom/gcc-ipq8074.c
drivers/clk/qcom/gcc-msm8998.c
drivers/clk/qcom/gcc-qcs404.c
drivers/clk/qcom/gcc-sdm660.c
drivers/clk/qcom/gcc-sdm845.c
drivers/clk/qcom/gcc-sm8150.c [new file with mode: 0644]
drivers/clk/qcom/lpasscc-sdm845.c
drivers/clk/qcom/turingcc-qcs404.c
drivers/clk/renesas/clk-mstp.c
drivers/clk/renesas/r9a06g032-clocks.c
drivers/clk/renesas/rcar-usb2-clock-sel.c
drivers/clk/renesas/renesas-cpg-mssr.c
drivers/clk/sirf/clk-common.c
drivers/clk/socfpga/clk-gate.c
drivers/clk/socfpga/clk-periph-a10.c
drivers/clk/spear/spear1340_clock.c
drivers/clk/sprd/common.c
drivers/clk/st/clk-flexgen.c
drivers/clk/st/clkgen-fsyn.c
drivers/clk/st/clkgen-pll.c
drivers/clk/sunxi-ng/ccu-sun50i-h6.c
drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
drivers/clk/sunxi-ng/ccu-sun8i-v3s.h
drivers/clk/sunxi-ng/ccu_common.c
drivers/clk/ti/apll.c
drivers/clk/ti/clk-814x.c
drivers/clk/ti/dpll.c
drivers/clk/versatile/clk-versatile.c
drivers/clk/zte/clk-zx296718.c
drivers/phy/ti/phy-am654-serdes.c
drivers/rtc/rtc-sun6i.c
include/dt-bindings/clock/ast2600-clock.h [new file with mode: 0644]
include/dt-bindings/clock/g12a-clkc.h
include/dt-bindings/clock/imx8-clock.h
include/dt-bindings/clock/imx8mn-clock.h [new file with mode: 0644]
include/dt-bindings/clock/mt6779-clk.h [new file with mode: 0644]
include/dt-bindings/clock/mt8183-clk.h
include/dt-bindings/clock/qcom,gcc-qcs404.h
include/dt-bindings/clock/qcom,gcc-sm8150.h [new file with mode: 0644]
include/dt-bindings/clock/sun8i-v3s-ccu.h
include/dt-bindings/reset-controller/mt8183-resets.h [new file with mode: 0644]
include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h [new file with mode: 0644]
include/dt-bindings/reset/sun8i-v3s-ccu.h
include/linux/clk-provider.h
include/linux/clk.h
include/linux/clk/clk-conf.h

index 7b8b8eb0191f32a48036758520ec1051f9e53642..26410fbb85befd1b16a7d8bb2684a327c5ea77fa 100644 (file)
@@ -18,17 +18,19 @@ Clocks:
 -------
 
 
-The Device Tree node representing the AP806 system controller provides
-a number of clocks:
+The Device Tree node representing the AP806/AP807 system controller
+provides a number of clocks:
 
- - 0: clock of CPU cluster 0
- - 1: clock of CPU cluster 1
+ - 0: reference clock of CPU cluster 0
+ - 1: reference clock of CPU cluster 1
  - 2: fixed PLL at 1200 Mhz
  - 3: MSS clock, derived from the fixed PLL
 
 Required properties:
 
- - compatible: must be: "marvell,ap806-clock"
+ - compatible: must be one of:
+   * "marvell,ap806-clock"
+   * "marvell,ap807-clock"
  - #clock-cells: must be set to 1
 
 Pinctrl:
@@ -143,3 +145,33 @@ ap_syscon1: system-controller@6f8000 {
                #thermal-sensor-cells = <1>;
        };
 };
+
+Cluster clocks:
+---------------
+
+Device Tree Clock bindings for cluster clock of Marvell
+AP806/AP807. Each cluster contain up to 2 CPUs running at the same
+frequency.
+
+Required properties:
+ - compatible: must be one of:
+   * "marvell,ap806-cpu-clock"
+   * "marvell,ap807-cpu-clock"
+- #clock-cells : should be set to 1.
+
+- clocks : shall be the input parent clock(s) phandle for the clock
+           (one per cluster)
+
+- reg: register range associated with the cluster clocks
+
+ap_syscon1: system-controller@6f8000 {
+       compatible = "marvell,armada-ap806-syscon1", "syscon", "simple-mfd";
+       reg = <0x6f8000 0x1000>;
+
+       cpu_clk: clock-cpu@278 {
+               compatible = "marvell,ap806-cpu-clock";
+               clocks = <&ap_clk 0>, <&ap_clk 1>;
+               #clock-cells = <1>;
+               reg = <0x278 0xa30>;
+       };
+};
index 161e63a6c254d036350a9b41d1e455feaf3baf48..ff000ccade78c4f5787dcc57cf417609dd400bad 100644 (file)
@@ -8,6 +8,7 @@ Required Properties:
 - compatible: Should be one of:
        - "mediatek,mt2701-apmixedsys"
        - "mediatek,mt2712-apmixedsys", "syscon"
+       - "mediatek,mt6779-apmixedsys", "syscon"
        - "mediatek,mt6797-apmixedsys"
        - "mediatek,mt7622-apmixedsys"
        - "mediatek,mt7623-apmixedsys", "mediatek,mt2701-apmixedsys"
index 07c9d813465c9d2a5f14ddf06b1f09efe3d98621..e4ca7b7031236f5dca2de2cd1f62d7e31c14b346 100644 (file)
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: Should be one of:
        - "mediatek,mt2701-audsys", "syscon"
+       - "mediatek,mt6779-audio", "syscon"
        - "mediatek,mt7622-audsys", "syscon"
        - "mediatek,mt7623-audsys", "mediatek,mt2701-audsys", "syscon"
        - "mediatek,mt8183-audiosys", "syscon"
index d8930f64aa985eff2dc9ab020abc18b1d6cfdadb..1f4aaa15a37ecde03b4ef9d94683eea867f3824f 100644 (file)
@@ -6,6 +6,7 @@ The MediaTek camsys controller provides various clocks to the system.
 Required Properties:
 
 - compatible: Should be one of:
+       - "mediatek,mt6779-camsys", "syscon"
        - "mediatek,mt8183-camsys", "syscon"
 - #clock-cells: Must be 1
 
index e3bc4a1e7a6e46b419b3aa68e989c3d104813a17..2b693e343c56d6754ce34c955b64e4137bc27f9e 100644 (file)
@@ -8,6 +8,7 @@ Required Properties:
 - compatible: Should be one of:
        - "mediatek,mt2701-imgsys", "syscon"
        - "mediatek,mt2712-imgsys", "syscon"
+       - "mediatek,mt6779-imgsys", "syscon"
        - "mediatek,mt6797-imgsys", "syscon"
        - "mediatek,mt7623-imgsys", "mediatek,mt2701-imgsys", "syscon"
        - "mediatek,mt8173-imgsys", "syscon"
index a90913988d7ea789c576a1cae08d98d382259c98..db2f4fd754e7d7207748ffe884bb01e270351a31 100644 (file)
@@ -9,6 +9,7 @@ Required Properties:
 - compatible: Should be one of:
        - "mediatek,mt2701-infracfg", "syscon"
        - "mediatek,mt2712-infracfg", "syscon"
+       - "mediatek,mt6779-infracfg_ao", "syscon"
        - "mediatek,mt6797-infracfg", "syscon"
        - "mediatek,mt7622-infracfg", "syscon"
        - "mediatek,mt7623-infracfg", "mediatek,mt2701-infracfg", "syscon"
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ipesys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ipesys.txt
new file mode 100644 (file)
index 0000000..2ce889b
--- /dev/null
@@ -0,0 +1,22 @@
+Mediatek ipesys controller
+============================
+
+The Mediatek ipesys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be one of:
+       - "mediatek,mt6779-ipesys", "syscon"
+- #clock-cells: Must be 1
+
+The ipesys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+ipesys: clock-controller@1b000000 {
+       compatible = "mediatek,mt6779-ipesys", "syscon";
+       reg = <0 0x1b000000 0 0x1000>;
+       #clock-cells = <1>;
+};
index 72787e7dd2274cd620e4f70bf112d2726a87a75d..ad5f9d2f68183d08658fea89fe69dcff4883fa42 100644 (file)
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: Should be one of:
        - "mediatek,mt2712-mfgcfg", "syscon"
+       - "mediatek,mt6779-mfgcfg", "syscon"
        - "mediatek,mt8183-mfgcfg", "syscon"
 - #clock-cells: Must be 1
 
index 545eab717c967459c25188f61286503be603907e..301eefbe161892b91477d3bf971797c4bdf97372 100644 (file)
@@ -8,6 +8,7 @@ Required Properties:
 - compatible: Should be one of:
        - "mediatek,mt2701-mmsys", "syscon"
        - "mediatek,mt2712-mmsys", "syscon"
+       - "mediatek,mt6779-mmsys", "syscon"
        - "mediatek,mt6797-mmsys", "syscon"
        - "mediatek,mt7623-mmsys", "mediatek,mt2701-mmsys", "syscon"
        - "mediatek,mt8173-mmsys", "syscon"
index 4c7e478117a0c79dc7925082587544164bd82ea6..ecf027a9003a86835b086ffb3153c3c9aea4ce27 100644 (file)
@@ -14,6 +14,7 @@ Required Properties:
        - "mediatek,mt7629-pericfg", "syscon"
        - "mediatek,mt8135-pericfg", "syscon"
        - "mediatek,mt8173-pericfg", "syscon"
+       - "mediatek,mt8183-pericfg", "syscon"
 - #clock-cells: Must be 1
 - #reset-cells: Must be 1
 
index a023b8338960f28f8ab8b55afbe53ba43ce5be94..0293d693ce0caa2a950bd9781c8583e4823dc268 100644 (file)
@@ -8,6 +8,7 @@ Required Properties:
 - compatible: Should be one of:
        - "mediatek,mt2701-topckgen"
        - "mediatek,mt2712-topckgen", "syscon"
+       - "mediatek,mt6779-topckgen", "syscon"
        - "mediatek,mt6797-topckgen"
        - "mediatek,mt7622-topckgen"
        - "mediatek,mt7623-topckgen", "mediatek,mt2701-topckgen"
index 57176bb8dbb508087df62791c4eb3873b65242f2..7894558b7a1c36b415faf42b77ae6dac4277fc34 100644 (file)
@@ -8,6 +8,7 @@ Required Properties:
 - compatible: Should be one of:
        - "mediatek,mt2701-vdecsys", "syscon"
        - "mediatek,mt2712-vdecsys", "syscon"
+       - "mediatek,mt6779-vdecsys", "syscon"
        - "mediatek,mt6797-vdecsys", "syscon"
        - "mediatek,mt7623-vdecsys", "mediatek,mt2701-vdecsys", "syscon"
        - "mediatek,mt8173-vdecsys", "syscon"
index c9faa626908769e54fe68c2f93f0c4ad8ccc5746..6a6a14e15cd7ff30fcd516021a47fe15a2f696b4 100644 (file)
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: Should be one of:
        - "mediatek,mt2712-vencsys", "syscon"
+       - "mediatek,mt6779-vencsys", "syscon"
        - "mediatek,mt6797-vencsys", "syscon"
        - "mediatek,mt8173-vencsys", "syscon"
        - "mediatek,mt8183-vencsys", "syscon"
index c935405458fed1304a17fce059371ec8660bcc04..1bde87fc94c55a8ff47d2712f64744be81524aa2 100644 (file)
@@ -31,6 +31,7 @@ properties:
       - allwinner,sun8i-h3-ccu
       - allwinner,sun8i-h3-r-ccu
       - allwinner,sun8i-r40-ccu
+      - allwinner,sun8i-v3-ccu
       - allwinner,sun8i-v3s-ccu
       - allwinner,sun9i-a80-ccu
       - allwinner,sun50i-a64-ccu
index 0f777749f4f1e3b82fceed4788e48bc738adbe3f..b3957d10d241fb434aead20f3e9b3586f0f3d060 100644 (file)
@@ -22,6 +22,7 @@ Required Properties:
                                       components.
 - resets       : phandle of the internal reset line
 - #clock-cells : should be 1.
+- #reset-cells  : should be 1 on the g12a (and following) soc family
 
 Each clock is assigned an identifier and client nodes can use this identifier
 to specify the clock which they consume. All available clocks are defined as
index 6eaa52092313915d5dcb30590f4deee2640a0368..7ccecd5c02c1730fa953631b5e4b8f02250d83e2 100644 (file)
@@ -11,6 +11,7 @@ Required Properties:
                "amlogic,axg-clkc" for AXG SoC.
                "amlogic,g12a-clkc" for G12A SoC.
                "amlogic,g12b-clkc" for G12B SoC.
+               "amlogic,sm1-clkc" for SM1 SoC.
 - clocks : list of clock phandle, one for each entry clock-names.
 - clock-names : should contain the following:
   * "xtal": the platform xtal
diff --git a/Documentation/devicetree/bindings/clock/imx8mn-clock.yaml b/Documentation/devicetree/bindings/clock/imx8mn-clock.yaml
new file mode 100644 (file)
index 0000000..622f365
--- /dev/null
@@ -0,0 +1,112 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/bindings/clock/imx8mn-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX8M Nano Clock Control Module Binding
+
+maintainers:
+  - Anson Huang <Anson.Huang@nxp.com>
+
+description: |
+  NXP i.MX8M Nano clock control module is an integrated clock controller, which
+  generates and supplies to all modules.
+
+properties:
+  compatible:
+    const: fsl,imx8mn-ccm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: 32k osc
+      - description: 24m osc
+      - description: ext1 clock input
+      - description: ext2 clock input
+      - description: ext3 clock input
+      - description: ext4 clock input
+
+  clock-names:
+    items:
+      - const: osc_32k
+      - const: osc_24m
+      - const: clk_ext1
+      - const: clk_ext2
+      - const: clk_ext3
+      - const: clk_ext4
+
+  '#clock-cells':
+    const: 1
+    description: |
+      The clock consumer should specify the desired clock by having the clock
+      ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8mn-clock.h
+      for the full list of i.MX8M Nano clock IDs.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+
+examples:
+  # Clock Control Module node:
+  - |
+    clk: clock-controller@30380000 {
+        compatible = "fsl,imx8mn-ccm";
+        reg = <0x0 0x30380000 0x0 0x10000>;
+        #clock-cells = <1>;
+        clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>,
+                 <&clk_ext2>, <&clk_ext3>, <&clk_ext4>;
+        clock-names = "osc_32k", "osc_24m", "clk_ext1",
+                      "clk_ext2", "clk_ext3", "clk_ext4";
+    };
+
+  # Required external clocks for Clock Control Module node:
+  - |
+    osc_32k: clock-osc-32k {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency = <32768>;
+        clock-output-names = "osc_32k";
+    };
+
+    osc_24m: clock-osc-24m {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency = <24000000>;
+        clock-output-names = "osc_24m";
+    };
+
+    clk_ext1: clock-ext1 {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency = <133000000>;
+        clock-output-names = "clk_ext1";
+    };
+
+    clk_ext2: clock-ext2 {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency = <133000000>;
+        clock-output-names = "clk_ext2";
+    };
+
+    clk_ext3: clock-ext3 {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency = <133000000>;
+        clock-output-names = "clk_ext3";
+    };
+
+    clk_ext4: clock-ext4 {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency= <133000000>;
+        clock-output-names = "clk_ext4";
+    };
+
+...
index 8661c3cd3ccf543931c8ca040d9bd09873905387..d14362ad41323109064e5de27e9c7d295fa8c64e 100644 (file)
@@ -23,6 +23,7 @@ Required properties :
                        "qcom,gcc-sdm630"
                        "qcom,gcc-sdm660"
                        "qcom,gcc-sdm845"
+                       "qcom,gcc-sm8150"
 
 - reg : shall contain base register location and length
 - #clock-cells : shall contain 1
@@ -38,6 +39,13 @@ Documentation/devicetree/bindings/thermal/qcom-tsens.txt
 - protected-clocks : Protected clock specifier list as per common clock
  binding.
 
+For SM8150 only:
+       - clocks: a list of phandles and clock-specifier pairs,
+                 one for each entry in clock-names.
+       - clock-names: "bi_tcxo" (required)
+                      "sleep_clk" (optional)
+                      "aud_ref_clock" (optional)
+
 Example:
        clock-controller@900000 {
                compatible = "qcom,gcc-msm8960";
@@ -71,3 +79,16 @@ Example of GCC with protected-clocks properties:
                                   <GCC_LPASS_Q6_AXI_CLK>,
                                   <GCC_LPASS_SWAY_CLK>;
        };
+
+Example of GCC with clocks
+       gcc: clock-controller@100000 {
+               compatible = "qcom,gcc-sm8150";
+               reg = <0x00100000 0x1f0000>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+               #power-domain-cells = <1>;
+               clock-names = "bi_tcxo",
+                             "sleep_clk";
+               clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
+                        <&sleep_clk>;
+       };
index 3c007653da31249d176eb71384a0817371b7659c..365bbde599b1f3da37e7cd20409cfd18468a1dd8 100644 (file)
@@ -6,9 +6,14 @@ some Qualcomm Technologies Inc. SoCs. It accepts clock requests from
 other hardware subsystems via RSC to control clocks.
 
 Required properties :
-- compatible : shall contain "qcom,sdm845-rpmh-clk"
+- compatible : must be one of:
+              "qcom,sdm845-rpmh-clk"
+              "qcom,sm8150-rpmh-clk"
 
 - #clock-cells : must contain 1
+- clocks: a list of phandles and clock-specifier pairs,
+         one for each entry in clock-names.
+- clock-names: Parent board clock: "xo".
 
 Example :
 
index 801fa1cd03217cb54853fcfddcb49ab7c21a1478..c44247d0b83e8a467d59a21c8f8c1296e0fd1e46 100644 (file)
@@ -116,7 +116,6 @@ config COMMON_CLK_SI514
        depends on OF
        select REGMAP_I2C
        help
-       ---help---
          This driver supports the Silicon Labs 514 programmable clock
          generator.
 
@@ -125,7 +124,6 @@ config COMMON_CLK_SI544
        depends on I2C
        select REGMAP_I2C
        help
-       ---help---
          This driver supports the Silicon Labs 544 programmable clock
          generator.
 
@@ -135,7 +133,6 @@ config COMMON_CLK_SI570
        depends on OF
        select REGMAP_I2C
        help
-       ---help---
          This driver supports Silicon Labs 570/571/598/599 programmable
          clock generators.
 
@@ -153,7 +150,6 @@ config COMMON_CLK_CDCE925
        depends on OF
        select REGMAP_I2C
        help
-       ---help---
          This driver supports the TI CDCE913/925/937/949 programmable clock
          synthesizer. Each chip has different number of PLLs and outputs.
          For example, the CDCE925 contains two PLLs with spread-spectrum
@@ -212,7 +208,6 @@ config COMMON_CLK_AXI_CLKGEN
        tristate "AXI clkgen driver"
        depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST
        help
-       ---help---
          Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx
          FPGAs. It is commonly used in Analog Devices' reference designs.
 
@@ -279,26 +274,22 @@ config COMMON_CLK_VC5
        depends on OF
        select REGMAP_I2C
        help
-       ---help---
          This driver supports the IDT VersaClock 5 and VersaClock 6
          programmable clock generators.
 
 config COMMON_CLK_STM32MP157
        def_bool COMMON_CLK && MACH_STM32MP157
        help
-       ---help---
          Support for stm32mp157 SoC family clocks
 
 config COMMON_CLK_STM32F
        def_bool COMMON_CLK && (MACH_STM32F429 || MACH_STM32F469 || MACH_STM32F746)
        help
-       ---help---
          Support for stm32f4 and stm32f7 SoC families clocks
 
 config COMMON_CLK_STM32H7
        def_bool COMMON_CLK && MACH_STM32H743
        help
-       ---help---
          Support for stm32h7 SoC family clocks
 
 config COMMON_CLK_BD718XX
index 0cad76021297f4b246907b941bdabf95b637a7e2..0138fb14e6f883bd641230e8d1c4315f5b7b1eff 100644 (file)
@@ -30,6 +30,7 @@ obj-$(CONFIG_ARCH_EFM32)              += clk-efm32gg.o
 obj-$(CONFIG_COMMON_CLK_FIXED_MMIO)    += clk-fixed-mmio.o
 obj-$(CONFIG_COMMON_CLK_GEMINI)                += clk-gemini.o
 obj-$(CONFIG_COMMON_CLK_ASPEED)                += clk-aspeed.o
+obj-$(CONFIG_MACH_ASPEED_G6)           += clk-ast2600.o
 obj-$(CONFIG_ARCH_HIGHBANK)            += clk-highbank.o
 obj-$(CONFIG_CLK_HSDK)                 += clk-hsdk-pll.o
 obj-$(CONFIG_COMMON_CLK_LOCHNAGAR)     += clk-lochnagar.o
index 32dd29e0a37e18ea2e160816e618fe58403db097..4de97cc7cb54d5a7199233bfd36cf3688b29ee12 100644 (file)
@@ -68,16 +68,17 @@ int owl_clk_probe(struct device *dev, struct clk_hw_onecell_data *hw_clks)
        struct clk_hw *hw;
 
        for (i = 0; i < hw_clks->num; i++) {
+               const char *name;
 
                hw = hw_clks->hws[i];
-
                if (IS_ERR_OR_NULL(hw))
                        continue;
 
+               name = hw->init->name;
                ret = devm_clk_hw_register(dev, hw);
                if (ret) {
                        dev_err(dev, "Couldn't register clock %d - %s\n",
-                               i, hw->init->name);
+                               i, name);
                        return ret;
                }
        }
index 9e1dcd43258c604e26b3cda0552e7a64d05ec824..98e884957db871a867422f9cadae90603cb8926c 100644 (file)
@@ -146,7 +146,6 @@ static int clk_bcm63xx_probe(struct platform_device *pdev)
 {
        const struct clk_bcm63xx_table_entry *entry, *table;
        struct clk_bcm63xx_hw *hw;
-       struct resource *r;
        u8 maxbit = 0;
        int i, ret;
 
@@ -170,8 +169,7 @@ static int clk_bcm63xx_probe(struct platform_device *pdev)
        for (i = 0; i < maxbit; i++)
                hw->data.hws[i] = ERR_PTR(-ENODEV);
 
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       hw->regs = devm_ioremap_resource(&pdev->dev, r);
+       hw->regs = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(hw->regs))
                return PTR_ERR(hw->regs);
 
index 42b4df6ba249f2ec3b7382cfb2a732358473affb..abf06fb6453e31d82f05a049cf325e605ca3a6a4 100644 (file)
@@ -1,19 +1,19 @@
 // SPDX-License-Identifier: GPL-2.0+
+// Copyright IBM Corp
 
 #define pr_fmt(fmt) "clk-aspeed: " fmt
 
-#include <linux/clk-provider.h>
 #include <linux/mfd/syscon.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
-#include <linux/reset-controller.h>
 #include <linux/slab.h>
-#include <linux/spinlock.h>
 
 #include <dt-bindings/clock/aspeed-clock.h>
 
+#include "clk-aspeed.h"
+
 #define ASPEED_NUM_CLKS                36
 
 #define ASPEED_RESET2_OFFSET   32
@@ -42,48 +42,6 @@ static struct clk_hw_onecell_data *aspeed_clk_data;
 
 static void __iomem *scu_base;
 
-/**
- * struct aspeed_gate_data - Aspeed gated clocks
- * @clock_idx: bit used to gate this clock in the clock register
- * @reset_idx: bit used to reset this IP in the reset register. -1 if no
- *             reset is required when enabling the clock
- * @name: the clock name
- * @parent_name: the name of the parent clock
- * @flags: standard clock framework flags
- */
-struct aspeed_gate_data {
-       u8              clock_idx;
-       s8              reset_idx;
-       const char      *name;
-       const char      *parent_name;
-       unsigned long   flags;
-};
-
-/**
- * struct aspeed_clk_gate - Aspeed specific clk_gate structure
- * @hw:                handle between common and hardware-specific interfaces
- * @reg:       register controlling gate
- * @clock_idx: bit used to gate this clock in the clock register
- * @reset_idx: bit used to reset this IP in the reset register. -1 if no
- *             reset is required when enabling the clock
- * @flags:     hardware-specific flags
- * @lock:      register lock
- *
- * Some of the clocks in the Aspeed SoC must be put in reset before enabling.
- * This modified version of clk_gate allows an optional reset bit to be
- * specified.
- */
-struct aspeed_clk_gate {
-       struct clk_hw   hw;
-       struct regmap   *map;
-       u8              clock_idx;
-       s8              reset_idx;
-       u8              flags;
-       spinlock_t      *lock;
-};
-
-#define to_aspeed_clk_gate(_hw) container_of(_hw, struct aspeed_clk_gate, hw)
-
 /* TODO: ask Aspeed about the actual parent data */
 static const struct aspeed_gate_data aspeed_gates[] = {
        /*                               clk rst   name                 parent  flags */
@@ -208,13 +166,6 @@ static struct clk_hw *aspeed_ast2500_calc_pll(const char *name, u32 val)
                        mult, div);
 }
 
-struct aspeed_clk_soc_data {
-       const struct clk_div_table *div_table;
-       const struct clk_div_table *eclk_div_table;
-       const struct clk_div_table *mac_div_table;
-       struct clk_hw *(*calc_pll)(const char *name, u32 val);
-};
-
 static const struct aspeed_clk_soc_data ast2500_data = {
        .div_table = ast2500_div_table,
        .eclk_div_table = ast2500_eclk_div_table,
@@ -315,18 +266,6 @@ static const struct clk_ops aspeed_clk_gate_ops = {
        .is_enabled = aspeed_clk_is_enabled,
 };
 
-/**
- * struct aspeed_reset - Aspeed reset controller
- * @map: regmap to access the containing system controller
- * @rcdev: reset controller device
- */
-struct aspeed_reset {
-       struct regmap                   *map;
-       struct reset_controller_dev     rcdev;
-};
-
-#define to_aspeed_reset(p) container_of((p), struct aspeed_reset, rcdev)
-
 static const u8 aspeed_resets[] = {
        /* SCU04 resets */
        [ASPEED_RESET_XDMA]     = 25,
@@ -500,9 +439,14 @@ static int aspeed_clk_probe(struct platform_device *pdev)
                return PTR_ERR(hw);
        aspeed_clk_data->hws[ASPEED_CLK_MPLL] = hw;
 
-       /* SD/SDIO clock divider (TODO: There's a gate too) */
-       hw = clk_hw_register_divider_table(dev, "sdio", "hpll", 0,
-                       scu_base + ASPEED_CLK_SELECTION, 12, 3, 0,
+       /* SD/SDIO clock divider and gate */
+       hw = clk_hw_register_gate(dev, "sd_extclk_gate", "hpll", 0,
+                                 scu_base + ASPEED_CLK_SELECTION, 15, 0,
+                                 &aspeed_clk_lock);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       hw = clk_hw_register_divider_table(dev, "sd_extclk", "sd_extclk_gate",
+                       0, scu_base + ASPEED_CLK_SELECTION, 12, 3, 0,
                        soc_data->div_table,
                        &aspeed_clk_lock);
        if (IS_ERR(hw))
diff --git a/drivers/clk/clk-aspeed.h b/drivers/clk/clk-aspeed.h
new file mode 100644 (file)
index 0000000..5296b15
--- /dev/null
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Structures used by ASPEED clock drivers
+ *
+ * Copyright 2019 IBM Corp.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/kernel.h>
+#include <linux/reset-controller.h>
+#include <linux/spinlock.h>
+
+struct clk_div_table;
+struct regmap;
+
+/**
+ * struct aspeed_gate_data - Aspeed gated clocks
+ * @clock_idx: bit used to gate this clock in the clock register
+ * @reset_idx: bit used to reset this IP in the reset register. -1 if no
+ *             reset is required when enabling the clock
+ * @name: the clock name
+ * @parent_name: the name of the parent clock
+ * @flags: standard clock framework flags
+ */
+struct aspeed_gate_data {
+       u8              clock_idx;
+       s8              reset_idx;
+       const char      *name;
+       const char      *parent_name;
+       unsigned long   flags;
+};
+
+/**
+ * struct aspeed_clk_gate - Aspeed specific clk_gate structure
+ * @hw:                handle between common and hardware-specific interfaces
+ * @reg:       register controlling gate
+ * @clock_idx: bit used to gate this clock in the clock register
+ * @reset_idx: bit used to reset this IP in the reset register. -1 if no
+ *             reset is required when enabling the clock
+ * @flags:     hardware-specific flags
+ * @lock:      register lock
+ *
+ * Some of the clocks in the Aspeed SoC must be put in reset before enabling.
+ * This modified version of clk_gate allows an optional reset bit to be
+ * specified.
+ */
+struct aspeed_clk_gate {
+       struct clk_hw   hw;
+       struct regmap   *map;
+       u8              clock_idx;
+       s8              reset_idx;
+       u8              flags;
+       spinlock_t      *lock;
+};
+
+#define to_aspeed_clk_gate(_hw) container_of(_hw, struct aspeed_clk_gate, hw)
+
+/**
+ * struct aspeed_reset - Aspeed reset controller
+ * @map: regmap to access the containing system controller
+ * @rcdev: reset controller device
+ */
+struct aspeed_reset {
+       struct regmap                   *map;
+       struct reset_controller_dev     rcdev;
+};
+
+#define to_aspeed_reset(p) container_of((p), struct aspeed_reset, rcdev)
+
+/**
+ * struct aspeed_clk_soc_data - Aspeed SoC specific divisor information
+ * @div_table: Common divider lookup table
+ * @eclk_div_table: Divider lookup table for ECLK
+ * @mac_div_table: Divider lookup table for MAC (Ethernet) clocks
+ * @calc_pll: Callback to maculate common PLL settings
+ */
+struct aspeed_clk_soc_data {
+       const struct clk_div_table *div_table;
+       const struct clk_div_table *eclk_div_table;
+       const struct clk_div_table *mac_div_table;
+       struct clk_hw *(*calc_pll)(const char *name, u32 val);
+};
diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c
new file mode 100644 (file)
index 0000000..1c1bb39
--- /dev/null
@@ -0,0 +1,704 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Copyright IBM Corp
+// Copyright ASPEED Technology
+
+#define pr_fmt(fmt) "clk-ast2600: " fmt
+
+#include <linux/mfd/syscon.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/clock/ast2600-clock.h>
+
+#include "clk-aspeed.h"
+
+#define ASPEED_G6_NUM_CLKS             67
+
+#define ASPEED_G6_SILICON_REV          0x004
+
+#define ASPEED_G6_RESET_CTRL           0x040
+#define ASPEED_G6_RESET_CTRL2          0x050
+
+#define ASPEED_G6_CLK_STOP_CTRL                0x080
+#define ASPEED_G6_CLK_STOP_CTRL2       0x090
+
+#define ASPEED_G6_MISC_CTRL            0x0C0
+#define  UART_DIV13_EN                 BIT(12)
+
+#define ASPEED_G6_CLK_SELECTION1       0x300
+#define ASPEED_G6_CLK_SELECTION2       0x304
+#define ASPEED_G6_CLK_SELECTION4       0x310
+
+#define ASPEED_HPLL_PARAM              0x200
+#define ASPEED_APLL_PARAM              0x210
+#define ASPEED_MPLL_PARAM              0x220
+#define ASPEED_EPLL_PARAM              0x240
+#define ASPEED_DPLL_PARAM              0x260
+
+#define ASPEED_G6_STRAP1               0x500
+
+/* Globally visible clocks */
+static DEFINE_SPINLOCK(aspeed_g6_clk_lock);
+
+/* Keeps track of all clocks */
+static struct clk_hw_onecell_data *aspeed_g6_clk_data;
+
+static void __iomem *scu_g6_base;
+
+/*
+ * Clocks marked with CLK_IS_CRITICAL:
+ *
+ *  ref0 and ref1 are essential for the SoC to operate
+ *  mpll is required if SDRAM is used
+ */
+static const struct aspeed_gate_data aspeed_g6_gates[] = {
+       /*                                  clk rst  name               parent   flags */
+       [ASPEED_CLK_GATE_MCLK]          = {  0, -1, "mclk-gate",        "mpll",  CLK_IS_CRITICAL }, /* SDRAM */
+       [ASPEED_CLK_GATE_ECLK]          = {  1, -1, "eclk-gate",        "eclk",  0 },   /* Video Engine */
+       [ASPEED_CLK_GATE_GCLK]          = {  2,  7, "gclk-gate",        NULL,    0 },   /* 2D engine */
+       /* vclk parent - dclk/d1clk/hclk/mclk */
+       [ASPEED_CLK_GATE_VCLK]          = {  3,  6, "vclk-gate",        NULL,    0 },   /* Video Capture */
+       [ASPEED_CLK_GATE_BCLK]          = {  4,  8, "bclk-gate",        "bclk",  0 }, /* PCIe/PCI */
+       /* From dpll */
+       [ASPEED_CLK_GATE_DCLK]          = {  5, -1, "dclk-gate",        NULL,    CLK_IS_CRITICAL }, /* DAC */
+       [ASPEED_CLK_GATE_REF0CLK]       = {  6, -1, "ref0clk-gate",     "clkin", CLK_IS_CRITICAL },
+       [ASPEED_CLK_GATE_USBPORT2CLK]   = {  7,  3, "usb-port2-gate",   NULL,    0 },   /* USB2.0 Host port 2 */
+       /* Reserved 8 */
+       [ASPEED_CLK_GATE_USBUHCICLK]    = {  9, 15, "usb-uhci-gate",    NULL,    0 },   /* USB1.1 (requires port 2 enabled) */
+       /* From dpll/epll/40mhz usb p1 phy/gpioc6/dp phy pll */
+       [ASPEED_CLK_GATE_D1CLK]         = { 10, 13, "d1clk-gate",       "d1clk", 0 },   /* GFX CRT */
+       /* Reserved 11/12 */
+       [ASPEED_CLK_GATE_YCLK]          = { 13,  4, "yclk-gate",        NULL,    0 },   /* HAC */
+       [ASPEED_CLK_GATE_USBPORT1CLK]   = { 14, 14, "usb-port1-gate",   NULL,    0 },   /* USB2 hub/USB2 host port 1/USB1.1 dev */
+       [ASPEED_CLK_GATE_UART5CLK]      = { 15, -1, "uart5clk-gate",    "uart",  0 },   /* UART5 */
+       /* Reserved 16/19 */
+       [ASPEED_CLK_GATE_MAC1CLK]       = { 20, 11, "mac1clk-gate",     "mac12", 0 },   /* MAC1 */
+       [ASPEED_CLK_GATE_MAC2CLK]       = { 21, 12, "mac2clk-gate",     "mac12", 0 },   /* MAC2 */
+       /* Reserved 22/23 */
+       [ASPEED_CLK_GATE_RSACLK]        = { 24,  4, "rsaclk-gate",      NULL,    0 },   /* HAC */
+       [ASPEED_CLK_GATE_RVASCLK]       = { 25,  9, "rvasclk-gate",     NULL,    0 },   /* RVAS */
+       /* Reserved 26 */
+       [ASPEED_CLK_GATE_EMMCCLK]       = { 27, 16, "emmcclk-gate",     NULL,    0 },   /* For card clk */
+       /* Reserved 28/29/30 */
+       [ASPEED_CLK_GATE_LCLK]          = { 32, 32, "lclk-gate",        NULL,    0 }, /* LPC */
+       [ASPEED_CLK_GATE_ESPICLK]       = { 33, -1, "espiclk-gate",     NULL,    0 }, /* eSPI */
+       [ASPEED_CLK_GATE_REF1CLK]       = { 34, -1, "ref1clk-gate",     "clkin", CLK_IS_CRITICAL },
+       /* Reserved 35 */
+       [ASPEED_CLK_GATE_SDCLK]         = { 36, 56, "sdclk-gate",       NULL,    0 },   /* SDIO/SD */
+       [ASPEED_CLK_GATE_LHCCLK]        = { 37, -1, "lhclk-gate",       "lhclk", 0 },   /* LPC master/LPC+ */
+       /* Reserved 38 RSA: no longer used */
+       /* Reserved 39 */
+       [ASPEED_CLK_GATE_I3C0CLK]       = { 40,  40, "i3c0clk-gate",    NULL,    0 },   /* I3C0 */
+       [ASPEED_CLK_GATE_I3C1CLK]       = { 41,  41, "i3c1clk-gate",    NULL,    0 },   /* I3C1 */
+       [ASPEED_CLK_GATE_I3C2CLK]       = { 42,  42, "i3c2clk-gate",    NULL,    0 },   /* I3C2 */
+       [ASPEED_CLK_GATE_I3C3CLK]       = { 43,  43, "i3c3clk-gate",    NULL,    0 },   /* I3C3 */
+       [ASPEED_CLK_GATE_I3C4CLK]       = { 44,  44, "i3c4clk-gate",    NULL,    0 },   /* I3C4 */
+       [ASPEED_CLK_GATE_I3C5CLK]       = { 45,  45, "i3c5clk-gate",    NULL,    0 },   /* I3C5 */
+       [ASPEED_CLK_GATE_I3C6CLK]       = { 46,  46, "i3c6clk-gate",    NULL,    0 },   /* I3C6 */
+       [ASPEED_CLK_GATE_I3C7CLK]       = { 47,  47, "i3c7clk-gate",    NULL,    0 },   /* I3C7 */
+       [ASPEED_CLK_GATE_UART1CLK]      = { 48,  -1, "uart1clk-gate",   "uart",  0 },   /* UART1 */
+       [ASPEED_CLK_GATE_UART2CLK]      = { 49,  -1, "uart2clk-gate",   "uart",  0 },   /* UART2 */
+       [ASPEED_CLK_GATE_UART3CLK]      = { 50,  -1, "uart3clk-gate",   "uart",  0 },   /* UART3 */
+       [ASPEED_CLK_GATE_UART4CLK]      = { 51,  -1, "uart4clk-gate",   "uart",  0 },   /* UART4 */
+       [ASPEED_CLK_GATE_MAC3CLK]       = { 52,  52, "mac3clk-gate",    "mac34", 0 },   /* MAC3 */
+       [ASPEED_CLK_GATE_MAC4CLK]       = { 53,  53, "mac4clk-gate",    "mac34", 0 },   /* MAC4 */
+       [ASPEED_CLK_GATE_UART6CLK]      = { 54,  -1, "uart6clk-gate",   "uartx", 0 },   /* UART6 */
+       [ASPEED_CLK_GATE_UART7CLK]      = { 55,  -1, "uart7clk-gate",   "uartx", 0 },   /* UART7 */
+       [ASPEED_CLK_GATE_UART8CLK]      = { 56,  -1, "uart8clk-gate",   "uartx", 0 },   /* UART8 */
+       [ASPEED_CLK_GATE_UART9CLK]      = { 57,  -1, "uart9clk-gate",   "uartx", 0 },   /* UART9 */
+       [ASPEED_CLK_GATE_UART10CLK]     = { 58,  -1, "uart10clk-gate",  "uartx", 0 },   /* UART10 */
+       [ASPEED_CLK_GATE_UART11CLK]     = { 59,  -1, "uart11clk-gate",  "uartx", 0 },   /* UART11 */
+       [ASPEED_CLK_GATE_UART12CLK]     = { 60,  -1, "uart12clk-gate",  "uartx", 0 },   /* UART12 */
+       [ASPEED_CLK_GATE_UART13CLK]     = { 61,  -1, "uart13clk-gate",  "uartx", 0 },   /* UART13 */
+       [ASPEED_CLK_GATE_FSICLK]        = { 62,  59, "fsiclk-gate",     NULL,    0 },   /* FSI */
+};
+
+static const char * const eclk_parent_names[] = { "mpll", "hpll", "dpll" };
+
+static const struct clk_div_table ast2600_eclk_div_table[] = {
+       { 0x0, 2 },
+       { 0x1, 2 },
+       { 0x2, 3 },
+       { 0x3, 4 },
+       { 0x4, 5 },
+       { 0x5, 6 },
+       { 0x6, 7 },
+       { 0x7, 8 },
+       { 0 }
+};
+
+static const struct clk_div_table ast2600_mac_div_table[] = {
+       { 0x0, 4 },
+       { 0x1, 4 },
+       { 0x2, 6 },
+       { 0x3, 8 },
+       { 0x4, 10 },
+       { 0x5, 12 },
+       { 0x6, 14 },
+       { 0x7, 16 },
+       { 0 }
+};
+
+static const struct clk_div_table ast2600_div_table[] = {
+       { 0x0, 4 },
+       { 0x1, 8 },
+       { 0x2, 12 },
+       { 0x3, 16 },
+       { 0x4, 20 },
+       { 0x5, 24 },
+       { 0x6, 28 },
+       { 0x7, 32 },
+       { 0 }
+};
+
+/* For hpll/dpll/epll/mpll */
+static struct clk_hw *ast2600_calc_pll(const char *name, u32 val)
+{
+       unsigned int mult, div;
+
+       if (val & BIT(24)) {
+               /* Pass through mode */
+               mult = div = 1;
+       } else {
+               /* F = 25Mhz * [(M + 2) / (n + 1)] / (p + 1) */
+               u32 m = val  & 0x1fff;
+               u32 n = (val >> 13) & 0x3f;
+               u32 p = (val >> 19) & 0xf;
+               mult = (m + 1) / (n + 1);
+               div = (p + 1);
+       }
+       return clk_hw_register_fixed_factor(NULL, name, "clkin", 0,
+                       mult, div);
+};
+
+static struct clk_hw *ast2600_calc_apll(const char *name, u32 val)
+{
+       unsigned int mult, div;
+
+       if (val & BIT(20)) {
+               /* Pass through mode */
+               mult = div = 1;
+       } else {
+               /* F = 25Mhz * (2-od) * [(m + 2) / (n + 1)] */
+               u32 m = (val >> 5) & 0x3f;
+               u32 od = (val >> 4) & 0x1;
+               u32 n = val & 0xf;
+
+               mult = (2 - od) * (m + 2);
+               div = n + 1;
+       }
+       return clk_hw_register_fixed_factor(NULL, name, "clkin", 0,
+                       mult, div);
+};
+
+static u32 get_bit(u8 idx)
+{
+       return BIT(idx % 32);
+}
+
+static u32 get_reset_reg(struct aspeed_clk_gate *gate)
+{
+       if (gate->reset_idx < 32)
+               return ASPEED_G6_RESET_CTRL;
+
+       return ASPEED_G6_RESET_CTRL2;
+}
+
+static u32 get_clock_reg(struct aspeed_clk_gate *gate)
+{
+       if (gate->clock_idx < 32)
+               return ASPEED_G6_CLK_STOP_CTRL;
+
+       return ASPEED_G6_CLK_STOP_CTRL2;
+}
+
+static int aspeed_g6_clk_is_enabled(struct clk_hw *hw)
+{
+       struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
+       u32 clk = get_bit(gate->clock_idx);
+       u32 rst = get_bit(gate->reset_idx);
+       u32 reg;
+       u32 enval;
+
+       /*
+        * If the IP is in reset, treat the clock as not enabled,
+        * this happens with some clocks such as the USB one when
+        * coming from cold reset. Without this, aspeed_clk_enable()
+        * will fail to lift the reset.
+        */
+       if (gate->reset_idx >= 0) {
+               regmap_read(gate->map, get_reset_reg(gate), &reg);
+
+               if (reg & rst)
+                       return 0;
+       }
+
+       regmap_read(gate->map, get_clock_reg(gate), &reg);
+
+       enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : clk;
+
+       return ((reg & clk) == enval) ? 1 : 0;
+}
+
+static int aspeed_g6_clk_enable(struct clk_hw *hw)
+{
+       struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
+       unsigned long flags;
+       u32 clk = get_bit(gate->clock_idx);
+       u32 rst = get_bit(gate->reset_idx);
+
+       spin_lock_irqsave(gate->lock, flags);
+
+       if (aspeed_g6_clk_is_enabled(hw)) {
+               spin_unlock_irqrestore(gate->lock, flags);
+               return 0;
+       }
+
+       if (gate->reset_idx >= 0) {
+               /* Put IP in reset */
+               regmap_write(gate->map, get_reset_reg(gate), rst);
+               /* Delay 100us */
+               udelay(100);
+       }
+
+       /* Enable clock */
+       if (gate->flags & CLK_GATE_SET_TO_DISABLE) {
+               regmap_write(gate->map, get_clock_reg(gate), clk);
+       } else {
+               /* Use set to clear register */
+               regmap_write(gate->map, get_clock_reg(gate) + 0x04, clk);
+       }
+
+       if (gate->reset_idx >= 0) {
+               /* A delay of 10ms is specified by the ASPEED docs */
+               mdelay(10);
+               /* Take IP out of reset */
+               regmap_write(gate->map, get_reset_reg(gate) + 0x4, rst);
+       }
+
+       spin_unlock_irqrestore(gate->lock, flags);
+
+       return 0;
+}
+
+static void aspeed_g6_clk_disable(struct clk_hw *hw)
+{
+       struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
+       unsigned long flags;
+       u32 clk = get_bit(gate->clock_idx);
+
+       spin_lock_irqsave(gate->lock, flags);
+
+       if (gate->flags & CLK_GATE_SET_TO_DISABLE) {
+               regmap_write(gate->map, get_clock_reg(gate), clk);
+       } else {
+               /* Use set to clear register */
+               regmap_write(gate->map, get_clock_reg(gate) + 0x4, clk);
+       }
+
+       spin_unlock_irqrestore(gate->lock, flags);
+}
+
+static const struct clk_ops aspeed_g6_clk_gate_ops = {
+       .enable = aspeed_g6_clk_enable,
+       .disable = aspeed_g6_clk_disable,
+       .is_enabled = aspeed_g6_clk_is_enabled,
+};
+
+static int aspeed_g6_reset_deassert(struct reset_controller_dev *rcdev,
+                                   unsigned long id)
+{
+       struct aspeed_reset *ar = to_aspeed_reset(rcdev);
+       u32 rst = get_bit(id);
+       u32 reg = id >= 32 ? ASPEED_G6_RESET_CTRL2 : ASPEED_G6_RESET_CTRL;
+
+       /* Use set to clear register */
+       return regmap_write(ar->map, reg + 0x04, rst);
+}
+
+static int aspeed_g6_reset_assert(struct reset_controller_dev *rcdev,
+                                 unsigned long id)
+{
+       struct aspeed_reset *ar = to_aspeed_reset(rcdev);
+       u32 rst = get_bit(id);
+       u32 reg = id >= 32 ? ASPEED_G6_RESET_CTRL2 : ASPEED_G6_RESET_CTRL;
+
+       return regmap_write(ar->map, reg, rst);
+}
+
+static int aspeed_g6_reset_status(struct reset_controller_dev *rcdev,
+                                 unsigned long id)
+{
+       struct aspeed_reset *ar = to_aspeed_reset(rcdev);
+       int ret;
+       u32 val;
+       u32 rst = get_bit(id);
+       u32 reg = id >= 32 ? ASPEED_G6_RESET_CTRL2 : ASPEED_G6_RESET_CTRL;
+
+       ret = regmap_read(ar->map, reg, &val);
+       if (ret)
+               return ret;
+
+       return !!(val & rst);
+}
+
+static const struct reset_control_ops aspeed_g6_reset_ops = {
+       .assert = aspeed_g6_reset_assert,
+       .deassert = aspeed_g6_reset_deassert,
+       .status = aspeed_g6_reset_status,
+};
+
+static struct clk_hw *aspeed_g6_clk_hw_register_gate(struct device *dev,
+               const char *name, const char *parent_name, unsigned long flags,
+               struct regmap *map, u8 clock_idx, u8 reset_idx,
+               u8 clk_gate_flags, spinlock_t *lock)
+{
+       struct aspeed_clk_gate *gate;
+       struct clk_init_data init;
+       struct clk_hw *hw;
+       int ret;
+
+       gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+       if (!gate)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &aspeed_g6_clk_gate_ops;
+       init.flags = flags;
+       init.parent_names = parent_name ? &parent_name : NULL;
+       init.num_parents = parent_name ? 1 : 0;
+
+       gate->map = map;
+       gate->clock_idx = clock_idx;
+       gate->reset_idx = reset_idx;
+       gate->flags = clk_gate_flags;
+       gate->lock = lock;
+       gate->hw.init = &init;
+
+       hw = &gate->hw;
+       ret = clk_hw_register(dev, hw);
+       if (ret) {
+               kfree(gate);
+               hw = ERR_PTR(ret);
+       }
+
+       return hw;
+}
+
+static const char * const vclk_parent_names[] = {
+       "dpll",
+       "d1pll",
+       "hclk",
+       "mclk",
+};
+
+static const char * const d1clk_parent_names[] = {
+       "dpll",
+       "epll",
+       "usb-phy-40m",
+       "gpioc6_clkin",
+       "dp_phy_pll",
+};
+
+static int aspeed_g6_clk_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct aspeed_reset *ar;
+       struct regmap *map;
+       struct clk_hw *hw;
+       u32 val, rate;
+       int i, ret;
+
+       map = syscon_node_to_regmap(dev->of_node);
+       if (IS_ERR(map)) {
+               dev_err(dev, "no syscon regmap\n");
+               return PTR_ERR(map);
+       }
+
+       ar = devm_kzalloc(dev, sizeof(*ar), GFP_KERNEL);
+       if (!ar)
+               return -ENOMEM;
+
+       ar->map = map;
+
+       ar->rcdev.owner = THIS_MODULE;
+       ar->rcdev.nr_resets = 64;
+       ar->rcdev.ops = &aspeed_g6_reset_ops;
+       ar->rcdev.of_node = dev->of_node;
+
+       ret = devm_reset_controller_register(dev, &ar->rcdev);
+       if (ret) {
+               dev_err(dev, "could not register reset controller\n");
+               return ret;
+       }
+
+       /* UART clock div13 setting */
+       regmap_read(map, ASPEED_G6_MISC_CTRL, &val);
+       if (val & UART_DIV13_EN)
+               rate = 24000000 / 13;
+       else
+               rate = 24000000;
+       hw = clk_hw_register_fixed_rate(dev, "uart", NULL, 0, rate);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_UART] = hw;
+
+       /* UART6~13 clock div13 setting */
+       regmap_read(map, 0x80, &val);
+       if (val & BIT(31))
+               rate = 24000000 / 13;
+       else
+               rate = 24000000;
+       hw = clk_hw_register_fixed_rate(dev, "uartx", NULL, 0, rate);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_UARTX] = hw;
+
+       /* EMMC ext clock divider */
+       hw = clk_hw_register_gate(dev, "emmc_extclk_gate", "hpll", 0,
+                       scu_g6_base + ASPEED_G6_CLK_SELECTION1, 15, 0,
+                       &aspeed_g6_clk_lock);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       hw = clk_hw_register_divider_table(dev, "emmc_extclk", "emmc_extclk_gate", 0,
+                       scu_g6_base + ASPEED_G6_CLK_SELECTION1, 12, 3, 0,
+                       ast2600_div_table,
+                       &aspeed_g6_clk_lock);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_EMMC] = hw;
+
+       /* SD/SDIO clock divider and gate */
+       hw = clk_hw_register_gate(dev, "sd_extclk_gate", "hpll", 0,
+                       scu_g6_base + ASPEED_G6_CLK_SELECTION4, 31, 0,
+                       &aspeed_g6_clk_lock);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       hw = clk_hw_register_divider_table(dev, "sd_extclk", "sd_extclk_gate",
+                       0, scu_g6_base + ASPEED_G6_CLK_SELECTION4, 28, 3, 0,
+                       ast2600_div_table,
+                       &aspeed_g6_clk_lock);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_SDIO] = hw;
+
+       /* MAC1/2 AHB bus clock divider */
+       hw = clk_hw_register_divider_table(dev, "mac12", "hpll", 0,
+                       scu_g6_base + ASPEED_G6_CLK_SELECTION1, 16, 3, 0,
+                       ast2600_mac_div_table,
+                       &aspeed_g6_clk_lock);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_MAC12] = hw;
+
+       /* MAC3/4 AHB bus clock divider */
+       hw = clk_hw_register_divider_table(dev, "mac34", "hpll", 0,
+                       scu_g6_base + 0x310, 24, 3, 0,
+                       ast2600_mac_div_table,
+                       &aspeed_g6_clk_lock);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_MAC34] = hw;
+
+       /* LPC Host (LHCLK) clock divider */
+       hw = clk_hw_register_divider_table(dev, "lhclk", "hpll", 0,
+                       scu_g6_base + ASPEED_G6_CLK_SELECTION1, 20, 3, 0,
+                       ast2600_div_table,
+                       &aspeed_g6_clk_lock);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_LHCLK] = hw;
+
+       /* gfx d1clk : use dp clk */
+       regmap_update_bits(map, ASPEED_G6_CLK_SELECTION1, GENMASK(10, 8), BIT(10));
+       /* SoC Display clock selection */
+       hw = clk_hw_register_mux(dev, "d1clk", d1clk_parent_names,
+                       ARRAY_SIZE(d1clk_parent_names), 0,
+                       scu_g6_base + ASPEED_G6_CLK_SELECTION1, 8, 3, 0,
+                       &aspeed_g6_clk_lock);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_D1CLK] = hw;
+
+       /* d1 clk div 0x308[17:15] x [14:12] - 8,7,6,5,4,3,2,1 */
+       regmap_write(map, 0x308, 0x12000); /* 3x3 = 9 */
+
+       /* P-Bus (BCLK) clock divider */
+       hw = clk_hw_register_divider_table(dev, "bclk", "hpll", 0,
+                       scu_g6_base + ASPEED_G6_CLK_SELECTION1, 20, 3, 0,
+                       ast2600_div_table,
+                       &aspeed_g6_clk_lock);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_BCLK] = hw;
+
+       /* Video Capture clock selection */
+       hw = clk_hw_register_mux(dev, "vclk", vclk_parent_names,
+                       ARRAY_SIZE(vclk_parent_names), 0,
+                       scu_g6_base + ASPEED_G6_CLK_SELECTION2, 12, 3, 0,
+                       &aspeed_g6_clk_lock);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_VCLK] = hw;
+
+       /* Video Engine clock divider */
+       hw = clk_hw_register_divider_table(dev, "eclk", NULL, 0,
+                       scu_g6_base + ASPEED_G6_CLK_SELECTION1, 28, 3, 0,
+                       ast2600_eclk_div_table,
+                       &aspeed_g6_clk_lock);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_ECLK] = hw;
+
+       for (i = 0; i < ARRAY_SIZE(aspeed_g6_gates); i++) {
+               const struct aspeed_gate_data *gd = &aspeed_g6_gates[i];
+               u32 gate_flags;
+
+               /*
+                * Special case: the USB port 1 clock (bit 14) is always
+                * working the opposite way from the other ones.
+                */
+               gate_flags = (gd->clock_idx == 14) ? 0 : CLK_GATE_SET_TO_DISABLE;
+               hw = aspeed_g6_clk_hw_register_gate(dev,
+                               gd->name,
+                               gd->parent_name,
+                               gd->flags,
+                               map,
+                               gd->clock_idx,
+                               gd->reset_idx,
+                               gate_flags,
+                               &aspeed_g6_clk_lock);
+               if (IS_ERR(hw))
+                       return PTR_ERR(hw);
+               aspeed_g6_clk_data->hws[i] = hw;
+       }
+
+       return 0;
+};
+
+static const struct of_device_id aspeed_g6_clk_dt_ids[] = {
+       { .compatible = "aspeed,ast2600-scu" },
+       { }
+};
+
+static struct platform_driver aspeed_g6_clk_driver = {
+       .probe  = aspeed_g6_clk_probe,
+       .driver = {
+               .name = "ast2600-clk",
+               .of_match_table = aspeed_g6_clk_dt_ids,
+               .suppress_bind_attrs = true,
+       },
+};
+builtin_platform_driver(aspeed_g6_clk_driver);
+
+static const u32 ast2600_a0_axi_ahb_div_table[] = {
+       2, 2, 3, 5,
+};
+
+static const u32 ast2600_a1_axi_ahb_div_table[] = {
+       4, 6, 2, 4,
+};
+
+static void __init aspeed_g6_cc(struct regmap *map)
+{
+       struct clk_hw *hw;
+       u32 val, div, chip_id, axi_div, ahb_div;
+
+       clk_hw_register_fixed_rate(NULL, "clkin", NULL, 0, 25000000);
+
+       /*
+        * High-speed PLL clock derived from the crystal. This the CPU clock,
+        * and we assume that it is enabled
+        */
+       regmap_read(map, ASPEED_HPLL_PARAM, &val);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_HPLL] = ast2600_calc_pll("hpll", val);
+
+       regmap_read(map, ASPEED_MPLL_PARAM, &val);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_MPLL] = ast2600_calc_pll("mpll", val);
+
+       regmap_read(map, ASPEED_DPLL_PARAM, &val);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_DPLL] = ast2600_calc_pll("dpll", val);
+
+       regmap_read(map, ASPEED_EPLL_PARAM, &val);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_EPLL] = ast2600_calc_pll("epll", val);
+
+       regmap_read(map, ASPEED_APLL_PARAM, &val);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_APLL] = ast2600_calc_apll("apll", val);
+
+       /* Strap bits 12:11 define the AXI/AHB clock frequency ratio (aka HCLK)*/
+       regmap_read(map, ASPEED_G6_STRAP1, &val);
+       if (val & BIT(16))
+               axi_div = 1;
+       else
+               axi_div = 2;
+
+       regmap_read(map, ASPEED_G6_SILICON_REV, &chip_id);
+       if (chip_id & BIT(16))
+               ahb_div = ast2600_a1_axi_ahb_div_table[(val >> 11) & 0x3];
+       else
+               ahb_div = ast2600_a0_axi_ahb_div_table[(val >> 11) & 0x3];
+
+       hw = clk_hw_register_fixed_factor(NULL, "ahb", "hpll", 0, 1, axi_div * ahb_div);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_AHB] = hw;
+
+       regmap_read(map, ASPEED_G6_CLK_SELECTION1, &val);
+       val = (val >> 23) & 0x7;
+       div = 4 * (val + 1);
+       hw = clk_hw_register_fixed_factor(NULL, "apb1", "hpll", 0, 1, div);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_APB1] = hw;
+
+       regmap_read(map, ASPEED_G6_CLK_SELECTION4, &val);
+       val = (val >> 9) & 0x7;
+       div = 2 * (val + 1);
+       hw = clk_hw_register_fixed_factor(NULL, "apb2", "ahb", 0, 1, div);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_APB2] = hw;
+
+       /* USB 2.0 port1 phy 40MHz clock */
+       hw = clk_hw_register_fixed_rate(NULL, "usb-phy-40m", NULL, 0, 40000000);
+       aspeed_g6_clk_data->hws[ASPEED_CLK_USBPHY_40M] = hw;
+};
+
+static void __init aspeed_g6_cc_init(struct device_node *np)
+{
+       struct regmap *map;
+       int ret;
+       int i;
+
+       scu_g6_base = of_iomap(np, 0);
+       if (!scu_g6_base)
+               return;
+
+       aspeed_g6_clk_data = kzalloc(struct_size(aspeed_g6_clk_data, hws,
+                                     ASPEED_G6_NUM_CLKS), GFP_KERNEL);
+       if (!aspeed_g6_clk_data)
+               return;
+
+       /*
+        * This way all clocks fetched before the platform device probes,
+        * except those we assign here for early use, will be deferred.
+        */
+       for (i = 0; i < ASPEED_G6_NUM_CLKS; i++)
+               aspeed_g6_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER);
+
+       /*
+        * We check that the regmap works on this very first access,
+        * but as this is an MMIO-backed regmap, subsequent regmap
+        * access is not going to fail and we skip error checks from
+        * this point.
+        */
+       map = syscon_node_to_regmap(np);
+       if (IS_ERR(map)) {
+               pr_err("no syscon regmap\n");
+               return;
+       }
+
+       aspeed_g6_cc(map);
+       aspeed_g6_clk_data->num = ASPEED_G6_NUM_CLKS;
+       ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, aspeed_g6_clk_data);
+       if (ret)
+               pr_err("failed to add DT provider: %d\n", ret);
+};
+CLK_OF_DECLARE_DRIVER(aspeed_cc_g6, "aspeed,ast2600-scu", aspeed_g6_cc_init);
index b06038b8f6586034df7385fd478a4a6b8b2d4fc2..4f13a681ddfcdde9812293496998f20f97b42e79 100644 (file)
@@ -3,7 +3,6 @@
  * Copyright (c) 2013 NVIDIA CORPORATION.  All rights reserved.
  */
 
-#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/err.h>
 #include <linux/slab.h>
index fa8c91758b1d7dc88e2f8c2cdd3566b939b0cebe..565bcd0cdde9e907003fc2281bb52f689cbd12b3 100644 (file)
@@ -198,7 +198,7 @@ static u8 lochnagar_clk_get_parent(struct clk_hw *hw)
        if (ret < 0) {
                dev_dbg(priv->dev, "Failed to read parent of %s: %d\n",
                        lclk->name, ret);
-               return hw->init->num_parents;
+               return clk_hw_get_num_parents(hw);
        }
 
        val &= lclk->src_mask;
index 5fc78faf820c0f03632d3d213f7c035044a0e667..80b9d78493bcd40546fb448f075271ab6df34c8f 100644 (file)
@@ -437,7 +437,7 @@ static int m10v_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
                if (readl_poll_timeout(divider->write_valid_reg, val,
                        !val, M10V_UPOLL_RATE, M10V_UTIMEOUT))
                        pr_err("%s:%s couldn't stabilize\n",
-                               __func__, divider->hw.init->name);
+                               __func__, clk_hw_get_name(hw));
        }
 
        if (divider->lock)
index 07f3b252f3e0cb3118582a184d660ea83d4b8ada..bed140f7375f0ff88b047011c8a426f178b9b330 100644 (file)
@@ -686,7 +686,7 @@ static const struct clockgen_chipinfo chipinfo[] = {
                .guts_compat = "fsl,qoriq-device-config-1.0",
                .init_periph = p5020_init_periph,
                .cmux_groups = {
-                       &p2041_cmux_grp1, &p2041_cmux_grp2
+                       &p5020_cmux_grp1, &p5020_cmux_grp2
                },
                .cmux_to_group = {
                        0, 1, -1
index 72424eb7e5f8777549721f5a06325f3924175b66..6e780c2a9e6ba4290cf8bce60936c5a943d4e1e4 100644 (file)
@@ -547,7 +547,6 @@ static int si5341_synth_clk_set_rate(struct clk_hw *hw, unsigned long rate,
        bool is_integer;
 
        n_num = synth->data->freq_vco;
-       n_den = rate;
 
        /* see if there's an integer solution */
        r = do_div(n_num, rate);
index c0990703ce5403c1092bda6d982c56dffd70e6a0..e7300e1094b978b89dd2b8fab832156b2db1b67d 100644 (file)
@@ -593,6 +593,8 @@ static void clk_core_get_boundaries(struct clk_core *core,
 {
        struct clk *clk_user;
 
+       lockdep_assert_held(&prepare_lock);
+
        *min_rate = core->min_rate;
        *max_rate = core->max_rate;
 
@@ -2437,7 +2439,7 @@ static int clk_core_set_parent_nolock(struct clk_core *core,
        if (core->parent == parent)
                return 0;
 
-       /* verify ops for for multi-parent clks */
+       /* verify ops for multi-parent clks */
        if (core->num_parents > 1 && !core->ops->set_parent)
                return -EPERM;
 
@@ -2487,6 +2489,12 @@ runtime_put:
        return ret;
 }
 
+int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *parent)
+{
+       return clk_core_set_parent_nolock(hw->core, parent->core);
+}
+EXPORT_SYMBOL_GPL(clk_hw_set_parent);
+
 /**
  * clk_set_parent - switch the parent of a mux clk
  * @clk: the mux clk whose input we are switching
@@ -2847,9 +2855,6 @@ static struct hlist_head *orphan_list[] = {
 static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
                                 int level)
 {
-       if (!c)
-               return;
-
        seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu %5d %6d\n",
                   level * 3 + 1, "",
                   30 - level * 3, c->name,
@@ -2864,9 +2869,6 @@ static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
 {
        struct clk_core *child;
 
-       if (!c)
-               return;
-
        clk_summary_show_one(s, c, level);
 
        hlist_for_each_entry(child, &c->children, child_node)
@@ -2896,8 +2898,9 @@ DEFINE_SHOW_ATTRIBUTE(clk_summary);
 
 static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
 {
-       if (!c)
-               return;
+       unsigned long min_rate, max_rate;
+
+       clk_core_get_boundaries(c, &min_rate, &max_rate);
 
        /* This should be JSON format, i.e. elements separated with a comma */
        seq_printf(s, "\"%s\": { ", c->name);
@@ -2905,6 +2908,8 @@ static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
        seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
        seq_printf(s, "\"protect_count\": %d,", c->protect_count);
        seq_printf(s, "\"rate\": %lu,", clk_core_get_rate(c));
+       seq_printf(s, "\"min_rate\": %lu,", min_rate);
+       seq_printf(s, "\"max_rate\": %lu,", max_rate);
        seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c));
        seq_printf(s, "\"phase\": %d,", clk_core_get_phase(c));
        seq_printf(s, "\"duty_cycle\": %u",
@@ -2915,9 +2920,6 @@ static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level)
 {
        struct clk_core *child;
 
-       if (!c)
-               return;
-
        clk_dump_one(s, c, level);
 
        hlist_for_each_entry(child, &c->children, child_node) {
@@ -3013,15 +3015,15 @@ static void possible_parent_show(struct seq_file *s, struct clk_core *core,
         */
        parent = clk_core_get_parent_by_index(core, i);
        if (parent)
-               seq_printf(s, "%s", parent->name);
+               seq_puts(s, parent->name);
        else if (core->parents[i].name)
-               seq_printf(s, "%s", core->parents[i].name);
+               seq_puts(s, core->parents[i].name);
        else if (core->parents[i].fw_name)
                seq_printf(s, "<%s>(fw)", core->parents[i].fw_name);
        else if (core->parents[i].index >= 0)
-               seq_printf(s, "%s",
-                          of_clk_get_parent_name(core->of_node,
-                                                 core->parents[i].index));
+               seq_puts(s,
+                        of_clk_get_parent_name(core->of_node,
+                                               core->parents[i].index));
        else
                seq_puts(s, "(missing)");
 
@@ -3064,6 +3066,34 @@ static int clk_duty_cycle_show(struct seq_file *s, void *data)
 }
 DEFINE_SHOW_ATTRIBUTE(clk_duty_cycle);
 
+static int clk_min_rate_show(struct seq_file *s, void *data)
+{
+       struct clk_core *core = s->private;
+       unsigned long min_rate, max_rate;
+
+       clk_prepare_lock();
+       clk_core_get_boundaries(core, &min_rate, &max_rate);
+       clk_prepare_unlock();
+       seq_printf(s, "%lu\n", min_rate);
+
+       return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_min_rate);
+
+static int clk_max_rate_show(struct seq_file *s, void *data)
+{
+       struct clk_core *core = s->private;
+       unsigned long min_rate, max_rate;
+
+       clk_prepare_lock();
+       clk_core_get_boundaries(core, &min_rate, &max_rate);
+       clk_prepare_unlock();
+       seq_printf(s, "%lu\n", max_rate);
+
+       return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(clk_max_rate);
+
 static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
 {
        struct dentry *root;
@@ -3075,6 +3105,8 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
        core->dentry = root;
 
        debugfs_create_ulong("clk_rate", 0444, root, &core->rate);
+       debugfs_create_file("clk_min_rate", 0444, root, core, &clk_min_rate_fops);
+       debugfs_create_file("clk_max_rate", 0444, root, core, &clk_max_rate_fops);
        debugfs_create_ulong("clk_accuracy", 0444, root, &core->accuracy);
        debugfs_create_u32("clk_phase", 0444, root, &core->phase);
        debugfs_create_file("clk_flags", 0444, root, core, &clk_flags_fops);
@@ -3484,9 +3516,9 @@ static int clk_cpy_name(const char **dst_p, const char *src, bool must_exist)
        return 0;
 }
 
-static int clk_core_populate_parent_map(struct clk_core *core)
+static int clk_core_populate_parent_map(struct clk_core *core,
+                                       const struct clk_init_data *init)
 {
-       const struct clk_init_data *init = core->hw->init;
        u8 num_parents = init->num_parents;
        const char * const *parent_names = init->parent_names;
        const struct clk_hw **parent_hws = init->parent_hws;
@@ -3566,6 +3598,14 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
 {
        int ret;
        struct clk_core *core;
+       const struct clk_init_data *init = hw->init;
+
+       /*
+        * The init data is not supposed to be used outside of registration path.
+        * Set it to NULL so that provider drivers can't use it either and so that
+        * we catch use of hw->init early on in the core.
+        */
+       hw->init = NULL;
 
        core = kzalloc(sizeof(*core), GFP_KERNEL);
        if (!core) {
@@ -3573,17 +3613,17 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
                goto fail_out;
        }
 
-       core->name = kstrdup_const(hw->init->name, GFP_KERNEL);
+       core->name = kstrdup_const(init->name, GFP_KERNEL);
        if (!core->name) {
                ret = -ENOMEM;
                goto fail_name;
        }
 
-       if (WARN_ON(!hw->init->ops)) {
+       if (WARN_ON(!init->ops)) {
                ret = -EINVAL;
                goto fail_ops;
        }
-       core->ops = hw->init->ops;
+       core->ops = init->ops;
 
        if (dev && pm_runtime_enabled(dev))
                core->rpm_enabled = true;
@@ -3592,13 +3632,13 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
        if (dev && dev->driver)
                core->owner = dev->driver->owner;
        core->hw = hw;
-       core->flags = hw->init->flags;
-       core->num_parents = hw->init->num_parents;
+       core->flags = init->flags;
+       core->num_parents = init->num_parents;
        core->min_rate = 0;
        core->max_rate = ULONG_MAX;
        hw->core = core;
 
-       ret = clk_core_populate_parent_map(core);
+       ret = clk_core_populate_parent_map(core, init);
        if (ret)
                goto fail_parents;
 
@@ -4316,12 +4356,43 @@ void devm_of_clk_del_provider(struct device *dev)
 }
 EXPORT_SYMBOL(devm_of_clk_del_provider);
 
-/*
- * Beware the return values when np is valid, but no clock provider is found.
- * If name == NULL, the function returns -ENOENT.
- * If name != NULL, the function returns -EINVAL. This is because
- * of_parse_phandle_with_args() is called even if of_property_match_string()
- * returns an error.
+/**
+ * of_parse_clkspec() - Parse a DT clock specifier for a given device node
+ * @np: device node to parse clock specifier from
+ * @index: index of phandle to parse clock out of. If index < 0, @name is used
+ * @name: clock name to find and parse. If name is NULL, the index is used
+ * @out_args: Result of parsing the clock specifier
+ *
+ * Parses a device node's "clocks" and "clock-names" properties to find the
+ * phandle and cells for the index or name that is desired. The resulting clock
+ * specifier is placed into @out_args, or an errno is returned when there's a
+ * parsing error. The @index argument is ignored if @name is non-NULL.
+ *
+ * Example:
+ *
+ * phandle1: clock-controller@1 {
+ *     #clock-cells = <2>;
+ * }
+ *
+ * phandle2: clock-controller@2 {
+ *     #clock-cells = <1>;
+ * }
+ *
+ * clock-consumer@3 {
+ *     clocks = <&phandle1 1 2 &phandle2 3>;
+ *     clock-names = "name1", "name2";
+ * }
+ *
+ * To get a device_node for `clock-controller@2' node you may call this
+ * function a few different ways:
+ *
+ *   of_parse_clkspec(clock-consumer@3, -1, "name2", &args);
+ *   of_parse_clkspec(clock-consumer@3, 1, NULL, &args);
+ *   of_parse_clkspec(clock-consumer@3, 1, "name2", &args);
+ *
+ * Return: 0 upon successfully parsing the clock specifier. Otherwise, -ENOENT
+ * if @name is NULL or -EINVAL if @name is non-NULL and it can't be found in
+ * the "clock-names" property of @np.
  */
 static int of_parse_clkspec(const struct device_node *np, int index,
                            const char *name, struct of_phandle_args *out_args)
index 1c99e992d63882209734a873e149272f58e3d82f..1ac11b6a47a37177c0c3c97d1903066a8c3fa3c6 100644 (file)
@@ -778,12 +778,15 @@ int of_davinci_pll_init(struct device *dev, struct device_node *node,
                int i;
 
                clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
-               if (!clk_data)
+               if (!clk_data) {
+                       of_node_put(child);
                        return -ENOMEM;
+               }
 
                clks = kmalloc_array(n_clks, sizeof(*clks), GFP_KERNEL);
                if (!clks) {
                        kfree(clk_data);
+                       of_node_put(child);
                        return -ENOMEM;
                }
 
index 0eaf418482800d5593586c1cfa290ea1fc07e178..1ac0c7990392d74f7c62726b6bb94f66f56545a3 100644 (file)
@@ -14,6 +14,12 @@ config CLK_IMX8MM
        help
            Build the driver for i.MX8MM CCM Clock Driver
 
+config CLK_IMX8MN
+       bool "IMX8MN CCM Clock Driver"
+       depends on ARCH_MXC && ARM64
+       help
+           Build the driver for i.MX8MN CCM Clock Driver
+
 config CLK_IMX8MQ
        bool "IMX8MQ CCM Clock Driver"
        depends on ARCH_MXC && ARM64
index 05641c64b31740566621a9b0ef7d858430d2b6ee..77a3d714f1d59986395f7e6e694e204a4739a4d3 100644 (file)
@@ -26,6 +26,7 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
        clk-lpcg-scu.o
 
 obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
+obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
 obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
 obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
 
index 42e4667f22fd4805613459ccb5ed09af2f644b13..2022d9bead9152f39a31230fd3a4534ed5f06fb4 100644 (file)
@@ -42,6 +42,19 @@ static const struct clk_div_table ulp_div_table[] = {
        { .val = 7, .div = 64, },
 };
 
+static const int pcc2_uart_clk_ids[] __initconst = {
+       IMX7ULP_CLK_LPUART4,
+       IMX7ULP_CLK_LPUART5,
+};
+
+static const int pcc3_uart_clk_ids[] __initconst = {
+       IMX7ULP_CLK_LPUART6,
+       IMX7ULP_CLK_LPUART7,
+};
+
+static struct clk **pcc2_uart_clks[ARRAY_SIZE(pcc2_uart_clk_ids) + 1] __initdata;
+static struct clk **pcc3_uart_clks[ARRAY_SIZE(pcc3_uart_clk_ids) + 1] __initdata;
+
 static void __init imx7ulp_clk_scg1_init(struct device_node *np)
 {
        struct clk_hw_onecell_data *clk_data;
@@ -135,6 +148,7 @@ static void __init imx7ulp_clk_pcc2_init(struct device_node *np)
        struct clk_hw_onecell_data *clk_data;
        struct clk_hw **clks;
        void __iomem *base;
+       int i;
 
        clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_PCC2_END),
                           GFP_KERNEL);
@@ -173,6 +187,14 @@ static void __init imx7ulp_clk_pcc2_init(struct device_node *np)
        imx_check_clk_hws(clks, clk_data->num);
 
        of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
+
+       for (i = 0; i < ARRAY_SIZE(pcc2_uart_clk_ids); i++) {
+               int index = pcc2_uart_clk_ids[i];
+
+               pcc2_uart_clks[i] = &clks[index]->clk;
+       }
+
+       imx_register_uart_clocks(pcc2_uart_clks);
 }
 CLK_OF_DECLARE(imx7ulp_clk_pcc2, "fsl,imx7ulp-pcc2", imx7ulp_clk_pcc2_init);
 
@@ -181,6 +203,7 @@ static void __init imx7ulp_clk_pcc3_init(struct device_node *np)
        struct clk_hw_onecell_data *clk_data;
        struct clk_hw **clks;
        void __iomem *base;
+       int i;
 
        clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_PCC3_END),
                           GFP_KERNEL);
@@ -218,6 +241,14 @@ static void __init imx7ulp_clk_pcc3_init(struct device_node *np)
        imx_check_clk_hws(clks, clk_data->num);
 
        of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
+
+       for (i = 0; i < ARRAY_SIZE(pcc3_uart_clk_ids); i++) {
+               int index = pcc3_uart_clk_ids[i];
+
+               pcc3_uart_clks[i] = &clks[index]->clk;
+       }
+
+       imx_register_uart_clocks(pcc3_uart_clks);
 }
 CLK_OF_DECLARE(imx7ulp_clk_pcc3, "fsl,imx7ulp-pcc3", imx7ulp_clk_pcc3_init);
 
index 6b8e75df994d387d47af89d7d19449aef72a0a16..067ab876911dd4979dae95746b0389f5bcd3caa8 100644 (file)
@@ -22,27 +22,10 @@ static u32 share_count_sai3;
 static u32 share_count_sai4;
 static u32 share_count_sai5;
 static u32 share_count_sai6;
-static u32 share_count_dcss;
+static u32 share_count_disp;
 static u32 share_count_pdm;
 static u32 share_count_nand;
 
-#define PLL_1416X_RATE(_rate, _m, _p, _s)              \
-       {                                               \
-               .rate   =       (_rate),                \
-               .mdiv   =       (_m),                   \
-               .pdiv   =       (_p),                   \
-               .sdiv   =       (_s),                   \
-       }
-
-#define PLL_1443X_RATE(_rate, _m, _p, _s, _k)          \
-       {                                               \
-               .rate   =       (_rate),                \
-               .mdiv   =       (_m),                   \
-               .pdiv   =       (_p),                   \
-               .sdiv   =       (_s),                   \
-               .kdiv   =       (_k),                   \
-       }
-
 static const struct imx_pll14xx_rate_table imx8mm_pll1416x_tbl[] = {
        PLL_1416X_RATE(1800000000U, 225, 3, 0),
        PLL_1416X_RATE(1600000000U, 200, 3, 0),
@@ -55,8 +38,8 @@ static const struct imx_pll14xx_rate_table imx8mm_pll1416x_tbl[] = {
 };
 
 static const struct imx_pll14xx_rate_table imx8mm_audiopll_tbl[] = {
-       PLL_1443X_RATE(786432000U, 655, 5, 2, 23593),
-       PLL_1443X_RATE(722534400U, 301, 5, 1, 3670),
+       PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
+       PLL_1443X_RATE(361267200U, 361, 3, 3, 17511),
 };
 
 static const struct imx_pll14xx_rate_table imx8mm_videopll_tbl[] = {
@@ -68,43 +51,43 @@ static const struct imx_pll14xx_rate_table imx8mm_drampll_tbl[] = {
        PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
 };
 
-static struct imx_pll14xx_clk imx8mm_audio_pll __initdata = {
+static struct imx_pll14xx_clk imx8mm_audio_pll = {
                .type = PLL_1443X,
                .rate_table = imx8mm_audiopll_tbl,
                .rate_count = ARRAY_SIZE(imx8mm_audiopll_tbl),
 };
 
-static struct imx_pll14xx_clk imx8mm_video_pll __initdata = {
+static struct imx_pll14xx_clk imx8mm_video_pll = {
                .type = PLL_1443X,
                .rate_table = imx8mm_videopll_tbl,
                .rate_count = ARRAY_SIZE(imx8mm_videopll_tbl),
 };
 
-static struct imx_pll14xx_clk imx8mm_dram_pll __initdata = {
+static struct imx_pll14xx_clk imx8mm_dram_pll = {
                .type = PLL_1443X,
                .rate_table = imx8mm_drampll_tbl,
                .rate_count = ARRAY_SIZE(imx8mm_drampll_tbl),
 };
 
-static struct imx_pll14xx_clk imx8mm_arm_pll __initdata = {
+static struct imx_pll14xx_clk imx8mm_arm_pll = {
                .type = PLL_1416X,
                .rate_table = imx8mm_pll1416x_tbl,
                .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
 };
 
-static struct imx_pll14xx_clk imx8mm_gpu_pll __initdata = {
+static struct imx_pll14xx_clk imx8mm_gpu_pll = {
                .type = PLL_1416X,
                .rate_table = imx8mm_pll1416x_tbl,
                .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
 };
 
-static struct imx_pll14xx_clk imx8mm_vpu_pll __initdata = {
+static struct imx_pll14xx_clk imx8mm_vpu_pll = {
                .type = PLL_1416X,
                .rate_table = imx8mm_pll1416x_tbl,
                .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
 };
 
-static struct imx_pll14xx_clk imx8mm_sys_pll __initdata = {
+static struct imx_pll14xx_clk imx8mm_sys_pll = {
                .type = PLL_1416X,
                .rate_table = imx8mm_pll1416x_tbl,
                .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
@@ -192,10 +175,10 @@ static const char *imx8mm_vpu_g1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_8
 static const char *imx8mm_vpu_g2_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
                                           "sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
 
-static const char *imx8mm_disp_dtrc_sels[] = {"osc_24m", "video_pll2_out", "sys_pll1_800m", "sys_pll2_1000m",
+static const char *imx8mm_disp_dtrc_sels[] = {"osc_24m", "dummy", "sys_pll1_800m", "sys_pll2_1000m",
                                              "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
 
-static const char *imx8mm_disp_dc8000_sels[] = {"osc_24m", "video_pll2_out", "sys_pll1_800m", "sys_pll2_1000m",
+static const char *imx8mm_disp_dc8000_sels[] = {"osc_24m", "dummy", "sys_pll1_800m", "sys_pll2_1000m",
                                                "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
 
 static const char *imx8mm_pcie1_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m",
@@ -249,7 +232,7 @@ static const char *imx8mm_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll
 static const char *imx8mm_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out", "sys_pll1_400m",
                                         "audio_pll2_out", "sys_pll3_out", "sys_pll2_250m", "video_pll1_out", };
 
-static const char *imx8mm_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
+static const char *imx8mm_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll2_333m", "sys_pll2_500m",
                                         "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", };
 
 static const char *imx8mm_usdhc1_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
@@ -304,13 +287,13 @@ static const char *imx8mm_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_1
                                         "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
 
 static const char *imx8mm_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
-                                        "sys3_pll2_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
+                                        "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
 
 static const char *imx8mm_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
                                         "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
 
 static const char *imx8mm_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", "sys_pll1_40m",
-                                        "video_pll1_out", "sys_pll1_800m", "audio_pll1_out", "clk_ext1" };
+                                        "video_pll1_out", "sys_pll1_80m", "audio_pll1_out", "clk_ext1" };
 
 static const char *imx8mm_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m", "vpu_pll_out",
                                         "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m", };
@@ -364,7 +347,7 @@ static const char *imx8mm_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_
                                        "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
 
 static const char *imx8mm_vpu_h1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
-                                          "audio_pll2_out", "sys_pll2_125m", "sys_pll3_clk", "audio_pll1_out", };
+                                          "audio_pll2_out", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
 
 static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
 
@@ -374,7 +357,7 @@ static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m",
 static struct clk *clks[IMX8MM_CLK_END];
 static struct clk_onecell_data clk_data;
 
-static struct clk ** const uart_clks[] __initconst = {
+static struct clk ** const uart_clks[] = {
        &clks[IMX8MM_CLK_UART1_ROOT],
        &clks[IMX8MM_CLK_UART2_ROOT],
        &clks[IMX8MM_CLK_UART3_ROOT],
@@ -382,19 +365,20 @@ static struct clk ** const uart_clks[] __initconst = {
        NULL
 };
 
-static int __init imx8mm_clocks_init(struct device_node *ccm_node)
+static int imx8mm_clocks_probe(struct platform_device *pdev)
 {
-       struct device_node *np;
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
        void __iomem *base;
        int ret;
 
        clks[IMX8MM_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
-       clks[IMX8MM_CLK_24M] = of_clk_get_by_name(ccm_node, "osc_24m");
-       clks[IMX8MM_CLK_32K] = of_clk_get_by_name(ccm_node, "osc_32k");
-       clks[IMX8MM_CLK_EXT1] = of_clk_get_by_name(ccm_node, "clk_ext1");
-       clks[IMX8MM_CLK_EXT2] = of_clk_get_by_name(ccm_node, "clk_ext2");
-       clks[IMX8MM_CLK_EXT3] = of_clk_get_by_name(ccm_node, "clk_ext3");
-       clks[IMX8MM_CLK_EXT4] = of_clk_get_by_name(ccm_node, "clk_ext4");
+       clks[IMX8MM_CLK_24M] = of_clk_get_by_name(np, "osc_24m");
+       clks[IMX8MM_CLK_32K] = of_clk_get_by_name(np, "osc_32k");
+       clks[IMX8MM_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1");
+       clks[IMX8MM_CLK_EXT2] = of_clk_get_by_name(np, "clk_ext2");
+       clks[IMX8MM_CLK_EXT3] = of_clk_get_by_name(np, "clk_ext3");
+       clks[IMX8MM_CLK_EXT4] = of_clk_get_by_name(np, "clk_ext4");
 
        np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop");
        base = of_iomap(np, 0);
@@ -424,28 +408,16 @@ static int __init imx8mm_clocks_init(struct device_node *ccm_node)
        clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mm_sys_pll);
 
        /* PLL bypass out */
-       clks[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 4, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 4, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 4, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 4, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MM_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 4, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MM_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 4, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MM_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 4, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MM_SYS_PLL1_BYPASS] = imx_clk_mux_flags("sys_pll1_bypass", base + 0x94, 4, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MM_SYS_PLL2_BYPASS] = imx_clk_mux_flags("sys_pll2_bypass", base + 0x104, 4, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MM_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 4, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
-
-       /* unbypass all the plls */
-       clk_set_parent(clks[IMX8MM_AUDIO_PLL1_BYPASS], clks[IMX8MM_AUDIO_PLL1]);
-       clk_set_parent(clks[IMX8MM_AUDIO_PLL2_BYPASS], clks[IMX8MM_AUDIO_PLL2]);
-       clk_set_parent(clks[IMX8MM_VIDEO_PLL1_BYPASS], clks[IMX8MM_VIDEO_PLL1]);
-       clk_set_parent(clks[IMX8MM_DRAM_PLL_BYPASS], clks[IMX8MM_DRAM_PLL]);
-       clk_set_parent(clks[IMX8MM_GPU_PLL_BYPASS], clks[IMX8MM_GPU_PLL]);
-       clk_set_parent(clks[IMX8MM_VPU_PLL_BYPASS], clks[IMX8MM_VPU_PLL]);
-       clk_set_parent(clks[IMX8MM_ARM_PLL_BYPASS], clks[IMX8MM_ARM_PLL]);
-       clk_set_parent(clks[IMX8MM_SYS_PLL1_BYPASS], clks[IMX8MM_SYS_PLL1]);
-       clk_set_parent(clks[IMX8MM_SYS_PLL2_BYPASS], clks[IMX8MM_SYS_PLL2]);
-       clk_set_parent(clks[IMX8MM_SYS_PLL3_BYPASS], clks[IMX8MM_SYS_PLL3]);
+       clks[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_SYS_PLL1_BYPASS] = imx_clk_mux_flags("sys_pll1_bypass", base + 0x94, 28, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_SYS_PLL2_BYPASS] = imx_clk_mux_flags("sys_pll2_bypass", base + 0x104, 28, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MM_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
 
        /* PLL out gate */
        clks[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
@@ -480,10 +452,10 @@ static int __init imx8mm_clocks_init(struct device_node *ccm_node)
        clks[IMX8MM_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
        clks[IMX8MM_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
 
-       np = ccm_node;
-       base = of_iomap(np, 0);
-       if (WARN_ON(!base))
-               return -ENOMEM;
+       np = dev->of_node;
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (WARN_ON(IS_ERR(base)))
+               return PTR_ERR(base);
 
        /* Core Slice */
        clks[IMX8MM_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels));
@@ -631,7 +603,7 @@ static int __init imx8mm_clocks_init(struct device_node *ccm_node)
        clks[IMX8MM_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
        clks[IMX8MM_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
        clks[IMX8MM_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
-       clks[IMX8MM_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref", base + 0x44d0, 0);
+       clks[IMX8MM_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0);
        clks[IMX8MM_CLK_GPU3D_ROOT] = imx_clk_gate4("gpu3d_root_clk", "gpu3d_div", base + 0x44f0, 0);
        clks[IMX8MM_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
        clks[IMX8MM_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
@@ -644,10 +616,10 @@ static int __init imx8mm_clocks_init(struct device_node *ccm_node)
        clks[IMX8MM_CLK_VPU_G2_ROOT] = imx_clk_gate4("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0);
        clks[IMX8MM_CLK_PDM_ROOT] = imx_clk_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm);
        clks[IMX8MM_CLK_PDM_IPG]  = imx_clk_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
-       clks[IMX8MM_CLK_DISP_ROOT] = imx_clk_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_dcss);
-       clks[IMX8MM_CLK_DISP_AXI_ROOT]  = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss);
-       clks[IMX8MM_CLK_DISP_APB_ROOT]  = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss);
-       clks[IMX8MM_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss);
+       clks[IMX8MM_CLK_DISP_ROOT] = imx_clk_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_disp);
+       clks[IMX8MM_CLK_DISP_AXI_ROOT]  = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp);
+       clks[IMX8MM_CLK_DISP_APB_ROOT]  = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp);
+       clks[IMX8MM_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_disp);
        clks[IMX8MM_CLK_USDHC3_ROOT] = imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0);
        clks[IMX8MM_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
        clks[IMX8MM_CLK_VPU_DEC_ROOT] = imx_clk_gate4("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0);
@@ -675,11 +647,30 @@ static int __init imx8mm_clocks_init(struct device_node *ccm_node)
        ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
        if (ret < 0) {
                pr_err("failed to register clks for i.MX8MM\n");
-               return -EINVAL;
+               goto unregister_clks;
        }
 
        imx_register_uart_clocks(uart_clks);
 
        return 0;
+
+unregister_clks:
+       imx_unregister_clocks(clks, ARRAY_SIZE(clks));
+
+       return ret;
 }
-CLK_OF_DECLARE_DRIVER(imx8mm, "fsl,imx8mm-ccm", imx8mm_clocks_init);
+
+static const struct of_device_id imx8mm_clk_of_match[] = {
+       { .compatible = "fsl,imx8mm-ccm" },
+       { /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, imx8mm_clk_of_match);
+
+static struct platform_driver imx8mm_clk_driver = {
+       .probe = imx8mm_clocks_probe,
+       .driver = {
+               .name = "imx8mm-ccm",
+               .of_match_table = of_match_ptr(imx8mm_clk_of_match),
+       },
+};
+module_platform_driver(imx8mm_clk_driver);
diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
new file mode 100644 (file)
index 0000000..47a4b44
--- /dev/null
@@ -0,0 +1,648 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2018-2019 NXP.
+ */
+
+#include <dt-bindings/clock/imx8mn-clock.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#include "clk.h"
+
+static u32 share_count_sai2;
+static u32 share_count_sai3;
+static u32 share_count_sai5;
+static u32 share_count_sai6;
+static u32 share_count_sai7;
+static u32 share_count_disp;
+static u32 share_count_pdm;
+static u32 share_count_nand;
+
+enum {
+       ARM_PLL,
+       GPU_PLL,
+       VPU_PLL,
+       SYS_PLL1,
+       SYS_PLL2,
+       SYS_PLL3,
+       DRAM_PLL,
+       AUDIO_PLL1,
+       AUDIO_PLL2,
+       VIDEO_PLL2,
+       NR_PLLS,
+};
+
+static const struct imx_pll14xx_rate_table imx8mn_pll1416x_tbl[] = {
+       PLL_1416X_RATE(1800000000U, 225, 3, 0),
+       PLL_1416X_RATE(1600000000U, 200, 3, 0),
+       PLL_1416X_RATE(1500000000U, 375, 3, 1),
+       PLL_1416X_RATE(1400000000U, 350, 3, 1),
+       PLL_1416X_RATE(1200000000U, 300, 3, 1),
+       PLL_1416X_RATE(1000000000U, 250, 3, 1),
+       PLL_1416X_RATE(800000000U,  200, 3, 1),
+       PLL_1416X_RATE(750000000U,  250, 2, 2),
+       PLL_1416X_RATE(700000000U,  350, 3, 2),
+       PLL_1416X_RATE(600000000U,  300, 3, 2),
+};
+
+static const struct imx_pll14xx_rate_table imx8mn_audiopll_tbl[] = {
+       PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),
+       PLL_1443X_RATE(361267200U, 361, 3, 3, 17511),
+};
+
+static const struct imx_pll14xx_rate_table imx8mn_videopll_tbl[] = {
+       PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+       PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
+};
+
+static const struct imx_pll14xx_rate_table imx8mn_drampll_tbl[] = {
+       PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+};
+
+static struct imx_pll14xx_clk imx8mn_audio_pll = {
+               .type = PLL_1443X,
+               .rate_table = imx8mn_audiopll_tbl,
+               .rate_count = ARRAY_SIZE(imx8mn_audiopll_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mn_video_pll = {
+               .type = PLL_1443X,
+               .rate_table = imx8mn_videopll_tbl,
+               .rate_count = ARRAY_SIZE(imx8mn_videopll_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mn_dram_pll = {
+               .type = PLL_1443X,
+               .rate_table = imx8mn_drampll_tbl,
+               .rate_count = ARRAY_SIZE(imx8mn_drampll_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mn_arm_pll = {
+               .type = PLL_1416X,
+               .rate_table = imx8mn_pll1416x_tbl,
+               .rate_count = ARRAY_SIZE(imx8mn_pll1416x_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mn_gpu_pll = {
+               .type = PLL_1416X,
+               .rate_table = imx8mn_pll1416x_tbl,
+               .rate_count = ARRAY_SIZE(imx8mn_pll1416x_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mn_vpu_pll = {
+               .type = PLL_1416X,
+               .rate_table = imx8mn_pll1416x_tbl,
+               .rate_count = ARRAY_SIZE(imx8mn_pll1416x_tbl),
+};
+
+static struct imx_pll14xx_clk imx8mn_sys_pll = {
+               .type = PLL_1416X,
+               .rate_table = imx8mn_pll1416x_tbl,
+               .rate_count = ARRAY_SIZE(imx8mn_pll1416x_tbl),
+};
+
+static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
+static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
+static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
+static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
+static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
+static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
+static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
+static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
+static const char * const sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", };
+static const char * const sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
+static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
+
+static const char * const imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m",
+                                              "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m",
+                                              "audio_pll1_out", "sys_pll3_out", };
+
+static const char * const imx8mn_gpu_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
+                                                   "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                                   "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mn_gpu_shader_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
+                                                     "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                                     "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mn_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m",
+                                                   "sys_pll2_250m", "sys_pll2_1000m", "audio_pll1_out",
+                                                   "video_pll1_out", "sys_pll1_100m",};
+
+static const char * const imx8mn_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
+                                                   "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out",
+                                                   "video_pll1_out", "sys_pll3_out", };
+
+static const char * const imx8mn_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
+                                                     "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out",
+                                                     "sys_pll2_250m", "audio_pll1_out", };
+
+static const char * const imx8mn_disp_axi_sels[] = {"osc_24m", "sys_pll2_1000m", "sys_pll1_800m",
+                                                   "sys_pll3_out", "sys_pll1_40m", "audio_pll2_out",
+                                                   "clk_ext1", "clk_ext4", };
+
+static const char * const imx8mn_disp_apb_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll1_800m",
+                                                   "sys_pll3_out", "sys_pll1_40m", "audio_pll2_out",
+                                                   "clk_ext1", "clk_ext3", };
+
+static const char * const imx8mn_usb_bus_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m",
+                                                  "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
+                                                  "clk_ext4", "audio_pll2_out", };
+
+static const char * const imx8mn_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
+                                                  "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                                  "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mn_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
+                                                  "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                                  "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mn_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out",
+                                              "sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out",
+                                              "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mn_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m",
+                                              "sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out",
+                                              "audio_pll1_out", "video_pll1_out", };
+
+static const char * const imx8mn_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m",
+                                                    "sys_pll2_1000m", "sys_pll2_166m", "sys_pll3_out",
+                                                    "audio_pll1_out", "video_pll1_out", };
+
+static const char * const imx8mn_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m",
+                                                   "sys_pll2_500m", "sys_pll2_1000m", "sys_pll3_out",
+                                                   "audio_pll1_out", "sys_pll1_266m", };
+
+static const char * const imx8mn_dram_apb_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
+                                                   "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+                                                   "sys_pll2_250m", "audio_pll2_out", };
+
+static const char * const imx8mn_disp_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out",
+                                                     "audio_pll1_out", "sys_pll1_800m", "sys_pll2_1000m",
+                                                     "sys_pll3_out", "clk_ext4", };
+
+static const char * const imx8mn_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext3", "clk_ext4", };
+
+static const char * const imx8mn_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext3", "clk_ext4", };
+
+static const char * const imx8mn_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext2", "clk_ext3", };
+
+static const char * const imx8mn_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext3", "clk_ext4", };
+
+static const char * const imx8mn_sai7_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext3", "clk_ext4", };
+
+static const char * const imx8mn_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                                 "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                                 "clk_ext2", "clk_ext3", };
+
+static const char * const imx8mn_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m",
+                                                   "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
+                                                   "video_pll1_out", "clk_ext4", };
+
+static const char * const imx8mn_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
+                                                     "clk_ext1", "clk_ext2", "clk_ext3",
+                                                     "clk_ext4", "video_pll1_out", };
+
+static const char * const imx8mn_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m",
+                                                   "sys_pll2_200m", "sys_pll2_500m", "video_pll1_out",
+                                                   "audio_pll2_out", };
+
+static const char * const imx8mn_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out",
+                                               "sys_pll1_400m", "audio_pll2_out", "sys_pll3_out",
+                                               "sys_pll2_250m", "video_pll1_out", };
+
+static const char * const imx8mn_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll2_333m",
+                                               "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m",
+                                               "sys_pll3_out", "sys_pll1_100m", };
+
+static const char * const imx8mn_usdhc1_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
+                                                 "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
+                                                 "audio_pll2_out", "sys_pll1_100m", };
+
+static const char * const imx8mn_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
+                                                 "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
+                                                 "audio_pll2_out", "sys_pll1_100m", };
+
+static const char * const imx8mn_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+                                               "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+                                               "audio_pll2_out", "sys_pll1_133m", };
+
+static const char * const imx8mn_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+                                               "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+                                               "audio_pll2_out", "sys_pll1_133m", };
+
+static const char * const imx8mn_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+                                               "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+                                               "audio_pll2_out", "sys_pll1_133m", };
+
+static const char * const imx8mn_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+                                               "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+                                               "audio_pll2_out", "sys_pll1_133m", };
+
+static const char * const imx8mn_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
+                                                "sys_pll2_100m", "sys_pll3_out", "clk_ext2",
+                                                "clk_ext4", "audio_pll2_out", };
+
+static const char * const imx8mn_uart2_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
+                                                "sys_pll2_100m", "sys_pll3_out", "clk_ext2",
+                                                "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mn_uart3_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
+                                                "sys_pll2_100m", "sys_pll3_out", "clk_ext2",
+                                                "clk_ext4", "audio_pll2_out", };
+
+static const char * const imx8mn_uart4_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
+                                                "sys_pll2_100m", "sys_pll3_out", "clk_ext2",
+                                                "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mn_usb_core_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m",
+                                                   "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
+                                                   "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mn_usb_phy_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m",
+                                                  "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
+                                                  "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mn_gic_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
+                                       "sys_pll2_100m", "sys_pll1_800m", "clk_ext2",
+                                       "clk_ext4", "audio_pll2_out" };
+
+static const char * const imx8mn_ecspi1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
+                                                 "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+                                                 "sys_pll2_250m", "audio_pll2_out", };
+
+static const char * const imx8mn_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
+                                                 "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+                                                 "sys_pll2_250m", "audio_pll2_out", };
+
+static const char * const imx8mn_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+                                               "sys_pll1_40m", "sys_pll3_out", "clk_ext1",
+                                               "sys_pll1_80m", "video_pll1_out", };
+
+static const char * const imx8mn_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+                                               "sys_pll1_40m", "sys_pll3_out", "clk_ext1",
+                                               "sys_pll1_80m", "video_pll1_out", };
+
+static const char * const imx8mn_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+                                               "sys_pll1_40m", "sys_pll3_out", "clk_ext2",
+                                               "sys_pll1_80m", "video_pll1_out", };
+
+static const char * const imx8mn_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+                                               "sys_pll1_40m", "sys_pll3_out", "clk_ext2",
+                                               "sys_pll1_80m", "video_pll1_out", };
+
+static const char * const imx8mn_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m",
+                                               "vpu_pll_out", "sys_pll2_125m", "sys_pll3_out",
+                                               "sys_pll1_80m", "sys_pll2_166m", };
+
+static const char * const imx8mn_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_out",
+                                                "sys_pll3_out", "sys_pll2_200m", "sys_pll1_266m",
+                                                "sys_pll2_500m", "sys_pll1_100m", };
+
+static const char * const imx8mn_dsi_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
+                                                   "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+                                                   "audio_pll2_out", "video_pll1_out", };
+
+static const char * const imx8mn_dsi_phy_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_100m",
+                                                  "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2",
+                                                  "audio_pll2_out", "video_pll1_out", };
+
+static const char * const imx8mn_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_100m",
+                                                  "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+                                                  "audio_pll2_out", "video_pll1_out", };
+
+static const char * const imx8mn_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
+                                                 "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
+                                                 "audio_pll2_out", "sys_pll1_100m", };
+
+static const char * const imx8mn_camera_pixel_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
+                                                       "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+                                                       "audio_pll2_out", "video_pll1_out", };
+
+static const char * const imx8mn_csi1_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
+                                                   "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2",
+                                                   "audio_pll2_out", "video_pll1_out", };
+
+static const char * const imx8mn_csi2_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
+                                                   "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2",
+                                                   "audio_pll2_out", "video_pll1_out", };
+
+static const char * const imx8mn_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
+                                                   "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+                                                   "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mn_ecspi3_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
+                                                 "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+                                                 "sys_pll2_250m", "audio_pll2_out", };
+
+static const char * const imx8mn_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
+                                              "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+                                              "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mn_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
+
+static const char * const imx8mn_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m",
+                                                "sys_pll1_200m", "audio_pll2_out", "vpu_pll",
+                                                "sys_pll1_80m", };
+static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m",
+                                                "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out",
+                                                "video_pll1_out", "osc_32k", };
+
+static struct clk *clks[IMX8MN_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static struct clk ** const uart_clks[] = {
+       &clks[IMX8MN_CLK_UART1_ROOT],
+       &clks[IMX8MN_CLK_UART2_ROOT],
+       &clks[IMX8MN_CLK_UART3_ROOT],
+       &clks[IMX8MN_CLK_UART4_ROOT],
+       NULL
+};
+
+static int imx8mn_clocks_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       void __iomem *base;
+       int ret;
+
+       clks[IMX8MN_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+       clks[IMX8MN_CLK_24M] = of_clk_get_by_name(np, "osc_24m");
+       clks[IMX8MN_CLK_32K] = of_clk_get_by_name(np, "osc_32k");
+       clks[IMX8MN_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1");
+       clks[IMX8MN_CLK_EXT2] = of_clk_get_by_name(np, "clk_ext2");
+       clks[IMX8MN_CLK_EXT3] = of_clk_get_by_name(np, "clk_ext3");
+       clks[IMX8MN_CLK_EXT4] = of_clk_get_by_name(np, "clk_ext4");
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop");
+       base = of_iomap(np, 0);
+       if (WARN_ON(!base)) {
+               ret = -ENOMEM;
+               goto unregister_clks;
+       }
+
+       clks[IMX8MN_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_DRAM_PLL_REF_SEL] = imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_SYS_PLL1_REF_SEL] = imx_clk_mux("sys_pll1_ref_sel", base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+       clks[IMX8MN_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx8mn_audio_pll);
+       clks[IMX8MN_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mn_audio_pll);
+       clks[IMX8MN_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mn_video_pll);
+       clks[IMX8MN_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mn_dram_pll);
+       clks[IMX8MN_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mn_gpu_pll);
+       clks[IMX8MN_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mn_vpu_pll);
+       clks[IMX8MN_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mn_arm_pll);
+       clks[IMX8MN_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mn_sys_pll);
+       clks[IMX8MN_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mn_sys_pll);
+       clks[IMX8MN_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mn_sys_pll);
+
+       /* PLL bypass out */
+       clks[IMX8MN_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_SYS_PLL1_BYPASS] = imx_clk_mux_flags("sys_pll1_bypass", base + 0x94, 28, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_SYS_PLL2_BYPASS] = imx_clk_mux_flags("sys_pll2_bypass", base + 0x104, 28, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
+
+       /* PLL out gate */
+       clks[IMX8MN_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
+       clks[IMX8MN_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
+       clks[IMX8MN_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
+       clks[IMX8MN_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
+       clks[IMX8MN_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
+       clks[IMX8MN_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11);
+       clks[IMX8MN_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11);
+       clks[IMX8MN_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1_bypass", base + 0x94, 11);
+       clks[IMX8MN_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2_bypass", base + 0x104, 11);
+       clks[IMX8MN_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11);
+
+       /* SYS PLL fixed output */
+       clks[IMX8MN_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
+       clks[IMX8MN_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
+       clks[IMX8MN_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
+       clks[IMX8MN_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
+       clks[IMX8MN_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
+       clks[IMX8MN_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
+       clks[IMX8MN_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
+       clks[IMX8MN_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
+       clks[IMX8MN_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
+
+       clks[IMX8MN_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
+       clks[IMX8MN_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
+       clks[IMX8MN_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
+       clks[IMX8MN_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
+       clks[IMX8MN_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
+       clks[IMX8MN_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
+       clks[IMX8MN_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
+       clks[IMX8MN_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
+       clks[IMX8MN_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
+
+       np = dev->of_node;
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (WARN_ON(IS_ERR(base))) {
+               ret = PTR_ERR(base);
+               goto unregister_clks;
+       }
+
+       /* CORE */
+       clks[IMX8MN_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mn_a53_sels, ARRAY_SIZE(imx8mn_a53_sels));
+       clks[IMX8MN_CLK_GPU_CORE_SRC] = imx_clk_mux2("gpu_core_src", base + 0x8180, 24, 3,  imx8mn_gpu_core_sels, ARRAY_SIZE(imx8mn_gpu_core_sels));
+       clks[IMX8MN_CLK_GPU_SHADER_SRC] = imx_clk_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mn_gpu_shader_sels,  ARRAY_SIZE(imx8mn_gpu_shader_sels));
+       clks[IMX8MN_CLK_A53_CG] = imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
+       clks[IMX8MN_CLK_GPU_CORE_CG] = imx_clk_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28);
+       clks[IMX8MN_CLK_GPU_SHADER_CG] = imx_clk_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28);
+
+       clks[IMX8MN_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
+       clks[IMX8MN_CLK_GPU_CORE_DIV] = imx_clk_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3);
+       clks[IMX8MN_CLK_GPU_SHADER_DIV] = imx_clk_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3);
+
+       /* BUS */
+       clks[IMX8MN_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mn_main_axi_sels, base + 0x8800);
+       clks[IMX8MN_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mn_enet_axi_sels, base + 0x8880);
+       clks[IMX8MN_CLK_NAND_USDHC_BUS] = imx8m_clk_composite("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900);
+       clks[IMX8MN_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mn_disp_axi_sels, base + 0x8a00);
+       clks[IMX8MN_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mn_disp_apb_sels, base + 0x8a80);
+       clks[IMX8MN_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80);
+       clks[IMX8MN_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mn_gpu_axi_sels, base + 0x8c00);
+       clks[IMX8MN_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mn_gpu_ahb_sels, base + 0x8c80);
+       clks[IMX8MN_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mn_noc_sels, base + 0x8d00);
+
+       clks[IMX8MN_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mn_ahb_sels, base + 0x9000);
+       clks[IMX8MN_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mn_audio_ahb_sels, base + 0x9100);
+       clks[IMX8MN_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
+       clks[IMX8MN_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
+       clks[IMX8MN_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mn_dram_core_sels, ARRAY_SIZE(imx8mn_dram_core_sels), CLK_IS_CRITICAL);
+       clks[IMX8MN_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000);
+       clks[IMX8MN_CLK_DRAM_APB] = imx8m_clk_composite_critical("dram_apb", imx8mn_dram_apb_sels, base + 0xa080);
+       clks[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_composite("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500);
+       clks[IMX8MN_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mn_sai2_sels, base + 0xa600);
+       clks[IMX8MN_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mn_sai3_sels, base + 0xa680);
+       clks[IMX8MN_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mn_sai5_sels, base + 0xa780);
+       clks[IMX8MN_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mn_sai6_sels, base + 0xa800);
+       clks[IMX8MN_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mn_spdif1_sels, base + 0xa880);
+       clks[IMX8MN_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mn_enet_ref_sels, base + 0xa980);
+       clks[IMX8MN_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mn_enet_timer_sels, base + 0xaa00);
+       clks[IMX8MN_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mn_enet_phy_sels, base + 0xaa80);
+       clks[IMX8MN_CLK_NAND] = imx8m_clk_composite("nand", imx8mn_nand_sels, base + 0xab00);
+       clks[IMX8MN_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mn_qspi_sels, base + 0xab80);
+       clks[IMX8MN_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mn_usdhc1_sels, base + 0xac00);
+       clks[IMX8MN_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mn_usdhc2_sels, base + 0xac80);
+       clks[IMX8MN_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mn_i2c1_sels, base + 0xad00);
+       clks[IMX8MN_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mn_i2c2_sels, base + 0xad80);
+       clks[IMX8MN_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mn_i2c3_sels, base + 0xae00);
+       clks[IMX8MN_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mn_i2c4_sels, base + 0xae80);
+       clks[IMX8MN_CLK_UART1] = imx8m_clk_composite("uart1", imx8mn_uart1_sels, base + 0xaf00);
+       clks[IMX8MN_CLK_UART2] = imx8m_clk_composite("uart2", imx8mn_uart2_sels, base + 0xaf80);
+       clks[IMX8MN_CLK_UART3] = imx8m_clk_composite("uart3", imx8mn_uart3_sels, base + 0xb000);
+       clks[IMX8MN_CLK_UART4] = imx8m_clk_composite("uart4", imx8mn_uart4_sels, base + 0xb080);
+       clks[IMX8MN_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mn_usb_core_sels, base + 0xb100);
+       clks[IMX8MN_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mn_usb_phy_sels, base + 0xb180);
+       clks[IMX8MN_CLK_GIC] = imx8m_clk_composite_critical("gic", imx8mn_gic_sels, base + 0xb200);
+       clks[IMX8MN_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mn_ecspi1_sels, base + 0xb280);
+       clks[IMX8MN_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mn_ecspi2_sels, base + 0xb300);
+       clks[IMX8MN_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mn_pwm1_sels, base + 0xb380);
+       clks[IMX8MN_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mn_pwm2_sels, base + 0xb400);
+       clks[IMX8MN_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mn_pwm3_sels, base + 0xb480);
+       clks[IMX8MN_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mn_pwm4_sels, base + 0xb500);
+       clks[IMX8MN_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mn_wdog_sels, base + 0xb900);
+       clks[IMX8MN_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mn_wrclk_sels, base + 0xb980);
+       clks[IMX8MN_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mn_clko1_sels, base + 0xba00);
+       clks[IMX8MN_CLK_CLKO2] = imx8m_clk_composite("clko2", imx8mn_clko2_sels, base + 0xba80);
+       clks[IMX8MN_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mn_dsi_core_sels, base + 0xbb00);
+       clks[IMX8MN_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mn_dsi_phy_sels, base + 0xbb80);
+       clks[IMX8MN_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mn_dsi_dbi_sels, base + 0xbc00);
+       clks[IMX8MN_CLK_USDHC3] = imx8m_clk_composite("usdhc3", imx8mn_usdhc3_sels, base + 0xbc80);
+       clks[IMX8MN_CLK_CAMERA_PIXEL] = imx8m_clk_composite("camera_pixel", imx8mn_camera_pixel_sels, base + 0xbd00);
+       clks[IMX8MN_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mn_csi1_phy_sels, base + 0xbd80);
+       clks[IMX8MN_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mn_csi2_phy_sels, base + 0xbf00);
+       clks[IMX8MN_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mn_csi2_esc_sels, base + 0xbf80);
+       clks[IMX8MN_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mn_ecspi3_sels, base + 0xc180);
+       clks[IMX8MN_CLK_PDM] = imx8m_clk_composite("pdm", imx8mn_pdm_sels, base + 0xc200);
+       clks[IMX8MN_CLK_SAI7] = imx8m_clk_composite("sai7", imx8mn_sai7_sels, base + 0xc300);
+
+       clks[IMX8MN_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
+       clks[IMX8MN_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
+       clks[IMX8MN_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
+       clks[IMX8MN_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
+       clks[IMX8MN_CLK_GPIO1_ROOT] = imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
+       clks[IMX8MN_CLK_GPIO2_ROOT] = imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
+       clks[IMX8MN_CLK_GPIO3_ROOT] = imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
+       clks[IMX8MN_CLK_GPIO4_ROOT] = imx_clk_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
+       clks[IMX8MN_CLK_GPIO5_ROOT] = imx_clk_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
+       clks[IMX8MN_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
+       clks[IMX8MN_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
+       clks[IMX8MN_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
+       clks[IMX8MN_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
+       clks[IMX8MN_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
+       clks[IMX8MN_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
+       clks[IMX8MN_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
+       clks[IMX8MN_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
+       clks[IMX8MN_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
+       clks[IMX8MN_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
+       clks[IMX8MN_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
+       clks[IMX8MN_CLK_NAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
+       clks[IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
+       clks[IMX8MN_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
+       clks[IMX8MN_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2);
+       clks[IMX8MN_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
+       clks[IMX8MN_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3);
+       clks[IMX8MN_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
+       clks[IMX8MN_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
+       clks[IMX8MN_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
+       clks[IMX8MN_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
+       clks[IMX8MN_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
+       clks[IMX8MN_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
+       clks[IMX8MN_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
+       clks[IMX8MN_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
+       clks[IMX8MN_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref", base + 0x44d0, 0);
+       clks[IMX8MN_CLK_GPU_CORE_ROOT] = imx_clk_gate4("gpu_core_root_clk", "gpu_core_div", base + 0x44f0, 0);
+       clks[IMX8MN_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
+       clks[IMX8MN_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
+       clks[IMX8MN_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
+       clks[IMX8MN_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
+       clks[IMX8MN_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
+       clks[IMX8MN_CLK_GPU_BUS_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0);
+       clks[IMX8MN_CLK_ASRC_ROOT] = imx_clk_gate4("asrc_root_clk", "audio_ahb", base + 0x4580, 0);
+       clks[IMX8MN_CLK_PDM_ROOT] = imx_clk_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm);
+       clks[IMX8MN_CLK_PDM_IPG]  = imx_clk_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
+       clks[IMX8MN_CLK_DISP_AXI_ROOT]  = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp);
+       clks[IMX8MN_CLK_DISP_APB_ROOT]  = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp);
+       clks[IMX8MN_CLK_CAMERA_PIXEL_ROOT] = imx_clk_gate2_shared2("camera_pixel_clk", "camera_pixel", base + 0x45d0, 0, &share_count_disp);
+       clks[IMX8MN_CLK_DISP_PIXEL_ROOT] = imx_clk_gate2_shared2("disp_pixel_clk", "disp_pixel", base + 0x45d0, 0, &share_count_disp);
+       clks[IMX8MN_CLK_USDHC3_ROOT] = imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0);
+       clks[IMX8MN_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
+       clks[IMX8MN_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
+       clks[IMX8MN_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
+       clks[IMX8MN_CLK_SDMA3_ROOT] = imx_clk_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
+       clks[IMX8MN_CLK_SAI7_ROOT] = imx_clk_gate2_shared2("sai7_root_clk", "sai7", base + 0x4650, 0, &share_count_sai7);
+
+       clks[IMX8MN_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
+
+       clks[IMX8MN_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
+                                          clks[IMX8MN_CLK_A53_DIV],
+                                          clks[IMX8MN_CLK_A53_SRC],
+                                          clks[IMX8MN_ARM_PLL_OUT],
+                                          clks[IMX8MN_CLK_24M]);
+
+       imx_check_clocks(clks, ARRAY_SIZE(clks));
+
+       clk_data.clks = clks;
+       clk_data.clk_num = ARRAY_SIZE(clks);
+       ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+       if (ret < 0) {
+               dev_err(dev, "failed to register clks for i.MX8MN\n");
+               goto unregister_clks;
+       }
+
+       imx_register_uart_clocks(uart_clks);
+
+       return 0;
+
+unregister_clks:
+       imx_unregister_clocks(clks, ARRAY_SIZE(clks));
+
+       return ret;
+}
+
+static const struct of_device_id imx8mn_clk_of_match[] = {
+       { .compatible = "fsl,imx8mn-ccm" },
+       { /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, imx8mn_clk_of_match);
+
+static struct platform_driver imx8mn_clk_driver = {
+       .probe = imx8mn_clocks_probe,
+       .driver = {
+               .name = "imx8mn-ccm",
+               .of_match_table = of_match_ptr(imx8mn_clk_of_match),
+       },
+};
+module_platform_driver(imx8mn_clk_driver);
index d407a07e7e6dd2110c587138c2f524a70ddc34dc..41fc9c63356ea9befaee04cb9a37c6de96ecce41 100644 (file)
@@ -41,34 +41,34 @@ static const char * const dram_pll_out_sels[] = {"dram_pll1_ref_sel", };
 
 /* CCM ROOT */
 static const char * const imx8mq_a53_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m",
-                                       "sys1_pll_800m", "sys1_pll_400m", "audio_pll1_out", "sys3_pll2_out", };
+                                       "sys1_pll_800m", "sys1_pll_400m", "audio_pll1_out", "sys3_pll_out", };
 
 static const char * const imx8mq_arm_m4_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_250m", "sys1_pll_266m",
-                                       "sys1_pll_800m", "audio_pll1_out", "video_pll1_out", "sys3_pll2_out", };
+                                       "sys1_pll_800m", "audio_pll1_out", "video_pll1_out", "sys3_pll_out", };
 
 static const char * const imx8mq_vpu_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m",
                                        "sys1_pll_800m", "sys1_pll_400m", "audio_pll1_out", "vpu_pll_out", };
 
-static const char * const imx8mq_gpu_core_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll2_out",
+static const char * const imx8mq_gpu_core_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll_out",
                                             "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
 
-static const char * const imx8mq_gpu_shader_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll2_out",
+static const char * const imx8mq_gpu_shader_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll_out",
                                               "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
 
 static const char * const imx8mq_main_axi_sels[] = {"osc_25m", "sys2_pll_333m", "sys1_pll_800m", "sys2_pll_250m",
                                             "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "sys1_pll_100m",};
 
 static const char * const imx8mq_enet_axi_sels[] = {"osc_25m", "sys1_pll_266m", "sys1_pll_800m", "sys2_pll_250m",
-                                            "sys2_pll_200m", "audio_pll1_out", "video_pll1_out", "sys3_pll2_out", };
+                                            "sys2_pll_200m", "audio_pll1_out", "video_pll1_out", "sys3_pll_out", };
 
 static const char * const imx8mq_nand_usdhc_sels[] = {"osc_25m", "sys1_pll_266m", "sys1_pll_800m", "sys2_pll_200m",
-                                              "sys1_pll_133m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll1_out", };
+                                              "sys1_pll_133m", "sys3_pll_out", "sys2_pll_250m", "audio_pll1_out", };
 
-static const char * const imx8mq_vpu_bus_sels[] = {"osc_25m", "sys1_pll_800m", "vpu_pll_out", "audio_pll2_out", "sys3_pll2_out", "sys2_pll_1000m", "sys2_pll_200m", "sys1_pll_100m", };
+static const char * const imx8mq_vpu_bus_sels[] = {"osc_25m", "sys1_pll_800m", "vpu_pll_out", "audio_pll2_out", "sys3_pll_out", "sys2_pll_1000m", "sys2_pll_200m", "sys1_pll_100m", };
 
-static const char * const imx8mq_disp_axi_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll2_out", "sys1_pll_400m", "audio_pll2_out", "clk_ext1", "clk_ext4", };
+static const char * const imx8mq_disp_axi_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll_out", "sys1_pll_400m", "audio_pll2_out", "clk_ext1", "clk_ext4", };
 
-static const char * const imx8mq_disp_apb_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll2_out",
+static const char * const imx8mq_disp_apb_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll_out",
                                             "sys1_pll_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", };
 
 static const char * const imx8mq_disp_rtrm_sels[] = {"osc_25m", "sys1_pll_800m", "sys2_pll_200m", "sys1_pll_400m",
@@ -77,53 +77,53 @@ static const char * const imx8mq_disp_rtrm_sels[] = {"osc_25m", "sys1_pll_800m",
 static const char * const imx8mq_usb_bus_sels[] = {"osc_25m", "sys2_pll_500m", "sys1_pll_800m", "sys2_pll_100m",
                                            "sys2_pll_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", };
 
-static const char * const imx8mq_gpu_axi_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll2_out", "sys2_pll_1000m",
+static const char * const imx8mq_gpu_axi_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll_out", "sys2_pll_1000m",
                                            "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
 
-static const char * const imx8mq_gpu_ahb_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll2_out", "sys2_pll_1000m",
+static const char * const imx8mq_gpu_ahb_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll_out", "sys2_pll_1000m",
                                            "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
 
-static const char * const imx8mq_noc_sels[] = {"osc_25m", "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_1000m", "sys2_pll_500m",
+static const char * const imx8mq_noc_sels[] = {"osc_25m", "sys1_pll_800m", "sys3_pll_out", "sys2_pll_1000m", "sys2_pll_500m",
                                        "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
 
-static const char * const imx8mq_noc_apb_sels[] = {"osc_25m", "sys1_pll_400m", "sys3_pll2_out", "sys2_pll_333m", "sys2_pll_200m",
+static const char * const imx8mq_noc_apb_sels[] = {"osc_25m", "sys1_pll_400m", "sys3_pll_out", "sys2_pll_333m", "sys2_pll_200m",
                                            "sys1_pll_800m", "audio_pll1_out", "video_pll1_out", };
 
 static const char * const imx8mq_ahb_sels[] = {"osc_25m", "sys1_pll_133m", "sys1_pll_800m", "sys1_pll_400m",
-                                       "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", };
+                                       "sys2_pll_125m", "sys3_pll_out", "audio_pll1_out", "video_pll1_out", };
 
 static const char * const imx8mq_audio_ahb_sels[] = {"osc_25m", "sys2_pll_500m", "sys1_pll_800m", "sys2_pll_1000m",
-                                                 "sys2_pll_166m", "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", };
+                                                 "sys2_pll_166m", "sys3_pll_out", "audio_pll1_out", "video_pll1_out", };
 
 static const char * const imx8mq_dsi_ahb_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
-                                               "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out"};
+                                               "sys2_pll_1000m", "sys3_pll_out", "clk_ext3", "audio_pll2_out"};
 
 static const char * const imx8mq_dram_alt_sels[] = {"osc_25m", "sys1_pll_800m", "sys1_pll_100m", "sys2_pll_500m",
                                                "sys2_pll_250m", "sys1_pll_400m", "audio_pll1_out", "sys1_pll_266m", };
 
 static const char * const imx8mq_dram_apb_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
-                                               "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
+                                               "sys1_pll_800m", "sys3_pll_out", "sys2_pll_250m", "audio_pll2_out", };
 
-static const char * const imx8mq_vpu_g1_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_100m", "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", };
+static const char * const imx8mq_vpu_g1_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_100m", "sys2_pll_125m", "sys3_pll_out", "audio_pll1_out", };
 
-static const char * const imx8mq_vpu_g2_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_100m", "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", };
+static const char * const imx8mq_vpu_g2_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_100m", "sys2_pll_125m", "sys3_pll_out", "audio_pll1_out", };
 
-static const char * const imx8mq_disp_dtrc_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", "sys2_pll_100m", "sys3_pll2_out", "audio_pll2_out", };
+static const char * const imx8mq_disp_dtrc_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", "sys2_pll_100m", "sys3_pll_out", "audio_pll2_out", };
 
-static const char * const imx8mq_disp_dc8000_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", "sys2_pll_100m", "sys3_pll2_out", "audio_pll2_out", };
+static const char * const imx8mq_disp_dc8000_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", "sys2_pll_100m", "sys3_pll_out", "audio_pll2_out", };
 
 static const char * const imx8mq_pcie1_ctrl_sels[] = {"osc_25m", "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m",
-                                              "sys1_pll_800m", "sys2_pll_500m", "sys2_pll_250m", "sys3_pll2_out", };
+                                              "sys1_pll_800m", "sys2_pll_500m", "sys2_pll_250m", "sys3_pll_out", };
 
 static const char * const imx8mq_pcie1_phy_sels[] = {"osc_25m", "sys2_pll_100m", "sys2_pll_500m", "clk_ext1", "clk_ext2",
                                              "clk_ext3", "clk_ext4", };
 
-static const char * const imx8mq_pcie1_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_500m", "sys3_pll2_out",
+static const char * const imx8mq_pcie1_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_500m", "sys3_pll_out",
                                              "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_160m", "sys1_pll_200m", };
 
-static const char * const imx8mq_dc_pixel_sels[] = {"osc_25m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", "sys2_pll_1000m", "sys3_pll2_out", "clk_ext4", };
+static const char * const imx8mq_dc_pixel_sels[] = {"osc_25m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", "sys2_pll_1000m", "sys3_pll_out", "clk_ext4", };
 
-static const char * const imx8mq_lcdif_pixel_sels[] = {"osc_25m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", "sys2_pll_1000m", "sys3_pll2_out", "clk_ext4", };
+static const char * const imx8mq_lcdif_pixel_sels[] = {"osc_25m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", "sys2_pll_1000m", "sys3_pll_out", "clk_ext4", };
 
 static const char * const imx8mq_sai1_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext1", "clk_ext2", };
 
@@ -151,40 +151,40 @@ static const char * const imx8mq_enet_phy_sels[] = {"osc_25m", "sys2_pll_50m", "
                                             "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
 
 static const char * const imx8mq_nand_sels[] = {"osc_25m", "sys2_pll_500m", "audio_pll1_out", "sys1_pll_400m",
-                                        "audio_pll2_out", "sys3_pll2_out", "sys2_pll_250m", "video_pll1_out", };
+                                        "audio_pll2_out", "sys3_pll_out", "sys2_pll_250m", "video_pll1_out", };
 
 static const char * const imx8mq_qspi_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
-                                        "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", };
+                                        "audio_pll2_out", "sys1_pll_266m", "sys3_pll_out", "sys1_pll_100m", };
 
 static const char * const imx8mq_usdhc1_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
-                                        "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", };
+                                        "audio_pll2_out", "sys1_pll_266m", "sys3_pll_out", "sys1_pll_100m", };
 
 static const char * const imx8mq_usdhc2_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
-                                        "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", };
+                                        "audio_pll2_out", "sys1_pll_266m", "sys3_pll_out", "sys1_pll_100m", };
 
-static const char * const imx8mq_i2c1_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
+static const char * const imx8mq_i2c1_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll_out", "audio_pll1_out",
                                         "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
 
-static const char * const imx8mq_i2c2_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
+static const char * const imx8mq_i2c2_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll_out", "audio_pll1_out",
                                         "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
 
-static const char * const imx8mq_i2c3_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
+static const char * const imx8mq_i2c3_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll_out", "audio_pll1_out",
                                         "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
 
-static const char * const imx8mq_i2c4_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
+static const char * const imx8mq_i2c4_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll_out", "audio_pll1_out",
                                         "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
 
 static const char * const imx8mq_uart1_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
-                                         "sys3_pll2_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
+                                         "sys3_pll_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
 
 static const char * const imx8mq_uart2_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
-                                         "sys3_pll2_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+                                         "sys3_pll_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
 
 static const char * const imx8mq_uart3_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
-                                         "sys3_pll2_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
+                                         "sys3_pll_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
 
 static const char * const imx8mq_uart4_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
-                                         "sys3_pll2_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
+                                         "sys3_pll_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
 
 static const char * const imx8mq_usb_core_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m",
                                             "sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
@@ -196,79 +196,79 @@ static const char * const imx8mq_gic_sels[] = {"osc_25m", "sys2_pll_200m", "sys1
                                               "sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out" };
 
 static const char * const imx8mq_ecspi1_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
-                                          "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
+                                          "sys1_pll_800m", "sys3_pll_out", "sys2_pll_250m", "audio_pll2_out", };
 
 static const char * const imx8mq_ecspi2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
-                                          "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
+                                          "sys1_pll_800m", "sys3_pll_out", "sys2_pll_250m", "audio_pll2_out", };
 
 static const char * const imx8mq_pwm1_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
-                                        "sys3_pll2_out", "clk_ext1", "sys1_pll_80m", "video_pll1_out", };
+                                        "sys3_pll_out", "clk_ext1", "sys1_pll_80m", "video_pll1_out", };
 
 static const char * const imx8mq_pwm2_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
-                                        "sys3_pll2_out", "clk_ext1", "sys1_pll_80m", "video_pll1_out", };
+                                        "sys3_pll_out", "clk_ext1", "sys1_pll_80m", "video_pll1_out", };
 
 static const char * const imx8mq_pwm3_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
-                                        "sys3_pll2_out", "clk_ext2", "sys1_pll_80m", "video_pll1_out", };
+                                        "sys3_pll_out", "clk_ext2", "sys1_pll_80m", "video_pll1_out", };
 
 static const char * const imx8mq_pwm4_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
-                                        "sys3_pll2_out", "clk_ext2", "sys1_pll_80m", "video_pll1_out", };
+                                        "sys3_pll_out", "clk_ext2", "sys1_pll_80m", "video_pll1_out", };
 
 static const char * const imx8mq_gpt1_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_400m", "sys1_pll_40m",
                                         "sys1_pll_80m", "audio_pll1_out", "clk_ext1", };
 
 static const char * const imx8mq_wdog_sels[] = {"osc_25m", "sys1_pll_133m", "sys1_pll_160m", "vpu_pll_out",
-                                        "sys2_pll_125m", "sys3_pll2_out", "sys1_pll_80m", "sys2_pll_166m", };
+                                        "sys2_pll_125m", "sys3_pll_out", "sys1_pll_80m", "sys2_pll_166m", };
 
-static const char * const imx8mq_wrclk_sels[] = {"osc_25m", "sys1_pll_40m", "vpu_pll_out", "sys3_pll2_out", "sys2_pll_200m",
+static const char * const imx8mq_wrclk_sels[] = {"osc_25m", "sys1_pll_40m", "vpu_pll_out", "sys3_pll_out", "sys2_pll_200m",
                                          "sys1_pll_266m", "sys2_pll_500m", "sys1_pll_100m", };
 
 static const char * const imx8mq_dsi_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
-                                            "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
+                                            "sys2_pll_1000m", "sys3_pll_out", "audio_pll2_out", "video_pll1_out", };
 
 static const char * const imx8mq_dsi_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
                                            "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
 
 static const char * const imx8mq_dsi_dbi_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_100m", "sys1_pll_800m",
-                                           "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
+                                           "sys2_pll_1000m", "sys3_pll_out", "audio_pll2_out", "video_pll1_out", };
 
 static const char * const imx8mq_dsi_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
-                                           "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", };
+                                           "sys2_pll_1000m", "sys3_pll_out", "clk_ext3", "audio_pll2_out", };
 
 static const char * const imx8mq_csi1_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
-                                             "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
+                                             "sys2_pll_1000m", "sys3_pll_out", "audio_pll2_out", "video_pll1_out", };
 
 static const char * const imx8mq_csi1_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
                                             "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
 
 static const char * const imx8mq_csi1_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
-                                            "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", };
+                                            "sys2_pll_1000m", "sys3_pll_out", "clk_ext3", "audio_pll2_out", };
 
 static const char * const imx8mq_csi2_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
-                                             "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
+                                             "sys2_pll_1000m", "sys3_pll_out", "audio_pll2_out", "video_pll1_out", };
 
 static const char * const imx8mq_csi2_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
                                             "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
 
 static const char * const imx8mq_csi2_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
-                                            "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", };
+                                            "sys2_pll_1000m", "sys3_pll_out", "clk_ext3", "audio_pll2_out", };
 
 static const char * const imx8mq_pcie2_ctrl_sels[] = {"osc_25m", "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m",
-                                              "sys1_pll_800m", "sys2_pll_500m", "sys2_pll_333m", "sys3_pll2_out", };
+                                              "sys1_pll_800m", "sys2_pll_500m", "sys2_pll_333m", "sys3_pll_out", };
 
 static const char * const imx8mq_pcie2_phy_sels[] = {"osc_25m", "sys2_pll_100m", "sys2_pll_500m", "clk_ext1",
                                              "clk_ext2", "clk_ext3", "clk_ext4", "sys1_pll_400m", };
 
-static const char * const imx8mq_pcie2_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_50m", "sys3_pll2_out",
+static const char * const imx8mq_pcie2_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_50m", "sys3_pll_out",
                                              "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_160m", "sys1_pll_200m", };
 
 static const char * const imx8mq_ecspi3_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
-                                          "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
+                                          "sys1_pll_800m", "sys3_pll_out", "sys2_pll_250m", "audio_pll2_out", };
 static const char * const imx8mq_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
 
 static const char * const imx8mq_clko1_sels[] = {"osc_25m", "sys1_pll_800m", "osc_27m", "sys1_pll_200m",
                                          "audio_pll2_out", "sys2_pll_500m", "vpu_pll_out", "sys1_pll_80m", };
 static const char * const imx8mq_clko2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_400m", "sys2_pll_166m",
-                                         "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", "ckil", };
+                                         "sys3_pll_out", "audio_pll1_out", "video_pll1_out", "ckil", };
 
 static struct clk_onecell_data clk_data;
 
@@ -406,7 +406,8 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
        clks[IMX8MQ_CLK_NOC_APB] = imx8m_clk_composite_critical("noc_apb", imx8mq_noc_apb_sels, base + 0x8d80);
 
        /* AHB */
-       clks[IMX8MQ_CLK_AHB] = imx8m_clk_composite("ahb", imx8mq_ahb_sels, base + 0x9000);
+       /* AHB clock is used by the AHB bus therefore marked as critical */
+       clks[IMX8MQ_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mq_ahb_sels, base + 0x9000);
        clks[IMX8MQ_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mq_audio_ahb_sels, base + 0x9100);
 
        /* IPG */
@@ -523,8 +524,8 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
        clks[IMX8MQ_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
        clks[IMX8MQ_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
        clks[IMX8MQ_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
-       clks[IMX8MQ_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref", base + 0x44d0, 0);
-       clks[IMX8MQ_CLK_USB2_CTRL_ROOT] = imx_clk_gate4("usb2_ctrl_root_clk", "usb_core_ref", base + 0x44e0, 0);
+       clks[IMX8MQ_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0);
+       clks[IMX8MQ_CLK_USB2_CTRL_ROOT] = imx_clk_gate4("usb2_ctrl_root_clk", "usb_bus", base + 0x44e0, 0);
        clks[IMX8MQ_CLK_USB1_PHY_ROOT] = imx_clk_gate4("usb1_phy_root_clk", "usb_phy_ref", base + 0x44f0, 0);
        clks[IMX8MQ_CLK_USB2_PHY_ROOT] = imx_clk_gate4("usb2_phy_root_clk", "usb_phy_ref", base + 0x4500, 0);
        clks[IMX8MQ_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
@@ -539,7 +540,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
        clks[IMX8MQ_CLK_DISP_AXI_ROOT]  = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss);
        clks[IMX8MQ_CLK_DISP_APB_ROOT]  = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss);
        clks[IMX8MQ_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss);
-       clks[IMX8MQ_CLK_TMU_ROOT] = imx_clk_gate4_flags("tmu_root_clk", "ipg_root", base + 0x4620, 0, CLK_IS_CRITICAL);
+       clks[IMX8MQ_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
        clks[IMX8MQ_CLK_VPU_DEC_ROOT] = imx_clk_gate2_flags("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
        clks[IMX8MQ_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
        clks[IMX8MQ_CLK_CSI2_ROOT] = imx_clk_gate4("csi2_root_clk", "csi2_core", base + 0x4660, 0);
@@ -561,10 +562,18 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
        clk_data.clk_num = ARRAY_SIZE(clks);
 
        err = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
-       WARN_ON(err);
+       if (err < 0) {
+               dev_err(dev, "failed to register clks for i.MX8MQ\n");
+               goto unregister_clks;
+       }
 
        imx_register_uart_clocks(uart_clks);
 
+       return 0;
+
+unregister_clks:
+       imx_unregister_clocks(clks, ARRAY_SIZE(clks));
+
        return err;
 }
 
index fb6edf1b8aa2688bc1ce7e2e2555698d8c01a583..c0aff7ca6374c951537e669e8b970309f4e7e167 100644 (file)
@@ -72,6 +72,11 @@ static const struct imx8qxp_lpcg_data imx8qxp_lpcg_adma[] = {
        { IMX_ADMA_LPCG_I2C2_CLK, "i2c2_lpcg_clk", "i2c2_clk", 0, ADMA_LPI2C_2_LPCG, 0, 0, },
        { IMX_ADMA_LPCG_I2C3_IPG_CLK, "i2c3_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPI2C_3_LPCG, 16, 0, },
        { IMX_ADMA_LPCG_I2C3_CLK, "i2c3_lpcg_clk", "i2c3_clk", 0, ADMA_LPI2C_3_LPCG, 0, 0, },
+
+       { IMX_ADMA_LPCG_DSP_CORE_CLK, "dsp_lpcg_core_clk", "dma_ipg_clk_root", 0, ADMA_HIFI_LPCG, 28, 0, },
+       { IMX_ADMA_LPCG_DSP_IPG_CLK, "dsp_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_HIFI_LPCG, 20, 0, },
+       { IMX_ADMA_LPCG_DSP_ADB_CLK, "dsp_lpcg_adb_clk", "dma_ipg_clk_root", 0, ADMA_HIFI_LPCG, 16, 0, },
+       { IMX_ADMA_LPCG_OCRAM_IPG_CLK, "ocram_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_OCRAM_LPCG, 16, 0, },
 };
 
 static const struct imx8qxp_ss_lpcg imx8qxp_ss_adma = {
index b7213023b238fdeadbf0548b17790432956483c4..7a815ec76aa5c88e57ff7e11cfb9c4433267ab33 100644 (file)
@@ -191,6 +191,10 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,
        tmp &= ~RST_MASK;
        writel_relaxed(tmp, pll->base);
 
+       /* Enable BYPASS */
+       tmp |= BYPASS_MASK;
+       writel(tmp, pll->base);
+
        div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
                (rate->sdiv << SDIV_SHIFT);
        writel_relaxed(div_val, pll->base + 0x4);
@@ -250,6 +254,10 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
        tmp &= ~RST_MASK;
        writel_relaxed(tmp, pll->base);
 
+       /* Enable BYPASS */
+       tmp |= BYPASS_MASK;
+       writel_relaxed(tmp, pll->base);
+
        div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
                (rate->sdiv << SDIV_SHIFT);
        writel_relaxed(div_val, pll->base + 0x4);
@@ -283,16 +291,28 @@ static int clk_pll14xx_prepare(struct clk_hw *hw)
 {
        struct clk_pll14xx *pll = to_clk_pll14xx(hw);
        u32 val;
+       int ret;
 
        /*
         * RESETB = 1 from 0, PLL starts its normal
         * operation after lock time
         */
        val = readl_relaxed(pll->base + GNRL_CTL);
+       if (val & RST_MASK)
+               return 0;
+       val |= BYPASS_MASK;
+       writel_relaxed(val, pll->base + GNRL_CTL);
        val |= RST_MASK;
        writel_relaxed(val, pll->base + GNRL_CTL);
 
-       return clk_pll14xx_wait_lock(pll);
+       ret = clk_pll14xx_wait_lock(pll);
+       if (ret)
+               return ret;
+
+       val &= ~BYPASS_MASK;
+       writel_relaxed(val, pll->base + GNRL_CTL);
+
+       return 0;
 }
 
 static int clk_pll14xx_is_prepared(struct clk_hw *hw)
@@ -348,6 +368,7 @@ struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
        struct clk_pll14xx *pll;
        struct clk *clk;
        struct clk_init_data init;
+       u32 val;
 
        pll = kzalloc(sizeof(*pll), GFP_KERNEL);
        if (!pll)
@@ -379,6 +400,10 @@ struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
        pll->rate_table = pll_clk->rate_table;
        pll->rate_count = pll_clk->rate_count;
 
+       val = readl_relaxed(pll->base + GNRL_CTL);
+       val &= ~BYPASS_MASK;
+       writel_relaxed(val, pll->base + GNRL_CTL);
+
        clk = clk_register(NULL, &pll->hw);
        if (IS_ERR(clk)) {
                pr_err("%s: failed to register pll %s %lu\n",
index f628071f6605e3f3dd18b9db8cd82cbaec6f82ff..cfc05e43c3430d58a26e291480f7a09e622e3781 100644 (file)
 
 DEFINE_SPINLOCK(imx_ccm_lock);
 
+void imx_unregister_clocks(struct clk *clks[], unsigned int count)
+{
+       unsigned int i;
+
+       for (i = 0; i < count; i++)
+               clk_unregister(clks[i]);
+}
+
 void __init imx_mmdc_mask_handshake(void __iomem *ccm_base,
                                    unsigned int chn)
 {
index d94d9cb079d3970e38e0f745d39b8e3311bcb25a..f7a389a50401abeb765159ce4c7b97e3a432dfa4 100644 (file)
@@ -10,8 +10,8 @@ extern spinlock_t imx_ccm_lock;
 void imx_check_clocks(struct clk *clks[], unsigned int count);
 void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count);
 void imx_register_uart_clocks(struct clk ** const clks[]);
-void imx_register_uart_clocks_hws(struct clk_hw ** const hws[]);
 void imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn);
+void imx_unregister_clocks(struct clk *clks[], unsigned int count);
 
 extern void imx_cscmr1_fixup(u32 *val);
 
@@ -50,12 +50,6 @@ struct imx_pll14xx_clk {
        int flags;
 };
 
-#define imx_clk_busy_divider(name, parent_name, reg, shift, width, busy_reg, busy_shift) \
-       imx_clk_hw_busy_divider(name, parent_name, reg, shift, width, busy_reg, busy_shift)->clk
-
-#define imx_clk_busy_mux(name, reg, shift, width, busy_reg, busy_shift, parent_names, num_parents) \
-       imx_clk_hw_busy_mux(name, reg, shift, width, busy_reg, busy_shift, parent_names, num_parents)->clk
-
 #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \
        imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)->clk
 
@@ -73,15 +67,6 @@ struct imx_pll14xx_clk {
 #define imx_clk_gate_exclusive(name, parent, reg, shift, exclusive_mask) \
        imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask)->clk
 
-#define imx_clk_fixup_divider(name, parent, reg, shift, width, fixup) \
-       imx_clk_hw_fixup_divider(name, parent, reg, shift, width, fixup)->clk
-
-#define imx_clk_fixup_mux(name, reg, shift, width, parents, num_parents, fixup) \
-       imx_clk_hw_fixup_mux(name, reg, shift, width, parents, num_parents, fixup)->clk
-
-#define imx_clk_mux_ldb(name, reg, shift, width, parents, num_parents) \
-       imx_clk_hw_mux_ldb(name, reg, shift, width, parents, num_parents)->clk
-
 #define imx_clk_fixed_factor(name, parent, mult, div) \
        imx_clk_hw_fixed_factor(name, parent, mult, div)->clk
 
@@ -91,21 +76,12 @@ struct imx_pll14xx_clk {
 #define imx_clk_gate_dis(name, parent, reg, shift) \
        imx_clk_hw_gate_dis(name, parent, reg, shift)->clk
 
-#define imx_clk_gate_dis_flags(name, parent, reg, shift, flags) \
-       imx_clk_hw_gate_dis_flags(name, parent, reg, shift, flags)->clk
-
-#define imx_clk_gate_flags(name, parent, reg, shift, flags) \
-       imx_clk_hw_gate_flags(name, parent, reg, shift, flags)->clk
-
 #define imx_clk_gate2(name, parent, reg, shift) \
        imx_clk_hw_gate2(name, parent, reg, shift)->clk
 
 #define imx_clk_gate2_flags(name, parent, reg, shift, flags) \
        imx_clk_hw_gate2_flags(name, parent, reg, shift, flags)->clk
 
-#define imx_clk_gate2_shared(name, parent, reg, shift, share_count) \
-       imx_clk_hw_gate2_shared(name, parent, reg, shift, share_count)->clk
-
 #define imx_clk_gate2_shared2(name, parent, reg, shift, share_count) \
        imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count)->clk
 
@@ -153,6 +129,23 @@ enum imx_pllv3_type {
 struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name,
                const char *parent_name, void __iomem *base, u32 div_mask);
 
+#define PLL_1416X_RATE(_rate, _m, _p, _s)              \
+       {                                               \
+               .rate   =       (_rate),                \
+               .mdiv   =       (_m),                   \
+               .pdiv   =       (_p),                   \
+               .sdiv   =       (_s),                   \
+       }
+
+#define PLL_1443X_RATE(_rate, _m, _p, _s, _k)          \
+       {                                               \
+               .rate   =       (_rate),                \
+               .mdiv   =       (_m),                   \
+               .pdiv   =       (_p),                   \
+               .sdiv   =       (_s),                   \
+               .kdiv   =       (_k),                   \
+       }
+
 struct clk_hw *imx_clk_pllv4(const char *name, const char *parent_name,
                             void __iomem *base);
 
index 2642d36d1e2cb685a10af21c3b32c95d12f123ec..a3b4635f6278463f9afdd4a4ef02f04f50d49e74 100644 (file)
@@ -257,4 +257,4 @@ static void __init jz4725b_cgu_init(struct device_node *np)
 
        ingenic_cgu_register_syscore_ops(cgu);
 }
-CLK_OF_DECLARE(jz4725b_cgu, "ingenic,jz4725b-cgu", jz4725b_cgu_init);
+CLK_OF_DECLARE_DRIVER(jz4725b_cgu, "ingenic,jz4725b-cgu", jz4725b_cgu_init);
index 4c0a20949c2c2785978b6b4d04f990b661c861c2..978f32dd424a6b6b8b7fcc475bf31231f78d2439 100644 (file)
@@ -53,6 +53,10 @@ static const u8 jz4740_cgu_cpccr_div_table[] = {
        1, 2, 3, 4, 6, 8, 12, 16, 24, 32,
 };
 
+static const u8 jz4740_cgu_pll_half_div_table[] = {
+       2, 1,
+};
+
 static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
 
        /* External clocks */
@@ -86,7 +90,10 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
        [JZ4740_CLK_PLL_HALF] = {
                "pll half", CGU_CLK_DIV,
                .parents = { JZ4740_CLK_PLL, -1, -1, -1 },
-               .div = { CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1 },
+               .div = {
+                       CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1,
+                       jz4740_cgu_pll_half_div_table,
+               },
        },
 
        [JZ4740_CLK_CCLK] = {
@@ -241,4 +248,4 @@ static void __init jz4740_cgu_init(struct device_node *np)
 
        ingenic_cgu_register_syscore_ops(cgu);
 }
-CLK_OF_DECLARE(jz4740_cgu, "ingenic,jz4740-cgu", jz4740_cgu_init);
+CLK_OF_DECLARE_DRIVER(jz4740_cgu, "ingenic,jz4740-cgu", jz4740_cgu_init);
index eebc1bea3841ea6938a1954f056ce8544952dced..956dd653a43d22a4cc6975af01db626a75adcbca 100644 (file)
@@ -443,4 +443,4 @@ static void __init jz4770_cgu_init(struct device_node *np)
 }
 
 /* We only probe via devicetree, no need for a platform driver */
-CLK_OF_DECLARE(jz4770_cgu, "ingenic,jz4770-cgu", jz4770_cgu_init);
+CLK_OF_DECLARE_DRIVER(jz4770_cgu, "ingenic,jz4770-cgu", jz4770_cgu_init);
index 8c67f89df25e54909fa5ed3443aeb804416e4022..ea905ff72bf03492b2dc5201509d42cbf2711d61 100644 (file)
@@ -725,4 +725,4 @@ static void __init jz4780_cgu_init(struct device_node *np)
 
        ingenic_cgu_register_syscore_ops(cgu);
 }
-CLK_OF_DECLARE(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init);
+CLK_OF_DECLARE_DRIVER(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init);
index ce3d9b300bab57d4855601972a696cd8c17e4fab..7efc3617bbd55396aa342e3d5f3203f20b1663a7 100644 (file)
@@ -117,6 +117,62 @@ config COMMON_CLK_MT2712_VENCSYS
        ---help---
          This driver supports MediaTek MT2712 vencsys clocks.
 
+config COMMON_CLK_MT6779
+       bool "Clock driver for MediaTek MT6779"
+       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK && ARM64
+       help
+         This driver supports MediaTek MT6779 basic clocks.
+
+config COMMON_CLK_MT6779_MMSYS
+       bool "Clock driver for MediaTek MT6779 mmsys"
+       depends on COMMON_CLK_MT6779
+       help
+         This driver supports MediaTek MT6779 mmsys clocks.
+
+config COMMON_CLK_MT6779_IMGSYS
+       bool "Clock driver for MediaTek MT6779 imgsys"
+       depends on COMMON_CLK_MT6779
+       help
+         This driver supports MediaTek MT6779 imgsys clocks.
+
+config COMMON_CLK_MT6779_IPESYS
+       bool "Clock driver for MediaTek MT6779 ipesys"
+       depends on COMMON_CLK_MT6779
+       help
+         This driver supports MediaTek MT6779 ipesys clocks.
+
+config COMMON_CLK_MT6779_CAMSYS
+       bool "Clock driver for MediaTek MT6779 camsys"
+       depends on COMMON_CLK_MT6779
+       help
+         This driver supports MediaTek MT6779 camsys clocks.
+
+config COMMON_CLK_MT6779_VDECSYS
+       bool "Clock driver for MediaTek MT6779 vdecsys"
+       depends on COMMON_CLK_MT6779
+       help
+         This driver supports MediaTek MT6779 vdecsys clocks.
+
+config COMMON_CLK_MT6779_VENCSYS
+       bool "Clock driver for MediaTek MT6779 vencsys"
+       depends on COMMON_CLK_MT6779
+       help
+         This driver supports MediaTek MT6779 vencsys clocks.
+
+config COMMON_CLK_MT6779_MFGCFG
+       bool "Clock driver for MediaTek MT6779 mfgcfg"
+       depends on COMMON_CLK_MT6779
+       help
+         This driver supports MediaTek MT6779 mfgcfg clocks.
+
+config COMMON_CLK_MT6779_AUDSYS
+       bool "Clock driver for Mediatek MT6779 audsys"
+       depends on COMMON_CLK_MT6779
+       help
+         This driver supports Mediatek MT6779 audsys clocks.
+
 config COMMON_CLK_MT6797
        bool "Clock driver for MediaTek MT6797"
        depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
index 672de0099eef83448df5bb97305facbecd3ac754..8cdb76a5cd713f062d4620a8fef2e5ca79bf2da0 100644 (file)
@@ -1,6 +1,15 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o clk-mux.o
 
+obj-$(CONFIG_COMMON_CLK_MT6779) += clk-mt6779.o
+obj-$(CONFIG_COMMON_CLK_MT6779_MMSYS) += clk-mt6779-mm.o
+obj-$(CONFIG_COMMON_CLK_MT6779_IMGSYS) += clk-mt6779-img.o
+obj-$(CONFIG_COMMON_CLK_MT6779_IPESYS) += clk-mt6779-ipe.o
+obj-$(CONFIG_COMMON_CLK_MT6779_CAMSYS) += clk-mt6779-cam.o
+obj-$(CONFIG_COMMON_CLK_MT6779_VDECSYS) += clk-mt6779-vdec.o
+obj-$(CONFIG_COMMON_CLK_MT6779_VENCSYS) += clk-mt6779-venc.o
+obj-$(CONFIG_COMMON_CLK_MT6779_MFGCFG) += clk-mt6779-mfg.o
+obj-$(CONFIG_COMMON_CLK_MT6779_AUDSYS) += clk-mt6779-aud.o
 obj-$(CONFIG_COMMON_CLK_MT6797) += clk-mt6797.o
 obj-$(CONFIG_COMMON_CLK_MT6797_IMGSYS) += clk-mt6797-img.o
 obj-$(CONFIG_COMMON_CLK_MT6797_MMSYS) += clk-mt6797-mm.o
index 803bf0ae1fd65a5b3a1770c12d458a6a4e4dbe1f..a35cf0b221501197ca5ccd980183209494f1aaa3 100644 (file)
@@ -150,7 +150,8 @@ struct clk *mtk_clk_register_gate(
                int sta_ofs,
                u8 bit,
                const struct clk_ops *ops,
-               unsigned long flags)
+               unsigned long flags,
+               struct device *dev)
 {
        struct mtk_clk_gate *cg;
        struct clk *clk;
@@ -174,7 +175,7 @@ struct clk *mtk_clk_register_gate(
 
        cg->hw.init = &init;
 
-       clk = clk_register(NULL, &cg->hw);
+       clk = clk_register(dev, &cg->hw);
        if (IS_ERR(clk))
                kfree(cg);
 
index e05c736974859d807e299b26017e4b21f4e74ded..3c3329ec54b7afc9ca7aaac38a4e8e18a5ac3f57 100644 (file)
@@ -40,7 +40,8 @@ struct clk *mtk_clk_register_gate(
                int sta_ofs,
                u8 bit,
                const struct clk_ops *ops,
-               unsigned long flags);
+               unsigned long flags,
+               struct device *dev);
 
 #define GATE_MTK_FLAGS(_id, _name, _parent, _regs, _shift,     \
                        _ops, _flags) {                         \
diff --git a/drivers/clk/mediatek/clk-mt6779-aud.c b/drivers/clk/mediatek/clk-mt6779-aud.c
new file mode 100644 (file)
index 0000000..11b209f
--- /dev/null
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Wendell Lin <wendell.lin@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6779-clk.h>
+
+static const struct mtk_gate_regs audio0_cg_regs = {
+       .set_ofs = 0x0,
+       .clr_ofs = 0x0,
+       .sta_ofs = 0x0,
+};
+
+static const struct mtk_gate_regs audio1_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x4,
+       .sta_ofs = 0x4,
+};
+
+#define GATE_AUDIO0(_id, _name, _parent, _shift)               \
+       GATE_MTK(_id, _name, _parent, &audio0_cg_regs, _shift,  \
+               &mtk_clk_gate_ops_no_setclr)
+#define GATE_AUDIO1(_id, _name, _parent, _shift)               \
+       GATE_MTK(_id, _name, _parent, &audio1_cg_regs, _shift,  \
+               &mtk_clk_gate_ops_no_setclr)
+
+static const struct mtk_gate audio_clks[] = {
+       /* AUDIO0 */
+       GATE_AUDIO0(CLK_AUD_AFE, "aud_afe", "audio_sel", 2),
+       GATE_AUDIO0(CLK_AUD_22M, "aud_22m", "aud_eng1_sel", 8),
+       GATE_AUDIO0(CLK_AUD_24M, "aud_24m", "aud_eng2_sel", 9),
+       GATE_AUDIO0(CLK_AUD_APLL2_TUNER, "aud_apll2_tuner",
+                   "aud_eng2_sel", 18),
+       GATE_AUDIO0(CLK_AUD_APLL_TUNER, "aud_apll_tuner",
+                   "aud_eng1_sel", 19),
+       GATE_AUDIO0(CLK_AUD_TDM, "aud_tdm", "aud_eng1_sel", 20),
+       GATE_AUDIO0(CLK_AUD_ADC, "aud_adc", "audio_sel", 24),
+       GATE_AUDIO0(CLK_AUD_DAC, "aud_dac", "audio_sel", 25),
+       GATE_AUDIO0(CLK_AUD_DAC_PREDIS, "aud_dac_predis",
+                   "audio_sel", 26),
+       GATE_AUDIO0(CLK_AUD_TML, "aud_tml", "audio_sel", 27),
+       GATE_AUDIO0(CLK_AUD_NLE, "aud_nle", "audio_sel", 28),
+       /* AUDIO1 */
+       GATE_AUDIO1(CLK_AUD_I2S1_BCLK_SW, "aud_i2s1_bclk",
+                   "audio_sel", 4),
+       GATE_AUDIO1(CLK_AUD_I2S2_BCLK_SW, "aud_i2s2_bclk",
+                   "audio_sel", 5),
+       GATE_AUDIO1(CLK_AUD_I2S3_BCLK_SW, "aud_i2s3_bclk",
+                   "audio_sel", 6),
+       GATE_AUDIO1(CLK_AUD_I2S4_BCLK_SW, "aud_i2s4_bclk",
+                   "audio_sel", 7),
+       GATE_AUDIO1(CLK_AUD_I2S5_BCLK_SW, "aud_i2s5_bclk",
+                   "audio_sel", 8),
+       GATE_AUDIO1(CLK_AUD_CONN_I2S_ASRC, "aud_conn_i2s",
+                   "audio_sel", 12),
+       GATE_AUDIO1(CLK_AUD_GENERAL1_ASRC, "aud_general1",
+                   "audio_sel", 13),
+       GATE_AUDIO1(CLK_AUD_GENERAL2_ASRC, "aud_general2",
+                   "audio_sel", 14),
+       GATE_AUDIO1(CLK_AUD_DAC_HIRES, "aud_dac_hires",
+                   "audio_h_sel", 15),
+       GATE_AUDIO1(CLK_AUD_ADC_HIRES, "aud_adc_hires",
+                   "audio_h_sel", 16),
+       GATE_AUDIO1(CLK_AUD_ADC_HIRES_TML, "aud_adc_hires_tml",
+                   "audio_h_sel", 17),
+       GATE_AUDIO1(CLK_AUD_PDN_ADDA6_ADC, "aud_pdn_adda6_adc",
+                   "audio_sel", 20),
+       GATE_AUDIO1(CLK_AUD_ADDA6_ADC_HIRES, "aud_adda6_adc_hires",
+                   "audio_h_sel",
+                   21),
+       GATE_AUDIO1(CLK_AUD_3RD_DAC, "aud_3rd_dac", "audio_sel",
+                   28),
+       GATE_AUDIO1(CLK_AUD_3RD_DAC_PREDIS, "aud_3rd_dac_predis",
+                   "audio_sel", 29),
+       GATE_AUDIO1(CLK_AUD_3RD_DAC_TML, "aud_3rd_dac_tml",
+                   "audio_sel", 30),
+       GATE_AUDIO1(CLK_AUD_3RD_DAC_HIRES, "aud_3rd_dac_hires",
+                   "audio_h_sel", 31),
+};
+
+static const struct of_device_id of_match_clk_mt6779_aud[] = {
+       { .compatible = "mediatek,mt6779-audio", },
+       {}
+};
+
+static int clk_mt6779_aud_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_AUD_NR_CLK);
+
+       mtk_clk_register_gates(node, audio_clks, ARRAY_SIZE(audio_clks),
+                              clk_data);
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static struct platform_driver clk_mt6779_aud_drv = {
+       .probe = clk_mt6779_aud_probe,
+       .driver = {
+               .name = "clk-mt6779-aud",
+               .of_match_table = of_match_clk_mt6779_aud,
+       },
+};
+
+builtin_platform_driver(clk_mt6779_aud_drv);
diff --git a/drivers/clk/mediatek/clk-mt6779-cam.c b/drivers/clk/mediatek/clk-mt6779-cam.c
new file mode 100644 (file)
index 0000000..244d420
--- /dev/null
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Wendell Lin <wendell.lin@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/mt6779-clk.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+static const struct mtk_gate_regs cam_cg_regs = {
+       .set_ofs = 0x0004,
+       .clr_ofs = 0x0008,
+       .sta_ofs = 0x0000,
+};
+
+#define GATE_CAM(_id, _name, _parent, _shift)                  \
+       GATE_MTK(_id, _name, _parent, &cam_cg_regs, _shift,     \
+               &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate cam_clks[] = {
+       GATE_CAM(CLK_CAM_LARB10, "camsys_larb10", "cam_sel", 0),
+       GATE_CAM(CLK_CAM_DFP_VAD, "camsys_dfp_vad", "cam_sel", 1),
+       GATE_CAM(CLK_CAM_LARB11, "camsys_larb11", "cam_sel", 2),
+       GATE_CAM(CLK_CAM_LARB9, "camsys_larb9", "cam_sel", 3),
+       GATE_CAM(CLK_CAM_CAM, "camsys_cam", "cam_sel", 6),
+       GATE_CAM(CLK_CAM_CAMTG, "camsys_camtg", "cam_sel", 7),
+       GATE_CAM(CLK_CAM_SENINF, "camsys_seninf", "cam_sel", 8),
+       GATE_CAM(CLK_CAM_CAMSV0, "camsys_camsv0", "cam_sel", 9),
+       GATE_CAM(CLK_CAM_CAMSV1, "camsys_camsv1", "cam_sel", 10),
+       GATE_CAM(CLK_CAM_CAMSV2, "camsys_camsv2", "cam_sel", 11),
+       GATE_CAM(CLK_CAM_CAMSV3, "camsys_camsv3", "cam_sel", 12),
+       GATE_CAM(CLK_CAM_CCU, "camsys_ccu", "cam_sel", 13),
+       GATE_CAM(CLK_CAM_FAKE_ENG, "camsys_fake_eng", "cam_sel", 14),
+};
+
+static const struct of_device_id of_match_clk_mt6779_cam[] = {
+       { .compatible = "mediatek,mt6779-camsys", },
+       {}
+};
+
+static int clk_mt6779_cam_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_CAM_NR_CLK);
+
+       mtk_clk_register_gates(node, cam_clks, ARRAY_SIZE(cam_clks),
+                              clk_data);
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static struct platform_driver clk_mt6779_cam_drv = {
+       .probe = clk_mt6779_cam_probe,
+       .driver = {
+               .name = "clk-mt6779-cam",
+               .of_match_table = of_match_clk_mt6779_cam,
+       },
+};
+
+builtin_platform_driver(clk_mt6779_cam_drv);
diff --git a/drivers/clk/mediatek/clk-mt6779-img.c b/drivers/clk/mediatek/clk-mt6779-img.c
new file mode 100644 (file)
index 0000000..26292a4
--- /dev/null
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Wendell Lin <wendell.lin@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/mt6779-clk.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+static const struct mtk_gate_regs img_cg_regs = {
+       .set_ofs = 0x0004,
+       .clr_ofs = 0x0008,
+       .sta_ofs = 0x0000,
+};
+
+#define GATE_IMG(_id, _name, _parent, _shift)                  \
+       GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift,     \
+               &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate img_clks[] = {
+       GATE_IMG(CLK_IMG_LARB5, "imgsys_larb5", "img_sel", 0),
+       GATE_IMG(CLK_IMG_LARB6, "imgsys_larb6", "img_sel", 1),
+       GATE_IMG(CLK_IMG_DIP, "imgsys_dip", "img_sel", 2),
+       GATE_IMG(CLK_IMG_MFB, "imgsys_mfb", "img_sel", 6),
+       GATE_IMG(CLK_IMG_WPE_A, "imgsys_wpe_a", "img_sel", 7),
+};
+
+static const struct of_device_id of_match_clk_mt6779_img[] = {
+       { .compatible = "mediatek,mt6779-imgsys", },
+       {}
+};
+
+static int clk_mt6779_img_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
+
+       mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
+                              clk_data);
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static struct platform_driver clk_mt6779_img_drv = {
+       .probe = clk_mt6779_img_probe,
+       .driver = {
+               .name = "clk-mt6779-img",
+               .of_match_table = of_match_clk_mt6779_img,
+       },
+};
+
+builtin_platform_driver(clk_mt6779_img_drv);
diff --git a/drivers/clk/mediatek/clk-mt6779-ipe.c b/drivers/clk/mediatek/clk-mt6779-ipe.c
new file mode 100644 (file)
index 0000000..bb51907
--- /dev/null
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Wendell Lin <wendell.lin@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/mt6779-clk.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+static const struct mtk_gate_regs ipe_cg_regs = {
+       .set_ofs = 0x0004,
+       .clr_ofs = 0x0008,
+       .sta_ofs = 0x0000,
+};
+
+#define GATE_IPE(_id, _name, _parent, _shift)                  \
+       GATE_MTK(_id, _name, _parent, &ipe_cg_regs, _shift,     \
+               &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate ipe_clks[] = {
+       GATE_IPE(CLK_IPE_LARB7, "ipe_larb7", "ipe_sel", 0),
+       GATE_IPE(CLK_IPE_LARB8, "ipe_larb8", "ipe_sel", 1),
+       GATE_IPE(CLK_IPE_SMI_SUBCOM, "ipe_smi_subcom", "ipe_sel", 2),
+       GATE_IPE(CLK_IPE_FD, "ipe_fd", "ipe_sel", 3),
+       GATE_IPE(CLK_IPE_FE, "ipe_fe", "ipe_sel", 4),
+       GATE_IPE(CLK_IPE_RSC, "ipe_rsc", "ipe_sel", 5),
+       GATE_IPE(CLK_IPE_DPE, "ipe_dpe", "ipe_sel", 6),
+};
+
+static const struct of_device_id of_match_clk_mt6779_ipe[] = {
+       { .compatible = "mediatek,mt6779-ipesys", },
+       {}
+};
+
+static int clk_mt6779_ipe_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_IPE_NR_CLK);
+
+       mtk_clk_register_gates(node, ipe_clks, ARRAY_SIZE(ipe_clks),
+                              clk_data);
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static struct platform_driver clk_mt6779_ipe_drv = {
+       .probe = clk_mt6779_ipe_probe,
+       .driver = {
+               .name = "clk-mt6779-ipe",
+               .of_match_table = of_match_clk_mt6779_ipe,
+       },
+};
+
+builtin_platform_driver(clk_mt6779_ipe_drv);
diff --git a/drivers/clk/mediatek/clk-mt6779-mfg.c b/drivers/clk/mediatek/clk-mt6779-mfg.c
new file mode 100644 (file)
index 0000000..c6ee2a8
--- /dev/null
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Wendell Lin <wendell.lin@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6779-clk.h>
+
+static const struct mtk_gate_regs mfg_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_MFG(_id, _name, _parent, _shift)                  \
+       GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift,     \
+               &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate mfg_clks[] = {
+       GATE_MFG(CLK_MFGCFG_BG3D, "mfg_bg3d", "mfg_sel", 0),
+};
+
+static int clk_mt6779_mfg_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_MFGCFG_NR_CLK);
+
+       mtk_clk_register_gates(node, mfg_clks, ARRAY_SIZE(mfg_clks),
+                              clk_data);
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static const struct of_device_id of_match_clk_mt6779_mfg[] = {
+       { .compatible = "mediatek,mt6779-mfgcfg", },
+       {}
+};
+
+static struct platform_driver clk_mt6779_mfg_drv = {
+       .probe = clk_mt6779_mfg_probe,
+       .driver = {
+               .name = "clk-mt6779-mfg",
+               .of_match_table = of_match_clk_mt6779_mfg,
+       },
+};
+
+builtin_platform_driver(clk_mt6779_mfg_drv);
diff --git a/drivers/clk/mediatek/clk-mt6779-mm.c b/drivers/clk/mediatek/clk-mt6779-mm.c
new file mode 100644 (file)
index 0000000..fb5fbb8
--- /dev/null
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Wendell Lin <wendell.lin@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/mt6779-clk.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+static const struct mtk_gate_regs mm0_cg_regs = {
+       .set_ofs = 0x0104,
+       .clr_ofs = 0x0108,
+       .sta_ofs = 0x0100,
+};
+
+static const struct mtk_gate_regs mm1_cg_regs = {
+       .set_ofs = 0x0114,
+       .clr_ofs = 0x0118,
+       .sta_ofs = 0x0110,
+};
+
+#define GATE_MM0(_id, _name, _parent, _shift)                  \
+       GATE_MTK(_id, _name, _parent, &mm0_cg_regs, _shift,     \
+               &mtk_clk_gate_ops_setclr)
+#define GATE_MM1(_id, _name, _parent, _shift)                  \
+       GATE_MTK(_id, _name, _parent, &mm1_cg_regs, _shift,     \
+               &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate mm_clks[] = {
+       /* MM0 */
+       GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0),
+       GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
+       GATE_MM0(CLK_MM_SMI_LARB1, "mm_smi_larb1", "mm_sel", 2),
+       GATE_MM0(CLK_MM_GALS_COMM0, "mm_gals_comm0", "mm_sel", 3),
+       GATE_MM0(CLK_MM_GALS_COMM1, "mm_gals_comm1", "mm_sel", 4),
+       GATE_MM0(CLK_MM_GALS_CCU2MM, "mm_gals_ccu2mm", "mm_sel", 5),
+       GATE_MM0(CLK_MM_GALS_IPU12MM, "mm_gals_ipu12mm", "mm_sel", 6),
+       GATE_MM0(CLK_MM_GALS_IMG2MM, "mm_gals_img2mm", "mm_sel", 7),
+       GATE_MM0(CLK_MM_GALS_CAM2MM, "mm_gals_cam2mm", "mm_sel", 8),
+       GATE_MM0(CLK_MM_GALS_IPU2MM, "mm_gals_ipu2mm", "mm_sel", 9),
+       GATE_MM0(CLK_MM_MDP_DL_TXCK, "mm_mdp_dl_txck", "mm_sel", 10),
+       GATE_MM0(CLK_MM_IPU_DL_TXCK, "mm_ipu_dl_txck", "mm_sel", 11),
+       GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 12),
+       GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 13),
+       GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 14),
+       GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 15),
+       GATE_MM0(CLK_MM_MDP_TDSHP, "mm_mdp_tdshp", "mm_sel", 16),
+       GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 17),
+       GATE_MM0(CLK_MM_MDP_WROT1, "mm_mdp_wrot1", "mm_sel", 18),
+       GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 19),
+       GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 20),
+       GATE_MM0(CLK_MM_DISP_OVL0_2L, "mm_disp_ovl0_2l", "mm_sel", 21),
+       GATE_MM0(CLK_MM_DISP_OVL1_2L, "mm_disp_ovl1_2l", "mm_sel", 22),
+       GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 23),
+       GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 24),
+       GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 25),
+       GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_sel", 26),
+       GATE_MM0(CLK_MM_DISP_CCORR0, "mm_disp_ccorr0", "mm_sel", 27),
+       GATE_MM0(CLK_MM_DISP_AAL0, "mm_disp_aal0", "mm_sel", 28),
+       GATE_MM0(CLK_MM_DISP_GAMMA0, "mm_disp_gamma0", "mm_sel", 29),
+       GATE_MM0(CLK_MM_DISP_DITHER0, "mm_disp_dither0", "mm_sel", 30),
+       GATE_MM0(CLK_MM_DISP_SPLIT, "mm_disp_split", "mm_sel", 31),
+       /* MM1 */
+       GATE_MM1(CLK_MM_DSI0_MM_CK, "mm_dsi0_mmck", "mm_sel", 0),
+       GATE_MM1(CLK_MM_DSI0_IF_CK, "mm_dsi0_ifck", "mm_sel", 1),
+       GATE_MM1(CLK_MM_DPI_MM_CK, "mm_dpi_mmck", "mm_sel", 2),
+       GATE_MM1(CLK_MM_DPI_IF_CK, "mm_dpi_ifck", "dpi0_sel", 3),
+       GATE_MM1(CLK_MM_FAKE_ENG2, "mm_fake_eng2", "mm_sel", 4),
+       GATE_MM1(CLK_MM_MDP_DL_RX_CK, "mm_mdp_dl_rxck", "mm_sel", 5),
+       GATE_MM1(CLK_MM_IPU_DL_RX_CK, "mm_ipu_dl_rxck", "mm_sel", 6),
+       GATE_MM1(CLK_MM_26M, "mm_26m", "f_f26m_ck", 7),
+       GATE_MM1(CLK_MM_MM_R2Y, "mm_mmsys_r2y", "mm_sel", 8),
+       GATE_MM1(CLK_MM_DISP_RSZ, "mm_disp_rsz", "mm_sel", 9),
+       GATE_MM1(CLK_MM_MDP_AAL, "mm_mdp_aal", "mm_sel", 10),
+       GATE_MM1(CLK_MM_MDP_HDR, "mm_mdp_hdr", "mm_sel", 11),
+       GATE_MM1(CLK_MM_DBI_MM_CK, "mm_dbi_mmck", "mm_sel", 12),
+       GATE_MM1(CLK_MM_DBI_IF_CK, "mm_dbi_ifck", "dpi0_sel", 13),
+       GATE_MM1(CLK_MM_DISP_POSTMASK0, "mm_disp_pm0", "mm_sel", 14),
+       GATE_MM1(CLK_MM_DISP_HRT_BW, "mm_disp_hrt_bw", "mm_sel", 15),
+       GATE_MM1(CLK_MM_DISP_OVL_FBDC, "mm_disp_ovl_fbdc", "mm_sel", 16),
+};
+
+static const struct of_device_id of_match_clk_mt6779_mm[] = {
+       { .compatible = "mediatek,mt6779-mmsys", },
+       {}
+};
+
+static int clk_mt6779_mm_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
+
+       mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
+                              clk_data);
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static struct platform_driver clk_mt6779_mm_drv = {
+       .probe = clk_mt6779_mm_probe,
+       .driver = {
+               .name = "clk-mt6779-mm",
+               .of_match_table = of_match_clk_mt6779_mm,
+       },
+};
+
+builtin_platform_driver(clk_mt6779_mm_drv);
diff --git a/drivers/clk/mediatek/clk-mt6779-vdec.c b/drivers/clk/mediatek/clk-mt6779-vdec.c
new file mode 100644 (file)
index 0000000..1900da2
--- /dev/null
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Wendell Lin <wendell.lin@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6779-clk.h>
+
+static const struct mtk_gate_regs vdec0_cg_regs = {
+       .set_ofs = 0x0000,
+       .clr_ofs = 0x0004,
+       .sta_ofs = 0x0000,
+};
+
+static const struct mtk_gate_regs vdec1_cg_regs = {
+       .set_ofs = 0x0008,
+       .clr_ofs = 0x000c,
+       .sta_ofs = 0x0008,
+};
+
+#define GATE_VDEC0_I(_id, _name, _parent, _shift)              \
+       GATE_MTK(_id, _name, _parent, &vdec0_cg_regs, _shift,   \
+               &mtk_clk_gate_ops_setclr_inv)
+#define GATE_VDEC1_I(_id, _name, _parent, _shift)              \
+       GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift,   \
+               &mtk_clk_gate_ops_setclr_inv)
+
+static const struct mtk_gate vdec_clks[] = {
+       /* VDEC0 */
+       GATE_VDEC0_I(CLK_VDEC_VDEC, "vdec_cken", "vdec_sel", 0),
+       /* VDEC1 */
+       GATE_VDEC1_I(CLK_VDEC_LARB1, "vdec_larb1_cken", "vdec_sel", 0),
+};
+
+static const struct of_device_id of_match_clk_mt6779_vdec[] = {
+       { .compatible = "mediatek,mt6779-vdecsys", },
+       {}
+};
+
+static int clk_mt6779_vdec_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_VDEC_GCON_NR_CLK);
+
+       mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
+                              clk_data);
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static struct platform_driver clk_mt6779_vdec_drv = {
+       .probe = clk_mt6779_vdec_probe,
+       .driver = {
+               .name = "clk-mt6779-vdec",
+               .of_match_table = of_match_clk_mt6779_vdec,
+       },
+};
+
+builtin_platform_driver(clk_mt6779_vdec_drv);
diff --git a/drivers/clk/mediatek/clk-mt6779-venc.c b/drivers/clk/mediatek/clk-mt6779-venc.c
new file mode 100644 (file)
index 0000000..b41d1f8
--- /dev/null
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Wendell Lin <wendell.lin@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6779-clk.h>
+
+static const struct mtk_gate_regs venc_cg_regs = {
+       .set_ofs = 0x0004,
+       .clr_ofs = 0x0008,
+       .sta_ofs = 0x0000,
+};
+
+#define GATE_VENC_I(_id, _name, _parent, _shift)               \
+       GATE_MTK(_id, _name, _parent, &venc_cg_regs, _shift,    \
+               &mtk_clk_gate_ops_setclr_inv)
+
+static const struct mtk_gate venc_clks[] = {
+       GATE_VENC_I(CLK_VENC_GCON_LARB, "venc_larb", "venc_sel", 0),
+       GATE_VENC_I(CLK_VENC_GCON_VENC, "venc_venc", "venc_sel", 4),
+       GATE_VENC_I(CLK_VENC_GCON_JPGENC, "venc_jpgenc", "venc_sel", 8),
+       GATE_VENC_I(CLK_VENC_GCON_GALS, "venc_gals", "venc_sel", 28),
+};
+
+static const struct of_device_id of_match_clk_mt6779_venc[] = {
+       { .compatible = "mediatek,mt6779-vencsys", },
+       {}
+};
+
+static int clk_mt6779_venc_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_VENC_GCON_NR_CLK);
+
+       mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
+                              clk_data);
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static struct platform_driver clk_mt6779_venc_drv = {
+       .probe = clk_mt6779_venc_probe,
+       .driver = {
+               .name = "clk-mt6779-venc",
+               .of_match_table = of_match_clk_mt6779_venc,
+       },
+};
+
+builtin_platform_driver(clk_mt6779_venc_drv);
diff --git a/drivers/clk/mediatek/clk-mt6779.c b/drivers/clk/mediatek/clk-mt6779.c
new file mode 100644 (file)
index 0000000..608a9a6
--- /dev/null
@@ -0,0 +1,1315 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Wendell Lin <wendell.lin@mediatek.com>
+ */
+
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-mux.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt6779-clk.h>
+
+static DEFINE_SPINLOCK(mt6779_clk_lock);
+
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+       FIXED_CLK(CLK_TOP_CLK26M, "f_f26m_ck", "clk26m", 26000000),
+};
+
+static const struct mtk_fixed_factor top_divs[] = {
+       FACTOR(CLK_TOP_CLK13M, "clk13m", "clk26m", 1, 2),
+       FACTOR(CLK_TOP_F26M_CK_D2, "csw_f26m_ck_d2", "clk26m", 1, 2),
+       FACTOR(CLK_TOP_MAINPLL_CK, "mainpll_ck", "mainpll", 1, 1),
+       FACTOR(CLK_TOP_MAINPLL_D2, "mainpll_d2", "mainpll_ck", 1, 2),
+       FACTOR(CLK_TOP_MAINPLL_D2_D2, "mainpll_d2_d2", "mainpll_d2", 1, 2),
+       FACTOR(CLK_TOP_MAINPLL_D2_D4, "mainpll_d2_d4", "mainpll_d2", 1, 4),
+       FACTOR(CLK_TOP_MAINPLL_D2_D8, "mainpll_d2_d8", "mainpll_d2", 1, 8),
+       FACTOR(CLK_TOP_MAINPLL_D2_D16, "mainpll_d2_d16", "mainpll_d2", 1, 16),
+       FACTOR(CLK_TOP_MAINPLL_D3, "mainpll_d3", "mainpll", 1, 3),
+       FACTOR(CLK_TOP_MAINPLL_D3_D2, "mainpll_d3_d2", "mainpll_d3", 1, 2),
+       FACTOR(CLK_TOP_MAINPLL_D3_D4, "mainpll_d3_d4", "mainpll_d3", 1, 4),
+       FACTOR(CLK_TOP_MAINPLL_D3_D8, "mainpll_d3_d8", "mainpll_d3", 1, 8),
+       FACTOR(CLK_TOP_MAINPLL_D5, "mainpll_d5", "mainpll", 1, 5),
+       FACTOR(CLK_TOP_MAINPLL_D5_D2, "mainpll_d5_d2", "mainpll_d5", 1, 2),
+       FACTOR(CLK_TOP_MAINPLL_D5_D4, "mainpll_d5_d4", "mainpll_d5", 1, 4),
+       FACTOR(CLK_TOP_MAINPLL_D7, "mainpll_d7", "mainpll", 1, 7),
+       FACTOR(CLK_TOP_MAINPLL_D7_D2, "mainpll_d7_d2", "mainpll_d7", 1, 2),
+       FACTOR(CLK_TOP_MAINPLL_D7_D4, "mainpll_d7_d4", "mainpll_d7", 1, 4),
+       FACTOR(CLK_TOP_UNIVPLL_CK, "univpll", "univ2pll", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL_D2_D2, "univpll_d2_d2", "univpll_d2", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL_D2_D4, "univpll_d2_d4", "univpll_d2", 1, 4),
+       FACTOR(CLK_TOP_UNIVPLL_D2_D8, "univpll_d2_d8", "univpll_d2", 1, 8),
+       FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
+       FACTOR(CLK_TOP_UNIVPLL_D3_D2, "univpll_d3_d2", "univpll_d3", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL_D3_D4, "univpll_d3_d4", "univpll_d3", 1, 4),
+       FACTOR(CLK_TOP_UNIVPLL_D3_D8, "univpll_d3_d8", "univpll_d3", 1, 8),
+       FACTOR(CLK_TOP_UNIVPLL_D3_D16, "univpll_d3_d16", "univpll_d3", 1, 16),
+       FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
+       FACTOR(CLK_TOP_UNIVPLL_D5_D2, "univpll_d5_d2", "univpll_d5", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL_D5_D4, "univpll_d5_d4", "univpll_d5", 1, 4),
+       FACTOR(CLK_TOP_UNIVPLL_D5_D8, "univpll_d5_d8", "univpll_d5", 1, 8),
+       FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7),
+       FACTOR(CLK_TOP_UNIVP_192M_CK, "univpll_192m_ck", "univ2pll", 1, 13),
+       FACTOR(CLK_TOP_UNIVP_192M_D2, "univpll_192m_d2", "univpll_192m_ck",
+              1, 2),
+       FACTOR(CLK_TOP_UNIVP_192M_D4, "univpll_192m_d4", "univpll_192m_ck",
+              1, 4),
+       FACTOR(CLK_TOP_UNIVP_192M_D8, "univpll_192m_d8", "univpll_192m_ck",
+              1, 8),
+       FACTOR(CLK_TOP_UNIVP_192M_D16, "univpll_192m_d16", "univpll_192m_ck",
+              1, 16),
+       FACTOR(CLK_TOP_UNIVP_192M_D32, "univpll_192m_d32", "univpll_192m_ck",
+              1, 32),
+       FACTOR(CLK_TOP_APLL1_CK, "apll1_ck", "apll1", 1, 1),
+       FACTOR(CLK_TOP_APLL1_D2, "apll1_d2", "apll1", 1, 2),
+       FACTOR(CLK_TOP_APLL1_D4, "apll1_d4", "apll1", 1, 4),
+       FACTOR(CLK_TOP_APLL1_D8, "apll1_d8", "apll1", 1, 8),
+       FACTOR(CLK_TOP_APLL2_CK, "apll2_ck", "apll2", 1, 1),
+       FACTOR(CLK_TOP_APLL2_D2, "apll2_d2", "apll2", 1, 2),
+       FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2", 1, 4),
+       FACTOR(CLK_TOP_APLL2_D8, "apll2_d8", "apll2", 1, 8),
+       FACTOR(CLK_TOP_TVDPLL_CK, "tvdpll_ck", "tvdpll", 1, 1),
+       FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll_ck", 1, 2),
+       FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4),
+       FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll", 1, 8),
+       FACTOR(CLK_TOP_TVDPLL_D16, "tvdpll_d16", "tvdpll", 1, 16),
+       FACTOR(CLK_TOP_MMPLL_CK, "mmpll_ck", "mmpll", 1, 1),
+       FACTOR(CLK_TOP_MMPLL_D4, "mmpll_d4", "mmpll", 1, 4),
+       FACTOR(CLK_TOP_MMPLL_D4_D2, "mmpll_d4_d2", "mmpll_d4", 1, 2),
+       FACTOR(CLK_TOP_MMPLL_D4_D4, "mmpll_d4_d4", "mmpll_d4", 1, 4),
+       FACTOR(CLK_TOP_MMPLL_D5, "mmpll_d5", "mmpll", 1, 5),
+       FACTOR(CLK_TOP_MMPLL_D5_D2, "mmpll_d5_d2", "mmpll_d5", 1, 2),
+       FACTOR(CLK_TOP_MMPLL_D5_D4, "mmpll_d5_d4", "mmpll_d5", 1, 4),
+       FACTOR(CLK_TOP_MMPLL_D6, "mmpll_d6", "mmpll", 1, 6),
+       FACTOR(CLK_TOP_MMPLL_D7, "mmpll_d7", "mmpll", 1, 7),
+       FACTOR(CLK_TOP_MFGPLL_CK, "mfgpll_ck", "mfgpll", 1, 1),
+       FACTOR(CLK_TOP_ADSPPLL_CK, "adsppll_ck", "adsppll", 1, 1),
+       FACTOR(CLK_TOP_ADSPPLL_D4, "adsppll_d4", "adsppll", 1, 4),
+       FACTOR(CLK_TOP_ADSPPLL_D5, "adsppll_d5", "adsppll", 1, 5),
+       FACTOR(CLK_TOP_ADSPPLL_D6, "adsppll_d6", "adsppll", 1, 6),
+       FACTOR(CLK_TOP_MSDCPLL_CK, "msdcpll_ck", "msdcpll", 1, 1),
+       FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
+       FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4),
+       FACTOR(CLK_TOP_MSDCPLL_D8, "msdcpll_d8", "msdcpll", 1, 8),
+       FACTOR(CLK_TOP_MSDCPLL_D16, "msdcpll_d16", "msdcpll", 1, 16),
+       FACTOR(CLK_TOP_AD_OSC_CK, "ad_osc_ck", "osc", 1, 1),
+       FACTOR(CLK_TOP_OSC_D2, "osc_d2", "osc", 1, 2),
+       FACTOR(CLK_TOP_OSC_D4, "osc_d4", "osc", 1, 4),
+       FACTOR(CLK_TOP_OSC_D8, "osc_d8", "osc", 1, 8),
+       FACTOR(CLK_TOP_OSC_D10, "osc_d10", "osc", 1, 10),
+       FACTOR(CLK_TOP_OSC_D16, "osc_d16", "osc", 1, 16),
+       FACTOR(CLK_TOP_AD_OSC2_CK, "ad_osc2_ck", "osc2", 1, 1),
+       FACTOR(CLK_TOP_OSC2_D2, "osc2_d2", "osc2", 1, 2),
+       FACTOR(CLK_TOP_OSC2_D3, "osc2_d3", "osc2", 1, 3),
+       FACTOR(CLK_TOP_TVDPLL_MAINPLL_D2_CK, "tvdpll_mainpll_d2_ck",
+              "tvdpll", 1, 1),
+       FACTOR(CLK_TOP_FMEM_466M_CK, "fmem_466m_ck", "fmem", 1, 1),
+};
+
+static const char * const axi_parents[] = {
+       "clk26m",
+       "mainpll_d2_d4",
+       "mainpll_d7",
+       "osc_d4"
+};
+
+static const char * const mm_parents[] = {
+       "clk26m",
+       "tvdpll_mainpll_d2_ck",
+       "mmpll_d7",
+       "mmpll_d5_d2",
+       "mainpll_d2_d2",
+       "mainpll_d3_d2"
+};
+
+static const char * const scp_parents[] = {
+       "clk26m",
+       "univpll_d2_d8",
+       "mainpll_d2_d4",
+       "mainpll_d3",
+       "univpll_d3",
+       "ad_osc2_ck",
+       "osc2_d2",
+       "osc2_d3"
+};
+
+static const char * const img_parents[] = {
+       "clk26m",
+       "mainpll_d2",
+       "mainpll_d2",
+       "univpll_d3",
+       "mainpll_d3",
+       "mmpll_d5_d2",
+       "tvdpll_mainpll_d2_ck",
+       "mainpll_d5"
+};
+
+static const char * const ipe_parents[] = {
+       "clk26m",
+       "mainpll_d2",
+       "mmpll_d7",
+       "univpll_d3",
+       "mainpll_d3",
+       "mmpll_d5_d2",
+       "mainpll_d2_d2",
+       "mainpll_d5"
+};
+
+static const char * const dpe_parents[] = {
+       "clk26m",
+       "mainpll_d2",
+       "mmpll_d7",
+       "univpll_d3",
+       "mainpll_d3",
+       "mmpll_d5_d2",
+       "mainpll_d2_d2",
+       "mainpll_d5"
+};
+
+static const char * const cam_parents[] = {
+       "clk26m",
+       "mainpll_d2",
+       "mmpll_d6",
+       "mainpll_d3",
+       "mmpll_d7",
+       "univpll_d3",
+       "mmpll_d5_d2",
+       "adsppll_d5",
+       "tvdpll_mainpll_d2_ck",
+       "univpll_d3_d2"
+};
+
+static const char * const ccu_parents[] = {
+       "clk26m",
+       "mainpll_d2",
+       "mmpll_d6",
+       "mainpll_d3",
+       "mmpll_d7",
+       "univpll_d3",
+       "mmpll_d5_d2",
+       "mainpll_d2_d2",
+       "adsppll_d5",
+       "univpll_d3_d2"
+};
+
+static const char * const dsp_parents[] = {
+       "clk26m",
+       "univpll_d3_d8",
+       "univpll_d3_d4",
+       "mainpll_d2_d4",
+       "univpll_d3_d2",
+       "mainpll_d2_d2",
+       "univpll_d2_d2",
+       "mainpll_d3",
+       "univpll_d3",
+       "mmpll_d7",
+       "mmpll_d6",
+       "adsppll_d5",
+       "tvdpll_ck",
+       "tvdpll_mainpll_d2_ck",
+       "univpll_d2",
+       "adsppll_d4"
+};
+
+static const char * const dsp1_parents[] = {
+       "clk26m",
+       "univpll_d3_d8",
+       "univpll_d3_d4",
+       "mainpll_d2_d4",
+       "univpll_d3_d2",
+       "mainpll_d2_d2",
+       "univpll_d2_d2",
+       "mainpll_d3",
+       "univpll_d3",
+       "mmpll_d7",
+       "mmpll_d6",
+       "adsppll_d5",
+       "tvdpll_ck",
+       "tvdpll_mainpll_d2_ck",
+       "univpll_d2",
+       "adsppll_d4"
+};
+
+static const char * const dsp2_parents[] = {
+       "clk26m",
+       "univpll_d3_d8",
+       "univpll_d3_d4",
+       "mainpll_d2_d4",
+       "univpll_d3_d2",
+       "mainpll_d2_d2",
+       "univpll_d2_d2",
+       "mainpll_d3",
+       "univpll_d3",
+       "mmpll_d7",
+       "mmpll_d6",
+       "adsppll_d5",
+       "tvdpll_ck",
+       "tvdpll_mainpll_d2_ck",
+       "univpll_d2",
+       "adsppll_d4"
+};
+
+static const char * const dsp3_parents[] = {
+       "clk26m",
+       "univpll_d3_d8",
+       "mainpll_d2_d4",
+       "univpll_d3_d2",
+       "mainpll_d2_d2",
+       "univpll_d2_d2",
+       "mainpll_d3",
+       "univpll_d3",
+       "mmpll_d7",
+       "mmpll_d6",
+       "mainpll_d2",
+       "tvdpll_ck",
+       "tvdpll_mainpll_d2_ck",
+       "univpll_d2",
+       "adsppll_d4",
+       "mmpll_d4"
+};
+
+static const char * const ipu_if_parents[] = {
+       "clk26m",
+       "univpll_d3_d8",
+       "univpll_d3_d4",
+       "mainpll_d2_d4",
+       "univpll_d3_d2",
+       "mainpll_d2_d2",
+       "univpll_d2_d2",
+       "mainpll_d3",
+       "univpll_d3",
+       "mmpll_d7",
+       "mmpll_d6",
+       "adsppll_d5",
+       "tvdpll_ck",
+       "tvdpll_mainpll_d2_ck",
+       "univpll_d2",
+       "adsppll_d4"
+};
+
+static const char * const mfg_parents[] = {
+       "clk26m",
+       "mfgpll_ck",
+       "univpll_d3",
+       "mainpll_d5"
+};
+
+static const char * const f52m_mfg_parents[] = {
+       "clk26m",
+       "univpll_d3_d2",
+       "univpll_d3_d4",
+       "univpll_d3_d8"
+};
+
+static const char * const camtg_parents[] = {
+       "clk26m",
+       "univpll_192m_d8",
+       "univpll_d3_d8",
+       "univpll_192m_d4",
+       "univpll_d3_d16",
+       "csw_f26m_ck_d2",
+       "univpll_192m_d16",
+       "univpll_192m_d32"
+};
+
+static const char * const camtg2_parents[] = {
+       "clk26m",
+       "univpll_192m_d8",
+       "univpll_d3_d8",
+       "univpll_192m_d4",
+       "univpll_d3_d16",
+       "csw_f26m_ck_d2",
+       "univpll_192m_d16",
+       "univpll_192m_d32"
+};
+
+static const char * const camtg3_parents[] = {
+       "clk26m",
+       "univpll_192m_d8",
+       "univpll_d3_d8",
+       "univpll_192m_d4",
+       "univpll_d3_d16",
+       "csw_f26m_ck_d2",
+       "univpll_192m_d16",
+       "univpll_192m_d32"
+};
+
+static const char * const camtg4_parents[] = {
+       "clk26m",
+       "univpll_192m_d8",
+       "univpll_d3_d8",
+       "univpll_192m_d4",
+       "univpll_d3_d16",
+       "csw_f26m_ck_d2",
+       "univpll_192m_d16",
+       "univpll_192m_d32"
+};
+
+static const char * const uart_parents[] = {
+       "clk26m",
+       "univpll_d3_d8"
+};
+
+static const char * const spi_parents[] = {
+       "clk26m",
+       "mainpll_d5_d2",
+       "mainpll_d3_d4",
+       "msdcpll_d4"
+};
+
+static const char * const msdc50_hclk_parents[] = {
+       "clk26m",
+       "mainpll_d2_d2",
+       "mainpll_d3_d2"
+};
+
+static const char * const msdc50_0_parents[] = {
+       "clk26m",
+       "msdcpll_ck",
+       "msdcpll_d2",
+       "univpll_d2_d4",
+       "mainpll_d3_d2",
+       "univpll_d2_d2"
+};
+
+static const char * const msdc30_1_parents[] = {
+       "clk26m",
+       "univpll_d3_d2",
+       "mainpll_d3_d2",
+       "mainpll_d7",
+       "msdcpll_d2"
+};
+
+static const char * const audio_parents[] = {
+       "clk26m",
+       "mainpll_d5_d4",
+       "mainpll_d7_d4",
+       "mainpll_d2_d16"
+};
+
+static const char * const aud_intbus_parents[] = {
+       "clk26m",
+       "mainpll_d2_d4",
+       "mainpll_d7_d2"
+};
+
+static const char * const fpwrap_ulposc_parents[] = {
+       "osc_d10",
+       "clk26m",
+       "osc_d4",
+       "osc_d8",
+       "osc_d16"
+};
+
+static const char * const atb_parents[] = {
+       "clk26m",
+       "mainpll_d2_d2",
+       "mainpll_d5"
+};
+
+static const char * const sspm_parents[] = {
+       "clk26m",
+       "univpll_d2_d4",
+       "mainpll_d2_d2",
+       "univpll_d2_d2",
+       "mainpll_d3"
+};
+
+static const char * const dpi0_parents[] = {
+       "clk26m",
+       "tvdpll_d2",
+       "tvdpll_d4",
+       "tvdpll_d8",
+       "tvdpll_d16"
+};
+
+static const char * const scam_parents[] = {
+       "clk26m",
+       "mainpll_d5_d2"
+};
+
+static const char * const disppwm_parents[] = {
+       "clk26m",
+       "univpll_d3_d4",
+       "osc_d2",
+       "osc_d4",
+       "osc_d16"
+};
+
+static const char * const usb_top_parents[] = {
+       "clk26m",
+       "univpll_d5_d4",
+       "univpll_d3_d4",
+       "univpll_d5_d2"
+};
+
+static const char * const ssusb_top_xhci_parents[] = {
+       "clk26m",
+       "univpll_d5_d4",
+       "univpll_d3_d4",
+       "univpll_d5_d2"
+};
+
+static const char * const spm_parents[] = {
+       "clk26m",
+       "osc_d8",
+       "mainpll_d2_d8"
+};
+
+static const char * const i2c_parents[] = {
+       "clk26m",
+       "mainpll_d2_d8",
+       "univpll_d5_d2"
+};
+
+static const char * const seninf_parents[] = {
+       "clk26m",
+       "univpll_d7",
+       "univpll_d3_d2",
+       "univpll_d2_d2",
+       "mainpll_d3",
+       "mmpll_d4_d2",
+       "mmpll_d7",
+       "mmpll_d6"
+};
+
+static const char * const seninf1_parents[] = {
+       "clk26m",
+       "univpll_d7",
+       "univpll_d3_d2",
+       "univpll_d2_d2",
+       "mainpll_d3",
+       "mmpll_d4_d2",
+       "mmpll_d7",
+       "mmpll_d6"
+};
+
+static const char * const seninf2_parents[] = {
+       "clk26m",
+       "univpll_d7",
+       "univpll_d3_d2",
+       "univpll_d2_d2",
+       "mainpll_d3",
+       "mmpll_d4_d2",
+       "mmpll_d7",
+       "mmpll_d6"
+};
+
+static const char * const dxcc_parents[] = {
+       "clk26m",
+       "mainpll_d2_d2",
+       "mainpll_d2_d4",
+       "mainpll_d2_d8"
+};
+
+static const char * const aud_engen1_parents[] = {
+       "clk26m",
+       "apll1_d2",
+       "apll1_d4",
+       "apll1_d8"
+};
+
+static const char * const aud_engen2_parents[] = {
+       "clk26m",
+       "apll2_d2",
+       "apll2_d4",
+       "apll2_d8"
+};
+
+static const char * const faes_ufsfde_parents[] = {
+       "clk26m",
+       "mainpll_d2",
+       "mainpll_d2_d2",
+       "mainpll_d3",
+       "mainpll_d2_d4",
+       "univpll_d3"
+};
+
+static const char * const fufs_parents[] = {
+       "clk26m",
+       "mainpll_d2_d4",
+       "mainpll_d2_d8",
+       "mainpll_d2_d16"
+};
+
+static const char * const aud_1_parents[] = {
+       "clk26m",
+       "apll1_ck"
+};
+
+static const char * const aud_2_parents[] = {
+       "clk26m",
+       "apll2_ck"
+};
+
+static const char * const adsp_parents[] = {
+       "clk26m",
+       "mainpll_d3",
+       "univpll_d2_d4",
+       "univpll_d2",
+       "mmpll_d4",
+       "adsppll_d4",
+       "adsppll_d6"
+};
+
+static const char * const dpmaif_parents[] = {
+       "clk26m",
+       "univpll_d2_d4",
+       "mainpll_d3",
+       "mainpll_d2_d2",
+       "univpll_d2_d2",
+       "univpll_d3"
+};
+
+static const char * const venc_parents[] = {
+       "clk26m",
+       "mmpll_d7",
+       "mainpll_d3",
+       "univpll_d2_d2",
+       "mainpll_d2_d2",
+       "univpll_d3",
+       "mmpll_d6",
+       "mainpll_d5",
+       "mainpll_d3_d2",
+       "mmpll_d4_d2",
+       "univpll_d2_d4",
+       "mmpll_d5",
+       "univpll_192m_d2"
+
+};
+
+static const char * const vdec_parents[] = {
+       "clk26m",
+       "univpll_d2_d4",
+       "mainpll_d3",
+       "univpll_d2_d2",
+       "mainpll_d2_d2",
+       "univpll_d3",
+       "univpll_d5",
+       "univpll_d5_d2",
+       "mainpll_d2",
+       "univpll_d2",
+       "univpll_192m_d2"
+};
+
+static const char * const camtm_parents[] = {
+       "clk26m",
+       "univpll_d7",
+       "univpll_d3_d2",
+       "univpll_d2_d2"
+};
+
+static const char * const pwm_parents[] = {
+       "clk26m",
+       "univpll_d2_d8"
+};
+
+static const char * const audio_h_parents[] = {
+       "clk26m",
+       "univpll_d7",
+       "apll1_ck",
+       "apll2_ck"
+};
+
+static const char * const camtg5_parents[] = {
+       "clk26m",
+       "univpll_192m_d8",
+       "univpll_d3_d8",
+       "univpll_192m_d4",
+       "univpll_d3_d16",
+       "csw_f26m_ck_d2",
+       "univpll_192m_d16",
+       "univpll_192m_d32"
+};
+
+/*
+ * CRITICAL CLOCK:
+ * axi_sel is the main bus clock of whole SOC.
+ * spm_sel is the clock of the always-on co-processor.
+ * sspm_sel is the clock of the always-on co-processor.
+ */
+static const struct mtk_mux top_muxes[] = {
+       /* CLK_CFG_0 */
+       MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_AXI, "axi_sel", axi_parents,
+                                  0x20, 0x24, 0x28, 0, 2, 7,
+                                  0x004, 0, CLK_IS_CRITICAL),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MM, "mm_sel", mm_parents,
+                            0x20, 0x24, 0x28, 8, 3, 15, 0x004, 1),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SCP, "scp_sel", scp_parents,
+                            0x20, 0x24, 0x28, 16, 3, 23, 0x004, 2),
+       /* CLK_CFG_1 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_IMG, "img_sel", img_parents,
+                            0x30, 0x34, 0x38, 0, 3, 7, 0x004, 4),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_IPE, "ipe_sel", ipe_parents,
+                            0x30, 0x34, 0x38, 8, 3, 15, 0x004, 5),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DPE, "dpe_sel", dpe_parents,
+                            0x30, 0x34, 0x38, 16, 3, 23, 0x004, 6),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAM, "cam_sel", cam_parents,
+                            0x30, 0x34, 0x38, 24, 4, 31, 0x004, 7),
+       /* CLK_CFG_2 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CCU, "ccu_sel", ccu_parents,
+                            0x40, 0x44, 0x48, 0, 4, 7, 0x004, 8),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP, "dsp_sel", dsp_parents,
+                            0x40, 0x44, 0x48, 8, 4, 15, 0x004, 9),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP1, "dsp1_sel", dsp1_parents,
+                            0x40, 0x44, 0x48, 16, 4, 23, 0x004, 10),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP2, "dsp2_sel", dsp2_parents,
+                            0x40, 0x44, 0x48, 24, 4, 31, 0x004, 11),
+       /* CLK_CFG_3 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP3, "dsp3_sel", dsp3_parents,
+                            0x50, 0x54, 0x58, 0, 4, 7, 0x004, 12),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_IPU_IF, "ipu_if_sel", ipu_if_parents,
+                            0x50, 0x54, 0x58, 8, 4, 15, 0x004, 13),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MFG, "mfg_sel", mfg_parents,
+                            0x50, 0x54, 0x58, 16, 2, 23, 0x004, 14),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_F52M_MFG, "f52m_mfg_sel",
+                            f52m_mfg_parents, 0x50, 0x54, 0x58,
+                            24, 2, 31, 0x004, 15),
+       /* CLK_CFG_4 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG, "camtg_sel", camtg_parents,
+                            0x60, 0x64, 0x68, 0, 3, 7, 0x004, 16),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG2, "camtg2_sel", camtg2_parents,
+                            0x60, 0x64, 0x68, 8, 3, 15, 0x004, 17),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG3, "camtg3_sel", camtg3_parents,
+                            0x60, 0x64, 0x68, 16, 3, 23, 0x004, 18),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG4, "camtg4_sel", camtg4_parents,
+                            0x60, 0x64, 0x68, 24, 3, 31, 0x004, 19),
+       /* CLK_CFG_5 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_UART, "uart_sel", uart_parents,
+                            0x70, 0x74, 0x78, 0, 1, 7, 0x004, 20),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI, "spi_sel", spi_parents,
+                            0x70, 0x74, 0x78, 8, 2, 15, 0x004, 21),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_HCLK, "msdc50_hclk_sel",
+                            msdc50_hclk_parents, 0x70, 0x74, 0x78,
+                            16, 2, 23, 0x004, 22),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0, "msdc50_0_sel",
+                            msdc50_0_parents, 0x70, 0x74, 0x78,
+                            24, 3, 31, 0x004, 23),
+       /* CLK_CFG_6 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_1, "msdc30_1_sel",
+                            msdc30_1_parents, 0x80, 0x84, 0x88,
+                            0, 3, 7, 0x004, 24),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD, "audio_sel", audio_parents,
+                            0x80, 0x84, 0x88, 8, 2, 15, 0x004, 25),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_INTBUS, "aud_intbus_sel",
+                            aud_intbus_parents, 0x80, 0x84, 0x88,
+                            16, 2, 23, 0x004, 26),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_FPWRAP_ULPOSC, "fpwrap_ulposc_sel",
+                            fpwrap_ulposc_parents, 0x80, 0x84, 0x88,
+                            24, 3, 31, 0x004, 27),
+       /* CLK_CFG_7 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_ATB, "atb_sel", atb_parents,
+                            0x90, 0x94, 0x98, 0, 2, 7, 0x004, 28),
+       MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SSPM, "sspm_sel", sspm_parents,
+                                  0x90, 0x94, 0x98, 8, 3, 15,
+                                  0x004, 29, CLK_IS_CRITICAL),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DPI0, "dpi0_sel", dpi0_parents,
+                            0x90, 0x94, 0x98, 16, 3, 23, 0x004, 30),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SCAM, "scam_sel", scam_parents,
+                            0x90, 0x94, 0x98, 24, 1, 31, 0x004, 0),
+       /* CLK_CFG_8 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP_PWM, "disppwm_sel",
+                            disppwm_parents, 0xa0, 0xa4, 0xa8,
+                            0, 3, 7, 0x008, 1),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_TOP, "usb_top_sel",
+                            usb_top_parents, 0xa0, 0xa4, 0xa8,
+                            8, 2, 15, 0x008, 2),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_TOP_XHCI, "ssusb_top_xhci_sel",
+                            ssusb_top_xhci_parents, 0xa0, 0xa4, 0xa8,
+                            16, 2, 23, 0x008, 3),
+       MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SPM, "spm_sel", spm_parents,
+                                  0xa0, 0xa4, 0xa8, 24, 2, 31,
+                                  0x008, 4, CLK_IS_CRITICAL),
+       /* CLK_CFG_9 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C, "i2c_sel", i2c_parents,
+                            0xb0, 0xb4, 0xb8, 0, 2, 7, 0x008, 5),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF, "seninf_sel", seninf_parents,
+                            0xb0, 0xb4, 0xb8, 8, 2, 15, 0x008, 6),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF1, "seninf1_sel",
+                            seninf1_parents, 0xb0, 0xb4, 0xb8,
+                            16, 2, 23, 0x008, 7),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF2, "seninf2_sel",
+                            seninf2_parents, 0xb0, 0xb4, 0xb8,
+                            24, 2, 31, 0x008, 8),
+       /* CLK_CFG_10 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DXCC, "dxcc_sel", dxcc_parents,
+                            0xc0, 0xc4, 0xc8, 0, 2, 7, 0x008, 9),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_ENG1, "aud_eng1_sel",
+                            aud_engen1_parents, 0xc0, 0xc4, 0xc8,
+                            8, 2, 15, 0x008, 10),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_ENG2, "aud_eng2_sel",
+                            aud_engen2_parents, 0xc0, 0xc4, 0xc8,
+                            16, 2, 23, 0x008, 11),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_FAES_UFSFDE, "faes_ufsfde_sel",
+                            faes_ufsfde_parents, 0xc0, 0xc4, 0xc8,
+                            24, 3, 31,
+                            0x008, 12),
+       /* CLK_CFG_11 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_FUFS, "fufs_sel", fufs_parents,
+                            0xd0, 0xd4, 0xd8, 0, 2, 7, 0x008, 13),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_1, "aud_1_sel", aud_1_parents,
+                            0xd0, 0xd4, 0xd8, 8, 1, 15, 0x008, 14),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_2, "aud_2_sel", aud_2_parents,
+                            0xd0, 0xd4, 0xd8, 16, 1, 23, 0x008, 15),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_ADSP, "adsp_sel", adsp_parents,
+                            0xd0, 0xd4, 0xd8, 24, 3, 31, 0x008, 16),
+       /* CLK_CFG_12 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DPMAIF, "dpmaif_sel", dpmaif_parents,
+                            0xe0, 0xe4, 0xe8, 0, 3, 7, 0x008, 17),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_VENC, "venc_sel", venc_parents,
+                            0xe0, 0xe4, 0xe8, 8, 4, 15, 0x008, 18),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_VDEC, "vdec_sel", vdec_parents,
+                            0xe0, 0xe4, 0xe8, 16, 4, 23, 0x008, 19),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTM, "camtm_sel", camtm_parents,
+                            0xe0, 0xe4, 0xe8, 24, 2, 31, 0x004, 20),
+       /* CLK_CFG_13 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM, "pwm_sel", pwm_parents,
+                            0xf0, 0xf4, 0xf8, 0, 1, 7, 0x008, 21),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_H, "audio_h_sel",
+                            audio_h_parents, 0xf0, 0xf4, 0xf8,
+                            8, 2, 15, 0x008, 22),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG5, "camtg5_sel", camtg5_parents,
+                            0xf0, 0xf4, 0xf8, 24, 3, 31, 0x008, 24),
+};
+
+static const char * const i2s0_m_ck_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+static const char * const i2s1_m_ck_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+static const char * const i2s2_m_ck_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+static const char * const i2s3_m_ck_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+static const char * const i2s4_m_ck_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+static const char * const i2s5_m_ck_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+static const struct mtk_composite top_aud_muxes[] = {
+       MUX(CLK_TOP_I2S0_M_SEL, "i2s0_m_ck_sel", i2s0_m_ck_parents,
+           0x320, 8, 1),
+       MUX(CLK_TOP_I2S1_M_SEL, "i2s1_m_ck_sel", i2s1_m_ck_parents,
+           0x320, 9, 1),
+       MUX(CLK_TOP_I2S2_M_SEL, "i2s2_m_ck_sel", i2s2_m_ck_parents,
+           0x320, 10, 1),
+       MUX(CLK_TOP_I2S3_M_SEL, "i2s3_m_ck_sel", i2s3_m_ck_parents,
+           0x320, 11, 1),
+       MUX(CLK_TOP_I2S4_M_SEL, "i2s4_m_ck_sel", i2s4_m_ck_parents,
+           0x320, 12, 1),
+       MUX(CLK_TOP_I2S5_M_SEL, "i2s5_m_ck_sel", i2s5_m_ck_parents,
+           0x328, 20, 1),
+};
+
+static struct mtk_composite top_aud_divs[] = {
+       DIV_GATE(CLK_TOP_APLL12_DIV0, "apll12_div0", "i2s0_m_ck_sel",
+                0x320, 2, 0x324, 8, 0),
+       DIV_GATE(CLK_TOP_APLL12_DIV1, "apll12_div1", "i2s1_m_ck_sel",
+                0x320, 3, 0x324, 8, 8),
+       DIV_GATE(CLK_TOP_APLL12_DIV2, "apll12_div2", "i2s2_m_ck_sel",
+                0x320, 4, 0x324, 8, 16),
+       DIV_GATE(CLK_TOP_APLL12_DIV3, "apll12_div3", "i2s3_m_ck_sel",
+                0x320, 5, 0x324, 8, 24),
+       DIV_GATE(CLK_TOP_APLL12_DIV4, "apll12_div4", "i2s4_m_ck_sel",
+                0x320, 6, 0x328, 8, 0),
+       DIV_GATE(CLK_TOP_APLL12_DIVB, "apll12_divb", "apll12_div4",
+                0x320, 7, 0x328, 8, 8),
+       DIV_GATE(CLK_TOP_APLL12_DIV5, "apll12_div5", "i2s5_m_ck_sel",
+                0x328, 16, 0x328, 4, 28),
+};
+
+static const struct mtk_gate_regs infra0_cg_regs = {
+       .set_ofs = 0x80,
+       .clr_ofs = 0x84,
+       .sta_ofs = 0x90,
+};
+
+static const struct mtk_gate_regs infra1_cg_regs = {
+       .set_ofs = 0x88,
+       .clr_ofs = 0x8c,
+       .sta_ofs = 0x94,
+};
+
+static const struct mtk_gate_regs infra2_cg_regs = {
+       .set_ofs = 0xa4,
+       .clr_ofs = 0xa8,
+       .sta_ofs = 0xac,
+};
+
+static const struct mtk_gate_regs infra3_cg_regs = {
+       .set_ofs = 0xc0,
+       .clr_ofs = 0xc4,
+       .sta_ofs = 0xc8,
+};
+
+#define GATE_INFRA0(_id, _name, _parent, _shift)               \
+       GATE_MTK(_id, _name, _parent, &infra0_cg_regs, _shift,  \
+               &mtk_clk_gate_ops_setclr)
+#define GATE_INFRA1(_id, _name, _parent, _shift)               \
+       GATE_MTK(_id, _name, _parent, &infra1_cg_regs, _shift,  \
+               &mtk_clk_gate_ops_setclr)
+#define GATE_INFRA2(_id, _name, _parent, _shift)               \
+       GATE_MTK(_id, _name, _parent, &infra2_cg_regs, _shift,  \
+               &mtk_clk_gate_ops_setclr)
+#define GATE_INFRA3(_id, _name, _parent, _shift)               \
+       GATE_MTK(_id, _name, _parent, &infra3_cg_regs, _shift,  \
+               &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate infra_clks[] = {
+       /* INFRA0 */
+       GATE_INFRA0(CLK_INFRA_PMIC_TMR, "infra_pmic_tmr",
+                   "axi_sel", 0),
+       GATE_INFRA0(CLK_INFRA_PMIC_AP, "infra_pmic_ap",
+                   "axi_sel", 1),
+       GATE_INFRA0(CLK_INFRA_PMIC_MD, "infra_pmic_md",
+                   "axi_sel", 2),
+       GATE_INFRA0(CLK_INFRA_PMIC_CONN, "infra_pmic_conn",
+                   "axi_sel", 3),
+       GATE_INFRA0(CLK_INFRA_SCPSYS, "infra_scp",
+                   "axi_sel", 4),
+       GATE_INFRA0(CLK_INFRA_SEJ, "infra_sej",
+                   "f_f26m_ck", 5),
+       GATE_INFRA0(CLK_INFRA_APXGPT, "infra_apxgpt",
+                   "axi_sel", 6),
+       GATE_INFRA0(CLK_INFRA_ICUSB, "infra_icusb",
+                   "axi_sel", 8),
+       GATE_INFRA0(CLK_INFRA_GCE, "infra_gce",
+                   "axi_sel", 9),
+       GATE_INFRA0(CLK_INFRA_THERM, "infra_therm",
+                   "axi_sel", 10),
+       GATE_INFRA0(CLK_INFRA_I2C0, "infra_i2c0",
+                   "i2c_sel", 11),
+       GATE_INFRA0(CLK_INFRA_I2C1, "infra_i2c1",
+                   "i2c_sel", 12),
+       GATE_INFRA0(CLK_INFRA_I2C2, "infra_i2c2",
+                   "i2c_sel", 13),
+       GATE_INFRA0(CLK_INFRA_I2C3, "infra_i2c3",
+                   "i2c_sel", 14),
+       GATE_INFRA0(CLK_INFRA_PWM_HCLK, "infra_pwm_hclk",
+                   "pwm_sel", 15),
+       GATE_INFRA0(CLK_INFRA_PWM1, "infra_pwm1",
+                   "pwm_sel", 16),
+       GATE_INFRA0(CLK_INFRA_PWM2, "infra_pwm2",
+                   "pwm_sel", 17),
+       GATE_INFRA0(CLK_INFRA_PWM3, "infra_pwm3",
+                   "pwm_sel", 18),
+       GATE_INFRA0(CLK_INFRA_PWM4, "infra_pwm4",
+                   "pwm_sel", 19),
+       GATE_INFRA0(CLK_INFRA_PWM, "infra_pwm",
+                   "pwm_sel", 21),
+       GATE_INFRA0(CLK_INFRA_UART1, "infra_uart1",
+                   "uart_sel", 23),
+       GATE_INFRA0(CLK_INFRA_UART2, "infra_uart2",
+                   "uart_sel", 24),
+       GATE_INFRA0(CLK_INFRA_UART3, "infra_uart3",
+                   "uart_sel", 25),
+       GATE_INFRA0(CLK_INFRA_GCE_26M, "infra_gce_26m",
+                   "axi_sel", 27),
+       GATE_INFRA0(CLK_INFRA_CQ_DMA_FPC, "infra_cqdma_fpc",
+                   "axi_sel", 28),
+       GATE_INFRA0(CLK_INFRA_BTIF, "infra_btif",
+                   "axi_sel", 31),
+       /* INFRA1 */
+       GATE_INFRA1(CLK_INFRA_SPI0, "infra_spi0",
+                   "spi_sel", 1),
+       GATE_INFRA1(CLK_INFRA_MSDC0, "infra_msdc0",
+                   "msdc50_hclk_sel", 2),
+       GATE_INFRA1(CLK_INFRA_MSDC1, "infra_msdc1",
+                   "axi_sel", 4),
+       GATE_INFRA1(CLK_INFRA_MSDC2, "infra_msdc2",
+                   "axi_sel", 5),
+       GATE_INFRA1(CLK_INFRA_MSDC0_SCK, "infra_msdc0_sck",
+                   "msdc50_0_sel", 6),
+       GATE_INFRA1(CLK_INFRA_DVFSRC, "infra_dvfsrc",
+                   "f_f26m_ck", 7),
+       GATE_INFRA1(CLK_INFRA_GCPU, "infra_gcpu",
+                   "axi_sel", 8),
+       GATE_INFRA1(CLK_INFRA_TRNG, "infra_trng",
+                   "axi_sel", 9),
+       GATE_INFRA1(CLK_INFRA_AUXADC, "infra_auxadc",
+                   "f_f26m_ck", 10),
+       GATE_INFRA1(CLK_INFRA_CPUM, "infra_cpum",
+                   "axi_sel", 11),
+       GATE_INFRA1(CLK_INFRA_CCIF1_AP, "infra_ccif1_ap",
+                   "axi_sel", 12),
+       GATE_INFRA1(CLK_INFRA_CCIF1_MD, "infra_ccif1_md",
+                   "axi_sel", 13),
+       GATE_INFRA1(CLK_INFRA_AUXADC_MD, "infra_auxadc_md",
+                   "f_f26m_ck", 14),
+       GATE_INFRA1(CLK_INFRA_MSDC1_SCK, "infra_msdc1_sck",
+                   "msdc30_1_sel", 16),
+       GATE_INFRA1(CLK_INFRA_MSDC2_SCK, "infra_msdc2_sck",
+                   "msdc30_2_sel", 17),
+       GATE_INFRA1(CLK_INFRA_AP_DMA, "infra_apdma",
+                   "axi_sel", 18),
+       GATE_INFRA1(CLK_INFRA_XIU, "infra_xiu",
+                   "axi_sel", 19),
+       GATE_INFRA1(CLK_INFRA_DEVICE_APC, "infra_device_apc",
+                   "axi_sel", 20),
+       GATE_INFRA1(CLK_INFRA_CCIF_AP, "infra_ccif_ap",
+                   "axi_sel", 23),
+       GATE_INFRA1(CLK_INFRA_DEBUGSYS, "infra_debugsys",
+                   "axi_sel", 24),
+       GATE_INFRA1(CLK_INFRA_AUD, "infra_audio",
+                   "axi_sel", 25),
+       GATE_INFRA1(CLK_INFRA_CCIF_MD, "infra_ccif_md",
+                   "axi_sel", 26),
+       GATE_INFRA1(CLK_INFRA_DXCC_SEC_CORE, "infra_dxcc_sec_core",
+                   "dxcc_sel", 27),
+       GATE_INFRA1(CLK_INFRA_DXCC_AO, "infra_dxcc_ao",
+                   "dxcc_sel", 28),
+       GATE_INFRA1(CLK_INFRA_DEVMPU_BCLK, "infra_devmpu_bclk",
+                   "axi_sel", 30),
+       GATE_INFRA1(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m",
+                   "f_f26m_ck", 31),
+       /* INFRA2 */
+       GATE_INFRA2(CLK_INFRA_IRTX, "infra_irtx",
+                   "f_f26m_ck", 0),
+       GATE_INFRA2(CLK_INFRA_USB, "infra_usb",
+                   "usb_top_sel", 1),
+       GATE_INFRA2(CLK_INFRA_DISP_PWM, "infra_disppwm",
+                   "axi_sel", 2),
+       GATE_INFRA2(CLK_INFRA_AUD_26M_BCLK,
+                   "infracfg_ao_audio_26m_bclk", "f_f26m_ck", 4),
+       GATE_INFRA2(CLK_INFRA_SPI1, "infra_spi1",
+                   "spi_sel", 6),
+       GATE_INFRA2(CLK_INFRA_I2C4, "infra_i2c4",
+                   "i2c_sel", 7),
+       GATE_INFRA2(CLK_INFRA_MODEM_TEMP_SHARE, "infra_md_tmp_share",
+                   "f_f26m_ck", 8),
+       GATE_INFRA2(CLK_INFRA_SPI2, "infra_spi2",
+                   "spi_sel", 9),
+       GATE_INFRA2(CLK_INFRA_SPI3, "infra_spi3",
+                   "spi_sel", 10),
+       GATE_INFRA2(CLK_INFRA_UNIPRO_SCK, "infra_unipro_sck",
+                   "fufs_sel", 11),
+       GATE_INFRA2(CLK_INFRA_UNIPRO_TICK, "infra_unipro_tick",
+                   "fufs_sel", 12),
+       GATE_INFRA2(CLK_INFRA_UFS_MP_SAP_BCLK, "infra_ufs_mp_sap_bck",
+                   "fufs_sel", 13),
+       GATE_INFRA2(CLK_INFRA_MD32_BCLK, "infra_md32_bclk",
+                   "axi_sel", 14),
+       GATE_INFRA2(CLK_INFRA_UNIPRO_MBIST, "infra_unipro_mbist",
+                   "axi_sel", 16),
+       GATE_INFRA2(CLK_INFRA_SSPM_BUS_HCLK, "infra_sspm_bus_hclk",
+                   "axi_sel", 17),
+       GATE_INFRA2(CLK_INFRA_I2C5, "infra_i2c5",
+                   "i2c_sel", 18),
+       GATE_INFRA2(CLK_INFRA_I2C5_ARBITER, "infra_i2c5_arbiter",
+                   "i2c_sel", 19),
+       GATE_INFRA2(CLK_INFRA_I2C5_IMM, "infra_i2c5_imm",
+                   "i2c_sel", 20),
+       GATE_INFRA2(CLK_INFRA_I2C1_ARBITER, "infra_i2c1_arbiter",
+                   "i2c_sel", 21),
+       GATE_INFRA2(CLK_INFRA_I2C1_IMM, "infra_i2c1_imm",
+                   "i2c_sel", 22),
+       GATE_INFRA2(CLK_INFRA_I2C2_ARBITER, "infra_i2c2_arbiter",
+                   "i2c_sel", 23),
+       GATE_INFRA2(CLK_INFRA_I2C2_IMM, "infra_i2c2_imm",
+                   "i2c_sel", 24),
+       GATE_INFRA2(CLK_INFRA_SPI4, "infra_spi4",
+                   "spi_sel", 25),
+       GATE_INFRA2(CLK_INFRA_SPI5, "infra_spi5",
+                   "spi_sel", 26),
+       GATE_INFRA2(CLK_INFRA_CQ_DMA, "infra_cqdma",
+                   "axi_sel", 27),
+       GATE_INFRA2(CLK_INFRA_UFS, "infra_ufs",
+                   "fufs_sel", 28),
+       GATE_INFRA2(CLK_INFRA_AES_UFSFDE, "infra_aes_ufsfde",
+                   "faes_ufsfde_sel", 29),
+       GATE_INFRA2(CLK_INFRA_UFS_TICK, "infra_ufs_tick",
+                   "fufs_sel", 30),
+       GATE_INFRA2(CLK_INFRA_SSUSB_XHCI, "infra_ssusb_xhci",
+                   "ssusb_top_xhci_sel", 31),
+       /* INFRA3 */
+       GATE_INFRA3(CLK_INFRA_MSDC0_SELF, "infra_msdc0_self",
+                   "msdc50_0_sel", 0),
+       GATE_INFRA3(CLK_INFRA_MSDC1_SELF, "infra_msdc1_self",
+                   "msdc50_0_sel", 1),
+       GATE_INFRA3(CLK_INFRA_MSDC2_SELF, "infra_msdc2_self",
+                   "msdc50_0_sel", 2),
+       GATE_INFRA3(CLK_INFRA_SSPM_26M_SELF, "infra_sspm_26m_self",
+                   "f_f26m_ck", 3),
+       GATE_INFRA3(CLK_INFRA_SSPM_32K_SELF, "infra_sspm_32k_self",
+                   "f_f26m_ck", 4),
+       GATE_INFRA3(CLK_INFRA_UFS_AXI, "infra_ufs_axi",
+                   "axi_sel", 5),
+       GATE_INFRA3(CLK_INFRA_I2C6, "infra_i2c6",
+                   "i2c_sel", 6),
+       GATE_INFRA3(CLK_INFRA_AP_MSDC0, "infra_ap_msdc0",
+                   "msdc50_hclk_sel", 7),
+       GATE_INFRA3(CLK_INFRA_MD_MSDC0, "infra_md_msdc0",
+                   "msdc50_hclk_sel", 8),
+       GATE_INFRA3(CLK_INFRA_CCIF2_AP, "infra_ccif2_ap",
+                   "axi_sel", 16),
+       GATE_INFRA3(CLK_INFRA_CCIF2_MD, "infra_ccif2_md",
+                   "axi_sel", 17),
+       GATE_INFRA3(CLK_INFRA_CCIF3_AP, "infra_ccif3_ap",
+                   "axi_sel", 18),
+       GATE_INFRA3(CLK_INFRA_CCIF3_MD, "infra_ccif3_md",
+                   "axi_sel", 19),
+       GATE_INFRA3(CLK_INFRA_SEJ_F13M, "infra_sej_f13m",
+                   "f_f26m_ck", 20),
+       GATE_INFRA3(CLK_INFRA_AES_BCLK, "infra_aes_bclk",
+                   "axi_sel", 21),
+       GATE_INFRA3(CLK_INFRA_I2C7, "infra_i2c7",
+                   "i2c_sel", 22),
+       GATE_INFRA3(CLK_INFRA_I2C8, "infra_i2c8",
+                   "i2c_sel", 23),
+       GATE_INFRA3(CLK_INFRA_FBIST2FPC, "infra_fbist2fpc",
+                   "msdc50_0_sel", 24),
+       GATE_INFRA3(CLK_INFRA_DPMAIF_CK, "infra_dpmaif",
+                   "dpmaif_sel", 26),
+       GATE_INFRA3(CLK_INFRA_FADSP, "infra_fadsp",
+                   "adsp_sel", 27),
+       GATE_INFRA3(CLK_INFRA_CCIF4_AP, "infra_ccif4_ap",
+                   "axi_sel", 28),
+       GATE_INFRA3(CLK_INFRA_CCIF4_MD, "infra_ccif4_md",
+                   "axi_sel", 29),
+       GATE_INFRA3(CLK_INFRA_SPI6, "infra_spi6",
+                   "spi_sel", 30),
+       GATE_INFRA3(CLK_INFRA_SPI7, "infra_spi7",
+                   "spi_sel", 31),
+};
+
+static const struct mtk_gate_regs apmixed_cg_regs = {
+       .set_ofs = 0x20,
+       .clr_ofs = 0x20,
+       .sta_ofs = 0x20,
+};
+
+#define GATE_APMIXED_FLAGS(_id, _name, _parent, _shift, _flags)        \
+       GATE_MTK_FLAGS(_id, _name, _parent, &apmixed_cg_regs,           \
+               _shift, &mtk_clk_gate_ops_no_setclr_inv, _flags)
+
+#define GATE_APMIXED(_id, _name, _parent, _shift)      \
+       GATE_APMIXED_FLAGS(_id, _name, _parent, _shift, 0)
+
+/*
+ * CRITICAL CLOCK:
+ * apmixed_appll26m is the toppest clock gate of all PLLs.
+ */
+static const struct mtk_gate apmixed_clks[] = {
+       GATE_APMIXED(CLK_APMIXED_SSUSB26M, "apmixed_ssusb26m",
+                    "f_f26m_ck", 4),
+       GATE_APMIXED_FLAGS(CLK_APMIXED_APPLL26M, "apmixed_appll26m",
+                          "f_f26m_ck", 5, CLK_IS_CRITICAL),
+       GATE_APMIXED(CLK_APMIXED_MIPIC0_26M, "apmixed_mipic026m",
+                    "f_f26m_ck", 6),
+       GATE_APMIXED(CLK_APMIXED_MDPLLGP26M, "apmixed_mdpll26m",
+                    "f_f26m_ck", 7),
+       GATE_APMIXED(CLK_APMIXED_MM_F26M, "apmixed_mmsys26m",
+                    "f_f26m_ck", 8),
+       GATE_APMIXED(CLK_APMIXED_UFS26M, "apmixed_ufs26m",
+                    "f_f26m_ck", 9),
+       GATE_APMIXED(CLK_APMIXED_MIPIC1_26M, "apmixed_mipic126m",
+                    "f_f26m_ck", 11),
+       GATE_APMIXED(CLK_APMIXED_MEMPLL26M, "apmixed_mempll26m",
+                    "f_f26m_ck", 13),
+       GATE_APMIXED(CLK_APMIXED_CLKSQ_LVPLL_26M, "apmixed_lvpll26m",
+                    "f_f26m_ck", 14),
+       GATE_APMIXED(CLK_APMIXED_MIPID0_26M, "apmixed_mipid026m",
+                    "f_f26m_ck", 16),
+       GATE_APMIXED(CLK_APMIXED_MIPID1_26M, "apmixed_mipid126m",
+                    "f_f26m_ck", 17),
+};
+
+#define MT6779_PLL_FMAX                (3800UL * MHZ)
+#define MT6779_PLL_FMIN                (1500UL * MHZ)
+
+#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags,            \
+                       _rst_bar_mask, _pcwbits, _pcwibits, _pd_reg,    \
+                       _pd_shift, _tuner_reg,  _tuner_en_reg,          \
+                       _tuner_en_bit, _pcw_reg, _pcw_shift,            \
+                       _pcw_chg_reg, _div_table) {                     \
+               .id = _id,                                              \
+               .name = _name,                                          \
+               .reg = _reg,                                            \
+               .pwr_reg = _pwr_reg,                                    \
+               .en_mask = _en_mask,                                    \
+               .flags = _flags,                                        \
+               .rst_bar_mask = _rst_bar_mask,                          \
+               .fmax = MT6779_PLL_FMAX,                                \
+               .fmin = MT6779_PLL_FMIN,                                \
+               .pcwbits = _pcwbits,                                    \
+               .pcwibits = _pcwibits,                                  \
+               .pd_reg = _pd_reg,                                      \
+               .pd_shift = _pd_shift,                                  \
+               .tuner_reg = _tuner_reg,                                \
+               .tuner_en_reg = _tuner_en_reg,                          \
+               .tuner_en_bit = _tuner_en_bit,                          \
+               .pcw_reg = _pcw_reg,                                    \
+               .pcw_shift = _pcw_shift,                                \
+               .pcw_chg_reg = _pcw_chg_reg,                            \
+               .div_table = _div_table,                                \
+       }
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags,              \
+                       _rst_bar_mask, _pcwbits, _pcwibits, _pd_reg,    \
+                       _pd_shift, _tuner_reg, _tuner_en_reg,           \
+                       _tuner_en_bit, _pcw_reg, _pcw_shift,            \
+                       _pcw_chg_reg)                                   \
+               PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags,     \
+                       _rst_bar_mask, _pcwbits, _pcwibits, _pd_reg,    \
+                       _pd_shift, _tuner_reg, _tuner_en_reg,           \
+                       _tuner_en_bit, _pcw_reg, _pcw_shift,            \
+                       _pcw_chg_reg, NULL)
+
+static const struct mtk_pll_data plls[] = {
+       PLL(CLK_APMIXED_ARMPLL_LL, "armpll_ll", 0x0200, 0x020C, BIT(0),
+           PLL_AO, 0, 22, 8, 0x0204, 24, 0, 0, 0, 0x0204, 0, 0),
+       PLL(CLK_APMIXED_ARMPLL_BL, "armpll_bl", 0x0210, 0x021C, BIT(0),
+           PLL_AO, 0, 22, 8, 0x0214, 24, 0, 0, 0, 0x0214, 0, 0),
+       PLL(CLK_APMIXED_CCIPLL, "ccipll", 0x02A0, 0x02AC, BIT(0),
+           PLL_AO, 0, 22, 8, 0x02A4, 24, 0, 0, 0, 0x02A4, 0, 0),
+       PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0230, 0x023C, BIT(0),
+           (HAVE_RST_BAR), BIT(24), 22, 8, 0x0234, 24, 0, 0, 0,
+           0x0234, 0, 0),
+       PLL(CLK_APMIXED_UNIV2PLL, "univ2pll", 0x0240, 0x024C, BIT(0),
+           (HAVE_RST_BAR), BIT(24), 22, 8, 0x0244, 24,
+           0, 0, 0, 0x0244, 0, 0),
+       PLL(CLK_APMIXED_MFGPLL, "mfgpll", 0x0250, 0x025C, BIT(0),
+           0, 0, 22, 8, 0x0254, 24, 0, 0, 0, 0x0254, 0, 0),
+       PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0260, 0x026C, BIT(0),
+           0, 0, 22, 8, 0x0264, 24, 0, 0, 0, 0x0264, 0, 0),
+       PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x0270, 0x027C, BIT(0),
+           0, 0, 22, 8, 0x0274, 24, 0, 0, 0, 0x0274, 0, 0),
+       PLL(CLK_APMIXED_ADSPPLL, "adsppll", 0x02b0, 0x02bC, BIT(0),
+           (HAVE_RST_BAR), BIT(23), 22, 8, 0x02b4, 24,
+           0, 0, 0, 0x02b4, 0, 0),
+       PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0280, 0x028C, BIT(0),
+           (HAVE_RST_BAR), BIT(23), 22, 8, 0x0284, 24,
+           0, 0, 0, 0x0284, 0, 0),
+       PLL(CLK_APMIXED_APLL1, "apll1", 0x02C0, 0x02D0, BIT(0),
+           0, 0, 32, 8, 0x02C0, 1, 0, 0x14, 0, 0x02C4, 0, 0x2C0),
+       PLL(CLK_APMIXED_APLL2, "apll2", 0x02D4, 0x02E4, BIT(0),
+           0, 0, 32, 8, 0x02D4, 1, 0, 0x14, 1, 0x02D8, 0, 0x02D4),
+};
+
+static int clk_mt6779_apmixed_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
+
+       mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+
+       mtk_clk_register_gates(node, apmixed_clks,
+                              ARRAY_SIZE(apmixed_clks), clk_data);
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static int clk_mt6779_top_probe(struct platform_device *pdev)
+{
+       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       void __iomem *base;
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+
+       base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
+
+       mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
+                                   clk_data);
+
+       mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+
+       mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes),
+                              node, &mt6779_clk_lock, clk_data);
+
+       mtk_clk_register_composites(top_aud_muxes, ARRAY_SIZE(top_aud_muxes),
+                                   base, &mt6779_clk_lock, clk_data);
+
+       mtk_clk_register_composites(top_aud_divs, ARRAY_SIZE(top_aud_divs),
+                                   base, &mt6779_clk_lock, clk_data);
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static int clk_mt6779_infra_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
+
+       mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+                              clk_data);
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static const struct of_device_id of_match_clk_mt6779[] = {
+       {
+               .compatible = "mediatek,mt6779-apmixed",
+               .data = clk_mt6779_apmixed_probe,
+       }, {
+               .compatible = "mediatek,mt6779-topckgen",
+               .data = clk_mt6779_top_probe,
+       }, {
+               .compatible = "mediatek,mt6779-infracfg_ao",
+               .data = clk_mt6779_infra_probe,
+       }, {
+               /* sentinel */
+       }
+};
+
+static int clk_mt6779_probe(struct platform_device *pdev)
+{
+       int (*clk_probe)(struct platform_device *pdev);
+       int r;
+
+       clk_probe = of_device_get_match_data(&pdev->dev);
+       if (!clk_probe)
+               return -EINVAL;
+
+       r = clk_probe(pdev);
+       if (r)
+               dev_err(&pdev->dev,
+                       "could not register clock provider: %s: %d\n",
+                       pdev->name, r);
+
+       return r;
+}
+
+static struct platform_driver clk_mt6779_drv = {
+       .probe = clk_mt6779_probe,
+       .driver = {
+               .name = "clk-mt6779",
+               .of_match_table = of_match_clk_mt6779,
+       },
+};
+
+static int __init clk_mt6779_init(void)
+{
+       return platform_driver_register(&clk_mt6779_drv);
+}
+
+arch_initcall(clk_mt6779_init);
index 99a6b020833e7bc36fc631564adddb548f559408..37b4162c5882036da6e74afea176361f8a108258 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 
 #include "clk-mtk.h"
 #include "clk-gate.h"
@@ -30,10 +31,12 @@ static int clk_mt8183_mfg_probe(struct platform_device *pdev)
        struct clk_onecell_data *clk_data;
        struct device_node *node = pdev->dev.of_node;
 
+       pm_runtime_enable(&pdev->dev);
+
        clk_data = mtk_alloc_clk_data(CLK_MFG_NR_CLK);
 
-       mtk_clk_register_gates(node, mfg_clks, ARRAY_SIZE(mfg_clks),
-                       clk_data);
+       mtk_clk_register_gates_with_dev(node, mfg_clks, ARRAY_SIZE(mfg_clks),
+                       clk_data, &pdev->dev);
 
        return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 }
index 1aa5f40592514db3e015c67e176d43c44ce22a69..7e7452e5669422d3bc2fe1d5e4c5e767ae8408f9 100644 (file)
@@ -17,6 +17,9 @@
 
 #include <dt-bindings/clock/mt8183-clk.h>
 
+/* Infra global controller reset set register */
+#define INFRA_RST0_SET_OFFSET          0x120
+
 static DEFINE_SPINLOCK(mt8183_clk_lock);
 
 static const struct mtk_fixed_clk top_fixed_clks[] = {
@@ -999,6 +1002,20 @@ static const struct mtk_gate infra_clks[] = {
                "msdc50_0_sel", 24),
 };
 
+static const struct mtk_gate_regs peri_cg_regs = {
+       .set_ofs = 0x20c,
+       .clr_ofs = 0x20c,
+       .sta_ofs = 0x20c,
+};
+
+#define GATE_PERI(_id, _name, _parent, _shift)                 \
+       GATE_MTK(_id, _name, _parent, &peri_cg_regs, _shift,    \
+               &mtk_clk_gate_ops_no_setclr_inv)
+
+static const struct mtk_gate peri_clks[] = {
+       GATE_PERI(CLK_PERI_AXI, "peri_axi", "axi_sel", 31),
+};
+
 static const struct mtk_gate_regs apmixed_cg_regs = {
        .set_ofs = 0x20,
        .clr_ofs = 0x20,
@@ -1185,12 +1202,36 @@ static int clk_mt8183_infra_probe(struct platform_device *pdev)
 {
        struct clk_onecell_data *clk_data;
        struct device_node *node = pdev->dev.of_node;
+       int r;
 
        clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
 
        mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
                clk_data);
 
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r) {
+               dev_err(&pdev->dev,
+                       "%s(): could not register clock provider: %d\n",
+                       __func__, r);
+               return r;
+       }
+
+       mtk_register_reset_controller_set_clr(node, 4, INFRA_RST0_SET_OFFSET);
+
+       return r;
+}
+
+static int clk_mt8183_peri_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
+
+       mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
+                              clk_data);
+
        return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 }
 
@@ -1223,6 +1264,9 @@ static const struct of_device_id of_match_clk_mt8183[] = {
        }, {
                .compatible = "mediatek,mt8183-infracfg",
                .data = clk_mt8183_infra_probe,
+       }, {
+               .compatible = "mediatek,mt8183-pericfg",
+               .data = clk_mt8183_peri_probe,
        }, {
                .compatible = "mediatek,mt8183-mcucfg",
                .data = clk_mt8183_mcu_probe,
index d28790c7491920b0b77a468fe2b041b671173af3..cec1c8a27211352a215d00319c807133aea3465a 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/delay.h>
 #include <linux/clkdev.h>
 #include <linux/mfd/syscon.h>
+#include <linux/device.h>
 
 #include "clk-mtk.h"
 #include "clk-gate.h"
@@ -93,9 +94,10 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
        }
 }
 
-int mtk_clk_register_gates(struct device_node *node,
+int mtk_clk_register_gates_with_dev(struct device_node *node,
                const struct mtk_gate *clks,
-               int num, struct clk_onecell_data *clk_data)
+               int num, struct clk_onecell_data *clk_data,
+               struct device *dev)
 {
        int i;
        struct clk *clk;
@@ -122,7 +124,7 @@ int mtk_clk_register_gates(struct device_node *node,
                                gate->regs->set_ofs,
                                gate->regs->clr_ofs,
                                gate->regs->sta_ofs,
-                               gate->shift, gate->ops, gate->flags);
+                               gate->shift, gate->ops, gate->flags, dev);
 
                if (IS_ERR(clk)) {
                        pr_err("Failed to register clk %s: %ld\n",
@@ -136,6 +138,14 @@ int mtk_clk_register_gates(struct device_node *node,
        return 0;
 }
 
+int mtk_clk_register_gates(struct device_node *node,
+               const struct mtk_gate *clks,
+               int num, struct clk_onecell_data *clk_data)
+{
+       return mtk_clk_register_gates_with_dev(node,
+               clks, num, clk_data, NULL);
+}
+
 struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
                void __iomem *base, spinlock_t *lock)
 {
index 733a11d1de946146633d3d41b439c569a50c49f8..c3d6756b0c7e758f503ec8c107d04ae91458b817 100644 (file)
@@ -169,6 +169,11 @@ int mtk_clk_register_gates(struct device_node *node,
                        const struct mtk_gate *clks, int num,
                        struct clk_onecell_data *clk_data);
 
+int mtk_clk_register_gates_with_dev(struct device_node *node,
+               const struct mtk_gate *clks,
+               int num, struct clk_onecell_data *clk_data,
+               struct device *dev);
+
 struct mtk_clk_divider {
        int id;
        const char *name;
@@ -240,4 +245,7 @@ struct clk *mtk_clk_register_ref2usb_tx(const char *name,
 void mtk_register_reset_controller(struct device_node *np,
                        unsigned int num_regs, int regofs);
 
+void mtk_register_reset_controller_set_clr(struct device_node *np,
+       unsigned int num_regs, int regofs);
+
 #endif /* __DRV_CLK_MTK_H */
index d8376b92349ee7a11c09891b7200eff32b760414..cb939c071b0ccabeeda89331043002967209cf17 100644 (file)
@@ -19,6 +19,24 @@ struct mtk_reset {
        struct reset_controller_dev rcdev;
 };
 
+static int mtk_reset_assert_set_clr(struct reset_controller_dev *rcdev,
+       unsigned long id)
+{
+       struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
+       unsigned int reg = data->regofs + ((id / 32) << 4);
+
+       return regmap_write(data->regmap, reg, 1);
+}
+
+static int mtk_reset_deassert_set_clr(struct reset_controller_dev *rcdev,
+       unsigned long id)
+{
+       struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
+       unsigned int reg = data->regofs + ((id / 32) << 4) + 0x4;
+
+       return regmap_write(data->regmap, reg, 1);
+}
+
 static int mtk_reset_assert(struct reset_controller_dev *rcdev,
                              unsigned long id)
 {
@@ -49,14 +67,32 @@ static int mtk_reset(struct reset_controller_dev *rcdev,
        return mtk_reset_deassert(rcdev, id);
 }
 
+static int mtk_reset_set_clr(struct reset_controller_dev *rcdev,
+       unsigned long id)
+{
+       int ret;
+
+       ret = mtk_reset_assert_set_clr(rcdev, id);
+       if (ret)
+               return ret;
+       return mtk_reset_deassert_set_clr(rcdev, id);
+}
+
 static const struct reset_control_ops mtk_reset_ops = {
        .assert = mtk_reset_assert,
        .deassert = mtk_reset_deassert,
        .reset = mtk_reset,
 };
 
-void mtk_register_reset_controller(struct device_node *np,
-                       unsigned int num_regs, int regofs)
+static const struct reset_control_ops mtk_reset_ops_set_clr = {
+       .assert = mtk_reset_assert_set_clr,
+       .deassert = mtk_reset_deassert_set_clr,
+       .reset = mtk_reset_set_clr,
+};
+
+static void mtk_register_reset_controller_common(struct device_node *np,
+                       unsigned int num_regs, int regofs,
+                       const struct reset_control_ops *reset_ops)
 {
        struct mtk_reset *data;
        int ret;
@@ -77,7 +113,7 @@ void mtk_register_reset_controller(struct device_node *np,
        data->regofs = regofs;
        data->rcdev.owner = THIS_MODULE;
        data->rcdev.nr_resets = num_regs * 32;
-       data->rcdev.ops = &mtk_reset_ops;
+       data->rcdev.ops = reset_ops;
        data->rcdev.of_node = np;
 
        ret = reset_controller_register(&data->rcdev);
@@ -87,3 +123,17 @@ void mtk_register_reset_controller(struct device_node *np,
                return;
        }
 }
+
+void mtk_register_reset_controller(struct device_node *np,
+       unsigned int num_regs, int regofs)
+{
+       mtk_register_reset_controller_common(np, num_regs, regofs,
+               &mtk_reset_ops);
+}
+
+void mtk_register_reset_controller_set_clr(struct device_node *np,
+       unsigned int num_regs, int regofs)
+{
+       mtk_register_reset_controller_common(np, num_regs, regofs,
+               &mtk_reset_ops_set_clr);
+}
index a6b20e123e0cc16ddc802c51c0efb356d5c70da7..dabeb435d06784205399a84d75f9faa883de0466 100644 (file)
@@ -1,7 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
-config COMMON_CLK_MESON_INPUT
-       tristate
-
 config COMMON_CLK_MESON_REGMAP
        tristate
        select REGMAP
@@ -33,13 +30,15 @@ config COMMON_CLK_MESON_VID_PLL_DIV
 config COMMON_CLK_MESON_AO_CLKC
        tristate
        select COMMON_CLK_MESON_REGMAP
-       select COMMON_CLK_MESON_INPUT
        select RESET_CONTROLLER
 
 config COMMON_CLK_MESON_EE_CLKC
        tristate
        select COMMON_CLK_MESON_REGMAP
-       select COMMON_CLK_MESON_INPUT
+
+config COMMON_CLK_MESON_CPU_DYNDIV
+       tristate
+       select COMMON_CLK_MESON_REGMAP
 
 config COMMON_CLK_MESON8B
        bool
@@ -86,7 +85,6 @@ config COMMON_CLK_AXG
 config COMMON_CLK_AXG_AUDIO
        tristate "Meson AXG Audio Clock Controller Driver"
        depends on ARCH_MESON
-       select COMMON_CLK_MESON_INPUT
        select COMMON_CLK_MESON_REGMAP
        select COMMON_CLK_MESON_PHASE
        select COMMON_CLK_MESON_SCLK_DIV
@@ -104,6 +102,7 @@ config COMMON_CLK_G12A
        select COMMON_CLK_MESON_PLL
        select COMMON_CLK_MESON_AO_CLKC
        select COMMON_CLK_MESON_EE_CLKC
+       select COMMON_CLK_MESON_CPU_DYNDIV
        select MFD_SYSCON
        help
          Support for the clock controller on Amlogic S905D2, S905X2 and S905Y2
index bc35a4efd6b77c7de2f2a1fde2358fade29fef9a..3939f218587abfb324d32a81768eddabfca2d3c9 100644 (file)
@@ -2,9 +2,9 @@
 # Amlogic clock drivers
 
 obj-$(CONFIG_COMMON_CLK_MESON_AO_CLKC) += meson-aoclk.o
+obj-$(CONFIG_COMMON_CLK_MESON_CPU_DYNDIV) += clk-cpu-dyndiv.o
 obj-$(CONFIG_COMMON_CLK_MESON_DUALDIV) += clk-dualdiv.o
 obj-$(CONFIG_COMMON_CLK_MESON_EE_CLKC) += meson-eeclk.o
-obj-$(CONFIG_COMMON_CLK_MESON_INPUT) += clk-input.o
 obj-$(CONFIG_COMMON_CLK_MESON_MPLL) += clk-mpll.o
 obj-$(CONFIG_COMMON_CLK_MESON_PHASE) += clk-phase.o
 obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o
index 0086f31288eb8621bc38a0c4a104cd2c664079ed..b488b40c9d0e3f56bd94d0a7145abd475a263d3d 100644 (file)
@@ -18,8 +18,6 @@
 #include "clk-regmap.h"
 #include "clk-dualdiv.h"
 
-#define IN_PREFIX "ao-in-"
-
 /*
  * AO Configuration Clock registers offsets
  * Register offsets from the data sheet must be multiplied by 4.
@@ -42,7 +40,9 @@ static struct clk_regmap axg_aoclk_##_name = {                                \
        .hw.init = &(struct clk_init_data) {                            \
                .name =  "axg_ao_" #_name,                              \
                .ops = &clk_regmap_gate_ops,                            \
-               .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \
+               .parent_data = &(const struct clk_parent_data) {        \
+                       .fw_name = "mpeg-clk",                          \
+               },                                                      \
                .num_parents = 1,                                       \
                .flags = CLK_IGNORE_UNUSED,                             \
        },                                                              \
@@ -64,7 +64,9 @@ static struct clk_regmap axg_aoclk_cts_oscin = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_oscin",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -77,7 +79,9 @@ static struct clk_regmap axg_aoclk_32k_pre = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_32k_pre",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_oscin" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_aoclk_cts_oscin.hw
+               },
                .num_parents = 1,
        },
 };
@@ -124,7 +128,9 @@ static struct clk_regmap axg_aoclk_32k_div = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_32k_div",
                .ops = &meson_clk_dualdiv_ops,
-               .parent_names = (const char *[]){ "axg_ao_32k_pre" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_aoclk_32k_pre.hw
+               },
                .num_parents = 1,
        },
 };
@@ -139,8 +145,10 @@ static struct clk_regmap axg_aoclk_32k_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_32k_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "axg_ao_32k_div",
-                                                 "axg_ao_32k_pre" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_aoclk_32k_div.hw,
+                       &axg_aoclk_32k_pre.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -154,7 +162,9 @@ static struct clk_regmap axg_aoclk_32k = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_32k",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "axg_ao_32k_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_aoclk_32k_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -170,8 +180,10 @@ static struct clk_regmap axg_aoclk_cts_rtc_oscin = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_cts_rtc_oscin",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "axg_ao_32k",
-                                                 IN_PREFIX "ext_32k-0" },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .hw = &axg_aoclk_32k.hw },
+                       { .fw_name = "ext_32k-0", },
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -187,8 +199,10 @@ static struct clk_regmap axg_aoclk_clk81 = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_clk81",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk",
-                                                 "axg_ao_cts_rtc_oscin"},
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "mpeg-clk", },
+                       { .hw = &axg_aoclk_cts_rtc_oscin.hw },
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -203,8 +217,10 @@ static struct clk_regmap axg_aoclk_saradc_mux = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_saradc_mux",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal",
-                                                 "axg_ao_clk81" },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &axg_aoclk_clk81.hw },
+               },
                .num_parents = 2,
        },
 };
@@ -218,7 +234,9 @@ static struct clk_regmap axg_aoclk_saradc_div = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_saradc_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "axg_ao_saradc_mux" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_aoclk_saradc_mux.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -232,7 +250,9 @@ static struct clk_regmap axg_aoclk_saradc_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_saradc_gate",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "axg_ao_saradc_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_aoclk_saradc_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -290,12 +310,6 @@ static const struct clk_hw_onecell_data axg_aoclk_onecell_data = {
        .num = NR_CLKS,
 };
 
-static const struct meson_aoclk_input axg_aoclk_inputs[] = {
-       { .name = "xtal",       .required = true  },
-       { .name = "mpeg-clk",   .required = true  },
-       { .name = "ext-32k-0",  .required = false },
-};
-
 static const struct meson_aoclk_data axg_aoclkc_data = {
        .reset_reg      = AO_RTI_GEN_CNTL_REG0,
        .num_reset      = ARRAY_SIZE(axg_aoclk_reset),
@@ -303,9 +317,6 @@ static const struct meson_aoclk_data axg_aoclkc_data = {
        .num_clks       = ARRAY_SIZE(axg_aoclk_regmap),
        .clks           = axg_aoclk_regmap,
        .hw_data        = &axg_aoclk_onecell_data,
-       .inputs         = axg_aoclk_inputs,
-       .num_inputs     = ARRAY_SIZE(axg_aoclk_inputs),
-       .input_prefix   = IN_PREFIX,
 };
 
 static const struct of_device_id axg_aoclkc_match_table[] = {
index 8028ff6f661075168f6e41afde073f0082d1d932..18b23cdf679c07ade20a7827e877bbae718b7c80 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
+#include <linux/reset-controller.h>
 #include <linux/slab.h>
 
 #include "axg-audio.h"
-#include "clk-input.h"
 #include "clk-regmap.h"
 #include "clk-phase.h"
 #include "sclk-div.h"
@@ -24,7 +24,7 @@
 #define AUD_SLV_SCLK_COUNT     10
 #define AUD_SLV_LRCLK_COUNT    10
 
-#define AUD_GATE(_name, _reg, _bit, _pname, _iflags)                   \
+#define AUD_GATE(_name, _reg, _bit, _phws, _iflags)                    \
 struct clk_regmap aud_##_name = {                                      \
        .data = &(struct clk_regmap_gate_data){                         \
                .offset = (_reg),                                       \
@@ -33,13 +33,13 @@ struct clk_regmap aud_##_name = {                                   \
        .hw.init = &(struct clk_init_data) {                            \
                .name = "aud_"#_name,                                   \
                .ops = &clk_regmap_gate_ops,                            \
-               .parent_names = (const char *[]){ _pname },             \
+               .parent_hws = (const struct clk_hw *[]) { &_phws.hw },  \
                .num_parents = 1,                                       \
                .flags = CLK_DUTY_CYCLE_PARENT | (_iflags),             \
        },                                                              \
 }
 
-#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pnames, _iflags) \
+#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pdata, _iflags)  \
 struct clk_regmap aud_##_name = {                                      \
        .data = &(struct clk_regmap_mux_data){                          \
                .offset = (_reg),                                       \
@@ -50,13 +50,13 @@ struct clk_regmap aud_##_name = {                                   \
        .hw.init = &(struct clk_init_data){                             \
                .name = "aud_"#_name,                                   \
                .ops = &clk_regmap_mux_ops,                             \
-               .parent_names = (_pnames),                              \
-               .num_parents = ARRAY_SIZE(_pnames),                     \
+               .parent_data = _pdata,                                  \
+               .num_parents = ARRAY_SIZE(_pdata),                      \
                .flags = CLK_DUTY_CYCLE_PARENT | (_iflags),             \
        },                                                              \
 }
 
-#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _pname, _iflags) \
+#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _phws, _iflags)  \
 struct clk_regmap aud_##_name = {                                      \
        .data = &(struct clk_regmap_div_data){                          \
                .offset = (_reg),                                       \
@@ -67,15 +67,27 @@ struct clk_regmap aud_##_name = {                                   \
        .hw.init = &(struct clk_init_data){                             \
                .name = "aud_"#_name,                                   \
                .ops = &clk_regmap_divider_ops,                         \
-               .parent_names = (const char *[]) { _pname },            \
+               .parent_hws = (const struct clk_hw *[]) { &_phws.hw },  \
                .num_parents = 1,                                       \
                .flags = (_iflags),                                     \
        },                                                              \
 }
 
 #define AUD_PCLK_GATE(_name, _bit)                             \
-       AUD_GATE(_name, AUDIO_CLK_GATE_EN, _bit, "audio_pclk", 0)
-
+struct clk_regmap aud_##_name = {                                      \
+       .data = &(struct clk_regmap_gate_data){                         \
+               .offset = (AUDIO_CLK_GATE_EN),                          \
+               .bit_idx = (_bit),                                      \
+       },                                                              \
+       .hw.init = &(struct clk_init_data) {                            \
+               .name = "aud_"#_name,                                   \
+               .ops = &clk_regmap_gate_ops,                            \
+               .parent_data = &(const struct clk_parent_data) {        \
+                       .fw_name = "pclk",                              \
+               },                                                      \
+               .num_parents = 1,                                       \
+       },                                                              \
+}
 /* Audio peripheral clocks */
 static AUD_PCLK_GATE(ddr_arb,     0);
 static AUD_PCLK_GATE(pdm,         1);
@@ -100,14 +112,20 @@ static AUD_PCLK_GATE(power_detect, 19);
 static AUD_PCLK_GATE(spdifout_b,   21);
 
 /* Audio Master Clocks */
-static const char * const mst_mux_parent_names[] = {
-       "aud_mst_in0", "aud_mst_in1", "aud_mst_in2", "aud_mst_in3",
-       "aud_mst_in4", "aud_mst_in5", "aud_mst_in6", "aud_mst_in7",
+static const struct clk_parent_data mst_mux_parent_data[] = {
+       { .fw_name = "mst_in0", },
+       { .fw_name = "mst_in1", },
+       { .fw_name = "mst_in2", },
+       { .fw_name = "mst_in3", },
+       { .fw_name = "mst_in4", },
+       { .fw_name = "mst_in5", },
+       { .fw_name = "mst_in6", },
+       { .fw_name = "mst_in7", },
 };
 
 #define AUD_MST_MUX(_name, _reg, _flag)                                \
        AUD_MUX(_name##_sel, _reg, 0x7, 24, _flag,              \
-               mst_mux_parent_names, CLK_SET_RATE_PARENT)
+               mst_mux_parent_data, 0)
 
 #define AUD_MST_MCLK_MUX(_name, _reg)                          \
        AUD_MST_MUX(_name, _reg, CLK_MUX_ROUND_CLOSEST)
@@ -129,7 +147,7 @@ static AUD_MST_MCLK_MUX(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL);
 
 #define AUD_MST_DIV(_name, _reg, _flag)                                \
        AUD_DIV(_name##_div, _reg, 0, 16, _flag,                \
-                   "aud_"#_name"_sel", CLK_SET_RATE_PARENT)    \
+                   aud_##_name##_sel, CLK_SET_RATE_PARENT)     \
 
 #define AUD_MST_MCLK_DIV(_name, _reg)                          \
        AUD_MST_DIV(_name, _reg, CLK_DIVIDER_ROUND_CLOSEST)
@@ -150,7 +168,7 @@ static AUD_MST_SYS_DIV(pdm_sysclk,    AUDIO_CLK_PDMIN_CTRL1);
 static AUD_MST_MCLK_DIV(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL);
 
 #define AUD_MST_MCLK_GATE(_name, _reg)                         \
-       AUD_GATE(_name, _reg, 31,  "aud_"#_name"_div",  \
+       AUD_GATE(_name, _reg, 31,  aud_##_name##_div,           \
                 CLK_SET_RATE_PARENT)
 
 static AUD_MST_MCLK_GATE(mst_a_mclk,   AUDIO_MCLK_A_CTRL);
@@ -168,7 +186,7 @@ static AUD_MST_MCLK_GATE(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL);
 /* Sample Clocks */
 #define AUD_MST_SCLK_PRE_EN(_name, _reg)                       \
        AUD_GATE(mst_##_name##_sclk_pre_en, _reg, 31,           \
-                "aud_mst_"#_name"_mclk", 0)
+                aud_mst_##_name##_mclk, 0)
 
 static AUD_MST_SCLK_PRE_EN(a, AUDIO_MST_A_SCLK_CTRL0);
 static AUD_MST_SCLK_PRE_EN(b, AUDIO_MST_B_SCLK_CTRL0);
@@ -178,7 +196,7 @@ static AUD_MST_SCLK_PRE_EN(e, AUDIO_MST_E_SCLK_CTRL0);
 static AUD_MST_SCLK_PRE_EN(f, AUDIO_MST_F_SCLK_CTRL0);
 
 #define AUD_SCLK_DIV(_name, _reg, _div_shift, _div_width,              \
-                        _hi_shift, _hi_width, _pname, _iflags)         \
+                        _hi_shift, _hi_width, _phws, _iflags)          \
 struct clk_regmap aud_##_name = {                                      \
        .data = &(struct meson_sclk_div_data) {                         \
                .div = {                                                \
@@ -195,7 +213,7 @@ struct clk_regmap aud_##_name = {                                   \
        .hw.init = &(struct clk_init_data) {                            \
                .name = "aud_"#_name,                                   \
                .ops = &meson_sclk_div_ops,                             \
-               .parent_names = (const char *[]) { _pname },            \
+               .parent_hws = (const struct clk_hw *[]) { &_phws.hw },  \
                .num_parents = 1,                                       \
                .flags = (_iflags),                                     \
        },                                                              \
@@ -203,7 +221,7 @@ struct clk_regmap aud_##_name = {                                   \
 
 #define AUD_MST_SCLK_DIV(_name, _reg)                                  \
        AUD_SCLK_DIV(mst_##_name##_sclk_div, _reg, 20, 10, 0, 0,        \
-                    "aud_mst_"#_name"_sclk_pre_en",                    \
+                    aud_mst_##_name##_sclk_pre_en,                     \
                     CLK_SET_RATE_PARENT)
 
 static AUD_MST_SCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0);
@@ -214,8 +232,8 @@ static AUD_MST_SCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0);
 static AUD_MST_SCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0);
 
 #define AUD_MST_SCLK_POST_EN(_name, _reg)                              \
-       AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30,          \
-                "aud_mst_"#_name"_sclk_div", CLK_SET_RATE_PARENT)
+       AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30,                  \
+                aud_mst_##_name##_sclk_div, CLK_SET_RATE_PARENT)
 
 static AUD_MST_SCLK_POST_EN(a, AUDIO_MST_A_SCLK_CTRL0);
 static AUD_MST_SCLK_POST_EN(b, AUDIO_MST_B_SCLK_CTRL0);
@@ -224,8 +242,8 @@ static AUD_MST_SCLK_POST_EN(d, AUDIO_MST_D_SCLK_CTRL0);
 static AUD_MST_SCLK_POST_EN(e, AUDIO_MST_E_SCLK_CTRL0);
 static AUD_MST_SCLK_POST_EN(f, AUDIO_MST_F_SCLK_CTRL0);
 
-#define AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2, \
-                        _pname, _iflags)                               \
+#define AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2,   \
+                        _phws, _iflags)                                \
 struct clk_regmap aud_##_name = {                                      \
        .data = &(struct meson_clk_triphase_data) {                     \
                .ph0 = {                                                \
@@ -247,7 +265,7 @@ struct clk_regmap aud_##_name = {                                   \
        .hw.init = &(struct clk_init_data) {                            \
                .name = "aud_"#_name,                                   \
                .ops = &meson_clk_triphase_ops,                         \
-               .parent_names = (const char *[]) { _pname },            \
+               .parent_hws = (const struct clk_hw *[]) { &_phws.hw },  \
                .num_parents = 1,                                       \
                .flags = CLK_DUTY_CYCLE_PARENT | (_iflags),             \
        },                                                              \
@@ -255,7 +273,7 @@ struct clk_regmap aud_##_name = {                                   \
 
 #define AUD_MST_SCLK(_name, _reg)                                      \
        AUD_TRIPHASE(mst_##_name##_sclk, _reg, 1, 0, 2, 4,              \
-                    "aud_mst_"#_name"_sclk_post_en", CLK_SET_RATE_PARENT)
+                    aud_mst_##_name##_sclk_post_en, CLK_SET_RATE_PARENT)
 
 static AUD_MST_SCLK(a, AUDIO_MST_A_SCLK_CTRL1);
 static AUD_MST_SCLK(b, AUDIO_MST_B_SCLK_CTRL1);
@@ -266,7 +284,7 @@ static AUD_MST_SCLK(f, AUDIO_MST_F_SCLK_CTRL1);
 
 #define AUD_MST_LRCLK_DIV(_name, _reg)                                 \
        AUD_SCLK_DIV(mst_##_name##_lrclk_div, _reg, 0, 10, 10, 10,      \
-                    "aud_mst_"#_name"_sclk_post_en", 0)                \
+                    aud_mst_##_name##_sclk_post_en, 0)                 \
 
 static AUD_MST_LRCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0);
 static AUD_MST_LRCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0);
@@ -277,7 +295,7 @@ static AUD_MST_LRCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0);
 
 #define AUD_MST_LRCLK(_name, _reg)                                     \
        AUD_TRIPHASE(mst_##_name##_lrclk, _reg, 1, 1, 3, 5,             \
-                    "aud_mst_"#_name"_lrclk_div", CLK_SET_RATE_PARENT)
+                    aud_mst_##_name##_lrclk_div, CLK_SET_RATE_PARENT)
 
 static AUD_MST_LRCLK(a, AUDIO_MST_A_SCLK_CTRL1);
 static AUD_MST_LRCLK(b, AUDIO_MST_B_SCLK_CTRL1);
@@ -286,19 +304,29 @@ static AUD_MST_LRCLK(d, AUDIO_MST_D_SCLK_CTRL1);
 static AUD_MST_LRCLK(e, AUDIO_MST_E_SCLK_CTRL1);
 static AUD_MST_LRCLK(f, AUDIO_MST_F_SCLK_CTRL1);
 
-static const char * const tdm_sclk_parent_names[] = {
-       "aud_mst_a_sclk", "aud_mst_b_sclk", "aud_mst_c_sclk",
-       "aud_mst_d_sclk", "aud_mst_e_sclk", "aud_mst_f_sclk",
-       "aud_slv_sclk0", "aud_slv_sclk1", "aud_slv_sclk2",
-       "aud_slv_sclk3", "aud_slv_sclk4", "aud_slv_sclk5",
-       "aud_slv_sclk6", "aud_slv_sclk7", "aud_slv_sclk8",
-       "aud_slv_sclk9"
+static const struct clk_parent_data tdm_sclk_parent_data[] = {
+       { .hw = &aud_mst_a_sclk.hw, },
+       { .hw = &aud_mst_b_sclk.hw, },
+       { .hw = &aud_mst_c_sclk.hw, },
+       { .hw = &aud_mst_d_sclk.hw, },
+       { .hw = &aud_mst_e_sclk.hw, },
+       { .hw = &aud_mst_f_sclk.hw, },
+       { .fw_name = "slv_sclk0", },
+       { .fw_name = "slv_sclk1", },
+       { .fw_name = "slv_sclk2", },
+       { .fw_name = "slv_sclk3", },
+       { .fw_name = "slv_sclk4", },
+       { .fw_name = "slv_sclk5", },
+       { .fw_name = "slv_sclk6", },
+       { .fw_name = "slv_sclk7", },
+       { .fw_name = "slv_sclk8", },
+       { .fw_name = "slv_sclk9", },
 };
 
 #define AUD_TDM_SCLK_MUX(_name, _reg)                          \
        AUD_MUX(tdm##_name##_sclk_sel, _reg, 0xf, 24,           \
                    CLK_MUX_ROUND_CLOSEST,                      \
-                   tdm_sclk_parent_names, 0)
+                   tdm_sclk_parent_data, 0)
 
 static AUD_TDM_SCLK_MUX(in_a,  AUDIO_CLK_TDMIN_A_CTRL);
 static AUD_TDM_SCLK_MUX(in_b,  AUDIO_CLK_TDMIN_B_CTRL);
@@ -310,7 +338,7 @@ static AUD_TDM_SCLK_MUX(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
 
 #define AUD_TDM_SCLK_PRE_EN(_name, _reg)                               \
        AUD_GATE(tdm##_name##_sclk_pre_en, _reg, 31,                    \
-                "aud_tdm"#_name"_sclk_sel", CLK_SET_RATE_PARENT)
+                aud_tdm##_name##_sclk_sel, CLK_SET_RATE_PARENT)
 
 static AUD_TDM_SCLK_PRE_EN(in_a,  AUDIO_CLK_TDMIN_A_CTRL);
 static AUD_TDM_SCLK_PRE_EN(in_b,  AUDIO_CLK_TDMIN_B_CTRL);
@@ -322,7 +350,7 @@ static AUD_TDM_SCLK_PRE_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
 
 #define AUD_TDM_SCLK_POST_EN(_name, _reg)                              \
        AUD_GATE(tdm##_name##_sclk_post_en, _reg, 30,                   \
-                "aud_tdm"#_name"_sclk_pre_en", CLK_SET_RATE_PARENT)
+                aud_tdm##_name##_sclk_pre_en, CLK_SET_RATE_PARENT)
 
 static AUD_TDM_SCLK_POST_EN(in_a,  AUDIO_CLK_TDMIN_A_CTRL);
 static AUD_TDM_SCLK_POST_EN(in_b,  AUDIO_CLK_TDMIN_B_CTRL);
@@ -344,8 +372,9 @@ static AUD_TDM_SCLK_POST_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
        .hw.init = &(struct clk_init_data) {                            \
                .name = "aud_tdm"#_name"_sclk",                         \
                .ops = &meson_clk_phase_ops,                            \
-               .parent_names = (const char *[])                        \
-               { "aud_tdm"#_name"_sclk_post_en" },                     \
+               .parent_hws = (const struct clk_hw *[]) {               \
+                       &aud_tdm##_name##_sclk_post_en.hw               \
+               },                                                      \
                .num_parents = 1,                                       \
                .flags = CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT,   \
        },                                                              \
@@ -359,19 +388,29 @@ static AUD_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
 static AUD_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
 static AUD_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
 
-static const char * const tdm_lrclk_parent_names[] = {
-       "aud_mst_a_lrclk", "aud_mst_b_lrclk", "aud_mst_c_lrclk",
-       "aud_mst_d_lrclk", "aud_mst_e_lrclk", "aud_mst_f_lrclk",
-       "aud_slv_lrclk0", "aud_slv_lrclk1", "aud_slv_lrclk2",
-       "aud_slv_lrclk3", "aud_slv_lrclk4", "aud_slv_lrclk5",
-       "aud_slv_lrclk6", "aud_slv_lrclk7", "aud_slv_lrclk8",
-       "aud_slv_lrclk9"
+static const struct clk_parent_data tdm_lrclk_parent_data[] = {
+       { .hw = &aud_mst_a_lrclk.hw, },
+       { .hw = &aud_mst_b_lrclk.hw, },
+       { .hw = &aud_mst_c_lrclk.hw, },
+       { .hw = &aud_mst_d_lrclk.hw, },
+       { .hw = &aud_mst_e_lrclk.hw, },
+       { .hw = &aud_mst_f_lrclk.hw, },
+       { .fw_name = "slv_lrclk0", },
+       { .fw_name = "slv_lrclk1", },
+       { .fw_name = "slv_lrclk2", },
+       { .fw_name = "slv_lrclk3", },
+       { .fw_name = "slv_lrclk4", },
+       { .fw_name = "slv_lrclk5", },
+       { .fw_name = "slv_lrclk6", },
+       { .fw_name = "slv_lrclk7", },
+       { .fw_name = "slv_lrclk8", },
+       { .fw_name = "slv_lrclk9", },
 };
 
-#define AUD_TDM_LRLCK(_name, _reg)                    \
-       AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20,     \
-               CLK_MUX_ROUND_CLOSEST,                 \
-               tdm_lrclk_parent_names, 0)
+#define AUD_TDM_LRLCK(_name, _reg)                     \
+       AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20,      \
+               CLK_MUX_ROUND_CLOSEST,                  \
+               tdm_lrclk_parent_data, 0)
 
 static AUD_TDM_LRLCK(in_a,  AUDIO_CLK_TDMIN_A_CTRL);
 static AUD_TDM_LRLCK(in_b,  AUDIO_CLK_TDMIN_B_CTRL);
@@ -386,39 +425,51 @@ static AUD_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
        AUD_MUX(tdm_##_name, _reg, 0x7, _shift, 0, _parents,    \
                CLK_SET_RATE_NO_REPARENT)
 
-static const char * const mclk_pad_ctrl_parent_names[] = {
-       "aud_mst_a_mclk", "aud_mst_b_mclk", "aud_mst_c_mclk",
-       "aud_mst_d_mclk", "aud_mst_e_mclk", "aud_mst_f_mclk",
+static const struct clk_parent_data mclk_pad_ctrl_parent_data[] = {
+       { .hw = &aud_mst_a_mclk.hw },
+       { .hw = &aud_mst_b_mclk.hw },
+       { .hw = &aud_mst_c_mclk.hw },
+       { .hw = &aud_mst_d_mclk.hw },
+       { .hw = &aud_mst_e_mclk.hw },
+       { .hw = &aud_mst_f_mclk.hw },
 };
 
 static AUD_TDM_PAD_CTRL(mclk_pad_0, AUDIO_MST_PAD_CTRL0, 0,
-                       mclk_pad_ctrl_parent_names);
+                       mclk_pad_ctrl_parent_data);
 static AUD_TDM_PAD_CTRL(mclk_pad_1, AUDIO_MST_PAD_CTRL0, 4,
-                       mclk_pad_ctrl_parent_names);
-
-static const char * const lrclk_pad_ctrl_parent_names[] = {
-       "aud_mst_a_lrclk", "aud_mst_b_lrclk", "aud_mst_c_lrclk",
-       "aud_mst_d_lrclk", "aud_mst_e_lrclk", "aud_mst_f_lrclk",
+                       mclk_pad_ctrl_parent_data);
+
+static const struct clk_parent_data lrclk_pad_ctrl_parent_data[] = {
+       { .hw = &aud_mst_a_lrclk.hw },
+       { .hw = &aud_mst_b_lrclk.hw },
+       { .hw = &aud_mst_c_lrclk.hw },
+       { .hw = &aud_mst_d_lrclk.hw },
+       { .hw = &aud_mst_e_lrclk.hw },
+       { .hw = &aud_mst_f_lrclk.hw },
 };
 
 static AUD_TDM_PAD_CTRL(lrclk_pad_0, AUDIO_MST_PAD_CTRL1, 16,
-                       lrclk_pad_ctrl_parent_names);
+                       lrclk_pad_ctrl_parent_data);
 static AUD_TDM_PAD_CTRL(lrclk_pad_1, AUDIO_MST_PAD_CTRL1, 20,
-                       lrclk_pad_ctrl_parent_names);
+                       lrclk_pad_ctrl_parent_data);
 static AUD_TDM_PAD_CTRL(lrclk_pad_2, AUDIO_MST_PAD_CTRL1, 24,
-                       lrclk_pad_ctrl_parent_names);
-
-static const char * const sclk_pad_ctrl_parent_names[] = {
-       "aud_mst_a_sclk", "aud_mst_b_sclk", "aud_mst_c_sclk",
-       "aud_mst_d_sclk", "aud_mst_e_sclk", "aud_mst_f_sclk",
+                       lrclk_pad_ctrl_parent_data);
+
+static const struct clk_parent_data sclk_pad_ctrl_parent_data[] = {
+       { .hw = &aud_mst_a_sclk.hw },
+       { .hw = &aud_mst_b_sclk.hw },
+       { .hw = &aud_mst_c_sclk.hw },
+       { .hw = &aud_mst_d_sclk.hw },
+       { .hw = &aud_mst_e_sclk.hw },
+       { .hw = &aud_mst_f_sclk.hw },
 };
 
 static AUD_TDM_PAD_CTRL(sclk_pad_0, AUDIO_MST_PAD_CTRL1, 0,
-                       sclk_pad_ctrl_parent_names);
+                       sclk_pad_ctrl_parent_data);
 static AUD_TDM_PAD_CTRL(sclk_pad_1, AUDIO_MST_PAD_CTRL1, 4,
-                       sclk_pad_ctrl_parent_names);
+                       sclk_pad_ctrl_parent_data);
 static AUD_TDM_PAD_CTRL(sclk_pad_2, AUDIO_MST_PAD_CTRL1, 8,
-                       sclk_pad_ctrl_parent_names);
+                       sclk_pad_ctrl_parent_data);
 
 /*
  * Array of all clocks provided by this provider
@@ -868,54 +919,84 @@ static int devm_clk_get_enable(struct device *dev, char *id)
        return 0;
 }
 
-static int axg_register_clk_hw_input(struct device *dev,
-                                    const char *name)
+struct axg_audio_reset_data {
+       struct reset_controller_dev rstc;
+       struct regmap *map;
+       unsigned int offset;
+};
+
+static void axg_audio_reset_reg_and_bit(struct axg_audio_reset_data *rst,
+                                       unsigned long id,
+                                       unsigned int *reg,
+                                       unsigned int *bit)
 {
-       char *clk_name;
-       struct clk_hw *hw;
-       int err = 0;
+       unsigned int stride = regmap_get_reg_stride(rst->map);
 
-       clk_name = kasprintf(GFP_KERNEL, "aud_%s", name);
-       if (!clk_name)
-               return -ENOMEM;
+       *reg = (id / (stride * BITS_PER_BYTE)) * stride;
+       *reg += rst->offset;
+       *bit = id % (stride * BITS_PER_BYTE);
+}
 
-       hw = meson_clk_hw_register_input(dev, name, clk_name, 0);
-       if (IS_ERR(hw)) {
-               /* It is ok if an input clock is missing */
-               if (PTR_ERR(hw) == -ENOENT) {
-                       dev_dbg(dev, "%s not provided", name);
-               } else {
-                       err = PTR_ERR(hw);
-                       if (err != -EPROBE_DEFER)
-                               dev_err(dev, "failed to get %s clock", name);
-               }
-       }
+static int axg_audio_reset_update(struct reset_controller_dev *rcdev,
+                               unsigned long id, bool assert)
+{
+       struct axg_audio_reset_data *rst =
+               container_of(rcdev, struct axg_audio_reset_data, rstc);
+       unsigned int offset, bit;
+
+       axg_audio_reset_reg_and_bit(rst, id, &offset, &bit);
 
-       kfree(clk_name);
-       return err;
+       regmap_update_bits(rst->map, offset, BIT(bit),
+                       assert ? BIT(bit) : 0);
+
+       return 0;
 }
 
-static int axg_register_clk_hw_inputs(struct device *dev,
-                                     const char *basename,
-                                     unsigned int count)
+static int axg_audio_reset_status(struct reset_controller_dev *rcdev,
+                               unsigned long id)
 {
-       char *name;
-       int i, ret;
+       struct axg_audio_reset_data *rst =
+               container_of(rcdev, struct axg_audio_reset_data, rstc);
+       unsigned int val, offset, bit;
 
-       for (i = 0; i < count; i++) {
-               name = kasprintf(GFP_KERNEL, "%s%d", basename, i);
-               if (!name)
-                       return -ENOMEM;
+       axg_audio_reset_reg_and_bit(rst, id, &offset, &bit);
 
-               ret = axg_register_clk_hw_input(dev, name);
-               kfree(name);
-               if (ret)
-                       return ret;
-       }
+       regmap_read(rst->map, offset, &val);
 
-       return 0;
+       return !!(val & BIT(bit));
+}
+
+static int axg_audio_reset_assert(struct reset_controller_dev *rcdev,
+                               unsigned long id)
+{
+       return axg_audio_reset_update(rcdev, id, true);
 }
 
+static int axg_audio_reset_deassert(struct reset_controller_dev *rcdev,
+                               unsigned long id)
+{
+       return axg_audio_reset_update(rcdev, id, false);
+}
+
+static int axg_audio_reset_toggle(struct reset_controller_dev *rcdev,
+                               unsigned long id)
+{
+       int ret;
+
+       ret = axg_audio_reset_assert(rcdev, id);
+       if (ret)
+               return ret;
+
+       return axg_audio_reset_deassert(rcdev, id);
+}
+
+static const struct reset_control_ops axg_audio_rstc_ops = {
+       .assert = axg_audio_reset_assert,
+       .deassert = axg_audio_reset_deassert,
+       .reset = axg_audio_reset_toggle,
+       .status = axg_audio_reset_status,
+};
+
 static const struct regmap_config axg_audio_regmap_cfg = {
        .reg_bits       = 32,
        .val_bits       = 32,
@@ -925,12 +1006,15 @@ static const struct regmap_config axg_audio_regmap_cfg = {
 
 struct audioclk_data {
        struct clk_hw_onecell_data *hw_onecell_data;
+       unsigned int reset_offset;
+       unsigned int reset_num;
 };
 
 static int axg_audio_clkc_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        const struct audioclk_data *data;
+       struct axg_audio_reset_data *rst;
        struct regmap *map;
        struct resource *res;
        void __iomem *regs;
@@ -963,50 +1047,49 @@ static int axg_audio_clkc_probe(struct platform_device *pdev)
                return ret;
        }
 
-       /* Register the peripheral input clock */
-       hw = meson_clk_hw_register_input(dev, "pclk", "audio_pclk", 0);
-       if (IS_ERR(hw))
-               return PTR_ERR(hw);
-
-       /* Register optional input master clocks */
-       ret = axg_register_clk_hw_inputs(dev, "mst_in",
-                                        AUD_MST_IN_COUNT);
-       if (ret)
-               return ret;
-
-       /* Register optional input slave sclks */
-       ret = axg_register_clk_hw_inputs(dev, "slv_sclk",
-                                        AUD_SLV_SCLK_COUNT);
-       if (ret)
-               return ret;
-
-       /* Register optional input slave lrclks */
-       ret = axg_register_clk_hw_inputs(dev, "slv_lrclk",
-                                        AUD_SLV_LRCLK_COUNT);
-       if (ret)
-               return ret;
-
        /* Populate regmap for the regmap backed clocks */
        for (i = 0; i < ARRAY_SIZE(aud_clk_regmaps); i++)
                aud_clk_regmaps[i]->map = map;
 
        /* Take care to skip the registered input clocks */
        for (i = AUD_CLKID_DDR_ARB; i < data->hw_onecell_data->num; i++) {
+               const char *name;
+
                hw = data->hw_onecell_data->hws[i];
                /* array might be sparse */
                if (!hw)
                        continue;
 
+               name = hw->init->name;
+
                ret = devm_clk_hw_register(dev, hw);
                if (ret) {
-                       dev_err(dev, "failed to register clock %s\n",
-                               hw->init->name);
+                       dev_err(dev, "failed to register clock %s\n", name);
                        return ret;
                }
        }
 
-       return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
-                                          data->hw_onecell_data);
+       ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+                                       data->hw_onecell_data);
+       if (ret)
+               return ret;
+
+       /* Stop here if there is no reset */
+       if (!data->reset_num)
+               return 0;
+
+       rst = devm_kzalloc(dev, sizeof(*rst), GFP_KERNEL);
+       if (!rst)
+               return -ENOMEM;
+
+       rst->map = map;
+       rst->offset = data->reset_offset;
+       rst->rstc.nr_resets = data->reset_num;
+       rst->rstc.ops = &axg_audio_rstc_ops;
+       rst->rstc.of_node = dev->of_node;
+       rst->rstc.owner = THIS_MODULE;
+
+       return devm_reset_controller_register(dev, &rst->rstc);
 }
 
 static const struct audioclk_data axg_audioclk_data = {
@@ -1015,6 +1098,8 @@ static const struct audioclk_data axg_audioclk_data = {
 
 static const struct audioclk_data g12a_audioclk_data = {
        .hw_onecell_data = &g12a_audio_hw_onecell_data,
+       .reset_offset = AUDIO_SW_RESET,
+       .reset_num = 26,
 };
 
 static const struct of_device_id clkc_match_table[] = {
index 5d972d55d6c741ef8ee80fd0c3012ba6b558f0c9..c00e28b2e1a962d3db3a9e20fdf033ecc6168473 100644 (file)
@@ -22,6 +22,7 @@
 #define AUDIO_MCLK_F_CTRL      0x018
 #define AUDIO_MST_PAD_CTRL0    0x01c
 #define AUDIO_MST_PAD_CTRL1    0x020
+#define AUDIO_SW_RESET         0x024
 #define AUDIO_MST_A_SCLK_CTRL0 0x040
 #define AUDIO_MST_A_SCLK_CTRL1 0x044
 #define AUDIO_MST_B_SCLK_CTRL0 0x048
index 3ddd0efc9ee0b7a2d233888e1650361929511f86..13fc0006f63d82f4de17a376ecafe9344907e93f 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
-#include "clk-input.h"
 #include "clk-regmap.h"
 #include "clk-pll.h"
 #include "clk-mpll.h"
@@ -59,7 +58,9 @@ static struct clk_regmap axg_fixed_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -74,7 +75,9 @@ static struct clk_regmap axg_fixed_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_fixed_pll_dco.hw
+               },
                .num_parents = 1,
                /*
                 * This clock won't ever change at runtime so
@@ -114,7 +117,9 @@ static struct clk_regmap axg_sys_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -129,7 +134,9 @@ static struct clk_regmap axg_sys_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "sys_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_sys_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -215,7 +222,9 @@ static struct clk_regmap axg_gp0_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "gp0_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -230,7 +239,9 @@ static struct clk_regmap axg_gp0_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "gp0_pll",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "gp0_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_gp0_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -284,7 +295,9 @@ static struct clk_regmap axg_hifi_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "hifi_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -299,7 +312,9 @@ static struct clk_regmap axg_hifi_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "hifi_pll",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "hifi_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_hifi_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -311,7 +326,7 @@ static struct clk_fixed_factor axg_fclk_div2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div2_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -324,7 +339,9 @@ static struct clk_regmap axg_fclk_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div2_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_fclk_div2_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_IS_CRITICAL,
        },
@@ -336,7 +353,7 @@ static struct clk_fixed_factor axg_fclk_div3_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div3_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -349,7 +366,9 @@ static struct clk_regmap axg_fclk_div3 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div3",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div3_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_fclk_div3_div.hw
+               },
                .num_parents = 1,
                /*
                 * FIXME:
@@ -372,7 +391,7 @@ static struct clk_fixed_factor axg_fclk_div4_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div4_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -385,7 +404,9 @@ static struct clk_regmap axg_fclk_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div4",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div4_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_fclk_div4_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -396,7 +417,7 @@ static struct clk_fixed_factor axg_fclk_div5_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div5_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -409,7 +430,9 @@ static struct clk_regmap axg_fclk_div5 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div5",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div5_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_fclk_div5_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -420,7 +443,9 @@ static struct clk_fixed_factor axg_fclk_div7_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div7_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -433,7 +458,9 @@ static struct clk_regmap axg_fclk_div7 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div7",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div7_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_fclk_div7_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -447,7 +474,9 @@ static struct clk_regmap axg_mpll_prediv = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll_prediv",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -480,7 +509,9 @@ static struct clk_regmap axg_mpll0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -493,7 +524,9 @@ static struct clk_regmap axg_mpll0 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpll0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -527,7 +560,9 @@ static struct clk_regmap axg_mpll1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll1_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -540,7 +575,9 @@ static struct clk_regmap axg_mpll1 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpll1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -579,7 +616,9 @@ static struct clk_regmap axg_mpll2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll2_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -592,7 +631,9 @@ static struct clk_regmap axg_mpll2 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll2_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpll2_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -626,7 +667,9 @@ static struct clk_regmap axg_mpll3_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll3_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -639,7 +682,9 @@ static struct clk_regmap axg_mpll3 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll3",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll3_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpll3_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -702,7 +747,9 @@ static struct clk_regmap axg_pcie_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -717,7 +764,9 @@ static struct clk_regmap axg_pcie_pll_od = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_pll_od",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "pcie_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_pcie_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -733,7 +782,9 @@ static struct clk_regmap axg_pcie_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_pll",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "pcie_pll_od" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_pcie_pll_od.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -750,7 +801,7 @@ static struct clk_regmap axg_pcie_mux = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_mux",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "pcie_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &axg_pcie_pll.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -767,7 +818,7 @@ static struct clk_regmap axg_pcie_ref = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_ref",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "pcie_mux" },
+               .parent_hws = (const struct clk_hw *[]) { &axg_pcie_mux.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -781,7 +832,7 @@ static struct clk_regmap axg_pcie_cml_en0 = {
        .hw.init = &(struct clk_init_data) {
                .name = "pcie_cml_en0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "pcie_ref" },
+               .parent_hws = (const struct clk_hw *[]) { &axg_pcie_ref.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
 
@@ -796,16 +847,21 @@ static struct clk_regmap axg_pcie_cml_en1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "pcie_cml_en1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "pcie_ref" },
+               .parent_hws = (const struct clk_hw *[]) { &axg_pcie_ref.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
 static u32 mux_table_clk81[]   = { 0, 2, 3, 4, 5, 6, 7 };
-static const char * const clk81_parent_names[] = {
-       IN_PREFIX "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
-       "fclk_div3", "fclk_div5"
+static const struct clk_parent_data clk81_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &axg_fclk_div7.hw },
+       { .hw = &axg_mpll1.hw },
+       { .hw = &axg_mpll2.hw },
+       { .hw = &axg_fclk_div4.hw },
+       { .hw = &axg_fclk_div3.hw },
+       { .hw = &axg_fclk_div5.hw },
 };
 
 static struct clk_regmap axg_mpeg_clk_sel = {
@@ -818,8 +874,8 @@ static struct clk_regmap axg_mpeg_clk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "mpeg_clk_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = clk81_parent_names,
-               .num_parents = ARRAY_SIZE(clk81_parent_names),
+               .parent_data = clk81_parent_data,
+               .num_parents = ARRAY_SIZE(clk81_parent_data),
        },
 };
 
@@ -832,7 +888,9 @@ static struct clk_regmap axg_mpeg_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpeg_clk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpeg_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -846,15 +904,20 @@ static struct clk_regmap axg_clk81 = {
        .hw.init = &(struct clk_init_data){
                .name = "clk81",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpeg_clk_div.hw
+               },
                .num_parents = 1,
                .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
        },
 };
 
-static const char * const axg_sd_emmc_clk0_parent_names[] = {
-       IN_PREFIX "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
-
+static const struct clk_parent_data axg_sd_emmc_clk0_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &axg_fclk_div2.hw },
+       { .hw = &axg_fclk_div3.hw },
+       { .hw = &axg_fclk_div5.hw },
+       { .hw = &axg_fclk_div7.hw },
        /*
         * Following these parent clocks, we should also have had mpll2, mpll3
         * and gp0_pll but these clocks are too precious to be used here. All
@@ -873,8 +936,8 @@ static struct clk_regmap axg_sd_emmc_b_clk0_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_b_clk0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = axg_sd_emmc_clk0_parent_names,
-               .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names),
+               .parent_data = axg_sd_emmc_clk0_parent_data,
+               .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_data),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -889,7 +952,9 @@ static struct clk_regmap axg_sd_emmc_b_clk0_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_b_clk0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_sd_emmc_b_clk0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -903,7 +968,9 @@ static struct clk_regmap axg_sd_emmc_b_clk0 = {
        .hw.init = &(struct clk_init_data){
                .name = "sd_emmc_b_clk0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_sd_emmc_b_clk0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -919,8 +986,8 @@ static struct clk_regmap axg_sd_emmc_c_clk0_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_c_clk0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = axg_sd_emmc_clk0_parent_names,
-               .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names),
+               .parent_data = axg_sd_emmc_clk0_parent_data,
+               .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_data),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -935,7 +1002,9 @@ static struct clk_regmap axg_sd_emmc_c_clk0_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_c_clk0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_sd_emmc_c_clk0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -949,7 +1018,9 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = {
        .hw.init = &(struct clk_init_data){
                .name = "sd_emmc_c_clk0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_sd_emmc_c_clk0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -957,9 +1028,18 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = {
 
 static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8,
                                    9, 10, 11, 13, 14, };
-static const char * const gen_clk_parent_names[] = {
-       IN_PREFIX "xtal", "hifi_pll", "mpll0", "mpll1", "mpll2", "mpll3",
-       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll",
+static const struct clk_parent_data gen_clk_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &axg_hifi_pll.hw },
+       { .hw = &axg_mpll0.hw },
+       { .hw = &axg_mpll1.hw },
+       { .hw = &axg_mpll2.hw },
+       { .hw = &axg_mpll3.hw },
+       { .hw = &axg_fclk_div4.hw },
+       { .hw = &axg_fclk_div3.hw },
+       { .hw = &axg_fclk_div5.hw },
+       { .hw = &axg_fclk_div7.hw },
+       { .hw = &axg_gp0_pll.hw },
 };
 
 static struct clk_regmap axg_gen_clk_sel = {
@@ -978,8 +1058,8 @@ static struct clk_regmap axg_gen_clk_sel = {
                 * hifi_pll, mpll0, mpll1, mpll2, mpll3, fdiv4,
                 * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll
                 */
-               .parent_names = gen_clk_parent_names,
-               .num_parents = ARRAY_SIZE(gen_clk_parent_names),
+               .parent_data = gen_clk_parent_data,
+               .num_parents = ARRAY_SIZE(gen_clk_parent_data),
        },
 };
 
@@ -992,7 +1072,9 @@ static struct clk_regmap axg_gen_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "gen_clk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "gen_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_gen_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1006,12 +1088,17 @@ static struct clk_regmap axg_gen_clk = {
        .hw.init = &(struct clk_init_data){
                .name = "gen_clk",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "gen_clk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_gen_clk_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
+#define MESON_GATE(_name, _reg, _bit) \
+       MESON_PCLK(_name, _reg, _bit, &axg_clk81.hw)
+
 /* Everything Else (EE) domain gates */
 static MESON_GATE(axg_ddr, HHI_GCLK_MPEG0, 0);
 static MESON_GATE(axg_audio_locker, HHI_GCLK_MPEG0, 2);
diff --git a/drivers/clk/meson/clk-cpu-dyndiv.c b/drivers/clk/meson/clk-cpu-dyndiv.c
new file mode 100644 (file)
index 0000000..3697692
--- /dev/null
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+
+#include "clk-regmap.h"
+#include "clk-cpu-dyndiv.h"
+
+static inline struct meson_clk_cpu_dyndiv_data *
+meson_clk_cpu_dyndiv_data(struct clk_regmap *clk)
+{
+       return (struct meson_clk_cpu_dyndiv_data *)clk->data;
+}
+
+static unsigned long meson_clk_cpu_dyndiv_recalc_rate(struct clk_hw *hw,
+                                                     unsigned long prate)
+{
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_clk_cpu_dyndiv_data *data = meson_clk_cpu_dyndiv_data(clk);
+
+       return divider_recalc_rate(hw, prate,
+                                  meson_parm_read(clk->map, &data->div),
+                                  NULL, 0, data->div.width);
+}
+
+static long meson_clk_cpu_dyndiv_round_rate(struct clk_hw *hw,
+                                           unsigned long rate,
+                                           unsigned long *prate)
+{
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_clk_cpu_dyndiv_data *data = meson_clk_cpu_dyndiv_data(clk);
+
+       return divider_round_rate(hw, rate, prate, NULL, data->div.width, 0);
+}
+
+static int meson_clk_cpu_dyndiv_set_rate(struct clk_hw *hw, unsigned long rate,
+                                         unsigned long parent_rate)
+{
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_clk_cpu_dyndiv_data *data = meson_clk_cpu_dyndiv_data(clk);
+       unsigned int val;
+       int ret;
+
+       ret = divider_get_val(rate, parent_rate, NULL, data->div.width, 0);
+       if (ret < 0)
+               return ret;
+
+       val = (unsigned int)ret << data->div.shift;
+
+       /* Write the SYS_CPU_DYN_ENABLE bit before changing the divider */
+       meson_parm_write(clk->map, &data->dyn, 1);
+
+       /* Update the divider while removing the SYS_CPU_DYN_ENABLE bit */
+       return regmap_update_bits(clk->map, data->div.reg_off,
+                                 SETPMASK(data->div.width, data->div.shift) |
+                                 SETPMASK(data->dyn.width, data->dyn.shift),
+                                 val);
+};
+
+const struct clk_ops meson_clk_cpu_dyndiv_ops = {
+       .recalc_rate = meson_clk_cpu_dyndiv_recalc_rate,
+       .round_rate = meson_clk_cpu_dyndiv_round_rate,
+       .set_rate = meson_clk_cpu_dyndiv_set_rate,
+};
+EXPORT_SYMBOL_GPL(meson_clk_cpu_dyndiv_ops);
+
+MODULE_DESCRIPTION("Amlogic CPU Dynamic Clock divider");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-cpu-dyndiv.h b/drivers/clk/meson/clk-cpu-dyndiv.h
new file mode 100644 (file)
index 0000000..f490840
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#ifndef __MESON_CLK_CPU_DYNDIV_H
+#define __MESON_CLK_CPU_DYNDIV_H
+
+#include <linux/clk-provider.h>
+#include "parm.h"
+
+struct meson_clk_cpu_dyndiv_data {
+       struct parm div;
+       struct parm dyn;
+};
+
+extern const struct clk_ops meson_clk_cpu_dyndiv_ops;
+
+#endif /* __MESON_CLK_CPU_DYNDIV_H */
diff --git a/drivers/clk/meson/clk-input.c b/drivers/clk/meson/clk-input.c
deleted file mode 100644 (file)
index 086226e..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (c) 2018 BayLibre, SAS.
- * Author: Jerome Brunet <jbrunet@baylibre.com>
- */
-
-#include <linux/clk.h>
-#include <linux/clk-provider.h>
-#include <linux/device.h>
-#include <linux/module.h>
-#include "clk-input.h"
-
-static const struct clk_ops meson_clk_no_ops = {};
-
-struct clk_hw *meson_clk_hw_register_input(struct device *dev,
-                                          const char *of_name,
-                                          const char *clk_name,
-                                          unsigned long flags)
-{
-       struct clk *parent_clk = devm_clk_get(dev, of_name);
-       struct clk_init_data init;
-       const char *parent_name;
-       struct clk_hw *hw;
-       int ret;
-
-       if (IS_ERR(parent_clk))
-               return (struct clk_hw *)parent_clk;
-
-       hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
-       if (!hw)
-               return ERR_PTR(-ENOMEM);
-
-       parent_name = __clk_get_name(parent_clk);
-       init.name = clk_name;
-       init.ops = &meson_clk_no_ops;
-       init.flags = flags;
-       init.parent_names = &parent_name;
-       init.num_parents = 1;
-       hw->init = &init;
-
-       ret = devm_clk_hw_register(dev, hw);
-
-       return ret ? ERR_PTR(ret) : hw;
-}
-EXPORT_SYMBOL_GPL(meson_clk_hw_register_input);
-
-MODULE_DESCRIPTION("Amlogic clock input helper");
-MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-input.h b/drivers/clk/meson/clk-input.h
deleted file mode 100644 (file)
index 4a541b9..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2019 BayLibre, SAS.
- * Author: Jerome Brunet <jbrunet@baylibre.com>
- */
-
-#ifndef __MESON_CLK_INPUT_H
-#define __MESON_CLK_INPUT_H
-
-#include <linux/clk-provider.h>
-
-struct device;
-
-struct clk_hw *meson_clk_hw_register_input(struct device *dev,
-                                          const char *of_name,
-                                          const char *clk_name,
-                                          unsigned long flags);
-
-#endif /* __MESON_CLK_INPUT_H */
index 1dd0abe3ba91a48f2fb290f5958a6b8d81f68348..c4a39604cffdd32a5904f21a429b0dee378610e3 100644 (file)
@@ -111,7 +111,7 @@ clk_get_regmap_mux_data(struct clk_regmap *clk)
 extern const struct clk_ops clk_regmap_mux_ops;
 extern const struct clk_ops clk_regmap_mux_ro_ops;
 
-#define __MESON_GATE(_name, _reg, _bit, _ops)                          \
+#define __MESON_PCLK(_name, _reg, _bit, _ops, _pname)                  \
 struct clk_regmap _name = {                                            \
        .data = &(struct clk_regmap_gate_data){                         \
                .offset = (_reg),                                       \
@@ -120,15 +120,15 @@ struct clk_regmap _name = {                                               \
        .hw.init = &(struct clk_init_data) {                            \
                .name = #_name,                                         \
                .ops = _ops,                                            \
-               .parent_names = (const char *[]){ "clk81" },            \
+               .parent_hws = (const struct clk_hw *[]) { _pname },     \
                .num_parents = 1,                                       \
                .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),     \
        },                                                              \
 }
 
-#define MESON_GATE(_name, _reg, _bit)  \
-       __MESON_GATE(_name, _reg, _bit, &clk_regmap_gate_ops)
+#define MESON_PCLK(_name, _reg, _bit, _pname)  \
+       __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ops, _pname)
 
-#define MESON_GATE_RO(_name, _reg, _bit)       \
-       __MESON_GATE(_name, _reg, _bit, &clk_regmap_gate_ro_ops)
+#define MESON_PCLK_RO(_name, _reg, _bit, _pname)       \
+       __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ro_ops, _pname)
 #endif /* __CLK_REGMAP_H */
index 1994e735396b53aae310390405f8b04a95499101..62499563e4f5a5f2942cbcadaf624376c82ff9e9 100644 (file)
@@ -18,8 +18,6 @@
 #include "clk-regmap.h"
 #include "clk-dualdiv.h"
 
-#define IN_PREFIX "ao-in-"
-
 /*
  * AO Configuration Clock registers offsets
  * Register offsets from the data sheet must be multiplied by 4.
@@ -51,7 +49,9 @@ static struct clk_regmap g12a_aoclk_##_name = {                               \
        .hw.init = &(struct clk_init_data) {                            \
                .name =  "g12a_ao_" #_name,                             \
                .ops = &clk_regmap_gate_ops,                            \
-               .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \
+               .parent_data = &(const struct clk_parent_data) {        \
+                       .fw_name = "mpeg-clk",                          \
+               },                                                      \
                .num_parents = 1,                                       \
                .flags = CLK_IGNORE_UNUSED,                             \
        },                                                              \
@@ -81,7 +81,9 @@ static struct clk_regmap g12a_aoclk_cts_oscin = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_oscin",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -106,7 +108,9 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_pre = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_32k_by_oscin_pre",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_oscin" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_cts_oscin.hw
+               },
                .num_parents = 1,
        },
 };
@@ -143,7 +147,9 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_div = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_32k_by_oscin_div",
                .ops = &meson_clk_dualdiv_ops,
-               .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_pre" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_32k_by_oscin_pre.hw
+               },
                .num_parents = 1,
        },
 };
@@ -158,8 +164,10 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_32k_by_oscin_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_div",
-                                                 "g12a_ao_32k_by_oscin_pre" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_32k_by_oscin_div.hw,
+                       &g12a_aoclk_32k_by_oscin_pre.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -173,7 +181,9 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_32k_by_oscin",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_32k_by_oscin_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -189,7 +199,9 @@ static struct clk_regmap g12a_aoclk_cec_pre = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_cec_pre",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_oscin" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_cts_oscin.hw
+               },
                .num_parents = 1,
        },
 };
@@ -226,7 +238,9 @@ static struct clk_regmap g12a_aoclk_cec_div = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_cec_div",
                .ops = &meson_clk_dualdiv_ops,
-               .parent_names = (const char *[]){ "g12a_ao_cec_pre" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_cec_pre.hw
+               },
                .num_parents = 1,
        },
 };
@@ -241,8 +255,10 @@ static struct clk_regmap g12a_aoclk_cec_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_cec_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "g12a_ao_cec_div",
-                                                 "g12a_ao_cec_pre" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_cec_div.hw,
+                       &g12a_aoclk_cec_pre.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -256,7 +272,9 @@ static struct clk_regmap g12a_aoclk_cec = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_cec",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "g12a_ao_cec_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_cec_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -272,8 +290,10 @@ static struct clk_regmap g12a_aoclk_cts_rtc_oscin = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_cts_rtc_oscin",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin",
-                                                 IN_PREFIX "ext_32k-0" },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .hw = &g12a_aoclk_32k_by_oscin.hw },
+                       { .fw_name = "ext-32k-0", },
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -289,8 +309,10 @@ static struct clk_regmap g12a_aoclk_clk81 = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_clk81",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk",
-                                                 "g12a_ao_cts_rtc_oscin"},
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "mpeg-clk", },
+                       { .hw = &g12a_aoclk_cts_rtc_oscin.hw },
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -305,8 +327,10 @@ static struct clk_regmap g12a_aoclk_saradc_mux = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_saradc_mux",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal",
-                                                 "g12a_ao_clk81" },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &g12a_aoclk_clk81.hw },
+               },
                .num_parents = 2,
        },
 };
@@ -320,7 +344,9 @@ static struct clk_regmap g12a_aoclk_saradc_div = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_saradc_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "g12a_ao_saradc_mux" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_saradc_mux.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -334,7 +360,9 @@ static struct clk_regmap g12a_aoclk_saradc_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_saradc_gate",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "g12a_ao_saradc_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_saradc_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -417,12 +445,6 @@ static const struct clk_hw_onecell_data g12a_aoclk_onecell_data = {
        .num = NR_CLKS,
 };
 
-static const struct meson_aoclk_input g12a_aoclk_inputs[] = {
-       { .name = "xtal",       .required = true  },
-       { .name = "mpeg-clk",   .required = true  },
-       { .name = "ext-32k-0",  .required = false },
-};
-
 static const struct meson_aoclk_data g12a_aoclkc_data = {
        .reset_reg      = AO_RTI_GEN_CNTL_REG0,
        .num_reset      = ARRAY_SIZE(g12a_aoclk_reset),
@@ -430,9 +452,6 @@ static const struct meson_aoclk_data g12a_aoclkc_data = {
        .num_clks       = ARRAY_SIZE(g12a_aoclk_regmap),
        .clks           = g12a_aoclk_regmap,
        .hw_data        = &g12a_aoclk_onecell_data,
-       .inputs         = g12a_aoclk_inputs,
-       .num_inputs     = ARRAY_SIZE(g12a_aoclk_inputs),
-       .input_prefix   = IN_PREFIX,
 };
 
 static const struct of_device_id g12a_aoclkc_match_table[] = {
index db1c4ed9d54e64248318ae635fc6638974a57846..ea4c791f106ddb9604779c7805168c059cbfbf8e 100644 (file)
 #include <linux/init.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/clk.h>
 
-#include "clk-input.h"
 #include "clk-mpll.h"
 #include "clk-pll.h"
 #include "clk-regmap.h"
+#include "clk-cpu-dyndiv.h"
 #include "vid-pll-div.h"
 #include "meson-eeclk.h"
 #include "g12a.h"
@@ -61,7 +62,9 @@ static struct clk_regmap g12a_fixed_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -76,7 +79,9 @@ static struct clk_regmap g12a_fixed_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fixed_pll_dco.hw
+               },
                .num_parents = 1,
                /*
                 * This clock won't ever change at runtime so
@@ -85,16 +90,9 @@ static struct clk_regmap g12a_fixed_pll = {
        },
 };
 
-/*
- * Internal sys pll emulation configuration parameters
- */
-static const struct reg_sequence g12a_sys_init_regs[] = {
-       { .reg = HHI_SYS_PLL_CNTL1,     .def = 0x00000000 },
-       { .reg = HHI_SYS_PLL_CNTL2,     .def = 0x00000000 },
-       { .reg = HHI_SYS_PLL_CNTL3,     .def = 0x48681c00 },
-       { .reg = HHI_SYS_PLL_CNTL4,     .def = 0x88770290 },
-       { .reg = HHI_SYS_PLL_CNTL5,     .def = 0x39272000 },
-       { .reg = HHI_SYS_PLL_CNTL6,     .def = 0x56540000 },
+static const struct pll_mult_range g12a_sys_pll_mult_range = {
+       .min = 128,
+       .max = 250,
 };
 
 static struct clk_regmap g12a_sys_pll_dco = {
@@ -124,14 +122,17 @@ static struct clk_regmap g12a_sys_pll_dco = {
                        .shift   = 29,
                        .width   = 1,
                },
-               .init_regs = g12a_sys_init_regs,
-               .init_count = ARRAY_SIZE(g12a_sys_init_regs),
+               .range = &g12a_sys_pll_mult_range,
        },
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll_dco",
-               .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .ops = &meson_clk_pll_ops,
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
+               /* This clock feeds the CPU, avoid disabling it */
+               .flags = CLK_IS_CRITICAL,
        },
 };
 
@@ -144,9 +145,12 @@ static struct clk_regmap g12a_sys_pll = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll",
-               .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "sys_pll_dco" },
+               .ops = &clk_regmap_divider_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_sys_pll_dco.hw
+               },
                .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -177,12 +181,17 @@ static struct clk_regmap g12b_sys1_pll_dco = {
                        .shift   = 29,
                        .width   = 1,
                },
+               .range = &g12a_sys_pll_mult_range,
        },
        .hw.init = &(struct clk_init_data){
                .name = "sys1_pll_dco",
-               .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .ops = &meson_clk_pll_ops,
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
+               /* This clock feeds the CPU, avoid disabling it */
+               .flags = CLK_IS_CRITICAL,
        },
 };
 
@@ -195,9 +204,12 @@ static struct clk_regmap g12b_sys1_pll = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "sys1_pll",
-               .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "sys1_pll_dco" },
+               .ops = &clk_regmap_divider_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_sys1_pll_dco.hw
+               },
                .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -209,7 +221,7 @@ static struct clk_regmap g12a_sys_pll_div16_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "sys_pll_div16_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "sys_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_sys_pll.hw },
                .num_parents = 1,
                /*
                 * This clock is used to debug the sys_pll range
@@ -226,7 +238,9 @@ static struct clk_regmap g12b_sys1_pll_div16_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "sys1_pll_div16_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "sys1_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_sys1_pll.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is used to debug the sys_pll range
@@ -241,7 +255,9 @@ static struct clk_fixed_factor g12a_sys_pll_div16 = {
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll_div16",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "sys_pll_div16_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_sys_pll_div16_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -252,11 +268,75 @@ static struct clk_fixed_factor g12b_sys1_pll_div16 = {
        .hw.init = &(struct clk_init_data){
                .name = "sys1_pll_div16",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "sys1_pll_div16_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_sys1_pll_div16_en.hw
+               },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor g12a_fclk_div2_div = {
+       .mult = 1,
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div2_div",
+               .ops = &clk_fixed_factor_ops,
+               .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_regmap g12a_fclk_div2 = {
+       .data = &(struct clk_regmap_gate_data){
+               .offset = HHI_FIX_PLL_CNTL1,
+               .bit_idx = 24,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div2",
+               .ops = &clk_regmap_gate_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fclk_div2_div.hw
+               },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor g12a_fclk_div3_div = {
+       .mult = 1,
+       .div = 3,
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div3_div",
+               .ops = &clk_fixed_factor_ops,
+               .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw },
                .num_parents = 1,
        },
 };
 
+static struct clk_regmap g12a_fclk_div3 = {
+       .data = &(struct clk_regmap_gate_data){
+               .offset = HHI_FIX_PLL_CNTL1,
+               .bit_idx = 20,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div3",
+               .ops = &clk_regmap_gate_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fclk_div3_div.hw
+               },
+               .num_parents = 1,
+               /*
+                * This clock is used by the resident firmware and is required
+                * by the platform to operate correctly.
+                * Until the following condition are met, we need this clock to
+                * be marked as critical:
+                * a) Mark the clock used by a firmware resource, if possible
+                * b) CCF has a clock hand-off mechanism to make the sure the
+                *    clock stays on until the proper driver comes along
+                */
+               .flags = CLK_IS_CRITICAL,
+       },
+};
+
 /* Datasheet names this field as "premux0" */
 static struct clk_regmap g12a_cpu_clk_premux0 = {
        .data = &(struct clk_regmap_mux_data){
@@ -266,26 +346,61 @@ static struct clk_regmap g12a_cpu_clk_premux0 = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_dyn0_sel",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal",
-                                                 "fclk_div2",
-                                                 "fclk_div3" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &g12a_fclk_div2.hw },
+                       { .hw = &g12a_fclk_div3.hw },
+               },
+               .num_parents = 3,
+               /* This sub-tree is used a parking clock */
+               .flags = CLK_SET_RATE_NO_REPARENT,
+       },
+};
+
+/* Datasheet names this field as "premux1" */
+static struct clk_regmap g12a_cpu_clk_premux1 = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL0,
+               .mask = 0x3,
+               .shift = 16,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_clk_dyn1_sel",
+               .ops = &clk_regmap_mux_ops,
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &g12a_fclk_div2.hw },
+                       { .hw = &g12a_fclk_div3.hw },
+               },
                .num_parents = 3,
+               /* This sub-tree is used a parking clock */
+               .flags = CLK_SET_RATE_NO_REPARENT
        },
 };
 
 /* Datasheet names this field as "mux0_divn_tcnt" */
 static struct clk_regmap g12a_cpu_clk_mux0_div = {
-       .data = &(struct clk_regmap_div_data){
-               .offset = HHI_SYS_CPU_CLK_CNTL0,
-               .shift = 4,
-               .width = 6,
+       .data = &(struct meson_clk_cpu_dyndiv_data){
+               .div = {
+                       .reg_off = HHI_SYS_CPU_CLK_CNTL0,
+                       .shift = 4,
+                       .width = 6,
+               },
+               .dyn = {
+                       .reg_off = HHI_SYS_CPU_CLK_CNTL0,
+                       .shift = 26,
+                       .width = 1,
+               },
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_dyn0_div",
-               .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_dyn0_sel" },
+               .ops = &meson_clk_cpu_dyndiv_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_premux0.hw
+               },
                .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -298,27 +413,13 @@ static struct clk_regmap g12a_cpu_clk_postmux0 = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_dyn0",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_dyn0_sel",
-                                                 "cpu_clk_dyn0_div" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_premux0.hw,
+                       &g12a_cpu_clk_mux0_div.hw,
+               },
                .num_parents = 2,
-       },
-};
-
-/* Datasheet names this field as "premux1" */
-static struct clk_regmap g12a_cpu_clk_premux1 = {
-       .data = &(struct clk_regmap_mux_data){
-               .offset = HHI_SYS_CPU_CLK_CNTL0,
-               .mask = 0x3,
-               .shift = 16,
-       },
-       .hw.init = &(struct clk_init_data){
-               .name = "cpu_clk_dyn1_sel",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal",
-                                                 "fclk_div2",
-                                                 "fclk_div3" },
-               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -332,7 +433,9 @@ static struct clk_regmap g12a_cpu_clk_mux1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_dyn1_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_dyn1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_premux1.hw
+               },
                .num_parents = 1,
        },
 };
@@ -346,10 +449,14 @@ static struct clk_regmap g12a_cpu_clk_postmux1 = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_dyn1",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_dyn1_sel",
-                                                 "cpu_clk_dyn1_div" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_premux1.hw,
+                       &g12a_cpu_clk_mux1_div.hw,
+               },
                .num_parents = 2,
+               /* This sub-tree is used a parking clock */
+               .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
 
@@ -362,10 +469,13 @@ static struct clk_regmap g12a_cpu_clk_dyn = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_dyn",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_dyn0",
-                                                 "cpu_clk_dyn1" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_postmux0.hw,
+                       &g12a_cpu_clk_postmux1.hw,
+               },
                .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -378,10 +488,13 @@ static struct clk_regmap g12a_cpu_clk = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_dyn",
-                                                 "sys_pll" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_dyn.hw,
+                       &g12a_sys_pll.hw,
+               },
                .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -394,10 +507,13 @@ static struct clk_regmap g12b_cpu_clk = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_dyn",
-                                                 "sys1_pll" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_dyn.hw,
+                       &g12b_sys1_pll.hw
+               },
                .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -410,26 +526,38 @@ static struct clk_regmap g12b_cpub_clk_premux0 = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn0_sel",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal",
-                                                 "fclk_div2",
-                                                 "fclk_div3" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &g12a_fclk_div2.hw },
+                       { .hw = &g12a_fclk_div3.hw },
+               },
                .num_parents = 3,
        },
 };
 
 /* Datasheet names this field as "mux0_divn_tcnt" */
 static struct clk_regmap g12b_cpub_clk_mux0_div = {
-       .data = &(struct clk_regmap_div_data){
-               .offset = HHI_SYS_CPUB_CLK_CNTL,
-               .shift = 4,
-               .width = 6,
+       .data = &(struct meson_clk_cpu_dyndiv_data){
+               .div = {
+                       .reg_off = HHI_SYS_CPUB_CLK_CNTL,
+                       .shift = 4,
+                       .width = 6,
+               },
+               .dyn = {
+                       .reg_off = HHI_SYS_CPUB_CLK_CNTL,
+                       .shift = 26,
+                       .width = 1,
+               },
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn0_div",
-               .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_dyn0_sel" },
+               .ops = &meson_clk_cpu_dyndiv_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_premux0.hw
+               },
                .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -442,10 +570,13 @@ static struct clk_regmap g12b_cpub_clk_postmux0 = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn0",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_dyn0_sel",
-                                                 "cpub_clk_dyn0_div" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_premux0.hw,
+                       &g12b_cpub_clk_mux0_div.hw
+               },
                .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -458,11 +589,15 @@ static struct clk_regmap g12b_cpub_clk_premux1 = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn1_sel",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal",
-                                                 "fclk_div2",
-                                                 "fclk_div3" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &g12a_fclk_div2.hw },
+                       { .hw = &g12a_fclk_div3.hw },
+               },
                .num_parents = 3,
+               /* This sub-tree is used a parking clock */
+               .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
 
@@ -476,7 +611,9 @@ static struct clk_regmap g12b_cpub_clk_mux1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn1_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_dyn1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_premux1.hw
+               },
                .num_parents = 1,
        },
 };
@@ -490,10 +627,14 @@ static struct clk_regmap g12b_cpub_clk_postmux1 = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn1",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_dyn1_sel",
-                                                 "cpub_clk_dyn1_div" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_premux1.hw,
+                       &g12b_cpub_clk_mux1_div.hw
+               },
                .num_parents = 2,
+               /* This sub-tree is used a parking clock */
+               .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
 
@@ -506,10 +647,13 @@ static struct clk_regmap g12b_cpub_clk_dyn = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_dyn0",
-                                                 "cpub_clk_dyn1" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_postmux0.hw,
+                       &g12b_cpub_clk_postmux1.hw
+               },
                .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -522,13 +666,447 @@ static struct clk_regmap g12b_cpub_clk = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk",
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_dyn.hw,
+                       &g12a_sys_pll.hw
+               },
+               .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_regmap sm1_gp1_pll;
+
+/* Datasheet names this field as "premux0" */
+static struct clk_regmap sm1_dsu_clk_premux0 = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL5,
+               .mask = 0x3,
+               .shift = 0,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "dsu_clk_dyn0_sel",
+               .ops = &clk_regmap_mux_ro_ops,
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &g12a_fclk_div2.hw },
+                       { .hw = &g12a_fclk_div3.hw },
+                       { .hw = &sm1_gp1_pll.hw },
+               },
+               .num_parents = 4,
+       },
+};
+
+/* Datasheet names this field as "premux1" */
+static struct clk_regmap sm1_dsu_clk_premux1 = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL5,
+               .mask = 0x3,
+               .shift = 16,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "dsu_clk_dyn1_sel",
+               .ops = &clk_regmap_mux_ro_ops,
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &g12a_fclk_div2.hw },
+                       { .hw = &g12a_fclk_div3.hw },
+                       { .hw = &sm1_gp1_pll.hw },
+               },
+               .num_parents = 4,
+       },
+};
+
+/* Datasheet names this field as "Mux0_divn_tcnt" */
+static struct clk_regmap sm1_dsu_clk_mux0_div = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL5,
+               .shift = 4,
+               .width = 6,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "dsu_clk_dyn0_div",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &sm1_dsu_clk_premux0.hw
+               },
+               .num_parents = 1,
+       },
+};
+
+/* Datasheet names this field as "postmux0" */
+static struct clk_regmap sm1_dsu_clk_postmux0 = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL5,
+               .mask = 0x1,
+               .shift = 2,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "dsu_clk_dyn0",
+               .ops = &clk_regmap_mux_ro_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &sm1_dsu_clk_premux0.hw,
+                       &sm1_dsu_clk_mux0_div.hw,
+               },
+               .num_parents = 2,
+       },
+};
+
+/* Datasheet names this field as "Mux1_divn_tcnt" */
+static struct clk_regmap sm1_dsu_clk_mux1_div = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL5,
+               .shift = 20,
+               .width = 6,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "dsu_clk_dyn1_div",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &sm1_dsu_clk_premux1.hw
+               },
+               .num_parents = 1,
+       },
+};
+
+/* Datasheet names this field as "postmux1" */
+static struct clk_regmap sm1_dsu_clk_postmux1 = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL5,
+               .mask = 0x1,
+               .shift = 18,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "dsu_clk_dyn1",
+               .ops = &clk_regmap_mux_ro_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &sm1_dsu_clk_premux1.hw,
+                       &sm1_dsu_clk_mux1_div.hw,
+               },
+               .num_parents = 2,
+       },
+};
+
+/* Datasheet names this field as "Final_dyn_mux_sel" */
+static struct clk_regmap sm1_dsu_clk_dyn = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL5,
+               .mask = 0x1,
+               .shift = 10,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "dsu_clk_dyn",
+               .ops = &clk_regmap_mux_ro_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &sm1_dsu_clk_postmux0.hw,
+                       &sm1_dsu_clk_postmux1.hw,
+               },
+               .num_parents = 2,
+       },
+};
+
+/* Datasheet names this field as "Final_mux_sel" */
+static struct clk_regmap sm1_dsu_final_clk = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL5,
+               .mask = 0x1,
+               .shift = 11,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "dsu_clk_final",
+               .ops = &clk_regmap_mux_ro_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &sm1_dsu_clk_dyn.hw,
+                       &g12a_sys_pll.hw,
+               },
+               .num_parents = 2,
+       },
+};
+
+/* Datasheet names this field as "Cpu_clk_sync_mux_sel" bit 0 */
+static struct clk_regmap sm1_cpu1_clk = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL6,
+               .mask = 0x1,
+               .shift = 24,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu1_clk",
+               .ops = &clk_regmap_mux_ro_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk.hw,
+                       /* This CPU also have a dedicated clock tree */
+               },
+               .num_parents = 1,
+       },
+};
+
+/* Datasheet names this field as "Cpu_clk_sync_mux_sel" bit 1 */
+static struct clk_regmap sm1_cpu2_clk = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL6,
+               .mask = 0x1,
+               .shift = 25,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu2_clk",
+               .ops = &clk_regmap_mux_ro_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk.hw,
+                       /* This CPU also have a dedicated clock tree */
+               },
+               .num_parents = 1,
+       },
+};
+
+/* Datasheet names this field as "Cpu_clk_sync_mux_sel" bit 2 */
+static struct clk_regmap sm1_cpu3_clk = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL6,
+               .mask = 0x1,
+               .shift = 26,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu3_clk",
+               .ops = &clk_regmap_mux_ro_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk.hw,
+                       /* This CPU also have a dedicated clock tree */
+               },
+               .num_parents = 1,
+       },
+};
+
+/* Datasheet names this field as "Cpu_clk_sync_mux_sel" bit 4 */
+static struct clk_regmap sm1_dsu_clk = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL6,
+               .mask = 0x1,
+               .shift = 27,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "dsu_clk",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_dyn",
-                                                 "sys_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk.hw,
+                       &sm1_dsu_final_clk.hw,
+               },
                .num_parents = 2,
        },
 };
 
+static int g12a_cpu_clk_mux_notifier_cb(struct notifier_block *nb,
+                                       unsigned long event, void *data)
+{
+       if (event == POST_RATE_CHANGE || event == PRE_RATE_CHANGE) {
+               /* Wait for clock propagation before/after changing the mux */
+               udelay(100);
+               return NOTIFY_OK;
+       }
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block g12a_cpu_clk_mux_nb = {
+       .notifier_call = g12a_cpu_clk_mux_notifier_cb,
+};
+
+struct g12a_cpu_clk_postmux_nb_data {
+       struct notifier_block nb;
+       struct clk_hw *xtal;
+       struct clk_hw *cpu_clk_dyn;
+       struct clk_hw *cpu_clk_postmux0;
+       struct clk_hw *cpu_clk_postmux1;
+       struct clk_hw *cpu_clk_premux1;
+};
+
+static int g12a_cpu_clk_postmux_notifier_cb(struct notifier_block *nb,
+                                           unsigned long event, void *data)
+{
+       struct g12a_cpu_clk_postmux_nb_data *nb_data =
+               container_of(nb, struct g12a_cpu_clk_postmux_nb_data, nb);
+
+       switch (event) {
+       case PRE_RATE_CHANGE:
+               /*
+                * This notifier means cpu_clk_postmux0 clock will be changed
+                * to feed cpu_clk, this is the current path :
+                * cpu_clk
+                *    \- cpu_clk_dyn
+                *          \- cpu_clk_postmux0
+                *                \- cpu_clk_muxX_div
+                *                      \- cpu_clk_premux0
+                *                              \- fclk_div3 or fclk_div2
+                *              OR
+                *                \- cpu_clk_premux0
+                *                      \- fclk_div3 or fclk_div2
+                */
+
+               /* Setup cpu_clk_premux1 to xtal */
+               clk_hw_set_parent(nb_data->cpu_clk_premux1,
+                                 nb_data->xtal);
+
+               /* Setup cpu_clk_postmux1 to bypass divider */
+               clk_hw_set_parent(nb_data->cpu_clk_postmux1,
+                                 nb_data->cpu_clk_premux1);
+
+               /* Switch to parking clk on cpu_clk_postmux1 */
+               clk_hw_set_parent(nb_data->cpu_clk_dyn,
+                                 nb_data->cpu_clk_postmux1);
+
+               /*
+                * Now, cpu_clk is 24MHz in the current path :
+                * cpu_clk
+                *    \- cpu_clk_dyn
+                *          \- cpu_clk_postmux1
+                *                \- cpu_clk_premux1
+                *                      \- xtal
+                */
+
+               udelay(100);
+
+               return NOTIFY_OK;
+
+       case POST_RATE_CHANGE:
+               /*
+                * The cpu_clk_postmux0 has ben updated, now switch back
+                * cpu_clk_dyn to cpu_clk_postmux0 and take the changes
+                * in account.
+                */
+
+               /* Configure cpu_clk_dyn back to cpu_clk_postmux0 */
+               clk_hw_set_parent(nb_data->cpu_clk_dyn,
+                                 nb_data->cpu_clk_postmux0);
+
+               /*
+                * new path :
+                * cpu_clk
+                *    \- cpu_clk_dyn
+                *          \- cpu_clk_postmux0
+                *                \- cpu_clk_muxX_div
+                *                      \- cpu_clk_premux0
+                *                              \- fclk_div3 or fclk_div2
+                *              OR
+                *                \- cpu_clk_premux0
+                *                      \- fclk_div3 or fclk_div2
+                */
+
+               udelay(100);
+
+               return NOTIFY_OK;
+
+       default:
+               return NOTIFY_DONE;
+       }
+}
+
+static struct g12a_cpu_clk_postmux_nb_data g12a_cpu_clk_postmux0_nb_data = {
+       .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw,
+       .cpu_clk_postmux0 = &g12a_cpu_clk_postmux0.hw,
+       .cpu_clk_postmux1 = &g12a_cpu_clk_postmux1.hw,
+       .cpu_clk_premux1 = &g12a_cpu_clk_premux1.hw,
+       .nb.notifier_call = g12a_cpu_clk_postmux_notifier_cb,
+};
+
+static struct g12a_cpu_clk_postmux_nb_data g12b_cpub_clk_postmux0_nb_data = {
+       .cpu_clk_dyn = &g12b_cpub_clk_dyn.hw,
+       .cpu_clk_postmux0 = &g12b_cpub_clk_postmux0.hw,
+       .cpu_clk_postmux1 = &g12b_cpub_clk_postmux1.hw,
+       .cpu_clk_premux1 = &g12b_cpub_clk_premux1.hw,
+       .nb.notifier_call = g12a_cpu_clk_postmux_notifier_cb,
+};
+
+struct g12a_sys_pll_nb_data {
+       struct notifier_block nb;
+       struct clk_hw *sys_pll;
+       struct clk_hw *cpu_clk;
+       struct clk_hw *cpu_clk_dyn;
+};
+
+static int g12a_sys_pll_notifier_cb(struct notifier_block *nb,
+                                   unsigned long event, void *data)
+{
+       struct g12a_sys_pll_nb_data *nb_data =
+               container_of(nb, struct g12a_sys_pll_nb_data, nb);
+
+       switch (event) {
+       case PRE_RATE_CHANGE:
+               /*
+                * This notifier means sys_pll clock will be changed
+                * to feed cpu_clk, this the current path :
+                * cpu_clk
+                *    \- sys_pll
+                *          \- sys_pll_dco
+                */
+
+               /* Configure cpu_clk to use cpu_clk_dyn */
+               clk_hw_set_parent(nb_data->cpu_clk,
+                                 nb_data->cpu_clk_dyn);
+
+               /*
+                * Now, cpu_clk uses the dyn path
+                * cpu_clk
+                *    \- cpu_clk_dyn
+                *          \- cpu_clk_dynX
+                *                \- cpu_clk_dynX_sel
+                *                   \- cpu_clk_dynX_div
+                *                      \- xtal/fclk_div2/fclk_div3
+                *                   \- xtal/fclk_div2/fclk_div3
+                */
+
+               udelay(100);
+
+               return NOTIFY_OK;
+
+       case POST_RATE_CHANGE:
+               /*
+                * The sys_pll has ben updated, now switch back cpu_clk to
+                * sys_pll
+                */
+
+               /* Configure cpu_clk to use sys_pll */
+               clk_hw_set_parent(nb_data->cpu_clk,
+                                 nb_data->sys_pll);
+
+               udelay(100);
+
+               /* new path :
+                * cpu_clk
+                *    \- sys_pll
+                *          \- sys_pll_dco
+                */
+
+               return NOTIFY_OK;
+
+       default:
+               return NOTIFY_DONE;
+       }
+}
+
+static struct g12a_sys_pll_nb_data g12a_sys_pll_nb_data = {
+       .sys_pll = &g12a_sys_pll.hw,
+       .cpu_clk = &g12a_cpu_clk.hw,
+       .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw,
+       .nb.notifier_call = g12a_sys_pll_notifier_cb,
+};
+
+/* G12B first CPU cluster uses sys1_pll */
+static struct g12a_sys_pll_nb_data g12b_cpu_clk_sys1_pll_nb_data = {
+       .sys_pll = &g12b_sys1_pll.hw,
+       .cpu_clk = &g12b_cpu_clk.hw,
+       .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw,
+       .nb.notifier_call = g12a_sys_pll_notifier_cb,
+};
+
+/* G12B second CPU cluster uses sys_pll */
+static struct g12a_sys_pll_nb_data g12b_cpub_clk_sys_pll_nb_data = {
+       .sys_pll = &g12a_sys_pll.hw,
+       .cpu_clk = &g12b_cpub_clk.hw,
+       .cpu_clk_dyn = &g12b_cpub_clk_dyn.hw,
+       .nb.notifier_call = g12a_sys_pll_notifier_cb,
+};
+
 static struct clk_regmap g12a_cpu_clk_div16_en = {
        .data = &(struct clk_regmap_gate_data){
                .offset = HHI_SYS_CPU_CLK_CNTL1,
@@ -537,7 +1115,9 @@ static struct clk_regmap g12a_cpu_clk_div16_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpu_clk_div16_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is used to debug the cpu_clk range
@@ -554,7 +1134,9 @@ static struct clk_regmap g12b_cpub_clk_div16_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpub_clk_div16_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is used to debug the cpu_clk range
@@ -569,7 +1151,9 @@ static struct clk_fixed_factor g12a_cpu_clk_div16 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_div16",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_clk_div16_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_div16_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -580,7 +1164,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div16 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_div16",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpub_clk_div16_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_div16_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -595,7 +1181,7 @@ static struct clk_regmap g12a_cpu_clk_apb_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_apb_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
                .num_parents = 1,
        },
 };
@@ -608,7 +1194,9 @@ static struct clk_regmap g12a_cpu_clk_apb = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpu_clk_apb",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_apb_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_apb_div.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is set by the ROM monitor code,
@@ -627,7 +1215,7 @@ static struct clk_regmap g12a_cpu_clk_atb_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_atb_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
                .num_parents = 1,
        },
 };
@@ -640,7 +1228,9 @@ static struct clk_regmap g12a_cpu_clk_atb = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpu_clk_atb",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_atb_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_atb_div.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is set by the ROM monitor code,
@@ -659,7 +1249,7 @@ static struct clk_regmap g12a_cpu_clk_axi_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_axi_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
                .num_parents = 1,
        },
 };
@@ -672,7 +1262,9 @@ static struct clk_regmap g12a_cpu_clk_axi = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpu_clk_axi",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_axi_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_axi_div.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is set by the ROM monitor code,
@@ -691,7 +1283,17 @@ static struct clk_regmap g12a_cpu_clk_trace_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_trace_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_data = &(const struct clk_parent_data) {
+                       /*
+                        * Note:
+                        * G12A and G12B have different cpu_clks (with
+                        * different struct clk_hw). We fallback to the global
+                        * naming string mechanism so cpu_clk_trace_div picks
+                        * up the appropriate one.
+                        */
+                       .name = "cpu_clk",
+                       .index = -1,
+               },
                .num_parents = 1,
        },
 };
@@ -704,7 +1306,9 @@ static struct clk_regmap g12a_cpu_clk_trace = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpu_clk_trace",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_trace_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_trace_div.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is set by the ROM monitor code,
@@ -719,7 +1323,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpub_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -730,7 +1336,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div3 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_div3",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpub_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -741,7 +1349,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_div4",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpub_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -752,7 +1362,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div5 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_div5",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpub_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -763,7 +1375,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div6 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_div6",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpub_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -774,7 +1388,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div7 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_div7",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpub_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -785,7 +1401,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div8 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_div8",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpub_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -801,13 +1419,15 @@ static struct clk_regmap g12b_cpub_clk_apb_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_apb_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_div2",
-                                                 "cpub_clk_div3",
-                                                 "cpub_clk_div4",
-                                                 "cpub_clk_div5",
-                                                 "cpub_clk_div6",
-                                                 "cpub_clk_div7",
-                                                 "cpub_clk_div8" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_div2.hw,
+                       &g12b_cpub_clk_div3.hw,
+                       &g12b_cpub_clk_div4.hw,
+                       &g12b_cpub_clk_div5.hw,
+                       &g12b_cpub_clk_div6.hw,
+                       &g12b_cpub_clk_div7.hw,
+                       &g12b_cpub_clk_div8.hw
+               },
                .num_parents = 7,
        },
 };
@@ -821,7 +1441,9 @@ static struct clk_regmap g12b_cpub_clk_apb = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpub_clk_apb",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_apb_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_apb_sel.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is set by the ROM monitor code,
@@ -840,13 +1462,15 @@ static struct clk_regmap g12b_cpub_clk_atb_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_atb_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_div2",
-                                                 "cpub_clk_div3",
-                                                 "cpub_clk_div4",
-                                                 "cpub_clk_div5",
-                                                 "cpub_clk_div6",
-                                                 "cpub_clk_div7",
-                                                 "cpub_clk_div8" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_div2.hw,
+                       &g12b_cpub_clk_div3.hw,
+                       &g12b_cpub_clk_div4.hw,
+                       &g12b_cpub_clk_div5.hw,
+                       &g12b_cpub_clk_div6.hw,
+                       &g12b_cpub_clk_div7.hw,
+                       &g12b_cpub_clk_div8.hw
+               },
                .num_parents = 7,
        },
 };
@@ -860,7 +1484,9 @@ static struct clk_regmap g12b_cpub_clk_atb = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpub_clk_atb",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_atb_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_atb_sel.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is set by the ROM monitor code,
@@ -879,13 +1505,15 @@ static struct clk_regmap g12b_cpub_clk_axi_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_axi_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_div2",
-                                                 "cpub_clk_div3",
-                                                 "cpub_clk_div4",
-                                                 "cpub_clk_div5",
-                                                 "cpub_clk_div6",
-                                                 "cpub_clk_div7",
-                                                 "cpub_clk_div8" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_div2.hw,
+                       &g12b_cpub_clk_div3.hw,
+                       &g12b_cpub_clk_div4.hw,
+                       &g12b_cpub_clk_div5.hw,
+                       &g12b_cpub_clk_div6.hw,
+                       &g12b_cpub_clk_div7.hw,
+                       &g12b_cpub_clk_div8.hw
+               },
                .num_parents = 7,
        },
 };
@@ -899,7 +1527,9 @@ static struct clk_regmap g12b_cpub_clk_axi = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpub_clk_axi",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_axi_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_axi_sel.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is set by the ROM monitor code,
@@ -918,13 +1548,15 @@ static struct clk_regmap g12b_cpub_clk_trace_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_trace_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_div2",
-                                                 "cpub_clk_div3",
-                                                 "cpub_clk_div4",
-                                                 "cpub_clk_div5",
-                                                 "cpub_clk_div6",
-                                                 "cpub_clk_div7",
-                                                 "cpub_clk_div8" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_div2.hw,
+                       &g12b_cpub_clk_div3.hw,
+                       &g12b_cpub_clk_div4.hw,
+                       &g12b_cpub_clk_div5.hw,
+                       &g12b_cpub_clk_div6.hw,
+                       &g12b_cpub_clk_div7.hw,
+                       &g12b_cpub_clk_div8.hw
+               },
                .num_parents = 7,
        },
 };
@@ -938,7 +1570,9 @@ static struct clk_regmap g12b_cpub_clk_trace = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpub_clk_trace",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_trace_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_trace_sel.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is set by the ROM monitor code,
@@ -952,76 +1586,143 @@ static const struct pll_mult_range g12a_gp0_pll_mult_range = {
        .max = 255,
 };
 
-/*
- * Internal gp0 pll emulation configuration parameters
- */
-static const struct reg_sequence g12a_gp0_init_regs[] = {
-       { .reg = HHI_GP0_PLL_CNTL1,     .def = 0x00000000 },
-       { .reg = HHI_GP0_PLL_CNTL2,     .def = 0x00000000 },
-       { .reg = HHI_GP0_PLL_CNTL3,     .def = 0x48681c00 },
-       { .reg = HHI_GP0_PLL_CNTL4,     .def = 0x33771290 },
-       { .reg = HHI_GP0_PLL_CNTL5,     .def = 0x39272000 },
-       { .reg = HHI_GP0_PLL_CNTL6,     .def = 0x56540000 },
+/*
+ * Internal gp0 pll emulation configuration parameters
+ */
+static const struct reg_sequence g12a_gp0_init_regs[] = {
+       { .reg = HHI_GP0_PLL_CNTL1,     .def = 0x00000000 },
+       { .reg = HHI_GP0_PLL_CNTL2,     .def = 0x00000000 },
+       { .reg = HHI_GP0_PLL_CNTL3,     .def = 0x48681c00 },
+       { .reg = HHI_GP0_PLL_CNTL4,     .def = 0x33771290 },
+       { .reg = HHI_GP0_PLL_CNTL5,     .def = 0x39272000 },
+       { .reg = HHI_GP0_PLL_CNTL6,     .def = 0x56540000 },
+};
+
+static struct clk_regmap g12a_gp0_pll_dco = {
+       .data = &(struct meson_clk_pll_data){
+               .en = {
+                       .reg_off = HHI_GP0_PLL_CNTL0,
+                       .shift   = 28,
+                       .width   = 1,
+               },
+               .m = {
+                       .reg_off = HHI_GP0_PLL_CNTL0,
+                       .shift   = 0,
+                       .width   = 8,
+               },
+               .n = {
+                       .reg_off = HHI_GP0_PLL_CNTL0,
+                       .shift   = 10,
+                       .width   = 5,
+               },
+               .frac = {
+                       .reg_off = HHI_GP0_PLL_CNTL1,
+                       .shift   = 0,
+                       .width   = 17,
+               },
+               .l = {
+                       .reg_off = HHI_GP0_PLL_CNTL0,
+                       .shift   = 31,
+                       .width   = 1,
+               },
+               .rst = {
+                       .reg_off = HHI_GP0_PLL_CNTL0,
+                       .shift   = 29,
+                       .width   = 1,
+               },
+               .range = &g12a_gp0_pll_mult_range,
+               .init_regs = g12a_gp0_init_regs,
+               .init_count = ARRAY_SIZE(g12a_gp0_init_regs),
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "gp0_pll_dco",
+               .ops = &meson_clk_pll_ops,
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_regmap g12a_gp0_pll = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_GP0_PLL_CNTL0,
+               .shift = 16,
+               .width = 3,
+               .flags = (CLK_DIVIDER_POWER_OF_TWO |
+                         CLK_DIVIDER_ROUND_CLOSEST),
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "gp0_pll",
+               .ops = &clk_regmap_divider_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_gp0_pll_dco.hw
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
 };
 
-static struct clk_regmap g12a_gp0_pll_dco = {
+static struct clk_regmap sm1_gp1_pll_dco = {
        .data = &(struct meson_clk_pll_data){
                .en = {
-                       .reg_off = HHI_GP0_PLL_CNTL0,
+                       .reg_off = HHI_GP1_PLL_CNTL0,
                        .shift   = 28,
                        .width   = 1,
                },
                .m = {
-                       .reg_off = HHI_GP0_PLL_CNTL0,
+                       .reg_off = HHI_GP1_PLL_CNTL0,
                        .shift   = 0,
                        .width   = 8,
                },
                .n = {
-                       .reg_off = HHI_GP0_PLL_CNTL0,
+                       .reg_off = HHI_GP1_PLL_CNTL0,
                        .shift   = 10,
                        .width   = 5,
                },
                .frac = {
-                       .reg_off = HHI_GP0_PLL_CNTL1,
+                       .reg_off = HHI_GP1_PLL_CNTL1,
                        .shift   = 0,
                        .width   = 17,
                },
                .l = {
-                       .reg_off = HHI_GP0_PLL_CNTL0,
+                       .reg_off = HHI_GP1_PLL_CNTL0,
                        .shift   = 31,
                        .width   = 1,
                },
                .rst = {
-                       .reg_off = HHI_GP0_PLL_CNTL0,
+                       .reg_off = HHI_GP1_PLL_CNTL0,
                        .shift   = 29,
                        .width   = 1,
                },
-               .range = &g12a_gp0_pll_mult_range,
-               .init_regs = g12a_gp0_init_regs,
-               .init_count = ARRAY_SIZE(g12a_gp0_init_regs),
        },
        .hw.init = &(struct clk_init_data){
-               .name = "gp0_pll_dco",
-               .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .name = "gp1_pll_dco",
+               .ops = &meson_clk_pll_ro_ops,
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
+               /* This clock feeds the DSU, avoid disabling it */
+               .flags = CLK_IS_CRITICAL,
        },
 };
 
-static struct clk_regmap g12a_gp0_pll = {
+static struct clk_regmap sm1_gp1_pll = {
        .data = &(struct clk_regmap_div_data){
-               .offset = HHI_GP0_PLL_CNTL0,
+               .offset = HHI_GP1_PLL_CNTL0,
                .shift = 16,
                .width = 3,
                .flags = (CLK_DIVIDER_POWER_OF_TWO |
                          CLK_DIVIDER_ROUND_CLOSEST),
        },
        .hw.init = &(struct clk_init_data){
-               .name = "gp0_pll",
-               .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "gp0_pll_dco" },
+               .name = "gp1_pll",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &sm1_gp1_pll_dco.hw
+               },
                .num_parents = 1,
-               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -1077,7 +1778,9 @@ static struct clk_regmap g12a_hifi_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "hifi_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -1093,7 +1796,9 @@ static struct clk_regmap g12a_hifi_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "hifi_pll",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "hifi_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_hifi_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1164,7 +1869,9 @@ static struct clk_regmap g12a_pcie_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_pll_dco",
                .ops = &meson_clk_pcie_pll_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -1175,7 +1882,9 @@ static struct clk_fixed_factor g12a_pcie_pll_dco_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_pll_dco_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "pcie_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_pcie_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1193,7 +1902,9 @@ static struct clk_regmap g12a_pcie_pll_od = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_pll_od",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "pcie_pll_dco_div2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_pcie_pll_dco_div2.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1205,7 +1916,9 @@ static struct clk_fixed_factor g12a_pcie_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_pll_pll",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "pcie_pll_od" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_pcie_pll_od.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1247,7 +1960,9 @@ static struct clk_regmap g12a_hdmi_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
                /*
                 * Display directly handle hdmi pll registers ATM, we need
@@ -1267,7 +1982,9 @@ static struct clk_regmap g12a_hdmi_pll_od = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_od",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_hdmi_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
@@ -1283,7 +2000,9 @@ static struct clk_regmap g12a_hdmi_pll_od2 = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_od2",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_od" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_hdmi_pll_od.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
@@ -1299,77 +2018,21 @@ static struct clk_regmap g12a_hdmi_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_od2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_hdmi_pll_od2.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
 };
 
-static struct clk_fixed_factor g12a_fclk_div2_div = {
-       .mult = 1,
-       .div = 2,
-       .hw.init = &(struct clk_init_data){
-               .name = "fclk_div2_div",
-               .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
-               .num_parents = 1,
-       },
-};
-
-static struct clk_regmap g12a_fclk_div2 = {
-       .data = &(struct clk_regmap_gate_data){
-               .offset = HHI_FIX_PLL_CNTL1,
-               .bit_idx = 24,
-       },
-       .hw.init = &(struct clk_init_data){
-               .name = "fclk_div2",
-               .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div2_div" },
-               .num_parents = 1,
-       },
-};
-
-static struct clk_fixed_factor g12a_fclk_div3_div = {
-       .mult = 1,
-       .div = 3,
-       .hw.init = &(struct clk_init_data){
-               .name = "fclk_div3_div",
-               .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
-               .num_parents = 1,
-       },
-};
-
-static struct clk_regmap g12a_fclk_div3 = {
-       .data = &(struct clk_regmap_gate_data){
-               .offset = HHI_FIX_PLL_CNTL1,
-               .bit_idx = 20,
-       },
-       .hw.init = &(struct clk_init_data){
-               .name = "fclk_div3",
-               .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div3_div" },
-               .num_parents = 1,
-               /*
-                * This clock is used by the resident firmware and is required
-                * by the platform to operate correctly.
-                * Until the following condition are met, we need this clock to
-                * be marked as critical:
-                * a) Mark the clock used by a firmware resource, if possible
-                * b) CCF has a clock hand-off mechanism to make the sure the
-                *    clock stays on until the proper driver comes along
-                */
-               .flags = CLK_IS_CRITICAL,
-       },
-};
-
 static struct clk_fixed_factor g12a_fclk_div4_div = {
        .mult = 1,
        .div = 4,
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div4_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -1382,7 +2045,9 @@ static struct clk_regmap g12a_fclk_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div4",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div4_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fclk_div4_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1393,7 +2058,7 @@ static struct clk_fixed_factor g12a_fclk_div5_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div5_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -1406,7 +2071,9 @@ static struct clk_regmap g12a_fclk_div5 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div5",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div5_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fclk_div5_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1417,7 +2084,7 @@ static struct clk_fixed_factor g12a_fclk_div7_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div7_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -1430,7 +2097,9 @@ static struct clk_regmap g12a_fclk_div7 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div7",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div7_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fclk_div7_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1441,7 +2110,9 @@ static struct clk_fixed_factor g12a_fclk_div2p5_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div2p5_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fixed_pll_dco.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1454,7 +2125,9 @@ static struct clk_regmap g12a_fclk_div2p5 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div2p5",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div2p5_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fclk_div2p5_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1465,7 +2138,9 @@ static struct clk_fixed_factor g12a_mpll_50m_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll_50m_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fixed_pll_dco.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1479,8 +2154,10 @@ static struct clk_regmap g12a_mpll_50m = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll_50m",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal",
-                                                 "mpll_50m_div" },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &g12a_mpll_50m_div.hw },
+               },
                .num_parents = 2,
        },
 };
@@ -1491,7 +2168,9 @@ static struct clk_fixed_factor g12a_mpll_prediv = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll_prediv",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fixed_pll_dco.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1529,7 +2208,9 @@ static struct clk_regmap g12a_mpll0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1542,7 +2223,7 @@ static struct clk_regmap g12a_mpll0 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll0_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_mpll0_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1581,7 +2262,9 @@ static struct clk_regmap g12a_mpll1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll1_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1594,7 +2277,7 @@ static struct clk_regmap g12a_mpll1 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll1_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_mpll1_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1633,7 +2316,9 @@ static struct clk_regmap g12a_mpll2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll2_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1646,7 +2331,7 @@ static struct clk_regmap g12a_mpll2 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll2_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_mpll2_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1685,7 +2370,9 @@ static struct clk_regmap g12a_mpll3_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll3_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1698,16 +2385,21 @@ static struct clk_regmap g12a_mpll3 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll3",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll3_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_mpll3_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
 static u32 mux_table_clk81[]   = { 0, 2, 3, 4, 5, 6, 7 };
-static const char * const clk81_parent_names[] = {
-       IN_PREFIX "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
-       "fclk_div3", "fclk_div5"
+static const struct clk_parent_data clk81_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &g12a_fclk_div7.hw },
+       { .hw = &g12a_mpll1.hw },
+       { .hw = &g12a_mpll2.hw },
+       { .hw = &g12a_fclk_div4.hw },
+       { .hw = &g12a_fclk_div3.hw },
+       { .hw = &g12a_fclk_div5.hw },
 };
 
 static struct clk_regmap g12a_mpeg_clk_sel = {
@@ -1720,8 +2412,8 @@ static struct clk_regmap g12a_mpeg_clk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "mpeg_clk_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = clk81_parent_names,
-               .num_parents = ARRAY_SIZE(clk81_parent_names),
+               .parent_data = clk81_parent_data,
+               .num_parents = ARRAY_SIZE(clk81_parent_data),
        },
 };
 
@@ -1734,7 +2426,9 @@ static struct clk_regmap g12a_mpeg_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpeg_clk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mpeg_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1748,15 +2442,20 @@ static struct clk_regmap g12a_clk81 = {
        .hw.init = &(struct clk_init_data){
                .name = "clk81",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mpeg_clk_div.hw
+               },
                .num_parents = 1,
                .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
        },
 };
 
-static const char * const g12a_sd_emmc_clk0_parent_names[] = {
-       IN_PREFIX "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
-
+static const struct clk_parent_data g12a_sd_emmc_clk0_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &g12a_fclk_div2.hw },
+       { .hw = &g12a_fclk_div3.hw },
+       { .hw = &g12a_fclk_div5.hw },
+       { .hw = &g12a_fclk_div7.hw },
        /*
         * Following these parent clocks, we should also have had mpll2, mpll3
         * and gp0_pll but these clocks are too precious to be used here. All
@@ -1775,8 +2474,8 @@ static struct clk_regmap g12a_sd_emmc_a_clk0_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_a_clk0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_sd_emmc_clk0_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_names),
+               .parent_data = g12a_sd_emmc_clk0_parent_data,
+               .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1790,7 +2489,9 @@ static struct clk_regmap g12a_sd_emmc_a_clk0_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_a_clk0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_sd_emmc_a_clk0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1804,7 +2505,9 @@ static struct clk_regmap g12a_sd_emmc_a_clk0 = {
        .hw.init = &(struct clk_init_data){
                .name = "sd_emmc_a_clk0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sd_emmc_a_clk0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_sd_emmc_a_clk0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1820,8 +2523,8 @@ static struct clk_regmap g12a_sd_emmc_b_clk0_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_b_clk0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_sd_emmc_clk0_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_names),
+               .parent_data = g12a_sd_emmc_clk0_parent_data,
+               .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1835,7 +2538,9 @@ static struct clk_regmap g12a_sd_emmc_b_clk0_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_b_clk0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_sd_emmc_b_clk0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1849,7 +2554,9 @@ static struct clk_regmap g12a_sd_emmc_b_clk0 = {
        .hw.init = &(struct clk_init_data){
                .name = "sd_emmc_b_clk0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_sd_emmc_b_clk0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1865,8 +2572,8 @@ static struct clk_regmap g12a_sd_emmc_c_clk0_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_c_clk0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_sd_emmc_clk0_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_names),
+               .parent_data = g12a_sd_emmc_clk0_parent_data,
+               .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1880,7 +2587,9 @@ static struct clk_regmap g12a_sd_emmc_c_clk0_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_c_clk0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_sd_emmc_c_clk0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1894,17 +2603,89 @@ static struct clk_regmap g12a_sd_emmc_c_clk0 = {
        .hw.init = &(struct clk_init_data){
                .name = "sd_emmc_c_clk0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_sd_emmc_c_clk0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
+/* Video Clocks */
+
+static struct clk_regmap g12a_vid_pll_div = {
+       .data = &(struct meson_vid_pll_div_data){
+               .val = {
+                       .reg_off = HHI_VID_PLL_CLK_DIV,
+                       .shift   = 0,
+                       .width   = 15,
+               },
+               .sel = {
+                       .reg_off = HHI_VID_PLL_CLK_DIV,
+                       .shift   = 16,
+                       .width   = 2,
+               },
+       },
+       .hw.init = &(struct clk_init_data) {
+               .name = "vid_pll_div",
+               .ops = &meson_vid_pll_div_ro_ops,
+               .parent_hws = (const struct clk_hw *[]) { &g12a_hdmi_pll.hw },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static const struct clk_hw *g12a_vid_pll_parent_hws[] = {
+       &g12a_vid_pll_div.hw,
+       &g12a_hdmi_pll.hw,
+};
+
+static struct clk_regmap g12a_vid_pll_sel = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_VID_PLL_CLK_DIV,
+               .mask = 0x1,
+               .shift = 18,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "vid_pll_sel",
+               .ops = &clk_regmap_mux_ops,
+               /*
+                * bit 18 selects from 2 possible parents:
+                * vid_pll_div or hdmi_pll
+                */
+               .parent_hws = g12a_vid_pll_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vid_pll_parent_hws),
+               .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct clk_regmap g12a_vid_pll = {
+       .data = &(struct clk_regmap_gate_data){
+               .offset = HHI_VID_PLL_CLK_DIV,
+               .bit_idx = 19,
+       },
+       .hw.init = &(struct clk_init_data) {
+               .name = "vid_pll",
+               .ops = &clk_regmap_gate_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vid_pll_sel.hw
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+       },
+};
+
 /* VPU Clock */
 
-static const char * const g12a_vpu_parent_names[] = {
-       "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7",
-       "mpll1", "vid_pll", "hifi_pll", "gp0_pll",
+static const struct clk_hw *g12a_vpu_parent_hws[] = {
+       &g12a_fclk_div3.hw,
+       &g12a_fclk_div4.hw,
+       &g12a_fclk_div5.hw,
+       &g12a_fclk_div7.hw,
+       &g12a_mpll1.hw,
+       &g12a_vid_pll.hw,
+       &g12a_hifi_pll.hw,
+       &g12a_gp0_pll.hw,
 };
 
 static struct clk_regmap g12a_vpu_0_sel = {
@@ -1916,8 +2697,8 @@ static struct clk_regmap g12a_vpu_0_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vpu_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vpu_parent_names),
+               .parent_hws = g12a_vpu_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vpu_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
@@ -1931,7 +2712,7 @@ static struct clk_regmap g12a_vpu_0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vpu_0_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vpu_0_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1945,7 +2726,7 @@ static struct clk_regmap g12a_vpu_0 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vpu_0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vpu_0_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vpu_0_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1960,8 +2741,8 @@ static struct clk_regmap g12a_vpu_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vpu_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vpu_parent_names),
+               .parent_hws = g12a_vpu_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vpu_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
@@ -1975,7 +2756,7 @@ static struct clk_regmap g12a_vpu_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vpu_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vpu_1_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1989,7 +2770,7 @@ static struct clk_regmap g12a_vpu_1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vpu_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vpu_1_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vpu_1_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2008,7 +2789,10 @@ static struct clk_regmap g12a_vpu = {
                 * bit 31 selects from 2 possible parents:
                 * vpu_0 or vpu_1
                 */
-               .parent_names = (const char *[]){ "vpu_0", "vpu_1" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vpu_0.hw,
+                       &g12a_vpu_1.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -2016,9 +2800,14 @@ static struct clk_regmap g12a_vpu = {
 
 /* VDEC clocks */
 
-static const char * const g12a_vdec_parent_names[] = {
-       "fclk_div2p5", "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7",
-       "hifi_pll", "gp0_pll",
+static const struct clk_hw *g12a_vdec_parent_hws[] = {
+       &g12a_fclk_div2p5.hw,
+       &g12a_fclk_div3.hw,
+       &g12a_fclk_div4.hw,
+       &g12a_fclk_div5.hw,
+       &g12a_fclk_div7.hw,
+       &g12a_hifi_pll.hw,
+       &g12a_gp0_pll.hw,
 };
 
 static struct clk_regmap g12a_vdec_1_sel = {
@@ -2031,8 +2820,8 @@ static struct clk_regmap g12a_vdec_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vdec_parent_names),
+               .parent_hws = g12a_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2047,7 +2836,9 @@ static struct clk_regmap g12a_vdec_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vdec_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2061,7 +2852,9 @@ static struct clk_regmap g12a_vdec_1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vdec_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2077,8 +2870,8 @@ static struct clk_regmap g12a_vdec_hevcf_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hevcf_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vdec_parent_names),
+               .parent_hws = g12a_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2093,7 +2886,9 @@ static struct clk_regmap g12a_vdec_hevcf_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hevcf_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_hevcf_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vdec_hevcf_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2107,7 +2902,9 @@ static struct clk_regmap g12a_vdec_hevcf = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_hevcf",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_hevcf_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vdec_hevcf_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2123,8 +2920,8 @@ static struct clk_regmap g12a_vdec_hevc_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hevc_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vdec_parent_names),
+               .parent_hws = g12a_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2139,7 +2936,9 @@ static struct clk_regmap g12a_vdec_hevc_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hevc_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_hevc_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vdec_hevc_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2153,7 +2952,9 @@ static struct clk_regmap g12a_vdec_hevc = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_hevc",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_hevc_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vdec_hevc_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2161,9 +2962,15 @@ static struct clk_regmap g12a_vdec_hevc = {
 
 /* VAPB Clock */
 
-static const char * const g12a_vapb_parent_names[] = {
-       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7",
-       "mpll1", "vid_pll", "mpll2", "fclk_div2p5",
+static const struct clk_hw *g12a_vapb_parent_hws[] = {
+       &g12a_fclk_div4.hw,
+       &g12a_fclk_div3.hw,
+       &g12a_fclk_div5.hw,
+       &g12a_fclk_div7.hw,
+       &g12a_mpll1.hw,
+       &g12a_vid_pll.hw,
+       &g12a_mpll2.hw,
+       &g12a_fclk_div2p5.hw,
 };
 
 static struct clk_regmap g12a_vapb_0_sel = {
@@ -2175,8 +2982,8 @@ static struct clk_regmap g12a_vapb_0_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vapb_0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vapb_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vapb_parent_names),
+               .parent_hws = g12a_vapb_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vapb_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
@@ -2190,7 +2997,9 @@ static struct clk_regmap g12a_vapb_0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vapb_0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vapb_0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vapb_0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2204,7 +3013,9 @@ static struct clk_regmap g12a_vapb_0 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vapb_0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vapb_0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vapb_0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2219,8 +3030,8 @@ static struct clk_regmap g12a_vapb_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vapb_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vapb_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vapb_parent_names),
+               .parent_hws = g12a_vapb_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vapb_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
@@ -2234,7 +3045,9 @@ static struct clk_regmap g12a_vapb_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vapb_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vapb_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vapb_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2248,7 +3061,9 @@ static struct clk_regmap g12a_vapb_1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vapb_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vapb_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vapb_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2267,89 +3082,38 @@ static struct clk_regmap g12a_vapb_sel = {
                 * bit 31 selects from 2 possible parents:
                 * vapb_0 or vapb_1
                 */
-               .parent_names = (const char *[]){ "vapb_0", "vapb_1" },
-               .num_parents = 2,
-               .flags = CLK_SET_RATE_NO_REPARENT,
-       },
-};
-
-static struct clk_regmap g12a_vapb = {
-       .data = &(struct clk_regmap_gate_data){
-               .offset = HHI_VAPBCLK_CNTL,
-               .bit_idx = 30,
-       },
-       .hw.init = &(struct clk_init_data) {
-               .name = "vapb",
-               .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vapb_sel" },
-               .num_parents = 1,
-               .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
-       },
-};
-
-/* Video Clocks */
-
-static struct clk_regmap g12a_vid_pll_div = {
-       .data = &(struct meson_vid_pll_div_data){
-               .val = {
-                       .reg_off = HHI_VID_PLL_CLK_DIV,
-                       .shift   = 0,
-                       .width   = 15,
-               },
-               .sel = {
-                       .reg_off = HHI_VID_PLL_CLK_DIV,
-                       .shift   = 16,
-                       .width   = 2,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vapb_0.hw,
+                       &g12a_vapb_1.hw,
                },
-       },
-       .hw.init = &(struct clk_init_data) {
-               .name = "vid_pll_div",
-               .ops = &meson_vid_pll_div_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll" },
-               .num_parents = 1,
-               .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
-       },
-};
-
-static const char * const g12a_vid_pll_parent_names[] = { "vid_pll_div",
-                                                         "hdmi_pll" };
-
-static struct clk_regmap g12a_vid_pll_sel = {
-       .data = &(struct clk_regmap_mux_data){
-               .offset = HHI_VID_PLL_CLK_DIV,
-               .mask = 0x1,
-               .shift = 18,
-       },
-       .hw.init = &(struct clk_init_data){
-               .name = "vid_pll_sel",
-               .ops = &clk_regmap_mux_ops,
-               /*
-                * bit 18 selects from 2 possible parents:
-                * vid_pll_div or hdmi_pll
-                */
-               .parent_names = g12a_vid_pll_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vid_pll_parent_names),
-               .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
+               .num_parents = 2,
+               .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
 
-static struct clk_regmap g12a_vid_pll = {
+static struct clk_regmap g12a_vapb = {
        .data = &(struct clk_regmap_gate_data){
-               .offset = HHI_VID_PLL_CLK_DIV,
-               .bit_idx = 19,
+               .offset = HHI_VAPBCLK_CNTL,
+               .bit_idx = 30,
        },
        .hw.init = &(struct clk_init_data) {
-               .name = "vid_pll",
+               .name = "vapb",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vid_pll_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vapb_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
 };
 
-static const char * const g12a_vclk_parent_names[] = {
-       "vid_pll", "gp0_pll", "hifi_pll", "mpll1", "fclk_div3", "fclk_div4",
-       "fclk_div5", "fclk_div7"
+static const struct clk_hw *g12a_vclk_parent_hws[] = {
+       &g12a_vid_pll.hw,
+       &g12a_gp0_pll.hw,
+       &g12a_hifi_pll.hw,
+       &g12a_mpll1.hw,
+       &g12a_fclk_div3.hw,
+       &g12a_fclk_div4.hw,
+       &g12a_fclk_div5.hw,
+       &g12a_fclk_div7.hw,
 };
 
 static struct clk_regmap g12a_vclk_sel = {
@@ -2361,8 +3125,8 @@ static struct clk_regmap g12a_vclk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vclk_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vclk_parent_names),
+               .parent_hws = g12a_vclk_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vclk_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2376,8 +3140,8 @@ static struct clk_regmap g12a_vclk2_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vclk_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vclk_parent_names),
+               .parent_hws = g12a_vclk_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vclk_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2390,7 +3154,7 @@ static struct clk_regmap g12a_vclk_input = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_input",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2404,7 +3168,7 @@ static struct clk_regmap g12a_vclk2_input = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_input",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2419,7 +3183,9 @@ static struct clk_regmap g12a_vclk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vclk_input" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk_input.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE,
        },
@@ -2434,7 +3200,9 @@ static struct clk_regmap g12a_vclk2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vclk2_input" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk2_input.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE,
        },
@@ -2448,7 +3216,7 @@ static struct clk_regmap g12a_vclk = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2462,7 +3230,7 @@ static struct clk_regmap g12a_vclk2 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2476,7 +3244,7 @@ static struct clk_regmap g12a_vclk_div1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2490,7 +3258,7 @@ static struct clk_regmap g12a_vclk_div2_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div2_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2504,7 +3272,7 @@ static struct clk_regmap g12a_vclk_div4_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div4_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2518,7 +3286,7 @@ static struct clk_regmap g12a_vclk_div6_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div6_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2532,7 +3300,7 @@ static struct clk_regmap g12a_vclk_div12_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div12_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2546,7 +3314,7 @@ static struct clk_regmap g12a_vclk2_div1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2560,7 +3328,7 @@ static struct clk_regmap g12a_vclk2_div2_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div2_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2574,7 +3342,7 @@ static struct clk_regmap g12a_vclk2_div4_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div4_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2588,7 +3356,7 @@ static struct clk_regmap g12a_vclk2_div6_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div6_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2602,7 +3370,7 @@ static struct clk_regmap g12a_vclk2_div12_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div12_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2614,7 +3382,9 @@ static struct clk_fixed_factor g12a_vclk_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_div2_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk_div2_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -2625,7 +3395,9 @@ static struct clk_fixed_factor g12a_vclk_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div4",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_div4_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk_div4_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -2636,7 +3408,9 @@ static struct clk_fixed_factor g12a_vclk_div6 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div6",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_div6_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk_div6_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -2647,7 +3421,9 @@ static struct clk_fixed_factor g12a_vclk_div12 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div12",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_div12_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk_div12_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -2658,7 +3434,9 @@ static struct clk_fixed_factor g12a_vclk2_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_div2_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk2_div2_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -2669,7 +3447,9 @@ static struct clk_fixed_factor g12a_vclk2_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div4",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_div4_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk2_div4_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -2680,7 +3460,9 @@ static struct clk_fixed_factor g12a_vclk2_div6 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div6",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_div6_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk2_div6_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -2691,16 +3473,25 @@ static struct clk_fixed_factor g12a_vclk2_div12 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div12",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_div12_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk2_div12_en.hw
+               },
                .num_parents = 1,
        },
 };
 
 static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
-static const char * const g12a_cts_parent_names[] = {
-       "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6",
-       "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4",
-       "vclk2_div6", "vclk2_div12"
+static const struct clk_hw *g12a_cts_parent_hws[] = {
+       &g12a_vclk_div1.hw,
+       &g12a_vclk_div2.hw,
+       &g12a_vclk_div4.hw,
+       &g12a_vclk_div6.hw,
+       &g12a_vclk_div12.hw,
+       &g12a_vclk2_div1.hw,
+       &g12a_vclk2_div2.hw,
+       &g12a_vclk2_div4.hw,
+       &g12a_vclk2_div6.hw,
+       &g12a_vclk2_div12.hw,
 };
 
 static struct clk_regmap g12a_cts_enci_sel = {
@@ -2713,8 +3504,8 @@ static struct clk_regmap g12a_cts_enci_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_enci_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_cts_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_cts_parent_names),
+               .parent_hws = g12a_cts_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_cts_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2729,8 +3520,8 @@ static struct clk_regmap g12a_cts_encp_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_encp_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_cts_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_cts_parent_names),
+               .parent_hws = g12a_cts_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_cts_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2745,18 +3536,25 @@ static struct clk_regmap g12a_cts_vdac_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_vdac_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_cts_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_cts_parent_names),
+               .parent_hws = g12a_cts_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_cts_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
 
 /* TOFIX: add support for cts_tcon */
 static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
-static const char * const g12a_cts_hdmi_tx_parent_names[] = {
-       "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6",
-       "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4",
-       "vclk2_div6", "vclk2_div12"
+static const struct clk_hw *g12a_cts_hdmi_tx_parent_hws[] = {
+       &g12a_vclk_div1.hw,
+       &g12a_vclk_div2.hw,
+       &g12a_vclk_div4.hw,
+       &g12a_vclk_div6.hw,
+       &g12a_vclk_div12.hw,
+       &g12a_vclk2_div1.hw,
+       &g12a_vclk2_div2.hw,
+       &g12a_vclk2_div4.hw,
+       &g12a_vclk2_div6.hw,
+       &g12a_vclk2_div12.hw,
 };
 
 static struct clk_regmap g12a_hdmi_tx_sel = {
@@ -2769,8 +3567,8 @@ static struct clk_regmap g12a_hdmi_tx_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_tx_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_cts_hdmi_tx_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_cts_hdmi_tx_parent_names),
+               .parent_hws = g12a_cts_hdmi_tx_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_cts_hdmi_tx_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2783,7 +3581,9 @@ static struct clk_regmap g12a_cts_enci = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_enci",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_enci_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cts_enci_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2797,7 +3597,9 @@ static struct clk_regmap g12a_cts_encp = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_encp",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_encp_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cts_encp_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2811,7 +3613,9 @@ static struct clk_regmap g12a_cts_vdac = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_vdac",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_vdac_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cts_vdac_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2825,7 +3629,9 @@ static struct clk_regmap g12a_hdmi_tx = {
        .hw.init = &(struct clk_init_data) {
                .name = "hdmi_tx",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "hdmi_tx_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_hdmi_tx_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2833,8 +3639,11 @@ static struct clk_regmap g12a_hdmi_tx = {
 
 /* HDMI Clocks */
 
-static const char * const g12a_hdmi_parent_names[] = {
-       IN_PREFIX "xtal", "fclk_div4", "fclk_div3", "fclk_div5"
+static const struct clk_parent_data g12a_hdmi_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &g12a_fclk_div4.hw },
+       { .hw = &g12a_fclk_div3.hw },
+       { .hw = &g12a_fclk_div5.hw },
 };
 
 static struct clk_regmap g12a_hdmi_sel = {
@@ -2847,8 +3656,8 @@ static struct clk_regmap g12a_hdmi_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_hdmi_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_hdmi_parent_names),
+               .parent_data = g12a_hdmi_parent_data,
+               .num_parents = ARRAY_SIZE(g12a_hdmi_parent_data),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2862,7 +3671,7 @@ static struct clk_regmap g12a_hdmi_div = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "hdmi_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_hdmi_sel.hw },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE,
        },
@@ -2876,7 +3685,7 @@ static struct clk_regmap g12a_hdmi = {
        .hw.init = &(struct clk_init_data) {
                .name = "hdmi",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "hdmi_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_hdmi_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2886,10 +3695,15 @@ static struct clk_regmap g12a_hdmi = {
  * The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
  * muxed by a glitch-free switch.
  */
-
-static const char * const g12a_mali_0_1_parent_names[] = {
-       IN_PREFIX "xtal", "gp0_pll", "hihi_pll", "fclk_div2p5",
-       "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7"
+static const struct clk_parent_data g12a_mali_0_1_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &g12a_gp0_pll.hw },
+       { .hw = &g12a_hifi_pll.hw },
+       { .hw = &g12a_fclk_div2p5.hw },
+       { .hw = &g12a_fclk_div3.hw },
+       { .hw = &g12a_fclk_div4.hw },
+       { .hw = &g12a_fclk_div5.hw },
+       { .hw = &g12a_fclk_div7.hw },
 };
 
 static struct clk_regmap g12a_mali_0_sel = {
@@ -2901,7 +3715,7 @@ static struct clk_regmap g12a_mali_0_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_mali_0_1_parent_names,
+               .parent_data = g12a_mali_0_1_parent_data,
                .num_parents = 8,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -2916,7 +3730,9 @@ static struct clk_regmap g12a_mali_0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "mali_0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mali_0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -2930,7 +3746,9 @@ static struct clk_regmap g12a_mali_0 = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mali_0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mali_0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2945,7 +3763,7 @@ static struct clk_regmap g12a_mali_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_mali_0_1_parent_names,
+               .parent_data = g12a_mali_0_1_parent_data,
                .num_parents = 8,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -2960,7 +3778,9 @@ static struct clk_regmap g12a_mali_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "mali_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mali_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -2974,14 +3794,17 @@ static struct clk_regmap g12a_mali_1 = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mali_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mali_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
-static const char * const g12a_mali_parent_names[] = {
-       "mali_0", "mali_1"
+static const struct clk_hw *g12a_mali_parent_hws[] = {
+       &g12a_mali_0.hw,
+       &g12a_mali_1.hw,
 };
 
 static struct clk_regmap g12a_mali = {
@@ -2993,7 +3816,7 @@ static struct clk_regmap g12a_mali = {
        .hw.init = &(struct clk_init_data){
                .name = "mali",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_mali_parent_names,
+               .parent_hws = g12a_mali_parent_hws,
                .num_parents = 2,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -3008,7 +3831,9 @@ static struct clk_regmap g12a_ts_div = {
        .hw.init = &(struct clk_init_data){
                .name = "ts_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -3021,11 +3846,19 @@ static struct clk_regmap g12a_ts = {
        .hw.init = &(struct clk_init_data){
                .name = "ts",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "ts_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_ts_div.hw
+               },
                .num_parents = 1,
        },
 };
 
+#define MESON_GATE(_name, _reg, _bit) \
+       MESON_PCLK(_name, _reg, _bit, &g12a_clk81.hw)
+
+#define MESON_GATE_RO(_name, _reg, _bit) \
+       MESON_PCLK_RO(_name, _reg, _bit, &g12a_clk81.hw)
+
 /* Everything Else (EE) domain gates */
 static MESON_GATE(g12a_ddr,                    HHI_GCLK_MPEG0, 0);
 static MESON_GATE(g12a_dos,                    HHI_GCLK_MPEG0, 1);
@@ -3571,6 +4404,240 @@ static struct clk_hw_onecell_data g12b_hw_onecell_data = {
        .num = NR_CLKS,
 };
 
+static struct clk_hw_onecell_data sm1_hw_onecell_data = {
+       .hws = {
+               [CLKID_SYS_PLL]                 = &g12a_sys_pll.hw,
+               [CLKID_FIXED_PLL]               = &g12a_fixed_pll.hw,
+               [CLKID_FCLK_DIV2]               = &g12a_fclk_div2.hw,
+               [CLKID_FCLK_DIV3]               = &g12a_fclk_div3.hw,
+               [CLKID_FCLK_DIV4]               = &g12a_fclk_div4.hw,
+               [CLKID_FCLK_DIV5]               = &g12a_fclk_div5.hw,
+               [CLKID_FCLK_DIV7]               = &g12a_fclk_div7.hw,
+               [CLKID_FCLK_DIV2P5]             = &g12a_fclk_div2p5.hw,
+               [CLKID_GP0_PLL]                 = &g12a_gp0_pll.hw,
+               [CLKID_MPEG_SEL]                = &g12a_mpeg_clk_sel.hw,
+               [CLKID_MPEG_DIV]                = &g12a_mpeg_clk_div.hw,
+               [CLKID_CLK81]                   = &g12a_clk81.hw,
+               [CLKID_MPLL0]                   = &g12a_mpll0.hw,
+               [CLKID_MPLL1]                   = &g12a_mpll1.hw,
+               [CLKID_MPLL2]                   = &g12a_mpll2.hw,
+               [CLKID_MPLL3]                   = &g12a_mpll3.hw,
+               [CLKID_DDR]                     = &g12a_ddr.hw,
+               [CLKID_DOS]                     = &g12a_dos.hw,
+               [CLKID_AUDIO_LOCKER]            = &g12a_audio_locker.hw,
+               [CLKID_MIPI_DSI_HOST]           = &g12a_mipi_dsi_host.hw,
+               [CLKID_ETH_PHY]                 = &g12a_eth_phy.hw,
+               [CLKID_ISA]                     = &g12a_isa.hw,
+               [CLKID_PL301]                   = &g12a_pl301.hw,
+               [CLKID_PERIPHS]                 = &g12a_periphs.hw,
+               [CLKID_SPICC0]                  = &g12a_spicc_0.hw,
+               [CLKID_I2C]                     = &g12a_i2c.hw,
+               [CLKID_SANA]                    = &g12a_sana.hw,
+               [CLKID_SD]                      = &g12a_sd.hw,
+               [CLKID_RNG0]                    = &g12a_rng0.hw,
+               [CLKID_UART0]                   = &g12a_uart0.hw,
+               [CLKID_SPICC1]                  = &g12a_spicc_1.hw,
+               [CLKID_HIU_IFACE]               = &g12a_hiu_reg.hw,
+               [CLKID_MIPI_DSI_PHY]            = &g12a_mipi_dsi_phy.hw,
+               [CLKID_ASSIST_MISC]             = &g12a_assist_misc.hw,
+               [CLKID_SD_EMMC_A]               = &g12a_emmc_a.hw,
+               [CLKID_SD_EMMC_B]               = &g12a_emmc_b.hw,
+               [CLKID_SD_EMMC_C]               = &g12a_emmc_c.hw,
+               [CLKID_AUDIO_CODEC]             = &g12a_audio_codec.hw,
+               [CLKID_AUDIO]                   = &g12a_audio.hw,
+               [CLKID_ETH]                     = &g12a_eth_core.hw,
+               [CLKID_DEMUX]                   = &g12a_demux.hw,
+               [CLKID_AUDIO_IFIFO]             = &g12a_audio_ififo.hw,
+               [CLKID_ADC]                     = &g12a_adc.hw,
+               [CLKID_UART1]                   = &g12a_uart1.hw,
+               [CLKID_G2D]                     = &g12a_g2d.hw,
+               [CLKID_RESET]                   = &g12a_reset.hw,
+               [CLKID_PCIE_COMB]               = &g12a_pcie_comb.hw,
+               [CLKID_PARSER]                  = &g12a_parser.hw,
+               [CLKID_USB]                     = &g12a_usb_general.hw,
+               [CLKID_PCIE_PHY]                = &g12a_pcie_phy.hw,
+               [CLKID_AHB_ARB0]                = &g12a_ahb_arb0.hw,
+               [CLKID_AHB_DATA_BUS]            = &g12a_ahb_data_bus.hw,
+               [CLKID_AHB_CTRL_BUS]            = &g12a_ahb_ctrl_bus.hw,
+               [CLKID_HTX_HDCP22]              = &g12a_htx_hdcp22.hw,
+               [CLKID_HTX_PCLK]                = &g12a_htx_pclk.hw,
+               [CLKID_BT656]                   = &g12a_bt656.hw,
+               [CLKID_USB1_DDR_BRIDGE]         = &g12a_usb1_to_ddr.hw,
+               [CLKID_MMC_PCLK]                = &g12a_mmc_pclk.hw,
+               [CLKID_UART2]                   = &g12a_uart2.hw,
+               [CLKID_VPU_INTR]                = &g12a_vpu_intr.hw,
+               [CLKID_GIC]                     = &g12a_gic.hw,
+               [CLKID_SD_EMMC_A_CLK0_SEL]      = &g12a_sd_emmc_a_clk0_sel.hw,
+               [CLKID_SD_EMMC_A_CLK0_DIV]      = &g12a_sd_emmc_a_clk0_div.hw,
+               [CLKID_SD_EMMC_A_CLK0]          = &g12a_sd_emmc_a_clk0.hw,
+               [CLKID_SD_EMMC_B_CLK0_SEL]      = &g12a_sd_emmc_b_clk0_sel.hw,
+               [CLKID_SD_EMMC_B_CLK0_DIV]      = &g12a_sd_emmc_b_clk0_div.hw,
+               [CLKID_SD_EMMC_B_CLK0]          = &g12a_sd_emmc_b_clk0.hw,
+               [CLKID_SD_EMMC_C_CLK0_SEL]      = &g12a_sd_emmc_c_clk0_sel.hw,
+               [CLKID_SD_EMMC_C_CLK0_DIV]      = &g12a_sd_emmc_c_clk0_div.hw,
+               [CLKID_SD_EMMC_C_CLK0]          = &g12a_sd_emmc_c_clk0.hw,
+               [CLKID_MPLL0_DIV]               = &g12a_mpll0_div.hw,
+               [CLKID_MPLL1_DIV]               = &g12a_mpll1_div.hw,
+               [CLKID_MPLL2_DIV]               = &g12a_mpll2_div.hw,
+               [CLKID_MPLL3_DIV]               = &g12a_mpll3_div.hw,
+               [CLKID_FCLK_DIV2_DIV]           = &g12a_fclk_div2_div.hw,
+               [CLKID_FCLK_DIV3_DIV]           = &g12a_fclk_div3_div.hw,
+               [CLKID_FCLK_DIV4_DIV]           = &g12a_fclk_div4_div.hw,
+               [CLKID_FCLK_DIV5_DIV]           = &g12a_fclk_div5_div.hw,
+               [CLKID_FCLK_DIV7_DIV]           = &g12a_fclk_div7_div.hw,
+               [CLKID_FCLK_DIV2P5_DIV]         = &g12a_fclk_div2p5_div.hw,
+               [CLKID_HIFI_PLL]                = &g12a_hifi_pll.hw,
+               [CLKID_VCLK2_VENCI0]            = &g12a_vclk2_venci0.hw,
+               [CLKID_VCLK2_VENCI1]            = &g12a_vclk2_venci1.hw,
+               [CLKID_VCLK2_VENCP0]            = &g12a_vclk2_vencp0.hw,
+               [CLKID_VCLK2_VENCP1]            = &g12a_vclk2_vencp1.hw,
+               [CLKID_VCLK2_VENCT0]            = &g12a_vclk2_venct0.hw,
+               [CLKID_VCLK2_VENCT1]            = &g12a_vclk2_venct1.hw,
+               [CLKID_VCLK2_OTHER]             = &g12a_vclk2_other.hw,
+               [CLKID_VCLK2_ENCI]              = &g12a_vclk2_enci.hw,
+               [CLKID_VCLK2_ENCP]              = &g12a_vclk2_encp.hw,
+               [CLKID_DAC_CLK]                 = &g12a_dac_clk.hw,
+               [CLKID_AOCLK]                   = &g12a_aoclk_gate.hw,
+               [CLKID_IEC958]                  = &g12a_iec958_gate.hw,
+               [CLKID_ENC480P]                 = &g12a_enc480p.hw,
+               [CLKID_RNG1]                    = &g12a_rng1.hw,
+               [CLKID_VCLK2_ENCT]              = &g12a_vclk2_enct.hw,
+               [CLKID_VCLK2_ENCL]              = &g12a_vclk2_encl.hw,
+               [CLKID_VCLK2_VENCLMMC]          = &g12a_vclk2_venclmmc.hw,
+               [CLKID_VCLK2_VENCL]             = &g12a_vclk2_vencl.hw,
+               [CLKID_VCLK2_OTHER1]            = &g12a_vclk2_other1.hw,
+               [CLKID_FIXED_PLL_DCO]           = &g12a_fixed_pll_dco.hw,
+               [CLKID_SYS_PLL_DCO]             = &g12a_sys_pll_dco.hw,
+               [CLKID_GP0_PLL_DCO]             = &g12a_gp0_pll_dco.hw,
+               [CLKID_HIFI_PLL_DCO]            = &g12a_hifi_pll_dco.hw,
+               [CLKID_DMA]                     = &g12a_dma.hw,
+               [CLKID_EFUSE]                   = &g12a_efuse.hw,
+               [CLKID_ROM_BOOT]                = &g12a_rom_boot.hw,
+               [CLKID_RESET_SEC]               = &g12a_reset_sec.hw,
+               [CLKID_SEC_AHB_APB3]            = &g12a_sec_ahb_apb3.hw,
+               [CLKID_MPLL_PREDIV]             = &g12a_mpll_prediv.hw,
+               [CLKID_VPU_0_SEL]               = &g12a_vpu_0_sel.hw,
+               [CLKID_VPU_0_DIV]               = &g12a_vpu_0_div.hw,
+               [CLKID_VPU_0]                   = &g12a_vpu_0.hw,
+               [CLKID_VPU_1_SEL]               = &g12a_vpu_1_sel.hw,
+               [CLKID_VPU_1_DIV]               = &g12a_vpu_1_div.hw,
+               [CLKID_VPU_1]                   = &g12a_vpu_1.hw,
+               [CLKID_VPU]                     = &g12a_vpu.hw,
+               [CLKID_VAPB_0_SEL]              = &g12a_vapb_0_sel.hw,
+               [CLKID_VAPB_0_DIV]              = &g12a_vapb_0_div.hw,
+               [CLKID_VAPB_0]                  = &g12a_vapb_0.hw,
+               [CLKID_VAPB_1_SEL]              = &g12a_vapb_1_sel.hw,
+               [CLKID_VAPB_1_DIV]              = &g12a_vapb_1_div.hw,
+               [CLKID_VAPB_1]                  = &g12a_vapb_1.hw,
+               [CLKID_VAPB_SEL]                = &g12a_vapb_sel.hw,
+               [CLKID_VAPB]                    = &g12a_vapb.hw,
+               [CLKID_HDMI_PLL_DCO]            = &g12a_hdmi_pll_dco.hw,
+               [CLKID_HDMI_PLL_OD]             = &g12a_hdmi_pll_od.hw,
+               [CLKID_HDMI_PLL_OD2]            = &g12a_hdmi_pll_od2.hw,
+               [CLKID_HDMI_PLL]                = &g12a_hdmi_pll.hw,
+               [CLKID_VID_PLL]                 = &g12a_vid_pll_div.hw,
+               [CLKID_VID_PLL_SEL]             = &g12a_vid_pll_sel.hw,
+               [CLKID_VID_PLL_DIV]             = &g12a_vid_pll.hw,
+               [CLKID_VCLK_SEL]                = &g12a_vclk_sel.hw,
+               [CLKID_VCLK2_SEL]               = &g12a_vclk2_sel.hw,
+               [CLKID_VCLK_INPUT]              = &g12a_vclk_input.hw,
+               [CLKID_VCLK2_INPUT]             = &g12a_vclk2_input.hw,
+               [CLKID_VCLK_DIV]                = &g12a_vclk_div.hw,
+               [CLKID_VCLK2_DIV]               = &g12a_vclk2_div.hw,
+               [CLKID_VCLK]                    = &g12a_vclk.hw,
+               [CLKID_VCLK2]                   = &g12a_vclk2.hw,
+               [CLKID_VCLK_DIV1]               = &g12a_vclk_div1.hw,
+               [CLKID_VCLK_DIV2_EN]            = &g12a_vclk_div2_en.hw,
+               [CLKID_VCLK_DIV4_EN]            = &g12a_vclk_div4_en.hw,
+               [CLKID_VCLK_DIV6_EN]            = &g12a_vclk_div6_en.hw,
+               [CLKID_VCLK_DIV12_EN]           = &g12a_vclk_div12_en.hw,
+               [CLKID_VCLK2_DIV1]              = &g12a_vclk2_div1.hw,
+               [CLKID_VCLK2_DIV2_EN]           = &g12a_vclk2_div2_en.hw,
+               [CLKID_VCLK2_DIV4_EN]           = &g12a_vclk2_div4_en.hw,
+               [CLKID_VCLK2_DIV6_EN]           = &g12a_vclk2_div6_en.hw,
+               [CLKID_VCLK2_DIV12_EN]          = &g12a_vclk2_div12_en.hw,
+               [CLKID_VCLK_DIV2]               = &g12a_vclk_div2.hw,
+               [CLKID_VCLK_DIV4]               = &g12a_vclk_div4.hw,
+               [CLKID_VCLK_DIV6]               = &g12a_vclk_div6.hw,
+               [CLKID_VCLK_DIV12]              = &g12a_vclk_div12.hw,
+               [CLKID_VCLK2_DIV2]              = &g12a_vclk2_div2.hw,
+               [CLKID_VCLK2_DIV4]              = &g12a_vclk2_div4.hw,
+               [CLKID_VCLK2_DIV6]              = &g12a_vclk2_div6.hw,
+               [CLKID_VCLK2_DIV12]             = &g12a_vclk2_div12.hw,
+               [CLKID_CTS_ENCI_SEL]            = &g12a_cts_enci_sel.hw,
+               [CLKID_CTS_ENCP_SEL]            = &g12a_cts_encp_sel.hw,
+               [CLKID_CTS_VDAC_SEL]            = &g12a_cts_vdac_sel.hw,
+               [CLKID_HDMI_TX_SEL]             = &g12a_hdmi_tx_sel.hw,
+               [CLKID_CTS_ENCI]                = &g12a_cts_enci.hw,
+               [CLKID_CTS_ENCP]                = &g12a_cts_encp.hw,
+               [CLKID_CTS_VDAC]                = &g12a_cts_vdac.hw,
+               [CLKID_HDMI_TX]                 = &g12a_hdmi_tx.hw,
+               [CLKID_HDMI_SEL]                = &g12a_hdmi_sel.hw,
+               [CLKID_HDMI_DIV]                = &g12a_hdmi_div.hw,
+               [CLKID_HDMI]                    = &g12a_hdmi.hw,
+               [CLKID_MALI_0_SEL]              = &g12a_mali_0_sel.hw,
+               [CLKID_MALI_0_DIV]              = &g12a_mali_0_div.hw,
+               [CLKID_MALI_0]                  = &g12a_mali_0.hw,
+               [CLKID_MALI_1_SEL]              = &g12a_mali_1_sel.hw,
+               [CLKID_MALI_1_DIV]              = &g12a_mali_1_div.hw,
+               [CLKID_MALI_1]                  = &g12a_mali_1.hw,
+               [CLKID_MALI]                    = &g12a_mali.hw,
+               [CLKID_MPLL_50M_DIV]            = &g12a_mpll_50m_div.hw,
+               [CLKID_MPLL_50M]                = &g12a_mpll_50m.hw,
+               [CLKID_SYS_PLL_DIV16_EN]        = &g12a_sys_pll_div16_en.hw,
+               [CLKID_SYS_PLL_DIV16]           = &g12a_sys_pll_div16.hw,
+               [CLKID_CPU_CLK_DYN0_SEL]        = &g12a_cpu_clk_premux0.hw,
+               [CLKID_CPU_CLK_DYN0_DIV]        = &g12a_cpu_clk_mux0_div.hw,
+               [CLKID_CPU_CLK_DYN0]            = &g12a_cpu_clk_postmux0.hw,
+               [CLKID_CPU_CLK_DYN1_SEL]        = &g12a_cpu_clk_premux1.hw,
+               [CLKID_CPU_CLK_DYN1_DIV]        = &g12a_cpu_clk_mux1_div.hw,
+               [CLKID_CPU_CLK_DYN1]            = &g12a_cpu_clk_postmux1.hw,
+               [CLKID_CPU_CLK_DYN]             = &g12a_cpu_clk_dyn.hw,
+               [CLKID_CPU_CLK]                 = &g12a_cpu_clk.hw,
+               [CLKID_CPU_CLK_DIV16_EN]        = &g12a_cpu_clk_div16_en.hw,
+               [CLKID_CPU_CLK_DIV16]           = &g12a_cpu_clk_div16.hw,
+               [CLKID_CPU_CLK_APB_DIV]         = &g12a_cpu_clk_apb_div.hw,
+               [CLKID_CPU_CLK_APB]             = &g12a_cpu_clk_apb.hw,
+               [CLKID_CPU_CLK_ATB_DIV]         = &g12a_cpu_clk_atb_div.hw,
+               [CLKID_CPU_CLK_ATB]             = &g12a_cpu_clk_atb.hw,
+               [CLKID_CPU_CLK_AXI_DIV]         = &g12a_cpu_clk_axi_div.hw,
+               [CLKID_CPU_CLK_AXI]             = &g12a_cpu_clk_axi.hw,
+               [CLKID_CPU_CLK_TRACE_DIV]       = &g12a_cpu_clk_trace_div.hw,
+               [CLKID_CPU_CLK_TRACE]           = &g12a_cpu_clk_trace.hw,
+               [CLKID_PCIE_PLL_DCO]            = &g12a_pcie_pll_dco.hw,
+               [CLKID_PCIE_PLL_DCO_DIV2]       = &g12a_pcie_pll_dco_div2.hw,
+               [CLKID_PCIE_PLL_OD]             = &g12a_pcie_pll_od.hw,
+               [CLKID_PCIE_PLL]                = &g12a_pcie_pll.hw,
+               [CLKID_VDEC_1_SEL]              = &g12a_vdec_1_sel.hw,
+               [CLKID_VDEC_1_DIV]              = &g12a_vdec_1_div.hw,
+               [CLKID_VDEC_1]                  = &g12a_vdec_1.hw,
+               [CLKID_VDEC_HEVC_SEL]           = &g12a_vdec_hevc_sel.hw,
+               [CLKID_VDEC_HEVC_DIV]           = &g12a_vdec_hevc_div.hw,
+               [CLKID_VDEC_HEVC]               = &g12a_vdec_hevc.hw,
+               [CLKID_VDEC_HEVCF_SEL]          = &g12a_vdec_hevcf_sel.hw,
+               [CLKID_VDEC_HEVCF_DIV]          = &g12a_vdec_hevcf_div.hw,
+               [CLKID_VDEC_HEVCF]              = &g12a_vdec_hevcf.hw,
+               [CLKID_TS_DIV]                  = &g12a_ts_div.hw,
+               [CLKID_TS]                      = &g12a_ts.hw,
+               [CLKID_GP1_PLL_DCO]             = &sm1_gp1_pll_dco.hw,
+               [CLKID_GP1_PLL]                 = &sm1_gp1_pll.hw,
+               [CLKID_DSU_CLK_DYN0_SEL]        = &sm1_dsu_clk_premux0.hw,
+               [CLKID_DSU_CLK_DYN0_DIV]        = &sm1_dsu_clk_premux1.hw,
+               [CLKID_DSU_CLK_DYN0]            = &sm1_dsu_clk_mux0_div.hw,
+               [CLKID_DSU_CLK_DYN1_SEL]        = &sm1_dsu_clk_postmux0.hw,
+               [CLKID_DSU_CLK_DYN1_DIV]        = &sm1_dsu_clk_mux1_div.hw,
+               [CLKID_DSU_CLK_DYN1]            = &sm1_dsu_clk_postmux1.hw,
+               [CLKID_DSU_CLK_DYN]             = &sm1_dsu_clk_dyn.hw,
+               [CLKID_DSU_CLK_FINAL]           = &sm1_dsu_final_clk.hw,
+               [CLKID_DSU_CLK]                 = &sm1_dsu_clk.hw,
+               [CLKID_CPU1_CLK]                = &sm1_cpu1_clk.hw,
+               [CLKID_CPU2_CLK]                = &sm1_cpu2_clk.hw,
+               [CLKID_CPU3_CLK]                = &sm1_cpu3_clk.hw,
+               [NR_CLKS]                       = NULL,
+       },
+       .num = NR_CLKS,
+};
+
 /* Convenience table to populate regmap in .probe */
 static struct clk_regmap *const g12a_clk_regmaps[] = {
        &g12a_clk81,
@@ -3786,34 +4853,243 @@ static struct clk_regmap *const g12a_clk_regmaps[] = {
        &g12b_cpub_clk_axi,
        &g12b_cpub_clk_trace_sel,
        &g12b_cpub_clk_trace,
+       &sm1_gp1_pll_dco,
+       &sm1_gp1_pll,
+       &sm1_dsu_clk_premux0,
+       &sm1_dsu_clk_premux1,
+       &sm1_dsu_clk_mux0_div,
+       &sm1_dsu_clk_postmux0,
+       &sm1_dsu_clk_mux1_div,
+       &sm1_dsu_clk_postmux1,
+       &sm1_dsu_clk_dyn,
+       &sm1_dsu_final_clk,
+       &sm1_dsu_clk,
+       &sm1_cpu1_clk,
+       &sm1_cpu2_clk,
+       &sm1_cpu3_clk,
 };
 
 static const struct reg_sequence g12a_init_regs[] = {
        { .reg = HHI_MPLL_CNTL0,        .def = 0x00000543 },
 };
 
-static const struct meson_eeclkc_data g12a_clkc_data = {
-       .regmap_clks = g12a_clk_regmaps,
-       .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
-       .hw_onecell_data = &g12a_hw_onecell_data,
-       .init_regs = g12a_init_regs,
-       .init_count = ARRAY_SIZE(g12a_init_regs),
-};
-
-static const struct meson_eeclkc_data g12b_clkc_data = {
-       .regmap_clks = g12a_clk_regmaps,
-       .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
-       .hw_onecell_data = &g12b_hw_onecell_data
+static int meson_g12a_dvfs_setup_common(struct platform_device *pdev,
+                                       struct clk_hw **hws)
+{
+       const char *notifier_clk_name;
+       struct clk *notifier_clk;
+       struct clk_hw *xtal;
+       int ret;
+
+       xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0);
+
+       /* Setup clock notifier for cpu_clk_postmux0 */
+       g12a_cpu_clk_postmux0_nb_data.xtal = xtal;
+       notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk_postmux0.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk,
+                                   &g12a_cpu_clk_postmux0_nb_data.nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the cpu_clk_postmux0 notifier\n");
+               return ret;
+       }
+
+       /* Setup clock notifier for cpu_clk_dyn mux */
+       notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk_dyn.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the cpu_clk_dyn notifier\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static int meson_g12b_dvfs_setup(struct platform_device *pdev)
+{
+       struct clk_hw **hws = g12b_hw_onecell_data.hws;
+       const char *notifier_clk_name;
+       struct clk *notifier_clk;
+       struct clk_hw *xtal;
+       int ret;
+
+       ret = meson_g12a_dvfs_setup_common(pdev, hws);
+       if (ret)
+               return ret;
+
+       xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0);
+
+       /* Setup clock notifier for cpu_clk mux */
+       notifier_clk_name = clk_hw_get_name(&g12b_cpu_clk.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the cpu_clk notifier\n");
+               return ret;
+       }
+
+       /* Setup clock notifier for sys1_pll */
+       notifier_clk_name = clk_hw_get_name(&g12b_sys1_pll.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk,
+                                   &g12b_cpu_clk_sys1_pll_nb_data.nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the sys1_pll notifier\n");
+               return ret;
+       }
+
+       /* Add notifiers for the second CPU cluster */
+
+       /* Setup clock notifier for cpub_clk_postmux0 */
+       g12b_cpub_clk_postmux0_nb_data.xtal = xtal;
+       notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk_postmux0.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk,
+                                   &g12b_cpub_clk_postmux0_nb_data.nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the cpub_clk_postmux0 notifier\n");
+               return ret;
+       }
+
+       /* Setup clock notifier for cpub_clk_dyn mux */
+       notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk_dyn.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the cpub_clk_dyn notifier\n");
+               return ret;
+       }
+
+       /* Setup clock notifier for cpub_clk mux */
+       notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the cpub_clk notifier\n");
+               return ret;
+       }
+
+       /* Setup clock notifier for sys_pll */
+       notifier_clk_name = clk_hw_get_name(&g12a_sys_pll.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk,
+                                   &g12b_cpub_clk_sys_pll_nb_data.nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the sys_pll notifier\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static int meson_g12a_dvfs_setup(struct platform_device *pdev)
+{
+       struct clk_hw **hws = g12a_hw_onecell_data.hws;
+       const char *notifier_clk_name;
+       struct clk *notifier_clk;
+       int ret;
+
+       ret = meson_g12a_dvfs_setup_common(pdev, hws);
+       if (ret)
+               return ret;
+
+       /* Setup clock notifier for cpu_clk mux */
+       notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the cpu_clk notifier\n");
+               return ret;
+       }
+
+       /* Setup clock notifier for sys_pll */
+       notifier_clk_name = clk_hw_get_name(&g12a_sys_pll.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk, &g12a_sys_pll_nb_data.nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the sys_pll notifier\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+struct meson_g12a_data {
+       const struct meson_eeclkc_data eeclkc_data;
+       int (*dvfs_setup)(struct platform_device *pdev);
+};
+
+static int meson_g12a_probe(struct platform_device *pdev)
+{
+       const struct meson_eeclkc_data *eeclkc_data;
+       const struct meson_g12a_data *g12a_data;
+       int ret;
+
+       eeclkc_data = of_device_get_match_data(&pdev->dev);
+       if (!eeclkc_data)
+               return -EINVAL;
+
+       ret = meson_eeclkc_probe(pdev);
+       if (ret)
+               return ret;
+
+       g12a_data = container_of(eeclkc_data, struct meson_g12a_data,
+                                eeclkc_data);
+
+       if (g12a_data->dvfs_setup)
+               return g12a_data->dvfs_setup(pdev);
+
+       return 0;
+}
+
+static const struct meson_g12a_data g12a_clkc_data = {
+       .eeclkc_data = {
+               .regmap_clks = g12a_clk_regmaps,
+               .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
+               .hw_onecell_data = &g12a_hw_onecell_data,
+               .init_regs = g12a_init_regs,
+               .init_count = ARRAY_SIZE(g12a_init_regs),
+       },
+       .dvfs_setup = meson_g12a_dvfs_setup,
+};
+
+static const struct meson_g12a_data g12b_clkc_data = {
+       .eeclkc_data = {
+               .regmap_clks = g12a_clk_regmaps,
+               .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
+               .hw_onecell_data = &g12b_hw_onecell_data,
+       },
+       .dvfs_setup = meson_g12b_dvfs_setup,
+};
+
+static const struct meson_g12a_data sm1_clkc_data = {
+       .eeclkc_data = {
+               .regmap_clks = g12a_clk_regmaps,
+               .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
+               .hw_onecell_data = &sm1_hw_onecell_data,
+       },
+       .dvfs_setup = meson_g12a_dvfs_setup,
 };
 
 static const struct of_device_id clkc_match_table[] = {
-       { .compatible = "amlogic,g12a-clkc", .data = &g12a_clkc_data },
-       { .compatible = "amlogic,g12b-clkc", .data = &g12b_clkc_data },
+       {
+               .compatible = "amlogic,g12a-clkc",
+               .data = &g12a_clkc_data.eeclkc_data
+       },
+       {
+               .compatible = "amlogic,g12b-clkc",
+               .data = &g12b_clkc_data.eeclkc_data
+       },
+       {
+               .compatible = "amlogic,sm1-clkc",
+               .data = &sm1_clkc_data.eeclkc_data
+       },
        {}
 };
 
 static struct platform_driver g12a_driver = {
-       .probe          = meson_eeclkc_probe,
+       .probe          = meson_g12a_probe,
        .driver         = {
                .name   = "g12a-clkc",
                .of_match_table = clkc_match_table,
index c8aed31fbe1715c4e2077a61c9e1a71493388a88..9df4068aced113e9ccb7ebf82ce12cede69317be 100644 (file)
 #define HHI_GP0_PLL_CNTL5              0x054
 #define HHI_GP0_PLL_CNTL6              0x058
 #define HHI_GP0_PLL_STS                        0x05C
+#define HHI_GP1_PLL_CNTL0              0x060
+#define HHI_GP1_PLL_CNTL1              0x064
+#define HHI_GP1_PLL_CNTL2              0x068
+#define HHI_GP1_PLL_CNTL3              0x06C
+#define HHI_GP1_PLL_CNTL4              0x070
+#define HHI_GP1_PLL_CNTL5              0x074
+#define HHI_GP1_PLL_CNTL6              0x078
+#define HHI_GP1_PLL_STS                        0x07C
 #define HHI_PCIE_PLL_CNTL0             0x098
 #define HHI_PCIE_PLL_CNTL1             0x09C
 #define HHI_PCIE_PLL_CNTL2             0x0A0
 #define HHI_SYS_CPUB_CLK_CNTL1         0x200
 #define HHI_SYS_CPUB_CLK_CNTL          0x208
 #define HHI_VPU_CLKB_CNTL              0x20C
+#define HHI_SYS_CPU_CLK_CNTL2          0x210
+#define HHI_SYS_CPU_CLK_CNTL3          0x214
+#define HHI_SYS_CPU_CLK_CNTL4          0x218
+#define HHI_SYS_CPU_CLK_CNTL5          0x21c
+#define HHI_SYS_CPU_CLK_CNTL6          0x220
 #define HHI_GEN_CLK_CNTL               0x228
 #define HHI_VDIN_MEAS_CLK_CNTL         0x250
 #define HHI_MIPIDSI_PHY_CLK_CNTL       0x254
 #define CLKID_CPUB_CLK_DYN1_DIV                        221
 #define CLKID_CPUB_CLK_DYN1                    222
 #define CLKID_CPUB_CLK_DYN                     223
-#define CLKID_CPUB_CLK                         224
 #define CLKID_CPUB_CLK_DIV16_EN                        225
 #define CLKID_CPUB_CLK_DIV16                   226
 #define CLKID_CPUB_CLK_DIV2                    227
 #define CLKID_CPUB_CLK_AXI                     239
 #define CLKID_CPUB_CLK_TRACE_SEL               240
 #define CLKID_CPUB_CLK_TRACE                   241
+#define CLKID_GP1_PLL_DCO                      242
+#define CLKID_DSU_CLK_DYN0_SEL                 244
+#define CLKID_DSU_CLK_DYN0_DIV                 245
+#define CLKID_DSU_CLK_DYN0                     246
+#define CLKID_DSU_CLK_DYN1_SEL                 247
+#define CLKID_DSU_CLK_DYN1_DIV                 248
+#define CLKID_DSU_CLK_DYN1                     249
+#define CLKID_DSU_CLK_DYN                      250
+#define CLKID_DSU_CLK_FINAL                    251
 
-#define NR_CLKS                                        242
+#define NR_CLKS                                        256
 
 /* include the CLKIDs that have been made part of the DT binding */
 #include <dt-bindings/clock/g12a-clkc.h>
index 449f6ac189d86ea59fcb0d66ea0efe4d40dea9ac..e940861a396b591c190da58042b108f2e81ac9e8 100644 (file)
@@ -11,8 +11,6 @@
 #include "clk-regmap.h"
 #include "clk-dualdiv.h"
 
-#define IN_PREFIX "ao-in-"
-
 /* AO Configuration Clock registers offsets */
 #define AO_RTI_PWR_CNTL_REG1   0x0c
 #define AO_RTI_PWR_CNTL_REG0   0x10
@@ -31,7 +29,9 @@ static struct clk_regmap _name##_ao = {                                       \
        .hw.init = &(struct clk_init_data) {                            \
                .name = #_name "_ao",                                   \
                .ops = &clk_regmap_gate_ops,                            \
-               .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \
+               .parent_data = &(const struct clk_parent_data) {        \
+                       .fw_name = "mpeg-clk",                          \
+               },                                                      \
                .num_parents = 1,                                       \
                .flags = CLK_IGNORE_UNUSED,                             \
        },                                                              \
@@ -52,7 +52,9 @@ static struct clk_regmap ao_cts_oscin = {
        .hw.init = &(struct clk_init_data){
                .name = "ao_cts_oscin",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -65,7 +67,7 @@ static struct clk_regmap ao_32k_pre = {
        .hw.init = &(struct clk_init_data){
                .name = "ao_32k_pre",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "ao_cts_oscin" },
+               .parent_hws = (const struct clk_hw *[]) { &ao_cts_oscin.hw },
                .num_parents = 1,
        },
 };
@@ -112,7 +114,7 @@ static struct clk_regmap ao_32k_div = {
        .hw.init = &(struct clk_init_data){
                .name = "ao_32k_div",
                .ops = &meson_clk_dualdiv_ops,
-               .parent_names = (const char *[]){ "ao_32k_pre" },
+               .parent_hws = (const struct clk_hw *[]) { &ao_32k_pre.hw },
                .num_parents = 1,
        },
 };
@@ -127,8 +129,10 @@ static struct clk_regmap ao_32k_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "ao_32k_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "ao_32k_div",
-                                                 "ao_32k_pre" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &ao_32k_div.hw,
+                       &ao_32k_pre.hw
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -142,7 +146,7 @@ static struct clk_regmap ao_32k = {
        .hw.init = &(struct clk_init_data){
                .name = "ao_32k",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "ao_32k_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &ao_32k_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -159,10 +163,12 @@ static struct clk_regmap ao_cts_rtc_oscin = {
        .hw.init = &(struct clk_init_data){
                .name = "ao_cts_rtc_oscin",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "ext-32k-0",
-                                                 IN_PREFIX "ext-32k-1",
-                                                 IN_PREFIX "ext-32k-2",
-                                                 "ao_32k" },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "ext-32k-0", },
+                       { .fw_name = "ext-32k-1", },
+                       { .fw_name = "ext-32k-2", },
+                       { .hw = &ao_32k.hw },
+               },
                .num_parents = 4,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -178,8 +184,10 @@ static struct clk_regmap ao_clk81 = {
        .hw.init = &(struct clk_init_data){
                .name = "ao_clk81",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk",
-                                                 "ao_cts_rtc_oscin" },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "mpeg-clk", },
+                       { .hw = &ao_cts_rtc_oscin.hw },
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -208,8 +216,10 @@ static struct clk_regmap ao_cts_cec = {
                 * Until CCF gets fixed, adding this fake parent that won't
                 * ever be registered should work around the problem
                 */
-               .parent_names = (const char *[]){ "fixme",
-                                                 "ao_cts_rtc_oscin" },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .name = "fixme", .index = -1, },
+                       { .hw = &ao_cts_rtc_oscin.hw },
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -261,14 +271,6 @@ static const struct clk_hw_onecell_data gxbb_aoclk_onecell_data = {
        .num = NR_CLKS,
 };
 
-static const struct meson_aoclk_input gxbb_aoclk_inputs[] = {
-       { .name = "xtal",       .required = true,  },
-       { .name = "mpeg-clk",   .required = true,  },
-       {. name = "ext-32k-0",  .required = false, },
-       {. name = "ext-32k-1",  .required = false, },
-       {. name = "ext-32k-2",  .required = false, },
-};
-
 static const struct meson_aoclk_data gxbb_aoclkc_data = {
        .reset_reg      = AO_RTI_GEN_CNTL_REG0,
        .num_reset      = ARRAY_SIZE(gxbb_aoclk_reset),
@@ -276,9 +278,6 @@ static const struct meson_aoclk_data gxbb_aoclkc_data = {
        .num_clks       = ARRAY_SIZE(gxbb_aoclk),
        .clks           = gxbb_aoclk,
        .hw_data        = &gxbb_aoclk_onecell_data,
-       .inputs         = gxbb_aoclk_inputs,
-       .num_inputs     = ARRAY_SIZE(gxbb_aoclk_inputs),
-       .input_prefix   = IN_PREFIX,
 };
 
 static const struct of_device_id gxbb_aoclkc_match_table[] = {
index dab16d9b1af8b442eed369771e38117c06f48864..7cfb998eeb3e0e05234f041ce0bb6938dc7db1f9 100644 (file)
 #include <linux/platform_device.h>
 
 #include "gxbb.h"
-#include "clk-input.h"
 #include "clk-regmap.h"
 #include "clk-pll.h"
 #include "clk-mpll.h"
 #include "meson-eeclk.h"
 #include "vid-pll-div.h"
 
-#define IN_PREFIX "ee-in-"
-
 static DEFINE_SPINLOCK(meson_clk_lock);
 
 static const struct pll_params_table gxbb_gp0_pll_params_table[] = {
@@ -121,7 +118,9 @@ static struct clk_regmap gxbb_fixed_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -136,7 +135,9 @@ static struct clk_regmap gxbb_fixed_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_fixed_pll_dco.hw
+               },
                .num_parents = 1,
                /*
                 * This clock won't ever change at runtime so
@@ -151,7 +152,9 @@ static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_pre_mult",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -192,7 +195,9 @@ static struct clk_regmap gxbb_hdmi_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_pre_mult" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_hdmi_pll_pre_mult.hw
+               },
                .num_parents = 1,
                /*
                 * Display directly handle hdmi pll registers ATM, we need
@@ -244,7 +249,9 @@ static struct clk_regmap gxl_hdmi_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
                /*
                 * Display directly handle hdmi pll registers ATM, we need
@@ -264,7 +271,9 @@ static struct clk_regmap gxbb_hdmi_pll_od = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_od",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_hdmi_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
@@ -280,7 +289,9 @@ static struct clk_regmap gxbb_hdmi_pll_od2 = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_od2",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_od" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_hdmi_pll_od.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
@@ -296,7 +307,9 @@ static struct clk_regmap gxbb_hdmi_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_od2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_hdmi_pll_od2.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
@@ -312,7 +325,9 @@ static struct clk_regmap gxl_hdmi_pll_od = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_od",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxl_hdmi_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
@@ -328,7 +343,9 @@ static struct clk_regmap gxl_hdmi_pll_od2 = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_od2",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_od" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxl_hdmi_pll_od.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
@@ -344,7 +361,9 @@ static struct clk_regmap gxl_hdmi_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_od2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxl_hdmi_pll_od2.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
@@ -381,7 +400,9 @@ static struct clk_regmap gxbb_sys_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -396,7 +417,9 @@ static struct clk_regmap gxbb_sys_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "sys_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sys_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -442,7 +465,9 @@ static struct clk_regmap gxbb_gp0_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "gp0_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -494,7 +519,9 @@ static struct clk_regmap gxl_gp0_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "gp0_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -509,7 +536,17 @@ static struct clk_regmap gxbb_gp0_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "gp0_pll",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "gp0_pll_dco" },
+               .parent_data = &(const struct clk_parent_data) {
+                       /*
+                        * Note:
+                        * GXL and GXBB have different gp0_pll_dco (with
+                        * different struct clk_hw). We fallback to the global
+                        * naming string mechanism so gp0_pll picks up the
+                        * appropriate one.
+                        */
+                       .name = "gp0_pll_dco",
+                       .index = -1,
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -521,7 +558,9 @@ static struct clk_fixed_factor gxbb_fclk_div2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div2_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -534,7 +573,9 @@ static struct clk_regmap gxbb_fclk_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div2_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_fclk_div2_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_IS_CRITICAL,
        },
@@ -546,7 +587,7 @@ static struct clk_fixed_factor gxbb_fclk_div3_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div3_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -559,7 +600,9 @@ static struct clk_regmap gxbb_fclk_div3 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div3",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div3_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_fclk_div3_div.hw
+               },
                .num_parents = 1,
                /*
                 * FIXME:
@@ -582,7 +625,7 @@ static struct clk_fixed_factor gxbb_fclk_div4_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div4_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -595,7 +638,9 @@ static struct clk_regmap gxbb_fclk_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div4",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div4_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_fclk_div4_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -606,7 +651,7 @@ static struct clk_fixed_factor gxbb_fclk_div5_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div5_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -619,7 +664,9 @@ static struct clk_regmap gxbb_fclk_div5 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div5",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div5_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_fclk_div5_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -630,7 +677,7 @@ static struct clk_fixed_factor gxbb_fclk_div7_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div7_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -643,7 +690,9 @@ static struct clk_regmap gxbb_fclk_div7 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div7",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div7_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_fclk_div7_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -657,7 +706,7 @@ static struct clk_regmap gxbb_mpll_prediv = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll_prediv",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -684,7 +733,9 @@ static struct clk_regmap gxbb_mpll0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -697,7 +748,7 @@ static struct clk_regmap gxbb_mpll0 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll0_div" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -725,7 +776,9 @@ static struct clk_regmap gxbb_mpll1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll1_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -738,7 +791,7 @@ static struct clk_regmap gxbb_mpll1 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll1_div" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_mpll1_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -766,7 +819,9 @@ static struct clk_regmap gxbb_mpll2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll2_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -779,16 +834,21 @@ static struct clk_regmap gxbb_mpll2 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll2_div" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_mpll2_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
 static u32 mux_table_clk81[]   = { 0, 2, 3, 4, 5, 6, 7 };
-static const char * const clk81_parent_names[] = {
-       IN_PREFIX "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
-       "fclk_div3", "fclk_div5"
+static const struct clk_parent_data clk81_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &gxbb_fclk_div7.hw },
+       { .hw = &gxbb_mpll1.hw },
+       { .hw = &gxbb_mpll2.hw },
+       { .hw = &gxbb_fclk_div4.hw },
+       { .hw = &gxbb_fclk_div3.hw },
+       { .hw = &gxbb_fclk_div5.hw },
 };
 
 static struct clk_regmap gxbb_mpeg_clk_sel = {
@@ -806,8 +866,8 @@ static struct clk_regmap gxbb_mpeg_clk_sel = {
                 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
                 * fclk_div4, fclk_div3, fclk_div5
                 */
-               .parent_names = clk81_parent_names,
-               .num_parents = ARRAY_SIZE(clk81_parent_names),
+               .parent_data = clk81_parent_data,
+               .num_parents = ARRAY_SIZE(clk81_parent_data),
        },
 };
 
@@ -820,7 +880,9 @@ static struct clk_regmap gxbb_mpeg_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpeg_clk_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mpeg_clk_sel.hw
+               },
                .num_parents = 1,
        },
 };
@@ -834,7 +896,9 @@ static struct clk_regmap gxbb_clk81 = {
        .hw.init = &(struct clk_init_data){
                .name = "clk81",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mpeg_clk_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_IS_CRITICAL,
        },
@@ -850,7 +914,10 @@ static struct clk_regmap gxbb_sar_adc_clk_sel = {
                .name = "sar_adc_clk_sel",
                .ops = &clk_regmap_mux_ops,
                /* NOTE: The datasheet doesn't list the parents for bit 10 */
-               .parent_names = (const char *[]){ IN_PREFIX "xtal", "clk81", },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &gxbb_clk81.hw },
+               },
                .num_parents = 2,
        },
 };
@@ -864,7 +931,9 @@ static struct clk_regmap gxbb_sar_adc_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "sar_adc_clk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sar_adc_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sar_adc_clk_sel.hw
+               },
                .num_parents = 1,
        },
 };
@@ -877,7 +946,9 @@ static struct clk_regmap gxbb_sar_adc_clk = {
        .hw.init = &(struct clk_init_data){
                .name = "sar_adc_clk",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sar_adc_clk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sar_adc_clk_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -888,9 +959,15 @@ static struct clk_regmap gxbb_sar_adc_clk = {
  * muxed by a glitch-free switch.
  */
 
-static const char * const gxbb_mali_0_1_parent_names[] = {
-       IN_PREFIX "xtal", "gp0_pll", "mpll2", "mpll1", "fclk_div7",
-       "fclk_div4", "fclk_div3", "fclk_div5"
+static const struct clk_parent_data gxbb_mali_0_1_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &gxbb_gp0_pll.hw },
+       { .hw = &gxbb_mpll2.hw },
+       { .hw = &gxbb_mpll1.hw },
+       { .hw = &gxbb_fclk_div7.hw },
+       { .hw = &gxbb_fclk_div4.hw },
+       { .hw = &gxbb_fclk_div3.hw },
+       { .hw = &gxbb_fclk_div5.hw },
 };
 
 static struct clk_regmap gxbb_mali_0_sel = {
@@ -907,7 +984,7 @@ static struct clk_regmap gxbb_mali_0_sel = {
                 * xtal, gp0_pll, mpll2, mpll1, fclk_div7,
                 * fclk_div4, fclk_div3, fclk_div5
                 */
-               .parent_names = gxbb_mali_0_1_parent_names,
+               .parent_data = gxbb_mali_0_1_parent_data,
                .num_parents = 8,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -922,7 +999,9 @@ static struct clk_regmap gxbb_mali_0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "mali_0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mali_0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -936,7 +1015,9 @@ static struct clk_regmap gxbb_mali_0 = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mali_0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mali_0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -956,7 +1037,7 @@ static struct clk_regmap gxbb_mali_1_sel = {
                 * xtal, gp0_pll, mpll2, mpll1, fclk_div7,
                 * fclk_div4, fclk_div3, fclk_div5
                 */
-               .parent_names = gxbb_mali_0_1_parent_names,
+               .parent_data = gxbb_mali_0_1_parent_data,
                .num_parents = 8,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -971,7 +1052,9 @@ static struct clk_regmap gxbb_mali_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "mali_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mali_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -985,14 +1068,17 @@ static struct clk_regmap gxbb_mali_1 = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mali_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mali_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
-static const char * const gxbb_mali_parent_names[] = {
-       "mali_0", "mali_1"
+static const struct clk_hw *gxbb_mali_parent_hws[] = {
+       &gxbb_mali_0.hw,
+       &gxbb_mali_1.hw,
 };
 
 static struct clk_regmap gxbb_mali = {
@@ -1004,7 +1090,7 @@ static struct clk_regmap gxbb_mali = {
        .hw.init = &(struct clk_init_data){
                .name = "mali",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_mali_parent_names,
+               .parent_hws = gxbb_mali_parent_hws,
                .num_parents = 2,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -1021,7 +1107,11 @@ static struct clk_regmap gxbb_cts_amclk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_amclk_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mpll0.hw,
+                       &gxbb_mpll1.hw,
+                       &gxbb_mpll2.hw,
+               },
                .num_parents = 3,
        },
 };
@@ -1036,7 +1126,9 @@ static struct clk_regmap gxbb_cts_amclk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_amclk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "cts_amclk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_cts_amclk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1050,7 +1142,9 @@ static struct clk_regmap gxbb_cts_amclk = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_amclk",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_amclk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_cts_amclk_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1067,7 +1161,11 @@ static struct clk_regmap gxbb_cts_mclk_i958_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_mclk_i958_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mpll0.hw,
+                       &gxbb_mpll1.hw,
+                       &gxbb_mpll2.hw,
+               },
                .num_parents = 3,
        },
 };
@@ -1082,7 +1180,9 @@ static struct clk_regmap gxbb_cts_mclk_i958_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_mclk_i958_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "cts_mclk_i958_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_cts_mclk_i958_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1096,7 +1196,9 @@ static struct clk_regmap gxbb_cts_mclk_i958 = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_mclk_i958",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_mclk_i958_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_cts_mclk_i958_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1111,7 +1213,10 @@ static struct clk_regmap gxbb_cts_i958 = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_i958",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "cts_amclk", "cts_mclk_i958" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_cts_amclk.hw,
+                       &gxbb_cts_mclk_i958.hw
+               },
                .num_parents = 2,
                /*
                 *The parent is specific to origin of the audio data. Let the
@@ -1121,6 +1226,33 @@ static struct clk_regmap gxbb_cts_i958 = {
        },
 };
 
+static const struct clk_parent_data gxbb_32k_clk_parent_data[] = {
+       { .fw_name = "xtal", },
+       /*
+        * FIXME: This clock is provided by the ao clock controller but the
+        * clock is not yet part of the binding of this controller, so string
+        * name must be use to set this parent.
+        */
+       { .name = "cts_slow_oscin", .index = -1 },
+       { .hw = &gxbb_fclk_div3.hw },
+       { .hw = &gxbb_fclk_div5.hw },
+};
+
+static struct clk_regmap gxbb_32k_clk_sel = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_32K_CLK_CNTL,
+               .mask = 0x3,
+               .shift = 16,
+               },
+       .hw.init = &(struct clk_init_data){
+               .name = "32k_clk_sel",
+               .ops = &clk_regmap_mux_ops,
+               .parent_data = gxbb_32k_clk_parent_data,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
 static struct clk_regmap gxbb_32k_clk_div = {
        .data = &(struct clk_regmap_div_data){
                .offset = HHI_32K_CLK_CNTL,
@@ -1130,7 +1262,9 @@ static struct clk_regmap gxbb_32k_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "32k_clk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "32k_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_32k_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST,
        },
@@ -1144,34 +1278,20 @@ static struct clk_regmap gxbb_32k_clk = {
        .hw.init = &(struct clk_init_data){
                .name = "32k_clk",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "32k_clk_div" },
-               .num_parents = 1,
-               .flags = CLK_SET_RATE_PARENT,
-       },
-};
-
-static const char * const gxbb_32k_clk_parent_names[] = {
-       IN_PREFIX "xtal", "cts_slow_oscin", "fclk_div3", "fclk_div5"
-};
-
-static struct clk_regmap gxbb_32k_clk_sel = {
-       .data = &(struct clk_regmap_mux_data){
-               .offset = HHI_32K_CLK_CNTL,
-               .mask = 0x3,
-               .shift = 16,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_32k_clk_div.hw
                },
-       .hw.init = &(struct clk_init_data){
-               .name = "32k_clk_sel",
-               .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_32k_clk_parent_names,
-               .num_parents = 4,
+               .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
-static const char * const gxbb_sd_emmc_clk0_parent_names[] = {
-       IN_PREFIX "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
-
+static const struct clk_parent_data gxbb_sd_emmc_clk0_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &gxbb_fclk_div2.hw },
+       { .hw = &gxbb_fclk_div3.hw },
+       { .hw = &gxbb_fclk_div5.hw },
+       { .hw = &gxbb_fclk_div7.hw },
        /*
         * Following these parent clocks, we should also have had mpll2, mpll3
         * and gp0_pll but these clocks are too precious to be used here. All
@@ -1190,8 +1310,8 @@ static struct clk_regmap gxbb_sd_emmc_a_clk0_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_a_clk0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_sd_emmc_clk0_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
+               .parent_data = gxbb_sd_emmc_clk0_parent_data,
+               .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_data),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1206,7 +1326,9 @@ static struct clk_regmap gxbb_sd_emmc_a_clk0_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_a_clk0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sd_emmc_a_clk0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1220,7 +1342,9 @@ static struct clk_regmap gxbb_sd_emmc_a_clk0 = {
        .hw.init = &(struct clk_init_data){
                .name = "sd_emmc_a_clk0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sd_emmc_a_clk0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sd_emmc_a_clk0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1236,8 +1360,8 @@ static struct clk_regmap gxbb_sd_emmc_b_clk0_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_b_clk0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_sd_emmc_clk0_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
+               .parent_data = gxbb_sd_emmc_clk0_parent_data,
+               .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_data),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1252,7 +1376,9 @@ static struct clk_regmap gxbb_sd_emmc_b_clk0_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_b_clk0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sd_emmc_b_clk0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1266,7 +1392,9 @@ static struct clk_regmap gxbb_sd_emmc_b_clk0 = {
        .hw.init = &(struct clk_init_data){
                .name = "sd_emmc_b_clk0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sd_emmc_b_clk0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1282,8 +1410,8 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_c_clk0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_sd_emmc_clk0_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
+               .parent_data = gxbb_sd_emmc_clk0_parent_data,
+               .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_data),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1298,7 +1426,9 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_c_clk0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sd_emmc_c_clk0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1312,7 +1442,9 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0 = {
        .hw.init = &(struct clk_init_data){
                .name = "sd_emmc_c_clk0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sd_emmc_c_clk0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1320,8 +1452,11 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0 = {
 
 /* VPU Clock */
 
-static const char * const gxbb_vpu_parent_names[] = {
-       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
+static const struct clk_hw *gxbb_vpu_parent_hws[] = {
+       &gxbb_fclk_div4.hw,
+       &gxbb_fclk_div3.hw,
+       &gxbb_fclk_div5.hw,
+       &gxbb_fclk_div7.hw,
 };
 
 static struct clk_regmap gxbb_vpu_0_sel = {
@@ -1337,8 +1472,8 @@ static struct clk_regmap gxbb_vpu_0_sel = {
                 * bits 9:10 selects from 4 possible parents:
                 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
                 */
-               .parent_names = gxbb_vpu_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vpu_parent_names),
+               .parent_hws = gxbb_vpu_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_vpu_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
@@ -1352,7 +1487,7 @@ static struct clk_regmap gxbb_vpu_0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vpu_0_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vpu_0_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1366,7 +1501,7 @@ static struct clk_regmap gxbb_vpu_0 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vpu_0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vpu_0_div" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vpu_0_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1385,8 +1520,8 @@ static struct clk_regmap gxbb_vpu_1_sel = {
                 * bits 25:26 selects from 4 possible parents:
                 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
                 */
-               .parent_names = gxbb_vpu_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vpu_parent_names),
+               .parent_hws = gxbb_vpu_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_vpu_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
@@ -1400,7 +1535,7 @@ static struct clk_regmap gxbb_vpu_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vpu_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vpu_1_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1414,7 +1549,7 @@ static struct clk_regmap gxbb_vpu_1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vpu_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vpu_1_div" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vpu_1_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1433,7 +1568,10 @@ static struct clk_regmap gxbb_vpu = {
                 * bit 31 selects from 2 possible parents:
                 * vpu_0 or vpu_1
                 */
-               .parent_names = (const char *[]){ "vpu_0", "vpu_1" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vpu_0.hw,
+                       &gxbb_vpu_1.hw
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -1441,8 +1579,11 @@ static struct clk_regmap gxbb_vpu = {
 
 /* VAPB Clock */
 
-static const char * const gxbb_vapb_parent_names[] = {
-       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
+static const struct clk_hw *gxbb_vapb_parent_hws[] = {
+       &gxbb_fclk_div4.hw,
+       &gxbb_fclk_div3.hw,
+       &gxbb_fclk_div5.hw,
+       &gxbb_fclk_div7.hw,
 };
 
 static struct clk_regmap gxbb_vapb_0_sel = {
@@ -1458,8 +1599,8 @@ static struct clk_regmap gxbb_vapb_0_sel = {
                 * bits 9:10 selects from 4 possible parents:
                 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
                 */
-               .parent_names = gxbb_vapb_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vapb_parent_names),
+               .parent_hws = gxbb_vapb_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_vapb_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
@@ -1473,7 +1614,9 @@ static struct clk_regmap gxbb_vapb_0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vapb_0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vapb_0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vapb_0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1487,7 +1630,9 @@ static struct clk_regmap gxbb_vapb_0 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vapb_0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vapb_0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vapb_0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1506,8 +1651,8 @@ static struct clk_regmap gxbb_vapb_1_sel = {
                 * bits 25:26 selects from 4 possible parents:
                 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
                 */
-               .parent_names = gxbb_vapb_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vapb_parent_names),
+               .parent_hws = gxbb_vapb_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_vapb_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
@@ -1521,7 +1666,9 @@ static struct clk_regmap gxbb_vapb_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vapb_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vapb_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vapb_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1535,7 +1682,9 @@ static struct clk_regmap gxbb_vapb_1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vapb_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vapb_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vapb_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1554,7 +1703,10 @@ static struct clk_regmap gxbb_vapb_sel = {
                 * bit 31 selects from 2 possible parents:
                 * vapb_0 or vapb_1
                 */
-               .parent_names = (const char *[]){ "vapb_0", "vapb_1" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vapb_0.hw,
+                       &gxbb_vapb_1.hw
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -1568,7 +1720,7 @@ static struct clk_regmap gxbb_vapb = {
        .hw.init = &(struct clk_init_data) {
                .name = "vapb",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vapb_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vapb_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1592,13 +1744,33 @@ static struct clk_regmap gxbb_vid_pll_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "vid_pll_div",
                .ops = &meson_vid_pll_div_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll" },
+               .parent_data = &(const struct clk_parent_data) {
+                       /*
+                        * Note:
+                        * GXL and GXBB have different hdmi_plls (with
+                        * different struct clk_hw). We fallback to the global
+                        * naming string mechanism so vid_pll_div picks up the
+                        * appropriate one.
+                        */
+                       .name = "hdmi_pll",
+                       .index = -1,
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
        },
 };
 
-static const char * const gxbb_vid_pll_parent_names[] = { "vid_pll_div", "hdmi_pll" };
+static const struct clk_parent_data gxbb_vid_pll_parent_data[] = {
+       { .hw = &gxbb_vid_pll_div.hw },
+       /*
+        * Note:
+        * GXL and GXBB have different hdmi_plls (with
+        * different struct clk_hw). We fallback to the global
+        * naming string mechanism so vid_pll_div picks up the
+        * appropriate one.
+        */
+       { .name = "hdmi_pll", .index = -1 },
+};
 
 static struct clk_regmap gxbb_vid_pll_sel = {
        .data = &(struct clk_regmap_mux_data){
@@ -1613,8 +1785,8 @@ static struct clk_regmap gxbb_vid_pll_sel = {
                 * bit 18 selects from 2 possible parents:
                 * vid_pll_div or hdmi_pll
                 */
-               .parent_names = gxbb_vid_pll_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vid_pll_parent_names),
+               .parent_data = gxbb_vid_pll_parent_data,
+               .num_parents = ARRAY_SIZE(gxbb_vid_pll_parent_data),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -1627,15 +1799,22 @@ static struct clk_regmap gxbb_vid_pll = {
        .hw.init = &(struct clk_init_data) {
                .name = "vid_pll",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vid_pll_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vid_pll_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
 };
 
-static const char * const gxbb_vclk_parent_names[] = {
-       "vid_pll", "fclk_div4", "fclk_div3", "fclk_div5", "vid_pll",
-       "fclk_div7", "mpll1",
+static const struct clk_hw *gxbb_vclk_parent_hws[] = {
+       &gxbb_vid_pll.hw,
+       &gxbb_fclk_div4.hw,
+       &gxbb_fclk_div3.hw,
+       &gxbb_fclk_div5.hw,
+       &gxbb_vid_pll.hw,
+       &gxbb_fclk_div7.hw,
+       &gxbb_mpll1.hw,
 };
 
 static struct clk_regmap gxbb_vclk_sel = {
@@ -1652,8 +1831,8 @@ static struct clk_regmap gxbb_vclk_sel = {
                 * vid_pll, fclk_div4, fclk_div3, fclk_div5,
                 * vid_pll, fclk_div7, mp1
                 */
-               .parent_names = gxbb_vclk_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vclk_parent_names),
+               .parent_hws = gxbb_vclk_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_vclk_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -1672,8 +1851,8 @@ static struct clk_regmap gxbb_vclk2_sel = {
                 * vid_pll, fclk_div4, fclk_div3, fclk_div5,
                 * vid_pll, fclk_div7, mp1
                 */
-               .parent_names = gxbb_vclk_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vclk_parent_names),
+               .parent_hws = gxbb_vclk_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_vclk_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -1686,7 +1865,7 @@ static struct clk_regmap gxbb_vclk_input = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_input",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1700,7 +1879,7 @@ static struct clk_regmap gxbb_vclk2_input = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_input",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1715,7 +1894,9 @@ static struct clk_regmap gxbb_vclk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vclk_input" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk_input.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE,
        },
@@ -1730,7 +1911,9 @@ static struct clk_regmap gxbb_vclk2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vclk2_input" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk2_input.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE,
        },
@@ -1744,7 +1927,7 @@ static struct clk_regmap gxbb_vclk = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk_div" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1758,7 +1941,7 @@ static struct clk_regmap gxbb_vclk2 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2_div" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1772,7 +1955,7 @@ static struct clk_regmap gxbb_vclk_div1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1786,7 +1969,7 @@ static struct clk_regmap gxbb_vclk_div2_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div2_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1800,7 +1983,7 @@ static struct clk_regmap gxbb_vclk_div4_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div4_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1814,7 +1997,7 @@ static struct clk_regmap gxbb_vclk_div6_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div6_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1828,7 +2011,7 @@ static struct clk_regmap gxbb_vclk_div12_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div12_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1842,7 +2025,7 @@ static struct clk_regmap gxbb_vclk2_div1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1856,7 +2039,7 @@ static struct clk_regmap gxbb_vclk2_div2_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div2_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1870,7 +2053,7 @@ static struct clk_regmap gxbb_vclk2_div4_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div4_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1884,7 +2067,7 @@ static struct clk_regmap gxbb_vclk2_div6_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div6_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1898,7 +2081,7 @@ static struct clk_regmap gxbb_vclk2_div12_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div12_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1910,7 +2093,9 @@ static struct clk_fixed_factor gxbb_vclk_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_div2_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk_div2_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1921,7 +2106,9 @@ static struct clk_fixed_factor gxbb_vclk_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div4",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_div4_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk_div4_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1932,7 +2119,9 @@ static struct clk_fixed_factor gxbb_vclk_div6 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div6",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_div6_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk_div6_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1943,7 +2132,9 @@ static struct clk_fixed_factor gxbb_vclk_div12 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div12",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_div12_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk_div12_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1954,7 +2145,9 @@ static struct clk_fixed_factor gxbb_vclk2_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_div2_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk2_div2_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1965,7 +2158,9 @@ static struct clk_fixed_factor gxbb_vclk2_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div4",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_div4_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk2_div4_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1976,7 +2171,9 @@ static struct clk_fixed_factor gxbb_vclk2_div6 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div6",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_div6_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk2_div6_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1987,16 +2184,25 @@ static struct clk_fixed_factor gxbb_vclk2_div12 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div12",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_div12_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk2_div12_en.hw
+               },
                .num_parents = 1,
        },
 };
 
 static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
-static const char * const gxbb_cts_parent_names[] = {
-       "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6",
-       "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4",
-       "vclk2_div6", "vclk2_div12"
+static const struct clk_hw *gxbb_cts_parent_hws[] = {
+       &gxbb_vclk_div1.hw,
+       &gxbb_vclk_div2.hw,
+       &gxbb_vclk_div4.hw,
+       &gxbb_vclk_div6.hw,
+       &gxbb_vclk_div12.hw,
+       &gxbb_vclk2_div1.hw,
+       &gxbb_vclk2_div2.hw,
+       &gxbb_vclk2_div4.hw,
+       &gxbb_vclk2_div6.hw,
+       &gxbb_vclk2_div12.hw,
 };
 
 static struct clk_regmap gxbb_cts_enci_sel = {
@@ -2009,8 +2215,8 @@ static struct clk_regmap gxbb_cts_enci_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_enci_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_cts_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_cts_parent_names),
+               .parent_hws = gxbb_cts_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_cts_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2025,8 +2231,8 @@ static struct clk_regmap gxbb_cts_encp_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_encp_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_cts_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_cts_parent_names),
+               .parent_hws = gxbb_cts_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_cts_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2041,18 +2247,25 @@ static struct clk_regmap gxbb_cts_vdac_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_vdac_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_cts_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_cts_parent_names),
+               .parent_hws = gxbb_cts_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_cts_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
 
 /* TOFIX: add support for cts_tcon */
 static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
-static const char * const gxbb_cts_hdmi_tx_parent_names[] = {
-       "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6",
-       "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4",
-       "vclk2_div6", "vclk2_div12"
+static const struct clk_hw *gxbb_cts_hdmi_tx_parent_hws[] = {
+       &gxbb_vclk_div1.hw,
+       &gxbb_vclk_div2.hw,
+       &gxbb_vclk_div4.hw,
+       &gxbb_vclk_div6.hw,
+       &gxbb_vclk_div12.hw,
+       &gxbb_vclk2_div1.hw,
+       &gxbb_vclk2_div2.hw,
+       &gxbb_vclk2_div4.hw,
+       &gxbb_vclk2_div6.hw,
+       &gxbb_vclk2_div12.hw,
 };
 
 static struct clk_regmap gxbb_hdmi_tx_sel = {
@@ -2071,8 +2284,8 @@ static struct clk_regmap gxbb_hdmi_tx_sel = {
                 * vclk2_div1, vclk2_div2, vclk2_div4, vclk2_div6, vclk2_div12,
                 * cts_tcon
                 */
-               .parent_names = gxbb_cts_hdmi_tx_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_cts_hdmi_tx_parent_names),
+               .parent_hws = gxbb_cts_hdmi_tx_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_cts_hdmi_tx_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2085,7 +2298,9 @@ static struct clk_regmap gxbb_cts_enci = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_enci",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_enci_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_cts_enci_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2099,7 +2314,9 @@ static struct clk_regmap gxbb_cts_encp = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_encp",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_encp_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_cts_encp_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2113,7 +2330,9 @@ static struct clk_regmap gxbb_cts_vdac = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_vdac",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_vdac_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_cts_vdac_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2127,7 +2346,9 @@ static struct clk_regmap gxbb_hdmi_tx = {
        .hw.init = &(struct clk_init_data) {
                .name = "hdmi_tx",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "hdmi_tx_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_hdmi_tx_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2135,8 +2356,11 @@ static struct clk_regmap gxbb_hdmi_tx = {
 
 /* HDMI Clocks */
 
-static const char * const gxbb_hdmi_parent_names[] = {
-       IN_PREFIX "xtal", "fclk_div4", "fclk_div3", "fclk_div5"
+static const struct clk_parent_data gxbb_hdmi_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &gxbb_fclk_div4.hw },
+       { .hw = &gxbb_fclk_div3.hw },
+       { .hw = &gxbb_fclk_div5.hw },
 };
 
 static struct clk_regmap gxbb_hdmi_sel = {
@@ -2149,8 +2373,8 @@ static struct clk_regmap gxbb_hdmi_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_hdmi_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_hdmi_parent_names),
+               .parent_data = gxbb_hdmi_parent_data,
+               .num_parents = ARRAY_SIZE(gxbb_hdmi_parent_data),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2164,7 +2388,7 @@ static struct clk_regmap gxbb_hdmi_div = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "hdmi_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_hdmi_sel.hw },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE,
        },
@@ -2178,7 +2402,7 @@ static struct clk_regmap gxbb_hdmi = {
        .hw.init = &(struct clk_init_data) {
                .name = "hdmi",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "hdmi_div" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_hdmi_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2186,8 +2410,11 @@ static struct clk_regmap gxbb_hdmi = {
 
 /* VDEC clocks */
 
-static const char * const gxbb_vdec_parent_names[] = {
-       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
+static const struct clk_hw *gxbb_vdec_parent_hws[] = {
+       &gxbb_fclk_div4.hw,
+       &gxbb_fclk_div3.hw,
+       &gxbb_fclk_div5.hw,
+       &gxbb_fclk_div7.hw,
 };
 
 static struct clk_regmap gxbb_vdec_1_sel = {
@@ -2200,8 +2427,8 @@ static struct clk_regmap gxbb_vdec_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vdec_parent_names),
+               .parent_hws = gxbb_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2216,7 +2443,9 @@ static struct clk_regmap gxbb_vdec_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vdec_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2230,7 +2459,9 @@ static struct clk_regmap gxbb_vdec_1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vdec_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2246,8 +2477,8 @@ static struct clk_regmap gxbb_vdec_hevc_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hevc_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vdec_parent_names),
+               .parent_hws = gxbb_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2262,7 +2493,9 @@ static struct clk_regmap gxbb_vdec_hevc_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hevc_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_hevc_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vdec_hevc_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2276,7 +2509,9 @@ static struct clk_regmap gxbb_vdec_hevc = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_hevc",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_hevc_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vdec_hevc_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2284,9 +2519,18 @@ static struct clk_regmap gxbb_vdec_hevc = {
 
 static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8,
                                    9, 10, 11, 13, 14, };
-static const char * const gen_clk_parent_names[] = {
-       IN_PREFIX "xtal", "vdec_1", "vdec_hevc", "mpll0", "mpll1", "mpll2",
-       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll",
+static const struct clk_parent_data gen_clk_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &gxbb_vdec_1.hw },
+       { .hw = &gxbb_vdec_hevc.hw },
+       { .hw = &gxbb_mpll0.hw },
+       { .hw = &gxbb_mpll1.hw },
+       { .hw = &gxbb_mpll2.hw },
+       { .hw = &gxbb_fclk_div4.hw },
+       { .hw = &gxbb_fclk_div3.hw },
+       { .hw = &gxbb_fclk_div5.hw },
+       { .hw = &gxbb_fclk_div7.hw },
+       { .hw = &gxbb_gp0_pll.hw },
 };
 
 static struct clk_regmap gxbb_gen_clk_sel = {
@@ -2305,8 +2549,8 @@ static struct clk_regmap gxbb_gen_clk_sel = {
                 * vid_pll, vid2_pll (hevc), mpll0, mpll1, mpll2, fdiv4,
                 * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll
                 */
-               .parent_names = gen_clk_parent_names,
-               .num_parents = ARRAY_SIZE(gen_clk_parent_names),
+               .parent_data = gen_clk_parent_data,
+               .num_parents = ARRAY_SIZE(gen_clk_parent_data),
        },
 };
 
@@ -2319,7 +2563,9 @@ static struct clk_regmap gxbb_gen_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "gen_clk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "gen_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_gen_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2333,12 +2579,17 @@ static struct clk_regmap gxbb_gen_clk = {
        .hw.init = &(struct clk_init_data){
                .name = "gen_clk",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "gen_clk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_gen_clk_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
+#define MESON_GATE(_name, _reg, _bit) \
+       MESON_PCLK(_name, _reg, _bit, &gxbb_clk81.hw)
+
 /* Everything Else (EE) domain gates */
 static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0);
 static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1);
index b67951909e04955730cddb6d0f252a95980f867d..bf8bea675d2437611a8d4b569a739f641bb38f2e 100644 (file)
@@ -17,8 +17,6 @@
 #include <linux/slab.h>
 #include "meson-aoclk.h"
 
-#include "clk-input.h"
-
 static int meson_aoclk_do_reset(struct reset_controller_dev *rcdev,
                               unsigned long id)
 {
@@ -33,37 +31,6 @@ static const struct reset_control_ops meson_aoclk_reset_ops = {
        .reset = meson_aoclk_do_reset,
 };
 
-static int meson_aoclkc_register_inputs(struct device *dev,
-                                       struct meson_aoclk_data *data)
-{
-       struct clk_hw *hw;
-       char *str;
-       int i;
-
-       for (i = 0; i < data->num_inputs; i++) {
-               const struct meson_aoclk_input *in = &data->inputs[i];
-
-               str = kasprintf(GFP_KERNEL, "%s%s", data->input_prefix,
-                               in->name);
-               if (!str)
-                       return -ENOMEM;
-
-               hw = meson_clk_hw_register_input(dev, in->name, str, 0);
-               kfree(str);
-
-               if (IS_ERR(hw)) {
-                       if (!in->required && PTR_ERR(hw) == -ENOENT)
-                               continue;
-                       else if (PTR_ERR(hw) != -EPROBE_DEFER)
-                               dev_err(dev, "failed to register input %s\n",
-                                       in->name);
-                       return PTR_ERR(hw);
-               }
-       }
-
-       return 0;
-}
-
 int meson_aoclkc_probe(struct platform_device *pdev)
 {
        struct meson_aoclk_reset_controller *rstc;
@@ -86,10 +53,6 @@ int meson_aoclkc_probe(struct platform_device *pdev)
                return PTR_ERR(regmap);
        }
 
-       ret = meson_aoclkc_register_inputs(dev, data);
-       if (ret)
-               return ret;
-
        /* Reset Controller */
        rstc->data = data;
        rstc->regmap = regmap;
index 999cde3868f7f38982c2a7bebe12b8ee352551ec..605b43855a6998dd07e6fdd5735ebf4fb070d9c0 100644 (file)
 
 #include "clk-regmap.h"
 
-struct meson_aoclk_input {
-       const char *name;
-       bool required;
-};
-
 struct meson_aoclk_data {
        const unsigned int                      reset_reg;
        const int                               num_reset;
        const unsigned int                      *reset;
        const int                               num_clks;
        struct clk_regmap                       **clks;
-       const int                               num_inputs;
-       const struct meson_aoclk_input          *inputs;
-       const char                              *input_prefix;
        const struct clk_hw_onecell_data        *hw_data;
 };
 
index 6ba2094be257772d3328ab0ffdfd4dfcbb2a0ea2..a7cb1e7aedc463f83df2008a47aedd39bd53cfd6 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 
-#include "clk-input.h"
 #include "clk-regmap.h"
 #include "meson-eeclk.h"
 
@@ -18,7 +17,6 @@ int meson_eeclkc_probe(struct platform_device *pdev)
 {
        const struct meson_eeclkc_data *data;
        struct device *dev = &pdev->dev;
-       struct clk_hw *input;
        struct regmap *map;
        int ret, i;
 
@@ -37,14 +35,6 @@ int meson_eeclkc_probe(struct platform_device *pdev)
        if (data->init_count)
                regmap_multi_reg_write(map, data->init_regs, data->init_count);
 
-       input = meson_clk_hw_register_input(dev, "xtal", IN_PREFIX "xtal", 0);
-       if (IS_ERR(input)) {
-               ret = PTR_ERR(input);
-               if (ret != -EPROBE_DEFER)
-                       dev_err(dev, "failed to get input clock");
-               return ret;
-       }
-
        /* Populate regmap for the regmap backed clocks */
        for (i = 0; i < data->regmap_clk_num; i++)
                data->regmap_clks[i]->map = map;
index 9ab5d6fa7ccb26adf3084bad886e9e7f4670f83b..77316207bde19c623f613678cc024425b878e144 100644 (file)
@@ -10,8 +10,6 @@
 #include <linux/clk-provider.h>
 #include "clk-regmap.h"
 
-#define IN_PREFIX "ee-in-"
-
 struct platform_device;
 
 struct meson_eeclkc_data {
index 537219fa573ea330f4323991c290d50a2459c7f2..67e6691e080c111ce8784818aa1aac9a4284ea2b 100644 (file)
@@ -97,7 +97,9 @@ static struct clk_regmap meson8b_fixed_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ "xtal" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_xtal.hw
+               },
                .num_parents = 1,
        },
 };
@@ -112,7 +114,9 @@ static struct clk_regmap meson8b_fixed_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fixed_pll_dco.hw
+               },
                .num_parents = 1,
                /*
                 * This clock won't ever change at runtime so
@@ -158,7 +162,9 @@ static struct clk_regmap meson8b_hdmi_pll_dco = {
                /* sometimes also called "HPLL" or "HPLL PLL" */
                .name = "hdmi_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ "xtal" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_xtal.hw
+               },
                .num_parents = 1,
        },
 };
@@ -173,7 +179,9 @@ static struct clk_regmap meson8b_hdmi_pll_lvds_out = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_lvds_out",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_hdmi_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -189,7 +197,9 @@ static struct clk_regmap meson8b_hdmi_pll_hdmi_out = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_hdmi_out",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_hdmi_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -227,7 +237,9 @@ static struct clk_regmap meson8b_sys_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ "xtal" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_xtal.hw
+               },
                .num_parents = 1,
        },
 };
@@ -242,7 +254,9 @@ static struct clk_regmap meson8b_sys_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sys_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_sys_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -254,7 +268,9 @@ static struct clk_fixed_factor meson8b_fclk_div2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div2_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -267,7 +283,9 @@ static struct clk_regmap meson8b_fclk_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div2_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fclk_div2_div.hw
+               },
                .num_parents = 1,
                /*
                 * FIXME: Ethernet with a RGMII PHYs is not working if
@@ -285,7 +303,9 @@ static struct clk_fixed_factor meson8b_fclk_div3_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div3_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -298,7 +318,9 @@ static struct clk_regmap meson8b_fclk_div3 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div3",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div3_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fclk_div3_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -309,7 +331,9 @@ static struct clk_fixed_factor meson8b_fclk_div4_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div4_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -322,7 +346,9 @@ static struct clk_regmap meson8b_fclk_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div4",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div4_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fclk_div4_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -333,7 +359,9 @@ static struct clk_fixed_factor meson8b_fclk_div5_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div5_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -346,7 +374,9 @@ static struct clk_regmap meson8b_fclk_div5 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div5",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div5_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fclk_div5_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -357,7 +387,9 @@ static struct clk_fixed_factor meson8b_fclk_div7_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div7_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -370,7 +402,9 @@ static struct clk_regmap meson8b_fclk_div7 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div7",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div7_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fclk_div7_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -384,7 +418,9 @@ static struct clk_regmap meson8b_mpll_prediv = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll_prediv",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -416,7 +452,9 @@ static struct clk_regmap meson8b_mpll0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -429,7 +467,9 @@ static struct clk_regmap meson8b_mpll0 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mpll0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -457,7 +497,9 @@ static struct clk_regmap meson8b_mpll1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll1_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -470,7 +512,9 @@ static struct clk_regmap meson8b_mpll1 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mpll1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -498,7 +542,9 @@ static struct clk_regmap meson8b_mpll2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll2_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -511,7 +557,9 @@ static struct clk_regmap meson8b_mpll2 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll2_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mpll2_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -533,8 +581,11 @@ static struct clk_regmap meson8b_mpeg_clk_sel = {
                 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
                 * fclk_div4, fclk_div3, fclk_div5
                 */
-               .parent_names = (const char *[]){ "fclk_div3", "fclk_div4",
-                       "fclk_div5" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fclk_div3.hw,
+                       &meson8b_fclk_div4.hw,
+                       &meson8b_fclk_div5.hw,
+               },
                .num_parents = 3,
        },
 };
@@ -548,7 +599,9 @@ static struct clk_regmap meson8b_mpeg_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpeg_clk_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mpeg_clk_sel.hw
+               },
                .num_parents = 1,
        },
 };
@@ -561,7 +614,9 @@ static struct clk_regmap meson8b_clk81 = {
        .hw.init = &(struct clk_init_data){
                .name = "clk81",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mpeg_clk_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_IS_CRITICAL,
        },
@@ -576,7 +631,10 @@ static struct clk_regmap meson8b_cpu_in_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_in_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "xtal", "sys_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_xtal.hw,
+                       &meson8b_sys_pll.hw,
+               },
                .num_parents = 2,
                .flags = (CLK_SET_RATE_PARENT |
                          CLK_SET_RATE_NO_REPARENT),
@@ -589,7 +647,9 @@ static struct clk_fixed_factor meson8b_cpu_in_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_in_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_in_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_in_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -601,7 +661,9 @@ static struct clk_fixed_factor meson8b_cpu_in_div3 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_in_div3",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_in_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_in_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -630,7 +692,9 @@ static struct clk_regmap meson8b_cpu_scale_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_scale_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "cpu_in_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_in_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -649,13 +713,15 @@ static struct clk_regmap meson8b_cpu_scale_out_sel = {
                .ops = &clk_regmap_mux_ops,
                /*
                 * NOTE: We are skipping the parent with value 0x2 (which is
-                * "cpu_in_div3") because it results in a duty cycle of 33%
-                * which makes the system unstable and can result in a lockup
-                * of the whole system.
+                * meson8b_cpu_in_div3) because it results in a duty cycle of
+                * 33% which makes the system unstable and can result in a
+                * lockup of the whole system.
                 */
-               .parent_names = (const char *[]) { "cpu_in_sel",
-                                                  "cpu_in_div2",
-                                                  "cpu_scale_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_in_sel.hw,
+                       &meson8b_cpu_in_div2.hw,
+                       &meson8b_cpu_scale_div.hw,
+               },
                .num_parents = 3,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -670,8 +736,10 @@ static struct clk_regmap meson8b_cpu_clk = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "xtal",
-                                                 "cpu_scale_out_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_xtal.hw,
+                       &meson8b_cpu_scale_out_sel.hw,
+               },
                .num_parents = 2,
                .flags = (CLK_SET_RATE_PARENT |
                          CLK_SET_RATE_NO_REPARENT |
@@ -690,8 +758,13 @@ static struct clk_regmap meson8b_nand_clk_sel = {
                .name = "nand_clk_sel",
                .ops = &clk_regmap_mux_ops,
                /* FIXME all other parents are unknown: */
-               .parent_names = (const char *[]){ "fclk_div4", "fclk_div3",
-                       "fclk_div5", "fclk_div7", "xtal" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fclk_div4.hw,
+                       &meson8b_fclk_div3.hw,
+                       &meson8b_fclk_div5.hw,
+                       &meson8b_fclk_div7.hw,
+                       &meson8b_xtal.hw,
+               },
                .num_parents = 5,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -707,7 +780,9 @@ static struct clk_regmap meson8b_nand_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "nand_clk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "nand_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_nand_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -721,7 +796,9 @@ static struct clk_regmap meson8b_nand_clk_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "nand_clk_gate",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "nand_clk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_nand_clk_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -733,7 +810,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -744,7 +823,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div3 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_div3",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -755,7 +836,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_div4",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -766,7 +849,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div5 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_div5",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -777,7 +862,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div6 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_div6",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -788,7 +875,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div7 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_div7",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -799,7 +888,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div8 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_div8",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -815,13 +906,15 @@ static struct clk_regmap meson8b_apb_clk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "apb_clk_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "cpu_clk_div2",
-                                                 "cpu_clk_div3",
-                                                 "cpu_clk_div4",
-                                                 "cpu_clk_div5",
-                                                 "cpu_clk_div6",
-                                                 "cpu_clk_div7",
-                                                 "cpu_clk_div8", },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk_div2.hw,
+                       &meson8b_cpu_clk_div3.hw,
+                       &meson8b_cpu_clk_div4.hw,
+                       &meson8b_cpu_clk_div5.hw,
+                       &meson8b_cpu_clk_div6.hw,
+                       &meson8b_cpu_clk_div7.hw,
+                       &meson8b_cpu_clk_div8.hw,
+               },
                .num_parents = 7,
        },
 };
@@ -835,7 +928,9 @@ static struct clk_regmap meson8b_apb_clk_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "apb_clk_dis",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "apb_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_apb_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -850,13 +945,15 @@ static struct clk_regmap meson8b_periph_clk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "periph_clk_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "cpu_clk_div2",
-                                                 "cpu_clk_div3",
-                                                 "cpu_clk_div4",
-                                                 "cpu_clk_div5",
-                                                 "cpu_clk_div6",
-                                                 "cpu_clk_div7",
-                                                 "cpu_clk_div8", },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk_div2.hw,
+                       &meson8b_cpu_clk_div3.hw,
+                       &meson8b_cpu_clk_div4.hw,
+                       &meson8b_cpu_clk_div5.hw,
+                       &meson8b_cpu_clk_div6.hw,
+                       &meson8b_cpu_clk_div7.hw,
+                       &meson8b_cpu_clk_div8.hw,
+               },
                .num_parents = 7,
        },
 };
@@ -870,7 +967,9 @@ static struct clk_regmap meson8b_periph_clk_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "periph_clk_dis",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "periph_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_periph_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -887,13 +986,15 @@ static struct clk_regmap meson8b_axi_clk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "axi_clk_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "cpu_clk_div2",
-                                                 "cpu_clk_div3",
-                                                 "cpu_clk_div4",
-                                                 "cpu_clk_div5",
-                                                 "cpu_clk_div6",
-                                                 "cpu_clk_div7",
-                                                 "cpu_clk_div8", },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk_div2.hw,
+                       &meson8b_cpu_clk_div3.hw,
+                       &meson8b_cpu_clk_div4.hw,
+                       &meson8b_cpu_clk_div5.hw,
+                       &meson8b_cpu_clk_div6.hw,
+                       &meson8b_cpu_clk_div7.hw,
+                       &meson8b_cpu_clk_div8.hw,
+               },
                .num_parents = 7,
        },
 };
@@ -907,7 +1008,9 @@ static struct clk_regmap meson8b_axi_clk_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "axi_clk_dis",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "axi_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_axi_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -922,13 +1025,15 @@ static struct clk_regmap meson8b_l2_dram_clk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "l2_dram_clk_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "cpu_clk_div2",
-                                                 "cpu_clk_div3",
-                                                 "cpu_clk_div4",
-                                                 "cpu_clk_div5",
-                                                 "cpu_clk_div6",
-                                                 "cpu_clk_div7",
-                                                 "cpu_clk_div8", },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk_div2.hw,
+                       &meson8b_cpu_clk_div3.hw,
+                       &meson8b_cpu_clk_div4.hw,
+                       &meson8b_cpu_clk_div5.hw,
+                       &meson8b_cpu_clk_div6.hw,
+                       &meson8b_cpu_clk_div7.hw,
+                       &meson8b_cpu_clk_div8.hw,
+               },
                .num_parents = 7,
        },
 };
@@ -942,7 +1047,9 @@ static struct clk_regmap meson8b_l2_dram_clk_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "l2_dram_clk_dis",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "l2_dram_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_l2_dram_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -963,7 +1070,9 @@ static struct clk_regmap meson8b_vid_pll_in_sel = {
                 * Meson8b: hdmi_pll_dco
                 * Meson8m2: vid2_pll
                 */
-               .parent_names = (const char *[]){ "hdmi_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_hdmi_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -977,7 +1086,9 @@ static struct clk_regmap meson8b_vid_pll_in_en = {
        .hw.init = &(struct clk_init_data){
                .name = "vid_pll_in_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vid_pll_in_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vid_pll_in_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -992,7 +1103,9 @@ static struct clk_regmap meson8b_vid_pll_pre_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vid_pll_pre_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "vid_pll_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vid_pll_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1007,7 +1120,9 @@ static struct clk_regmap meson8b_vid_pll_post_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vid_pll_post_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "vid_pll_pre_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vid_pll_pre_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1023,8 +1138,10 @@ static struct clk_regmap meson8b_vid_pll = {
                .name = "vid_pll",
                .ops = &clk_regmap_mux_ro_ops,
                /* TODO: parent 0x2 is vid_pll_pre_div_mult7_div2 */
-               .parent_names = (const char *[]){ "vid_pll_pre_div",
-                                                 "vid_pll_post_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vid_pll_pre_div.hw,
+                       &meson8b_vid_pll_post_div.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1039,15 +1156,22 @@ static struct clk_regmap meson8b_vid_pll_final_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vid_pll_final_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "vid_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vid_pll.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
-static const char * const meson8b_vclk_mux_parents[] = {
-       "vid_pll_final_div", "fclk_div4", "fclk_div3", "fclk_div5",
-       "vid_pll_final_div", "fclk_div7", "mpll1"
+static const struct clk_hw *meson8b_vclk_mux_parent_hws[] = {
+       &meson8b_vid_pll_final_div.hw,
+       &meson8b_fclk_div4.hw,
+       &meson8b_fclk_div3.hw,
+       &meson8b_fclk_div5.hw,
+       &meson8b_vid_pll_final_div.hw,
+       &meson8b_fclk_div7.hw,
+       &meson8b_mpll1.hw,
 };
 
 static struct clk_regmap meson8b_vclk_in_sel = {
@@ -1059,8 +1183,8 @@ static struct clk_regmap meson8b_vclk_in_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_in_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = meson8b_vclk_mux_parents,
-               .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parents),
+               .parent_hws = meson8b_vclk_mux_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1073,7 +1197,9 @@ static struct clk_regmap meson8b_vclk_in_en = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_in_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk_in_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_in_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1087,7 +1213,9 @@ static struct clk_regmap meson8b_vclk_div1_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div1_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1099,7 +1227,9 @@ static struct clk_fixed_factor meson8b_vclk_div2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        }
@@ -1113,7 +1243,9 @@ static struct clk_regmap meson8b_vclk_div2_div_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div2_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk_div2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_div2_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1125,7 +1257,9 @@ static struct clk_fixed_factor meson8b_vclk_div4_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div4",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        }
@@ -1139,7 +1273,9 @@ static struct clk_regmap meson8b_vclk_div4_div_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div4_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk_div4" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_div4_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1151,7 +1287,9 @@ static struct clk_fixed_factor meson8b_vclk_div6_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div6",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        }
@@ -1165,7 +1303,9 @@ static struct clk_regmap meson8b_vclk_div6_div_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div6_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk_div6" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_div6_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1177,7 +1317,9 @@ static struct clk_fixed_factor meson8b_vclk_div12_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div12",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        }
@@ -1191,7 +1333,9 @@ static struct clk_regmap meson8b_vclk_div12_div_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div12_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk_div12" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_div12_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1206,8 +1350,8 @@ static struct clk_regmap meson8b_vclk2_in_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_in_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = meson8b_vclk_mux_parents,
-               .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parents),
+               .parent_hws = meson8b_vclk_mux_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1220,7 +1364,9 @@ static struct clk_regmap meson8b_vclk2_clk_in_en = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_in_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk2_in_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_in_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1234,7 +1380,9 @@ static struct clk_regmap meson8b_vclk2_div1_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div1_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk2_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_clk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1246,7 +1394,9 @@ static struct clk_fixed_factor meson8b_vclk2_div2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_clk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        }
@@ -1260,7 +1410,9 @@ static struct clk_regmap meson8b_vclk2_div2_div_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div2_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk2_div2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_div2_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1272,7 +1424,9 @@ static struct clk_fixed_factor meson8b_vclk2_div4_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div4",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_clk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        }
@@ -1286,7 +1440,9 @@ static struct clk_regmap meson8b_vclk2_div4_div_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div4_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk2_div4" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_div4_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1298,7 +1454,9 @@ static struct clk_fixed_factor meson8b_vclk2_div6_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div6",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_clk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        }
@@ -1312,7 +1470,9 @@ static struct clk_regmap meson8b_vclk2_div6_div_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div6_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk2_div6" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_div6_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1324,7 +1484,9 @@ static struct clk_fixed_factor meson8b_vclk2_div12_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div12",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_clk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        }
@@ -1338,15 +1500,20 @@ static struct clk_regmap meson8b_vclk2_div12_div_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div12_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk2_div12" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_div12_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
-static const char * const meson8b_vclk_enc_mux_parents[] = {
-       "vclk_div1_en", "vclk_div2_en", "vclk_div4_en", "vclk_div6_en",
-       "vclk_div12_en",
+static const struct clk_hw *meson8b_vclk_enc_mux_parent_hws[] = {
+       &meson8b_vclk_div1_gate.hw,
+       &meson8b_vclk_div2_div_gate.hw,
+       &meson8b_vclk_div4_div_gate.hw,
+       &meson8b_vclk_div6_div_gate.hw,
+       &meson8b_vclk_div12_div_gate.hw,
 };
 
 static struct clk_regmap meson8b_cts_enct_sel = {
@@ -1358,8 +1525,8 @@ static struct clk_regmap meson8b_cts_enct_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_enct_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = meson8b_vclk_enc_mux_parents,
-               .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents),
+               .parent_hws = meson8b_vclk_enc_mux_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1372,7 +1539,9 @@ static struct clk_regmap meson8b_cts_enct = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_enct",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cts_enct_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_enct_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1387,8 +1556,8 @@ static struct clk_regmap meson8b_cts_encp_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_encp_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = meson8b_vclk_enc_mux_parents,
-               .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents),
+               .parent_hws = meson8b_vclk_enc_mux_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1401,7 +1570,9 @@ static struct clk_regmap meson8b_cts_encp = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_encp",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cts_encp_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_encp_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1416,8 +1587,8 @@ static struct clk_regmap meson8b_cts_enci_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_enci_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = meson8b_vclk_enc_mux_parents,
-               .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents),
+               .parent_hws = meson8b_vclk_enc_mux_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1430,7 +1601,9 @@ static struct clk_regmap meson8b_cts_enci = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_enci",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cts_enci_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_enci_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1445,8 +1618,8 @@ static struct clk_regmap meson8b_hdmi_tx_pixel_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_tx_pixel_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = meson8b_vclk_enc_mux_parents,
-               .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents),
+               .parent_hws = meson8b_vclk_enc_mux_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1459,15 +1632,20 @@ static struct clk_regmap meson8b_hdmi_tx_pixel = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_tx_pixel",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_tx_pixel_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_hdmi_tx_pixel_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
-static const char * const meson8b_vclk2_enc_mux_parents[] = {
-       "vclk2_div1_en", "vclk2_div2_en", "vclk2_div4_en", "vclk2_div6_en",
-       "vclk2_div12_en",
+static const struct clk_hw *meson8b_vclk2_enc_mux_parent_hws[] = {
+       &meson8b_vclk2_div1_gate.hw,
+       &meson8b_vclk2_div2_div_gate.hw,
+       &meson8b_vclk2_div4_div_gate.hw,
+       &meson8b_vclk2_div6_div_gate.hw,
+       &meson8b_vclk2_div12_div_gate.hw,
 };
 
 static struct clk_regmap meson8b_cts_encl_sel = {
@@ -1479,8 +1657,8 @@ static struct clk_regmap meson8b_cts_encl_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_encl_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = meson8b_vclk2_enc_mux_parents,
-               .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parents),
+               .parent_hws = meson8b_vclk2_enc_mux_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1493,7 +1671,9 @@ static struct clk_regmap meson8b_cts_encl = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_encl",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cts_encl_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_encl_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1508,8 +1688,8 @@ static struct clk_regmap meson8b_cts_vdac0_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_vdac0_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = meson8b_vclk2_enc_mux_parents,
-               .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parents),
+               .parent_hws = meson8b_vclk2_enc_mux_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1522,7 +1702,9 @@ static struct clk_regmap meson8b_cts_vdac0 = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_vdac0",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cts_vdac0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_vdac0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1539,7 +1721,9 @@ static struct clk_regmap meson8b_hdmi_sys_sel = {
                .name = "hdmi_sys_sel",
                .ops = &clk_regmap_mux_ro_ops,
                /* FIXME: all other parents are unknown */
-               .parent_names = (const char *[]){ "xtal" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_xtal.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -1554,7 +1738,9 @@ static struct clk_regmap meson8b_hdmi_sys_div = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_sys_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_sys_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_hdmi_sys_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1568,7 +1754,9 @@ static struct clk_regmap meson8b_hdmi_sys = {
        .hw.init = &(struct clk_init_data) {
                .name = "hdmi_sys",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_sys_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_hdmi_sys_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1579,9 +1767,14 @@ static struct clk_regmap meson8b_hdmi_sys = {
  * muxed by a glitch-free switch on Meson8b and Meson8m2. Meson8 only
  * has mali_0 and no glitch-free mux.
  */
-static const char * const meson8b_mali_0_1_parent_names[] = {
-       "xtal", "mpll2", "mpll1", "fclk_div7", "fclk_div4", "fclk_div3",
-       "fclk_div5"
+static const struct clk_hw *meson8b_mali_0_1_parent_hws[] = {
+       &meson8b_xtal.hw,
+       &meson8b_mpll2.hw,
+       &meson8b_mpll1.hw,
+       &meson8b_fclk_div7.hw,
+       &meson8b_fclk_div4.hw,
+       &meson8b_fclk_div3.hw,
+       &meson8b_fclk_div5.hw,
 };
 
 static u32 meson8b_mali_0_1_mux_table[] = { 0, 2, 3, 4, 5, 6, 7 };
@@ -1596,8 +1789,8 @@ static struct clk_regmap meson8b_mali_0_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_mali_0_1_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_names),
+               .parent_hws = meson8b_mali_0_1_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_hws),
                /*
                 * Don't propagate rate changes up because the only changeable
                 * parents are mpll1 and mpll2 but we need those for audio and
@@ -1617,7 +1810,9 @@ static struct clk_regmap meson8b_mali_0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "mali_0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mali_0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1631,7 +1826,9 @@ static struct clk_regmap meson8b_mali_0 = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mali_0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mali_0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1647,8 +1844,8 @@ static struct clk_regmap meson8b_mali_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_mali_0_1_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_names),
+               .parent_hws = meson8b_mali_0_1_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_hws),
                /*
                 * Don't propagate rate changes up because the only changeable
                 * parents are mpll1 and mpll2 but we need those for audio and
@@ -1668,7 +1865,9 @@ static struct clk_regmap meson8b_mali_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "mali_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mali_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1682,7 +1881,9 @@ static struct clk_regmap meson8b_mali_1 = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mali_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mali_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1697,7 +1898,10 @@ static struct clk_regmap meson8b_mali = {
        .hw.init = &(struct clk_init_data){
                .name = "mali",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "mali_0", "mali_1" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mali_0.hw,
+                       &meson8b_mali_1.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1740,7 +1944,9 @@ static struct clk_regmap meson8m2_gp_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "gp_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ "xtal" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_xtal.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1755,18 +1961,26 @@ static struct clk_regmap meson8m2_gp_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "gp_pll",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "gp_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8m2_gp_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
-static const char * const meson8b_vpu_0_1_parent_names[] = {
-       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
+static const struct clk_hw *meson8b_vpu_0_1_parent_hws[] = {
+       &meson8b_fclk_div4.hw,
+       &meson8b_fclk_div3.hw,
+       &meson8b_fclk_div5.hw,
+       &meson8b_fclk_div7.hw,
 };
 
-static const char * const mmeson8m2_vpu_0_1_parent_names[] = {
-       "fclk_div4", "fclk_div3", "fclk_div5", "gp_pll"
+static const struct clk_hw *mmeson8m2_vpu_0_1_parent_hws[] = {
+       &meson8b_fclk_div4.hw,
+       &meson8b_fclk_div3.hw,
+       &meson8b_fclk_div5.hw,
+       &meson8m2_gp_pll.hw,
 };
 
 static struct clk_regmap meson8b_vpu_0_sel = {
@@ -1778,8 +1992,8 @@ static struct clk_regmap meson8b_vpu_0_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_vpu_0_1_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_names),
+               .parent_hws = meson8b_vpu_0_1_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1793,8 +2007,8 @@ static struct clk_regmap meson8m2_vpu_0_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = mmeson8m2_vpu_0_1_parent_names,
-               .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_names),
+               .parent_hws = mmeson8m2_vpu_0_1_parent_hws,
+               .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1808,7 +2022,17 @@ static struct clk_regmap meson8b_vpu_0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vpu_0_sel" },
+               .parent_data = &(const struct clk_parent_data) {
+                       /*
+                        * Note:
+                        * meson8b and meson8m2 have different vpu_0_sels (with
+                        * different struct clk_hw). We fallback to the global
+                        * naming string mechanism so vpu_0_div picks up the
+                        * appropriate one.
+                        */
+                       .name = "vpu_0_sel",
+                       .index = -1,
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1822,7 +2046,9 @@ static struct clk_regmap meson8b_vpu_0 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vpu_0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vpu_0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vpu_0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1837,8 +2063,8 @@ static struct clk_regmap meson8b_vpu_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_vpu_0_1_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_names),
+               .parent_hws = meson8b_vpu_0_1_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1852,8 +2078,8 @@ static struct clk_regmap meson8m2_vpu_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = mmeson8m2_vpu_0_1_parent_names,
-               .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_names),
+               .parent_hws = mmeson8m2_vpu_0_1_parent_hws,
+               .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1867,7 +2093,17 @@ static struct clk_regmap meson8b_vpu_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vpu_1_sel" },
+               .parent_data = &(const struct clk_parent_data) {
+                       /*
+                        * Note:
+                        * meson8b and meson8m2 have different vpu_1_sels (with
+                        * different struct clk_hw). We fallback to the global
+                        * naming string mechanism so vpu_1_div picks up the
+                        * appropriate one.
+                        */
+                       .name = "vpu_1_sel",
+                       .index = -1,
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1881,7 +2117,9 @@ static struct clk_regmap meson8b_vpu_1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vpu_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vpu_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vpu_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1896,14 +2134,22 @@ static struct clk_regmap meson8b_vpu = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "vpu_0", "vpu_1" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vpu_0.hw,
+                       &meson8b_vpu_1.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
 
-static const char * const meson8b_vdec_parent_names[] = {
-       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "mpll2", "mpll1"
+static const struct clk_hw *meson8b_vdec_parent_hws[] = {
+       &meson8b_fclk_div4.hw,
+       &meson8b_fclk_div3.hw,
+       &meson8b_fclk_div5.hw,
+       &meson8b_fclk_div7.hw,
+       &meson8b_mpll2.hw,
+       &meson8b_mpll1.hw,
 };
 
 static struct clk_regmap meson8b_vdec_1_sel = {
@@ -1916,8 +2162,8 @@ static struct clk_regmap meson8b_vdec_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names),
+               .parent_hws = meson8b_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1932,7 +2178,9 @@ static struct clk_regmap meson8b_vdec_1_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_1_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1946,7 +2194,9 @@ static struct clk_regmap meson8b_vdec_1_1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_1_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_1_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_1_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1962,7 +2212,9 @@ static struct clk_regmap meson8b_vdec_1_2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_1_2_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1976,7 +2228,9 @@ static struct clk_regmap meson8b_vdec_1_2 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_1_2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_1_2_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_1_2_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1992,7 +2246,10 @@ static struct clk_regmap meson8b_vdec_1 = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_1",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "vdec_1_1", "vdec_1_2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_1_1.hw,
+                       &meson8b_vdec_1_2.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2008,8 +2265,8 @@ static struct clk_regmap meson8b_vdec_hcodec_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hcodec_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names),
+               .parent_hws = meson8b_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2024,7 +2281,9 @@ static struct clk_regmap meson8b_vdec_hcodec_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hcodec_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_hcodec_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_hcodec_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2038,7 +2297,9 @@ static struct clk_regmap meson8b_vdec_hcodec = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_hcodec",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_hcodec_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_hcodec_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2054,8 +2315,8 @@ static struct clk_regmap meson8b_vdec_2_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_2_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names),
+               .parent_hws = meson8b_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2070,7 +2331,9 @@ static struct clk_regmap meson8b_vdec_2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_2_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_2_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_2_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2084,7 +2347,9 @@ static struct clk_regmap meson8b_vdec_2 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_2_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_2_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2100,8 +2365,8 @@ static struct clk_regmap meson8b_vdec_hevc_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hevc_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names),
+               .parent_hws = meson8b_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2116,7 +2381,9 @@ static struct clk_regmap meson8b_vdec_hevc_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hevc_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_hevc_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_hevc_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2130,7 +2397,9 @@ static struct clk_regmap meson8b_vdec_hevc_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_hevc_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_hevc_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_hevc_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2147,15 +2416,19 @@ static struct clk_regmap meson8b_vdec_hevc = {
                .name = "vdec_hevc",
                .ops = &clk_regmap_mux_ops,
                /* TODO: The second parent is currently unknown */
-               .parent_names = (const char *[]){ "vdec_hevc_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_hevc_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
 /* TODO: the clock at index 0 is "DDR_PLL" which we don't support yet */
-static const char * const meson8b_cts_amclk_parent_names[] = {
-       "mpll0", "mpll1", "mpll2"
+static const struct clk_hw *meson8b_cts_amclk_parent_hws[] = {
+       &meson8b_mpll0.hw,
+       &meson8b_mpll1.hw,
+       &meson8b_mpll2.hw
 };
 
 static u32 meson8b_cts_amclk_mux_table[] = { 1, 2, 3 };
@@ -2171,8 +2444,8 @@ static struct clk_regmap meson8b_cts_amclk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_amclk_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_cts_amclk_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_cts_amclk_parent_names),
+               .parent_hws = meson8b_cts_amclk_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_cts_amclk_parent_hws),
        },
 };
 
@@ -2186,7 +2459,9 @@ static struct clk_regmap meson8b_cts_amclk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_amclk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "cts_amclk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_amclk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2200,15 +2475,19 @@ static struct clk_regmap meson8b_cts_amclk = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_amclk",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_amclk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_amclk_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
 /* TODO: the clock at index 0 is "DDR_PLL" which we don't support yet */
-static const char * const meson8b_cts_mclk_i958_parent_names[] = {
-       "mpll0", "mpll1", "mpll2"
+static const struct clk_hw *meson8b_cts_mclk_i958_parent_hws[] = {
+       &meson8b_mpll0.hw,
+       &meson8b_mpll1.hw,
+       &meson8b_mpll2.hw
 };
 
 static u32 meson8b_cts_mclk_i958_mux_table[] = { 1, 2, 3 };
@@ -2224,8 +2503,8 @@ static struct clk_regmap meson8b_cts_mclk_i958_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_mclk_i958_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_cts_mclk_i958_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_cts_mclk_i958_parent_names),
+               .parent_hws = meson8b_cts_mclk_i958_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_cts_mclk_i958_parent_hws),
        },
 };
 
@@ -2239,7 +2518,9 @@ static struct clk_regmap meson8b_cts_mclk_i958_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_mclk_i958_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "cts_mclk_i958_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_mclk_i958_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2253,7 +2534,9 @@ static struct clk_regmap meson8b_cts_mclk_i958 = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_mclk_i958",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_mclk_i958_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_mclk_i958_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2268,8 +2551,10 @@ static struct clk_regmap meson8b_cts_i958 = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_i958",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "cts_amclk",
-                                                 "cts_mclk_i958" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_amclk.hw,
+                       &meson8b_cts_mclk_i958.hw
+               },
                .num_parents = 2,
                /*
                 * The parent is specific to origin of the audio data. Let the
@@ -2279,6 +2564,9 @@ static struct clk_regmap meson8b_cts_i958 = {
        },
 };
 
+#define MESON_GATE(_name, _reg, _bit) \
+       MESON_PCLK(_name, _reg, _bit, &meson8b_clk81.hw)
+
 /* Everything Else (EE) domain gates */
 
 static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0);
index b09f6ded0a30d31f70b6c48395c8bbf354de9df8..415e6906a113f949089d133bf391029113dffcf8 100644 (file)
@@ -8,6 +8,9 @@ config MVEBU_CLK_CPU
 config MVEBU_CLK_COREDIV
        bool
 
+config ARMADA_AP_CP_HELPER
+       bool
+
 config ARMADA_370_CLK
        bool
        select MVEBU_CLK_COMMON
@@ -35,9 +38,14 @@ config ARMADA_XP_CLK
 
 config ARMADA_AP806_SYSCON
        bool
+       select ARMADA_AP_CP_HELPER
+
+config ARMADA_AP_CPU_CLK
+       bool
 
 config ARMADA_CP110_SYSCON
        bool
+       select ARMADA_AP_CP_HELPER
 
 config DOVE_CLK
        bool
index 93ac3685271f92d5cf9e976a48c38c85563bc49f..04464cef0f06ff40dd662f379c880e13b58c7420 100644 (file)
@@ -2,6 +2,7 @@
 obj-$(CONFIG_MVEBU_CLK_COMMON) += common.o
 obj-$(CONFIG_MVEBU_CLK_CPU)    += clk-cpu.o
 obj-$(CONFIG_MVEBU_CLK_COREDIV)        += clk-corediv.o
+obj-$(CONFIG_ARMADA_AP_CP_HELPER) += armada_ap_cp_helper.o
 
 obj-$(CONFIG_ARMADA_370_CLK)   += armada-370.o
 obj-$(CONFIG_ARMADA_375_CLK)   += armada-375.o
@@ -12,6 +13,7 @@ obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-tbg.o
 obj-$(CONFIG_ARMADA_37XX_CLK)  += armada-37xx-periph.o
 obj-$(CONFIG_ARMADA_XP_CLK)    += armada-xp.o mv98dx3236.o
 obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o
+obj-$(CONFIG_ARMADA_AP_CPU_CLK) += ap-cpu-clk.o
 obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o
 obj-$(CONFIG_DOVE_CLK)         += dove.o dove-divider.o
 obj-$(CONFIG_KIRKWOOD_CLK)     += kirkwood.o
diff --git a/drivers/clk/mvebu/ap-cpu-clk.c b/drivers/clk/mvebu/ap-cpu-clk.c
new file mode 100644 (file)
index 0000000..af5e5ac
--- /dev/null
@@ -0,0 +1,356 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Marvell Armada AP CPU Clock Controller
+ *
+ * Copyright (C) 2018 Marvell
+ *
+ * Omri Itach <omrii@marvell.com>
+ * Gregory Clement <gregory.clement@bootlin.com>
+ */
+
+#define pr_fmt(fmt) "ap-cpu-clk: " fmt
+
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include "armada_ap_cp_helper.h"
+
+#define AP806_CPU_CLUSTER0             0
+#define AP806_CPU_CLUSTER1             1
+#define AP806_CPUS_PER_CLUSTER         2
+#define APN806_CPU1_MASK               0x1
+
+#define APN806_CLUSTER_NUM_OFFSET      8
+#define APN806_CLUSTER_NUM_MASK                BIT(APN806_CLUSTER_NUM_OFFSET)
+
+#define APN806_MAX_DIVIDER             32
+
+/**
+ * struct cpu_dfs_regs: CPU DFS register mapping
+ * @divider_reg: full integer ratio from PLL frequency to CPU clock frequency
+ * @force_reg: request to force new ratio regardless of relation to other clocks
+ * @ratio_reg: central request to switch ratios
+ */
+struct cpu_dfs_regs {
+       unsigned int divider_reg;
+       unsigned int force_reg;
+       unsigned int ratio_reg;
+       unsigned int ratio_state_reg;
+       unsigned int divider_mask;
+       unsigned int cluster_offset;
+       unsigned int force_mask;
+       int divider_offset;
+       int divider_ratio;
+       int ratio_offset;
+       int ratio_state_offset;
+       int ratio_state_cluster_offset;
+};
+
+/* AP806 CPU DFS register mapping*/
+#define AP806_CA72MP2_0_PLL_CR_0_REG_OFFSET            0x278
+#define AP806_CA72MP2_0_PLL_CR_1_REG_OFFSET            0x280
+#define AP806_CA72MP2_0_PLL_CR_2_REG_OFFSET            0x284
+#define AP806_CA72MP2_0_PLL_SR_REG_OFFSET              0xC94
+
+#define AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET          0x14
+#define AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET                0
+#define AP806_PLL_CR_CPU_CLK_DIV_RATIO                 0
+#define AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_MASK \
+                       (0x3f << AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET)
+#define AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_OFFSET     24
+#define AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK \
+                       (0x1 << AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_OFFSET)
+#define AP806_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET     16
+#define AP806_CA72MP2_0_PLL_RATIO_STABLE_OFFSET        0
+#define AP806_CA72MP2_0_PLL_RATIO_STATE                        11
+
+#define STATUS_POLL_PERIOD_US          1
+#define STATUS_POLL_TIMEOUT_US         1000000
+
+#define to_ap_cpu_clk(_hw) container_of(_hw, struct ap_cpu_clk, hw)
+
+static const struct cpu_dfs_regs ap806_dfs_regs = {
+       .divider_reg = AP806_CA72MP2_0_PLL_CR_0_REG_OFFSET,
+       .force_reg = AP806_CA72MP2_0_PLL_CR_1_REG_OFFSET,
+       .ratio_reg = AP806_CA72MP2_0_PLL_CR_2_REG_OFFSET,
+       .ratio_state_reg = AP806_CA72MP2_0_PLL_SR_REG_OFFSET,
+       .divider_mask = AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_MASK,
+       .cluster_offset = AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET,
+       .force_mask = AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK,
+       .divider_offset = AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET,
+       .divider_ratio = AP806_PLL_CR_CPU_CLK_DIV_RATIO,
+       .ratio_offset = AP806_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET,
+       .ratio_state_offset = AP806_CA72MP2_0_PLL_RATIO_STABLE_OFFSET,
+       .ratio_state_cluster_offset = AP806_CA72MP2_0_PLL_RATIO_STABLE_OFFSET,
+};
+
+/* AP807 CPU DFS register mapping */
+#define AP807_DEVICE_GENERAL_CONTROL_10_REG_OFFSET             0x278
+#define AP807_DEVICE_GENERAL_CONTROL_11_REG_OFFSET             0x27c
+#define AP807_DEVICE_GENERAL_STATUS_6_REG_OFFSET               0xc98
+#define AP807_CA72MP2_0_PLL_CR_CLUSTER_OFFSET                  0x8
+#define AP807_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET                        18
+#define AP807_PLL_CR_0_CPU_CLK_DIV_RATIO_MASK \
+               (0x3f << AP807_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET)
+#define AP807_PLL_CR_1_CPU_CLK_DIV_RATIO_OFFSET                        12
+#define AP807_PLL_CR_1_CPU_CLK_DIV_RATIO_MASK \
+               (0x3f << AP807_PLL_CR_1_CPU_CLK_DIV_RATIO_OFFSET)
+#define AP807_PLL_CR_CPU_CLK_DIV_RATIO                         3
+#define AP807_PLL_CR_0_CPU_CLK_RELOAD_FORCE_OFFSET             0
+#define AP807_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK \
+               (0x3 << AP807_PLL_CR_0_CPU_CLK_RELOAD_FORCE_OFFSET)
+#define AP807_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET             6
+#define        AP807_CA72MP2_0_PLL_CLKDIV_RATIO_STABLE_OFFSET          20
+#define AP807_CA72MP2_0_PLL_CLKDIV_RATIO_STABLE_CLUSTER_OFFSET 3
+
+static const struct cpu_dfs_regs ap807_dfs_regs = {
+       .divider_reg = AP807_DEVICE_GENERAL_CONTROL_10_REG_OFFSET,
+       .force_reg = AP807_DEVICE_GENERAL_CONTROL_11_REG_OFFSET,
+       .ratio_reg = AP807_DEVICE_GENERAL_CONTROL_11_REG_OFFSET,
+       .ratio_state_reg = AP807_DEVICE_GENERAL_STATUS_6_REG_OFFSET,
+       .divider_mask = AP807_PLL_CR_0_CPU_CLK_DIV_RATIO_MASK,
+       .cluster_offset = AP807_CA72MP2_0_PLL_CR_CLUSTER_OFFSET,
+       .force_mask = AP807_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK,
+       .divider_offset = AP807_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET,
+       .divider_ratio = AP807_PLL_CR_CPU_CLK_DIV_RATIO,
+       .ratio_offset = AP807_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET,
+       .ratio_state_offset = AP807_CA72MP2_0_PLL_CLKDIV_RATIO_STABLE_OFFSET,
+       .ratio_state_cluster_offset =
+               AP807_CA72MP2_0_PLL_CLKDIV_RATIO_STABLE_CLUSTER_OFFSET
+};
+
+/*
+ * struct ap806_clk: CPU cluster clock controller instance
+ * @cluster: Cluster clock controller index
+ * @clk_name: Cluster clock controller name
+ * @dev : Cluster clock device
+ * @hw: HW specific structure of Cluster clock controller
+ * @pll_cr_base: CA72MP2 Register base (Device Sample at Reset register)
+ */
+struct ap_cpu_clk {
+       unsigned int cluster;
+       const char *clk_name;
+       struct device *dev;
+       struct clk_hw hw;
+       struct regmap *pll_cr_base;
+       const struct cpu_dfs_regs *pll_regs;
+};
+
+static unsigned long ap_cpu_clk_recalc_rate(struct clk_hw *hw,
+                                           unsigned long parent_rate)
+{
+       struct ap_cpu_clk *clk = to_ap_cpu_clk(hw);
+       unsigned int cpu_clkdiv_reg;
+       int cpu_clkdiv_ratio;
+
+       cpu_clkdiv_reg = clk->pll_regs->divider_reg +
+               (clk->cluster * clk->pll_regs->cluster_offset);
+       regmap_read(clk->pll_cr_base, cpu_clkdiv_reg, &cpu_clkdiv_ratio);
+       cpu_clkdiv_ratio &= clk->pll_regs->divider_mask;
+       cpu_clkdiv_ratio >>= clk->pll_regs->divider_offset;
+
+       return parent_rate / cpu_clkdiv_ratio;
+}
+
+static int ap_cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+                              unsigned long parent_rate)
+{
+       struct ap_cpu_clk *clk = to_ap_cpu_clk(hw);
+       int ret, reg, divider = parent_rate / rate;
+       unsigned int cpu_clkdiv_reg, cpu_force_reg, cpu_ratio_reg, stable_bit;
+
+       cpu_clkdiv_reg = clk->pll_regs->divider_reg +
+               (clk->cluster * clk->pll_regs->cluster_offset);
+       cpu_force_reg = clk->pll_regs->force_reg +
+               (clk->cluster * clk->pll_regs->cluster_offset);
+       cpu_ratio_reg = clk->pll_regs->ratio_reg +
+               (clk->cluster * clk->pll_regs->cluster_offset);
+
+       regmap_read(clk->pll_cr_base, cpu_clkdiv_reg, &reg);
+       reg &= ~(clk->pll_regs->divider_mask);
+       reg |= (divider << clk->pll_regs->divider_offset);
+
+       /*
+        * AP807 CPU divider has two channels with ratio 1:3 and divider_ratio
+        * is 1. Otherwise, in the case of the AP806, divider_ratio is 0.
+        */
+       if (clk->pll_regs->divider_ratio) {
+               reg &= ~(AP807_PLL_CR_1_CPU_CLK_DIV_RATIO_MASK);
+               reg |= ((divider * clk->pll_regs->divider_ratio) <<
+                               AP807_PLL_CR_1_CPU_CLK_DIV_RATIO_OFFSET);
+       }
+       regmap_write(clk->pll_cr_base, cpu_clkdiv_reg, reg);
+
+
+       regmap_update_bits(clk->pll_cr_base, cpu_force_reg,
+                          clk->pll_regs->force_mask,
+                          clk->pll_regs->force_mask);
+
+       regmap_update_bits(clk->pll_cr_base, cpu_ratio_reg,
+                          BIT(clk->pll_regs->ratio_offset),
+                          BIT(clk->pll_regs->ratio_offset));
+
+       stable_bit = BIT(clk->pll_regs->ratio_state_offset +
+                        clk->cluster *
+                        clk->pll_regs->ratio_state_cluster_offset),
+       ret = regmap_read_poll_timeout(clk->pll_cr_base,
+                                      clk->pll_regs->ratio_state_reg, reg,
+                                      reg & stable_bit, STATUS_POLL_PERIOD_US,
+                                      STATUS_POLL_TIMEOUT_US);
+       if (ret)
+               return ret;
+
+       regmap_update_bits(clk->pll_cr_base, cpu_ratio_reg,
+                          BIT(clk->pll_regs->ratio_offset), 0);
+
+       return 0;
+}
+
+static long ap_cpu_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+                                 unsigned long *parent_rate)
+{
+       int divider = *parent_rate / rate;
+
+       divider = min(divider, APN806_MAX_DIVIDER);
+
+       return *parent_rate / divider;
+}
+
+static const struct clk_ops ap_cpu_clk_ops = {
+       .recalc_rate    = ap_cpu_clk_recalc_rate,
+       .round_rate     = ap_cpu_clk_round_rate,
+       .set_rate       = ap_cpu_clk_set_rate,
+};
+
+static int ap_cpu_clock_probe(struct platform_device *pdev)
+{
+       int ret, nclusters = 0, cluster_index = 0;
+       struct device *dev = &pdev->dev;
+       struct device_node *dn, *np = dev->of_node;
+       struct clk_hw_onecell_data *ap_cpu_data;
+       struct ap_cpu_clk *ap_cpu_clk;
+       struct regmap *regmap;
+
+       regmap = syscon_node_to_regmap(np->parent);
+       if (IS_ERR(regmap)) {
+               pr_err("cannot get pll_cr_base regmap\n");
+               return PTR_ERR(regmap);
+       }
+
+       /*
+        * AP806 has 4 cpus and DFS for AP806 is controlled per
+        * cluster (2 CPUs per cluster), cpu0 and cpu1 are fixed to
+        * cluster0 while cpu2 and cpu3 are fixed to cluster1 whether
+        * they are enabled or not.  Since cpu0 is the boot cpu, then
+        * cluster0 must exist.  If cpu2 or cpu3 is enabled, cluster1
+        * will exist and the cluster number is 2; otherwise the
+        * cluster number is 1.
+        */
+       nclusters = 1;
+       for_each_of_cpu_node(dn) {
+               int cpu, err;
+
+               err = of_property_read_u32(dn, "reg", &cpu);
+               if (WARN_ON(err))
+                       return err;
+
+               /* If cpu2 or cpu3 is enabled */
+               if (cpu & APN806_CLUSTER_NUM_MASK) {
+                       nclusters = 2;
+                       break;
+               }
+       }
+       /*
+        * DFS for AP806 is controlled per cluster (2 CPUs per cluster),
+        * so allocate structs per cluster
+        */
+       ap_cpu_clk = devm_kcalloc(dev, nclusters, sizeof(*ap_cpu_clk),
+                                 GFP_KERNEL);
+       if (!ap_cpu_clk)
+               return -ENOMEM;
+
+       ap_cpu_data = devm_kzalloc(dev, sizeof(*ap_cpu_data) +
+                               sizeof(struct clk_hw *) * nclusters,
+                               GFP_KERNEL);
+       if (!ap_cpu_data)
+               return -ENOMEM;
+
+       for_each_of_cpu_node(dn) {
+               char *clk_name = "cpu-cluster-0";
+               struct clk_init_data init;
+               const char *parent_name;
+               struct clk *parent;
+               int cpu, err;
+
+               err = of_property_read_u32(dn, "reg", &cpu);
+               if (WARN_ON(err))
+                       return err;
+
+               cluster_index = cpu & APN806_CLUSTER_NUM_MASK;
+               cluster_index >>= APN806_CLUSTER_NUM_OFFSET;
+
+               /* Initialize once for one cluster */
+               if (ap_cpu_data->hws[cluster_index])
+                       continue;
+
+               parent = of_clk_get(np, cluster_index);
+               if (IS_ERR(parent)) {
+                       dev_err(dev, "Could not get the clock parent\n");
+                       return -EINVAL;
+               }
+               parent_name =  __clk_get_name(parent);
+               clk_name[12] += cluster_index;
+               ap_cpu_clk[cluster_index].clk_name =
+                       ap_cp_unique_name(dev, np->parent, clk_name);
+               ap_cpu_clk[cluster_index].cluster = cluster_index;
+               ap_cpu_clk[cluster_index].pll_cr_base = regmap;
+               ap_cpu_clk[cluster_index].hw.init = &init;
+               ap_cpu_clk[cluster_index].dev = dev;
+               ap_cpu_clk[cluster_index].pll_regs = of_device_get_match_data(&pdev->dev);
+
+               init.name = ap_cpu_clk[cluster_index].clk_name;
+               init.ops = &ap_cpu_clk_ops;
+               init.num_parents = 1;
+               init.parent_names = &parent_name;
+
+               ret = devm_clk_hw_register(dev, &ap_cpu_clk[cluster_index].hw);
+               if (ret)
+                       return ret;
+               ap_cpu_data->hws[cluster_index] = &ap_cpu_clk[cluster_index].hw;
+       }
+
+       ap_cpu_data->num = cluster_index + 1;
+
+       ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, ap_cpu_data);
+       if (ret)
+               dev_err(dev, "failed to register OF clock provider\n");
+
+       return ret;
+}
+
+static const struct of_device_id ap_cpu_clock_of_match[] = {
+       {
+               .compatible = "marvell,ap806-cpu-clock",
+               .data = &ap806_dfs_regs,
+       },
+       {
+               .compatible = "marvell,ap807-cpu-clock",
+               .data = &ap807_dfs_regs,
+       },
+       { }
+};
+
+static struct platform_driver ap_cpu_clock_driver = {
+       .probe = ap_cpu_clock_probe,
+       .driver         = {
+               .name   = "marvell-ap-cpu-clock",
+               .of_match_table = ap_cpu_clock_of_match,
+               .suppress_bind_attrs = true,
+       },
+};
+builtin_platform_driver(ap_cpu_clock_driver);
index ea54a874bbdadd0a58843a637ef0885a1f65a02d..948bd1e71aea6bd34d9eb9621ccf50d6c728f0c8 100644 (file)
 
 #define pr_fmt(fmt) "ap806-system-controller: " fmt
 
+#include "armada_ap_cp_helper.h"
 #include <linux/clk-provider.h>
 #include <linux/mfd/syscon.h>
 #include <linux/init.h>
 #include <linux/of.h>
-#include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
 #define AP806_SAR_REG                  0x400
 #define AP806_SAR_CLKFREQ_MODE_MASK    0x1f
 
-#define AP806_CLK_NUM                  5
+#define AP806_CLK_NUM                  6
 
 static struct clk *ap806_clks[AP806_CLK_NUM];
 
@@ -30,86 +30,149 @@ static struct clk_onecell_data ap806_clk_data = {
        .clk_num = AP806_CLK_NUM,
 };
 
-static char *ap806_unique_name(struct device *dev, struct device_node *np,
-                              char *name)
+static int ap806_get_sar_clocks(unsigned int freq_mode,
+                               unsigned int *cpuclk_freq,
+                               unsigned int *dclk_freq)
 {
-       const __be32 *reg;
-       u64 addr;
-
-       reg = of_get_property(np, "reg", NULL);
-       addr = of_translate_address(np, reg);
-       return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s",
-                       (unsigned long long)addr, name);
-}
-
-static int ap806_syscon_common_probe(struct platform_device *pdev,
-                                    struct device_node *syscon_node)
-{
-       unsigned int freq_mode, cpuclk_freq;
-       const char *name, *fixedclk_name;
-       struct device *dev = &pdev->dev;
-       struct device_node *np = dev->of_node;
-       struct regmap *regmap;
-       u32 reg;
-       int ret;
-
-       regmap = syscon_node_to_regmap(syscon_node);
-       if (IS_ERR(regmap)) {
-               dev_err(dev, "cannot get regmap\n");
-               return PTR_ERR(regmap);
-       }
-
-       ret = regmap_read(regmap, AP806_SAR_REG, &reg);
-       if (ret) {
-               dev_err(dev, "cannot read from regmap\n");
-               return ret;
-       }
-
-       freq_mode = reg & AP806_SAR_CLKFREQ_MODE_MASK;
        switch (freq_mode) {
        case 0x0:
+               *cpuclk_freq = 2000;
+               *dclk_freq = 600;
+               break;
        case 0x1:
-               cpuclk_freq = 2000;
+               *cpuclk_freq = 2000;
+               *dclk_freq = 525;
                break;
        case 0x6:
+               *cpuclk_freq = 1800;
+               *dclk_freq = 600;
+               break;
        case 0x7:
-               cpuclk_freq = 1800;
+               *cpuclk_freq = 1800;
+               *dclk_freq = 525;
                break;
        case 0x4:
+               *cpuclk_freq = 1600;
+               *dclk_freq = 400;
+               break;
        case 0xB:
+               *cpuclk_freq = 1600;
+               *dclk_freq = 450;
+               break;
        case 0xD:
-               cpuclk_freq = 1600;
+               *cpuclk_freq = 1600;
+               *dclk_freq = 525;
                break;
        case 0x1a:
-               cpuclk_freq = 1400;
+               *cpuclk_freq = 1400;
+               *dclk_freq = 400;
                break;
        case 0x14:
+               *cpuclk_freq = 1300;
+               *dclk_freq = 400;
+               break;
        case 0x17:
-               cpuclk_freq = 1300;
+               *cpuclk_freq = 1300;
+               *dclk_freq = 325;
                break;
        case 0x19:
-               cpuclk_freq = 1200;
+               *cpuclk_freq = 1200;
+               *dclk_freq = 400;
                break;
        case 0x13:
+               *cpuclk_freq = 1000;
+               *dclk_freq = 325;
+               break;
        case 0x1d:
-               cpuclk_freq = 1000;
+               *cpuclk_freq = 1000;
+               *dclk_freq = 400;
                break;
        case 0x1c:
-               cpuclk_freq = 800;
+               *cpuclk_freq = 800;
+               *dclk_freq = 400;
                break;
        case 0x1b:
-               cpuclk_freq = 600;
+               *cpuclk_freq = 600;
+               *dclk_freq = 400;
                break;
        default:
-               dev_err(dev, "invalid SAR value\n");
                return -EINVAL;
        }
 
+       return 0;
+}
+
+static int ap807_get_sar_clocks(unsigned int freq_mode,
+                               unsigned int *cpuclk_freq,
+                               unsigned int *dclk_freq)
+{
+       switch (freq_mode) {
+       case 0x0:
+               *cpuclk_freq = 2000;
+               *dclk_freq = 1200;
+               break;
+       case 0x6:
+               *cpuclk_freq = 2200;
+               *dclk_freq = 1200;
+               break;
+       case 0xD:
+               *cpuclk_freq = 1600;
+               *dclk_freq = 1200;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int ap806_syscon_common_probe(struct platform_device *pdev,
+                                    struct device_node *syscon_node)
+{
+       unsigned int freq_mode, cpuclk_freq, dclk_freq;
+       const char *name, *fixedclk_name;
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       struct regmap *regmap;
+       u32 reg;
+       int ret;
+
+       regmap = syscon_node_to_regmap(syscon_node);
+       if (IS_ERR(regmap)) {
+               dev_err(dev, "cannot get regmap\n");
+               return PTR_ERR(regmap);
+       }
+
+       ret = regmap_read(regmap, AP806_SAR_REG, &reg);
+       if (ret) {
+               dev_err(dev, "cannot read from regmap\n");
+               return ret;
+       }
+
+       freq_mode = reg & AP806_SAR_CLKFREQ_MODE_MASK;
+
+       if (of_device_is_compatible(pdev->dev.of_node,
+                                   "marvell,ap806-clock")) {
+               ret = ap806_get_sar_clocks(freq_mode, &cpuclk_freq, &dclk_freq);
+       } else if (of_device_is_compatible(pdev->dev.of_node,
+                                          "marvell,ap807-clock")) {
+               ret = ap807_get_sar_clocks(freq_mode, &cpuclk_freq, &dclk_freq);
+       } else {
+               dev_err(dev, "compatible not supported\n");
+               return -EINVAL;
+       }
+
+       if (ret) {
+               dev_err(dev, "invalid Sample at Reset value\n");
+               return ret;
+       }
+
        /* Convert to hertz */
        cpuclk_freq *= 1000 * 1000;
+       dclk_freq *= 1000 * 1000;
 
        /* CPU clocks depend on the Sample At Reset configuration */
-       name = ap806_unique_name(dev, syscon_node, "cpu-cluster-0");
+       name = ap_cp_unique_name(dev, syscon_node, "pll-cluster-0");
        ap806_clks[0] = clk_register_fixed_rate(dev, name, NULL,
                                                0, cpuclk_freq);
        if (IS_ERR(ap806_clks[0])) {
@@ -117,7 +180,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
                goto fail0;
        }
 
-       name = ap806_unique_name(dev, syscon_node, "cpu-cluster-1");
+       name = ap_cp_unique_name(dev, syscon_node, "pll-cluster-1");
        ap806_clks[1] = clk_register_fixed_rate(dev, name, NULL, 0,
                                                cpuclk_freq);
        if (IS_ERR(ap806_clks[1])) {
@@ -126,7 +189,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
        }
 
        /* Fixed clock is always 1200 Mhz */
-       fixedclk_name = ap806_unique_name(dev, syscon_node, "fixed");
+       fixedclk_name = ap_cp_unique_name(dev, syscon_node, "fixed");
        ap806_clks[2] = clk_register_fixed_rate(dev, fixedclk_name, NULL,
                                                0, 1200 * 1000 * 1000);
        if (IS_ERR(ap806_clks[2])) {
@@ -135,7 +198,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
        }
 
        /* MSS Clock is fixed clock divided by 6 */
-       name = ap806_unique_name(dev, syscon_node, "mss");
+       name = ap_cp_unique_name(dev, syscon_node, "mss");
        ap806_clks[3] = clk_register_fixed_factor(NULL, name, fixedclk_name,
                                                  0, 1, 6);
        if (IS_ERR(ap806_clks[3])) {
@@ -144,7 +207,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
        }
 
        /* SDIO(/eMMC) Clock is fixed clock divided by 3 */
-       name = ap806_unique_name(dev, syscon_node, "sdio");
+       name = ap_cp_unique_name(dev, syscon_node, "sdio");
        ap806_clks[4] = clk_register_fixed_factor(NULL, name,
                                                  fixedclk_name,
                                                  0, 1, 3);
@@ -153,6 +216,14 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
                goto fail4;
        }
 
+       /* AP-DCLK(HCLK) Clock is DDR clock divided by 2 */
+       name = ap_cp_unique_name(dev, syscon_node, "ap-dclk");
+       ap806_clks[5] = clk_register_fixed_rate(dev, name, NULL, 0, dclk_freq);
+       if (IS_ERR(ap806_clks[5])) {
+               ret = PTR_ERR(ap806_clks[5]);
+               goto fail5;
+       }
+
        ret = of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data);
        if (ret)
                goto fail_clk_add;
@@ -160,6 +231,8 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
        return 0;
 
 fail_clk_add:
+       clk_unregister_fixed_factor(ap806_clks[5]);
+fail5:
        clk_unregister_fixed_factor(ap806_clks[4]);
 fail4:
        clk_unregister_fixed_factor(ap806_clks[3]);
@@ -206,6 +279,7 @@ builtin_platform_driver(ap806_syscon_legacy_driver);
 
 static const struct of_device_id ap806_clock_of_match[] = {
        { .compatible = "marvell,ap806-clock", },
+       { .compatible = "marvell,ap807-clock", },
        { }
 };
 
diff --git a/drivers/clk/mvebu/armada_ap_cp_helper.c b/drivers/clk/mvebu/armada_ap_cp_helper.c
new file mode 100644 (file)
index 0000000..6a930f6
--- /dev/null
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Marvell Armada AP and CP110 helper
+ *
+ * Copyright (C) 2018 Marvell
+ *
+ * Gregory Clement <gregory.clement@bootlin.com>
+ *
+ */
+
+#include "armada_ap_cp_helper.h"
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+char *ap_cp_unique_name(struct device *dev, struct device_node *np,
+                       const char *name)
+{
+       const __be32 *reg;
+       u64 addr;
+
+       /* Do not create a name if there is no clock */
+       if (!name)
+               return NULL;
+
+       reg = of_get_property(np, "reg", NULL);
+       addr = of_translate_address(np, reg);
+       return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s",
+                             (unsigned long long)addr, name);
+}
diff --git a/drivers/clk/mvebu/armada_ap_cp_helper.h b/drivers/clk/mvebu/armada_ap_cp_helper.h
new file mode 100644 (file)
index 0000000..810af1e
--- /dev/null
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __ARMADA_AP_CP_HELPER_H
+#define __ARMADA_AP_CP_HELPER_H
+
+struct device;
+struct device_node;
+
+char *ap_cp_unique_name(struct device *dev, struct device_node *np,
+                       const char *name);
+#endif
index b6de283f45e3739744b293785062cb4670a2f479..808463276145b009305d3390e0ce1a366a922fb5 100644 (file)
 
 #define pr_fmt(fmt) "cp110-system-controller: " fmt
 
+#include "armada_ap_cp_helper.h"
 #include <linux/clk-provider.h>
 #include <linux/mfd/syscon.h>
 #include <linux/init.h>
 #include <linux/of.h>
-#include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
@@ -212,22 +212,6 @@ static struct clk_hw *cp110_of_clk_get(struct of_phandle_args *clkspec,
        return ERR_PTR(-EINVAL);
 }
 
-static char *cp110_unique_name(struct device *dev, struct device_node *np,
-                              const char *name)
-{
-       const __be32 *reg;
-       u64 addr;
-
-       /* Do not create a name if there is no clock */
-       if (!name)
-               return NULL;
-
-       reg = of_get_property(np, "reg", NULL);
-       addr = of_translate_address(np, reg);
-       return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s",
-                             (unsigned long long)addr, name);
-}
-
 static int cp110_syscon_common_probe(struct platform_device *pdev,
                                     struct device_node *syscon_node)
 {
@@ -261,7 +245,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
        cp110_clk_data->num = CP110_CLK_NUM;
 
        /* Register the PLL0 which is the root of the hw tree */
-       pll0_name = cp110_unique_name(dev, syscon_node, "pll0");
+       pll0_name = ap_cp_unique_name(dev, syscon_node, "pll0");
        hw = clk_hw_register_fixed_rate(NULL, pll0_name, NULL, 0,
                                        1000 * 1000 * 1000);
        if (IS_ERR(hw)) {
@@ -272,7 +256,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
        cp110_clks[CP110_CORE_PLL0] = hw;
 
        /* PPv2 is PLL0/3 */
-       ppv2_name = cp110_unique_name(dev, syscon_node, "ppv2-core");
+       ppv2_name = ap_cp_unique_name(dev, syscon_node, "ppv2-core");
        hw = clk_hw_register_fixed_factor(NULL, ppv2_name, pll0_name, 0, 1, 3);
        if (IS_ERR(hw)) {
                ret = PTR_ERR(hw);
@@ -282,7 +266,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
        cp110_clks[CP110_CORE_PPV2] = hw;
 
        /* X2CORE clock is PLL0/2 */
-       x2core_name = cp110_unique_name(dev, syscon_node, "x2core");
+       x2core_name = ap_cp_unique_name(dev, syscon_node, "x2core");
        hw = clk_hw_register_fixed_factor(NULL, x2core_name, pll0_name,
                                          0, 1, 2);
        if (IS_ERR(hw)) {
@@ -293,7 +277,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
        cp110_clks[CP110_CORE_X2CORE] = hw;
 
        /* Core clock is X2CORE/2 */
-       core_name = cp110_unique_name(dev, syscon_node, "core");
+       core_name = ap_cp_unique_name(dev, syscon_node, "core");
        hw = clk_hw_register_fixed_factor(NULL, core_name, x2core_name,
                                          0, 1, 2);
        if (IS_ERR(hw)) {
@@ -303,7 +287,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
 
        cp110_clks[CP110_CORE_CORE] = hw;
        /* NAND can be either PLL0/2.5 or core clock */
-       nand_name = cp110_unique_name(dev, syscon_node, "nand-core");
+       nand_name = ap_cp_unique_name(dev, syscon_node, "nand-core");
        if (nand_clk_ctrl & NF_CLOCK_SEL_400_MASK)
                hw = clk_hw_register_fixed_factor(NULL, nand_name,
                                                   pll0_name, 0, 2, 5);
@@ -318,7 +302,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
        cp110_clks[CP110_CORE_NAND] = hw;
 
        /* SDIO clock is PLL0/2.5 */
-       sdio_name = cp110_unique_name(dev, syscon_node, "sdio-core");
+       sdio_name = ap_cp_unique_name(dev, syscon_node, "sdio-core");
        hw = clk_hw_register_fixed_factor(NULL, sdio_name,
                                          pll0_name, 0, 2, 5);
        if (IS_ERR(hw)) {
@@ -330,7 +314,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
 
        /* create the unique name for all the gate clocks */
        for (i = 0; i < ARRAY_SIZE(gate_base_names); i++)
-               gate_name[i] =  cp110_unique_name(dev, syscon_node,
+               gate_name[i] =  ap_cp_unique_name(dev, syscon_node,
                                                  gate_base_names[i]);
 
        for (i = 0; i < ARRAY_SIZE(gate_base_names); i++) {
index e1ff83cc361eafdd2417e0e29b665ae9bf83b519..32dbb4f0949209345c4e993dddd91d9a2d3ed9f7 100644 (file)
@@ -21,7 +21,6 @@ if COMMON_CLK_QCOM
 
 config QCOM_A53PLL
        tristate "MSM8916 A53 PLL"
-       default ARCH_QCOM
        help
          Support for the A53 PLL on MSM8916 devices. It provides
          the CPU with frequencies above 1GHz.
@@ -31,7 +30,6 @@ config QCOM_A53PLL
 config QCOM_CLK_APCS_MSM8916
        tristate "MSM8916 APCS Clock Controller"
        depends on QCOM_APCS_IPC || COMPILE_TEST
-       default ARCH_QCOM
        help
          Support for the APCS Clock Controller on msm8916 devices. The
          APCS is managing the mux and divider which feeds the CPUs.
@@ -292,6 +290,13 @@ config SDM_LPASSCC_845
          Say Y if you want to use the LPASS branch clocks of the LPASS clock
          controller to reset the LPASS subsystem.
 
+config SM_GCC_8150
+       tristate "SM8150 Global Clock Controller"
+       help
+         Support for the global clock controller on SM8150 devices.
+         Say Y if you want to use peripheral devices such as UART,
+         SPI, I2C, USB, SD/UFS, PCIe etc.
+
 config SPMI_PMIC_CLKDIV
        tristate "SPMI PMIC clkdiv Support"
        depends on SPMI || COMPILE_TEST
index f0768fb1f037e1efb683ddbf0412ad24eb364187..4a813b4055d086d8b7ab2775738916d87f52fa7e 100644 (file)
@@ -50,6 +50,7 @@ obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
 obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o
 obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o
 obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
+obj-$(CONFIG_SM_GCC_8150) += gcc-sm8150.o
 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
 obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
 obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
index 0ced4a5a9a171e9025fc9696833fca1f9f3db82d..055318f97991535bc0d3d17360f8cf5c93d815ac 100644 (file)
@@ -32,6 +32,7 @@
 # define PLL_LOCK_DET          BIT(31)
 
 #define PLL_L_VAL(p)           ((p)->offset + (p)->regs[PLL_OFF_L_VAL])
+#define PLL_CAL_L_VAL(p)       ((p)->offset + (p)->regs[PLL_OFF_CAL_L_VAL])
 #define PLL_ALPHA_VAL(p)       ((p)->offset + (p)->regs[PLL_OFF_ALPHA_VAL])
 #define PLL_ALPHA_VAL_U(p)     ((p)->offset + (p)->regs[PLL_OFF_ALPHA_VAL_U])
 
 # define PLL_VCO_MASK          0x3
 
 #define PLL_USER_CTL_U(p)      ((p)->offset + (p)->regs[PLL_OFF_USER_CTL_U])
+#define PLL_USER_CTL_U1(p)     ((p)->offset + (p)->regs[PLL_OFF_USER_CTL_U1])
 
 #define PLL_CONFIG_CTL(p)      ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL])
 #define PLL_CONFIG_CTL_U(p)    ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U])
+#define PLL_CONFIG_CTL_U1(p)   ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U1])
 #define PLL_TEST_CTL(p)                ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL])
 #define PLL_TEST_CTL_U(p)      ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U])
 #define PLL_STATUS(p)          ((p)->offset + (p)->regs[PLL_OFF_STATUS])
 #define PLL_OPMODE(p)          ((p)->offset + (p)->regs[PLL_OFF_OPMODE])
 #define PLL_FRAC(p)            ((p)->offset + (p)->regs[PLL_OFF_FRAC])
+#define PLL_CAL_VAL(p)         ((p)->offset + (p)->regs[PLL_OFF_CAL_VAL])
 
 const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
        [CLK_ALPHA_PLL_TYPE_DEFAULT] =  {
@@ -96,6 +100,22 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
                [PLL_OFF_OPMODE] = 0x2c,
                [PLL_OFF_FRAC] = 0x38,
        },
+       [CLK_ALPHA_PLL_TYPE_TRION] = {
+               [PLL_OFF_L_VAL] = 0x04,
+               [PLL_OFF_CAL_L_VAL] = 0x08,
+               [PLL_OFF_USER_CTL] = 0x0c,
+               [PLL_OFF_USER_CTL_U] = 0x10,
+               [PLL_OFF_USER_CTL_U1] = 0x14,
+               [PLL_OFF_CONFIG_CTL] = 0x18,
+               [PLL_OFF_CONFIG_CTL_U] = 0x1c,
+               [PLL_OFF_CONFIG_CTL_U1] = 0x20,
+               [PLL_OFF_TEST_CTL] = 0x24,
+               [PLL_OFF_TEST_CTL_U] = 0x28,
+               [PLL_OFF_STATUS] = 0x30,
+               [PLL_OFF_OPMODE] = 0x38,
+               [PLL_OFF_ALPHA_VAL] = 0x40,
+               [PLL_OFF_CAL_VAL] = 0x44,
+       },
 };
 EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
 
@@ -120,6 +140,10 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
 #define FABIA_PLL_OUT_MASK     0x7
 #define FABIA_PLL_RATE_MARGIN  500
 
+#define TRION_PLL_STANDBY      0x0
+#define TRION_PLL_RUN          0x1
+#define TRION_PLL_OUT_MASK     0x7
+
 #define pll_alpha_width(p)                                     \
                ((PLL_ALPHA_VAL_U(p) - PLL_ALPHA_VAL(p) == 4) ? \
                                 ALPHA_REG_BITWIDTH : ALPHA_REG_16BIT_WIDTH)
@@ -730,6 +754,130 @@ static long alpha_pll_huayra_round_rate(struct clk_hw *hw, unsigned long rate,
        return alpha_huayra_pll_round_rate(rate, *prate, &l, &a);
 }
 
+static int trion_pll_is_enabled(struct clk_alpha_pll *pll,
+                               struct regmap *regmap)
+{
+       u32 mode_regval, opmode_regval;
+       int ret;
+
+       ret = regmap_read(regmap, PLL_MODE(pll), &mode_regval);
+       ret |= regmap_read(regmap, PLL_OPMODE(pll), &opmode_regval);
+       if (ret)
+               return 0;
+
+       return ((opmode_regval & TRION_PLL_RUN) && (mode_regval & PLL_OUTCTRL));
+}
+
+static int clk_trion_pll_is_enabled(struct clk_hw *hw)
+{
+       struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+
+       return trion_pll_is_enabled(pll, pll->clkr.regmap);
+}
+
+static int clk_trion_pll_enable(struct clk_hw *hw)
+{
+       struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+       struct regmap *regmap = pll->clkr.regmap;
+       u32 val;
+       int ret;
+
+       ret = regmap_read(regmap, PLL_MODE(pll), &val);
+       if (ret)
+               return ret;
+
+       /* If in FSM mode, just vote for it */
+       if (val & PLL_VOTE_FSM_ENA) {
+               ret = clk_enable_regmap(hw);
+               if (ret)
+                       return ret;
+               return wait_for_pll_enable_active(pll);
+       }
+
+       /* Set operation mode to RUN */
+       regmap_write(regmap, PLL_OPMODE(pll), TRION_PLL_RUN);
+
+       ret = wait_for_pll_enable_lock(pll);
+       if (ret)
+               return ret;
+
+       /* Enable the PLL outputs */
+       ret = regmap_update_bits(regmap, PLL_USER_CTL(pll),
+                                TRION_PLL_OUT_MASK, TRION_PLL_OUT_MASK);
+       if (ret)
+               return ret;
+
+       /* Enable the global PLL outputs */
+       return regmap_update_bits(regmap, PLL_MODE(pll),
+                                PLL_OUTCTRL, PLL_OUTCTRL);
+}
+
+static void clk_trion_pll_disable(struct clk_hw *hw)
+{
+       struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+       struct regmap *regmap = pll->clkr.regmap;
+       u32 val;
+       int ret;
+
+       ret = regmap_read(regmap, PLL_MODE(pll), &val);
+       if (ret)
+               return;
+
+       /* If in FSM mode, just unvote it */
+       if (val & PLL_VOTE_FSM_ENA) {
+               clk_disable_regmap(hw);
+               return;
+       }
+
+       /* Disable the global PLL output */
+       ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
+       if (ret)
+               return;
+
+       /* Disable the PLL outputs */
+       ret = regmap_update_bits(regmap, PLL_USER_CTL(pll),
+                                TRION_PLL_OUT_MASK, 0);
+       if (ret)
+               return;
+
+       /* Place the PLL mode in STANDBY */
+       regmap_write(regmap, PLL_OPMODE(pll), TRION_PLL_STANDBY);
+       regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
+}
+
+static unsigned long
+clk_trion_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+       struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+       struct regmap *regmap = pll->clkr.regmap;
+       u32 l, frac;
+       u64 prate = parent_rate;
+
+       regmap_read(regmap, PLL_L_VAL(pll), &l);
+       regmap_read(regmap, PLL_ALPHA_VAL(pll), &frac);
+
+       return alpha_pll_calc_rate(prate, l, frac, ALPHA_REG_16BIT_WIDTH);
+}
+
+static long clk_trion_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+                                    unsigned long *prate)
+{
+       struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+       unsigned long min_freq, max_freq;
+       u32 l;
+       u64 a;
+
+       rate = alpha_pll_round_rate(rate, *prate,
+                                   &l, &a, ALPHA_REG_16BIT_WIDTH);
+       if (!pll->vco_table || alpha_pll_find_vco(pll, rate))
+               return rate;
+
+       min_freq = pll->vco_table[0].min_freq;
+       max_freq = pll->vco_table[pll->num_vco - 1].max_freq;
+
+       return clamp(rate, min_freq, max_freq);
+}
+
 const struct clk_ops clk_alpha_pll_ops = {
        .enable = clk_alpha_pll_enable,
        .disable = clk_alpha_pll_disable,
@@ -760,6 +908,15 @@ const struct clk_ops clk_alpha_pll_hwfsm_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_alpha_pll_hwfsm_ops);
 
+const struct clk_ops clk_trion_fixed_pll_ops = {
+       .enable = clk_trion_pll_enable,
+       .disable = clk_trion_pll_disable,
+       .is_enabled = clk_trion_pll_is_enabled,
+       .recalc_rate = clk_trion_pll_recalc_rate,
+       .round_rate = clk_trion_pll_round_rate,
+};
+EXPORT_SYMBOL_GPL(clk_trion_fixed_pll_ops);
+
 static unsigned long
 clk_alpha_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 {
@@ -832,7 +989,7 @@ static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
        int div;
 
        /* 16 -> 0xf, 8 -> 0x7, 4 -> 0x3, 2 -> 0x1, 1 -> 0x0 */
-       div = DIV_ROUND_UP_ULL((u64)parent_rate, rate) - 1;
+       div = DIV_ROUND_UP_ULL(parent_rate, rate) - 1;
 
        return regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),
                                  PLL_POST_DIV_MASK(pll) << PLL_POST_DIV_SHIFT,
@@ -1036,11 +1193,6 @@ static unsigned long clk_alpha_pll_postdiv_fabia_recalc_rate(struct clk_hw *hw,
        u32 i, div = 1, val;
        int ret;
 
-       if (!pll->post_div_table) {
-               pr_err("Missing the post_div_table for the PLL\n");
-               return -EINVAL;
-       }
-
        ret = regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val);
        if (ret)
                return ret;
@@ -1058,16 +1210,71 @@ static unsigned long clk_alpha_pll_postdiv_fabia_recalc_rate(struct clk_hw *hw,
        return (parent_rate / div);
 }
 
-static long clk_alpha_pll_postdiv_fabia_round_rate(struct clk_hw *hw,
-                               unsigned long rate, unsigned long *prate)
+static unsigned long
+clk_trion_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 {
        struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
+       struct regmap *regmap = pll->clkr.regmap;
+       u32 i, div = 1, val;
 
-       if (!pll->post_div_table) {
-               pr_err("Missing the post_div_table for the PLL\n");
-               return -EINVAL;
+       regmap_read(regmap, PLL_USER_CTL(pll), &val);
+
+       val >>= pll->post_div_shift;
+       val &= PLL_POST_DIV_MASK(pll);
+
+       for (i = 0; i < pll->num_post_div; i++) {
+               if (pll->post_div_table[i].val == val) {
+                       div = pll->post_div_table[i].div;
+                       break;
+               }
+       }
+
+       return (parent_rate / div);
+}
+
+static long
+clk_trion_pll_postdiv_round_rate(struct clk_hw *hw, unsigned long rate,
+                                unsigned long *prate)
+{
+       struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
+
+       return divider_round_rate(hw, rate, prate, pll->post_div_table,
+                                 pll->width, CLK_DIVIDER_ROUND_CLOSEST);
+};
+
+static int
+clk_trion_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
+                              unsigned long parent_rate)
+{
+       struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
+       struct regmap *regmap = pll->clkr.regmap;
+       int i, val = 0, div;
+
+       div = DIV_ROUND_UP_ULL(parent_rate, rate);
+       for (i = 0; i < pll->num_post_div; i++) {
+               if (pll->post_div_table[i].div == div) {
+                       val = pll->post_div_table[i].val;
+                       break;
+               }
        }
 
+       return regmap_update_bits(regmap, PLL_USER_CTL(pll),
+                                 PLL_POST_DIV_MASK(pll) << PLL_POST_DIV_SHIFT,
+                                 val << PLL_POST_DIV_SHIFT);
+}
+
+const struct clk_ops clk_trion_pll_postdiv_ops = {
+       .recalc_rate = clk_trion_pll_postdiv_recalc_rate,
+       .round_rate = clk_trion_pll_postdiv_round_rate,
+       .set_rate = clk_trion_pll_postdiv_set_rate,
+};
+EXPORT_SYMBOL_GPL(clk_trion_pll_postdiv_ops);
+
+static long clk_alpha_pll_postdiv_fabia_round_rate(struct clk_hw *hw,
+                               unsigned long rate, unsigned long *prate)
+{
+       struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
+
        return divider_round_rate(hw, rate, prate, pll->post_div_table,
                                pll->width, CLK_DIVIDER_ROUND_CLOSEST);
 }
@@ -1089,12 +1296,7 @@ static int clk_alpha_pll_postdiv_fabia_set_rate(struct clk_hw *hw,
        if (val & PLL_VOTE_FSM_ENA)
                return 0;
 
-       if (!pll->post_div_table) {
-               pr_err("Missing the post_div_table for the PLL\n");
-               return -EINVAL;
-       }
-
-       div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
+       div = DIV_ROUND_UP_ULL(parent_rate, rate);
        for (i = 0; i < pll->num_post_div; i++) {
                if (pll->post_div_table[i].div == div) {
                        val = pll->post_div_table[i].val;
index 66755f0f84fcb1cc8d63369bc70a0727bcc1127a..15f27f4b06df5ec7570d42f4b53342161d246372 100644 (file)
@@ -13,22 +13,27 @@ enum {
        CLK_ALPHA_PLL_TYPE_HUAYRA,
        CLK_ALPHA_PLL_TYPE_BRAMMO,
        CLK_ALPHA_PLL_TYPE_FABIA,
+       CLK_ALPHA_PLL_TYPE_TRION,
        CLK_ALPHA_PLL_TYPE_MAX,
 };
 
 enum {
        PLL_OFF_L_VAL,
+       PLL_OFF_CAL_L_VAL,
        PLL_OFF_ALPHA_VAL,
        PLL_OFF_ALPHA_VAL_U,
        PLL_OFF_USER_CTL,
        PLL_OFF_USER_CTL_U,
+       PLL_OFF_USER_CTL_U1,
        PLL_OFF_CONFIG_CTL,
        PLL_OFF_CONFIG_CTL_U,
+       PLL_OFF_CONFIG_CTL_U1,
        PLL_OFF_TEST_CTL,
        PLL_OFF_TEST_CTL_U,
        PLL_OFF_STATUS,
        PLL_OFF_OPMODE,
        PLL_OFF_FRAC,
+       PLL_OFF_CAL_VAL,
        PLL_OFF_MAX_REGS
 };
 
@@ -117,5 +122,7 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
                             const struct alpha_pll_config *config);
 void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
                                const struct alpha_pll_config *config);
+extern const struct clk_ops clk_trion_fixed_pll_ops;
+extern const struct clk_ops clk_trion_pll_postdiv_ops;
 
 #endif
index 8c02bffe50dfac53e7d9adc92535084f11018f00..b98b81ef43a14aad0759a3661966893fc757e244 100644 (file)
@@ -119,7 +119,7 @@ static int update_config(struct clk_rcg2 *rcg)
        }
 
        WARN(1, "%s: rcg didn't update its configuration.", name);
-       return 0;
+       return -EBUSY;
 }
 
 static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index)
@@ -1105,8 +1105,6 @@ static int clk_rcg2_enable_dfs(const struct clk_rcg_dfs_data *data,
 
        rcg->freq_tbl = NULL;
 
-       pr_debug("DFS registered for clk %s\n", init->name);
-
        return 0;
 }
 
@@ -1117,12 +1115,8 @@ int qcom_cc_register_rcg_dfs(struct regmap *regmap,
 
        for (i = 0; i < len; i++) {
                ret = clk_rcg2_enable_dfs(&rcgs[i], regmap);
-               if (ret) {
-                       const char *name = rcgs[i].init->name;
-
-                       pr_err("DFS register failed for clk %s\n", name);
+               if (ret)
                        return ret;
-               }
        }
 
        return 0;
index c3fd632af1190d3cf1e32fa34ec1346724bdc3df..5b72689c3939d391da557f64944c6bc74d1fcaab 100644 (file)
@@ -95,7 +95,10 @@ static DEFINE_MUTEX(rpmh_clk_lock);
                .hw.init = &(struct clk_init_data){                     \
                        .ops = &clk_rpmh_ops,                           \
                        .name = #_name,                                 \
-                       .parent_names = (const char *[]){ "xo_board" }, \
+                       .parent_data =  &(const struct clk_parent_data){ \
+                                       .fw_name = "xo",                \
+                                       .name = "xo_board",             \
+                       },                                              \
                        .num_parents = 1,                               \
                },                                                      \
        };                                                              \
@@ -110,7 +113,10 @@ static DEFINE_MUTEX(rpmh_clk_lock);
                .hw.init = &(struct clk_init_data){                     \
                        .ops = &clk_rpmh_ops,                           \
                        .name = #_name_active,                          \
-                       .parent_names = (const char *[]){ "xo_board" }, \
+                       .parent_data =  &(const struct clk_parent_data){ \
+                                       .fw_name = "xo",                \
+                                       .name = "xo_board",             \
+                       },                                              \
                        .num_parents = 1,                               \
                },                                                      \
        }
@@ -368,6 +374,33 @@ static const struct clk_rpmh_desc clk_rpmh_sdm845 = {
        .num_clks = ARRAY_SIZE(sdm845_rpmh_clocks),
 };
 
+DEFINE_CLK_RPMH_ARC(sm8150, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 2);
+DEFINE_CLK_RPMH_VRM(sm8150, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 2);
+DEFINE_CLK_RPMH_VRM(sm8150, ln_bb_clk3, ln_bb_clk3_ao, "lnbclka3", 2);
+DEFINE_CLK_RPMH_VRM(sm8150, rf_clk1, rf_clk1_ao, "rfclka1", 1);
+DEFINE_CLK_RPMH_VRM(sm8150, rf_clk2, rf_clk2_ao, "rfclka2", 1);
+DEFINE_CLK_RPMH_VRM(sm8150, rf_clk3, rf_clk3_ao, "rfclka3", 1);
+
+static struct clk_hw *sm8150_rpmh_clocks[] = {
+       [RPMH_CXO_CLK]          = &sm8150_bi_tcxo.hw,
+       [RPMH_CXO_CLK_A]        = &sm8150_bi_tcxo_ao.hw,
+       [RPMH_LN_BB_CLK2]       = &sm8150_ln_bb_clk2.hw,
+       [RPMH_LN_BB_CLK2_A]     = &sm8150_ln_bb_clk2_ao.hw,
+       [RPMH_LN_BB_CLK3]       = &sm8150_ln_bb_clk3.hw,
+       [RPMH_LN_BB_CLK3_A]     = &sm8150_ln_bb_clk3_ao.hw,
+       [RPMH_RF_CLK1]          = &sm8150_rf_clk1.hw,
+       [RPMH_RF_CLK1_A]        = &sm8150_rf_clk1_ao.hw,
+       [RPMH_RF_CLK2]          = &sm8150_rf_clk2.hw,
+       [RPMH_RF_CLK2_A]        = &sm8150_rf_clk2_ao.hw,
+       [RPMH_RF_CLK3]          = &sm8150_rf_clk3.hw,
+       [RPMH_RF_CLK3_A]        = &sm8150_rf_clk3_ao.hw,
+};
+
+static const struct clk_rpmh_desc clk_rpmh_sm8150 = {
+       .clks = sm8150_rpmh_clocks,
+       .num_clks = ARRAY_SIZE(sm8150_rpmh_clocks),
+};
+
 static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec,
                                         void *data)
 {
@@ -396,6 +429,7 @@ static int clk_rpmh_probe(struct platform_device *pdev)
        hw_clks = desc->clks;
 
        for (i = 0; i < desc->num_clks; i++) {
+               const char *name = hw_clks[i]->init->name;
                u32 res_addr;
                size_t aux_data_len;
                const struct bcm_db *data;
@@ -426,8 +460,7 @@ static int clk_rpmh_probe(struct platform_device *pdev)
 
                ret = devm_clk_hw_register(&pdev->dev, hw_clks[i]);
                if (ret) {
-                       dev_err(&pdev->dev, "failed to register %s\n",
-                               hw_clks[i]->init->name);
+                       dev_err(&pdev->dev, "failed to register %s\n", name);
                        return ret;
                }
        }
@@ -447,6 +480,7 @@ static int clk_rpmh_probe(struct platform_device *pdev)
 
 static const struct of_device_id clk_rpmh_match_table[] = {
        { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845},
+       { .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150},
        { }
 };
 MODULE_DEVICE_TABLE(of, clk_rpmh_match_table);
index a6b2f86112d8634d79c4fa912d99ecb41dd0e600..28ddc747d703520f28fb8beed57a23aacee97f08 100644 (file)
@@ -306,4 +306,24 @@ int qcom_cc_probe(struct platform_device *pdev, const struct qcom_cc_desc *desc)
 }
 EXPORT_SYMBOL_GPL(qcom_cc_probe);
 
+int qcom_cc_probe_by_index(struct platform_device *pdev, int index,
+                          const struct qcom_cc_desc *desc)
+{
+       struct regmap *regmap;
+       struct resource *res;
+       void __iomem *base;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, index);
+       base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(base))
+               return -ENOMEM;
+
+       regmap = devm_regmap_init_mmio(&pdev->dev, base, desc->config);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       return qcom_cc_really_probe(pdev, desc, regmap);
+}
+EXPORT_SYMBOL_GPL(qcom_cc_probe_by_index);
+
 MODULE_LICENSE("GPL v2");
index 1e2a8bdac55a3781ec49ab988a27db6e7c8c5f0d..bb39a7e106d8a94950aabb25ab3885f16a421ddf 100644 (file)
@@ -61,5 +61,7 @@ extern int qcom_cc_really_probe(struct platform_device *pdev,
                                struct regmap *regmap);
 extern int qcom_cc_probe(struct platform_device *pdev,
                         const struct qcom_cc_desc *desc);
+extern int qcom_cc_probe_by_index(struct platform_device *pdev, int index,
+                                 const struct qcom_cc_desc *desc);
 
 #endif
index 39ade58b4ada499317ebd8f6c12bed6b1dc0a964..e01f5f591d1e2507846b966b8a4768504068ec54 100644 (file)
@@ -1108,7 +1108,7 @@ static struct clk_rcg2 sdcc2_apps_clk_src = {
                .name = "sdcc2_apps_clk_src",
                .parent_names = gcc_xo_gpll0_gpll2_gpll0_out_main_div2,
                .num_parents = 4,
-               .ops = &clk_rcg2_ops,
+               .ops = &clk_rcg2_floor_ops,
        },
 };
 
index 033688264c7b74503fedeadd9229e98e89866a3f..091acd59c1d6462cc3d7a739460938f9c410f8d0 100644 (file)
@@ -1042,7 +1042,7 @@ static struct clk_rcg2 sdcc2_apps_clk_src = {
                .name = "sdcc2_apps_clk_src",
                .parent_names = gcc_parent_names_4,
                .num_parents = 4,
-               .ops = &clk_rcg2_ops,
+               .ops = &clk_rcg2_floor_ops,
        },
 };
 
@@ -1066,7 +1066,7 @@ static struct clk_rcg2 sdcc4_apps_clk_src = {
                .name = "sdcc4_apps_clk_src",
                .parent_names = gcc_parent_names_1,
                .num_parents = 3,
-               .ops = &clk_rcg2_ops,
+               .ops = &clk_rcg2_floor_ops,
        },
 };
 
index 29cf464dd2c89be89870b2697a203f82d9431ad2..bd32212f37e64b1850d89b68e8beaea0fe20858c 100644 (file)
@@ -1057,7 +1057,7 @@ static struct clk_rcg2 sdcc1_apps_clk_src = {
                .name = "sdcc1_apps_clk_src",
                .parent_names = gcc_parent_names_13,
                .num_parents = 5,
-               .ops = &clk_rcg2_ops,
+               .ops = &clk_rcg2_floor_ops,
        },
 };
 
@@ -1103,7 +1103,7 @@ static struct clk_rcg2 sdcc2_apps_clk_src = {
                .name = "sdcc2_apps_clk_src",
                .parent_names = gcc_parent_names_14,
                .num_parents = 4,
-               .ops = &clk_rcg2_ops,
+               .ops = &clk_rcg2_floor_ops,
        },
 };
 
@@ -2604,6 +2604,32 @@ static struct clk_branch gcc_usb_hs_system_clk = {
        },
 };
 
+static struct clk_branch gcc_wdsp_q6ss_ahbs_clk = {
+       .halt_reg = 0x1e004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1e004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_wdsp_q6ss_ahbs_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_wdsp_q6ss_axim_clk = {
+       .halt_reg = 0x1e008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1e008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_wdsp_q6ss_axim_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static struct clk_hw *gcc_qcs404_hws[] = {
        &cxo.hw,
 };
@@ -2749,6 +2775,9 @@ static struct clk_regmap *gcc_qcs404_clocks[] = {
        [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr,
        [GCC_DCC_CLK] = &gcc_dcc_clk.clkr,
        [GCC_DCC_XO_CLK] = &gcc_dcc_xo_clk.clkr,
+       [GCC_WCSS_Q6_AHB_CLK] = &gcc_wdsp_q6ss_ahbs_clk.clkr,
+       [GCC_WCSS_Q6_AXIM_CLK] =  &gcc_wdsp_q6ss_axim_clk.clkr,
+
 };
 
 static const struct qcom_reset_map gcc_qcs404_resets[] = {
@@ -2774,6 +2803,7 @@ static const struct qcom_reset_map gcc_qcs404_resets[] = {
        [GCC_PCIE_0_SLEEP_ARES] = { 0x3e040, 1 },
        [GCC_PCIE_0_PIPE_ARES] = { 0x3e040, 0 },
        [GCC_EMAC_BCR] = { 0x4e000 },
+       [GCC_WDSP_RESTART] = {0x19000},
 };
 
 static const struct regmap_config gcc_qcs404_regmap_config = {
index 8827db23066f5926894c3088ab71411346d8ec01..bf5730832ef3dea56fd1401a26fc9cb805041095 100644 (file)
@@ -787,7 +787,7 @@ static struct clk_rcg2 sdcc2_apps_clk_src = {
                .name = "sdcc2_apps_clk_src",
                .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div_gpll4,
                .num_parents = 4,
-               .ops = &clk_rcg2_ops,
+               .ops = &clk_rcg2_floor_ops,
        },
 };
 
index 7131dcf9b0603ad6a5e4069d9367add7aa6961a1..95be125c3bddf125e2d86e1e9b138f1032a78377 100644 (file)
@@ -685,7 +685,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
                .name = "gcc_sdcc2_apps_clk_src",
                .parent_names = gcc_parent_names_10,
                .num_parents = 5,
-               .ops = &clk_rcg2_ops,
+               .ops = &clk_rcg2_floor_ops,
        },
 };
 
@@ -709,7 +709,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = {
                .name = "gcc_sdcc4_apps_clk_src",
                .parent_names = gcc_parent_names_0,
                .num_parents = 4,
-               .ops = &clk_rcg2_ops,
+               .ops = &clk_rcg2_floor_ops,
        },
 };
 
diff --git a/drivers/clk/qcom/gcc-sm8150.c b/drivers/clk/qcom/gcc-sm8150.c
new file mode 100644 (file)
index 0000000..2087721
--- /dev/null
@@ -0,0 +1,3588 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#include <dt-bindings/clock/qcom,gcc-sm8150.h>
+
+#include "common.h"
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "reset.h"
+
+enum {
+       P_BI_TCXO,
+       P_AUD_REF_CLK,
+       P_CORE_BI_PLL_TEST_SE,
+       P_GPLL0_OUT_EVEN,
+       P_GPLL0_OUT_MAIN,
+       P_GPLL7_OUT_MAIN,
+       P_GPLL9_OUT_MAIN,
+       P_SLEEP_CLK,
+};
+
+static const struct pll_vco trion_vco[] = {
+       { 249600000, 2000000000, 0 },
+};
+
+static struct clk_alpha_pll gpll0 = {
+       .offset = 0x0,
+       .vco_table = trion_vco,
+       .num_vco = ARRAY_SIZE(trion_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll0",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                               .name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_trion_fixed_pll_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_trion_even[] = {
+       { 0x0, 1 },
+       { 0x1, 2 },
+       { 0x3, 4 },
+       { 0x7, 8 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll0_out_even = {
+       .offset = 0x0,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_trion_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_trion_even),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll0_out_even",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "bi_tcxo",
+                       .name = "bi_tcxo",
+               },
+               .num_parents = 1,
+               .ops = &clk_trion_pll_postdiv_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll7 = {
+       .offset = 0x1a000,
+       .vco_table = trion_vco,
+       .num_vco = ARRAY_SIZE(trion_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll7",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                               .name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_trion_fixed_pll_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll gpll9 = {
+       .offset = 0x1c000,
+       .vco_table = trion_vco,
+       .num_vco = ARRAY_SIZE(trion_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll9",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                               .name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_trion_fixed_pll_ops,
+               },
+       },
+};
+
+static const struct parent_map gcc_parent_map_0[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL0_OUT_EVEN, 6 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const struct clk_parent_data gcc_parents_0[] = {
+       { .fw_name = "bi_tcxo", .name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+       { .fw_name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map gcc_parent_map_1[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_SLEEP_CLK, 5 },
+       { P_GPLL0_OUT_EVEN, 6 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const struct clk_parent_data gcc_parents_1[] = {
+       { .fw_name = "bi_tcxo", .name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .fw_name = "sleep_clk", .name = "sleep_clk" },
+       { .hw = &gpll0_out_even.clkr.hw },
+       { .fw_name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map gcc_parent_map_2[] = {
+       { P_BI_TCXO, 0 },
+       { P_SLEEP_CLK, 5 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const struct clk_parent_data gcc_parents_2[] = {
+       { .fw_name = "bi_tcxo", .name = "bi_tcxo" },
+       { .fw_name = "sleep_clk", .name = "sleep_clk" },
+       { .fw_name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map gcc_parent_map_3[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const struct clk_parent_data gcc_parents_3[] = {
+       { .fw_name = "bi_tcxo", .name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .fw_name = "core_bi_pll_test_se"},
+};
+
+static const struct parent_map gcc_parent_map_4[] = {
+       { P_BI_TCXO, 0 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const struct clk_parent_data gcc_parents_4[] = {
+       { .fw_name = "bi_tcxo", .name = "bi_tcxo" },
+       { .fw_name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map gcc_parent_map_5[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL7_OUT_MAIN, 3 },
+       { P_GPLL0_OUT_EVEN, 6 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const struct clk_parent_data gcc_parents_5[] = {
+       { .fw_name = "bi_tcxo", .name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll7.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+       { .fw_name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map gcc_parent_map_6[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL9_OUT_MAIN, 2 },
+       { P_GPLL0_OUT_EVEN, 6 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const struct clk_parent_data gcc_parents_6[] = {
+       { .fw_name = "bi_tcxo", .name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll9.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+       { .fw_name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map gcc_parent_map_7[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_AUD_REF_CLK, 2 },
+       { P_GPLL0_OUT_EVEN, 6 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const struct clk_parent_data gcc_parents_7[] = {
+       { .fw_name = "bi_tcxo", .name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .fw_name = "aud_ref_clk", .name = "aud_ref_clk" },
+       { .hw = &gpll0_out_even.clkr.hw },
+       { .fw_name = "core_bi_pll_test_se" },
+};
+
+static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_cpuss_ahb_clk_src = {
+       .cmd_rcgr = 0x48014,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_cpuss_ahb_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_emac_ptp_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0),
+       F(125000000, P_GPLL7_OUT_MAIN, 4, 0, 0),
+       F(250000000, P_GPLL7_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_emac_ptp_clk_src = {
+       .cmd_rcgr = 0x6038,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_5,
+       .freq_tbl = ftbl_gcc_emac_ptp_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_emac_ptp_clk_src",
+               .parent_data = gcc_parents_5,
+               .num_parents = 5,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_emac_rgmii_clk_src[] = {
+       F(2500000, P_BI_TCXO, 1, 25, 192),
+       F(5000000, P_BI_TCXO, 1, 25, 96),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0),
+       F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0),
+       F(125000000, P_GPLL7_OUT_MAIN, 4, 0, 0),
+       F(250000000, P_GPLL7_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_emac_rgmii_clk_src = {
+       .cmd_rcgr = 0x601c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_5,
+       .freq_tbl = ftbl_gcc_emac_rgmii_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_emac_rgmii_clk_src",
+               .parent_data = gcc_parents_5,
+               .num_parents = 5,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0),
+       F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_gp1_clk_src = {
+       .cmd_rcgr = 0x64004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_gp1_clk_src",
+               .parent_data = gcc_parents_1,
+               .num_parents = 5,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_gp2_clk_src = {
+       .cmd_rcgr = 0x65004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_gp2_clk_src",
+               .parent_data = gcc_parents_1,
+               .num_parents = 5,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_gp3_clk_src = {
+       .cmd_rcgr = 0x66004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_gp3_clk_src",
+               .parent_data = gcc_parents_1,
+               .num_parents = 5,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_pcie_0_aux_clk_src[] = {
+       F(9600000, P_BI_TCXO, 2, 0, 0),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_pcie_0_aux_clk_src = {
+       .cmd_rcgr = 0x6b02c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_pcie_0_aux_clk_src",
+               .parent_data = gcc_parents_2,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_pcie_1_aux_clk_src = {
+       .cmd_rcgr = 0x8d02c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_pcie_1_aux_clk_src",
+               .parent_data = gcc_parents_2,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_pcie_phy_refgen_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_pcie_phy_refgen_clk_src = {
+       .cmd_rcgr = 0x6f014,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_pcie_phy_refgen_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_pcie_phy_refgen_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = {
+       F(9600000, P_BI_TCXO, 2, 0, 0),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_pdm2_clk_src = {
+       .cmd_rcgr = 0x33010,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_pdm2_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_pdm2_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_qspi_core_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_qspi_core_clk_src = {
+       .cmd_rcgr = 0x4b008,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qspi_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qspi_core_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
+       F(7372800, P_GPLL0_OUT_EVEN, 1, 384, 15625),
+       F(14745600, P_GPLL0_OUT_EVEN, 1, 768, 15625),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(29491200, P_GPLL0_OUT_EVEN, 1, 1536, 15625),
+       F(32000000, P_GPLL0_OUT_EVEN, 1, 8, 75),
+       F(48000000, P_GPLL0_OUT_EVEN, 1, 4, 25),
+       F(64000000, P_GPLL0_OUT_EVEN, 1, 16, 75),
+       F(80000000, P_GPLL0_OUT_EVEN, 1, 4, 15),
+       F(96000000, P_GPLL0_OUT_EVEN, 1, 8, 25),
+       F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0),
+       F(102400000, P_GPLL0_OUT_EVEN, 1, 128, 375),
+       F(112000000, P_GPLL0_OUT_EVEN, 1, 28, 75),
+       F(117964800, P_GPLL0_OUT_EVEN, 1, 6144, 15625),
+       F(120000000, P_GPLL0_OUT_EVEN, 2.5, 0, 0),
+       F(128000000, P_GPLL0_OUT_MAIN, 1, 16, 75),
+       { }
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
+       .cmd_rcgr = 0x17148,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap0_s0_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
+       .cmd_rcgr = 0x17278,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap0_s1_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
+       .cmd_rcgr = 0x173a8,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap0_s2_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
+       .cmd_rcgr = 0x174d8,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap0_s3_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
+       .cmd_rcgr = 0x17608,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap0_s4_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
+       .cmd_rcgr = 0x17738,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap0_s5_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = {
+       .cmd_rcgr = 0x17868,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap0_s6_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = {
+       .cmd_rcgr = 0x17998,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap0_s7_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
+       .cmd_rcgr = 0x18148,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap1_s0_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
+       .cmd_rcgr = 0x18278,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap1_s1_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
+       .cmd_rcgr = 0x183a8,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap1_s2_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
+       .cmd_rcgr = 0x184d8,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap1_s3_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
+       .cmd_rcgr = 0x18608,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap1_s4_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
+       .cmd_rcgr = 0x18738,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap1_s5_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = {
+       .cmd_rcgr = 0x1e148,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap2_s0_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = {
+       .cmd_rcgr = 0x1e278,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap2_s1_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = {
+       .cmd_rcgr = 0x1e3a8,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap2_s2_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = {
+       .cmd_rcgr = 0x1e4d8,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap2_s3_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = {
+       .cmd_rcgr = 0x1e608,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap2_s4_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = {
+       .cmd_rcgr = 0x1e738,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qupv3_wrap2_s5_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
+       F(400000, P_BI_TCXO, 12, 1, 4),
+       F(9600000, P_BI_TCXO, 2, 0, 0),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(25000000, P_GPLL0_OUT_MAIN, 12, 1, 2),
+       F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       F(202000000, P_GPLL9_OUT_MAIN, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
+       .cmd_rcgr = 0x1400c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_6,
+       .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc2_apps_clk_src",
+               .parent_data = gcc_parents_6,
+               .num_parents = 5,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_floor_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc4_apps_clk_src[] = {
+       F(400000, P_BI_TCXO, 12, 1, 4),
+       F(9600000, P_BI_TCXO, 2, 0, 0),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(25000000, P_GPLL0_OUT_MAIN, 12, 1, 2),
+       F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdcc4_apps_clk_src = {
+       .cmd_rcgr = 0x1600c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_gcc_sdcc4_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc4_apps_clk_src",
+               .parent_data = gcc_parents_3,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_floor_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_tsif_ref_clk_src[] = {
+       F(105495, P_BI_TCXO, 2, 1, 91),
+       { }
+};
+
+static struct clk_rcg2 gcc_tsif_ref_clk_src = {
+       .cmd_rcgr = 0x36010,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_7,
+       .freq_tbl = ftbl_gcc_tsif_ref_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_tsif_ref_clk_src",
+               .parent_data = gcc_parents_7,
+               .num_parents = 5,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_card_axi_clk_src[] = {
+       F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0),
+       F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_card_axi_clk_src = {
+       .cmd_rcgr = 0x75020,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_ufs_card_axi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_card_axi_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_card_ice_core_clk_src[] = {
+       F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0),
+       F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_card_ice_core_clk_src = {
+       .cmd_rcgr = 0x75060,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_ufs_card_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_card_ice_core_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_card_phy_aux_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_card_phy_aux_clk_src = {
+       .cmd_rcgr = 0x75094,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4,
+       .freq_tbl = ftbl_gcc_ufs_card_phy_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_card_phy_aux_clk_src",
+               .parent_data = gcc_parents_4,
+               .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_card_unipro_core_clk_src[] = {
+       F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0),
+       F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_card_unipro_core_clk_src = {
+       .cmd_rcgr = 0x75078,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_ufs_card_unipro_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_card_unipro_core_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
+       F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0),
+       F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0),
+       F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = {
+       .cmd_rcgr = 0x77020,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_axi_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = {
+       .cmd_rcgr = 0x77060,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_ufs_card_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_ice_core_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = {
+       .cmd_rcgr = 0x77094,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4,
+       .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_phy_aux_clk_src",
+               .parent_data = gcc_parents_4,
+               .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = {
+       .cmd_rcgr = 0x77078,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_ufs_card_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_unipro_core_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
+       F(33333333, P_GPLL0_OUT_EVEN, 9, 0, 0),
+       F(66666667, P_GPLL0_OUT_EVEN, 4.5, 0, 0),
+       F(133333333, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_usb30_prim_master_clk_src = {
+       .cmd_rcgr = 0xf01c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb30_prim_master_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_prim_mock_utmi_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(20000000, P_GPLL0_OUT_EVEN, 15, 0, 0),
+       F(60000000, P_GPLL0_OUT_EVEN, 5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = {
+       .cmd_rcgr = 0xf034,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb30_prim_mock_utmi_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_usb30_sec_master_clk_src = {
+       .cmd_rcgr = 0x1001c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb30_sec_master_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_usb30_sec_mock_utmi_clk_src = {
+       .cmd_rcgr = 0x10034,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb30_sec_mock_utmi_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = {
+       .cmd_rcgr = 0xf060,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gcc_ufs_card_phy_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb3_prim_phy_aux_clk_src",
+               .parent_data = gcc_parents_2,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_usb3_sec_phy_aux_clk_src = {
+       .cmd_rcgr = 0x10060,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gcc_ufs_card_phy_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb3_sec_phy_aux_clk_src",
+               .parent_data = gcc_parents_2,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_aggre_noc_pcie_tbu_clk = {
+       .halt_reg = 0x90018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x90018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre_noc_pcie_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_aggre_ufs_card_axi_clk = {
+       .halt_reg = 0x750c0,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x750c0,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x750c0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre_ufs_card_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_ufs_card_axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_aggre_ufs_card_axi_hw_ctl_clk = {
+       .halt_reg = 0x750c0,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x750c0,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x750c0,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre_ufs_card_axi_hw_ctl_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_aggre_ufs_card_axi_clk.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch_simple_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_aggre_ufs_phy_axi_clk = {
+       .halt_reg = 0x770c0,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x770c0,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x770c0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre_ufs_phy_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_ufs_phy_axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_aggre_ufs_phy_axi_hw_ctl_clk = {
+       .halt_reg = 0x770c0,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x770c0,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x770c0,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre_ufs_phy_axi_hw_ctl_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_aggre_ufs_phy_axi_clk.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch_simple_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_aggre_usb3_prim_axi_clk = {
+       .halt_reg = 0xf07c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xf07c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre_usb3_prim_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_usb30_prim_master_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_aggre_usb3_sec_axi_clk = {
+       .halt_reg = 0x1007c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1007c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre_usb3_sec_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_usb30_sec_master_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_boot_rom_ahb_clk = {
+       .halt_reg = 0x38004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x38004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x52004,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_boot_rom_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+/*
+ * Clock ON depends on external parent 'config noc', so cant poll
+ * delay and also mark as crtitical for camss boot
+ */
+static struct clk_branch gcc_camera_ahb_clk = {
+       .halt_reg = 0xb008,
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0xb008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0xb008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camera_ahb_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camera_hf_axi_clk = {
+       .halt_reg = 0xb030,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camera_hf_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camera_sf_axi_clk = {
+       .halt_reg = 0xb034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camera_sf_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+/* XO critical input to camss, so no need to poll */
+static struct clk_branch gcc_camera_xo_clk = {
+       .halt_reg = 0xb044,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0xb044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camera_xo_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = {
+       .halt_reg = 0xf078,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xf078,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cfg_noc_usb3_prim_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_usb30_prim_master_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cfg_noc_usb3_sec_axi_clk = {
+       .halt_reg = 0x10078,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x10078,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cfg_noc_usb3_sec_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_usb30_sec_master_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cpuss_ahb_clk = {
+       .halt_reg = 0x48000,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52004,
+               .enable_mask = BIT(21),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cpuss_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_cpuss_ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                        /* required for cpuss */
+                       .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cpuss_dvm_bus_clk = {
+       .halt_reg = 0x48190,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x48190,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cpuss_dvm_bus_clk",
+                        /* required for cpuss */
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cpuss_gnoc_clk = {
+       .halt_reg = 0x48004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x48004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x52004,
+               .enable_mask = BIT(22),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cpuss_gnoc_clk",
+                        /* required for cpuss */
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cpuss_rbcpr_clk = {
+       .halt_reg = 0x48008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x48008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cpuss_rbcpr_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ddrss_gpu_axi_clk = {
+       .halt_reg = 0x71154,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x71154,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ddrss_gpu_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+/*
+ * Clock ON depends on external parent 'config noc', so cant poll
+ * delay and also mark as crtitical for disp boot
+ */
+static struct clk_branch gcc_disp_ahb_clk = {
+       .halt_reg = 0xb00c,
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0xb00c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0xb00c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_ahb_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_hf_axi_clk = {
+       .halt_reg = 0xb038,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb038,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_hf_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_sf_axi_clk = {
+       .halt_reg = 0xb03c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb03c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_sf_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+/* XO critical input to disp, so no need to poll */
+static struct clk_branch gcc_disp_xo_clk = {
+       .halt_reg = 0xb048,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0xb048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_xo_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_emac_axi_clk = {
+       .halt_reg = 0x6010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_emac_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_emac_ptp_clk = {
+       .halt_reg = 0x6034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_emac_ptp_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_emac_ptp_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_emac_rgmii_clk = {
+       .halt_reg = 0x6018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_emac_rgmii_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_emac_rgmii_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_emac_slv_ahb_clk = {
+       .halt_reg = 0x6014,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x6014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x6014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_emac_slv_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp1_clk = {
+       .halt_reg = 0x64000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x64000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp1_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_gp1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp2_clk = {
+       .halt_reg = 0x65000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x65000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp2_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_gp2_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp3_clk = {
+       .halt_reg = 0x66000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x66000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp3_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_gp3_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_cfg_ahb_clk = {
+       .halt_reg = 0x71004,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x71004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x71004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_cfg_ahb_clk",
+                        /* required for gpu */
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_iref_clk = {
+       .halt_reg = 0x8c010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8c010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_iref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_memnoc_gfx_clk = {
+       .halt_reg = 0x7100c,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x7100c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_memnoc_gfx_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = {
+       .halt_reg = 0x71018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x71018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_snoc_dvm_gfx_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_npu_at_clk = {
+       .halt_reg = 0x4d010,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x4d010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_npu_at_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_npu_axi_clk = {
+       .halt_reg = 0x4d008,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x4d008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_npu_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_npu_cfg_ahb_clk = {
+       .halt_reg = 0x4d004,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x4d004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x4d004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_npu_cfg_ahb_clk",
+                        /* required for npu */
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_npu_trig_clk = {
+       .halt_reg = 0x4d00c,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x4d00c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_npu_trig_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie0_phy_refgen_clk = {
+       .halt_reg = 0x6f02c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6f02c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie0_phy_refgen_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_pcie_phy_refgen_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie1_phy_refgen_clk = {
+       .halt_reg = 0x6f030,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6f030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie1_phy_refgen_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_pcie_phy_refgen_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_0_aux_clk = {
+       .halt_reg = 0x6b020,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(3),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_aux_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_pcie_0_aux_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_0_cfg_ahb_clk = {
+       .halt_reg = 0x6b01c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x6b01c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_cfg_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_0_clkref_clk = {
+       .halt_reg = 0x8c00c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8c00c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_clkref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_0_mstr_axi_clk = {
+       .halt_reg = 0x6b018,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_mstr_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+/* Clock ON depends on external parent 'PIPE' clock, so dont poll */
+static struct clk_branch gcc_pcie_0_pipe_clk = {
+       .halt_reg = 0x6b024,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_pipe_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_0_slv_axi_clk = {
+       .halt_reg = 0x6b014,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x6b014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_slv_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_0_slv_q2a_axi_clk = {
+       .halt_reg = 0x6b010,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(5),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_slv_q2a_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_1_aux_clk = {
+       .halt_reg = 0x8d020,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52004,
+               .enable_mask = BIT(29),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_aux_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_pcie_1_aux_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_1_cfg_ahb_clk = {
+       .halt_reg = 0x8d01c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x8d01c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x52004,
+               .enable_mask = BIT(28),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_cfg_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_1_clkref_clk = {
+       .halt_reg = 0x8c02c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8c02c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_clkref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_1_mstr_axi_clk = {
+       .halt_reg = 0x8d018,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52004,
+               .enable_mask = BIT(27),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_mstr_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+/* Clock ON depends on external parent 'PIPE' clock, so dont poll */
+static struct clk_branch gcc_pcie_1_pipe_clk = {
+       .halt_reg = 0x8d024,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x52004,
+               .enable_mask = BIT(30),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_pipe_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_1_slv_axi_clk = {
+       .halt_reg = 0x8d014,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x8d014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x52004,
+               .enable_mask = BIT(26),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_slv_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_1_slv_q2a_axi_clk = {
+       .halt_reg = 0x8d010,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52004,
+               .enable_mask = BIT(25),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_slv_q2a_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_phy_aux_clk = {
+       .halt_reg = 0x6f004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6f004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_phy_aux_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_pcie_0_aux_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm2_clk = {
+       .halt_reg = 0x3300c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3300c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm2_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_pdm2_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm_ahb_clk = {
+       .halt_reg = 0x33004,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x33004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x33004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm_xo4_clk = {
+       .halt_reg = 0x33008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x33008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm_xo4_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_prng_ahb_clk = {
+       .halt_reg = 0x34004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52004,
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_prng_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = {
+       .halt_reg = 0xb018,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0xb018,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0xb018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_camera_nrt_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_camera_rt_ahb_clk = {
+       .halt_reg = 0xb01c,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0xb01c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0xb01c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_camera_rt_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_disp_ahb_clk = {
+       .halt_reg = 0xb020,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0xb020,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0xb020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_disp_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_video_cvp_ahb_clk = {
+       .halt_reg = 0xb010,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0xb010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0xb010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_video_cvp_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_video_vcodec_ahb_clk = {
+       .halt_reg = 0xb014,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0xb014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0xb014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_video_vcodec_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qspi_cnoc_periph_ahb_clk = {
+       .halt_reg = 0x4b000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4b000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qspi_cnoc_periph_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qspi_core_clk = {
+       .halt_reg = 0x4b004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4b004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qspi_core_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qspi_core_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s0_clk = {
+       .halt_reg = 0x17144,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s0_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap0_s0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s1_clk = {
+       .halt_reg = 0x17274,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s1_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap0_s1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s2_clk = {
+       .halt_reg = 0x173a4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(12),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s2_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap0_s2_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s3_clk = {
+       .halt_reg = 0x174d4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s3_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap0_s3_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s4_clk = {
+       .halt_reg = 0x17604,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(14),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s4_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap0_s4_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s5_clk = {
+       .halt_reg = 0x17734,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(15),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s5_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap0_s5_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s6_clk = {
+       .halt_reg = 0x17864,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(16),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s6_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap0_s6_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s7_clk = {
+       .halt_reg = 0x17994,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(17),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s7_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap0_s7_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s0_clk = {
+       .halt_reg = 0x18144,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(22),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s0_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap1_s0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s1_clk = {
+       .halt_reg = 0x18274,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(23),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s1_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap1_s1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s2_clk = {
+       .halt_reg = 0x183a4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(24),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s2_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap1_s2_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s3_clk = {
+       .halt_reg = 0x184d4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(25),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s3_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap1_s3_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s4_clk = {
+       .halt_reg = 0x18604,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(26),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s4_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap1_s4_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s5_clk = {
+       .halt_reg = 0x18734,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(27),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s5_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap1_s5_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap2_s0_clk = {
+       .halt_reg = 0x1e144,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52014,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap2_s0_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap2_s0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap2_s1_clk = {
+       .halt_reg = 0x1e274,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52014,
+               .enable_mask = BIT(5),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap2_s1_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap2_s1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap2_s2_clk = {
+       .halt_reg = 0x1e3a4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52014,
+               .enable_mask = BIT(6),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap2_s2_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap2_s2_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap2_s3_clk = {
+       .halt_reg = 0x1e4d4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52014,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap2_s3_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap2_s3_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap2_s4_clk = {
+       .halt_reg = 0x1e604,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52014,
+               .enable_mask = BIT(8),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap2_s4_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap2_s4_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap2_s5_clk = {
+       .halt_reg = 0x1e734,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52014,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap2_s5_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_qupv3_wrap2_s5_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap_0_m_ahb_clk = {
+       .halt_reg = 0x17004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(6),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap_0_m_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap_0_s_ahb_clk = {
+       .halt_reg = 0x17008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x17008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap_0_s_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap_1_m_ahb_clk = {
+       .halt_reg = 0x18004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(20),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap_1_m_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = {
+       .halt_reg = 0x18008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x18008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(21),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap_1_s_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap_2_m_ahb_clk = {
+       .halt_reg = 0x1e004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52014,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap_2_m_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap_2_s_ahb_clk = {
+       .halt_reg = 0x1e008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x1e008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x52014,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap_2_s_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc2_ahb_clk = {
+       .halt_reg = 0x14008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x14008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc2_apps_clk = {
+       .halt_reg = 0x14004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x14004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_sdcc2_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc4_ahb_clk = {
+       .halt_reg = 0x16008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x16008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc4_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc4_apps_clk = {
+       .halt_reg = 0x16004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x16004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc4_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_sdcc4_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = {
+       .halt_reg = 0x4819c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sys_noc_cpuss_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_cpuss_ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       /* required for cpuss */
+                       .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_tsif_ahb_clk = {
+       .halt_reg = 0x36004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x36004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_tsif_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_tsif_inactivity_timers_clk = {
+       .halt_reg = 0x3600c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3600c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_tsif_inactivity_timers_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_tsif_ref_clk = {
+       .halt_reg = 0x36008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x36008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_tsif_ref_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_tsif_ref_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_card_ahb_clk = {
+       .halt_reg = 0x75014,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x75014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x75014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_card_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_card_axi_clk = {
+       .halt_reg = 0x75010,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x75010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x75010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_card_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_ufs_card_axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_card_axi_hw_ctl_clk = {
+       .halt_reg = 0x75010,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x75010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x75010,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_card_axi_hw_ctl_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_ufs_card_axi_clk.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch_simple_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_card_clkref_clk = {
+       .halt_reg = 0x8c004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8c004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_card_clkref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_card_ice_core_clk = {
+       .halt_reg = 0x7505c,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x7505c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7505c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_card_ice_core_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_ufs_card_ice_core_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_card_ice_core_hw_ctl_clk = {
+       .halt_reg = 0x7505c,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x7505c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7505c,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_card_ice_core_hw_ctl_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_ufs_card_ice_core_clk.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch_simple_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_card_phy_aux_clk = {
+       .halt_reg = 0x75090,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x75090,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x75090,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_card_phy_aux_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_ufs_card_phy_aux_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_card_phy_aux_hw_ctl_clk = {
+       .halt_reg = 0x75090,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x75090,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x75090,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_card_phy_aux_hw_ctl_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_ufs_card_phy_aux_clk.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch_simple_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_card_unipro_core_clk = {
+       .halt_reg = 0x75058,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x75058,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x75058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_card_unipro_core_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_ufs_card_unipro_core_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_card_unipro_core_hw_ctl_clk = {
+       .halt_reg = 0x75058,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x75058,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x75058,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_card_unipro_core_hw_ctl_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_ufs_card_unipro_core_clk.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch_simple_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_mem_clkref_clk = {
+       .halt_reg = 0x8c000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8c000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_mem_clkref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_ahb_clk = {
+       .halt_reg = 0x77014,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x77014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x77014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_axi_clk = {
+       .halt_reg = 0x77010,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x77010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x77010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_ufs_phy_axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_axi_hw_ctl_clk = {
+       .halt_reg = 0x77010,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x77010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x77010,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_axi_hw_ctl_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_ufs_phy_axi_clk.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch_simple_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_ice_core_clk = {
+       .halt_reg = 0x7705c,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x7705c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7705c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_ice_core_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_ufs_phy_ice_core_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_ice_core_hw_ctl_clk = {
+       .halt_reg = 0x7705c,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x7705c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7705c,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_ice_core_hw_ctl_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_ufs_phy_ice_core_clk.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch_simple_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_phy_aux_clk = {
+       .halt_reg = 0x77090,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x77090,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x77090,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_phy_aux_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_ufs_phy_phy_aux_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_phy_aux_hw_ctl_clk = {
+       .halt_reg = 0x77090,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x77090,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x77090,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_phy_aux_hw_ctl_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_ufs_phy_phy_aux_clk.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch_simple_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_unipro_core_clk = {
+       .halt_reg = 0x77058,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x77058,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x77058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_unipro_core_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_ufs_phy_unipro_core_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_unipro_core_hw_ctl_clk = {
+       .halt_reg = 0x77058,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x77058,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x77058,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_unipro_core_hw_ctl_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_ufs_phy_unipro_core_clk.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch_simple_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_prim_master_clk = {
+       .halt_reg = 0xf010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xf010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_prim_master_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_usb30_prim_master_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_prim_mock_utmi_clk = {
+       .halt_reg = 0xf018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xf018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_prim_mock_utmi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_prim_sleep_clk = {
+       .halt_reg = 0xf014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xf014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_prim_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_sec_master_clk = {
+       .halt_reg = 0x10010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x10010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_sec_master_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_usb30_sec_master_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_sec_mock_utmi_clk = {
+       .halt_reg = 0x10018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x10018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_sec_mock_utmi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_usb30_sec_mock_utmi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_sec_sleep_clk = {
+       .halt_reg = 0x10014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x10014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_sec_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_prim_clkref_clk = {
+       .halt_reg = 0x8c008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8c008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_clkref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_prim_phy_aux_clk = {
+       .halt_reg = 0xf050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xf050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_phy_aux_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_usb3_prim_phy_aux_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = {
+       .halt_reg = 0xf054,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xf054,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_phy_com_aux_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_usb3_prim_phy_aux_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_sec_clkref_clk = {
+       .halt_reg = 0x8c028,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8c028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_sec_clkref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_sec_phy_aux_clk = {
+       .halt_reg = 0x10050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x10050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_sec_phy_aux_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_usb3_sec_phy_aux_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_sec_phy_com_aux_clk = {
+       .halt_reg = 0x10054,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x10054,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_sec_phy_com_aux_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                     &gcc_usb3_sec_phy_aux_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+/*
+ * Clock ON depends on external parent 'config noc', so cant poll
+ * delay and also mark as crtitical for video boot
+ */
+static struct clk_branch gcc_video_ahb_clk = {
+       .halt_reg = 0xb004,
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0xb004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0xb004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_ahb_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_axi0_clk = {
+       .halt_reg = 0xb024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_axi0_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_axi1_clk = {
+       .halt_reg = 0xb028,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_axi1_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_axic_clk = {
+       .halt_reg = 0xb02c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb02c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_axic_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+/* XO critical input to video, so no need to poll */
+static struct clk_branch gcc_video_xo_clk = {
+       .halt_reg = 0xb040,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0xb040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_xo_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_regmap *gcc_sm8150_clocks[] = {
+       [GCC_AGGRE_NOC_PCIE_TBU_CLK] = &gcc_aggre_noc_pcie_tbu_clk.clkr,
+       [GCC_AGGRE_UFS_CARD_AXI_CLK] = &gcc_aggre_ufs_card_axi_clk.clkr,
+       [GCC_AGGRE_UFS_CARD_AXI_HW_CTL_CLK] =
+               &gcc_aggre_ufs_card_axi_hw_ctl_clk.clkr,
+       [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr,
+       [GCC_AGGRE_UFS_PHY_AXI_HW_CTL_CLK] =
+               &gcc_aggre_ufs_phy_axi_hw_ctl_clk.clkr,
+       [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr,
+       [GCC_AGGRE_USB3_SEC_AXI_CLK] = &gcc_aggre_usb3_sec_axi_clk.clkr,
+       [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
+       [GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr,
+       [GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr,
+       [GCC_CAMERA_SF_AXI_CLK] = &gcc_camera_sf_axi_clk.clkr,
+       [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr,
+       [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr,
+       [GCC_CFG_NOC_USB3_SEC_AXI_CLK] = &gcc_cfg_noc_usb3_sec_axi_clk.clkr,
+       [GCC_CPUSS_AHB_CLK] = &gcc_cpuss_ahb_clk.clkr,
+       [GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr,
+       [GCC_CPUSS_DVM_BUS_CLK] = &gcc_cpuss_dvm_bus_clk.clkr,
+       [GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr,
+       [GCC_CPUSS_RBCPR_CLK] = &gcc_cpuss_rbcpr_clk.clkr,
+       [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr,
+       [GCC_DISP_AHB_CLK] = &gcc_disp_ahb_clk.clkr,
+       [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr,
+       [GCC_DISP_SF_AXI_CLK] = &gcc_disp_sf_axi_clk.clkr,
+       [GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr,
+       [GCC_EMAC_AXI_CLK] = &gcc_emac_axi_clk.clkr,
+       [GCC_EMAC_PTP_CLK] = &gcc_emac_ptp_clk.clkr,
+       [GCC_EMAC_PTP_CLK_SRC] = &gcc_emac_ptp_clk_src.clkr,
+       [GCC_EMAC_RGMII_CLK] = &gcc_emac_rgmii_clk.clkr,
+       [GCC_EMAC_RGMII_CLK_SRC] = &gcc_emac_rgmii_clk_src.clkr,
+       [GCC_EMAC_SLV_AHB_CLK] = &gcc_emac_slv_ahb_clk.clkr,
+       [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+       [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr,
+       [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+       [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr,
+       [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+       [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr,
+       [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr,
+       [GCC_GPU_IREF_CLK] = &gcc_gpu_iref_clk.clkr,
+       [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr,
+       [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr,
+       [GCC_NPU_AT_CLK] = &gcc_npu_at_clk.clkr,
+       [GCC_NPU_AXI_CLK] = &gcc_npu_axi_clk.clkr,
+       [GCC_NPU_CFG_AHB_CLK] = &gcc_npu_cfg_ahb_clk.clkr,
+       [GCC_NPU_TRIG_CLK] = &gcc_npu_trig_clk.clkr,
+       [GCC_PCIE0_PHY_REFGEN_CLK] = &gcc_pcie0_phy_refgen_clk.clkr,
+       [GCC_PCIE1_PHY_REFGEN_CLK] = &gcc_pcie1_phy_refgen_clk.clkr,
+       [GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr,
+       [GCC_PCIE_0_AUX_CLK_SRC] = &gcc_pcie_0_aux_clk_src.clkr,
+       [GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr,
+       [GCC_PCIE_0_CLKREF_CLK] = &gcc_pcie_0_clkref_clk.clkr,
+       [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr,
+       [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr,
+       [GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr,
+       [GCC_PCIE_0_SLV_Q2A_AXI_CLK] = &gcc_pcie_0_slv_q2a_axi_clk.clkr,
+       [GCC_PCIE_1_AUX_CLK] = &gcc_pcie_1_aux_clk.clkr,
+       [GCC_PCIE_1_AUX_CLK_SRC] = &gcc_pcie_1_aux_clk_src.clkr,
+       [GCC_PCIE_1_CFG_AHB_CLK] = &gcc_pcie_1_cfg_ahb_clk.clkr,
+       [GCC_PCIE_1_CLKREF_CLK] = &gcc_pcie_1_clkref_clk.clkr,
+       [GCC_PCIE_1_MSTR_AXI_CLK] = &gcc_pcie_1_mstr_axi_clk.clkr,
+       [GCC_PCIE_1_PIPE_CLK] = &gcc_pcie_1_pipe_clk.clkr,
+       [GCC_PCIE_1_SLV_AXI_CLK] = &gcc_pcie_1_slv_axi_clk.clkr,
+       [GCC_PCIE_1_SLV_Q2A_AXI_CLK] = &gcc_pcie_1_slv_q2a_axi_clk.clkr,
+       [GCC_PCIE_PHY_AUX_CLK] = &gcc_pcie_phy_aux_clk.clkr,
+       [GCC_PCIE_PHY_REFGEN_CLK_SRC] = &gcc_pcie_phy_refgen_clk_src.clkr,
+       [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
+       [GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr,
+       [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
+       [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr,
+       [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+       [GCC_QMIP_CAMERA_NRT_AHB_CLK] = &gcc_qmip_camera_nrt_ahb_clk.clkr,
+       [GCC_QMIP_CAMERA_RT_AHB_CLK] = &gcc_qmip_camera_rt_ahb_clk.clkr,
+       [GCC_QMIP_DISP_AHB_CLK] = &gcc_qmip_disp_ahb_clk.clkr,
+       [GCC_QMIP_VIDEO_CVP_AHB_CLK] = &gcc_qmip_video_cvp_ahb_clk.clkr,
+       [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr,
+       [GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr,
+       [GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr,
+       [GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.clkr,
+       [GCC_QUPV3_WRAP0_S0_CLK_SRC] = &gcc_qupv3_wrap0_s0_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.clkr,
+       [GCC_QUPV3_WRAP0_S1_CLK_SRC] = &gcc_qupv3_wrap0_s1_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S2_CLK] = &gcc_qupv3_wrap0_s2_clk.clkr,
+       [GCC_QUPV3_WRAP0_S2_CLK_SRC] = &gcc_qupv3_wrap0_s2_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S3_CLK] = &gcc_qupv3_wrap0_s3_clk.clkr,
+       [GCC_QUPV3_WRAP0_S3_CLK_SRC] = &gcc_qupv3_wrap0_s3_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S4_CLK] = &gcc_qupv3_wrap0_s4_clk.clkr,
+       [GCC_QUPV3_WRAP0_S4_CLK_SRC] = &gcc_qupv3_wrap0_s4_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S5_CLK] = &gcc_qupv3_wrap0_s5_clk.clkr,
+       [GCC_QUPV3_WRAP0_S5_CLK_SRC] = &gcc_qupv3_wrap0_s5_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S6_CLK] = &gcc_qupv3_wrap0_s6_clk.clkr,
+       [GCC_QUPV3_WRAP0_S6_CLK_SRC] = &gcc_qupv3_wrap0_s6_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S7_CLK] = &gcc_qupv3_wrap0_s7_clk.clkr,
+       [GCC_QUPV3_WRAP0_S7_CLK_SRC] = &gcc_qupv3_wrap0_s7_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S0_CLK] = &gcc_qupv3_wrap1_s0_clk.clkr,
+       [GCC_QUPV3_WRAP1_S0_CLK_SRC] = &gcc_qupv3_wrap1_s0_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S1_CLK] = &gcc_qupv3_wrap1_s1_clk.clkr,
+       [GCC_QUPV3_WRAP1_S1_CLK_SRC] = &gcc_qupv3_wrap1_s1_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S2_CLK] = &gcc_qupv3_wrap1_s2_clk.clkr,
+       [GCC_QUPV3_WRAP1_S2_CLK_SRC] = &gcc_qupv3_wrap1_s2_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S3_CLK] = &gcc_qupv3_wrap1_s3_clk.clkr,
+       [GCC_QUPV3_WRAP1_S3_CLK_SRC] = &gcc_qupv3_wrap1_s3_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S4_CLK] = &gcc_qupv3_wrap1_s4_clk.clkr,
+       [GCC_QUPV3_WRAP1_S4_CLK_SRC] = &gcc_qupv3_wrap1_s4_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S5_CLK] = &gcc_qupv3_wrap1_s5_clk.clkr,
+       [GCC_QUPV3_WRAP1_S5_CLK_SRC] = &gcc_qupv3_wrap1_s5_clk_src.clkr,
+       [GCC_QUPV3_WRAP2_S0_CLK] = &gcc_qupv3_wrap2_s0_clk.clkr,
+       [GCC_QUPV3_WRAP2_S0_CLK_SRC] = &gcc_qupv3_wrap2_s0_clk_src.clkr,
+       [GCC_QUPV3_WRAP2_S1_CLK] = &gcc_qupv3_wrap2_s1_clk.clkr,
+       [GCC_QUPV3_WRAP2_S1_CLK_SRC] = &gcc_qupv3_wrap2_s1_clk_src.clkr,
+       [GCC_QUPV3_WRAP2_S2_CLK] = &gcc_qupv3_wrap2_s2_clk.clkr,
+       [GCC_QUPV3_WRAP2_S2_CLK_SRC] = &gcc_qupv3_wrap2_s2_clk_src.clkr,
+       [GCC_QUPV3_WRAP2_S3_CLK] = &gcc_qupv3_wrap2_s3_clk.clkr,
+       [GCC_QUPV3_WRAP2_S3_CLK_SRC] = &gcc_qupv3_wrap2_s3_clk_src.clkr,
+       [GCC_QUPV3_WRAP2_S4_CLK] = &gcc_qupv3_wrap2_s4_clk.clkr,
+       [GCC_QUPV3_WRAP2_S4_CLK_SRC] = &gcc_qupv3_wrap2_s4_clk_src.clkr,
+       [GCC_QUPV3_WRAP2_S5_CLK] = &gcc_qupv3_wrap2_s5_clk.clkr,
+       [GCC_QUPV3_WRAP2_S5_CLK_SRC] = &gcc_qupv3_wrap2_s5_clk_src.clkr,
+       [GCC_QUPV3_WRAP_0_M_AHB_CLK] = &gcc_qupv3_wrap_0_m_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP_0_S_AHB_CLK] = &gcc_qupv3_wrap_0_s_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP_1_M_AHB_CLK] = &gcc_qupv3_wrap_1_m_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP_2_M_AHB_CLK] = &gcc_qupv3_wrap_2_m_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP_2_S_AHB_CLK] = &gcc_qupv3_wrap_2_s_ahb_clk.clkr,
+       [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
+       [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
+       [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr,
+       [GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr,
+       [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr,
+       [GCC_SDCC4_APPS_CLK_SRC] = &gcc_sdcc4_apps_clk_src.clkr,
+       [GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr,
+       [GCC_TSIF_AHB_CLK] = &gcc_tsif_ahb_clk.clkr,
+       [GCC_TSIF_INACTIVITY_TIMERS_CLK] = &gcc_tsif_inactivity_timers_clk.clkr,
+       [GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr,
+       [GCC_TSIF_REF_CLK_SRC] = &gcc_tsif_ref_clk_src.clkr,
+       [GCC_UFS_CARD_AHB_CLK] = &gcc_ufs_card_ahb_clk.clkr,
+       [GCC_UFS_CARD_AXI_CLK] = &gcc_ufs_card_axi_clk.clkr,
+       [GCC_UFS_CARD_AXI_CLK_SRC] = &gcc_ufs_card_axi_clk_src.clkr,
+       [GCC_UFS_CARD_AXI_HW_CTL_CLK] = &gcc_ufs_card_axi_hw_ctl_clk.clkr,
+       [GCC_UFS_CARD_CLKREF_CLK] = &gcc_ufs_card_clkref_clk.clkr,
+       [GCC_UFS_CARD_ICE_CORE_CLK] = &gcc_ufs_card_ice_core_clk.clkr,
+       [GCC_UFS_CARD_ICE_CORE_CLK_SRC] = &gcc_ufs_card_ice_core_clk_src.clkr,
+       [GCC_UFS_CARD_ICE_CORE_HW_CTL_CLK] =
+               &gcc_ufs_card_ice_core_hw_ctl_clk.clkr,
+       [GCC_UFS_CARD_PHY_AUX_CLK] = &gcc_ufs_card_phy_aux_clk.clkr,
+       [GCC_UFS_CARD_PHY_AUX_CLK_SRC] = &gcc_ufs_card_phy_aux_clk_src.clkr,
+       [GCC_UFS_CARD_PHY_AUX_HW_CTL_CLK] =
+               &gcc_ufs_card_phy_aux_hw_ctl_clk.clkr,
+       [GCC_UFS_CARD_UNIPRO_CORE_CLK] = &gcc_ufs_card_unipro_core_clk.clkr,
+       [GCC_UFS_CARD_UNIPRO_CORE_CLK_SRC] =
+               &gcc_ufs_card_unipro_core_clk_src.clkr,
+       [GCC_UFS_CARD_UNIPRO_CORE_HW_CTL_CLK] =
+               &gcc_ufs_card_unipro_core_hw_ctl_clk.clkr,
+       [GCC_UFS_MEM_CLKREF_CLK] = &gcc_ufs_mem_clkref_clk.clkr,
+       [GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr,
+       [GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr,
+       [GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr,
+       [GCC_UFS_PHY_AXI_HW_CTL_CLK] = &gcc_ufs_phy_axi_hw_ctl_clk.clkr,
+       [GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr,
+       [GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr,
+       [GCC_UFS_PHY_ICE_CORE_HW_CTL_CLK] =
+               &gcc_ufs_phy_ice_core_hw_ctl_clk.clkr,
+       [GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr,
+       [GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr,
+       [GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK] = &gcc_ufs_phy_phy_aux_hw_ctl_clk.clkr,
+       [GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr,
+       [GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] =
+               &gcc_ufs_phy_unipro_core_clk_src.clkr,
+       [GCC_UFS_PHY_UNIPRO_CORE_HW_CTL_CLK] =
+               &gcc_ufs_phy_unipro_core_hw_ctl_clk.clkr,
+       [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr,
+       [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr,
+       [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr,
+       [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] =
+               &gcc_usb30_prim_mock_utmi_clk_src.clkr,
+       [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr,
+       [GCC_USB30_SEC_MASTER_CLK] = &gcc_usb30_sec_master_clk.clkr,
+       [GCC_USB30_SEC_MASTER_CLK_SRC] = &gcc_usb30_sec_master_clk_src.clkr,
+       [GCC_USB30_SEC_MOCK_UTMI_CLK] = &gcc_usb30_sec_mock_utmi_clk.clkr,
+       [GCC_USB30_SEC_MOCK_UTMI_CLK_SRC] =
+               &gcc_usb30_sec_mock_utmi_clk_src.clkr,
+       [GCC_USB30_SEC_SLEEP_CLK] = &gcc_usb30_sec_sleep_clk.clkr,
+       [GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_clk.clkr,
+       [GCC_USB3_PRIM_PHY_AUX_CLK] = &gcc_usb3_prim_phy_aux_clk.clkr,
+       [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr,
+       [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr,
+       [GCC_USB3_SEC_CLKREF_CLK] = &gcc_usb3_sec_clkref_clk.clkr,
+       [GCC_USB3_SEC_PHY_AUX_CLK] = &gcc_usb3_sec_phy_aux_clk.clkr,
+       [GCC_USB3_SEC_PHY_AUX_CLK_SRC] = &gcc_usb3_sec_phy_aux_clk_src.clkr,
+       [GCC_USB3_SEC_PHY_COM_AUX_CLK] = &gcc_usb3_sec_phy_com_aux_clk.clkr,
+       [GCC_VIDEO_AHB_CLK] = &gcc_video_ahb_clk.clkr,
+       [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr,
+       [GCC_VIDEO_AXI1_CLK] = &gcc_video_axi1_clk.clkr,
+       [GCC_VIDEO_AXIC_CLK] = &gcc_video_axic_clk.clkr,
+       [GCC_VIDEO_XO_CLK] = &gcc_video_xo_clk.clkr,
+       [GPLL0] = &gpll0.clkr,
+       [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr,
+       [GPLL7] = &gpll7.clkr,
+       [GPLL9] = &gpll9.clkr,
+};
+
+static const struct qcom_reset_map gcc_sm8150_resets[] = {
+       [GCC_EMAC_BCR] = { 0x6000 },
+       [GCC_GPU_BCR] = { 0x71000 },
+       [GCC_MMSS_BCR] = { 0xb000 },
+       [GCC_NPU_BCR] = { 0x4d000 },
+       [GCC_PCIE_0_BCR] = { 0x6b000 },
+       [GCC_PCIE_0_PHY_BCR] = { 0x6c01c },
+       [GCC_PCIE_1_BCR] = { 0x8d000 },
+       [GCC_PCIE_1_PHY_BCR] = { 0x8e01c },
+       [GCC_PCIE_PHY_BCR] = { 0x6f000 },
+       [GCC_PDM_BCR] = { 0x33000 },
+       [GCC_PRNG_BCR] = { 0x34000 },
+       [GCC_QSPI_BCR] = { 0x24008 },
+       [GCC_QUPV3_WRAPPER_0_BCR] = { 0x17000 },
+       [GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 },
+       [GCC_QUPV3_WRAPPER_2_BCR] = { 0x1e000 },
+       [GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 },
+       [GCC_QUSB2PHY_SEC_BCR] = { 0x12004 },
+       [GCC_USB3_PHY_PRIM_BCR] = { 0x50000 },
+       [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 },
+       [GCC_USB3_PHY_SEC_BCR] = { 0x5000c },
+       [GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 },
+       [GCC_SDCC2_BCR] = { 0x14000 },
+       [GCC_SDCC4_BCR] = { 0x16000 },
+       [GCC_TSIF_BCR] = { 0x36000 },
+       [GCC_UFS_CARD_BCR] = { 0x75000 },
+       [GCC_UFS_PHY_BCR] = { 0x77000 },
+       [GCC_USB30_PRIM_BCR] = { 0xf000 },
+       [GCC_USB30_SEC_BCR] = { 0x10000 },
+       [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 },
+};
+
+static const struct regmap_config gcc_sm8150_regmap_config = {
+       .reg_bits       = 32,
+       .reg_stride     = 4,
+       .val_bits       = 32,
+       .max_register   = 0x9c040,
+       .fast_io        = true,
+};
+
+static const struct qcom_cc_desc gcc_sm8150_desc = {
+       .config = &gcc_sm8150_regmap_config,
+       .clks = gcc_sm8150_clocks,
+       .num_clks = ARRAY_SIZE(gcc_sm8150_clocks),
+       .resets = gcc_sm8150_resets,
+       .num_resets = ARRAY_SIZE(gcc_sm8150_resets),
+};
+
+static const struct of_device_id gcc_sm8150_match_table[] = {
+       { .compatible = "qcom,gcc-sm8150" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gcc_sm8150_match_table);
+
+static int gcc_sm8150_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+
+       regmap = qcom_cc_map(pdev, &gcc_sm8150_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       /* Disable the GPLL0 active input to NPU and GPU via MISC registers */
+       regmap_update_bits(regmap, 0x4d110, 0x3, 0x3);
+       regmap_update_bits(regmap, 0x71028, 0x3, 0x3);
+
+       return qcom_cc_really_probe(pdev, &gcc_sm8150_desc, regmap);
+}
+
+static struct platform_driver gcc_sm8150_driver = {
+       .probe          = gcc_sm8150_probe,
+       .driver         = {
+               .name   = "gcc-sm8150",
+               .of_match_table = gcc_sm8150_match_table,
+       },
+};
+
+static int __init gcc_sm8150_init(void)
+{
+       return platform_driver_register(&gcc_sm8150_driver);
+}
+subsys_initcall(gcc_sm8150_init);
+
+static void __exit gcc_sm8150_exit(void)
+{
+       platform_driver_unregister(&gcc_sm8150_driver);
+}
+module_exit(gcc_sm8150_exit);
+
+MODULE_DESCRIPTION("QTI GCC SM8150 Driver");
+MODULE_LICENSE("GPL v2");
index e246b99dfbc6d590862563962cee44c47f170c1b..56d3e99288921ac8d5b8fef8a551a4ed382f9984 100644 (file)
@@ -112,25 +112,6 @@ static const struct qcom_cc_desc lpass_qdsp6ss_sdm845_desc = {
        .num_clks = ARRAY_SIZE(lpass_qdsp6ss_sdm845_clocks),
 };
 
-static int lpass_clocks_sdm845_probe(struct platform_device *pdev, int index,
-                                    const struct qcom_cc_desc *desc)
-{
-       struct regmap *regmap;
-       struct resource *res;
-       void __iomem *base;
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, index);
-       base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(base))
-               return PTR_ERR(base);
-
-       regmap = devm_regmap_init_mmio(&pdev->dev, base, desc->config);
-       if (IS_ERR(regmap))
-               return PTR_ERR(regmap);
-
-       return qcom_cc_really_probe(pdev, desc, regmap);
-}
-
 static int lpass_cc_sdm845_probe(struct platform_device *pdev)
 {
        const struct qcom_cc_desc *desc;
@@ -139,14 +120,14 @@ static int lpass_cc_sdm845_probe(struct platform_device *pdev)
        lpass_regmap_config.name = "cc";
        desc = &lpass_cc_sdm845_desc;
 
-       ret = lpass_clocks_sdm845_probe(pdev, 0, desc);
+       ret = qcom_cc_probe_by_index(pdev, 0, desc);
        if (ret)
                return ret;
 
        lpass_regmap_config.name = "qdsp6ss";
        desc = &lpass_qdsp6ss_sdm845_desc;
 
-       return lpass_clocks_sdm845_probe(pdev, 1, desc);
+       return qcom_cc_probe_by_index(pdev, 1, desc);
 }
 
 static const struct of_device_id lpass_cc_sdm845_match_table[] = {
index aa859e6ec9bd2bac615349c94f4a329dae7095b0..4cfbbf5bf4d90e08b8e8a039b7ef47938f86373c 100644 (file)
@@ -96,7 +96,7 @@ static const struct regmap_config turingcc_regmap_config = {
        .reg_bits       = 32,
        .reg_stride     = 4,
        .val_bits       = 32,
-       .max_register   = 0x30000,
+       .max_register   = 0x23004,
        .fast_io        = true,
 };
 
index 2db9093546c603f749caf48b9ffb35747c978aac..e326e6dc09fce67b795926fa0af072bc3c70d9e4 100644 (file)
@@ -334,7 +334,8 @@ void __init cpg_mstp_add_clk_domain(struct device_node *np)
                return;
 
        pd->name = np->name;
-       pd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP;
+       pd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON |
+                   GENPD_FLAG_ACTIVE_WAKEUP;
        pd->attach_dev = cpg_mstp_attach_dev;
        pd->detach_dev = cpg_mstp_detach_dev;
        pm_genpd_init(pd, &pm_domain_always_on_gov, false);
index b33e1383efe3abcd6f886ee06630f0386f7a2816..1907ee195a08cf77525720e0075fbd7ea2b5f2c9 100644 (file)
@@ -421,7 +421,8 @@ static int r9a06g032_add_clk_domain(struct device *dev)
                return -ENOMEM;
 
        pd->name = np->name;
-       pd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP;
+       pd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON |
+                   GENPD_FLAG_ACTIVE_WAKEUP;
        pd->attach_dev = r9a06g032_attach_dev;
        pd->detach_dev = r9a06g032_detach_dev;
        pm_genpd_init(pd, &pm_domain_always_on_gov, false);
index cc90b11a9c250a0a243e424c94e2106c21d60802..b97f5f9326cfc709ed91a8b9008c8fd7b935b491 100644 (file)
@@ -117,7 +117,6 @@ static int rcar_usb2_clock_sel_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct device_node *np = dev->of_node;
        struct usb2_clock_sel_priv *priv;
-       struct resource *res;
        struct clk *clk;
        struct clk_init_data init;
 
@@ -125,8 +124,7 @@ static int rcar_usb2_clock_sel_probe(struct platform_device *pdev)
        if (!priv)
                return -ENOMEM;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       priv->base = devm_ioremap_resource(dev, res);
+       priv->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(priv->base))
                return PTR_ERR(priv->base);
 
index 52bbb9ce3807db3164b0a1b6fc0eba9b903e8156..cc39c8fff8a1a7d99387a39f39e0a707397e45cb 100644 (file)
@@ -551,7 +551,8 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev,
 
        genpd = &pd->genpd;
        genpd->name = np->name;
-       genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP;
+       genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON |
+                      GENPD_FLAG_ACTIVE_WAKEUP;
        genpd->attach_dev = cpg_mssr_attach_dev;
        genpd->detach_dev = cpg_mssr_detach_dev;
        pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
index ad7951b6b285eb1ee253620ecc97a9003e9f2df0..dcf4e25a02168501d71811f82d255bfc303e187c 100644 (file)
@@ -297,9 +297,10 @@ static u8 dmn_clk_get_parent(struct clk_hw *hw)
 {
        struct clk_dmn *clk = to_dmnclk(hw);
        u32 cfg = clkc_readl(clk->regofs);
+       const char *name = clk_hw_get_name(hw);
 
        /* parent of io domain can only be pll3 */
-       if (strcmp(hw->init->name, "io") == 0)
+       if (strcmp(name, "io") == 0)
                return 4;
 
        WARN_ON((cfg & (BIT(3) - 1)) > 4);
@@ -311,9 +312,10 @@ static int dmn_clk_set_parent(struct clk_hw *hw, u8 parent)
 {
        struct clk_dmn *clk = to_dmnclk(hw);
        u32 cfg = clkc_readl(clk->regofs);
+       const char *name = clk_hw_get_name(hw);
 
        /* parent of io domain can only be pll3 */
-       if (strcmp(hw->init->name, "io") == 0)
+       if (strcmp(name, "io") == 0)
                return -EINVAL;
 
        cfg &= ~(BIT(3) - 1);
@@ -353,7 +355,8 @@ static long dmn_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 {
        unsigned long fin;
        unsigned ratio, wait, hold;
-       unsigned bits = (strcmp(hw->init->name, "mem") == 0) ? 3 : 4;
+       const char *name = clk_hw_get_name(hw);
+       unsigned bits = (strcmp(name, "mem") == 0) ? 3 : 4;
 
        fin = *parent_rate;
        ratio = fin / rate;
@@ -375,7 +378,8 @@ static int dmn_clk_set_rate(struct clk_hw *hw, unsigned long rate,
        struct clk_dmn *clk = to_dmnclk(hw);
        unsigned long fin;
        unsigned ratio, wait, hold, reg;
-       unsigned bits = (strcmp(hw->init->name, "mem") == 0) ? 3 : 4;
+       const char *name = clk_hw_get_name(hw);
+       unsigned bits = (strcmp(name, "mem") == 0) ? 3 : 4;
 
        fin = parent_rate;
        ratio = fin / rate;
index 3966cd43b5527397325ed98eb3f0d76afa860a4c..43ecd507bf836b77e4a9a754499dd3eb3199d28b 100644 (file)
@@ -30,22 +30,23 @@ static u8 socfpga_clk_get_parent(struct clk_hw *hwclk)
 {
        u32 l4_src;
        u32 perpll_src;
+       const char *name = clk_hw_get_name(hwclk);
 
-       if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) {
+       if (streq(name, SOCFPGA_L4_MP_CLK)) {
                l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
                return l4_src &= 0x1;
        }
-       if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) {
+       if (streq(name, SOCFPGA_L4_SP_CLK)) {
                l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
                return !!(l4_src & 2);
        }
 
        perpll_src = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
-       if (streq(hwclk->init->name, SOCFPGA_MMC_CLK))
+       if (streq(name, SOCFPGA_MMC_CLK))
                return perpll_src &= 0x3;
-       if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) ||
-                       streq(hwclk->init->name, SOCFPGA_NAND_X_CLK))
-                       return (perpll_src >> 2) & 3;
+       if (streq(name, SOCFPGA_NAND_CLK) ||
+           streq(name, SOCFPGA_NAND_X_CLK))
+               return (perpll_src >> 2) & 3;
 
        /* QSPI clock */
        return (perpll_src >> 4) & 3;
@@ -55,24 +56,25 @@ static u8 socfpga_clk_get_parent(struct clk_hw *hwclk)
 static int socfpga_clk_set_parent(struct clk_hw *hwclk, u8 parent)
 {
        u32 src_reg;
+       const char *name = clk_hw_get_name(hwclk);
 
-       if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) {
+       if (streq(name, SOCFPGA_L4_MP_CLK)) {
                src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
                src_reg &= ~0x1;
                src_reg |= parent;
                writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC);
-       } else if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) {
+       } else if (streq(name, SOCFPGA_L4_SP_CLK)) {
                src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
                src_reg &= ~0x2;
                src_reg |= (parent << 1);
                writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC);
        } else {
                src_reg = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
-               if (streq(hwclk->init->name, SOCFPGA_MMC_CLK)) {
+               if (streq(name, SOCFPGA_MMC_CLK)) {
                        src_reg &= ~0x3;
                        src_reg |= parent;
-               } else if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) ||
-                       streq(hwclk->init->name, SOCFPGA_NAND_X_CLK)) {
+               } else if (streq(name, SOCFPGA_NAND_CLK) ||
+                       streq(name, SOCFPGA_NAND_X_CLK)) {
                        src_reg &= ~0xC;
                        src_reg |= (parent << 2);
                } else {/* QSPI clock */
index a8ff7229611d98a773407c0888bf13bf214c6f53..3e0c55727b89cf7b720652393436cf49ea1c2423 100644 (file)
@@ -40,11 +40,12 @@ static u8 clk_periclk_get_parent(struct clk_hw *hwclk)
 {
        struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(hwclk);
        u32 clk_src;
+       const char *name = clk_hw_get_name(hwclk);
 
        clk_src = readl(socfpgaclk->hw.reg);
-       if (streq(hwclk->init->name, SOCFPGA_MPU_FREE_CLK) ||
-           streq(hwclk->init->name, SOCFPGA_NOC_FREE_CLK) ||
-           streq(hwclk->init->name, SOCFPGA_SDMMC_FREE_CLK))
+       if (streq(name, SOCFPGA_MPU_FREE_CLK) ||
+           streq(name, SOCFPGA_NOC_FREE_CLK) ||
+           streq(name, SOCFPGA_SDMMC_FREE_CLK))
                return (clk_src >> CLK_MGR_FREE_SHIFT) &
                        CLK_MGR_FREE_MASK;
        else
index e5bc8c828cf0d84a420fd087ae726d961f5f05c2..9163bbb464112e46973eb958d48babaea4673250 100644 (file)
@@ -335,7 +335,7 @@ static const struct aux_clk_masks i2s_prs1_masks = {
 };
 
 /* i2s sclk (bit clock) syynthesizers masks */
-static struct aux_clk_masks i2s_sclk_masks = {
+static const struct aux_clk_masks i2s_sclk_masks = {
        .eq_sel_mask = AUX_EQ_SEL_MASK,
        .eq_sel_shift = SPEAR1340_I2S_SCLK_EQ_SEL_SHIFT,
        .eq1_mask = AUX_EQ1_SEL,
index a5bdca1de5d074efba6985ad3fb5915c223e126a..9d56eac43832acc1f00b85d72a9946f6b3f67fd7 100644 (file)
@@ -76,16 +76,17 @@ int sprd_clk_probe(struct device *dev, struct clk_hw_onecell_data *clkhw)
        struct clk_hw *hw;
 
        for (i = 0; i < clkhw->num; i++) {
+               const char *name;
 
                hw = clkhw->hws[i];
-
                if (!hw)
                        continue;
 
+               name = hw->init->name;
                ret = devm_clk_hw_register(dev, hw);
                if (ret) {
                        dev_err(dev, "Couldn't register clock %d - %s\n",
-                               i, hw->init->name);
+                               i, name);
                        return ret;
                }
        }
index d18e49b4976f5377726f14a145c910e1df451a3d..4413b6e04a8ecb157883b54b650f1cb12602efff 100644 (file)
@@ -326,6 +326,7 @@ static void __init st_of_flexgen_setup(struct device_node *np)
                return;
 
        reg = of_iomap(pnode, 0);
+       of_node_put(pnode);
        if (!reg)
                return;
 
index ca1ccdb8a3b18aadfb3e0e37551fcf910f331c2c..a156bd0c6af751f421e2e9bac15396cfaf980a7c 100644 (file)
@@ -67,7 +67,6 @@ struct clkgen_quadfs_data {
 };
 
 static const struct clk_ops st_quadfs_pll_c32_ops;
-static const struct clk_ops st_quadfs_fs660c32_ops;
 
 static int clk_fs660c32_dig_get_params(unsigned long input,
                unsigned long output, struct stm_fs *fs);
index d8a688bd45ecf11267f90138d0c46047c6ea178a..c3952f2c42ba26da19a904cfd878b2a9f83834fa 100644 (file)
@@ -61,19 +61,6 @@ static const struct clk_ops stm_pll3200c32_ops;
 static const struct clk_ops stm_pll3200c32_a9_ops;
 static const struct clk_ops stm_pll4600c28_ops;
 
-static const struct clkgen_pll_data st_pll3200c32_407_a0 = {
-       /* 407 A0 */
-       .pdn_status     = CLKGEN_FIELD(0x2a0,   0x1,                    8),
-       .pdn_ctrl       = CLKGEN_FIELD(0x2a0,   0x1,                    8),
-       .locked_status  = CLKGEN_FIELD(0x2a0,   0x1,                    24),
-       .ndiv           = CLKGEN_FIELD(0x2a4,   C32_NDIV_MASK,          16),
-       .idf            = CLKGEN_FIELD(0x2a4,   C32_IDF_MASK,           0x0),
-       .num_odfs = 1,
-       .odf            = { CLKGEN_FIELD(0x2b4, C32_ODF_MASK,           0) },
-       .odf_gate       = { CLKGEN_FIELD(0x2b4, 0x1,                    6) },
-       .ops            = &stm_pll3200c32_ops,
-};
-
 static const struct clkgen_pll_data st_pll3200c32_cx_0 = {
        /* 407 C0 PLL0 */
        .pdn_status     = CLKGEN_FIELD(0x2a0,   0x1,                    8),
index aebef4af98613fc052d481351db48cdf1720228a..d89353a3cdec72beb67859f55acacfe4320a0902 100644 (file)
@@ -505,7 +505,7 @@ static struct ccu_div i2s3_clk = {
                .hw.init        = CLK_HW_INIT_PARENTS("i2s3",
                                                      audio_parents,
                                                      &ccu_div_ops,
-                                                     0),
+                                                     CLK_SET_RATE_PARENT),
        },
 };
 
@@ -518,7 +518,7 @@ static struct ccu_div i2s0_clk = {
                .hw.init        = CLK_HW_INIT_PARENTS("i2s0",
                                                      audio_parents,
                                                      &ccu_div_ops,
-                                                     0),
+                                                     CLK_SET_RATE_PARENT),
        },
 };
 
@@ -531,7 +531,7 @@ static struct ccu_div i2s1_clk = {
                .hw.init        = CLK_HW_INIT_PARENTS("i2s1",
                                                      audio_parents,
                                                      &ccu_div_ops,
-                                                     0),
+                                                     CLK_SET_RATE_PARENT),
        },
 };
 
@@ -544,7 +544,7 @@ static struct ccu_div i2s2_clk = {
                .hw.init        = CLK_HW_INIT_PARENTS("i2s2",
                                                      audio_parents,
                                                      &ccu_div_ops,
-                                                     0),
+                                                     CLK_SET_RATE_PARENT),
        },
 };
 
index 9b3939fc7faa614a87413685f597f41812c8eb76..5c779eec454b6edc734ced3a9fd7d5b1a020f4de 100644 (file)
@@ -77,7 +77,7 @@ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
                                        BIT(28),        /* lock */
                                        0);
 
-static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr",
+static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr0_clk, "pll-ddr0",
                                    "osc24M", 0x020,
                                    8, 5,       /* N */
                                    4, 2,       /* K */
@@ -116,6 +116,14 @@ static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph1_clk, "pll-periph1",
                                           2,           /* post-div */
                                           0);
 
+static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_ddr1_clk, "pll-ddr1",
+                                  "osc24M", 0x04c,
+                                  8, 7,        /* N */
+                                  0, 2,        /* M */
+                                  BIT(31),     /* gate */
+                                  BIT(28),     /* lock */
+                                  0);
+
 static const char * const cpu_parents[] = { "osc32k", "osc24M",
                                             "pll-cpu", "pll-cpu" };
 static SUNXI_CCU_MUX(cpu_clk, "cpu", cpu_parents,
@@ -227,6 +235,8 @@ static SUNXI_CCU_GATE(bus_codec_clk,        "bus-codec",    "apb1",
                      0x068, BIT(0), 0);
 static SUNXI_CCU_GATE(bus_pio_clk,     "bus-pio",      "apb1",
                      0x068, BIT(5), 0);
+static SUNXI_CCU_GATE(bus_i2s0_clk,    "bus-i2s0",     "apb1",
+                     0x068, BIT(12), 0);
 
 static SUNXI_CCU_GATE(bus_i2c0_clk,    "bus-i2c0",     "apb2",
                      0x06c, BIT(0), 0);
@@ -298,12 +308,18 @@ static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
                                  BIT(31),      /* gate */
                                  0);
 
+static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
+                                           "pll-audio-2x", "pll-audio" };
+static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents,
+                              0x0b0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
+
 static SUNXI_CCU_GATE(usb_phy0_clk,    "usb-phy0",     "osc24M",
                      0x0cc, BIT(8), 0);
 static SUNXI_CCU_GATE(usb_ohci0_clk,   "usb-ohci0",    "osc24M",
                      0x0cc, BIT(16), 0);
 
-static const char * const dram_parents[] = { "pll-ddr", "pll-periph0-2x" };
+static const char * const dram_parents[] = { "pll-ddr0", "pll-ddr1",
+                                            "pll-periph0-2x" };
 static SUNXI_CCU_M_WITH_MUX(dram_clk, "dram", dram_parents,
                            0x0f4, 0, 4, 20, 2, CLK_IS_CRITICAL);
 
@@ -363,10 +379,11 @@ static struct ccu_common *sun8i_v3s_ccu_clks[] = {
        &pll_audio_base_clk.common,
        &pll_video_clk.common,
        &pll_ve_clk.common,
-       &pll_ddr_clk.common,
+       &pll_ddr0_clk.common,
        &pll_periph0_clk.common,
        &pll_isp_clk.common,
        &pll_periph1_clk.common,
+       &pll_ddr1_clk.common,
        &cpu_clk.common,
        &axi_clk.common,
        &ahb1_clk.common,
@@ -433,6 +450,80 @@ static const struct clk_hw *clk_parent_pll_audio[] = {
        &pll_audio_base_clk.common.hw
 };
 
+static struct ccu_common *sun8i_v3_ccu_clks[] = {
+       &pll_cpu_clk.common,
+       &pll_audio_base_clk.common,
+       &pll_video_clk.common,
+       &pll_ve_clk.common,
+       &pll_ddr0_clk.common,
+       &pll_periph0_clk.common,
+       &pll_isp_clk.common,
+       &pll_periph1_clk.common,
+       &pll_ddr1_clk.common,
+       &cpu_clk.common,
+       &axi_clk.common,
+       &ahb1_clk.common,
+       &apb1_clk.common,
+       &apb2_clk.common,
+       &ahb2_clk.common,
+       &bus_ce_clk.common,
+       &bus_dma_clk.common,
+       &bus_mmc0_clk.common,
+       &bus_mmc1_clk.common,
+       &bus_mmc2_clk.common,
+       &bus_dram_clk.common,
+       &bus_emac_clk.common,
+       &bus_hstimer_clk.common,
+       &bus_spi0_clk.common,
+       &bus_otg_clk.common,
+       &bus_ehci0_clk.common,
+       &bus_ohci0_clk.common,
+       &bus_ve_clk.common,
+       &bus_tcon0_clk.common,
+       &bus_csi_clk.common,
+       &bus_de_clk.common,
+       &bus_codec_clk.common,
+       &bus_pio_clk.common,
+       &bus_i2s0_clk.common,
+       &bus_i2c0_clk.common,
+       &bus_i2c1_clk.common,
+       &bus_uart0_clk.common,
+       &bus_uart1_clk.common,
+       &bus_uart2_clk.common,
+       &bus_ephy_clk.common,
+       &bus_dbg_clk.common,
+       &mmc0_clk.common,
+       &mmc0_sample_clk.common,
+       &mmc0_output_clk.common,
+       &mmc1_clk.common,
+       &mmc1_sample_clk.common,
+       &mmc1_output_clk.common,
+       &mmc2_clk.common,
+       &mmc2_sample_clk.common,
+       &mmc2_output_clk.common,
+       &ce_clk.common,
+       &spi0_clk.common,
+       &i2s0_clk.common,
+       &usb_phy0_clk.common,
+       &usb_ohci0_clk.common,
+       &dram_clk.common,
+       &dram_ve_clk.common,
+       &dram_csi_clk.common,
+       &dram_ohci_clk.common,
+       &dram_ehci_clk.common,
+       &de_clk.common,
+       &tcon_clk.common,
+       &csi_misc_clk.common,
+       &csi0_mclk_clk.common,
+       &csi1_sclk_clk.common,
+       &csi1_mclk_clk.common,
+       &ve_clk.common,
+       &ac_dig_clk.common,
+       &avs_clk.common,
+       &mbus_clk.common,
+       &mipi_csi_clk.common,
+};
+
 /* We hardcode the divider to 4 for now */
 static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
                            clk_parent_pll_audio,
@@ -460,11 +551,12 @@ static struct clk_hw_onecell_data sun8i_v3s_hw_clks = {
                [CLK_PLL_AUDIO_8X]      = &pll_audio_8x_clk.hw,
                [CLK_PLL_VIDEO]         = &pll_video_clk.common.hw,
                [CLK_PLL_VE]            = &pll_ve_clk.common.hw,
-               [CLK_PLL_DDR]           = &pll_ddr_clk.common.hw,
+               [CLK_PLL_DDR0]          = &pll_ddr0_clk.common.hw,
                [CLK_PLL_PERIPH0]       = &pll_periph0_clk.common.hw,
                [CLK_PLL_PERIPH0_2X]    = &pll_periph0_2x_clk.hw,
                [CLK_PLL_ISP]           = &pll_isp_clk.common.hw,
                [CLK_PLL_PERIPH1]       = &pll_periph1_clk.common.hw,
+               [CLK_PLL_DDR1]          = &pll_ddr1_clk.common.hw,
                [CLK_CPU]               = &cpu_clk.common.hw,
                [CLK_AXI]               = &axi_clk.common.hw,
                [CLK_AHB1]              = &ahb1_clk.common.hw,
@@ -502,6 +594,9 @@ static struct clk_hw_onecell_data sun8i_v3s_hw_clks = {
                [CLK_MMC1]              = &mmc1_clk.common.hw,
                [CLK_MMC1_SAMPLE]       = &mmc1_sample_clk.common.hw,
                [CLK_MMC1_OUTPUT]       = &mmc1_output_clk.common.hw,
+               [CLK_MMC2]              = &mmc2_clk.common.hw,
+               [CLK_MMC2_SAMPLE]       = &mmc2_sample_clk.common.hw,
+               [CLK_MMC2_OUTPUT]       = &mmc2_output_clk.common.hw,
                [CLK_CE]                = &ce_clk.common.hw,
                [CLK_SPI0]              = &spi0_clk.common.hw,
                [CLK_USB_PHY0]          = &usb_phy0_clk.common.hw,
@@ -526,6 +621,88 @@ static struct clk_hw_onecell_data sun8i_v3s_hw_clks = {
        .num    = CLK_NUMBER,
 };
 
+static struct clk_hw_onecell_data sun8i_v3_hw_clks = {
+       .hws    = {
+               [CLK_PLL_CPU]           = &pll_cpu_clk.common.hw,
+               [CLK_PLL_AUDIO_BASE]    = &pll_audio_base_clk.common.hw,
+               [CLK_PLL_AUDIO]         = &pll_audio_clk.hw,
+               [CLK_PLL_AUDIO_2X]      = &pll_audio_2x_clk.hw,
+               [CLK_PLL_AUDIO_4X]      = &pll_audio_4x_clk.hw,
+               [CLK_PLL_AUDIO_8X]      = &pll_audio_8x_clk.hw,
+               [CLK_PLL_VIDEO]         = &pll_video_clk.common.hw,
+               [CLK_PLL_VE]            = &pll_ve_clk.common.hw,
+               [CLK_PLL_DDR0]          = &pll_ddr0_clk.common.hw,
+               [CLK_PLL_PERIPH0]       = &pll_periph0_clk.common.hw,
+               [CLK_PLL_PERIPH0_2X]    = &pll_periph0_2x_clk.hw,
+               [CLK_PLL_ISP]           = &pll_isp_clk.common.hw,
+               [CLK_PLL_PERIPH1]       = &pll_periph1_clk.common.hw,
+               [CLK_PLL_DDR1]          = &pll_ddr1_clk.common.hw,
+               [CLK_CPU]               = &cpu_clk.common.hw,
+               [CLK_AXI]               = &axi_clk.common.hw,
+               [CLK_AHB1]              = &ahb1_clk.common.hw,
+               [CLK_APB1]              = &apb1_clk.common.hw,
+               [CLK_APB2]              = &apb2_clk.common.hw,
+               [CLK_AHB2]              = &ahb2_clk.common.hw,
+               [CLK_BUS_CE]            = &bus_ce_clk.common.hw,
+               [CLK_BUS_DMA]           = &bus_dma_clk.common.hw,
+               [CLK_BUS_MMC0]          = &bus_mmc0_clk.common.hw,
+               [CLK_BUS_MMC1]          = &bus_mmc1_clk.common.hw,
+               [CLK_BUS_MMC2]          = &bus_mmc2_clk.common.hw,
+               [CLK_BUS_DRAM]          = &bus_dram_clk.common.hw,
+               [CLK_BUS_EMAC]          = &bus_emac_clk.common.hw,
+               [CLK_BUS_HSTIMER]       = &bus_hstimer_clk.common.hw,
+               [CLK_BUS_SPI0]          = &bus_spi0_clk.common.hw,
+               [CLK_BUS_OTG]           = &bus_otg_clk.common.hw,
+               [CLK_BUS_EHCI0]         = &bus_ehci0_clk.common.hw,
+               [CLK_BUS_OHCI0]         = &bus_ohci0_clk.common.hw,
+               [CLK_BUS_VE]            = &bus_ve_clk.common.hw,
+               [CLK_BUS_TCON0]         = &bus_tcon0_clk.common.hw,
+               [CLK_BUS_CSI]           = &bus_csi_clk.common.hw,
+               [CLK_BUS_DE]            = &bus_de_clk.common.hw,
+               [CLK_BUS_CODEC]         = &bus_codec_clk.common.hw,
+               [CLK_BUS_PIO]           = &bus_pio_clk.common.hw,
+               [CLK_BUS_I2S0]          = &bus_i2s0_clk.common.hw,
+               [CLK_BUS_I2C0]          = &bus_i2c0_clk.common.hw,
+               [CLK_BUS_I2C1]          = &bus_i2c1_clk.common.hw,
+               [CLK_BUS_UART0]         = &bus_uart0_clk.common.hw,
+               [CLK_BUS_UART1]         = &bus_uart1_clk.common.hw,
+               [CLK_BUS_UART2]         = &bus_uart2_clk.common.hw,
+               [CLK_BUS_EPHY]          = &bus_ephy_clk.common.hw,
+               [CLK_BUS_DBG]           = &bus_dbg_clk.common.hw,
+               [CLK_MMC0]              = &mmc0_clk.common.hw,
+               [CLK_MMC0_SAMPLE]       = &mmc0_sample_clk.common.hw,
+               [CLK_MMC0_OUTPUT]       = &mmc0_output_clk.common.hw,
+               [CLK_MMC1]              = &mmc1_clk.common.hw,
+               [CLK_MMC1_SAMPLE]       = &mmc1_sample_clk.common.hw,
+               [CLK_MMC1_OUTPUT]       = &mmc1_output_clk.common.hw,
+               [CLK_MMC2]              = &mmc2_clk.common.hw,
+               [CLK_MMC2_SAMPLE]       = &mmc2_sample_clk.common.hw,
+               [CLK_MMC2_OUTPUT]       = &mmc2_output_clk.common.hw,
+               [CLK_CE]                = &ce_clk.common.hw,
+               [CLK_SPI0]              = &spi0_clk.common.hw,
+               [CLK_I2S0]              = &i2s0_clk.common.hw,
+               [CLK_USB_PHY0]          = &usb_phy0_clk.common.hw,
+               [CLK_USB_OHCI0]         = &usb_ohci0_clk.common.hw,
+               [CLK_DRAM]              = &dram_clk.common.hw,
+               [CLK_DRAM_VE]           = &dram_ve_clk.common.hw,
+               [CLK_DRAM_CSI]          = &dram_csi_clk.common.hw,
+               [CLK_DRAM_EHCI]         = &dram_ehci_clk.common.hw,
+               [CLK_DRAM_OHCI]         = &dram_ohci_clk.common.hw,
+               [CLK_DE]                = &de_clk.common.hw,
+               [CLK_TCON0]             = &tcon_clk.common.hw,
+               [CLK_CSI_MISC]          = &csi_misc_clk.common.hw,
+               [CLK_CSI0_MCLK]         = &csi0_mclk_clk.common.hw,
+               [CLK_CSI1_SCLK]         = &csi1_sclk_clk.common.hw,
+               [CLK_CSI1_MCLK]         = &csi1_mclk_clk.common.hw,
+               [CLK_VE]                = &ve_clk.common.hw,
+               [CLK_AC_DIG]            = &ac_dig_clk.common.hw,
+               [CLK_AVS]               = &avs_clk.common.hw,
+               [CLK_MBUS]              = &mbus_clk.common.hw,
+               [CLK_MIPI_CSI]          = &mipi_csi_clk.common.hw,
+       },
+       .num    = CLK_NUMBER,
+};
+
 static struct ccu_reset_map sun8i_v3s_ccu_resets[] = {
        [RST_USB_PHY0]          =  { 0x0cc, BIT(0) },
 
@@ -561,6 +738,42 @@ static struct ccu_reset_map sun8i_v3s_ccu_resets[] = {
        [RST_BUS_UART2]         =  { 0x2d8, BIT(18) },
 };
 
+static struct ccu_reset_map sun8i_v3_ccu_resets[] = {
+       [RST_USB_PHY0]          =  { 0x0cc, BIT(0) },
+
+       [RST_MBUS]              =  { 0x0fc, BIT(31) },
+
+       [RST_BUS_CE]            =  { 0x2c0, BIT(5) },
+       [RST_BUS_DMA]           =  { 0x2c0, BIT(6) },
+       [RST_BUS_MMC0]          =  { 0x2c0, BIT(8) },
+       [RST_BUS_MMC1]          =  { 0x2c0, BIT(9) },
+       [RST_BUS_MMC2]          =  { 0x2c0, BIT(10) },
+       [RST_BUS_DRAM]          =  { 0x2c0, BIT(14) },
+       [RST_BUS_EMAC]          =  { 0x2c0, BIT(17) },
+       [RST_BUS_HSTIMER]       =  { 0x2c0, BIT(19) },
+       [RST_BUS_SPI0]          =  { 0x2c0, BIT(20) },
+       [RST_BUS_OTG]           =  { 0x2c0, BIT(24) },
+       [RST_BUS_EHCI0]         =  { 0x2c0, BIT(26) },
+       [RST_BUS_OHCI0]         =  { 0x2c0, BIT(29) },
+
+       [RST_BUS_VE]            =  { 0x2c4, BIT(0) },
+       [RST_BUS_TCON0]         =  { 0x2c4, BIT(4) },
+       [RST_BUS_CSI]           =  { 0x2c4, BIT(8) },
+       [RST_BUS_DE]            =  { 0x2c4, BIT(12) },
+       [RST_BUS_DBG]           =  { 0x2c4, BIT(31) },
+
+       [RST_BUS_EPHY]          =  { 0x2c8, BIT(2) },
+
+       [RST_BUS_CODEC]         =  { 0x2d0, BIT(0) },
+       [RST_BUS_I2S0]          =  { 0x2d0, BIT(12) },
+
+       [RST_BUS_I2C0]          =  { 0x2d8, BIT(0) },
+       [RST_BUS_I2C1]          =  { 0x2d8, BIT(1) },
+       [RST_BUS_UART0]         =  { 0x2d8, BIT(16) },
+       [RST_BUS_UART1]         =  { 0x2d8, BIT(17) },
+       [RST_BUS_UART2]         =  { 0x2d8, BIT(18) },
+};
+
 static const struct sunxi_ccu_desc sun8i_v3s_ccu_desc = {
        .ccu_clks       = sun8i_v3s_ccu_clks,
        .num_ccu_clks   = ARRAY_SIZE(sun8i_v3s_ccu_clks),
@@ -571,7 +784,18 @@ static const struct sunxi_ccu_desc sun8i_v3s_ccu_desc = {
        .num_resets     = ARRAY_SIZE(sun8i_v3s_ccu_resets),
 };
 
-static void __init sun8i_v3s_ccu_setup(struct device_node *node)
+static const struct sunxi_ccu_desc sun8i_v3_ccu_desc = {
+       .ccu_clks       = sun8i_v3_ccu_clks,
+       .num_ccu_clks   = ARRAY_SIZE(sun8i_v3_ccu_clks),
+
+       .hw_clks        = &sun8i_v3_hw_clks,
+
+       .resets         = sun8i_v3_ccu_resets,
+       .num_resets     = ARRAY_SIZE(sun8i_v3_ccu_resets),
+};
+
+static void __init sun8i_v3_v3s_ccu_init(struct device_node *node,
+                                        const struct sunxi_ccu_desc *ccu_desc)
 {
        void __iomem *reg;
        u32 val;
@@ -587,7 +811,21 @@ static void __init sun8i_v3s_ccu_setup(struct device_node *node)
        val &= ~GENMASK(19, 16);
        writel(val | (3 << 16), reg + SUN8I_V3S_PLL_AUDIO_REG);
 
-       sunxi_ccu_probe(node, reg, &sun8i_v3s_ccu_desc);
+       sunxi_ccu_probe(node, reg, ccu_desc);
+}
+
+static void __init sun8i_v3s_ccu_setup(struct device_node *node)
+{
+       sun8i_v3_v3s_ccu_init(node, &sun8i_v3s_ccu_desc);
+}
+
+static void __init sun8i_v3_ccu_setup(struct device_node *node)
+{
+       sun8i_v3_v3s_ccu_init(node, &sun8i_v3_ccu_desc);
 }
+
 CLK_OF_DECLARE(sun8i_v3s_ccu, "allwinner,sun8i-v3s-ccu",
               sun8i_v3s_ccu_setup);
+
+CLK_OF_DECLARE(sun8i_v3_ccu, "allwinner,sun8i-v3-ccu",
+              sun8i_v3_ccu_setup);
index fbc1da8b4520501e5fff49719ec52e5127a97b8e..b0160d305a6775a3721a5438b4223e8a77251367 100644 (file)
@@ -20,7 +20,7 @@
 #define CLK_PLL_AUDIO_8X       5
 #define CLK_PLL_VIDEO          6
 #define CLK_PLL_VE             7
-#define CLK_PLL_DDR            8
+#define CLK_PLL_DDR0           8
 #define CLK_PLL_PERIPH0                9
 #define CLK_PLL_PERIPH0_2X     10
 #define CLK_PLL_ISP            11
@@ -49,6 +49,8 @@
 
 /* And the GPU module clock is exported */
 
-#define CLK_NUMBER             (CLK_MIPI_CSI + 1)
+#define CLK_PLL_DDR1           74
+
+#define CLK_NUMBER             (CLK_I2S0 + 1)
 
 #endif /* _CCU_SUN8I_H3_H_ */
index 7fe3ac980e5f930e61cb4004c3bd5506205a7c14..2e20e650b6c01b209e26a84e28c9df3bae990eca 100644 (file)
@@ -97,14 +97,15 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
 
        for (i = 0; i < desc->hw_clks->num ; i++) {
                struct clk_hw *hw = desc->hw_clks->hws[i];
+               const char *name;
 
                if (!hw)
                        continue;
 
+               name = hw->init->name;
                ret = of_clk_hw_register(node, hw);
                if (ret) {
-                       pr_err("Couldn't register clock %d - %s\n",
-                              i, clk_hw_get_name(hw));
+                       pr_err("Couldn't register clock %d - %s\n", i, name);
                        goto err_clk_unreg;
                }
        }
index 015a657d33829e160f3acc18145461499c963f24..ac5bc8857a51456efb3fc32e620a8d9d24e1c426 100644 (file)
@@ -140,6 +140,7 @@ static void __init omap_clk_register_apll(void *user,
        struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw);
        struct dpll_data *ad = clk_hw->dpll_data;
        struct clk *clk;
+       const struct clk_init_data *init = clk_hw->hw.init;
 
        clk = of_clk_get(node, 0);
        if (IS_ERR(clk)) {
@@ -168,15 +169,15 @@ static void __init omap_clk_register_apll(void *user,
        clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, node->name);
        if (!IS_ERR(clk)) {
                of_clk_add_provider(node, of_clk_src_simple_get, clk);
-               kfree(clk_hw->hw.init->parent_names);
-               kfree(clk_hw->hw.init);
+               kfree(init->parent_names);
+               kfree(init);
                return;
        }
 
 cleanup:
        kfree(clk_hw->dpll_data);
-       kfree(clk_hw->hw.init->parent_names);
-       kfree(clk_hw->hw.init);
+       kfree(init->parent_names);
+       kfree(init);
        kfree(clk_hw);
 }
 
index e8cee6f3b4a0332742f84576d7ae373e4c09ca9a..087cfa75ac24846d5e9cd37bae040a4c333d49bb 100644 (file)
@@ -66,6 +66,7 @@ static int __init dm814x_adpll_early_init(void)
        }
 
        of_platform_populate(np, NULL, NULL, NULL);
+       of_node_put(np);
 
        return 0;
 }
index 659dadb23279caa755260be7b465794978f78b3a..247510e306e2a8a19f905c5700b83cf760325850 100644 (file)
@@ -165,6 +165,7 @@ static void __init _register_dpll(void *user,
        struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw);
        struct dpll_data *dd = clk_hw->dpll_data;
        struct clk *clk;
+       const struct clk_init_data *init = hw->init;
 
        clk = of_clk_get(node, 0);
        if (IS_ERR(clk)) {
@@ -196,15 +197,15 @@ static void __init _register_dpll(void *user,
 
        if (!IS_ERR(clk)) {
                of_clk_add_provider(node, of_clk_src_simple_get, clk);
-               kfree(clk_hw->hw.init->parent_names);
-               kfree(clk_hw->hw.init);
+               kfree(init->parent_names);
+               kfree(init);
                return;
        }
 
 cleanup:
        kfree(clk_hw->dpll_data);
-       kfree(clk_hw->hw.init->parent_names);
-       kfree(clk_hw->hw.init);
+       kfree(init->parent_names);
+       kfree(init);
        kfree(clk_hw);
 }
 
@@ -291,14 +292,12 @@ static void __init of_ti_dpll_setup(struct device_node *node,
        struct dpll_data *dd = NULL;
        u8 dpll_mode = 0;
 
-       dd = kzalloc(sizeof(*dd), GFP_KERNEL);
+       dd = kmemdup(ddt, sizeof(*dd), GFP_KERNEL);
        clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
        init = kzalloc(sizeof(*init), GFP_KERNEL);
        if (!dd || !clk_hw || !init)
                goto cleanup;
 
-       memcpy(dd, ddt, sizeof(*dd));
-
        clk_hw->dpll_data = dd;
        clk_hw->ops = &clkhwops_omap3_dpll;
        clk_hw->hw.init = init;
index 90bb0b041b7a9d4f5c448e192bcbea1a8831b472..fd54d5c0251cc724f38d4f1de390a57d44d4dd1a 100644 (file)
@@ -70,6 +70,7 @@ static void __init cm_osc_setup(struct device_node *np,
                        return;
                }
                cm_base = of_iomap(parent, 0);
+               of_node_put(parent);
                if (!cm_base) {
                        pr_err("could not remap core module base\n");
                        return;
index fd6c347bec6a7491321b8b911ae9e4f483aa2f33..dd7045bc48c152f124635b2c885e054497702ff5 100644 (file)
@@ -564,6 +564,7 @@ static int __init top_clocks_init(struct device_node *np)
 {
        void __iomem *reg_base;
        int i, ret;
+       const char *name;
 
        reg_base = of_iomap(np, 0);
        if (!reg_base) {
@@ -573,11 +574,10 @@ static int __init top_clocks_init(struct device_node *np)
 
        for (i = 0; i < ARRAY_SIZE(zx296718_pll_clk); i++) {
                zx296718_pll_clk[i].reg_base += (uintptr_t)reg_base;
+               name = zx296718_pll_clk[i].hw.init->name;
                ret = clk_hw_register(NULL, &zx296718_pll_clk[i].hw);
-               if (ret) {
-                       pr_warn("top clk %s init error!\n",
-                               zx296718_pll_clk[i].hw.init->name);
-               }
+               if (ret)
+                       pr_warn("top clk %s init error!\n", name);
        }
 
        for (i = 0; i < ARRAY_SIZE(top_ffactor_clk); i++) {
@@ -585,11 +585,10 @@ static int __init top_clocks_init(struct device_node *np)
                        top_hw_onecell_data.hws[top_ffactor_clk[i].id] =
                                        &top_ffactor_clk[i].factor.hw;
 
+               name = top_ffactor_clk[i].factor.hw.init->name;
                ret = clk_hw_register(NULL, &top_ffactor_clk[i].factor.hw);
-               if (ret) {
-                       pr_warn("top clk %s init error!\n",
-                               top_ffactor_clk[i].factor.hw.init->name);
-               }
+               if (ret)
+                       pr_warn("top clk %s init error!\n", name);
        }
 
        for (i = 0; i < ARRAY_SIZE(top_mux_clk); i++) {
@@ -598,11 +597,10 @@ static int __init top_clocks_init(struct device_node *np)
                                        &top_mux_clk[i].mux.hw;
 
                top_mux_clk[i].mux.reg += (uintptr_t)reg_base;
+               name = top_mux_clk[i].mux.hw.init->name;
                ret = clk_hw_register(NULL, &top_mux_clk[i].mux.hw);
-               if (ret) {
-                       pr_warn("top clk %s init error!\n",
-                               top_mux_clk[i].mux.hw.init->name);
-               }
+               if (ret)
+                       pr_warn("top clk %s init error!\n", name);
        }
 
        for (i = 0; i < ARRAY_SIZE(top_gate_clk); i++) {
@@ -611,11 +609,10 @@ static int __init top_clocks_init(struct device_node *np)
                                        &top_gate_clk[i].gate.hw;
 
                top_gate_clk[i].gate.reg += (uintptr_t)reg_base;
+               name = top_gate_clk[i].gate.hw.init->name;
                ret = clk_hw_register(NULL, &top_gate_clk[i].gate.hw);
-               if (ret) {
-                       pr_warn("top clk %s init error!\n",
-                               top_gate_clk[i].gate.hw.init->name);
-               }
+               if (ret)
+                       pr_warn("top clk %s init error!\n", name);
        }
 
        for (i = 0; i < ARRAY_SIZE(top_div_clk); i++) {
@@ -624,11 +621,10 @@ static int __init top_clocks_init(struct device_node *np)
                                        &top_div_clk[i].div.hw;
 
                top_div_clk[i].div.reg += (uintptr_t)reg_base;
+               name = top_div_clk[i].div.hw.init->name;
                ret = clk_hw_register(NULL, &top_div_clk[i].div.hw);
-               if (ret) {
-                       pr_warn("top clk %s init error!\n",
-                               top_div_clk[i].div.hw.init->name);
-               }
+               if (ret)
+                       pr_warn("top clk %s init error!\n", name);
        }
 
        ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
@@ -754,6 +750,7 @@ static int __init lsp0_clocks_init(struct device_node *np)
 {
        void __iomem *reg_base;
        int i, ret;
+       const char *name;
 
        reg_base = of_iomap(np, 0);
        if (!reg_base) {
@@ -767,11 +764,10 @@ static int __init lsp0_clocks_init(struct device_node *np)
                                        &lsp0_mux_clk[i].mux.hw;
 
                lsp0_mux_clk[i].mux.reg += (uintptr_t)reg_base;
+               name = lsp0_mux_clk[i].mux.hw.init->name;
                ret = clk_hw_register(NULL, &lsp0_mux_clk[i].mux.hw);
-               if (ret) {
-                       pr_warn("lsp0 clk %s init error!\n",
-                               lsp0_mux_clk[i].mux.hw.init->name);
-               }
+               if (ret)
+                       pr_warn("lsp0 clk %s init error!\n", name);
        }
 
        for (i = 0; i < ARRAY_SIZE(lsp0_gate_clk); i++) {
@@ -780,11 +776,10 @@ static int __init lsp0_clocks_init(struct device_node *np)
                                        &lsp0_gate_clk[i].gate.hw;
 
                lsp0_gate_clk[i].gate.reg += (uintptr_t)reg_base;
+               name = lsp0_gate_clk[i].gate.hw.init->name;
                ret = clk_hw_register(NULL, &lsp0_gate_clk[i].gate.hw);
-               if (ret) {
-                       pr_warn("lsp0 clk %s init error!\n",
-                               lsp0_gate_clk[i].gate.hw.init->name);
-               }
+               if (ret)
+                       pr_warn("lsp0 clk %s init error!\n", name);
        }
 
        for (i = 0; i < ARRAY_SIZE(lsp0_div_clk); i++) {
@@ -793,11 +788,10 @@ static int __init lsp0_clocks_init(struct device_node *np)
                                        &lsp0_div_clk[i].div.hw;
 
                lsp0_div_clk[i].div.reg += (uintptr_t)reg_base;
+               name = lsp0_div_clk[i].div.hw.init->name;
                ret = clk_hw_register(NULL, &lsp0_div_clk[i].div.hw);
-               if (ret) {
-                       pr_warn("lsp0 clk %s init error!\n",
-                               lsp0_div_clk[i].div.hw.init->name);
-               }
+               if (ret)
+                       pr_warn("lsp0 clk %s init error!\n", name);
        }
 
        ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
@@ -862,6 +856,7 @@ static int __init lsp1_clocks_init(struct device_node *np)
 {
        void __iomem *reg_base;
        int i, ret;
+       const char *name;
 
        reg_base = of_iomap(np, 0);
        if (!reg_base) {
@@ -875,11 +870,10 @@ static int __init lsp1_clocks_init(struct device_node *np)
                                        &lsp0_mux_clk[i].mux.hw;
 
                lsp1_mux_clk[i].mux.reg += (uintptr_t)reg_base;
+               name = lsp1_mux_clk[i].mux.hw.init->name;
                ret = clk_hw_register(NULL, &lsp1_mux_clk[i].mux.hw);
-               if (ret) {
-                       pr_warn("lsp1 clk %s init error!\n",
-                               lsp1_mux_clk[i].mux.hw.init->name);
-               }
+               if (ret)
+                       pr_warn("lsp1 clk %s init error!\n", name);
        }
 
        for (i = 0; i < ARRAY_SIZE(lsp1_gate_clk); i++) {
@@ -888,11 +882,10 @@ static int __init lsp1_clocks_init(struct device_node *np)
                                        &lsp1_gate_clk[i].gate.hw;
 
                lsp1_gate_clk[i].gate.reg += (uintptr_t)reg_base;
+               name = lsp1_gate_clk[i].gate.hw.init->name;
                ret = clk_hw_register(NULL, &lsp1_gate_clk[i].gate.hw);
-               if (ret) {
-                       pr_warn("lsp1 clk %s init error!\n",
-                               lsp1_gate_clk[i].gate.hw.init->name);
-               }
+               if (ret)
+                       pr_warn("lsp1 clk %s init error!\n", name);
        }
 
        for (i = 0; i < ARRAY_SIZE(lsp1_div_clk); i++) {
@@ -901,11 +894,10 @@ static int __init lsp1_clocks_init(struct device_node *np)
                                        &lsp1_div_clk[i].div.hw;
 
                lsp1_div_clk[i].div.reg += (uintptr_t)reg_base;
+               name = lsp1_div_clk[i].div.hw.init->name;
                ret = clk_hw_register(NULL, &lsp1_div_clk[i].div.hw);
-               if (ret) {
-                       pr_warn("lsp1 clk %s init error!\n",
-                               lsp1_div_clk[i].div.hw.init->name);
-               }
+               if (ret)
+                       pr_warn("lsp1 clk %s init error!\n", name);
        }
 
        ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
@@ -979,6 +971,7 @@ static int __init audio_clocks_init(struct device_node *np)
 {
        void __iomem *reg_base;
        int i, ret;
+       const char *name;
 
        reg_base = of_iomap(np, 0);
        if (!reg_base) {
@@ -992,11 +985,10 @@ static int __init audio_clocks_init(struct device_node *np)
                                        &audio_mux_clk[i].mux.hw;
 
                audio_mux_clk[i].mux.reg += (uintptr_t)reg_base;
+               name = audio_mux_clk[i].mux.hw.init->name;
                ret = clk_hw_register(NULL, &audio_mux_clk[i].mux.hw);
-               if (ret) {
-                       pr_warn("audio clk %s init error!\n",
-                               audio_mux_clk[i].mux.hw.init->name);
-               }
+               if (ret)
+                       pr_warn("audio clk %s init error!\n", name);
        }
 
        for (i = 0; i < ARRAY_SIZE(audio_adiv_clk); i++) {
@@ -1005,11 +997,10 @@ static int __init audio_clocks_init(struct device_node *np)
                                        &audio_adiv_clk[i].hw;
 
                audio_adiv_clk[i].reg_base += (uintptr_t)reg_base;
+               name = audio_adiv_clk[i].hw.init->name;
                ret = clk_hw_register(NULL, &audio_adiv_clk[i].hw);
-               if (ret) {
-                       pr_warn("audio clk %s init error!\n",
-                               audio_adiv_clk[i].hw.init->name);
-               }
+               if (ret)
+                       pr_warn("audio clk %s init error!\n", name);
        }
 
        for (i = 0; i < ARRAY_SIZE(audio_div_clk); i++) {
@@ -1018,11 +1009,10 @@ static int __init audio_clocks_init(struct device_node *np)
                                        &audio_div_clk[i].div.hw;
 
                audio_div_clk[i].div.reg += (uintptr_t)reg_base;
+               name = audio_div_clk[i].div.hw.init->name;
                ret = clk_hw_register(NULL, &audio_div_clk[i].div.hw);
-               if (ret) {
-                       pr_warn("audio clk %s init error!\n",
-                               audio_div_clk[i].div.hw.init->name);
-               }
+               if (ret)
+                       pr_warn("audio clk %s init error!\n", name);
        }
 
        for (i = 0; i < ARRAY_SIZE(audio_gate_clk); i++) {
@@ -1031,11 +1021,10 @@ static int __init audio_clocks_init(struct device_node *np)
                                        &audio_gate_clk[i].gate.hw;
 
                audio_gate_clk[i].gate.reg += (uintptr_t)reg_base;
+               name = audio_gate_clk[i].gate.hw.init->name;
                ret = clk_hw_register(NULL, &audio_gate_clk[i].gate.hw);
-               if (ret) {
-                       pr_warn("audio clk %s init error!\n",
-                               audio_gate_clk[i].gate.hw.init->name);
-               }
+               if (ret)
+                       pr_warn("audio clk %s init error!\n", name);
        }
 
        ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
index f8edd0840fa2b43180fae7729ad4dae7eae6988b..398a8c9b675a94b37e5cb1765ce6b83ace95be33 100644 (file)
@@ -335,6 +335,7 @@ static int serdes_am654_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 {
        struct serdes_am654_clk_mux *mux = to_serdes_am654_clk_mux(hw);
        struct regmap *regmap = mux->regmap;
+       const char *name = clk_hw_get_name(hw);
        unsigned int reg = mux->reg;
        int clk_id = mux->clk_id;
        int parents[SERDES_NUM_CLOCKS];
@@ -374,8 +375,7 @@ static int serdes_am654_clk_mux_set_parent(struct clk_hw *hw, u8 index)
                 * This can never happen, unless we missed
                 * a valid combination in serdes_am654_mux_table.
                 */
-               WARN(1, "Failed to find the parent of %s clock\n",
-                    hw->init->name);
+               WARN(1, "Failed to find the parent of %s clock\n", name);
                return -EINVAL;
        }
 
index c0e75c373605909b99cff0f3a87198a05c913aa9..d50ee023b559ae11f378fa7229369b3cda835cba 100644 (file)
@@ -279,7 +279,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,
 
        of_property_read_string_index(node, "clock-output-names", 1,
                                      &clkout_name);
-       rtc->ext_losc = clk_register_gate(NULL, clkout_name, rtc->hw.init->name,
+       rtc->ext_losc = clk_register_gate(NULL, clkout_name, init.name,
                                          0, rtc->base + SUN6I_LOSC_OUT_GATING,
                                          SUN6I_LOSC_OUT_GATING_EN_OFFSET, 0,
                                          &rtc->lock);
diff --git a/include/dt-bindings/clock/ast2600-clock.h b/include/dt-bindings/clock/ast2600-clock.h
new file mode 100644 (file)
index 0000000..38074a5
--- /dev/null
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later OR MIT */
+#ifndef DT_BINDINGS_AST2600_CLOCK_H
+#define DT_BINDINGS_AST2600_CLOCK_H
+
+#define ASPEED_CLK_GATE_ECLK           0
+#define ASPEED_CLK_GATE_GCLK           1
+
+#define ASPEED_CLK_GATE_MCLK           2
+
+#define ASPEED_CLK_GATE_VCLK           3
+#define ASPEED_CLK_GATE_BCLK           4
+#define ASPEED_CLK_GATE_DCLK           5
+
+#define ASPEED_CLK_GATE_LCLK           6
+#define ASPEED_CLK_GATE_LHCCLK         7
+
+#define ASPEED_CLK_GATE_D1CLK          8
+#define ASPEED_CLK_GATE_YCLK           9
+
+#define ASPEED_CLK_GATE_REF0CLK                10
+#define ASPEED_CLK_GATE_REF1CLK                11
+
+#define ASPEED_CLK_GATE_ESPICLK                12
+
+#define ASPEED_CLK_GATE_USBUHCICLK     13
+#define ASPEED_CLK_GATE_USBPORT1CLK    14
+#define ASPEED_CLK_GATE_USBPORT2CLK    15
+
+#define ASPEED_CLK_GATE_RSACLK         16
+#define ASPEED_CLK_GATE_RVASCLK                17
+
+#define ASPEED_CLK_GATE_MAC1CLK                18
+#define ASPEED_CLK_GATE_MAC2CLK                19
+#define ASPEED_CLK_GATE_MAC3CLK                20
+#define ASPEED_CLK_GATE_MAC4CLK                21
+
+#define ASPEED_CLK_GATE_UART1CLK       22
+#define ASPEED_CLK_GATE_UART2CLK       23
+#define ASPEED_CLK_GATE_UART3CLK       24
+#define ASPEED_CLK_GATE_UART4CLK       25
+#define ASPEED_CLK_GATE_UART5CLK       26
+#define ASPEED_CLK_GATE_UART6CLK       27
+#define ASPEED_CLK_GATE_UART7CLK       28
+#define ASPEED_CLK_GATE_UART8CLK       29
+#define ASPEED_CLK_GATE_UART9CLK       30
+#define ASPEED_CLK_GATE_UART10CLK      31
+#define ASPEED_CLK_GATE_UART11CLK      32
+#define ASPEED_CLK_GATE_UART12CLK      33
+#define ASPEED_CLK_GATE_UART13CLK      34
+
+#define ASPEED_CLK_GATE_SDCLK          35
+#define ASPEED_CLK_GATE_EMMCCLK                36
+
+#define ASPEED_CLK_GATE_I3C0CLK                37
+#define ASPEED_CLK_GATE_I3C1CLK                38
+#define ASPEED_CLK_GATE_I3C2CLK                39
+#define ASPEED_CLK_GATE_I3C3CLK                40
+#define ASPEED_CLK_GATE_I3C4CLK                41
+#define ASPEED_CLK_GATE_I3C5CLK                42
+#define ASPEED_CLK_GATE_I3C6CLK                43
+#define ASPEED_CLK_GATE_I3C7CLK                44
+
+#define ASPEED_CLK_GATE_FSICLK         45
+
+#define ASPEED_CLK_HPLL                        46
+#define ASPEED_CLK_MPLL                        47
+#define ASPEED_CLK_DPLL                        48
+#define ASPEED_CLK_EPLL                        49
+#define ASPEED_CLK_APLL                        50
+#define ASPEED_CLK_AHB                 51
+#define ASPEED_CLK_APB1                        52
+#define ASPEED_CLK_APB2                        53
+#define ASPEED_CLK_BCLK                        54
+#define ASPEED_CLK_D1CLK               55
+#define ASPEED_CLK_VCLK                        56
+#define ASPEED_CLK_LHCLK               57
+#define ASPEED_CLK_UART                        58
+#define ASPEED_CLK_UARTX               59
+#define ASPEED_CLK_SDIO                        60
+#define ASPEED_CLK_EMMC                        61
+#define ASPEED_CLK_ECLK                        62
+#define ASPEED_CLK_ECLK_MUX            63
+#define ASPEED_CLK_MAC12               64
+#define ASPEED_CLK_MAC34               65
+#define ASPEED_CLK_USBPHY_40M          66
+
+/* Only list resets here that are not part of a gate */
+#define ASPEED_RESET_ADC               55
+#define ASPEED_RESET_JTAG_MASTER2      54
+#define ASPEED_RESET_I3C_DMA           39
+#define ASPEED_RESET_PWM               37
+#define ASPEED_RESET_PECI              36
+#define ASPEED_RESET_MII               35
+#define ASPEED_RESET_I2C               34
+#define ASPEED_RESET_H2X               31
+#define ASPEED_RESET_GP_MCU            30
+#define ASPEED_RESET_DP_MCU            29
+#define ASPEED_RESET_DP                        28
+#define ASPEED_RESET_RC_XDMA           27
+#define ASPEED_RESET_GRAPHICS          26
+#define ASPEED_RESET_DEV_XDMA          25
+#define ASPEED_RESET_DEV_MCTP          24
+#define ASPEED_RESET_RC_MCTP           23
+#define ASPEED_RESET_JTAG_MASTER       22
+#define ASPEED_RESET_PCIE_DEV_O                21
+#define ASPEED_RESET_PCIE_DEV_OEN      20
+#define ASPEED_RESET_PCIE_RC_O         19
+#define ASPEED_RESET_PCIE_RC_OEN       18
+#define ASPEED_RESET_PCI_DP            5
+#define ASPEED_RESET_AHB               1
+#define ASPEED_RESET_SDRAM             0
+
+#endif
index b6b127e4563456089d86b7552c1b55b713843366..0837c1a7ae490aa54bc507814d7c12b38fa7c2d9 100644 (file)
 #define CLKID_VDEC_HEVC                                207
 #define CLKID_VDEC_HEVCF                       210
 #define CLKID_TS                               212
+#define CLKID_CPUB_CLK                         224
+#define CLKID_GP1_PLL                          243
+#define CLKID_DSU_CLK                          252
+#define CLKID_CPU1_CLK                         253
+#define CLKID_CPU2_CLK                         254
+#define CLKID_CPU3_CLK                         255
 
 #endif /* __G12A_CLKC_H */
index 4236818e3be56973d1b1c82d58be9a86dc3cd0fd..673a8c6623400e4b44c34f0526c5d39e99e5d6c2 100644 (file)
 #define IMX_ADMA_LPCG_PWM_IPG_CLK                      38
 #define IMX_ADMA_LPCG_LCD_PIX_CLK                      39
 #define IMX_ADMA_LPCG_LCD_APB_CLK                      40
+#define IMX_ADMA_LPCG_DSP_ADB_CLK                      41
+#define IMX_ADMA_LPCG_DSP_IPG_CLK                      42
+#define IMX_ADMA_LPCG_DSP_CORE_CLK                     43
+#define IMX_ADMA_LPCG_OCRAM_IPG_CLK                    44
 
-#define IMX_ADMA_LPCG_CLK_END                          41
+#define IMX_ADMA_LPCG_CLK_END                          45
 
 #endif /* __DT_BINDINGS_CLOCK_IMX_H */
diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h
new file mode 100644 (file)
index 0000000..d7b2016
--- /dev/null
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2018-2019 NXP
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMX8MN_H
+#define __DT_BINDINGS_CLOCK_IMX8MN_H
+
+#define IMX8MN_CLK_DUMMY                       0
+#define IMX8MN_CLK_32K                         1
+#define IMX8MN_CLK_24M                         2
+#define IMX8MN_OSC_HDMI_CLK                    3
+#define IMX8MN_CLK_EXT1                                4
+#define IMX8MN_CLK_EXT2                                5
+#define IMX8MN_CLK_EXT3                                6
+#define IMX8MN_CLK_EXT4                                7
+#define IMX8MN_AUDIO_PLL1_REF_SEL              8
+#define IMX8MN_AUDIO_PLL2_REF_SEL              9
+#define IMX8MN_VIDEO_PLL1_REF_SEL              10
+#define IMX8MN_DRAM_PLL_REF_SEL                        11
+#define IMX8MN_GPU_PLL_REF_SEL                 12
+#define IMX8MN_VPU_PLL_REF_SEL                 13
+#define IMX8MN_ARM_PLL_REF_SEL                 14
+#define IMX8MN_SYS_PLL1_REF_SEL                        15
+#define IMX8MN_SYS_PLL2_REF_SEL                        16
+#define IMX8MN_SYS_PLL3_REF_SEL                        17
+#define IMX8MN_AUDIO_PLL1                      18
+#define IMX8MN_AUDIO_PLL2                      19
+#define IMX8MN_VIDEO_PLL1                      20
+#define IMX8MN_DRAM_PLL                                21
+#define IMX8MN_GPU_PLL                         22
+#define IMX8MN_VPU_PLL                         23
+#define IMX8MN_ARM_PLL                         24
+#define IMX8MN_SYS_PLL1                                25
+#define IMX8MN_SYS_PLL2                                26
+#define IMX8MN_SYS_PLL3                                27
+#define IMX8MN_AUDIO_PLL1_BYPASS               28
+#define IMX8MN_AUDIO_PLL2_BYPASS               29
+#define IMX8MN_VIDEO_PLL1_BYPASS               30
+#define IMX8MN_DRAM_PLL_BYPASS                 31
+#define IMX8MN_GPU_PLL_BYPASS                  32
+#define IMX8MN_VPU_PLL_BYPASS                  33
+#define IMX8MN_ARM_PLL_BYPASS                  34
+#define IMX8MN_SYS_PLL1_BYPASS                 35
+#define IMX8MN_SYS_PLL2_BYPASS                 36
+#define IMX8MN_SYS_PLL3_BYPASS                 37
+#define IMX8MN_AUDIO_PLL1_OUT                  38
+#define IMX8MN_AUDIO_PLL2_OUT                  39
+#define IMX8MN_VIDEO_PLL1_OUT                  40
+#define IMX8MN_DRAM_PLL_OUT                    41
+#define IMX8MN_GPU_PLL_OUT                     42
+#define IMX8MN_VPU_PLL_OUT                     43
+#define IMX8MN_ARM_PLL_OUT                     44
+#define IMX8MN_SYS_PLL1_OUT                    45
+#define IMX8MN_SYS_PLL2_OUT                    46
+#define IMX8MN_SYS_PLL3_OUT                    47
+#define IMX8MN_SYS_PLL1_40M                    48
+#define IMX8MN_SYS_PLL1_80M                    49
+#define IMX8MN_SYS_PLL1_100M                   50
+#define IMX8MN_SYS_PLL1_133M                   51
+#define IMX8MN_SYS_PLL1_160M                   52
+#define IMX8MN_SYS_PLL1_200M                   53
+#define IMX8MN_SYS_PLL1_266M                   54
+#define IMX8MN_SYS_PLL1_400M                   55
+#define IMX8MN_SYS_PLL1_800M                   56
+#define IMX8MN_SYS_PLL2_50M                    57
+#define IMX8MN_SYS_PLL2_100M                   58
+#define IMX8MN_SYS_PLL2_125M                   59
+#define IMX8MN_SYS_PLL2_166M                   60
+#define IMX8MN_SYS_PLL2_200M                   61
+#define IMX8MN_SYS_PLL2_250M                   62
+#define IMX8MN_SYS_PLL2_333M                   63
+#define IMX8MN_SYS_PLL2_500M                   64
+#define IMX8MN_SYS_PLL2_1000M                  65
+
+/* CORE CLOCK ROOT */
+#define IMX8MN_CLK_A53_SRC                     66
+#define IMX8MN_CLK_GPU_CORE_SRC                        67
+#define IMX8MN_CLK_GPU_SHADER_SRC              68
+#define IMX8MN_CLK_A53_CG                      69
+#define IMX8MN_CLK_GPU_CORE_CG                 70
+#define IMX8MN_CLK_GPU_SHADER_CG               71
+#define IMX8MN_CLK_A53_DIV                     72
+#define IMX8MN_CLK_GPU_CORE_DIV                        73
+#define IMX8MN_CLK_GPU_SHADER_DIV              74
+
+/* BUS CLOCK ROOT */
+#define IMX8MN_CLK_MAIN_AXI                    75
+#define IMX8MN_CLK_ENET_AXI                    76
+#define IMX8MN_CLK_NAND_USDHC_BUS              77
+#define IMX8MN_CLK_DISP_AXI                    78
+#define IMX8MN_CLK_DISP_APB                    79
+#define IMX8MN_CLK_USB_BUS                     80
+#define IMX8MN_CLK_GPU_AXI                     81
+#define IMX8MN_CLK_GPU_AHB                     82
+#define IMX8MN_CLK_NOC                         83
+#define IMX8MN_CLK_AHB                         84
+#define IMX8MN_CLK_AUDIO_AHB                   85
+
+/* IPG CLOCK ROOT */
+#define IMX8MN_CLK_IPG_ROOT                    86
+#define IMX8MN_CLK_IPG_AUDIO_ROOT              87
+
+/* IP */
+#define IMX8MN_CLK_DRAM_CORE                   88
+#define IMX8MN_CLK_DRAM_ALT                    89
+#define IMX8MN_CLK_DRAM_APB                    90
+#define IMX8MN_CLK_DRAM_ALT_ROOT               91
+#define IMX8MN_CLK_DISP_PIXEL                  92
+#define IMX8MN_CLK_SAI2                                93
+#define IMX8MN_CLK_SAI3                                94
+#define IMX8MN_CLK_SAI5                                95
+#define IMX8MN_CLK_SAI6                                96
+#define IMX8MN_CLK_SPDIF1                      97
+#define IMX8MN_CLK_ENET_REF                    98
+#define IMX8MN_CLK_ENET_TIMER                  99
+#define IMX8MN_CLK_ENET_PHY_REF                        100
+#define IMX8MN_CLK_NAND                                101
+#define IMX8MN_CLK_QSPI                                102
+#define IMX8MN_CLK_USDHC1                      103
+#define IMX8MN_CLK_USDHC2                      104
+#define IMX8MN_CLK_I2C1                                105
+#define IMX8MN_CLK_I2C2                                106
+#define IMX8MN_CLK_I2C3                                107
+#define IMX8MN_CLK_I2C4                                118
+#define IMX8MN_CLK_UART1                       119
+#define IMX8MN_CLK_UART2                       110
+#define IMX8MN_CLK_UART3                       111
+#define IMX8MN_CLK_UART4                       112
+#define IMX8MN_CLK_USB_CORE_REF                        113
+#define IMX8MN_CLK_USB_PHY_REF                 114
+#define IMX8MN_CLK_ECSPI1                      115
+#define IMX8MN_CLK_ECSPI2                      116
+#define IMX8MN_CLK_PWM1                                117
+#define IMX8MN_CLK_PWM2                                118
+#define IMX8MN_CLK_PWM3                                119
+#define IMX8MN_CLK_PWM4                                120
+#define IMX8MN_CLK_WDOG                                121
+#define IMX8MN_CLK_WRCLK                       122
+#define IMX8MN_CLK_CLKO1                       123
+#define IMX8MN_CLK_CLKO2                       124
+#define IMX8MN_CLK_DSI_CORE                    125
+#define IMX8MN_CLK_DSI_PHY_REF                 126
+#define IMX8MN_CLK_DSI_DBI                     127
+#define IMX8MN_CLK_USDHC3                      128
+#define IMX8MN_CLK_CAMERA_PIXEL                        129
+#define IMX8MN_CLK_CSI1_PHY_REF                        130
+#define IMX8MN_CLK_CSI2_PHY_REF                        131
+#define IMX8MN_CLK_CSI2_ESC                    132
+#define IMX8MN_CLK_ECSPI3                      133
+#define IMX8MN_CLK_PDM                         134
+#define IMX8MN_CLK_SAI7                                135
+
+#define IMX8MN_CLK_ECSPI1_ROOT                 136
+#define IMX8MN_CLK_ECSPI2_ROOT                 137
+#define IMX8MN_CLK_ECSPI3_ROOT                 138
+#define IMX8MN_CLK_ENET1_ROOT                  139
+#define IMX8MN_CLK_GPIO1_ROOT                  140
+#define IMX8MN_CLK_GPIO2_ROOT                  141
+#define IMX8MN_CLK_GPIO3_ROOT                  142
+#define IMX8MN_CLK_GPIO4_ROOT                  143
+#define IMX8MN_CLK_GPIO5_ROOT                  144
+#define IMX8MN_CLK_I2C1_ROOT                   145
+#define IMX8MN_CLK_I2C2_ROOT                   146
+#define IMX8MN_CLK_I2C3_ROOT                   147
+#define IMX8MN_CLK_I2C4_ROOT                   148
+#define IMX8MN_CLK_MU_ROOT                     149
+#define IMX8MN_CLK_OCOTP_ROOT                  150
+#define IMX8MN_CLK_PWM1_ROOT                   151
+#define IMX8MN_CLK_PWM2_ROOT                   152
+#define IMX8MN_CLK_PWM3_ROOT                   153
+#define IMX8MN_CLK_PWM4_ROOT                   154
+#define IMX8MN_CLK_QSPI_ROOT                   155
+#define IMX8MN_CLK_NAND_ROOT                   156
+#define IMX8MN_CLK_SAI2_ROOT                   157
+#define IMX8MN_CLK_SAI2_IPG                    158
+#define IMX8MN_CLK_SAI3_ROOT                   159
+#define IMX8MN_CLK_SAI3_IPG                    160
+#define IMX8MN_CLK_SAI5_ROOT                   161
+#define IMX8MN_CLK_SAI5_IPG                    162
+#define IMX8MN_CLK_SAI6_ROOT                   163
+#define IMX8MN_CLK_SAI6_IPG                    164
+#define IMX8MN_CLK_SAI7_ROOT                   165
+#define IMX8MN_CLK_SAI7_IPG                    166
+#define IMX8MN_CLK_SDMA1_ROOT                  167
+#define IMX8MN_CLK_SDMA2_ROOT                  168
+#define IMX8MN_CLK_UART1_ROOT                  169
+#define IMX8MN_CLK_UART2_ROOT                  170
+#define IMX8MN_CLK_UART3_ROOT                  171
+#define IMX8MN_CLK_UART4_ROOT                  172
+#define IMX8MN_CLK_USB1_CTRL_ROOT              173
+#define IMX8MN_CLK_USDHC1_ROOT                 174
+#define IMX8MN_CLK_USDHC2_ROOT                 175
+#define IMX8MN_CLK_WDOG1_ROOT                  176
+#define IMX8MN_CLK_WDOG2_ROOT                  177
+#define IMX8MN_CLK_WDOG3_ROOT                  178
+#define IMX8MN_CLK_GPU_BUS_ROOT                        179
+#define IMX8MN_CLK_ASRC_ROOT                   180
+#define IMX8MN_CLK_GPU3D_ROOT                  181
+#define IMX8MN_CLK_PDM_ROOT                    182
+#define IMX8MN_CLK_PDM_IPG                     183
+#define IMX8MN_CLK_DISP_AXI_ROOT               184
+#define IMX8MN_CLK_DISP_APB_ROOT               185
+#define IMX8MN_CLK_DISP_PIXEL_ROOT             186
+#define IMX8MN_CLK_CAMERA_PIXEL_ROOT           187
+#define IMX8MN_CLK_USDHC3_ROOT                 188
+#define IMX8MN_CLK_SDMA3_ROOT                  189
+#define IMX8MN_CLK_TMU_ROOT                    190
+#define IMX8MN_CLK_ARM                         191
+#define IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK  192
+#define IMX8MN_CLK_GPU_CORE_ROOT               193
+#define IMX8MN_CLK_GIC                         194
+
+#define IMX8MN_CLK_END                         195
+
+#endif
diff --git a/include/dt-bindings/clock/mt6779-clk.h b/include/dt-bindings/clock/mt6779-clk.h
new file mode 100644 (file)
index 0000000..b083139
--- /dev/null
@@ -0,0 +1,436 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Wendell Lin <wendell.lin@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT6779_H
+#define _DT_BINDINGS_CLK_MT6779_H
+
+/* TOPCKGEN */
+#define CLK_TOP_AXI                    1
+#define CLK_TOP_MM                     2
+#define CLK_TOP_CAM                    3
+#define CLK_TOP_MFG                    4
+#define CLK_TOP_CAMTG                  5
+#define CLK_TOP_UART                   6
+#define CLK_TOP_SPI                    7
+#define CLK_TOP_MSDC50_0_HCLK          8
+#define CLK_TOP_MSDC50_0               9
+#define CLK_TOP_MSDC30_1               10
+#define CLK_TOP_MSDC30_2               11
+#define CLK_TOP_AUD                    12
+#define CLK_TOP_AUD_INTBUS             13
+#define CLK_TOP_FPWRAP_ULPOSC          14
+#define CLK_TOP_SCP                    15
+#define CLK_TOP_ATB                    16
+#define CLK_TOP_SSPM                   17
+#define CLK_TOP_DPI0                   18
+#define CLK_TOP_SCAM                   19
+#define CLK_TOP_AUD_1                  20
+#define CLK_TOP_AUD_2                  21
+#define CLK_TOP_DISP_PWM               22
+#define CLK_TOP_SSUSB_TOP_XHCI         23
+#define CLK_TOP_USB_TOP                        24
+#define CLK_TOP_SPM                    25
+#define CLK_TOP_I2C                    26
+#define CLK_TOP_F52M_MFG               27
+#define CLK_TOP_SENINF                 28
+#define CLK_TOP_DXCC                   29
+#define CLK_TOP_CAMTG2                 30
+#define CLK_TOP_AUD_ENG1               31
+#define CLK_TOP_AUD_ENG2               32
+#define CLK_TOP_FAES_UFSFDE            33
+#define CLK_TOP_FUFS                   34
+#define CLK_TOP_IMG                    35
+#define CLK_TOP_DSP                    36
+#define CLK_TOP_DSP1                   37
+#define CLK_TOP_DSP2                   38
+#define CLK_TOP_IPU_IF                 39
+#define CLK_TOP_CAMTG3                 40
+#define CLK_TOP_CAMTG4                 41
+#define CLK_TOP_PMICSPI                        42
+#define CLK_TOP_MAINPLL_CK             43
+#define CLK_TOP_MAINPLL_D2             44
+#define CLK_TOP_MAINPLL_D3             45
+#define CLK_TOP_MAINPLL_D5             46
+#define CLK_TOP_MAINPLL_D7             47
+#define CLK_TOP_MAINPLL_D2_D2          48
+#define CLK_TOP_MAINPLL_D2_D4          49
+#define CLK_TOP_MAINPLL_D2_D8          50
+#define CLK_TOP_MAINPLL_D2_D16         51
+#define CLK_TOP_MAINPLL_D3_D2          52
+#define CLK_TOP_MAINPLL_D3_D4          53
+#define CLK_TOP_MAINPLL_D3_D8          54
+#define CLK_TOP_MAINPLL_D5_D2          55
+#define CLK_TOP_MAINPLL_D5_D4          56
+#define CLK_TOP_MAINPLL_D7_D2          57
+#define CLK_TOP_MAINPLL_D7_D4          58
+#define CLK_TOP_UNIVPLL_CK             59
+#define CLK_TOP_UNIVPLL_D2             60
+#define CLK_TOP_UNIVPLL_D3             61
+#define CLK_TOP_UNIVPLL_D5             62
+#define CLK_TOP_UNIVPLL_D7             63
+#define CLK_TOP_UNIVPLL_D2_D2          64
+#define CLK_TOP_UNIVPLL_D2_D4          65
+#define CLK_TOP_UNIVPLL_D2_D8          66
+#define CLK_TOP_UNIVPLL_D3_D2          67
+#define CLK_TOP_UNIVPLL_D3_D4          68
+#define CLK_TOP_UNIVPLL_D3_D8          69
+#define CLK_TOP_UNIVPLL_D5_D2          70
+#define CLK_TOP_UNIVPLL_D5_D4          71
+#define CLK_TOP_UNIVPLL_D5_D8          72
+#define CLK_TOP_APLL1_CK               73
+#define CLK_TOP_APLL1_D2               74
+#define CLK_TOP_APLL1_D4               75
+#define CLK_TOP_APLL1_D8               76
+#define CLK_TOP_APLL2_CK               77
+#define CLK_TOP_APLL2_D2               78
+#define CLK_TOP_APLL2_D4               79
+#define CLK_TOP_APLL2_D8               80
+#define CLK_TOP_TVDPLL_CK              81
+#define CLK_TOP_TVDPLL_D2              82
+#define CLK_TOP_TVDPLL_D4              83
+#define CLK_TOP_TVDPLL_D8              84
+#define CLK_TOP_TVDPLL_D16             85
+#define CLK_TOP_MSDCPLL_CK             86
+#define CLK_TOP_MSDCPLL_D2             87
+#define CLK_TOP_MSDCPLL_D4             88
+#define CLK_TOP_MSDCPLL_D8             89
+#define CLK_TOP_MSDCPLL_D16            90
+#define CLK_TOP_AD_OSC_CK              91
+#define CLK_TOP_OSC_D2                 92
+#define CLK_TOP_OSC_D4                 93
+#define CLK_TOP_OSC_D8                 94
+#define CLK_TOP_OSC_D16                        95
+#define CLK_TOP_F26M_CK_D2             96
+#define CLK_TOP_MFGPLL_CK              97
+#define CLK_TOP_UNIVP_192M_CK          98
+#define CLK_TOP_UNIVP_192M_D2          99
+#define CLK_TOP_UNIVP_192M_D4          100
+#define CLK_TOP_UNIVP_192M_D8          101
+#define CLK_TOP_UNIVP_192M_D16         102
+#define CLK_TOP_UNIVP_192M_D32         103
+#define CLK_TOP_MMPLL_CK               104
+#define CLK_TOP_MMPLL_D4               105
+#define CLK_TOP_MMPLL_D4_D2            106
+#define CLK_TOP_MMPLL_D4_D4            107
+#define CLK_TOP_MMPLL_D5               108
+#define CLK_TOP_MMPLL_D5_D2            109
+#define CLK_TOP_MMPLL_D5_D4            110
+#define CLK_TOP_MMPLL_D6               111
+#define CLK_TOP_MMPLL_D7               112
+#define CLK_TOP_CLK26M                 113
+#define CLK_TOP_CLK13M                 114
+#define CLK_TOP_ADSP                   115
+#define CLK_TOP_DPMAIF                 116
+#define CLK_TOP_VENC                   117
+#define CLK_TOP_VDEC                   118
+#define CLK_TOP_CAMTM                  119
+#define CLK_TOP_PWM                    120
+#define CLK_TOP_ADSPPLL_CK             121
+#define CLK_TOP_I2S0_M_SEL             122
+#define CLK_TOP_I2S1_M_SEL             123
+#define CLK_TOP_I2S2_M_SEL             124
+#define CLK_TOP_I2S3_M_SEL             125
+#define CLK_TOP_I2S4_M_SEL             126
+#define CLK_TOP_I2S5_M_SEL             127
+#define CLK_TOP_APLL12_DIV0            128
+#define CLK_TOP_APLL12_DIV1            129
+#define CLK_TOP_APLL12_DIV2            130
+#define CLK_TOP_APLL12_DIV3            131
+#define CLK_TOP_APLL12_DIV4            132
+#define CLK_TOP_APLL12_DIVB            133
+#define CLK_TOP_APLL12_DIV5            134
+#define CLK_TOP_IPE                    135
+#define CLK_TOP_DPE                    136
+#define CLK_TOP_CCU                    137
+#define CLK_TOP_DSP3                   138
+#define CLK_TOP_SENINF1                        139
+#define CLK_TOP_SENINF2                        140
+#define CLK_TOP_AUD_H                  141
+#define CLK_TOP_CAMTG5                 142
+#define CLK_TOP_TVDPLL_MAINPLL_D2_CK   143
+#define CLK_TOP_AD_OSC2_CK             144
+#define CLK_TOP_OSC2_D2                        145
+#define CLK_TOP_OSC2_D3                        146
+#define CLK_TOP_FMEM_466M_CK           147
+#define CLK_TOP_ADSPPLL_D4             148
+#define CLK_TOP_ADSPPLL_D5             149
+#define CLK_TOP_ADSPPLL_D6             150
+#define CLK_TOP_OSC_D10                        151
+#define CLK_TOP_UNIVPLL_D3_D16         152
+#define CLK_TOP_NR_CLK                 153
+
+/* APMIXED */
+#define CLK_APMIXED_ARMPLL_LL          1
+#define CLK_APMIXED_ARMPLL_BL          2
+#define CLK_APMIXED_ARMPLL_BB          3
+#define CLK_APMIXED_CCIPLL             4
+#define CLK_APMIXED_MAINPLL            5
+#define CLK_APMIXED_UNIV2PLL           6
+#define CLK_APMIXED_MSDCPLL            7
+#define CLK_APMIXED_ADSPPLL            8
+#define CLK_APMIXED_MMPLL              9
+#define CLK_APMIXED_MFGPLL             10
+#define CLK_APMIXED_TVDPLL             11
+#define CLK_APMIXED_APLL1              12
+#define CLK_APMIXED_APLL2              13
+#define CLK_APMIXED_SSUSB26M           14
+#define CLK_APMIXED_APPLL26M           15
+#define CLK_APMIXED_MIPIC0_26M         16
+#define CLK_APMIXED_MDPLLGP26M         17
+#define CLK_APMIXED_MM_F26M            18
+#define CLK_APMIXED_UFS26M             19
+#define CLK_APMIXED_MIPIC1_26M         20
+#define CLK_APMIXED_MEMPLL26M          21
+#define CLK_APMIXED_CLKSQ_LVPLL_26M    22
+#define CLK_APMIXED_MIPID0_26M         23
+#define CLK_APMIXED_MIPID1_26M         24
+#define CLK_APMIXED_NR_CLK             25
+
+/* CAMSYS */
+#define CLK_CAM_LARB10                 1
+#define CLK_CAM_DFP_VAD                        2
+#define CLK_CAM_LARB11                 3
+#define CLK_CAM_LARB9                  4
+#define CLK_CAM_CAM                    5
+#define CLK_CAM_CAMTG                  6
+#define CLK_CAM_SENINF                 7
+#define CLK_CAM_CAMSV0                 8
+#define CLK_CAM_CAMSV1                 9
+#define CLK_CAM_CAMSV2                 10
+#define CLK_CAM_CAMSV3                 11
+#define CLK_CAM_CCU                    12
+#define CLK_CAM_FAKE_ENG               13
+#define CLK_CAM_NR_CLK                 14
+
+/* INFRA */
+#define CLK_INFRA_PMIC_TMR             1
+#define CLK_INFRA_PMIC_AP              2
+#define CLK_INFRA_PMIC_MD              3
+#define CLK_INFRA_PMIC_CONN            4
+#define CLK_INFRA_SCPSYS               5
+#define CLK_INFRA_SEJ                  6
+#define CLK_INFRA_APXGPT               7
+#define CLK_INFRA_ICUSB                        8
+#define CLK_INFRA_GCE                  9
+#define CLK_INFRA_THERM                        10
+#define CLK_INFRA_I2C0                 11
+#define CLK_INFRA_I2C1                 12
+#define CLK_INFRA_I2C2                 13
+#define CLK_INFRA_I2C3                 14
+#define CLK_INFRA_PWM_HCLK             15
+#define CLK_INFRA_PWM1                 16
+#define CLK_INFRA_PWM2                 17
+#define CLK_INFRA_PWM3                 18
+#define CLK_INFRA_PWM4                 19
+#define CLK_INFRA_PWM                  20
+#define CLK_INFRA_UART0                        21
+#define CLK_INFRA_UART1                        22
+#define CLK_INFRA_UART2                        23
+#define CLK_INFRA_UART3                        24
+#define CLK_INFRA_GCE_26M              25
+#define CLK_INFRA_CQ_DMA_FPC           26
+#define CLK_INFRA_BTIF                 27
+#define CLK_INFRA_SPI0                 28
+#define CLK_INFRA_MSDC0                        29
+#define CLK_INFRA_MSDC1                        30
+#define CLK_INFRA_MSDC2                        31
+#define CLK_INFRA_MSDC0_SCK            32
+#define CLK_INFRA_DVFSRC               33
+#define CLK_INFRA_GCPU                 34
+#define CLK_INFRA_TRNG                 35
+#define CLK_INFRA_AUXADC               36
+#define CLK_INFRA_CPUM                 37
+#define CLK_INFRA_CCIF1_AP             38
+#define CLK_INFRA_CCIF1_MD             39
+#define CLK_INFRA_AUXADC_MD            40
+#define CLK_INFRA_MSDC1_SCK            41
+#define CLK_INFRA_MSDC2_SCK            42
+#define CLK_INFRA_AP_DMA               43
+#define CLK_INFRA_XIU                  44
+#define CLK_INFRA_DEVICE_APC           45
+#define CLK_INFRA_CCIF_AP              46
+#define CLK_INFRA_DEBUGSYS             47
+#define CLK_INFRA_AUD                  48
+#define CLK_INFRA_CCIF_MD              49
+#define CLK_INFRA_DXCC_SEC_CORE                50
+#define CLK_INFRA_DXCC_AO              51
+#define CLK_INFRA_DRAMC_F26M           52
+#define CLK_INFRA_IRTX                 53
+#define CLK_INFRA_DISP_PWM             54
+#define CLK_INFRA_DPMAIF_CK            55
+#define CLK_INFRA_AUD_26M_BCLK         56
+#define CLK_INFRA_SPI1                 57
+#define CLK_INFRA_I2C4                 58
+#define CLK_INFRA_MODEM_TEMP_SHARE     59
+#define CLK_INFRA_SPI2                 60
+#define CLK_INFRA_SPI3                 61
+#define CLK_INFRA_UNIPRO_SCK           62
+#define CLK_INFRA_UNIPRO_TICK          63
+#define CLK_INFRA_UFS_MP_SAP_BCLK      64
+#define CLK_INFRA_MD32_BCLK            65
+#define CLK_INFRA_SSPM                 66
+#define CLK_INFRA_UNIPRO_MBIST         67
+#define CLK_INFRA_SSPM_BUS_HCLK                68
+#define CLK_INFRA_I2C5                 69
+#define CLK_INFRA_I2C5_ARBITER         70
+#define CLK_INFRA_I2C5_IMM             71
+#define CLK_INFRA_I2C1_ARBITER         72
+#define CLK_INFRA_I2C1_IMM             73
+#define CLK_INFRA_I2C2_ARBITER         74
+#define CLK_INFRA_I2C2_IMM             75
+#define CLK_INFRA_SPI4                 76
+#define CLK_INFRA_SPI5                 77
+#define CLK_INFRA_CQ_DMA               78
+#define CLK_INFRA_UFS                  79
+#define CLK_INFRA_AES_UFSFDE           80
+#define CLK_INFRA_UFS_TICK             81
+#define CLK_INFRA_MSDC0_SELF           82
+#define CLK_INFRA_MSDC1_SELF           83
+#define CLK_INFRA_MSDC2_SELF           84
+#define CLK_INFRA_SSPM_26M_SELF                85
+#define CLK_INFRA_SSPM_32K_SELF                86
+#define CLK_INFRA_UFS_AXI              87
+#define CLK_INFRA_I2C6                 88
+#define CLK_INFRA_AP_MSDC0             89
+#define CLK_INFRA_MD_MSDC0             90
+#define CLK_INFRA_USB                  91
+#define CLK_INFRA_DEVMPU_BCLK          92
+#define CLK_INFRA_CCIF2_AP             93
+#define CLK_INFRA_CCIF2_MD             94
+#define CLK_INFRA_CCIF3_AP             95
+#define CLK_INFRA_CCIF3_MD             96
+#define CLK_INFRA_SEJ_F13M             97
+#define CLK_INFRA_AES_BCLK             98
+#define CLK_INFRA_I2C7                 99
+#define CLK_INFRA_I2C8                 100
+#define CLK_INFRA_FBIST2FPC            101
+#define CLK_INFRA_CCIF4_AP             102
+#define CLK_INFRA_CCIF4_MD             103
+#define CLK_INFRA_FADSP                        104
+#define CLK_INFRA_SSUSB_XHCI           105
+#define CLK_INFRA_SPI6                 106
+#define CLK_INFRA_SPI7                 107
+#define CLK_INFRA_NR_CLK               108
+
+/* MFGCFG */
+#define CLK_MFGCFG_BG3D                        1
+#define CLK_MFGCFG_NR_CLK              2
+
+/* IMG */
+#define CLK_IMG_WPE_A                  1
+#define CLK_IMG_MFB                    2
+#define CLK_IMG_DIP                    3
+#define CLK_IMG_LARB6                  4
+#define CLK_IMG_LARB5                  5
+#define CLK_IMG_NR_CLK                 6
+
+/* IPE */
+#define CLK_IPE_LARB7                  1
+#define CLK_IPE_LARB8                  2
+#define CLK_IPE_SMI_SUBCOM             3
+#define CLK_IPE_FD                     4
+#define CLK_IPE_FE                     5
+#define CLK_IPE_RSC                    6
+#define CLK_IPE_DPE                    7
+#define CLK_IPE_NR_CLK                 8
+
+/* MM_CONFIG */
+#define CLK_MM_SMI_COMMON              1
+#define CLK_MM_SMI_LARB0               2
+#define CLK_MM_SMI_LARB1               3
+#define CLK_MM_GALS_COMM0              4
+#define CLK_MM_GALS_COMM1              5
+#define CLK_MM_GALS_CCU2MM             6
+#define CLK_MM_GALS_IPU12MM            7
+#define CLK_MM_GALS_IMG2MM             8
+#define CLK_MM_GALS_CAM2MM             9
+#define CLK_MM_GALS_IPU2MM             10
+#define CLK_MM_MDP_DL_TXCK             11
+#define CLK_MM_IPU_DL_TXCK             12
+#define CLK_MM_MDP_RDMA0               13
+#define CLK_MM_MDP_RDMA1               14
+#define CLK_MM_MDP_RSZ0                        15
+#define CLK_MM_MDP_RSZ1                        16
+#define CLK_MM_MDP_TDSHP               17
+#define CLK_MM_MDP_WROT0               18
+#define CLK_MM_FAKE_ENG                        19
+#define CLK_MM_DISP_OVL0               20
+#define CLK_MM_DISP_OVL0_2L            21
+#define CLK_MM_DISP_OVL1_2L            22
+#define CLK_MM_DISP_RDMA0              23
+#define CLK_MM_DISP_RDMA1              24
+#define CLK_MM_DISP_WDMA0              25
+#define CLK_MM_DISP_COLOR0             26
+#define CLK_MM_DISP_CCORR0             27
+#define CLK_MM_DISP_AAL0               28
+#define CLK_MM_DISP_GAMMA0             29
+#define CLK_MM_DISP_DITHER0            30
+#define CLK_MM_DISP_SPLIT              31
+#define CLK_MM_DSI0_MM_CK              32
+#define CLK_MM_DSI0_IF_CK              33
+#define CLK_MM_DPI_MM_CK               34
+#define CLK_MM_DPI_IF_CK               35
+#define CLK_MM_FAKE_ENG2               36
+#define CLK_MM_MDP_DL_RX_CK            37
+#define CLK_MM_IPU_DL_RX_CK            38
+#define CLK_MM_26M                     39
+#define CLK_MM_MM_R2Y                  40
+#define CLK_MM_DISP_RSZ                        41
+#define CLK_MM_MDP_WDMA0               42
+#define CLK_MM_MDP_AAL                 43
+#define CLK_MM_MDP_HDR                 44
+#define CLK_MM_DBI_MM_CK               45
+#define CLK_MM_DBI_IF_CK               46
+#define CLK_MM_MDP_WROT1               47
+#define CLK_MM_DISP_POSTMASK0          48
+#define CLK_MM_DISP_HRT_BW             49
+#define CLK_MM_DISP_OVL_FBDC           50
+#define CLK_MM_NR_CLK                  51
+
+/* VDEC_GCON */
+#define CLK_VDEC_VDEC                  1
+#define CLK_VDEC_LARB1                 2
+#define CLK_VDEC_GCON_NR_CLK           3
+
+/* VENC_GCON */
+#define CLK_VENC_GCON_LARB             1
+#define CLK_VENC_GCON_VENC             2
+#define CLK_VENC_GCON_JPGENC           3
+#define CLK_VENC_GCON_GALS             4
+#define CLK_VENC_GCON_NR_CLK           5
+
+/* AUD */
+#define CLK_AUD_AFE                    1
+#define CLK_AUD_22M                    2
+#define CLK_AUD_24M                    3
+#define CLK_AUD_APLL2_TUNER            4
+#define CLK_AUD_APLL_TUNER             5
+#define CLK_AUD_TDM                    6
+#define CLK_AUD_ADC                    7
+#define CLK_AUD_DAC                    8
+#define CLK_AUD_DAC_PREDIS             9
+#define CLK_AUD_TML                    10
+#define CLK_AUD_NLE                    11
+#define CLK_AUD_I2S1_BCLK_SW           12
+#define CLK_AUD_I2S2_BCLK_SW           13
+#define CLK_AUD_I2S3_BCLK_SW           14
+#define CLK_AUD_I2S4_BCLK_SW           15
+#define CLK_AUD_I2S5_BCLK_SW           16
+#define CLK_AUD_CONN_I2S_ASRC          17
+#define CLK_AUD_GENERAL1_ASRC          18
+#define CLK_AUD_GENERAL2_ASRC          19
+#define CLK_AUD_DAC_HIRES              20
+#define CLK_AUD_PDN_ADDA6_ADC          21
+#define CLK_AUD_ADC_HIRES              22
+#define CLK_AUD_ADC_HIRES_TML          23
+#define CLK_AUD_ADDA6_ADC_HIRES                24
+#define CLK_AUD_3RD_DAC                        25
+#define CLK_AUD_3RD_DAC_PREDIS         26
+#define CLK_AUD_3RD_DAC_TML            27
+#define CLK_AUD_3RD_DAC_HIRES          28
+#define CLK_AUD_NR_CLK                 29
+
+#endif /* _DT_BINDINGS_CLK_MT6779_H */
index 0046506eb24c3ac98bae4e431a9d5229c79e5c68..a7b470b0ec8ab41bd5198cd78430ec08fc608c01 100644 (file)
 #define CLK_INFRA_FBIST2FPC            100
 #define CLK_INFRA_NR_CLK               101
 
+/* PERICFG */
+#define CLK_PERI_AXI                   0
+#define CLK_PERI_NR_CLK                        1
+
 /* MFGCFG */
 #define CLK_MFG_BG3D                   0
 #define CLK_MFG_NR_CLK                 1
index 2cd62c98561f5c224c09f9761d847a88c2c592f0..bc3051543347066e3eac92cdc7e989b9ef2ae41e 100644 (file)
 #define GCC_MDP_TBU_CLK                                        138
 #define GCC_QDSS_DAP_CLK                               139
 #define GCC_DCC_XO_CLK                                 140
+#define GCC_WCSS_Q6_AHB_CLK                            141
+#define GCC_WCSS_Q6_AXIM_CLK                           142
 #define GCC_CDSP_CFG_AHB_CLK                           143
 #define GCC_BIMC_CDSP_CLK                              144
 #define GCC_CDSP_TBU_CLK                               145
 #define GCC_PCIE_0_CORE_STICKY_ARES                    19
 #define GCC_PCIE_0_SLEEP_ARES                          20
 #define GCC_PCIE_0_PIPE_ARES                           21
+#define GCC_WDSP_RESTART                               22
 
 #endif
diff --git a/include/dt-bindings/clock/qcom,gcc-sm8150.h b/include/dt-bindings/clock/qcom,gcc-sm8150.h
new file mode 100644 (file)
index 0000000..90d60ef
--- /dev/null
@@ -0,0 +1,243 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SM8150_H
+#define _DT_BINDINGS_CLK_QCOM_GCC_SM8150_H
+
+/* GCC clocks */
+#define GCC_AGGRE_NOC_PCIE_TBU_CLK                             0
+#define GCC_AGGRE_UFS_CARD_AXI_CLK                             1
+#define GCC_AGGRE_UFS_CARD_AXI_HW_CTL_CLK                      2
+#define GCC_AGGRE_UFS_PHY_AXI_CLK                              3
+#define GCC_AGGRE_UFS_PHY_AXI_HW_CTL_CLK                       4
+#define GCC_AGGRE_USB3_PRIM_AXI_CLK                            5
+#define GCC_AGGRE_USB3_SEC_AXI_CLK                             6
+#define GCC_BOOT_ROM_AHB_CLK                                   7
+#define GCC_CAMERA_AHB_CLK                                     8
+#define GCC_CAMERA_HF_AXI_CLK                                  9
+#define GCC_CAMERA_SF_AXI_CLK                                  10
+#define GCC_CAMERA_XO_CLK                                      11
+#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK                          12
+#define GCC_CFG_NOC_USB3_SEC_AXI_CLK                           13
+#define GCC_CPUSS_AHB_CLK                                      14
+#define GCC_CPUSS_AHB_CLK_SRC                                  15
+#define GCC_CPUSS_DVM_BUS_CLK                                  16
+#define GCC_CPUSS_GNOC_CLK                                     17
+#define GCC_CPUSS_RBCPR_CLK                                    18
+#define GCC_DDRSS_GPU_AXI_CLK                                  19
+#define GCC_DISP_AHB_CLK                                       20
+#define GCC_DISP_HF_AXI_CLK                                    21
+#define GCC_DISP_SF_AXI_CLK                                    22
+#define GCC_DISP_XO_CLK                                                23
+#define GCC_EMAC_AXI_CLK                                       24
+#define GCC_EMAC_PTP_CLK                                       25
+#define GCC_EMAC_PTP_CLK_SRC                                   26
+#define GCC_EMAC_RGMII_CLK                                     27
+#define GCC_EMAC_RGMII_CLK_SRC                                 28
+#define GCC_EMAC_SLV_AHB_CLK                                   29
+#define GCC_GP1_CLK                                            30
+#define GCC_GP1_CLK_SRC                                                31
+#define GCC_GP2_CLK                                            32
+#define GCC_GP2_CLK_SRC                                                33
+#define GCC_GP3_CLK                                            34
+#define GCC_GP3_CLK_SRC                                                35
+#define GCC_GPU_CFG_AHB_CLK                                    36
+#define GCC_GPU_GPLL0_CLK_SRC                                  37
+#define GCC_GPU_GPLL0_DIV_CLK_SRC                              38
+#define GCC_GPU_IREF_CLK                                       39
+#define GCC_GPU_MEMNOC_GFX_CLK                                 40
+#define GCC_GPU_SNOC_DVM_GFX_CLK                               41
+#define GCC_NPU_AT_CLK                                         42
+#define GCC_NPU_AXI_CLK                                                43
+#define GCC_NPU_CFG_AHB_CLK                                    44
+#define GCC_NPU_GPLL0_CLK_SRC                                  45
+#define GCC_NPU_GPLL0_DIV_CLK_SRC                              46
+#define GCC_NPU_TRIG_CLK                                       47
+#define GCC_PCIE0_PHY_REFGEN_CLK                               48
+#define GCC_PCIE1_PHY_REFGEN_CLK                               49
+#define GCC_PCIE_0_AUX_CLK                                     50
+#define GCC_PCIE_0_AUX_CLK_SRC                                 51
+#define GCC_PCIE_0_CFG_AHB_CLK                                 52
+#define GCC_PCIE_0_CLKREF_CLK                                  53
+#define GCC_PCIE_0_MSTR_AXI_CLK                                        54
+#define GCC_PCIE_0_PIPE_CLK                                    55
+#define GCC_PCIE_0_SLV_AXI_CLK                                 56
+#define GCC_PCIE_0_SLV_Q2A_AXI_CLK                             57
+#define GCC_PCIE_1_AUX_CLK                                     58
+#define GCC_PCIE_1_AUX_CLK_SRC                                 59
+#define GCC_PCIE_1_CFG_AHB_CLK                                 60
+#define GCC_PCIE_1_CLKREF_CLK                                  61
+#define GCC_PCIE_1_MSTR_AXI_CLK                                        62
+#define GCC_PCIE_1_PIPE_CLK                                    63
+#define GCC_PCIE_1_SLV_AXI_CLK                                 64
+#define GCC_PCIE_1_SLV_Q2A_AXI_CLK                             65
+#define GCC_PCIE_PHY_AUX_CLK                                   66
+#define GCC_PCIE_PHY_REFGEN_CLK_SRC                            67
+#define GCC_PDM2_CLK                                           68
+#define GCC_PDM2_CLK_SRC                                       69
+#define GCC_PDM_AHB_CLK                                                70
+#define GCC_PDM_XO4_CLK                                                71
+#define GCC_PRNG_AHB_CLK                                       72
+#define GCC_QMIP_CAMERA_NRT_AHB_CLK                            73
+#define GCC_QMIP_CAMERA_RT_AHB_CLK                             74
+#define GCC_QMIP_DISP_AHB_CLK                                  75
+#define GCC_QMIP_VIDEO_CVP_AHB_CLK                             76
+#define GCC_QMIP_VIDEO_VCODEC_AHB_CLK                          77
+#define GCC_QSPI_CNOC_PERIPH_AHB_CLK                           78
+#define GCC_QSPI_CORE_CLK                                      79
+#define GCC_QSPI_CORE_CLK_SRC                                  80
+#define GCC_QUPV3_WRAP0_S0_CLK                                 81
+#define GCC_QUPV3_WRAP0_S0_CLK_SRC                             82
+#define GCC_QUPV3_WRAP0_S1_CLK                                 83
+#define GCC_QUPV3_WRAP0_S1_CLK_SRC                             84
+#define GCC_QUPV3_WRAP0_S2_CLK                                 85
+#define GCC_QUPV3_WRAP0_S2_CLK_SRC                             86
+#define GCC_QUPV3_WRAP0_S3_CLK                                 87
+#define GCC_QUPV3_WRAP0_S3_CLK_SRC                             88
+#define GCC_QUPV3_WRAP0_S4_CLK                                 89
+#define GCC_QUPV3_WRAP0_S4_CLK_SRC                             90
+#define GCC_QUPV3_WRAP0_S5_CLK                                 91
+#define GCC_QUPV3_WRAP0_S5_CLK_SRC                             92
+#define GCC_QUPV3_WRAP0_S6_CLK                                 93
+#define GCC_QUPV3_WRAP0_S6_CLK_SRC                             94
+#define GCC_QUPV3_WRAP0_S7_CLK                                 95
+#define GCC_QUPV3_WRAP0_S7_CLK_SRC                             96
+#define GCC_QUPV3_WRAP1_S0_CLK                                 97
+#define GCC_QUPV3_WRAP1_S0_CLK_SRC                             98
+#define GCC_QUPV3_WRAP1_S1_CLK                                 99
+#define GCC_QUPV3_WRAP1_S1_CLK_SRC                             100
+#define GCC_QUPV3_WRAP1_S2_CLK                                 101
+#define GCC_QUPV3_WRAP1_S2_CLK_SRC                             102
+#define GCC_QUPV3_WRAP1_S3_CLK                                 103
+#define GCC_QUPV3_WRAP1_S3_CLK_SRC                             104
+#define GCC_QUPV3_WRAP1_S4_CLK                                 105
+#define GCC_QUPV3_WRAP1_S4_CLK_SRC                             106
+#define GCC_QUPV3_WRAP1_S5_CLK                                 107
+#define GCC_QUPV3_WRAP1_S5_CLK_SRC                             108
+#define GCC_QUPV3_WRAP2_S0_CLK                                 109
+#define GCC_QUPV3_WRAP2_S0_CLK_SRC                             110
+#define GCC_QUPV3_WRAP2_S1_CLK                                 111
+#define GCC_QUPV3_WRAP2_S1_CLK_SRC                             112
+#define GCC_QUPV3_WRAP2_S2_CLK                                 113
+#define GCC_QUPV3_WRAP2_S2_CLK_SRC                             114
+#define GCC_QUPV3_WRAP2_S3_CLK                                 115
+#define GCC_QUPV3_WRAP2_S3_CLK_SRC                             116
+#define GCC_QUPV3_WRAP2_S4_CLK                                 117
+#define GCC_QUPV3_WRAP2_S4_CLK_SRC                             118
+#define GCC_QUPV3_WRAP2_S5_CLK                                 119
+#define GCC_QUPV3_WRAP2_S5_CLK_SRC                             120
+#define GCC_QUPV3_WRAP_0_M_AHB_CLK                             121
+#define GCC_QUPV3_WRAP_0_S_AHB_CLK                             122
+#define GCC_QUPV3_WRAP_1_M_AHB_CLK                             123
+#define GCC_QUPV3_WRAP_1_S_AHB_CLK                             124
+#define GCC_QUPV3_WRAP_2_M_AHB_CLK                             125
+#define GCC_QUPV3_WRAP_2_S_AHB_CLK                             126
+#define GCC_SDCC2_AHB_CLK                                      127
+#define GCC_SDCC2_APPS_CLK                                     128
+#define GCC_SDCC2_APPS_CLK_SRC                                 129
+#define GCC_SDCC4_AHB_CLK                                      130
+#define GCC_SDCC4_APPS_CLK                                     131
+#define GCC_SDCC4_APPS_CLK_SRC                                 132
+#define GCC_SYS_NOC_CPUSS_AHB_CLK                              133
+#define GCC_TSIF_AHB_CLK                                       134
+#define GCC_TSIF_INACTIVITY_TIMERS_CLK                         135
+#define GCC_TSIF_REF_CLK                                       136
+#define GCC_TSIF_REF_CLK_SRC                                   137
+#define GCC_UFS_CARD_AHB_CLK                                   138
+#define GCC_UFS_CARD_AXI_CLK                                   139
+#define GCC_UFS_CARD_AXI_CLK_SRC                               140
+#define GCC_UFS_CARD_AXI_HW_CTL_CLK                            141
+#define GCC_UFS_CARD_CLKREF_CLK                                        142
+#define GCC_UFS_CARD_ICE_CORE_CLK                              143
+#define GCC_UFS_CARD_ICE_CORE_CLK_SRC                          144
+#define GCC_UFS_CARD_ICE_CORE_HW_CTL_CLK                       145
+#define GCC_UFS_CARD_PHY_AUX_CLK                               146
+#define GCC_UFS_CARD_PHY_AUX_CLK_SRC                           147
+#define GCC_UFS_CARD_PHY_AUX_HW_CTL_CLK                                148
+#define GCC_UFS_CARD_RX_SYMBOL_0_CLK                           149
+#define GCC_UFS_CARD_RX_SYMBOL_1_CLK                           150
+#define GCC_UFS_CARD_TX_SYMBOL_0_CLK                           151
+#define GCC_UFS_CARD_UNIPRO_CORE_CLK                           152
+#define GCC_UFS_CARD_UNIPRO_CORE_CLK_SRC                       153
+#define GCC_UFS_CARD_UNIPRO_CORE_HW_CTL_CLK                    154
+#define GCC_UFS_MEM_CLKREF_CLK                                 155
+#define GCC_UFS_PHY_AHB_CLK                                    156
+#define GCC_UFS_PHY_AXI_CLK                                    157
+#define GCC_UFS_PHY_AXI_CLK_SRC                                        158
+#define GCC_UFS_PHY_AXI_HW_CTL_CLK                             159
+#define GCC_UFS_PHY_ICE_CORE_CLK                               160
+#define GCC_UFS_PHY_ICE_CORE_CLK_SRC                           161
+#define GCC_UFS_PHY_ICE_CORE_HW_CTL_CLK                                162
+#define GCC_UFS_PHY_PHY_AUX_CLK                                        163
+#define GCC_UFS_PHY_PHY_AUX_CLK_SRC                            164
+#define GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK                         165
+#define GCC_UFS_PHY_RX_SYMBOL_0_CLK                            166
+#define GCC_UFS_PHY_RX_SYMBOL_1_CLK                            167
+#define GCC_UFS_PHY_TX_SYMBOL_0_CLK                            168
+#define GCC_UFS_PHY_UNIPRO_CORE_CLK                            169
+#define GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC                                170
+#define GCC_UFS_PHY_UNIPRO_CORE_HW_CTL_CLK                     171
+#define GCC_USB30_PRIM_MASTER_CLK                              172
+#define GCC_USB30_PRIM_MASTER_CLK_SRC                          173
+#define GCC_USB30_PRIM_MOCK_UTMI_CLK                           174
+#define GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC                       175
+#define GCC_USB30_PRIM_SLEEP_CLK                               176
+#define GCC_USB30_SEC_MASTER_CLK                               177
+#define GCC_USB30_SEC_MASTER_CLK_SRC                           178
+#define GCC_USB30_SEC_MOCK_UTMI_CLK                            179
+#define GCC_USB30_SEC_MOCK_UTMI_CLK_SRC                                180
+#define GCC_USB30_SEC_SLEEP_CLK                                        181
+#define GCC_USB3_PRIM_CLKREF_CLK                               182
+#define GCC_USB3_PRIM_PHY_AUX_CLK                              183
+#define GCC_USB3_PRIM_PHY_AUX_CLK_SRC                          184
+#define GCC_USB3_PRIM_PHY_COM_AUX_CLK                          185
+#define GCC_USB3_PRIM_PHY_PIPE_CLK                             186
+#define GCC_USB3_SEC_CLKREF_CLK                                        187
+#define GCC_USB3_SEC_PHY_AUX_CLK                               188
+#define GCC_USB3_SEC_PHY_AUX_CLK_SRC                           189
+#define GCC_USB3_SEC_PHY_COM_AUX_CLK                           190
+#define GCC_USB3_SEC_PHY_PIPE_CLK                              191
+#define GCC_VIDEO_AHB_CLK                                      192
+#define GCC_VIDEO_AXI0_CLK                                     193
+#define GCC_VIDEO_AXI1_CLK                                     194
+#define GCC_VIDEO_AXIC_CLK                                     195
+#define GCC_VIDEO_XO_CLK                                       196
+#define GPLL0                                                  197
+#define GPLL0_OUT_EVEN                                         198
+#define GPLL7                                                  199
+#define GPLL9                                                  200
+
+/* Reset clocks */
+#define GCC_EMAC_BCR                                           0
+#define GCC_GPU_BCR                                            1
+#define GCC_MMSS_BCR                                           2
+#define GCC_NPU_BCR                                            3
+#define GCC_PCIE_0_BCR                                         4
+#define GCC_PCIE_0_PHY_BCR                                     5
+#define GCC_PCIE_1_BCR                                         6
+#define GCC_PCIE_1_PHY_BCR                                     7
+#define GCC_PCIE_PHY_BCR                                       8
+#define GCC_PDM_BCR                                            9
+#define GCC_PRNG_BCR                                           10
+#define GCC_QSPI_BCR                                           11
+#define GCC_QUPV3_WRAPPER_0_BCR                                        12
+#define GCC_QUPV3_WRAPPER_1_BCR                                        13
+#define GCC_QUPV3_WRAPPER_2_BCR                                        14
+#define GCC_QUSB2PHY_PRIM_BCR                                  15
+#define GCC_QUSB2PHY_SEC_BCR                                   16
+#define GCC_USB3_PHY_PRIM_BCR                                  17
+#define GCC_USB3_DP_PHY_PRIM_BCR                               18
+#define GCC_USB3_PHY_SEC_BCR                                   19
+#define GCC_USB3PHY_PHY_SEC_BCR                                        20
+#define GCC_SDCC2_BCR                                          21
+#define GCC_SDCC4_BCR                                          22
+#define GCC_TSIF_BCR                                           23
+#define GCC_UFS_CARD_BCR                                       24
+#define GCC_UFS_PHY_BCR                                                25
+#define GCC_USB30_PRIM_BCR                                     26
+#define GCC_USB30_SEC_BCR                                      27
+#define GCC_USB_PHY_CFG_AHB2PHY_BCR                            28
+
+#endif
index c0d5d5599c87f5a50c740e0da2352f90388b67b2..014ac6123d1760c43484e6c116eaca423b490cf5 100644 (file)
 
 #define CLK_MIPI_CSI           73
 
+/* Clocks not available on V3s */
+#define CLK_BUS_I2S0           75
+#define CLK_I2S0               76
+
 #endif /* _DT_BINDINGS_CLK_SUN8I_V3S_H_ */
diff --git a/include/dt-bindings/reset-controller/mt8183-resets.h b/include/dt-bindings/reset-controller/mt8183-resets.h
new file mode 100644 (file)
index 0000000..8804e34
--- /dev/null
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Yong Liang <yong.liang@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT8183
+#define _DT_BINDINGS_RESET_CONTROLLER_MT8183
+
+/* INFRACFG AO resets */
+#define MT8183_INFRACFG_AO_THERM_SW_RST                                0
+#define MT8183_INFRACFG_AO_USB_TOP_SW_RST                      1
+#define MT8183_INFRACFG_AO_MM_IOMMU_SW_RST                     3
+#define MT8183_INFRACFG_AO_MSDC3_SW_RST                                4
+#define MT8183_INFRACFG_AO_MSDC2_SW_RST                                5
+#define MT8183_INFRACFG_AO_MSDC1_SW_RST                                6
+#define MT8183_INFRACFG_AO_MSDC0_SW_RST                                7
+#define MT8183_INFRACFG_AO_APDMA_SW_RST                                9
+#define MT8183_INFRACFG_AO_MIMP_D_SW_RST                       10
+#define MT8183_INFRACFG_AO_BTIF_SW_RST                         12
+#define MT8183_INFRACFG_AO_DISP_PWM_SW_RST                     14
+#define MT8183_INFRACFG_AO_AUXADC_SW_RST                       15
+
+#define MT8183_INFRACFG_AO_IRTX_SW_RST                         32
+#define MT8183_INFRACFG_AO_SPI0_SW_RST                         33
+#define MT8183_INFRACFG_AO_I2C0_SW_RST                         34
+#define MT8183_INFRACFG_AO_I2C1_SW_RST                         35
+#define MT8183_INFRACFG_AO_I2C2_SW_RST                         36
+#define MT8183_INFRACFG_AO_I2C3_SW_RST                         37
+#define MT8183_INFRACFG_AO_UART0_SW_RST                                38
+#define MT8183_INFRACFG_AO_UART1_SW_RST                                39
+#define MT8183_INFRACFG_AO_UART2_SW_RST                                40
+#define MT8183_INFRACFG_AO_PWM_SW_RST                          41
+#define MT8183_INFRACFG_AO_SPI1_SW_RST                         42
+#define MT8183_INFRACFG_AO_I2C4_SW_RST                         43
+#define MT8183_INFRACFG_AO_DVFSP_SW_RST                                44
+#define MT8183_INFRACFG_AO_SPI2_SW_RST                         45
+#define MT8183_INFRACFG_AO_SPI3_SW_RST                         46
+#define MT8183_INFRACFG_AO_UFSHCI_SW_RST                       47
+
+#define MT8183_INFRACFG_AO_PMIC_WRAP_SW_RST                    64
+#define MT8183_INFRACFG_AO_SPM_SW_RST                          65
+#define MT8183_INFRACFG_AO_USBSIF_SW_RST                       66
+#define MT8183_INFRACFG_AO_KP_SW_RST                           68
+#define MT8183_INFRACFG_AO_APXGPT_SW_RST                       69
+#define MT8183_INFRACFG_AO_CLDMA_AO_SW_RST                     70
+#define MT8183_INFRACFG_AO_UNIPRO_UFS_SW_RST                   71
+#define MT8183_INFRACFG_AO_DX_CC_SW_RST                                72
+#define MT8183_INFRACFG_AO_UFSPHY_SW_RST                       73
+
+#define MT8183_INFRACFG_AO_DX_CC_SEC_SW_RST                    96
+#define MT8183_INFRACFG_AO_GCE_SW_RST                          97
+#define MT8183_INFRACFG_AO_CLDMA_SW_RST                                98
+#define MT8183_INFRACFG_AO_TRNG_SW_RST                         99
+#define MT8183_INFRACFG_AO_AP_MD_CCIF_1_SW_RST                 103
+#define MT8183_INFRACFG_AO_AP_MD_CCIF_SW_RST                   104
+#define MT8183_INFRACFG_AO_I2C1_IMM_SW_RST                     105
+#define MT8183_INFRACFG_AO_I2C1_ARB_SW_RST                     106
+#define MT8183_INFRACFG_AO_I2C2_IMM_SW_RST                     107
+#define MT8183_INFRACFG_AO_I2C2_ARB_SW_RST                     108
+#define MT8183_INFRACFG_AO_I2C5_SW_RST                         109
+#define MT8183_INFRACFG_AO_I2C5_IMM_SW_RST                     110
+#define MT8183_INFRACFG_AO_I2C5_ARB_SW_RST                     111
+#define MT8183_INFRACFG_AO_SPI4_SW_RST                         112
+#define MT8183_INFRACFG_AO_SPI5_SW_RST                         113
+#define MT8183_INFRACFG_AO_INFRA2MFGAXI_CBIP_CLAS_SW_RST       114
+#define MT8183_INFRACFG_AO_MFGAXI2INFRA_M0_CBIP_GLAS_OUT_SW_RST        115
+#define MT8183_INFRACFG_AO_MFGAXI2INFRA_M1_CBIP_GLAS_OUT_SW_RST        116
+#define MT8183_INFRACFG_AO_UFS_AES_SW_RST                      117
+#define MT8183_INFRACFG_AO_CCU_I2C_IRQ_SW_RST                  118
+#define MT8183_INFRACFG_AO_CCU_I2C_DMA_SW_RST                  119
+#define MT8183_INFRACFG_AO_I2C6_SW_RST                         120
+#define MT8183_INFRACFG_AO_CCU_GALS_SW_RST                     121
+#define MT8183_INFRACFG_AO_IPU_GALS_SW_RST                     122
+#define MT8183_INFRACFG_AO_CONN2AP_GALS_SW_RST                 123
+#define MT8183_INFRACFG_AO_AP_MD_CCIF2_SW_RST                  124
+#define MT8183_INFRACFG_AO_AP_MD_CCIF3_SW_RST                  125
+#define MT8183_INFRACFG_AO_I2C7_SW_RST                         126
+#define MT8183_INFRACFG_AO_I2C8_SW_RST                         127
+
+#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT8183 */
diff --git a/include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h b/include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h
new file mode 100644 (file)
index 0000000..14b78da
--- /dev/null
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 BayLibre, SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ *
+ */
+
+#ifndef _DT_BINDINGS_AMLOGIC_MESON_G12A_AUDIO_RESET_H
+#define _DT_BINDINGS_AMLOGIC_MESON_G12A_AUDIO_RESET_H
+
+#define AUD_RESET_PDM          0
+#define AUD_RESET_TDMIN_A      1
+#define AUD_RESET_TDMIN_B      2
+#define AUD_RESET_TDMIN_C      3
+#define AUD_RESET_TDMIN_LB     4
+#define AUD_RESET_LOOPBACK     5
+#define AUD_RESET_TODDR_A      6
+#define AUD_RESET_TODDR_B      7
+#define AUD_RESET_TODDR_C      8
+#define AUD_RESET_FRDDR_A      9
+#define AUD_RESET_FRDDR_B      10
+#define AUD_RESET_FRDDR_C      11
+#define AUD_RESET_TDMOUT_A     12
+#define AUD_RESET_TDMOUT_B     13
+#define AUD_RESET_TDMOUT_C     14
+#define AUD_RESET_SPDIFOUT     15
+#define AUD_RESET_SPDIFOUT_B   16
+#define AUD_RESET_SPDIFIN      17
+#define AUD_RESET_EQDRC                18
+#define AUD_RESET_RESAMPLE     19
+#define AUD_RESET_DDRARB       20
+#define AUD_RESET_POWDET       21
+#define AUD_RESET_TORAM                22
+#define AUD_RESET_TOACODEC     23
+#define AUD_RESET_TOHDMITX     24
+#define AUD_RESET_CLKTREE      25
+
+#endif
index b58ef21a2e18d6057fec1ebf4a1ebf8bcb8cceb9..b6790173afd63f6c8b26781b7ee6ebbf90a389cb 100644 (file)
@@ -75,4 +75,7 @@
 #define RST_BUS_UART1          50
 #define RST_BUS_UART2          51
 
+/* Reset lines not available on V3s */
+#define RST_BUS_I2S0           52
+
 #endif /* _DT_BINDINGS_RST_SUN8I_H3_H_ */
index 2ae7604783dd1b4e12f4a3f36ed4b976dde3faf8..2fdfe80613635093be0aee02feeeb808d8edb36a 100644 (file)
@@ -299,7 +299,8 @@ struct clk_init_data {
  * into the clk API
  *
  * @init: pointer to struct clk_init_data that contains the init data shared
- * with the common clock framework.
+ * with the common clock framework. This pointer will be set to NULL once
+ * a clk_register() variant is called on this clk_hw pointer.
  */
 struct clk_hw {
        struct clk_core *core;
@@ -817,6 +818,7 @@ unsigned int clk_hw_get_num_parents(const struct clk_hw *hw);
 struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw);
 struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw,
                                          unsigned int index);
+int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *new_parent);
 unsigned int __clk_get_enable_count(struct clk *clk);
 unsigned long clk_hw_get_rate(const struct clk_hw *hw);
 unsigned long __clk_get_flags(struct clk *clk);
index 3c096c7a51dc6105bbc90abab34f01786e36beca..7a795fd6d141188f92e88c4aa32402663cd9615a 100644 (file)
@@ -239,7 +239,8 @@ static inline int clk_prepare(struct clk *clk)
        return 0;
 }
 
-static inline int __must_check clk_bulk_prepare(int num_clks, struct clk_bulk_data *clks)
+static inline int __must_check
+clk_bulk_prepare(int num_clks, const struct clk_bulk_data *clks)
 {
        might_sleep();
        return 0;
@@ -263,7 +264,8 @@ static inline void clk_unprepare(struct clk *clk)
 {
        might_sleep();
 }
-static inline void clk_bulk_unprepare(int num_clks, struct clk_bulk_data *clks)
+static inline void clk_bulk_unprepare(int num_clks,
+                                     const struct clk_bulk_data *clks)
 {
        might_sleep();
 }
@@ -819,7 +821,8 @@ static inline int clk_enable(struct clk *clk)
        return 0;
 }
 
-static inline int __must_check clk_bulk_enable(int num_clks, struct clk_bulk_data *clks)
+static inline int __must_check clk_bulk_enable(int num_clks,
+                                              const struct clk_bulk_data *clks)
 {
        return 0;
 }
@@ -828,7 +831,7 @@ static inline void clk_disable(struct clk *clk) {}
 
 
 static inline void clk_bulk_disable(int num_clks,
-                                   struct clk_bulk_data *clks) {}
+                                   const struct clk_bulk_data *clks) {}
 
 static inline unsigned long clk_get_rate(struct clk *clk)
 {
@@ -917,8 +920,8 @@ static inline void clk_disable_unprepare(struct clk *clk)
        clk_unprepare(clk);
 }
 
-static inline int __must_check clk_bulk_prepare_enable(int num_clks,
-                                       struct clk_bulk_data *clks)
+static inline int __must_check
+clk_bulk_prepare_enable(int num_clks, const struct clk_bulk_data *clks)
 {
        int ret;
 
@@ -933,7 +936,7 @@ static inline int __must_check clk_bulk_prepare_enable(int num_clks,
 }
 
 static inline void clk_bulk_disable_unprepare(int num_clks,
-                                             struct clk_bulk_data *clks)
+                                             const struct clk_bulk_data *clks)
 {
        clk_bulk_disable(num_clks, clks);
        clk_bulk_unprepare(num_clks, clks);
index 85f8cf9d12261d78eeedf70dc420cbe604d3b08a..eae9652c70cd25bb244f38c5ab8b448c6f9cf8c9 100644 (file)
@@ -4,6 +4,9 @@
  * Sylwester Nawrocki <s.nawrocki@samsung.com>
  */
 
+#ifndef __CLK_CONF_H
+#define __CLK_CONF_H
+
 #include <linux/types.h>
 
 struct device_node;
@@ -17,3 +20,5 @@ static inline int of_clk_set_defaults(struct device_node *node,
        return 0;
 }
 #endif
+
+#endif /* __CLK_CONF_H */