Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 13 Jan 2022 01:02:27 +0000 (17:02 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 13 Jan 2022 01:02:27 +0000 (17:02 -0800)
Pull clk updates from Stephen Boyd:
 "We have a couple patches in the framework core this time around but
  they're mostly minor cleanups and some debugfs stuff. The real work
  that's in here is the typical pile of clk driver updates and new SoC
  support.

  Per usual (or maybe just recent trends), Qualcomm gains a handful of
  SoC drivers additions and has the largest diffstat. After that there
  are quite a few updates to the Allwinner (sunxi) drivers to support
  modular drivers and Renesas is heavily updated to add more support for
  various clks.

  Overall it looks pretty normal.

  New Drivers:
   - Add MDMA and BDMA clks to Ingenic JZ4760 and JZ4770
   - MediaTek mt7986 SoC basic support
   - Clock and reset driver for Toshiba Visconti SoCs
   - Initial clock driver for the Exynos7885 SoC (Samsung Galaxy A8)
   - Allwinner D1 clks
   - Lan966x Generic Clock Controller driver and associated DT bindings
   - Qualcomm SDX65, SM8450, and MSM8976 GCC clks
   - Qualcomm SDX65 and SM8450 RPMh clks

  Updates:
   - Set suppress_bind_attrs to true for i.MX8ULP driver
   - Switch from do_div to div64_ul for throughout all i.MX drivers
   - Fix imx8mn_clko1_sels for i.MX8MN
   - Remove unused IPG_AUDIO_ROOT from i.MX8MP
   - Switch parent for audio_root_clk to audio ahb in i.MX8MP driver
   - Removal of all remaining uses of __clk_lookup() in
     drivers/clk/samsung
   - Refactoring of the CPU clocks registration to use common interface
   - An update of the Exynos850 driver (support for more clock domains)
     required by the E850-96 development board
   - Prep for runtime PM and generic power domains on Tegra
   - Support modular Allwinner clk drivers via platform bus
   - Lan966x clock driver extended to support clock gating
   - Add serial (SCI1), watchdog (WDT), timer (OSTM), SPI (RSPI), and
     thermal (TSU) clocks and resets on Renesas RZ/G2L
   - Rework SDHI clock handling in the Renesas R-Car Gen3 and RZ/G2
     clock drivers, and in the Renesas SDHI driver
   - Make the Cortex-A55 (I) clock on Renesas RZ/G2L programmable
   - Document support for the new Renesas R-Car S4-8 (R8A779F0) SoC
   - Add support for the new Renesas R-Car S4-8 (R8A779F0) SoC
   - Add GPU clock and resets on Renesas RZ/G2L
   - Add clk-provider.h to various Qualcomm clk drivers
   - devm version of clk_hw_register_gate()
   - kerneldoc fixes in a couple drivers"

* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (131 commits)
  clk: visconti: Remove pointless NULL check in visconti_pll_add_lookup()
  clk: mediatek: add mt7986 clock support
  clk: mediatek: add mt7986 clock IDs
  dt-bindings: clock: mediatek: document clk bindings for mediatek mt7986 SoC
  clk: mediatek: clk-gate: Use regmap_{set/clear}_bits helpers
  clk: mediatek: clk-gate: Shrink by adding clockgating bit check helper
  clk: x86: Fix clk_gate_flags for RV_CLK_GATE
  clk: x86: Use dynamic con_id string during clk registration
  ACPI: APD: Add a fmw property clk-name
  drivers: acpi: acpi_apd: Remove unused device property "is-rv"
  x86: clk: clk-fch: Add support for newer family of AMD's SOC
  clk: ingenic: Add MDMA and BDMA clocks
  dt-bindings: clk/ingenic: Add MDMA and BDMA clocks
  clk: bm1880: remove kfrees on static allocations
  clk: Drop unused COMMON_CLK_STM32MP157_SCMI config
  clk: st: clkgen-mux: search reg within node or parent
  clk: st: clkgen-fsyn: search reg within node or parent
  clk: Enable/Disable runtime PM for clk_summary
  MAINTAINERS: Add entries for Toshiba Visconti PLL and clock controller
  clk: visconti: Add support common clock driver and reset driver
  ...

198 files changed:
Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
Documentation/devicetree/bindings/clock/microchip,lan966x-gck.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,gcc-msm8976.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml
Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
Documentation/devicetree/bindings/clock/samsung,exynos7885-clock.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pismu.yaml [new file with mode: 0644]
MAINTAINERS
drivers/acpi/acpi_apd.c
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/clk-bm1880.c
drivers/clk/clk-gate.c
drivers/clk/clk-gemini.c
drivers/clk/clk-lan966x.c [new file with mode: 0644]
drivers/clk/clk-stm32f4.c
drivers/clk/clk-stm32mp1.c
drivers/clk/clk-tps68470.c [new file with mode: 0644]
drivers/clk/clk.c
drivers/clk/imx/clk-imx8mn.c
drivers/clk/imx/clk-imx8mp.c
drivers/clk/imx/clk-imx8ulp.c
drivers/clk/imx/clk-pllv1.c
drivers/clk/imx/clk-pllv3.c
drivers/clk/ingenic/jz4760-cgu.c
drivers/clk/ingenic/jz4770-cgu.c
drivers/clk/mediatek/Kconfig
drivers/clk/mediatek/Makefile
drivers/clk/mediatek/clk-gate.c
drivers/clk/mediatek/clk-mt7986-apmixed.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt7986-eth.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt7986-infracfg.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt7986-topckgen.c [new file with mode: 0644]
drivers/clk/meson/gxbb.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-rpmh.c
drivers/clk/qcom/clk-smd-rpm.c
drivers/clk/qcom/gcc-msm8976.c [new file with mode: 0644]
drivers/clk/qcom/gcc-msm8994.c
drivers/clk/qcom/gcc-sc7280.c
drivers/clk/qcom/gcc-sdx65.c [new file with mode: 0644]
drivers/clk/qcom/gcc-sm6350.c
drivers/clk/qcom/gcc-sm8350.c
drivers/clk/qcom/gcc-sm8450.c [new file with mode: 0644]
drivers/clk/qcom/lpasscc-sc7280.c
drivers/clk/qcom/lpasscc-sdm845.c
drivers/clk/qcom/mmcc-apq8084.c
drivers/clk/qcom/q6sstop-qcs404.c
drivers/clk/qcom/turingcc-qcs404.c
drivers/clk/renesas/Kconfig
drivers/clk/renesas/Makefile
drivers/clk/renesas/r8a774a1-cpg-mssr.c
drivers/clk/renesas/r8a774b1-cpg-mssr.c
drivers/clk/renesas/r8a774c0-cpg-mssr.c
drivers/clk/renesas/r8a774e1-cpg-mssr.c
drivers/clk/renesas/r8a7795-cpg-mssr.c
drivers/clk/renesas/r8a7796-cpg-mssr.c
drivers/clk/renesas/r8a77965-cpg-mssr.c
drivers/clk/renesas/r8a77980-cpg-mssr.c
drivers/clk/renesas/r8a77990-cpg-mssr.c
drivers/clk/renesas/r8a77995-cpg-mssr.c
drivers/clk/renesas/r8a779a0-cpg-mssr.c
drivers/clk/renesas/r8a779f0-cpg-mssr.c [new file with mode: 0644]
drivers/clk/renesas/r9a07g044-cpg.c
drivers/clk/renesas/rcar-cpg-lib.c
drivers/clk/renesas/rcar-cpg-lib.h
drivers/clk/renesas/rcar-gen3-cpg.c
drivers/clk/renesas/rcar-gen3-cpg.h
drivers/clk/renesas/rcar-gen4-cpg.c [new file with mode: 0644]
drivers/clk/renesas/rcar-gen4-cpg.h [new file with mode: 0644]
drivers/clk/renesas/renesas-cpg-mssr.c
drivers/clk/renesas/renesas-cpg-mssr.h
drivers/clk/renesas/rzg2l-cpg.c
drivers/clk/renesas/rzg2l-cpg.h
drivers/clk/samsung/Makefile
drivers/clk/samsung/clk-cpu.c
drivers/clk/samsung/clk-cpu.h
drivers/clk/samsung/clk-exynos-arm64.c [new file with mode: 0644]
drivers/clk/samsung/clk-exynos-arm64.h [new file with mode: 0644]
drivers/clk/samsung/clk-exynos3250.c
drivers/clk/samsung/clk-exynos4.c
drivers/clk/samsung/clk-exynos5250.c
drivers/clk/samsung/clk-exynos5420.c
drivers/clk/samsung/clk-exynos7885.c [new file with mode: 0644]
drivers/clk/samsung/clk-exynos850.c
drivers/clk/samsung/clk-pll.c
drivers/clk/samsung/clk-pll.h
drivers/clk/samsung/clk-s3c2410.c
drivers/clk/samsung/clk-s3c64xx.c
drivers/clk/samsung/clk-s5pv210.c
drivers/clk/samsung/clk.c
drivers/clk/samsung/clk.h
drivers/clk/socfpga/clk-agilex.c
drivers/clk/socfpga/clk-gate.c
drivers/clk/socfpga/clk-pll-s10.c
drivers/clk/socfpga/clk-s10.c
drivers/clk/st/clkgen-fsyn.c
drivers/clk/st/clkgen-mux.c
drivers/clk/sunxi-ng/Kconfig
drivers/clk/sunxi-ng/Makefile
drivers/clk/sunxi-ng/ccu-sun20i-d1-r.c [new file with mode: 0644]
drivers/clk/sunxi-ng/ccu-sun20i-d1-r.h [new file with mode: 0644]
drivers/clk/sunxi-ng/ccu-sun20i-d1.c [new file with mode: 0644]
drivers/clk/sunxi-ng/ccu-sun20i-d1.h [new file with mode: 0644]
drivers/clk/sunxi-ng/ccu-sun4i-a10.c
drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c
drivers/clk/sunxi-ng/ccu-sun50i-a100.c
drivers/clk/sunxi-ng/ccu-sun50i-a64.c
drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c
drivers/clk/sunxi-ng/ccu-sun50i-h6.c
drivers/clk/sunxi-ng/ccu-sun50i-h616.c
drivers/clk/sunxi-ng/ccu-sun6i-a31.c
drivers/clk/sunxi-ng/ccu-sun8i-a23.c
drivers/clk/sunxi-ng/ccu-sun8i-a33.c
drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
drivers/clk/sunxi-ng/ccu-sun8i-de2.c
drivers/clk/sunxi-ng/ccu-sun8i-h3.c
drivers/clk/sunxi-ng/ccu-sun8i-r.c
drivers/clk/sunxi-ng/ccu-sun8i-r40.c
drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c
drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c
drivers/clk/sunxi-ng/ccu-sun9i-a80.c
drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c
drivers/clk/sunxi-ng/ccu_common.c
drivers/clk/sunxi-ng/ccu_div.c
drivers/clk/sunxi-ng/ccu_div.h
drivers/clk/sunxi-ng/ccu_frac.c
drivers/clk/sunxi-ng/ccu_gate.c
drivers/clk/sunxi-ng/ccu_gate.h
drivers/clk/sunxi-ng/ccu_mp.c
drivers/clk/sunxi-ng/ccu_mp.h
drivers/clk/sunxi-ng/ccu_mult.c
drivers/clk/sunxi-ng/ccu_mux.c
drivers/clk/sunxi-ng/ccu_mux.h
drivers/clk/sunxi-ng/ccu_nk.c
drivers/clk/sunxi-ng/ccu_nkm.c
drivers/clk/sunxi-ng/ccu_nkmp.c
drivers/clk/sunxi-ng/ccu_nm.c
drivers/clk/sunxi-ng/ccu_phase.c
drivers/clk/sunxi-ng/ccu_reset.c
drivers/clk/sunxi-ng/ccu_sdm.c
drivers/clk/tegra/Makefile
drivers/clk/tegra/clk-device.c [new file with mode: 0644]
drivers/clk/tegra/clk-pll.c
drivers/clk/tegra/clk-super.c
drivers/clk/tegra/clk-tegra114.c
drivers/clk/tegra/clk-tegra20.c
drivers/clk/tegra/clk-tegra30.c
drivers/clk/tegra/clk.c
drivers/clk/tegra/clk.h
drivers/clk/ti/adpll.c
drivers/clk/visconti/Kconfig [new file with mode: 0644]
drivers/clk/visconti/Makefile [new file with mode: 0644]
drivers/clk/visconti/clkc-tmpv770x.c [new file with mode: 0644]
drivers/clk/visconti/clkc.c [new file with mode: 0644]
drivers/clk/visconti/clkc.h [new file with mode: 0644]
drivers/clk/visconti/pll-tmpv770x.c [new file with mode: 0644]
drivers/clk/visconti/pll.c [new file with mode: 0644]
drivers/clk/visconti/pll.h [new file with mode: 0644]
drivers/clk/visconti/reset.c [new file with mode: 0644]
drivers/clk/visconti/reset.h [new file with mode: 0644]
drivers/clk/x86/clk-fch.c
drivers/clk/zynq/pll.c
drivers/mmc/host/Kconfig
drivers/mmc/host/renesas_sdhi.h
drivers/mmc/host/renesas_sdhi_core.c
drivers/mmc/host/renesas_sdhi_internal_dmac.c
include/dt-bindings/clock/exynos4.h
include/dt-bindings/clock/exynos5250.h
include/dt-bindings/clock/exynos7885.h [new file with mode: 0644]
include/dt-bindings/clock/exynos850.h
include/dt-bindings/clock/imx8mp-clock.h
include/dt-bindings/clock/ingenic,jz4760-cgu.h
include/dt-bindings/clock/ingenic,jz4770-cgu.h
include/dt-bindings/clock/microchip,lan966x.h [new file with mode: 0644]
include/dt-bindings/clock/mt7986-clk.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,gcc-msm8976.h [new file with mode: 0644]
include/dt-bindings/clock/sun20i-d1-ccu.h [new file with mode: 0644]
include/dt-bindings/clock/sun20i-d1-r-ccu.h [new file with mode: 0644]
include/dt-bindings/clock/toshiba,tmpv770x.h [new file with mode: 0644]
include/dt-bindings/reset/sun20i-d1-ccu.h [new file with mode: 0644]
include/dt-bindings/reset/sun20i-d1-r-ccu.h [new file with mode: 0644]
include/dt-bindings/reset/toshiba,tmpv770x.h [new file with mode: 0644]
include/linux/clk-provider.h
include/linux/clk/sunxi-ng.h
include/linux/mfd/tps68470.h
include/linux/platform_data/clk-fch.h

index ea827e8..3fa7558 100644 (file)
@@ -14,6 +14,7 @@ Required Properties:
        - "mediatek,mt7622-apmixedsys"
        - "mediatek,mt7623-apmixedsys", "mediatek,mt2701-apmixedsys"
        - "mediatek,mt7629-apmixedsys"
+       - "mediatek,mt7986-apmixedsys"
        - "mediatek,mt8135-apmixedsys"
        - "mediatek,mt8167-apmixedsys", "syscon"
        - "mediatek,mt8173-apmixedsys"
index 6b7e806..0502db7 100644 (file)
@@ -10,6 +10,7 @@ Required Properties:
        - "mediatek,mt7622-ethsys", "syscon"
        - "mediatek,mt7623-ethsys", "mediatek,mt2701-ethsys", "syscon"
        - "mediatek,mt7629-ethsys", "syscon"
+       - "mediatek,mt7986-ethsys", "syscon"
 - #clock-cells: Must be 1
 - #reset-cells: Must be 1
 
index eb3523c..f66bd72 100644 (file)
@@ -15,6 +15,7 @@ Required Properties:
        - "mediatek,mt7622-infracfg", "syscon"
        - "mediatek,mt7623-infracfg", "mediatek,mt2701-infracfg", "syscon"
        - "mediatek,mt7629-infracfg", "syscon"
+       - "mediatek,mt7986-infracfg", "syscon"
        - "mediatek,mt8135-infracfg", "syscon"
        - "mediatek,mt8167-infracfg", "syscon"
        - "mediatek,mt8173-infracfg", "syscon"
index 30cb645..29ca7a1 100644 (file)
@@ -8,6 +8,8 @@ Required Properties:
 - compatible: Should be:
        - "mediatek,mt7622-sgmiisys", "syscon"
        - "mediatek,mt7629-sgmiisys", "syscon"
+       - "mediatek,mt7986-sgmiisys_0", "syscon"
+       - "mediatek,mt7986-sgmiisys_1", "syscon"
 - #clock-cells: Must be 1
 
 The SGMIISYS controller uses the common clk binding from
index 5ce7578..b82422b 100644 (file)
@@ -14,6 +14,7 @@ Required Properties:
        - "mediatek,mt7622-topckgen"
        - "mediatek,mt7623-topckgen", "mediatek,mt2701-topckgen"
        - "mediatek,mt7629-topckgen"
+       - "mediatek,mt7986-topckgen", "syscon"
        - "mediatek,mt8135-topckgen"
        - "mediatek,mt8167-topckgen", "syscon"
        - "mediatek,mt8173-topckgen"
index c4b7243..15ed64d 100644 (file)
@@ -34,6 +34,8 @@ properties:
       - allwinner,sun8i-v3-ccu
       - allwinner,sun8i-v3s-ccu
       - allwinner,sun9i-a80-ccu
+      - allwinner,sun20i-d1-ccu
+      - allwinner,sun20i-d1-r-ccu
       - allwinner,sun50i-a64-ccu
       - allwinner,sun50i-a64-r-ccu
       - allwinner,sun50i-a100-ccu
@@ -79,6 +81,7 @@ if:
       enum:
         - allwinner,sun8i-a83t-r-ccu
         - allwinner,sun8i-h3-r-ccu
+        - allwinner,sun20i-d1-r-ccu
         - allwinner,sun50i-a64-r-ccu
         - allwinner,sun50i-a100-r-ccu
         - allwinner,sun50i-h6-r-ccu
@@ -99,6 +102,7 @@ else:
     properties:
       compatible:
         enum:
+          - allwinner,sun20i-d1-ccu
           - allwinner,sun50i-a100-ccu
           - allwinner,sun50i-h6-ccu
           - allwinner,sun50i-h616-ccu
diff --git a/Documentation/devicetree/bindings/clock/microchip,lan966x-gck.yaml b/Documentation/devicetree/bindings/clock/microchip,lan966x-gck.yaml
new file mode 100644 (file)
index 0000000..df2bec1
--- /dev/null
@@ -0,0 +1,60 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/microchip,lan966x-gck.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip LAN966X Generic Clock Controller
+
+maintainers:
+  - Kavyasree Kotagiri <kavyasree.kotagiri@microchip.com>
+
+description: |
+  The LAN966X Generic clock controller contains 3 PLLs - cpu_clk,
+  ddr_clk and sys_clk. This clock controller generates and supplies
+  clock to various peripherals within the SoC.
+
+properties:
+  compatible:
+    const: microchip,lan966x-gck
+
+  reg:
+    minItems: 1
+    items:
+      - description: Generic clock registers
+      - description: Optional gate clock registers
+
+  clocks:
+    items:
+      - description: CPU clock source
+      - description: DDR clock source
+      - description: System clock source
+
+  clock-names:
+    items:
+      - const: cpu
+      - const: ddr
+      - const: sys
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    clks: clock-controller@e00c00a8 {
+        compatible = "microchip,lan966x-gck";
+        #clock-cells = <1>;
+        clocks = <&cpu_clk>, <&ddr_clk>, <&sys_clk>;
+        clock-names = "cpu", "ddr", "sys";
+        reg = <0xe00c00a8 0x38>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8976.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8976.yaml
new file mode 100644 (file)
index 0000000..f3430b1
--- /dev/null
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,gcc-msm8976.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global Clock & Reset Controller Binding for MSM8976
+
+maintainers:
+  - Stephen Boyd <sboyd@kernel.org>
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm global clock control module which supports the clocks, resets and
+  power domains on MSM8976.
+
+  See also:
+  - dt-bindings/clock/qcom,gcc-msm8976.h
+
+properties:
+  compatible:
+    enum:
+      - qcom,gcc-msm8976
+      - qcom,gcc-msm8976-v1.1
+
+  clocks:
+    items:
+      - description: XO source
+      - description: Always-on XO source
+      - description: Pixel clock from DSI PHY0
+      - description: Byte clock from DSI PHY0
+      - description: Pixel clock from DSI PHY1
+      - description: Byte clock from DSI PHY1
+
+  clock-names:
+    items:
+      - const: xo
+      - const: xo_a
+      - const: dsi0pll
+      - const: dsi0pllbyte
+      - const: dsi1pll
+      - const: dsi1pllbyte
+
+  vdd_gfx-supply:
+    description:
+      Phandle to voltage regulator providing power to the GX domain.
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - vdd_gfx-supply
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller@1800000 {
+      compatible = "qcom,gcc-msm8976";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+      reg = <0x1800000 0x80000>;
+
+      clocks = <&xo_board>,
+               <&xo_board>,
+               <&dsi0_phy 1>,
+               <&dsi0_phy 0>,
+               <&dsi1_phy 1>,
+               <&dsi1_phy 0>;
+
+      clock-names = "xo",
+                    "xo_a",
+                    "dsi0pll",
+                    "dsi0pllbyte",
+                    "dsi1pll",
+                    "dsi1pllbyte";
+
+      vdd_gfx-supply = <&pm8004_s5>;
+    };
+...
index 7221297..8406dde 100644 (file)
@@ -22,10 +22,12 @@ properties:
       - qcom,sc8180x-rpmh-clk
       - qcom,sdm845-rpmh-clk
       - qcom,sdx55-rpmh-clk
+      - qcom,sdx65-rpmh-clk
       - qcom,sm6350-rpmh-clk
       - qcom,sm8150-rpmh-clk
       - qcom,sm8250-rpmh-clk
       - qcom,sm8350-rpmh-clk
+      - qcom,sm8450-rpmh-clk
 
   clocks:
     maxItems: 1
index 9b414fb..e0b8621 100644 (file)
@@ -48,6 +48,7 @@ properties:
       - renesas,r8a77990-cpg-mssr # R-Car E3
       - renesas,r8a77995-cpg-mssr # R-Car D3
       - renesas,r8a779a0-cpg-mssr # R-Car V3U
+      - renesas,r8a779f0-cpg-mssr # R-Car S4-8
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos7885-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos7885-clock.yaml
new file mode 100644 (file)
index 0000000..7e5a9ca
--- /dev/null
@@ -0,0 +1,166 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos7885-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos7885 SoC clock controller
+
+maintainers:
+  - Dávid Virág <virag.david003@gmail.com>
+  - Chanwoo Choi <cw00.choi@samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+  - Sylwester Nawrocki <s.nawrocki@samsung.com>
+  - Tomasz Figa <tomasz.figa@gmail.com>
+
+description: |
+  Exynos7885 clock controller is comprised of several CMU units, generating
+  clocks for different domains. Those CMU units are modeled as separate device
+  tree nodes, and might depend on each other. The root clock in that root tree
+  is an external clock: OSCCLK (26 MHz). This external clock must be defined
+  as a fixed-rate clock in dts.
+
+  CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and
+  dividers; all other leaf clocks (other CMUs) are usually derived from CMU_TOP.
+
+  Each clock is assigned an identifier and client nodes can use this identifier
+  to specify the clock which they consume. All clocks available for usage
+  in clock consumer nodes are defined as preprocessor macros in
+  'dt-bindings/clock/exynos7885.h' header.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos7885-cmu-top
+      - samsung,exynos7885-cmu-core
+      - samsung,exynos7885-cmu-peri
+
+  clocks:
+    minItems: 1
+    maxItems: 10
+
+  clock-names:
+    minItems: 1
+    maxItems: 10
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos7885-cmu-top
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+
+        clock-names:
+          items:
+            - const: oscclk
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos7885-cmu-core
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CMU_CORE bus clock (from CMU_TOP)
+            - description: CCI clock (from CMU_TOP)
+            - description: G3D clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_core_bus
+            - const: dout_core_cci
+            - const: dout_core_g3d
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos7885-cmu-peri
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CMU_PERI bus clock (from CMU_TOP)
+            - description: SPI0 clock (from CMU_TOP)
+            - description: SPI1 clock (from CMU_TOP)
+            - description: UART0 clock (from CMU_TOP)
+            - description: UART1 clock (from CMU_TOP)
+            - description: UART2 clock (from CMU_TOP)
+            - description: USI0 clock (from CMU_TOP)
+            - description: USI1 clock (from CMU_TOP)
+            - description: USI2 clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_peri_bus
+            - const: dout_peri_spi0
+            - const: dout_peri_spi1
+            - const: dout_peri_uart0
+            - const: dout_peri_uart1
+            - const: dout_peri_uart2
+            - const: dout_peri_usi0
+            - const: dout_peri_usi1
+            - const: dout_peri_usi2
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+  - clock-names
+  - reg
+
+additionalProperties: false
+
+examples:
+  # Clock controller node for CMU_PERI
+  - |
+    #include <dt-bindings/clock/exynos7885.h>
+
+    cmu_peri: clock-controller@10010000 {
+        compatible = "samsung,exynos7885-cmu-peri";
+        reg = <0x10010000 0x8000>;
+        #clock-cells = <1>;
+
+        clocks = <&oscclk>,
+                 <&cmu_top CLK_DOUT_PERI_BUS>,
+                 <&cmu_top CLK_DOUT_PERI_SPI0>,
+                 <&cmu_top CLK_DOUT_PERI_SPI1>,
+                 <&cmu_top CLK_DOUT_PERI_UART0>,
+                 <&cmu_top CLK_DOUT_PERI_UART1>,
+                 <&cmu_top CLK_DOUT_PERI_UART2>,
+                 <&cmu_top CLK_DOUT_PERI_USI0>,
+                 <&cmu_top CLK_DOUT_PERI_USI1>,
+                 <&cmu_top CLK_DOUT_PERI_USI2>;
+        clock-names = "oscclk",
+                      "dout_peri_bus",
+                      "dout_peri_spi0",
+                      "dout_peri_spi1",
+                      "dout_peri_uart0",
+                      "dout_peri_uart1",
+                      "dout_peri_uart2",
+                      "dout_peri_usi0",
+                      "dout_peri_usi1",
+                      "dout_peri_usi2";
+    };
+
+...
index 7f8c91a..80ba608 100644 (file)
@@ -32,6 +32,8 @@ properties:
   compatible:
     enum:
       - samsung,exynos850-cmu-top
+      - samsung,exynos850-cmu-apm
+      - samsung,exynos850-cmu-cmgp
       - samsung,exynos850-cmu-core
       - samsung,exynos850-cmu-dpu
       - samsung,exynos850-cmu-hsi
@@ -68,6 +70,42 @@ allOf:
           items:
             - const: oscclk
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-apm
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CMU_APM bus clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_clkcmu_apm_bus
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-cmgp
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CMU_CMGP bus clock (from CMU_APM)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: gout_clkcmu_cmgp_bus
+
   - if:
       properties:
         compatible:
diff --git a/Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml b/Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml
new file mode 100644 (file)
index 0000000..7b7300c
--- /dev/null
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/toshiba,tmpv770x-pipllct.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Toshiba Visconti5 TMPV770X PLL Controller Device Tree Bindings
+
+maintainers:
+  - Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
+
+description:
+  Toshia Visconti5 PLL controller which supports the PLLs on TMPV770X.
+
+properties:
+  compatible:
+    const: toshiba,tmpv7708-pipllct
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+  clocks:
+    description: External reference clock (OSC2)
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    osc2_clk: osc2-clk {
+      compatible = "fixed-clock";
+      clock-frequency = <20000000>;
+      #clock-cells = <0>;
+    };
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pipllct: clock-controller@24220000 {
+            compatible = "toshiba,tmpv7708-pipllct";
+            reg = <0 0x24220000 0 0x820>;
+            #clock-cells = <1>;
+            clocks = <&osc2_clk>;
+        };
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pismu.yaml b/Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pismu.yaml
new file mode 100644 (file)
index 0000000..ed79f16
--- /dev/null
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/toshiba,tmpv770x-pismu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Toshiba Visconti5 TMPV770x SMU controller Device Tree Bindings
+
+maintainers:
+  - Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
+
+description:
+  Toshia Visconti5 SMU (System Management Unit) which supports the clock
+  and resets on TMPV770x.
+
+properties:
+  compatible:
+    items:
+      - const: toshiba,tmpv7708-pismu
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pismu: syscon@24200000 {
+            compatible = "toshiba,tmpv7708-pismu", "syscon";
+            reg = <0 0x24200000 0 0x2140>;
+            #clock-cells = <1>;
+            #reset-cells = <1>;
+        };
+    };
+...
index 7a07db3..e4ceccc 100644 (file)
@@ -2807,12 +2807,15 @@ L:      linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Supported
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/iwamatsu/linux-visconti.git
 F:     Documentation/devicetree/bindings/arm/toshiba.yaml
+F:     Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml
+F:     Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pismu.yaml
 F:     Documentation/devicetree/bindings/net/toshiba,visconti-dwmac.yaml
 F:     Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
 F:     Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
 F:     Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml
 F:     Documentation/devicetree/bindings/watchdog/toshiba,visconti-wdt.yaml
 F:     arch/arm64/boot/dts/toshiba/
+F:     drivers/clk/visconti/
 F:     drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
 F:     drivers/gpio/gpio-visconti.c
 F:     drivers/pci/controller/dwc/pcie-visconti.c
@@ -15868,6 +15871,15 @@ F:     Documentation/admin-guide/media/qcom_camss.rst
 F:     Documentation/devicetree/bindings/media/*camss*
 F:     drivers/media/platform/qcom/camss/
 
+QUALCOMM CLOCK DRIVERS
+M:     Bjorn Andersson <bjorn.andersson@linaro.org>
+L:     linux-arm-msm@vger.kernel.org
+S:     Supported
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git
+F:     Documentation/devicetree/bindings/clock/qcom,*
+F:     drivers/clk/qcom/
+F:     include/dt-bindings/clock/qcom,*
+
 QUALCOMM CORE POWER REDUCTION (CPR) AVS DRIVER
 M:     Niklas Cassel <nks@flawful.org>
 L:     linux-pm@vger.kernel.org
index 6e02448..2b958b4 100644 (file)
@@ -87,8 +87,15 @@ static int fch_misc_setup(struct apd_private_data *pdata)
        if (ret < 0)
                return -ENOENT;
 
-       if (!acpi_dev_get_property(adev, "is-rv", ACPI_TYPE_INTEGER, &obj))
-               clk_data->is_rv = obj->integer.value;
+       if (!acpi_dev_get_property(adev, "clk-name", ACPI_TYPE_STRING, &obj)) {
+               clk_data->name = devm_kzalloc(&adev->dev, obj->string.length,
+                                             GFP_KERNEL);
+
+               strcpy(clk_data->name, obj->string.pointer);
+       } else {
+               /* Set default name to mclk if entry missing in firmware */
+               clk_data->name = "mclk";
+       }
 
        list_for_each_entry(rentry, &resource_list, node) {
                clk_data->base = devm_ioremap(&adev->dev, rentry->res->start,
index c91931c..ad4256d 100644 (file)
@@ -169,6 +169,14 @@ config COMMON_CLK_CDCE706
        help
          This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
 
+config COMMON_CLK_TPS68470
+       tristate "Clock Driver for TI TPS68470 PMIC"
+       depends on I2C
+       depends on INTEL_SKL_INT3472 || COMPILE_TEST
+       select REGMAP_I2C
+       help
+         This driver supports the clocks provided by the TPS68470 PMIC.
+
 config COMMON_CLK_CDCE925
        tristate "Clock driver for TI CDCE913/925/937/949 devices"
        depends on I2C
@@ -221,6 +229,13 @@ config COMMON_CLK_GEMINI
          This driver supports the SoC clocks on the Cortina Systems Gemini
          platform, also known as SL3516 or CS3516.
 
+config COMMON_CLK_LAN966X
+       bool "Generic Clock Controller driver for LAN966X SoC"
+       help
+         This driver provides support for Generic Clock Controller(GCK) on
+         LAN966X SoC. GCK generates and supplies clock to various peripherals
+         within the SoC.
+
 config COMMON_CLK_ASPEED
        bool "Clock driver for Aspeed BMC SoCs"
        depends on ARCH_ASPEED || COMPILE_TEST
@@ -339,16 +354,6 @@ config COMMON_CLK_STM32MP157
        help
          Support for stm32mp157 SoC family clocks
 
-config COMMON_CLK_STM32MP157_SCMI
-       bool "stm32mp157 Clock driver with Trusted Firmware"
-       depends on COMMON_CLK_STM32MP157
-       select COMMON_CLK_SCMI
-       select ARM_SCMI_PROTOCOL
-       default y
-       help
-         Support for stm32mp157 SoC family clocks with Trusted Firmware using
-         SCMI protocol.
-
 config COMMON_CLK_STM32F
        def_bool COMMON_CLK && (MACH_STM32F429 || MACH_STM32F469 || MACH_STM32F746)
        help
@@ -418,6 +423,7 @@ source "drivers/clk/sunxi-ng/Kconfig"
 source "drivers/clk/tegra/Kconfig"
 source "drivers/clk/ti/Kconfig"
 source "drivers/clk/uniphier/Kconfig"
+source "drivers/clk/visconti/Kconfig"
 source "drivers/clk/x86/Kconfig"
 source "drivers/clk/xilinx/Kconfig"
 source "drivers/clk/zynqmp/Kconfig"
index a9bb247..16e5886 100644 (file)
@@ -37,6 +37,7 @@ obj-$(CONFIG_ARCH_HIGHBANK)           += clk-highbank.o
 obj-$(CONFIG_CLK_HSDK)                 += clk-hsdk-pll.o
 obj-$(CONFIG_COMMON_CLK_K210)          += clk-k210.o
 obj-$(CONFIG_LMK04832)                 += clk-lmk04832.o
+obj-$(CONFIG_COMMON_CLK_LAN966X)       += clk-lan966x.o
 obj-$(CONFIG_COMMON_CLK_LOCHNAGAR)     += clk-lochnagar.o
 obj-$(CONFIG_COMMON_CLK_MAX77686)      += clk-max77686.o
 obj-$(CONFIG_COMMON_CLK_MAX9485)       += clk-max9485.o
@@ -63,6 +64,7 @@ obj-$(CONFIG_COMMON_CLK_SI570)                += clk-si570.o
 obj-$(CONFIG_COMMON_CLK_STM32F)                += clk-stm32f4.o
 obj-$(CONFIG_COMMON_CLK_STM32H7)       += clk-stm32h7.o
 obj-$(CONFIG_COMMON_CLK_STM32MP157)    += clk-stm32mp1.o
+obj-$(CONFIG_COMMON_CLK_TPS68470)      += clk-tps68470.o
 obj-$(CONFIG_CLK_TWL6040)              += clk-twl6040.o
 obj-$(CONFIG_ARCH_VT8500)              += clk-vt8500.o
 obj-$(CONFIG_COMMON_CLK_VC5)           += clk-versaclock5.o
@@ -111,12 +113,13 @@ obj-y                                     += sprd/
 obj-$(CONFIG_ARCH_STI)                 += st/
 obj-$(CONFIG_SOC_STARFIVE)             += starfive/
 obj-$(CONFIG_ARCH_SUNXI)               += sunxi/
-obj-$(CONFIG_SUNXI_CCU)                        += sunxi-ng/
+obj-y                                  += sunxi-ng/
 obj-$(CONFIG_ARCH_TEGRA)               += tegra/
 obj-y                                  += ti/
 obj-$(CONFIG_CLK_UNIPHIER)             += uniphier/
 obj-$(CONFIG_ARCH_U8500)               += ux500/
 obj-y                                  += versatile/
+obj-$(CONFIG_COMMON_CLK_VISCONTI)      += visconti/
 ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_X86)                      += x86/
 endif
index e6d6599..fad78a2 100644 (file)
@@ -522,14 +522,6 @@ static struct clk_hw *bm1880_clk_register_pll(struct bm1880_pll_hw_clock *pll_cl
        return hw;
 }
 
-static void bm1880_clk_unregister_pll(struct clk_hw *hw)
-{
-       struct bm1880_pll_hw_clock *pll_hw = to_bm1880_pll_clk(hw);
-
-       clk_hw_unregister(hw);
-       kfree(pll_hw);
-}
-
 static int bm1880_clk_register_plls(struct bm1880_pll_hw_clock *clks,
                                    int num_clks,
                                    struct bm1880_clock_data *data)
@@ -555,7 +547,7 @@ static int bm1880_clk_register_plls(struct bm1880_pll_hw_clock *clks,
 
 err_clk:
        while (i--)
-               bm1880_clk_unregister_pll(data->hw_data.hws[clks[i].pll.id]);
+               clk_hw_unregister(data->hw_data.hws[clks[i].pll.id]);
 
        return PTR_ERR(hw);
 }
@@ -695,14 +687,6 @@ static struct clk_hw *bm1880_clk_register_div(struct bm1880_div_hw_clock *div_cl
        return hw;
 }
 
-static void bm1880_clk_unregister_div(struct clk_hw *hw)
-{
-       struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw);
-
-       clk_hw_unregister(hw);
-       kfree(div_hw);
-}
-
 static int bm1880_clk_register_divs(struct bm1880_div_hw_clock *clks,
                                    int num_clks,
                                    struct bm1880_clock_data *data)
@@ -729,7 +713,7 @@ static int bm1880_clk_register_divs(struct bm1880_div_hw_clock *clks,
 
 err_clk:
        while (i--)
-               bm1880_clk_unregister_div(data->hw_data.hws[clks[i].div.id]);
+               clk_hw_unregister(data->hw_data.hws[clks[i].div.id]);
 
        return PTR_ERR(hw);
 }
index 070dc47..6428380 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/clk-provider.h>
+#include <linux/device.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/io.h>
@@ -222,3 +223,37 @@ void clk_hw_unregister_gate(struct clk_hw *hw)
        kfree(gate);
 }
 EXPORT_SYMBOL_GPL(clk_hw_unregister_gate);
+
+static void devm_clk_hw_release_gate(struct device *dev, void *res)
+{
+       clk_hw_unregister_gate(*(struct clk_hw **)res);
+}
+
+struct clk_hw *__devm_clk_hw_register_gate(struct device *dev,
+               struct device_node *np, const char *name,
+               const char *parent_name, const struct clk_hw *parent_hw,
+               const struct clk_parent_data *parent_data,
+               unsigned long flags,
+               void __iomem *reg, u8 bit_idx,
+               u8 clk_gate_flags, spinlock_t *lock)
+{
+       struct clk_hw **ptr, *hw;
+
+       ptr = devres_alloc(devm_clk_hw_release_gate, sizeof(*ptr), GFP_KERNEL);
+       if (!ptr)
+               return ERR_PTR(-ENOMEM);
+
+       hw = __clk_hw_register_gate(dev, np, name, parent_name, parent_hw,
+                                   parent_data, flags, reg, bit_idx,
+                                   clk_gate_flags, lock);
+
+       if (!IS_ERR(hw)) {
+               *ptr = hw;
+               devres_add(dev, ptr);
+       } else {
+               devres_free(ptr);
+       }
+
+       return hw;
+}
+EXPORT_SYMBOL_GPL(__devm_clk_hw_register_gate);
index b51069e..a23fa6d 100644 (file)
@@ -50,7 +50,7 @@ static DEFINE_SPINLOCK(gemini_clk_lock);
 #define PCI_DLL_TAP_SEL_MASK           0x1f
 
 /**
- * struct gemini_data_data - Gemini gated clocks
+ * struct gemini_gate_data - Gemini gated clocks
  * @bit_idx: the bit used to gate this clock in the clock register
  * @name: the clock name
  * @parent_name: the name of the parent clock
diff --git a/drivers/clk/clk-lan966x.c b/drivers/clk/clk-lan966x.c
new file mode 100644 (file)
index 0000000..d1535ac
--- /dev/null
@@ -0,0 +1,293 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Microchip LAN966x SoC Clock driver.
+ *
+ * Copyright (C) 2021 Microchip Technology, Inc. and its subsidiaries
+ *
+ * Author: Kavyasree Kotagiri <kavyasree.kotagiri@microchip.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/clock/microchip,lan966x.h>
+
+#define GCK_ENA         BIT(0)
+#define GCK_SRC_SEL     GENMASK(9, 8)
+#define GCK_PRESCALER   GENMASK(23, 16)
+
+#define DIV_MAX                255
+
+static const char *clk_names[N_CLOCKS] = {
+       "qspi0", "qspi1", "qspi2", "sdmmc0",
+       "pi", "mcan0", "mcan1", "flexcom0",
+       "flexcom1", "flexcom2", "flexcom3",
+       "flexcom4", "timer1", "usb_refclk",
+};
+
+struct lan966x_gck {
+       struct clk_hw hw;
+       void __iomem *reg;
+};
+#define to_lan966x_gck(hw) container_of(hw, struct lan966x_gck, hw)
+
+static const struct clk_parent_data lan966x_gck_pdata[] = {
+       { .fw_name = "cpu", },
+       { .fw_name = "ddr", },
+       { .fw_name = "sys", },
+};
+
+static struct clk_init_data init = {
+       .parent_data = lan966x_gck_pdata,
+       .num_parents = ARRAY_SIZE(lan966x_gck_pdata),
+};
+
+struct clk_gate_soc_desc {
+       const char *name;
+       int bit_idx;
+};
+
+static const struct clk_gate_soc_desc clk_gate_desc[] = {
+       { "uhphs", 11 },
+       { "udphs", 10 },
+       { "mcramc", 9 },
+       { "hmatrix", 8 },
+       { }
+};
+
+static DEFINE_SPINLOCK(clk_gate_lock);
+static void __iomem *base;
+
+static int lan966x_gck_enable(struct clk_hw *hw)
+{
+       struct lan966x_gck *gck = to_lan966x_gck(hw);
+       u32 val = readl(gck->reg);
+
+       val |= GCK_ENA;
+       writel(val, gck->reg);
+
+       return 0;
+}
+
+static void lan966x_gck_disable(struct clk_hw *hw)
+{
+       struct lan966x_gck *gck = to_lan966x_gck(hw);
+       u32 val = readl(gck->reg);
+
+       val &= ~GCK_ENA;
+       writel(val, gck->reg);
+}
+
+static int lan966x_gck_set_rate(struct clk_hw *hw,
+                               unsigned long rate,
+                               unsigned long parent_rate)
+{
+       struct lan966x_gck *gck = to_lan966x_gck(hw);
+       u32 div, val = readl(gck->reg);
+
+       if (rate == 0 || parent_rate == 0)
+               return -EINVAL;
+
+       /* Set Prescalar */
+       div = parent_rate / rate;
+       val &= ~GCK_PRESCALER;
+       val |= FIELD_PREP(GCK_PRESCALER, (div - 1));
+       writel(val, gck->reg);
+
+       return 0;
+}
+
+static long lan966x_gck_round_rate(struct clk_hw *hw, unsigned long rate,
+                                  unsigned long *parent_rate)
+{
+       unsigned int div;
+
+       if (rate == 0 || *parent_rate == 0)
+               return -EINVAL;
+
+       if (rate >= *parent_rate)
+               return *parent_rate;
+
+       div = DIV_ROUND_CLOSEST(*parent_rate, rate);
+
+       return *parent_rate / div;
+}
+
+static unsigned long lan966x_gck_recalc_rate(struct clk_hw *hw,
+                                            unsigned long parent_rate)
+{
+       struct lan966x_gck *gck = to_lan966x_gck(hw);
+       u32 div, val = readl(gck->reg);
+
+       div = FIELD_GET(GCK_PRESCALER, val);
+
+       return parent_rate / (div + 1);
+}
+
+static int lan966x_gck_determine_rate(struct clk_hw *hw,
+                                     struct clk_rate_request *req)
+{
+       struct clk_hw *parent;
+       int i;
+
+       for (i = 0; i < clk_hw_get_num_parents(hw); ++i) {
+               parent = clk_hw_get_parent_by_index(hw, i);
+               if (!parent)
+                       continue;
+
+               /* Allowed prescaler divider range is 0-255 */
+               if (clk_hw_get_rate(parent) / req->rate <= DIV_MAX) {
+                       req->best_parent_hw = parent;
+                       req->best_parent_rate = clk_hw_get_rate(parent);
+
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static u8 lan966x_gck_get_parent(struct clk_hw *hw)
+{
+       struct lan966x_gck *gck = to_lan966x_gck(hw);
+       u32 val = readl(gck->reg);
+
+       return FIELD_GET(GCK_SRC_SEL, val);
+}
+
+static int lan966x_gck_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct lan966x_gck *gck = to_lan966x_gck(hw);
+       u32 val = readl(gck->reg);
+
+       val &= ~GCK_SRC_SEL;
+       val |= FIELD_PREP(GCK_SRC_SEL, index);
+       writel(val, gck->reg);
+
+       return 0;
+}
+
+static const struct clk_ops lan966x_gck_ops = {
+       .enable         = lan966x_gck_enable,
+       .disable        = lan966x_gck_disable,
+       .set_rate       = lan966x_gck_set_rate,
+       .round_rate     = lan966x_gck_round_rate,
+       .recalc_rate    = lan966x_gck_recalc_rate,
+       .determine_rate = lan966x_gck_determine_rate,
+       .set_parent     = lan966x_gck_set_parent,
+       .get_parent     = lan966x_gck_get_parent,
+};
+
+static struct clk_hw *lan966x_gck_clk_register(struct device *dev, int i)
+{
+       struct lan966x_gck *priv;
+       int ret;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return ERR_PTR(-ENOMEM);
+
+       priv->reg = base + (i * 4);
+       priv->hw.init = &init;
+       ret = devm_clk_hw_register(dev, &priv->hw);
+       if (ret)
+               return ERR_PTR(ret);
+
+       return &priv->hw;
+};
+
+static int lan966x_gate_clk_register(struct device *dev,
+                                    struct clk_hw_onecell_data *hw_data,
+                                    void __iomem *gate_base)
+{
+       int i;
+
+       for (i = GCK_GATE_UHPHS; i < N_CLOCKS; ++i) {
+               int idx = i - GCK_GATE_UHPHS;
+
+               hw_data->hws[i] =
+                       devm_clk_hw_register_gate(dev, clk_gate_desc[idx].name,
+                                                 "lan966x", 0, base,
+                                                 clk_gate_desc[idx].bit_idx,
+                                                 0, &clk_gate_lock);
+
+               if (IS_ERR(hw_data->hws[i]))
+                       return dev_err_probe(dev, PTR_ERR(hw_data->hws[i]),
+                                            "failed to register %s clock\n",
+                                            clk_gate_desc[idx].name);
+       }
+
+       return 0;
+}
+
+static int lan966x_clk_probe(struct platform_device *pdev)
+{
+       struct clk_hw_onecell_data *hw_data;
+       struct device *dev = &pdev->dev;
+       void __iomem *gate_base;
+       struct resource *res;
+       int i, ret;
+
+       hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, N_CLOCKS),
+                              GFP_KERNEL);
+       if (!hw_data)
+               return -ENOMEM;
+
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       init.ops = &lan966x_gck_ops;
+
+       hw_data->num = GCK_GATE_UHPHS;
+
+       for (i = 0; i < GCK_GATE_UHPHS; i++) {
+               init.name = clk_names[i];
+               hw_data->hws[i] = lan966x_gck_clk_register(dev, i);
+               if (IS_ERR(hw_data->hws[i])) {
+                       dev_err(dev, "failed to register %s clock\n",
+                               init.name);
+                       return PTR_ERR(hw_data->hws[i]);
+               }
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       if (res) {
+               gate_base = devm_ioremap_resource(&pdev->dev, res);
+               if (IS_ERR(gate_base))
+                       return PTR_ERR(gate_base);
+
+               hw_data->num = N_CLOCKS;
+
+               ret = lan966x_gate_clk_register(dev, hw_data, gate_base);
+               if (ret)
+                       return ret;
+       }
+
+       return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, hw_data);
+}
+
+static const struct of_device_id lan966x_clk_dt_ids[] = {
+       { .compatible = "microchip,lan966x-gck", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, lan966x_clk_dt_ids);
+
+static struct platform_driver lan966x_clk_driver = {
+       .probe  = lan966x_clk_probe,
+       .driver = {
+               .name = "lan966x-clk",
+               .of_match_table = lan966x_clk_dt_ids,
+       },
+};
+builtin_platform_driver(lan966x_clk_driver);
+
+MODULE_AUTHOR("Kavyasree Kotagiri <kavyasree.kotagiri@microchip.com>");
+MODULE_DESCRIPTION("LAN966X clock driver");
+MODULE_LICENSE("GPL v2");
index af46176..473dfe6 100644 (file)
@@ -129,7 +129,6 @@ static const struct stm32f4_gate_data stm32f429_gates[] __initconst = {
        { STM32F4_RCC_APB2ENR, 20,      "spi5",         "apb2_div" },
        { STM32F4_RCC_APB2ENR, 21,      "spi6",         "apb2_div" },
        { STM32F4_RCC_APB2ENR, 22,      "sai1",         "apb2_div" },
-       { STM32F4_RCC_APB2ENR, 26,      "ltdc",         "apb2_div" },
 };
 
 static const struct stm32f4_gate_data stm32f469_gates[] __initconst = {
@@ -211,7 +210,6 @@ static const struct stm32f4_gate_data stm32f469_gates[] __initconst = {
        { STM32F4_RCC_APB2ENR, 20,      "spi5",         "apb2_div" },
        { STM32F4_RCC_APB2ENR, 21,      "spi6",         "apb2_div" },
        { STM32F4_RCC_APB2ENR, 22,      "sai1",         "apb2_div" },
-       { STM32F4_RCC_APB2ENR, 26,      "ltdc",         "apb2_div" },
 };
 
 static const struct stm32f4_gate_data stm32f746_gates[] __initconst = {
@@ -286,7 +284,6 @@ static const struct stm32f4_gate_data stm32f746_gates[] __initconst = {
        { STM32F4_RCC_APB2ENR, 21,      "spi6",         "apb2_div" },
        { STM32F4_RCC_APB2ENR, 22,      "sai1",         "apb2_div" },
        { STM32F4_RCC_APB2ENR, 23,      "sai2",         "apb2_div" },
-       { STM32F4_RCC_APB2ENR, 26,      "ltdc",         "apb2_div" },
 };
 
 static const struct stm32f4_gate_data stm32f769_gates[] __initconst = {
@@ -364,7 +361,6 @@ static const struct stm32f4_gate_data stm32f769_gates[] __initconst = {
        { STM32F4_RCC_APB2ENR, 21,      "spi6",         "apb2_div" },
        { STM32F4_RCC_APB2ENR, 22,      "sai1",         "apb2_div" },
        { STM32F4_RCC_APB2ENR, 23,      "sai2",         "apb2_div" },
-       { STM32F4_RCC_APB2ENR, 26,      "ltdc",         "apb2_div" },
        { STM32F4_RCC_APB2ENR, 30,      "mdio",         "apb2_div" },
 };
 
index 4bd1fe7..863274a 100644 (file)
@@ -2253,8 +2253,6 @@ static int stm32_rcc_reset_init(struct device *dev, void __iomem *base,
        const struct stm32_rcc_match_data *data = match->data;
        struct stm32_reset_data *reset_data = NULL;
 
-       data = match->data;
-
        reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL);
        if (!reset_data)
                return -ENOMEM;
diff --git a/drivers/clk/clk-tps68470.c b/drivers/clk/clk-tps68470.c
new file mode 100644 (file)
index 0000000..e5fbefd
--- /dev/null
@@ -0,0 +1,261 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock driver for TPS68470 PMIC
+ *
+ * Copyright (c) 2021 Red Hat Inc.
+ * Copyright (C) 2018 Intel Corporation
+ *
+ * Authors:
+ *     Hans de Goede <hdegoede@redhat.com>
+ *     Zaikuo Wang <zaikuo.wang@intel.com>
+ *     Tianshu Qiu <tian.shu.qiu@intel.com>
+ *     Jian Xu Zheng <jian.xu.zheng@intel.com>
+ *     Yuning Pu <yuning.pu@intel.com>
+ *     Antti Laakso <antti.laakso@intel.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/kernel.h>
+#include <linux/mfd/tps68470.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/tps68470.h>
+#include <linux/regmap.h>
+
+#define TPS68470_CLK_NAME "tps68470-clk"
+
+#define to_tps68470_clkdata(clkd) \
+       container_of(clkd, struct tps68470_clkdata, clkout_hw)
+
+static struct tps68470_clkout_freqs {
+       unsigned long freq;
+       unsigned int xtaldiv;
+       unsigned int plldiv;
+       unsigned int postdiv;
+       unsigned int buckdiv;
+       unsigned int boostdiv;
+} clk_freqs[] = {
+/*
+ *  The PLL is used to multiply the crystal oscillator
+ *  frequency range of 3 MHz to 27 MHz by a programmable
+ *  factor of F = (M/N)*(1/P) such that the output
+ *  available at the HCLK_A or HCLK_B pins are in the range
+ *  of 4 MHz to 64 MHz in increments of 0.1 MHz.
+ *
+ * hclk_# = osc_in * (((plldiv*2)+320) / (xtaldiv+30)) * (1 / 2^postdiv)
+ *
+ * PLL_REF_CLK should be as close as possible to 100kHz
+ * PLL_REF_CLK = input clk / XTALDIV[7:0] + 30)
+ *
+ * PLL_VCO_CLK = (PLL_REF_CLK * (plldiv*2 + 320))
+ *
+ * BOOST should be as close as possible to 2Mhz
+ * BOOST = PLL_VCO_CLK / (BOOSTDIV[4:0] + 16) *
+ *
+ * BUCK should be as close as possible to 5.2Mhz
+ * BUCK = PLL_VCO_CLK / (BUCKDIV[3:0] + 5)
+ *
+ * osc_in   xtaldiv  plldiv   postdiv   hclk_#
+ * 20Mhz    170      32       1         19.2Mhz
+ * 20Mhz    170      40       1         20Mhz
+ * 20Mhz    170      80       1         24Mhz
+ */
+       { 19200000, 170, 32, 1, 2, 3 },
+       { 20000000, 170, 40, 1, 3, 4 },
+       { 24000000, 170, 80, 1, 4, 8 },
+};
+
+struct tps68470_clkdata {
+       struct clk_hw clkout_hw;
+       struct regmap *regmap;
+       unsigned long rate;
+};
+
+static int tps68470_clk_is_prepared(struct clk_hw *hw)
+{
+       struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
+       int val;
+
+       if (regmap_read(clkdata->regmap, TPS68470_REG_PLLCTL, &val))
+               return 0;
+
+       return val & TPS68470_PLL_EN_MASK;
+}
+
+static int tps68470_clk_prepare(struct clk_hw *hw)
+{
+       struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
+
+       regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG1,
+                          (TPS68470_PLL_OUTPUT_ENABLE << TPS68470_OUTPUT_A_SHIFT) |
+                          (TPS68470_PLL_OUTPUT_ENABLE << TPS68470_OUTPUT_B_SHIFT));
+
+       regmap_update_bits(clkdata->regmap, TPS68470_REG_PLLCTL,
+                          TPS68470_PLL_EN_MASK, TPS68470_PLL_EN_MASK);
+
+       /*
+        * The PLLCTL reg lock bit is set by the PMIC after approx. 4ms and
+        * does not indicate a true lock, so just wait 4 ms.
+        */
+       usleep_range(4000, 5000);
+
+       return 0;
+}
+
+static void tps68470_clk_unprepare(struct clk_hw *hw)
+{
+       struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
+
+       /* Disable clock first ... */
+       regmap_update_bits(clkdata->regmap, TPS68470_REG_PLLCTL, TPS68470_PLL_EN_MASK, 0);
+
+       /* ... and then tri-state the clock outputs. */
+       regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG1, 0);
+}
+
+static unsigned long tps68470_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+       struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
+
+       return clkdata->rate;
+}
+
+/*
+ * This returns the index of the clk_freqs[] cfg with the closest rate for
+ * use in tps68470_clk_round_rate(). tps68470_clk_set_rate() checks that
+ * the rate of the returned cfg is an exact match.
+ */
+static unsigned int tps68470_clk_cfg_lookup(unsigned long rate)
+{
+       long diff, best_diff = LONG_MAX;
+       unsigned int i, best_idx = 0;
+
+       for (i = 0; i < ARRAY_SIZE(clk_freqs); i++) {
+               diff = clk_freqs[i].freq - rate;
+               if (diff == 0)
+                       return i;
+
+               diff = abs(diff);
+               if (diff < best_diff) {
+                       best_diff = diff;
+                       best_idx = i;
+               }
+       }
+
+       return best_idx;
+}
+
+static long tps68470_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+                                   unsigned long *parent_rate)
+{
+       unsigned int idx = tps68470_clk_cfg_lookup(rate);
+
+       return clk_freqs[idx].freq;
+}
+
+static int tps68470_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+                                unsigned long parent_rate)
+{
+       struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
+       unsigned int idx = tps68470_clk_cfg_lookup(rate);
+
+       if (rate != clk_freqs[idx].freq)
+               return -EINVAL;
+
+       regmap_write(clkdata->regmap, TPS68470_REG_BOOSTDIV, clk_freqs[idx].boostdiv);
+       regmap_write(clkdata->regmap, TPS68470_REG_BUCKDIV, clk_freqs[idx].buckdiv);
+       regmap_write(clkdata->regmap, TPS68470_REG_PLLSWR, TPS68470_PLLSWR_DEFAULT);
+       regmap_write(clkdata->regmap, TPS68470_REG_XTALDIV, clk_freqs[idx].xtaldiv);
+       regmap_write(clkdata->regmap, TPS68470_REG_PLLDIV, clk_freqs[idx].plldiv);
+       regmap_write(clkdata->regmap, TPS68470_REG_POSTDIV, clk_freqs[idx].postdiv);
+       regmap_write(clkdata->regmap, TPS68470_REG_POSTDIV2, clk_freqs[idx].postdiv);
+       regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG2, TPS68470_CLKCFG2_DRV_STR_2MA);
+
+       regmap_write(clkdata->regmap, TPS68470_REG_PLLCTL,
+                    TPS68470_OSC_EXT_CAP_DEFAULT << TPS68470_OSC_EXT_CAP_SHIFT |
+                    TPS68470_CLK_SRC_XTAL << TPS68470_CLK_SRC_SHIFT);
+
+       clkdata->rate = rate;
+
+       return 0;
+}
+
+static const struct clk_ops tps68470_clk_ops = {
+       .is_prepared = tps68470_clk_is_prepared,
+       .prepare = tps68470_clk_prepare,
+       .unprepare = tps68470_clk_unprepare,
+       .recalc_rate = tps68470_clk_recalc_rate,
+       .round_rate = tps68470_clk_round_rate,
+       .set_rate = tps68470_clk_set_rate,
+};
+
+static int tps68470_clk_probe(struct platform_device *pdev)
+{
+       struct tps68470_clk_platform_data *pdata = pdev->dev.platform_data;
+       struct clk_init_data tps68470_clk_initdata = {
+               .name = TPS68470_CLK_NAME,
+               .ops = &tps68470_clk_ops,
+               /* Changing the dividers when the PLL is on is not allowed */
+               .flags = CLK_SET_RATE_GATE,
+       };
+       struct tps68470_clkdata *tps68470_clkdata;
+       int ret;
+
+       tps68470_clkdata = devm_kzalloc(&pdev->dev, sizeof(*tps68470_clkdata),
+                                       GFP_KERNEL);
+       if (!tps68470_clkdata)
+               return -ENOMEM;
+
+       tps68470_clkdata->regmap = dev_get_drvdata(pdev->dev.parent);
+       tps68470_clkdata->clkout_hw.init = &tps68470_clk_initdata;
+
+       /* Set initial rate */
+       tps68470_clk_set_rate(&tps68470_clkdata->clkout_hw, clk_freqs[0].freq, 0);
+
+       ret = devm_clk_hw_register(&pdev->dev, &tps68470_clkdata->clkout_hw);
+       if (ret)
+               return ret;
+
+       ret = devm_clk_hw_register_clkdev(&pdev->dev, &tps68470_clkdata->clkout_hw,
+                                         TPS68470_CLK_NAME, NULL);
+       if (ret)
+               return ret;
+
+       if (pdata) {
+               ret = devm_clk_hw_register_clkdev(&pdev->dev,
+                                                 &tps68470_clkdata->clkout_hw,
+                                                 pdata->consumer_con_id,
+                                                 pdata->consumer_dev_name);
+       }
+
+       return ret;
+}
+
+static struct platform_driver tps68470_clk_driver = {
+       .driver = {
+               .name = TPS68470_CLK_NAME,
+       },
+       .probe = tps68470_clk_probe,
+};
+
+/*
+ * The ACPI tps68470 probe-ordering depends on the clk/gpio/regulator drivers
+ * registering before the drivers for the camera-sensors which use them bind.
+ * subsys_initcall() ensures this when the drivers are builtin.
+ */
+static int __init tps68470_clk_init(void)
+{
+       return platform_driver_register(&tps68470_clk_driver);
+}
+subsys_initcall(tps68470_clk_init);
+
+static void __exit tps68470_clk_exit(void)
+{
+       platform_driver_unregister(&tps68470_clk_driver);
+}
+module_exit(tps68470_clk_exit);
+
+MODULE_ALIAS("platform:tps68470-clk");
+MODULE_DESCRIPTION("clock driver for TPS68470 pmic");
+MODULE_LICENSE("GPL");
index 566ee2c..8de6a22 100644 (file)
@@ -424,19 +424,20 @@ static void clk_core_fill_parent_index(struct clk_core *core, u8 index)
 
        if (entry->hw) {
                parent = entry->hw->core;
-               /*
-                * We have a direct reference but it isn't registered yet?
-                * Orphan it and let clk_reparent() update the orphan status
-                * when the parent is registered.
-                */
-               if (!parent)
-                       parent = ERR_PTR(-EPROBE_DEFER);
        } else {
                parent = clk_core_get(core, index);
                if (PTR_ERR(parent) == -ENOENT && entry->name)
                        parent = clk_core_lookup(entry->name);
        }
 
+       /*
+        * We have a direct reference but it isn't registered yet?
+        * Orphan it and let clk_reparent() update the orphan status
+        * when the parent is registered.
+        */
+       if (!parent)
+               parent = ERR_PTR(-EPROBE_DEFER);
+
        /* Only cache it if it's not an error */
        if (!IS_ERR(parent))
                entry->core = parent;
@@ -2965,7 +2966,9 @@ static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
 {
        struct clk_core *child;
 
+       clk_pm_runtime_get(c);
        clk_summary_show_one(s, c, level);
+       clk_pm_runtime_put(c);
 
        hlist_for_each_entry(child, &c->children, child_node)
                clk_summary_show_subtree(s, child, level + 1);
@@ -3217,6 +3220,42 @@ static int current_parent_show(struct seq_file *s, void *data)
 }
 DEFINE_SHOW_ATTRIBUTE(current_parent);
 
+#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
+static ssize_t current_parent_write(struct file *file, const char __user *ubuf,
+                                   size_t count, loff_t *ppos)
+{
+       struct seq_file *s = file->private_data;
+       struct clk_core *core = s->private;
+       struct clk_core *parent;
+       u8 idx;
+       int err;
+
+       err = kstrtou8_from_user(ubuf, count, 0, &idx);
+       if (err < 0)
+               return err;
+
+       parent = clk_core_get_parent_by_index(core, idx);
+       if (!parent)
+               return -ENOENT;
+
+       clk_prepare_lock();
+       err = clk_core_set_parent_nolock(core, parent);
+       clk_prepare_unlock();
+       if (err)
+               return err;
+
+       return count;
+}
+
+static const struct file_operations current_parent_rw_fops = {
+       .open           = current_parent_open,
+       .write          = current_parent_write,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+#endif
+
 static int clk_duty_cycle_show(struct seq_file *s, void *data)
 {
        struct clk_core *core = s->private;
@@ -3282,8 +3321,12 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
 #ifdef CLOCK_ALLOW_WRITE_DEBUGFS
        debugfs_create_file("clk_prepare_enable", 0644, root, core,
                            &clk_prepare_enable_fops);
-#endif
 
+       if (core->num_parents > 1)
+               debugfs_create_file("clk_parent", 0644, root, core,
+                                   &current_parent_rw_fops);
+       else
+#endif
        if (core->num_parents > 0)
                debugfs_create_file("clk_parent", 0444, root, core,
                                    &current_parent_fops);
@@ -3343,6 +3386,24 @@ static int __init clk_debug_init(void)
 {
        struct clk_core *core;
 
+#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
+       pr_warn("\n");
+       pr_warn("********************************************************************\n");
+       pr_warn("**     NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE           **\n");
+       pr_warn("**                                                                **\n");
+       pr_warn("**  WRITEABLE clk DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n");
+       pr_warn("**                                                                **\n");
+       pr_warn("** This means that this kernel is built to expose clk operations  **\n");
+       pr_warn("** such as parent or rate setting, enabling, disabling, etc.      **\n");
+       pr_warn("** to userspace, which may compromise security on your system.    **\n");
+       pr_warn("**                                                                **\n");
+       pr_warn("** If you see this message and you are not debugging the          **\n");
+       pr_warn("** kernel, report this immediately to your vendor!                **\n");
+       pr_warn("**                                                                **\n");
+       pr_warn("**     NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE           **\n");
+       pr_warn("********************************************************************\n");
+#endif
+
        rootdir = debugfs_create_dir("clk", NULL);
 
        debugfs_create_file("clk_summary", 0444, rootdir, &all_lists,
@@ -3413,9 +3474,6 @@ static int __clk_core_init(struct clk_core *core)
        unsigned long rate;
        int phase;
 
-       if (!core)
-               return -EINVAL;
-
        clk_prepare_lock();
 
        /*
index c555776..021355a 100644 (file)
@@ -277,9 +277,9 @@ static const char * const imx8mn_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audi
 
 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_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "dummy",
+                                                "sys_pll1_200m", "audio_pll2_out", "sys_pll2_500m",
+                                                "dummy", "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", };
index 1283730..c990ad3 100644 (file)
@@ -700,7 +700,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
        hws[IMX8MP_CLK_HDMI_ROOT] = imx_clk_hw_gate4("hdmi_root_clk", "hdmi_axi", ccm_base + 0x45f0, 0);
        hws[IMX8MP_CLK_TSENSOR_ROOT] = imx_clk_hw_gate4("tsensor_root_clk", "ipg_root", ccm_base + 0x4620, 0);
        hws[IMX8MP_CLK_VPU_ROOT] = imx_clk_hw_gate4("vpu_root_clk", "vpu_bus", ccm_base + 0x4630, 0);
-       hws[IMX8MP_CLK_AUDIO_ROOT] = imx_clk_hw_gate4("audio_root_clk", "ipg_root", ccm_base + 0x4650, 0);
+       hws[IMX8MP_CLK_AUDIO_ROOT] = imx_clk_hw_gate4("audio_root_clk", "audio_ahb", ccm_base + 0x4650, 0);
 
        hws[IMX8MP_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_core",
                                             hws[IMX8MP_CLK_A53_CORE]->clk,
index 6699437..8eb1af2 100644 (file)
@@ -559,6 +559,7 @@ static struct platform_driver imx8ulp_clk_driver = {
        .probe  = imx8ulp_clk_probe,
        .driver = {
                .name           = KBUILD_MODNAME,
+               .suppress_bind_attrs = true,
                .of_match_table = imx8ulp_clk_dt_ids,
        },
 };
index 36ffb05..93ee81b 100644 (file)
@@ -8,20 +8,19 @@
 
 #include "clk.h"
 
+#define MFN_BITS       (10)
+#define MFN_SIGN       (BIT(MFN_BITS - 1))
+#define MFN_MASK       (MFN_SIGN - 1)
+
 /**
- * pll v1
+ * struct clk_pllv1 - IMX PLLv1 clock descriptor
  *
- * @clk_hw     clock source
- * @parent     the parent clock name
- * @base       base address of pll registers
+ * @hw:                clock source
+ * @base:      base address of pll registers
+ * @type:      type of IMX_PLLV1
  *
  * PLL clock version 1, found on i.MX1/21/25/27/31/35
  */
-
-#define MFN_BITS       (10)
-#define MFN_SIGN       (BIT(MFN_BITS - 1))
-#define MFN_MASK       (MFN_SIGN - 1)
-
 struct clk_pllv1 {
        struct clk_hw   hw;
        void __iomem    *base;
index 20ee961..eea32f8 100644 (file)
@@ -247,7 +247,7 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
        div = rate / parent_rate;
        temp64 = (u64) (rate - div * parent_rate);
        temp64 *= mfd;
-       do_div(temp64, parent_rate);
+       temp64 = div64_ul(temp64, parent_rate);
        mfn = temp64;
 
        temp64 = (u64)parent_rate;
@@ -277,7 +277,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
        div = rate / parent_rate;
        temp64 = (u64) (rate - div * parent_rate);
        temp64 *= mfd;
-       do_div(temp64, parent_rate);
+       temp64 = div64_ul(temp64, parent_rate);
        mfn = temp64;
 
        val = readl_relaxed(pll->base);
@@ -334,7 +334,7 @@ static struct clk_pllv3_vf610_mf clk_pllv3_vf610_rate_to_mf(
                /* rate = parent_rate * (mfi + mfn/mfd) */
                temp64 = rate - parent_rate * mf.mfi;
                temp64 *= mf.mfd;
-               do_div(temp64, parent_rate);
+               temp64 = div64_ul(temp64, parent_rate);
                mf.mfn = temp64;
        }
 
index 080d492..8fdd383 100644 (file)
@@ -313,6 +313,16 @@ static const struct ingenic_cgu_clk_info jz4760_cgu_clocks[] = {
                .parents = { JZ4760_CLK_H2CLK, },
                .gate = { CGU_REG_CLKGR0, 21 },
        },
+       [JZ4760_CLK_MDMA] = {
+               "mdma", CGU_CLK_GATE,
+               .parents = { JZ4760_CLK_HCLK, },
+               .gate = { CGU_REG_CLKGR0, 25 },
+       },
+       [JZ4760_CLK_BDMA] = {
+               "bdma", CGU_CLK_GATE,
+               .parents = { JZ4760_CLK_HCLK, },
+               .gate = { CGU_REG_CLKGR1, 0 },
+       },
        [JZ4760_CLK_I2C0] = {
                "i2c0", CGU_CLK_GATE,
                .parents = { JZ4760_CLK_EXT, },
index 8c6c120..7ef9125 100644 (file)
@@ -329,6 +329,11 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
                .parents = { JZ4770_CLK_H2CLK, },
                .gate = { CGU_REG_CLKGR0, 21 },
        },
+       [JZ4770_CLK_BDMA] = {
+               "bdma", CGU_CLK_GATE,
+               .parents = { JZ4770_CLK_H2CLK, },
+               .gate = { CGU_REG_CLKGR1, 0 },
+       },
        [JZ4770_CLK_I2C0] = {
                "i2c0", CGU_CLK_GATE,
                .parents = { JZ4770_CLK_EXT, },
index 3ce6fb0..01ef02c 100644 (file)
@@ -344,6 +344,23 @@ config COMMON_CLK_MT7629_HIFSYS
          This driver supports MediaTek MT7629 HIFSYS clocks providing
          to PCI-E and USB.
 
+config COMMON_CLK_MT7986
+       bool "Clock driver for MediaTek MT7986"
+       depends on ARCH_MEDIATEK || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK
+       help
+         This driver supports MediaTek MT7986 basic clocks and clocks
+         required for various peripherals found on MediaTek.
+
+config COMMON_CLK_MT7986_ETHSYS
+       bool "Clock driver for MediaTek MT7986 ETHSYS"
+       depends on COMMON_CLK_MT7986
+       default COMMON_CLK_MT7986
+       help
+         This driver adds support for clocks for Ethernet and SGMII
+         required on MediaTek MT7986 SoC.
+
 config COMMON_CLK_MT8135
        bool "Clock driver for MediaTek MT8135"
        depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
index dc96038..7b0c264 100644 (file)
@@ -46,6 +46,10 @@ obj-$(CONFIG_COMMON_CLK_MT7622_AUDSYS) += clk-mt7622-aud.o
 obj-$(CONFIG_COMMON_CLK_MT7629) += clk-mt7629.o
 obj-$(CONFIG_COMMON_CLK_MT7629_ETHSYS) += clk-mt7629-eth.o
 obj-$(CONFIG_COMMON_CLK_MT7629_HIFSYS) += clk-mt7629-hif.o
+obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-apmixed.o
+obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-topckgen.o
+obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-infracfg.o
+obj-$(CONFIG_COMMON_CLK_MT7986_ETHSYS) += clk-mt7986-eth.o
 obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
 obj-$(CONFIG_COMMON_CLK_MT8167) += clk-mt8167.o
 obj-$(CONFIG_COMMON_CLK_MT8167_AUDSYS) += clk-mt8167-aud.o
index b02d2f7..5d88b42 100644 (file)
 #include "clk-mtk.h"
 #include "clk-gate.h"
 
-static int mtk_cg_bit_is_cleared(struct clk_hw *hw)
+static u32 mtk_get_clockgating(struct clk_hw *hw)
 {
        struct mtk_clk_gate *cg = to_mtk_clk_gate(hw);
        u32 val;
 
        regmap_read(cg->regmap, cg->sta_ofs, &val);
 
-       val &= BIT(cg->bit);
+       return val & BIT(cg->bit);
+}
 
-       return val == 0;
+static int mtk_cg_bit_is_cleared(struct clk_hw *hw)
+{
+       return mtk_get_clockgating(hw) == 0;
 }
 
 static int mtk_cg_bit_is_set(struct clk_hw *hw)
 {
-       struct mtk_clk_gate *cg = to_mtk_clk_gate(hw);
-       u32 val;
-
-       regmap_read(cg->regmap, cg->sta_ofs, &val);
-
-       val &= BIT(cg->bit);
-
-       return val != 0;
+       return mtk_get_clockgating(hw) != 0;
 }
 
 static void mtk_cg_set_bit(struct clk_hw *hw)
@@ -57,17 +53,15 @@ static void mtk_cg_clr_bit(struct clk_hw *hw)
 static void mtk_cg_set_bit_no_setclr(struct clk_hw *hw)
 {
        struct mtk_clk_gate *cg = to_mtk_clk_gate(hw);
-       u32 cgbit = BIT(cg->bit);
 
-       regmap_update_bits(cg->regmap, cg->sta_ofs, cgbit, cgbit);
+       regmap_set_bits(cg->regmap, cg->sta_ofs, BIT(cg->bit));
 }
 
 static void mtk_cg_clr_bit_no_setclr(struct clk_hw *hw)
 {
        struct mtk_clk_gate *cg = to_mtk_clk_gate(hw);
-       u32 cgbit = BIT(cg->bit);
 
-       regmap_update_bits(cg->regmap, cg->sta_ofs, cgbit, 0);
+       regmap_clear_bits(cg->regmap, cg->sta_ofs, BIT(cg->bit));
 }
 
 static int mtk_cg_enable(struct clk_hw *hw)
diff --git a/drivers/clk/mediatek/clk-mt7986-apmixed.c b/drivers/clk/mediatek/clk-mt7986-apmixed.c
new file mode 100644 (file)
index 0000000..76c8ebd
--- /dev/null
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-1.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ * Author: Wenzhen Yu <wenzhen.yu@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 "clk-mux.h"
+
+#include <dt-bindings/clock/mt7986-clk.h>
+#include <linux/clk.h>
+
+#define MT7986_PLL_FMAX (2500UL * MHZ)
+#define CON0_MT7986_RST_BAR BIT(27)
+
+#define PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,       \
+                _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift,         \
+                _div_table, _parent_name)                                     \
+       {                                                                      \
+               .id = _id, .name = _name, .reg = _reg, .pwr_reg = _pwr_reg,    \
+               .en_mask = _en_mask, .flags = _flags,                          \
+               .rst_bar_mask = CON0_MT7986_RST_BAR, .fmax = MT7986_PLL_FMAX,  \
+               .pcwbits = _pcwbits, .pd_reg = _pd_reg, .pd_shift = _pd_shift, \
+               .tuner_reg = _tuner_reg, .pcw_reg = _pcw_reg,                  \
+               .pcw_shift = _pcw_shift, .div_table = _div_table,              \
+               .parent_name = _parent_name,                                   \
+       }
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg,   \
+           _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift)                       \
+       PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,       \
+                _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, NULL,   \
+                "clkxtal")
+
+static const struct mtk_pll_data plls[] = {
+       PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0200, 0x020C, 0x00000001, 0, 32,
+           0x0200, 4, 0, 0x0204, 0),
+       PLL(CLK_APMIXED_NET2PLL, "net2pll", 0x0210, 0x021C, 0x00000001, 0, 32,
+           0x0210, 4, 0, 0x0214, 0),
+       PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0220, 0x022C, 0x00000001, 0, 32,
+           0x0220, 4, 0, 0x0224, 0),
+       PLL(CLK_APMIXED_SGMPLL, "sgmpll", 0x0230, 0x023c, 0x00000001, 0, 32,
+           0x0230, 4, 0, 0x0234, 0),
+       PLL(CLK_APMIXED_WEDMCUPLL, "wedmcupll", 0x0240, 0x024c, 0x00000001, 0,
+           32, 0x0240, 4, 0, 0x0244, 0),
+       PLL(CLK_APMIXED_NET1PLL, "net1pll", 0x0250, 0x025c, 0x00000001, 0, 32,
+           0x0250, 4, 0, 0x0254, 0),
+       PLL(CLK_APMIXED_MPLL, "mpll", 0x0260, 0x0270, 0x00000001, 0, 32, 0x0260,
+           4, 0, 0x0264, 0),
+       PLL(CLK_APMIXED_APLL2, "apll2", 0x0278, 0x0288, 0x00000001, 0, 32,
+           0x0278, 4, 0, 0x027c, 0),
+};
+
+static const struct of_device_id of_match_clk_mt7986_apmixed[] = {
+       { .compatible = "mediatek,mt7986-apmixedsys", },
+       {}
+};
+
+static int clk_mt7986_apmixed_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(ARRAY_SIZE(plls));
+       if (!clk_data)
+               return -ENOMEM;
+
+       mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+
+       clk_prepare_enable(clk_data->clks[CLK_APMIXED_ARMPLL]);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r) {
+               pr_err("%s(): could not register clock provider: %d\n",
+                      __func__, r);
+               goto free_apmixed_data;
+       }
+       return r;
+
+free_apmixed_data:
+       mtk_free_clk_data(clk_data);
+       return r;
+}
+
+static struct platform_driver clk_mt7986_apmixed_drv = {
+       .probe = clk_mt7986_apmixed_probe,
+       .driver = {
+               .name = "clk-mt7986-apmixed",
+               .of_match_table = of_match_clk_mt7986_apmixed,
+       },
+};
+builtin_platform_driver(clk_mt7986_apmixed_drv);
diff --git a/drivers/clk/mediatek/clk-mt7986-eth.c b/drivers/clk/mediatek/clk-mt7986-eth.c
new file mode 100644 (file)
index 0000000..495d023
--- /dev/null
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ * Author: Wenzhen Yu <wenzhen.yu@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/mt7986-clk.h>
+
+static const struct mtk_gate_regs sgmii0_cg_regs = {
+       .set_ofs = 0xe4,
+       .clr_ofs = 0xe4,
+       .sta_ofs = 0xe4,
+};
+
+#define GATE_SGMII0(_id, _name, _parent, _shift)                               \
+       {                                                                      \
+               .id = _id, .name = _name, .parent_name = _parent,              \
+               .regs = &sgmii0_cg_regs, .shift = _shift,                      \
+               .ops = &mtk_clk_gate_ops_no_setclr_inv,                        \
+       }
+
+static const struct mtk_gate sgmii0_clks[] __initconst = {
+       GATE_SGMII0(CLK_SGMII0_TX250M_EN, "sgmii0_tx250m_en", "top_xtal", 2),
+       GATE_SGMII0(CLK_SGMII0_RX250M_EN, "sgmii0_rx250m_en", "top_xtal", 3),
+       GATE_SGMII0(CLK_SGMII0_CDR_REF, "sgmii0_cdr_ref", "top_xtal", 4),
+       GATE_SGMII0(CLK_SGMII0_CDR_FB, "sgmii0_cdr_fb", "top_xtal", 5),
+};
+
+static const struct mtk_gate_regs sgmii1_cg_regs = {
+       .set_ofs = 0xe4,
+       .clr_ofs = 0xe4,
+       .sta_ofs = 0xe4,
+};
+
+#define GATE_SGMII1(_id, _name, _parent, _shift)                               \
+       {                                                                      \
+               .id = _id, .name = _name, .parent_name = _parent,              \
+               .regs = &sgmii1_cg_regs, .shift = _shift,                      \
+               .ops = &mtk_clk_gate_ops_no_setclr_inv,                        \
+       }
+
+static const struct mtk_gate sgmii1_clks[] __initconst = {
+       GATE_SGMII1(CLK_SGMII1_TX250M_EN, "sgmii1_tx250m_en", "top_xtal", 2),
+       GATE_SGMII1(CLK_SGMII1_RX250M_EN, "sgmii1_rx250m_en", "top_xtal", 3),
+       GATE_SGMII1(CLK_SGMII1_CDR_REF, "sgmii1_cdr_ref", "top_xtal", 4),
+       GATE_SGMII1(CLK_SGMII1_CDR_FB, "sgmii1_cdr_fb", "top_xtal", 5),
+};
+
+static const struct mtk_gate_regs eth_cg_regs = {
+       .set_ofs = 0x30,
+       .clr_ofs = 0x30,
+       .sta_ofs = 0x30,
+};
+
+#define GATE_ETH(_id, _name, _parent, _shift)                                  \
+       {                                                                      \
+               .id = _id, .name = _name, .parent_name = _parent,              \
+               .regs = &eth_cg_regs, .shift = _shift,                         \
+               .ops = &mtk_clk_gate_ops_no_setclr_inv,                        \
+       }
+
+static const struct mtk_gate eth_clks[] __initconst = {
+       GATE_ETH(CLK_ETH_FE_EN, "eth_fe_en", "netsys_2x_sel", 6),
+       GATE_ETH(CLK_ETH_GP2_EN, "eth_gp2_en", "sgm_325m_sel", 7),
+       GATE_ETH(CLK_ETH_GP1_EN, "eth_gp1_en", "sgm_325m_sel", 8),
+       GATE_ETH(CLK_ETH_WOCPU1_EN, "eth_wocpu1_en", "netsys_mcu_sel", 14),
+       GATE_ETH(CLK_ETH_WOCPU0_EN, "eth_wocpu0_en", "netsys_mcu_sel", 15),
+};
+
+static void __init mtk_sgmiisys_0_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii0_clks));
+
+       mtk_clk_register_gates(node, sgmii0_clks, ARRAY_SIZE(sgmii0_clks),
+                              clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                      __func__, r);
+}
+CLK_OF_DECLARE(mtk_sgmiisys_0, "mediatek,mt7986-sgmiisys_0",
+              mtk_sgmiisys_0_init);
+
+static void __init mtk_sgmiisys_1_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii1_clks));
+
+       mtk_clk_register_gates(node, sgmii1_clks, ARRAY_SIZE(sgmii1_clks),
+                              clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                      __func__, r);
+}
+CLK_OF_DECLARE(mtk_sgmiisys_1, "mediatek,mt7986-sgmiisys_1",
+              mtk_sgmiisys_1_init);
+
+static void __init mtk_ethsys_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(ARRAY_SIZE(eth_clks));
+
+       mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks), clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                      __func__, r);
+}
+CLK_OF_DECLARE(mtk_ethsys, "mediatek,mt7986-ethsys_ck", mtk_ethsys_init);
diff --git a/drivers/clk/mediatek/clk-mt7986-infracfg.c b/drivers/clk/mediatek/clk-mt7986-infracfg.c
new file mode 100644 (file)
index 0000000..3be168c
--- /dev/null
@@ -0,0 +1,224 @@
+// SPDX-License-Identifier: GPL-1.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ * Author: Wenzhen Yu <wenzhen.yu@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 "clk-mux.h"
+
+#include <dt-bindings/clock/mt7986-clk.h>
+#include <linux/clk.h>
+
+static DEFINE_SPINLOCK(mt7986_clk_lock);
+
+static const struct mtk_fixed_factor infra_divs[] = {
+       FACTOR(CLK_INFRA_SYSAXI_D2, "infra_sysaxi_d2", "sysaxi_sel", 1, 2),
+};
+
+static const char *const infra_uart_parent[] __initconst = { "csw_f26m_sel",
+                                                            "uart_sel" };
+
+static const char *const infra_spi_parents[] __initconst = { "i2c_sel",
+                                                            "spi_sel" };
+
+static const char *const infra_pwm_bsel_parents[] __initconst = {
+       "top_rtc_32p7k", "csw_f26m_sel", "infra_sysaxi_d2", "pwm_sel"
+};
+
+static const char *const infra_pcie_parents[] __initconst = {
+       "top_rtc_32p7k", "csw_f26m_sel", "top_xtal", "pextp_tl_ck_sel"
+};
+
+static const struct mtk_mux infra_muxes[] = {
+       /* MODULE_CLK_SEL_0 */
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART0_SEL, "infra_uart0_sel",
+                            infra_uart_parent, 0x0018, 0x0010, 0x0014, 0, 1,
+                            -1, -1, -1),
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART1_SEL, "infra_uart1_sel",
+                            infra_uart_parent, 0x0018, 0x0010, 0x0014, 1, 1,
+                            -1, -1, -1),
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART2_SEL, "infra_uart2_sel",
+                            infra_uart_parent, 0x0018, 0x0010, 0x0014, 2, 1,
+                            -1, -1, -1),
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI0_SEL, "infra_spi0_sel",
+                            infra_spi_parents, 0x0018, 0x0010, 0x0014, 4, 1,
+                            -1, -1, -1),
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI1_SEL, "infra_spi1_sel",
+                            infra_spi_parents, 0x0018, 0x0010, 0x0014, 5, 1,
+                            -1, -1, -1),
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM1_SEL, "infra_pwm1_sel",
+                            infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 9,
+                            2, -1, -1, -1),
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM2_SEL, "infra_pwm2_sel",
+                            infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 11,
+                            2, -1, -1, -1),
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_BSEL, "infra_pwm_bsel",
+                            infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 13,
+                            2, -1, -1, -1),
+       /* MODULE_CLK_SEL_1 */
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_SEL, "infra_pcie_sel",
+                            infra_pcie_parents, 0x0028, 0x0020, 0x0024, 0, 2,
+                            -1, -1, -1),
+};
+
+static const struct mtk_gate_regs infra0_cg_regs = {
+       .set_ofs = 0x40,
+       .clr_ofs = 0x44,
+       .sta_ofs = 0x48,
+};
+
+static const struct mtk_gate_regs infra1_cg_regs = {
+       .set_ofs = 0x50,
+       .clr_ofs = 0x54,
+       .sta_ofs = 0x58,
+};
+
+static const struct mtk_gate_regs infra2_cg_regs = {
+       .set_ofs = 0x60,
+       .clr_ofs = 0x64,
+       .sta_ofs = 0x68,
+};
+
+#define GATE_INFRA0(_id, _name, _parent, _shift)                               \
+       {                                                                      \
+               .id = _id, .name = _name, .parent_name = _parent,              \
+               .regs = &infra0_cg_regs, .shift = _shift,                      \
+               .ops = &mtk_clk_gate_ops_setclr,                               \
+       }
+
+#define GATE_INFRA1(_id, _name, _parent, _shift)                               \
+       {                                                                      \
+               .id = _id, .name = _name, .parent_name = _parent,              \
+               .regs = &infra1_cg_regs, .shift = _shift,                      \
+               .ops = &mtk_clk_gate_ops_setclr,                               \
+       }
+
+#define GATE_INFRA2(_id, _name, _parent, _shift)                               \
+       {                                                                      \
+               .id = _id, .name = _name, .parent_name = _parent,              \
+               .regs = &infra2_cg_regs, .shift = _shift,                      \
+               .ops = &mtk_clk_gate_ops_setclr,                               \
+       }
+
+static const struct mtk_gate infra_clks[] = {
+       /* INFRA0 */
+       GATE_INFRA0(CLK_INFRA_GPT_STA, "infra_gpt_sta", "infra_sysaxi_d2", 0),
+       GATE_INFRA0(CLK_INFRA_PWM_HCK, "infra_pwm_hck", "infra_sysaxi_d2", 1),
+       GATE_INFRA0(CLK_INFRA_PWM_STA, "infra_pwm_sta", "infra_pwm_bsel", 2),
+       GATE_INFRA0(CLK_INFRA_PWM1_CK, "infra_pwm1", "infra_pwm1_sel", 3),
+       GATE_INFRA0(CLK_INFRA_PWM2_CK, "infra_pwm2", "infra_pwm2_sel", 4),
+       GATE_INFRA0(CLK_INFRA_CQ_DMA_CK, "infra_cq_dma", "sysaxi_sel", 6),
+       GATE_INFRA0(CLK_INFRA_EIP97_CK, "infra_eip97", "eip_b_sel", 7),
+       GATE_INFRA0(CLK_INFRA_AUD_BUS_CK, "infra_aud_bus", "sysaxi_sel", 8),
+       GATE_INFRA0(CLK_INFRA_AUD_26M_CK, "infra_aud_26m", "csw_f26m_sel", 9),
+       GATE_INFRA0(CLK_INFRA_AUD_L_CK, "infra_aud_l", "aud_l_sel", 10),
+       GATE_INFRA0(CLK_INFRA_AUD_AUD_CK, "infra_aud_aud", "a1sys_sel", 11),
+       GATE_INFRA0(CLK_INFRA_AUD_EG2_CK, "infra_aud_eg2", "a_tuner_sel", 13),
+       GATE_INFRA0(CLK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", "csw_f26m_sel",
+                   14),
+       GATE_INFRA0(CLK_INFRA_DBG_CK, "infra_dbg", "infra_sysaxi_d2", 15),
+       GATE_INFRA0(CLK_INFRA_AP_DMA_CK, "infra_ap_dma", "infra_sysaxi_d2", 16),
+       GATE_INFRA0(CLK_INFRA_SEJ_CK, "infra_sej", "infra_sysaxi_d2", 24),
+       GATE_INFRA0(CLK_INFRA_SEJ_13M_CK, "infra_sej_13m", "csw_f26m_sel", 25),
+       GATE_INFRA0(CLK_INFRA_TRNG_CK, "infra_trng", "sysaxi_sel", 26),
+       /* INFRA1 */
+       GATE_INFRA1(CLK_INFRA_THERM_CK, "infra_therm", "csw_f26m_sel", 0),
+       GATE_INFRA1(CLK_INFRA_I2C0_CK, "infra_i2c0", "i2c_sel", 1),
+       GATE_INFRA1(CLK_INFRA_UART0_CK, "infra_uart0", "infra_uart0_sel", 2),
+       GATE_INFRA1(CLK_INFRA_UART1_CK, "infra_uart1", "infra_uart1_sel", 3),
+       GATE_INFRA1(CLK_INFRA_UART2_CK, "infra_uart2", "infra_uart2_sel", 4),
+       GATE_INFRA1(CLK_INFRA_NFI1_CK, "infra_nfi1", "nfi1x_sel", 8),
+       GATE_INFRA1(CLK_INFRA_SPINFI1_CK, "infra_spinfi1", "spinfi_sel", 9),
+       GATE_INFRA1(CLK_INFRA_NFI_HCK_CK, "infra_nfi_hck", "infra_sysaxi_d2",
+                   10),
+       GATE_INFRA1(CLK_INFRA_SPI0_CK, "infra_spi0", "infra_spi0_sel", 11),
+       GATE_INFRA1(CLK_INFRA_SPI1_CK, "infra_spi1", "infra_spi1_sel", 12),
+       GATE_INFRA1(CLK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", "infra_sysaxi_d2",
+                   13),
+       GATE_INFRA1(CLK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", "infra_sysaxi_d2",
+                   14),
+       GATE_INFRA1(CLK_INFRA_FRTC_CK, "infra_frtc", "top_rtc_32k", 15),
+       GATE_INFRA1(CLK_INFRA_MSDC_CK, "infra_msdc", "emmc_416m_sel", 16),
+       GATE_INFRA1(CLK_INFRA_MSDC_HCK_CK, "infra_msdc_hck", "emmc_250m_sel",
+                   17),
+       GATE_INFRA1(CLK_INFRA_MSDC_133M_CK, "infra_msdc_133m", "sysaxi_sel",
+                   18),
+       GATE_INFRA1(CLK_INFRA_MSDC_66M_CK, "infra_msdc_66m", "infra_sysaxi_d2",
+                   19),
+       GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m", "csw_f26m_sel", 20),
+       GATE_INFRA1(CLK_INFRA_ADC_FRC_CK, "infra_adc_frc", "csw_f26m_sel", 21),
+       GATE_INFRA1(CLK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", "nfi1x_sel", 23),
+       /* INFRA2 */
+       GATE_INFRA2(CLK_INFRA_IUSB_133_CK, "infra_iusb_133", "sysaxi_sel", 0),
+       GATE_INFRA2(CLK_INFRA_IUSB_66M_CK, "infra_iusb_66m", "infra_sysaxi_d2",
+                   1),
+       GATE_INFRA2(CLK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", "u2u3_sys_sel", 2),
+       GATE_INFRA2(CLK_INFRA_IUSB_CK, "infra_iusb", "u2u3_sel", 3),
+       GATE_INFRA2(CLK_INFRA_IPCIE_CK, "infra_ipcie", "pextp_tl_ck_sel", 12),
+       GATE_INFRA2(CLK_INFRA_IPCIE_PIPE_CK, "infra_ipcie_pipe", "top_xtal",
+                   13),
+       GATE_INFRA2(CLK_INFRA_IPCIER_CK, "infra_ipcier", "csw_f26m_sel", 14),
+       GATE_INFRA2(CLK_INFRA_IPCIEB_CK, "infra_ipcieb", "sysaxi_sel", 15),
+};
+
+static int clk_mt7986_infracfg_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       int r;
+       void __iomem *base;
+       int nr = ARRAY_SIZE(infra_divs) + ARRAY_SIZE(infra_muxes) +
+                ARRAY_SIZE(infra_clks);
+
+       base = of_iomap(node, 0);
+       if (!base) {
+               pr_err("%s(): ioremap failed\n", __func__);
+               return -ENOMEM;
+       }
+
+       clk_data = mtk_alloc_clk_data(nr);
+
+       if (!clk_data)
+               return -ENOMEM;
+
+       mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
+       mtk_clk_register_muxes(infra_muxes, ARRAY_SIZE(infra_muxes), node,
+                              &mt7986_clk_lock, clk_data);
+       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) {
+               pr_err("%s(): could not register clock provider: %d\n",
+                      __func__, r);
+               goto free_infracfg_data;
+       }
+       return r;
+
+free_infracfg_data:
+       mtk_free_clk_data(clk_data);
+       return r;
+
+}
+
+static const struct of_device_id of_match_clk_mt7986_infracfg[] = {
+       { .compatible = "mediatek,mt7986-infracfg", },
+       {}
+};
+
+static struct platform_driver clk_mt7986_infracfg_drv = {
+       .probe = clk_mt7986_infracfg_probe,
+       .driver = {
+               .name = "clk-mt7986-infracfg",
+               .of_match_table = of_match_clk_mt7986_infracfg,
+       },
+};
+builtin_platform_driver(clk_mt7986_infracfg_drv);
diff --git a/drivers/clk/mediatek/clk-mt7986-topckgen.c b/drivers/clk/mediatek/clk-mt7986-topckgen.c
new file mode 100644 (file)
index 0000000..8550e2b
--- /dev/null
@@ -0,0 +1,342 @@
+// SPDX-License-Identifier: GPL-1.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ * Author: Wenzhen Yu <wenzhen.yu@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 "clk-mux.h"
+
+#include <dt-bindings/clock/mt7986-clk.h>
+#include <linux/clk.h>
+
+static DEFINE_SPINLOCK(mt7986_clk_lock);
+
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+       FIXED_CLK(CLK_TOP_XTAL, "top_xtal", "clkxtal", 40000000),
+       FIXED_CLK(CLK_TOP_JTAG, "top_jtag", "clkxtal", 50000000),
+};
+
+static const struct mtk_fixed_factor top_divs[] = {
+       /* XTAL */
+       FACTOR(CLK_TOP_XTAL_D2, "top_xtal_d2", "top_xtal", 1, 2),
+       FACTOR(CLK_TOP_RTC_32K, "top_rtc_32k", "top_xtal", 1, 1250),
+       FACTOR(CLK_TOP_RTC_32P7K, "top_rtc_32p7k", "top_xtal", 1, 1220),
+       /* MPLL */
+       FACTOR(CLK_TOP_MPLL_D2, "top_mpll_d2", "mpll", 1, 2),
+       FACTOR(CLK_TOP_MPLL_D4, "top_mpll_d4", "mpll", 1, 4),
+       FACTOR(CLK_TOP_MPLL_D8, "top_mpll_d8", "mpll", 1, 8),
+       FACTOR(CLK_TOP_MPLL_D8_D2, "top_mpll_d8_d2", "mpll", 1, 16),
+       FACTOR(CLK_TOP_MPLL_D3_D2, "top_mpll_d3_d2", "mpll", 1, 6),
+       /* MMPLL */
+       FACTOR(CLK_TOP_MMPLL_D2, "top_mmpll_d2", "mmpll", 1, 2),
+       FACTOR(CLK_TOP_MMPLL_D4, "top_mmpll_d4", "mmpll", 1, 4),
+       FACTOR(CLK_TOP_MMPLL_D8, "top_mmpll_d8", "mmpll", 1, 8),
+       FACTOR(CLK_TOP_MMPLL_D8_D2, "top_mmpll_d8_d2", "mmpll", 1, 16),
+       FACTOR(CLK_TOP_MMPLL_D3_D8, "top_mmpll_d3_d8", "mmpll", 1, 24),
+       FACTOR(CLK_TOP_MMPLL_U2PHY, "top_mmpll_u2phy", "mmpll", 1, 30),
+       /* APLL2 */
+       FACTOR(CLK_TOP_APLL2_D4, "top_apll2_d4", "apll2", 1, 4),
+       /* NET1PLL */
+       FACTOR(CLK_TOP_NET1PLL_D4, "top_net1pll_d4", "net1pll", 1, 4),
+       FACTOR(CLK_TOP_NET1PLL_D5, "top_net1pll_d5", "net1pll", 1, 5),
+       FACTOR(CLK_TOP_NET1PLL_D5_D2, "top_net1pll_d5_d2", "net1pll", 1, 10),
+       FACTOR(CLK_TOP_NET1PLL_D5_D4, "top_net1pll_d5_d4", "net1pll", 1, 20),
+       FACTOR(CLK_TOP_NET1PLL_D8_D2, "top_net1pll_d8_d2", "net1pll", 1, 16),
+       FACTOR(CLK_TOP_NET1PLL_D8_D4, "top_net1pll_d8_d4", "net1pll", 1, 32),
+       /* NET2PLL */
+       FACTOR(CLK_TOP_NET2PLL_D4, "top_net2pll_d4", "net2pll", 1, 4),
+       FACTOR(CLK_TOP_NET2PLL_D4_D2, "top_net2pll_d4_d2", "net2pll", 1, 8),
+       FACTOR(CLK_TOP_NET2PLL_D3_D2, "top_net2pll_d3_d2", "net2pll", 1, 2),
+       /* WEDMCUPLL */
+       FACTOR(CLK_TOP_WEDMCUPLL_D5_D2, "top_wedmcupll_d5_d2", "wedmcupll", 1,
+              10),
+};
+
+static const char *const nfi1x_parents[] __initconst = { "top_xtal",
+                                                        "top_mmpll_d8",
+                                                        "top_net1pll_d8_d2",
+                                                        "top_net2pll_d3_d2",
+                                                        "top_mpll_d4",
+                                                        "top_mmpll_d8_d2",
+                                                        "top_wedmcupll_d5_d2",
+                                                        "top_mpll_d8" };
+
+static const char *const spinfi_parents[] __initconst = {
+       "top_xtal_d2",     "top_xtal",  "top_net1pll_d5_d4",
+       "top_mpll_d4",     "top_mmpll_d8_d2", "top_wedmcupll_d5_d2",
+       "top_mmpll_d3_d8", "top_mpll_d8"
+};
+
+static const char *const spi_parents[] __initconst = {
+       "top_xtal",       "top_mpll_d2",        "top_mmpll_d8",
+       "top_net1pll_d8_d2", "top_net2pll_d3_d2",  "top_net1pll_d5_d4",
+       "top_mpll_d4",       "top_wedmcupll_d5_d2"
+};
+
+static const char *const uart_parents[] __initconst = { "top_xtal",
+                                                       "top_mpll_d8",
+                                                       "top_mpll_d8_d2" };
+
+static const char *const pwm_parents[] __initconst = {
+       "top_xtal", "top_net1pll_d8_d2", "top_net1pll_d5_d4", "top_mpll_d4"
+};
+
+static const char *const i2c_parents[] __initconst = {
+       "top_xtal", "top_net1pll_d5_d4", "top_mpll_d4", "top_net1pll_d8_d4"
+};
+
+static const char *const pextp_tl_ck_parents[] __initconst = {
+       "top_xtal", "top_net1pll_d5_d4", "top_net2pll_d4_d2", "top_rtc_32k"
+};
+
+static const char *const emmc_250m_parents[] __initconst = {
+       "top_xtal", "top_net1pll_d5_d2"
+};
+
+static const char *const emmc_416m_parents[] __initconst = { "top_xtal",
+                                                            "mpll" };
+
+static const char *const f_26m_adc_parents[] __initconst = { "top_xtal",
+                                                            "top_mpll_d8_d2" };
+
+static const char *const dramc_md32_parents[] __initconst = { "top_xtal",
+                                                             "top_mpll_d2" };
+
+static const char *const sysaxi_parents[] __initconst = { "top_xtal",
+                                                         "top_net1pll_d8_d2",
+                                                         "top_net2pll_d4" };
+
+static const char *const sysapb_parents[] __initconst = { "top_xtal",
+                                                         "top_mpll_d3_d2",
+                                                         "top_net2pll_d4_d2" };
+
+static const char *const arm_db_main_parents[] __initconst = {
+       "top_xtal", "top_net2pll_d3_d2"
+};
+
+static const char *const arm_db_jtsel_parents[] __initconst = { "top_jtag",
+                                                               "top_xtal" };
+
+static const char *const netsys_parents[] __initconst = { "top_xtal",
+                                                         "top_mmpll_d4" };
+
+static const char *const netsys_500m_parents[] __initconst = {
+       "top_xtal", "top_net1pll_d5"
+};
+
+static const char *const netsys_mcu_parents[] __initconst = {
+       "top_xtal", "wedmcupll", "top_mmpll_d2", "top_net1pll_d4",
+       "top_net1pll_d5"
+};
+
+static const char *const netsys_2x_parents[] __initconst = {
+       "top_xtal", "net2pll", "wedmcupll", "top_mmpll_d2"
+};
+
+static const char *const sgm_325m_parents[] __initconst = { "top_xtal",
+                                                           "sgmpll" };
+
+static const char *const sgm_reg_parents[] __initconst = {
+       "top_xtal", "top_net1pll_d8_d4"
+};
+
+static const char *const a1sys_parents[] __initconst = { "top_xtal",
+                                                        "top_apll2_d4" };
+
+static const char *const conn_mcusys_parents[] __initconst = { "top_xtal",
+                                                              "top_mmpll_d2" };
+
+static const char *const eip_b_parents[] __initconst = { "top_xtal",
+                                                        "net2pll" };
+
+static const char *const aud_l_parents[] __initconst = { "top_xtal", "apll2",
+                                                        "top_mpll_d8_d2" };
+
+static const char *const a_tuner_parents[] __initconst = { "top_xtal",
+                                                          "top_apll2_d4",
+                                                          "top_mpll_d8_d2" };
+
+static const char *const u2u3_sys_parents[] __initconst = {
+       "top_xtal", "top_net1pll_d5_d4"
+};
+
+static const char *const da_u2_refsel_parents[] __initconst = {
+       "top_xtal", "top_mmpll_u2phy"
+};
+
+static const struct mtk_mux top_muxes[] = {
+       /* CLK_CFG_0 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents,
+                            0x000, 0x004, 0x008, 0, 3, 7, 0x1C0, 0),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents,
+                            0x000, 0x004, 0x008, 8, 3, 15, 0x1C0, 1),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x000,
+                            0x004, 0x008, 16, 3, 23, 0x1C0, 2),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents,
+                            0x000, 0x004, 0x008, 24, 3, 31, 0x1C0, 3),
+       /* CLK_CFG_1 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x010,
+                            0x014, 0x018, 0, 2, 7, 0x1C0, 4),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x010,
+                            0x014, 0x018, 8, 2, 15, 0x1C0, 5),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x010,
+                            0x014, 0x018, 16, 2, 23, 0x1C0, 6),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel",
+                            pextp_tl_ck_parents, 0x010, 0x014, 0x018, 24, 2,
+                            31, 0x1C0, 7),
+       /* CLK_CFG_2 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_250M_SEL, "emmc_250m_sel",
+                            emmc_250m_parents, 0x020, 0x024, 0x028, 0, 1, 7,
+                            0x1C0, 8),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_416M_SEL, "emmc_416m_sel",
+                            emmc_416m_parents, 0x020, 0x024, 0x028, 8, 1, 15,
+                            0x1C0, 9),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_F_26M_ADC_SEL, "f_26m_adc_sel",
+                            f_26m_adc_parents, 0x020, 0x024, 0x028, 16, 1, 23,
+                            0x1C0, 10),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DRAMC_SEL, "dramc_sel", f_26m_adc_parents,
+                            0x020, 0x024, 0x028, 24, 1, 31, 0x1C0, 11),
+       /* CLK_CFG_3 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel",
+                            dramc_md32_parents, 0x030, 0x034, 0x038, 0, 1, 7,
+                            0x1C0, 12),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents,
+                            0x030, 0x034, 0x038, 8, 2, 15, 0x1C0, 13),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents,
+                            0x030, 0x034, 0x038, 16, 2, 23, 0x1C0, 14),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel",
+                            arm_db_main_parents, 0x030, 0x034, 0x038, 24, 1,
+                            31, 0x1C0, 15),
+       /* CLK_CFG_4 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_ARM_DB_JTSEL, "arm_db_jtsel",
+                            arm_db_jtsel_parents, 0x040, 0x044, 0x048, 0, 1, 7,
+                            0x1C0, 16),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents,
+                            0x040, 0x044, 0x048, 8, 1, 15, 0x1C0, 17),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_500M_SEL, "netsys_500m_sel",
+                            netsys_500m_parents, 0x040, 0x044, 0x048, 16, 1,
+                            23, 0x1C0, 18),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel",
+                            netsys_mcu_parents, 0x040, 0x044, 0x048, 24, 3, 31,
+                            0x1C0, 19),
+       /* CLK_CFG_5 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_2X_SEL, "netsys_2x_sel",
+                            netsys_2x_parents, 0x050, 0x054, 0x058, 0, 2, 7,
+                            0x1C0, 20),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_325M_SEL, "sgm_325m_sel",
+                            sgm_325m_parents, 0x050, 0x054, 0x058, 8, 1, 15,
+                            0x1C0, 21),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel",
+                            sgm_reg_parents, 0x050, 0x054, 0x058, 16, 1, 23,
+                            0x1C0, 22),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents,
+                            0x050, 0x054, 0x058, 24, 1, 31, 0x1C0, 23),
+       /* CLK_CFG_6 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CONN_MCUSYS_SEL, "conn_mcusys_sel",
+                            conn_mcusys_parents, 0x060, 0x064, 0x068, 0, 1, 7,
+                            0x1C0, 24),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_EIP_B_SEL, "eip_b_sel", eip_b_parents,
+                            0x060, 0x064, 0x068, 8, 1, 15, 0x1C0, 25),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_PCIE_PHY_SEL, "pcie_phy_sel",
+                            f_26m_adc_parents, 0x060, 0x064, 0x068, 16, 1, 23,
+                            0x1C0, 26),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_USB3_PHY_SEL, "usb3_phy_sel",
+                            f_26m_adc_parents, 0x060, 0x064, 0x068, 24, 1, 31,
+                            0x1C0, 27),
+       /* CLK_CFG_7 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_F26M_SEL, "csw_f26m_sel",
+                            f_26m_adc_parents, 0x070, 0x074, 0x078, 0, 1, 7,
+                            0x1C0, 28),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents,
+                            0x070, 0x074, 0x078, 8, 2, 15, 0x1C0, 29),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_A_TUNER_SEL, "a_tuner_sel",
+                            a_tuner_parents, 0x070, 0x074, 0x078, 16, 2, 23,
+                            0x1C0, 30),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_SEL, "u2u3_sel", f_26m_adc_parents,
+                            0x070, 0x074, 0x078, 24, 1, 31, 0x1C4, 0),
+       /* CLK_CFG_8 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel",
+                            u2u3_sys_parents, 0x080, 0x084, 0x088, 0, 1, 7,
+                            0x1C4, 1),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel",
+                            u2u3_sys_parents, 0x080, 0x084, 0x088, 8, 1, 15,
+                            0x1C4, 2),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_U2_REFSEL, "da_u2_refsel",
+                            da_u2_refsel_parents, 0x080, 0x084, 0x088, 16, 1,
+                            23, 0x1C4, 3),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_U2_CK_1P_SEL, "da_u2_ck_1p_sel",
+                            da_u2_refsel_parents, 0x080, 0x084, 0x088, 24, 1,
+                            31, 0x1C4, 4),
+       /* CLK_CFG_9 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel",
+                            sgm_reg_parents, 0x090, 0x094, 0x098, 0, 1, 7,
+                            0x1C4, 5),
+};
+
+static int clk_mt7986_topckgen_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       int r;
+       void __iomem *base;
+       int nr = ARRAY_SIZE(top_fixed_clks) + ARRAY_SIZE(top_divs) +
+                ARRAY_SIZE(top_muxes);
+
+       base = of_iomap(node, 0);
+       if (!base) {
+               pr_err("%s(): ioremap failed\n", __func__);
+               return -ENOMEM;
+       }
+
+       clk_data = mtk_alloc_clk_data(nr);
+       if (!clk_data)
+               return -ENOMEM;
+
+       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,
+                              &mt7986_clk_lock, clk_data);
+
+       clk_prepare_enable(clk_data->clks[CLK_TOP_SYSAXI_SEL]);
+       clk_prepare_enable(clk_data->clks[CLK_TOP_SYSAPB_SEL]);
+       clk_prepare_enable(clk_data->clks[CLK_TOP_DRAMC_SEL]);
+       clk_prepare_enable(clk_data->clks[CLK_TOP_DRAMC_MD32_SEL]);
+       clk_prepare_enable(clk_data->clks[CLK_TOP_F26M_SEL]);
+       clk_prepare_enable(clk_data->clks[CLK_TOP_SGM_REG_SEL]);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r) {
+               pr_err("%s(): could not register clock provider: %d\n",
+                      __func__, r);
+               goto free_topckgen_data;
+       }
+       return r;
+
+free_topckgen_data:
+       mtk_free_clk_data(clk_data);
+       return r;
+}
+
+static const struct of_device_id of_match_clk_mt7986_topckgen[] = {
+       { .compatible = "mediatek,mt7986-topckgen", },
+       {}
+};
+
+static struct platform_driver clk_mt7986_topckgen_drv = {
+       .probe = clk_mt7986_topckgen_probe,
+       .driver = {
+               .name = "clk-mt7986-topckgen",
+               .of_match_table = of_match_clk_mt7986_topckgen,
+       },
+};
+builtin_platform_driver(clk_mt7986_topckgen_drv);
index d6eed76..608e0e8 100644 (file)
@@ -713,6 +713,35 @@ static struct clk_regmap gxbb_mpll_prediv = {
 };
 
 static struct clk_regmap gxbb_mpll0_div = {
+       .data = &(struct meson_clk_mpll_data){
+               .sdm = {
+                       .reg_off = HHI_MPLL_CNTL7,
+                       .shift   = 0,
+                       .width   = 14,
+               },
+               .sdm_en = {
+                       .reg_off = HHI_MPLL_CNTL,
+                       .shift   = 25,
+                       .width   = 1,
+               },
+               .n2 = {
+                       .reg_off = HHI_MPLL_CNTL7,
+                       .shift   = 16,
+                       .width   = 9,
+               },
+               .lock = &meson_clk_lock,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "mpll0_div",
+               .ops = &meson_clk_mpll_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mpll_prediv.hw
+               },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_regmap gxl_mpll0_div = {
        .data = &(struct meson_clk_mpll_data){
                .sdm = {
                        .reg_off = HHI_MPLL_CNTL7,
@@ -749,7 +778,16 @@ static struct clk_regmap gxbb_mpll0 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0",
                .ops = &clk_regmap_gate_ops,
-               .parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw },
+               .parent_data = &(const struct clk_parent_data) {
+                       /*
+                        * Note:
+                        * GXL and GXBB have different SDM_EN registers. We
+                        * fallback to the global naming string mechanism so
+                        * mpll0_div picks up the appropriate one.
+                        */
+                       .name = "mpll0_div",
+                       .index = -1,
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -3044,7 +3082,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
                [CLKID_VAPB_1]              = &gxbb_vapb_1.hw,
                [CLKID_VAPB_SEL]            = &gxbb_vapb_sel.hw,
                [CLKID_VAPB]                = &gxbb_vapb.hw,
-               [CLKID_MPLL0_DIV]           = &gxbb_mpll0_div.hw,
+               [CLKID_MPLL0_DIV]           = &gxl_mpll0_div.hw,
                [CLKID_MPLL1_DIV]           = &gxbb_mpll1_div.hw,
                [CLKID_MPLL2_DIV]           = &gxbb_mpll2_div.hw,
                [CLKID_MPLL_PREDIV]         = &gxbb_mpll_prediv.hw,
@@ -3439,7 +3477,7 @@ static struct clk_regmap *const gxl_clk_regmaps[] = {
        &gxbb_mpll0,
        &gxbb_mpll1,
        &gxbb_mpll2,
-       &gxbb_mpll0_div,
+       &gxl_mpll0_div,
        &gxbb_mpll1_div,
        &gxbb_mpll2_div,
        &gxbb_cts_amclk_div,
index 74efc82..42c8741 100644 (file)
@@ -265,6 +265,14 @@ config MSM_MMCC_8974
          Say Y if you want to support multimedia devices such as display,
          graphics, video encode/decode, camera, etc.
 
+config MSM_GCC_8976
+       tristate "MSM8956/76 Global Clock Controller"
+       select QCOM_GDSC
+       help
+         Support for the global clock controller on msm8956/76 devices.
+         Say Y if you want to use peripheral devices such as UART, SPI,
+         i2c, USB, SD/eMMC, SATA, PCIe, etc.
+
 config MSM_MMCC_8994
        tristate "MSM8994 Multimedia Clock Controller"
        select MSM_GCC_8994
@@ -564,6 +572,14 @@ config SM_CAMCC_8250
          Support for the camera clock controller on SM8250 devices.
          Say Y if you want to support camera devices and camera functionality.
 
+config SDX_GCC_65
+       tristate "SDX65 Global Clock Controller"
+       select QCOM_GDSC
+       help
+         Support for the global clock controller on SDX65 devices.
+         Say Y if you want to use peripheral devices such as UART,
+         SPI, I2C, USB, SD/UFS, PCIe etc.
+
 config SM_DISPCC_8250
        tristate "SM8150 and SM8250 Display Clock Controller"
        depends on SM_GCC_8150 || SM_GCC_8250
@@ -618,6 +634,14 @@ config SM_GCC_8350
          Say Y if you want to use peripheral devices such as UART,
          SPI, I2C, USB, SD/UFS, PCIe etc.
 
+config SM_GCC_8450
+       tristate "SM8450 Global Clock Controller"
+       select QCOM_GDSC
+       help
+         Support for the global clock controller on SM8450 devices.
+         Say Y if you want to use peripheral devices such as UART,
+         SPI, I2C, USB, SD/UFS, PCIe etc.
+
 config SM_GPUCC_8150
        tristate "SM8150 Graphics Clock Controller"
        select SM_GCC_8150
index 1718c34..0d98ca9 100644 (file)
@@ -36,6 +36,7 @@ obj-$(CONFIG_MSM_GCC_8939) += gcc-msm8939.o
 obj-$(CONFIG_MSM_GCC_8953) += gcc-msm8953.o
 obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
 obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
+obj-$(CONFIG_MSM_GCC_8976) += gcc-msm8976.o
 obj-$(CONFIG_MSM_GCC_8994) += gcc-msm8994.o
 obj-$(CONFIG_MSM_GCC_8996) += gcc-msm8996.o
 obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o
@@ -83,6 +84,7 @@ obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o
 obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
 obj-$(CONFIG_SDX_GCC_55) += gcc-sdx55.o
 obj-$(CONFIG_SM_CAMCC_8250) += camcc-sm8250.o
+obj-$(CONFIG_SDX_GCC_65) += gcc-sdx65.o
 obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o
 obj-$(CONFIG_SM_GCC_6115) += gcc-sm6115.o
 obj-$(CONFIG_SM_GCC_6125) += gcc-sm6125.o
@@ -90,6 +92,7 @@ obj-$(CONFIG_SM_GCC_6350) += gcc-sm6350.o
 obj-$(CONFIG_SM_GCC_8150) += gcc-sm8150.o
 obj-$(CONFIG_SM_GCC_8250) += gcc-sm8250.o
 obj-$(CONFIG_SM_GCC_8350) += gcc-sm8350.o
+obj-$(CONFIG_SM_GCC_8450) += gcc-sm8450.o
 obj-$(CONFIG_SM_GPUCC_8150) += gpucc-sm8150.o
 obj-$(CONFIG_SM_GPUCC_8250) += gpucc-sm8250.o
 obj-$(CONFIG_SM_VIDEOCC_8150) += videocc-sm8150.o
index 8f65b9b..4406cf6 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/kernel.h>
@@ -139,6 +140,20 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
                [PLL_OFF_OPMODE] = 0x28,
                [PLL_OFF_STATUS] = 0x38,
        },
+       [CLK_ALPHA_PLL_TYPE_LUCID_EVO] = {
+               [PLL_OFF_OPMODE] = 0x04,
+               [PLL_OFF_STATUS] = 0x0c,
+               [PLL_OFF_L_VAL] = 0x10,
+               [PLL_OFF_ALPHA_VAL] = 0x14,
+               [PLL_OFF_USER_CTL] = 0x18,
+               [PLL_OFF_USER_CTL_U] = 0x1c,
+               [PLL_OFF_CONFIG_CTL] = 0x20,
+               [PLL_OFF_CONFIG_CTL_U] = 0x24,
+               [PLL_OFF_CONFIG_CTL_U1] = 0x28,
+               [PLL_OFF_TEST_CTL] = 0x2c,
+               [PLL_OFF_TEST_CTL_U] = 0x30,
+               [PLL_OFF_TEST_CTL_U1] = 0x34,
+       },
 };
 EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
 
@@ -175,6 +190,10 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
 #define LUCID_5LPE_PLL_LATCH_INPUT     BIT(14)
 #define LUCID_5LPE_ENABLE_VOTE_RUN     BIT(21)
 
+/* LUCID EVO PLL specific settings and offsets */
+#define LUCID_EVO_ENABLE_VOTE_RUN       BIT(25)
+#define LUCID_EVO_PLL_L_VAL_MASK        GENMASK(15, 0)
+
 /* ZONDA PLL specific */
 #define ZONDA_PLL_OUT_MASK     0xf
 #define ZONDA_STAY_IN_CFA      BIT(16)
@@ -204,7 +223,7 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
        if (ret)
                return ret;
 
-       for (count = 100; count > 0; count--) {
+       for (count = 200; count > 0; count--) {
                ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
                if (ret)
                        return ret;
@@ -1750,24 +1769,32 @@ static int alpha_pll_lucid_5lpe_set_rate(struct clk_hw *hw, unsigned long rate,
                                          LUCID_5LPE_ALPHA_PLL_ACK_LATCH);
 }
 
-static int clk_lucid_5lpe_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
-                                              unsigned long parent_rate)
+static int __clk_lucid_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
+                                           unsigned long parent_rate,
+                                           unsigned long enable_vote_run)
 {
        struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
-       int i, val = 0, div, ret;
+       struct regmap *regmap = pll->clkr.regmap;
+       int i, val, div, ret;
        u32 mask;
 
        /*
         * If the PLL is in FSM mode, then treat set_rate callback as a
         * no-operation.
         */
-       ret = regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val);
+       ret = regmap_read(regmap, PLL_USER_CTL(pll), &val);
        if (ret)
                return ret;
 
-       if (val & LUCID_5LPE_ENABLE_VOTE_RUN)
+       if (val & enable_vote_run)
                return 0;
 
+       if (!pll->post_div_table) {
+               pr_err("Missing the post_div_table for the %s PLL\n",
+                      clk_hw_get_name(&pll->clkr.hw));
+               return -EINVAL;
+       }
+
        div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
        for (i = 0; i < pll->num_post_div; i++) {
                if (pll->post_div_table[i].div == div) {
@@ -1781,6 +1808,12 @@ static int clk_lucid_5lpe_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long
                                  mask, val << pll->post_div_shift);
 }
 
+static int clk_lucid_5lpe_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
+                                              unsigned long parent_rate)
+{
+       return __clk_lucid_pll_postdiv_set_rate(hw, rate, parent_rate, LUCID_5LPE_ENABLE_VOTE_RUN);
+}
+
 const struct clk_ops clk_alpha_pll_lucid_5lpe_ops = {
        .prepare = alpha_pll_lucid_5lpe_prepare,
        .enable = alpha_pll_lucid_5lpe_enable,
@@ -1960,3 +1993,124 @@ const struct clk_ops clk_alpha_pll_zonda_ops = {
        .set_rate = clk_zonda_pll_set_rate,
 };
 EXPORT_SYMBOL(clk_alpha_pll_zonda_ops);
+
+static int alpha_pll_lucid_evo_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_USER_CTL(pll), &val);
+       if (ret)
+               return ret;
+
+       /* If in FSM mode, just vote for it */
+       if (val & LUCID_EVO_ENABLE_VOTE_RUN) {
+               ret = clk_enable_regmap(hw);
+               if (ret)
+                       return ret;
+               return wait_for_pll_enable_lock(pll);
+       }
+
+       /* Check if PLL is already enabled */
+       ret = trion_pll_is_enabled(pll, regmap);
+       if (ret < 0) {
+               return ret;
+       } else if (ret) {
+               pr_warn("%s PLL is already enabled\n", clk_hw_get_name(&pll->clkr.hw));
+               return 0;
+       }
+
+       ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
+       if (ret)
+               return ret;
+
+       /* Set operation mode to RUN */
+       regmap_write(regmap, PLL_OPMODE(pll), 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), PLL_OUT_MASK, PLL_OUT_MASK);
+       if (ret)
+               return ret;
+
+       /* Enable the global PLL outputs */
+       ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL);
+       if (ret)
+               return ret;
+
+       /* Ensure that the write above goes through before returning. */
+       mb();
+       return ret;
+}
+
+static void alpha_pll_lucid_evo_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_USER_CTL(pll), &val);
+       if (ret)
+               return;
+
+       /* If in FSM mode, just unvote it */
+       if (val & LUCID_EVO_ENABLE_VOTE_RUN) {
+               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), PLL_OUT_MASK, 0);
+       if (ret)
+               return;
+
+       /* Place the PLL mode in STANDBY */
+       regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);
+}
+
+static unsigned long alpha_pll_lucid_evo_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;
+
+       regmap_read(regmap, PLL_L_VAL(pll), &l);
+       l &= LUCID_EVO_PLL_L_VAL_MASK;
+       regmap_read(regmap, PLL_ALPHA_VAL(pll), &frac);
+
+       return alpha_pll_calc_rate(parent_rate, l, frac, pll_alpha_width(pll));
+}
+
+static int clk_lucid_evo_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
+                                             unsigned long parent_rate)
+{
+       return __clk_lucid_pll_postdiv_set_rate(hw, rate, parent_rate, LUCID_EVO_ENABLE_VOTE_RUN);
+}
+
+const struct clk_ops clk_alpha_pll_fixed_lucid_evo_ops = {
+       .enable = alpha_pll_lucid_evo_enable,
+       .disable = alpha_pll_lucid_evo_disable,
+       .is_enabled = clk_trion_pll_is_enabled,
+       .recalc_rate = alpha_pll_lucid_evo_recalc_rate,
+       .round_rate = clk_alpha_pll_round_rate,
+};
+EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_lucid_evo_ops);
+
+const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops = {
+       .recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate,
+       .round_rate = clk_alpha_pll_postdiv_fabia_round_rate,
+       .set_rate = clk_lucid_evo_pll_postdiv_set_rate,
+};
+EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_evo_ops);
index 55e4fa4..6e9907d 100644 (file)
@@ -17,6 +17,7 @@ enum {
        CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION,
        CLK_ALPHA_PLL_TYPE_AGERA,
        CLK_ALPHA_PLL_TYPE_ZONDA,
+       CLK_ALPHA_PLL_TYPE_LUCID_EVO,
        CLK_ALPHA_PLL_TYPE_MAX,
 };
 
@@ -151,6 +152,8 @@ extern const struct clk_ops clk_alpha_pll_postdiv_lucid_5lpe_ops;
 
 extern const struct clk_ops clk_alpha_pll_zonda_ops;
 #define clk_alpha_pll_postdiv_zonda_ops clk_alpha_pll_postdiv_fabia_ops
+extern const struct clk_ops clk_alpha_pll_fixed_lucid_evo_ops;
+extern const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops;
 
 void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
                             const struct alpha_pll_config *config);
index 441d7a2..74e57c8 100644 (file)
@@ -515,6 +515,32 @@ static const struct clk_rpmh_desc clk_rpmh_sm8350 = {
 /* Resource name must match resource id present in cmd-db */
 DEFINE_CLK_RPMH_ARC(sc7280, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 4);
 
+DEFINE_CLK_RPMH_VRM(sm8450, ln_bb_clk1, ln_bb_clk1_ao, "lnbclka1", 4);
+DEFINE_CLK_RPMH_VRM(sm8450, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 4);
+
+static struct clk_hw *sm8450_rpmh_clocks[] = {
+       [RPMH_CXO_CLK]          = &sc7280_bi_tcxo.hw,
+       [RPMH_CXO_CLK_A]        = &sc7280_bi_tcxo_ao.hw,
+       [RPMH_LN_BB_CLK1]       = &sm8450_ln_bb_clk1.hw,
+       [RPMH_LN_BB_CLK1_A]     = &sm8450_ln_bb_clk1_ao.hw,
+       [RPMH_LN_BB_CLK2]       = &sm8450_ln_bb_clk2.hw,
+       [RPMH_LN_BB_CLK2_A]     = &sm8450_ln_bb_clk2_ao.hw,
+       [RPMH_RF_CLK1]          = &sdm845_rf_clk1.hw,
+       [RPMH_RF_CLK1_A]        = &sdm845_rf_clk1_ao.hw,
+       [RPMH_RF_CLK2]          = &sdm845_rf_clk2.hw,
+       [RPMH_RF_CLK2_A]        = &sdm845_rf_clk2_ao.hw,
+       [RPMH_RF_CLK3]          = &sdm845_rf_clk3.hw,
+       [RPMH_RF_CLK3_A]        = &sdm845_rf_clk3_ao.hw,
+       [RPMH_RF_CLK4]          = &sm8350_rf_clk4.hw,
+       [RPMH_RF_CLK4_A]        = &sm8350_rf_clk4_ao.hw,
+       [RPMH_IPA_CLK]          = &sdm845_ipa.hw,
+};
+
+static const struct clk_rpmh_desc clk_rpmh_sm8450 = {
+       .clks = sm8450_rpmh_clocks,
+       .num_clks = ARRAY_SIZE(sm8450_rpmh_clocks),
+};
+
 static struct clk_hw *sc7280_rpmh_clocks[] = {
        [RPMH_CXO_CLK]      = &sc7280_bi_tcxo.hw,
        [RPMH_CXO_CLK_A]    = &sc7280_bi_tcxo_ao.hw,
@@ -556,6 +582,30 @@ static const struct clk_rpmh_desc clk_rpmh_sm6350 = {
        .num_clks = ARRAY_SIZE(sm6350_rpmh_clocks),
 };
 
+DEFINE_CLK_RPMH_VRM(sdx65, ln_bb_clk1, ln_bb_clk1_ao, "lnbclka1", 4);
+
+static struct clk_hw *sdx65_rpmh_clocks[] = {
+       [RPMH_CXO_CLK]          = &sc7280_bi_tcxo.hw,
+       [RPMH_CXO_CLK_A]        = &sc7280_bi_tcxo_ao.hw,
+       [RPMH_LN_BB_CLK1]       = &sdx65_ln_bb_clk1.hw,
+       [RPMH_LN_BB_CLK1_A]     = &sdx65_ln_bb_clk1_ao.hw,
+       [RPMH_RF_CLK1]          = &sdm845_rf_clk1.hw,
+       [RPMH_RF_CLK1_A]        = &sdm845_rf_clk1_ao.hw,
+       [RPMH_RF_CLK2]          = &sdm845_rf_clk2.hw,
+       [RPMH_RF_CLK2_A]        = &sdm845_rf_clk2_ao.hw,
+       [RPMH_RF_CLK3]          = &sdm845_rf_clk3.hw,
+       [RPMH_RF_CLK3_A]        = &sdm845_rf_clk3_ao.hw,
+       [RPMH_RF_CLK4]          = &sm8350_rf_clk4.hw,
+       [RPMH_RF_CLK4_A]        = &sm8350_rf_clk4_ao.hw,
+       [RPMH_IPA_CLK]          = &sdm845_ipa.hw,
+       [RPMH_QPIC_CLK]         = &sdx55_qpic_clk.hw,
+};
+
+static const struct clk_rpmh_desc clk_rpmh_sdx65 = {
+       .clks = sdx65_rpmh_clocks,
+       .num_clks = ARRAY_SIZE(sdx65_rpmh_clocks),
+};
+
 static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec,
                                         void *data)
 {
@@ -643,10 +693,12 @@ static const struct of_device_id clk_rpmh_match_table[] = {
        { .compatible = "qcom,sc8180x-rpmh-clk", .data = &clk_rpmh_sc8180x},
        { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845},
        { .compatible = "qcom,sdx55-rpmh-clk",  .data = &clk_rpmh_sdx55},
+       { .compatible = "qcom,sdx65-rpmh-clk",  .data = &clk_rpmh_sdx65},
        { .compatible = "qcom,sm6350-rpmh-clk", .data = &clk_rpmh_sm6350},
        { .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150},
        { .compatible = "qcom,sm8250-rpmh-clk", .data = &clk_rpmh_sm8250},
        { .compatible = "qcom,sm8350-rpmh-clk", .data = &clk_rpmh_sm8350},
+       { .compatible = "qcom,sm8450-rpmh-clk", .data = &clk_rpmh_sm8450},
        { .compatible = "qcom,sc7280-rpmh-clk", .data = &clk_rpmh_sc7280},
        { }
 };
index 5776d85..ea28e45 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/soc/qcom/smd-rpm.h>
 
 #include <dt-bindings/clock/qcom,rpmcc.h>
-#include <dt-bindings/mfd/qcom-rpm.h>
 
 #define QCOM_RPM_KEY_SOFTWARE_ENABLE                   0x6e657773
 #define QCOM_RPM_KEY_PIN_CTRL_CLK_BUFFER_ENABLE_KEY    0x62636370
@@ -151,12 +150,6 @@ struct clk_smd_rpm_req {
        __le32 value;
 };
 
-struct rpm_cc {
-       struct qcom_rpm *rpm;
-       struct clk_smd_rpm **clks;
-       size_t num_clks;
-};
-
 struct rpm_smd_clk_desc {
        struct clk_smd_rpm **clks;
        size_t num_clks;
@@ -196,10 +189,6 @@ static int clk_smd_rpm_set_rate_active(struct clk_smd_rpm *r,
                .value = cpu_to_le32(DIV_ROUND_UP(rate, 1000)), /* to kHz */
        };
 
-       /* Buffered clock needs a binary value */
-       if (r->rpm_res_type == QCOM_SMD_RPM_CLK_BUF_A)
-               req.value = cpu_to_le32(!!req.value);
-
        return qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_ACTIVE_STATE,
                                  r->rpm_res_type, r->rpm_clk_id, &req,
                                  sizeof(req));
@@ -214,10 +203,6 @@ static int clk_smd_rpm_set_rate_sleep(struct clk_smd_rpm *r,
                .value = cpu_to_le32(DIV_ROUND_UP(rate, 1000)), /* to kHz */
        };
 
-       /* Buffered clock needs a binary value */
-       if (r->rpm_res_type == QCOM_SMD_RPM_CLK_BUF_A)
-               req.value = cpu_to_le32(!!req.value);
-
        return qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_SLEEP_STATE,
                                  r->rpm_res_type, r->rpm_clk_id, &req,
                                  sizeof(req));
@@ -1159,20 +1144,19 @@ MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table);
 static struct clk_hw *qcom_smdrpm_clk_hw_get(struct of_phandle_args *clkspec,
                                             void *data)
 {
-       struct rpm_cc *rcc = data;
+       const struct rpm_smd_clk_desc *desc = data;
        unsigned int idx = clkspec->args[0];
 
-       if (idx >= rcc->num_clks) {
+       if (idx >= desc->num_clks) {
                pr_err("%s: invalid index %u\n", __func__, idx);
                return ERR_PTR(-EINVAL);
        }
 
-       return rcc->clks[idx] ? &rcc->clks[idx]->hw : ERR_PTR(-ENOENT);
+       return desc->clks[idx] ? &desc->clks[idx]->hw : ERR_PTR(-ENOENT);
 }
 
 static int rpm_smd_clk_probe(struct platform_device *pdev)
 {
-       struct rpm_cc *rcc;
        int ret;
        size_t num_clks, i;
        struct qcom_smd_rpm *rpm;
@@ -1192,13 +1176,6 @@ static int rpm_smd_clk_probe(struct platform_device *pdev)
        rpm_smd_clks = desc->clks;
        num_clks = desc->num_clks;
 
-       rcc = devm_kzalloc(&pdev->dev, sizeof(*rcc), GFP_KERNEL);
-       if (!rcc)
-               return -ENOMEM;
-
-       rcc->clks = rpm_smd_clks;
-       rcc->num_clks = num_clks;
-
        for (i = 0; i < num_clks; i++) {
                if (!rpm_smd_clks[i])
                        continue;
@@ -1224,7 +1201,7 @@ static int rpm_smd_clk_probe(struct platform_device *pdev)
        }
 
        ret = devm_of_clk_add_hw_provider(&pdev->dev, qcom_smdrpm_clk_hw_get,
-                                    rcc);
+                                         (void *)desc);
        if (ret)
                goto err;
 
diff --git a/drivers/clk/qcom/gcc-msm8976.c b/drivers/clk/qcom/gcc-msm8976.c
new file mode 100644 (file)
index 0000000..a8b1581
--- /dev/null
@@ -0,0 +1,4155 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Qualcomm Global Clock Controller driver for MSM8956/76
+ *
+ * Copyright (c) 2016-2021, AngeloGioacchino Del Regno
+ *                     <angelogioacchino.delregno@somainline.org>
+ *
+ * Driver cleanup and modernization
+ * Copyright (c) 2021, Konrad Dybcio <konrad.dybcio@somainline.org>
+ *                     Marijn Suijten <marijn.suijten@somainline.org>
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,gcc-msm8976.h>
+
+#include "clk-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+       P_GPLL0_OUT_MAIN,
+       P_GPLL0_AUX,
+       P_GPLL0_OUT,
+       P_GPLL0_OUT_M,
+       P_GPLL0_OUT_MDP,
+       P_GPLL2_AUX,
+       P_GPLL2_OUT,
+       P_GPLL4_OUT_MAIN,
+       P_GPLL4_AUX,
+       P_GPLL4_OUT,
+       P_GPLL4_GFX3D,
+       P_GPLL6_OUT_MAIN,
+       P_GPLL6_AUX,
+       P_GPLL6_OUT,
+       P_GPLL6_GFX3D,
+       P_DSI0PLL,
+       P_DSI1PLL,
+       P_DSI0PLL_BYTE,
+       P_DSI1PLL_BYTE,
+       P_XO_A,
+       P_XO,
+};
+
+static struct clk_pll gpll0 = {
+       .l_reg = 0x21004,
+       .m_reg = 0x21008,
+       .n_reg = 0x2100c,
+       .config_reg = 0x21014,
+       .mode_reg = 0x21000,
+       .status_reg = 0x2101c,
+       .status_bit = 17,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll0",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "xo",
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_ops,
+       },
+};
+
+static struct clk_regmap gpll0_vote = {
+       .enable_reg = 0x45000,
+       .enable_mask = BIT(0),
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll0_vote",
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gpll0.clkr.hw,
+               },
+               .num_parents = 1,
+               /* This clock is required for other ones to function. */
+               .flags = CLK_IS_CRITICAL,
+               .ops = &clk_pll_vote_ops,
+       },
+};
+
+static struct clk_pll gpll2 = {
+       .l_reg = 0x4a004,
+       .m_reg = 0x4a008,
+       .n_reg = 0x4a00c,
+       .config_reg = 0x4a014,
+       .mode_reg = 0x4a000,
+       .status_reg = 0x4a01c,
+       .status_bit = 17,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll2",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "xo",
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_ops,
+       },
+};
+
+static struct clk_regmap gpll2_vote = {
+       .enable_reg = 0x45000,
+       .enable_mask = BIT(2),
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll2_vote",
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gpll2.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_vote_ops,
+       },
+};
+
+static const struct pll_freq_tbl gpll3_freq_tbl[] = {
+       { 1100000000, 57, 7, 24, 0 },
+       { }
+};
+
+static struct clk_pll gpll3 = {
+       .l_reg = 0x22004,
+       .m_reg = 0x22008,
+       .n_reg = 0x2200c,
+       .config_reg = 0x22010,
+       .mode_reg = 0x22000,
+       .status_reg = 0x22024,
+       .status_bit = 17,
+       .freq_tbl = gpll3_freq_tbl,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gpll3",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "xo",
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_ops,
+       },
+};
+
+static struct clk_regmap gpll3_vote = {
+       .enable_reg = 0x45000,
+       .enable_mask = BIT(4),
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll3_vote",
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gpll3.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_vote_ops,
+       },
+};
+
+/* GPLL3 at 1100MHz, main output enabled. */
+static const struct pll_config gpll3_config = {
+       .l = 57,
+       .m = 7,
+       .n = 24,
+       .vco_val = 0x0,
+       .vco_mask = 0x3 << 20,
+       .pre_div_val = 0x0,
+       .pre_div_mask = 0x7 << 12,
+       .post_div_val = 0x0,
+       .post_div_mask = 0x3 << 8,
+       .mn_ena_mask = BIT(24),
+       .main_output_mask = BIT(0),
+       .aux_output_mask = BIT(1),
+};
+
+static struct clk_pll gpll4 = {
+       .l_reg = 0x24004,
+       .m_reg = 0x24008,
+       .n_reg = 0x2400c,
+       .config_reg = 0x24018,
+       .mode_reg = 0x24000,
+       .status_reg = 0x24024,
+       .status_bit = 17,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll4",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "xo",
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_ops,
+       },
+};
+
+static struct clk_regmap gpll4_vote = {
+       .enable_reg = 0x45000,
+       .enable_mask = BIT(5),
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll4_vote",
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gpll4.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_vote_ops,
+       },
+};
+
+static struct clk_pll gpll6 = {
+       .mode_reg = 0x37000,
+       .l_reg = 0x37004,
+       .m_reg = 0x37008,
+       .n_reg = 0x3700c,
+       .config_reg = 0x37014,
+       .status_reg = 0x3701c,
+       .status_bit = 17,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll6",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "xo",
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_ops,
+       },
+};
+
+static struct clk_regmap gpll6_vote = {
+       .enable_reg = 0x45000,
+       .enable_mask = BIT(7),
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll6_vote",
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gpll6.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_pll_vote_ops,
+       },
+};
+
+static const struct parent_map gcc_parent_map_1[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL4_OUT, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_1[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0_vote.hw },
+       { .hw = &gpll4_vote.hw },
+};
+
+static const struct parent_map gcc_parent_map_v1_1[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL2_OUT, 4 },
+};
+
+static const struct clk_parent_data gcc_parent_data_v1_1[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0_vote.hw },
+       { .hw = &gpll2_vote.hw },
+};
+
+static const struct parent_map gcc_parent_map_2[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL2_AUX, 3 },
+       { P_GPLL4_OUT, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_2[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0_vote.hw },
+       { .hw = &gpll2_vote.hw },
+       { .hw = &gpll4_vote.hw },
+};
+
+static const struct parent_map gcc_parent_map_3[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL2_AUX, 3 },
+       { P_GPLL6_AUX, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_3[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0_vote.hw },
+       { .hw = &gpll2_vote.hw },
+       { .hw = &gpll6_vote.hw },
+};
+
+static const struct parent_map gcc_parent_map_4[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+};
+
+static const struct parent_map gcc_parent_map_4_fs[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT, 2 },
+};
+
+static const struct parent_map gcc_parent_map_5[] = {
+       { P_XO, 0 },
+       { P_GPLL4_OUT, 2 },
+       { P_GPLL6_OUT_MAIN, 1 },
+};
+
+static const struct clk_parent_data gcc_parent_data_5[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll4_vote.hw },
+       { .hw = &gpll6_vote.hw },
+};
+
+static const struct parent_map gcc_parent_map_6[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL4_OUT_MAIN, 5 },
+};
+
+static const struct clk_parent_data gcc_parent_data_6[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0_vote.hw },
+       { .hw = &gpll4_vote.hw },
+};
+
+static const struct parent_map gcc_parent_map_7_mdp[] = {
+       { P_XO, 0 },
+       { P_GPLL6_OUT, 3 },
+       { P_GPLL0_OUT_MDP, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_7_mdp[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll6_vote.hw },
+       { .hw = &gpll0_vote.hw },
+};
+
+static const struct parent_map gcc_parent_map_7[] = {
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL6_OUT, 3 },
+};
+
+static const struct clk_parent_data gcc_parent_data_7[] = {
+       { .hw = &gpll0_vote.hw },
+       { .hw = &gpll6_vote.hw },
+};
+
+static const struct parent_map gcc_parent_map_8[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+};
+
+static const struct clk_parent_data gcc_parent_data_4_8[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0_vote.hw },
+};
+
+static const struct parent_map gcc_parent_map_8_a[] = {
+       { P_XO_A, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+};
+
+static const struct clk_parent_data gcc_parent_data_8_a[] = {
+       { .fw_name = "xo_a" },
+       { .hw = &gpll0_vote.hw },
+};
+
+static const struct parent_map gcc_parent_map_8_gp[] = {
+       { P_GPLL0_OUT_MAIN, 1 },
+};
+
+static const struct clk_parent_data gcc_parent_data_8_gp[] = {
+       { .hw = &gpll0_vote.hw },
+};
+
+static const struct parent_map gcc_parent_map_9[] = {
+       { P_XO, 0 },
+       { P_GPLL6_OUT_MAIN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_9[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll6_vote.hw },
+};
+
+static const struct parent_map gcc_parent_map_10[] = {
+       { P_XO, 0 },
+};
+
+static const struct clk_parent_data gcc_parent_data_10[] = {
+       { .fw_name = "xo" },
+};
+
+static const struct parent_map gcc_parent_map_sdcc_ice[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_M, 3 },
+};
+
+static const struct parent_map gcc_parent_map_cci[] = {
+       { P_XO, 0 },
+       { P_GPLL0_AUX, 2 },
+};
+
+static const struct parent_map gcc_parent_map_cpp[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL4_AUX, 3 },
+};
+
+static const struct parent_map gcc_parent_map_mdss_pix0[] = {
+       { P_XO, 0 },
+       { P_DSI0PLL, 1 },
+};
+
+static const struct clk_parent_data gcc_parent_data_mdss_pix0[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "dsi0pll" },
+};
+
+static const struct parent_map gcc_parent_map_mdss_pix1[] = {
+       { P_XO, 0 },
+       { P_DSI0PLL, 3 },
+       { P_DSI1PLL, 1 },
+};
+
+static const struct clk_parent_data gcc_parent_data_mdss_pix1[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "dsi0pll" },
+       { .fw_name = "dsi1pll" },
+};
+
+static const struct parent_map gcc_parent_map_mdss_byte0[] = {
+       { P_XO, 0 },
+       { P_DSI0PLL_BYTE, 1 },
+};
+
+static const struct clk_parent_data gcc_parent_data_mdss_byte0[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "dsi0pllbyte" },
+};
+
+static const struct parent_map gcc_parent_map_mdss_byte1[] = {
+       { P_XO, 0 },
+       { P_DSI0PLL_BYTE, 3 },
+       { P_DSI1PLL_BYTE, 1 },
+};
+
+static const struct clk_parent_data gcc_parent_data_mdss_byte1[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "dsi0pllbyte" },
+       { .fw_name = "dsi1pllbyte" },
+};
+
+static const struct parent_map gcc_parent_map_gfx3d[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL4_GFX3D, 5 },
+       { P_GPLL6_GFX3D, 3 },
+};
+
+static const struct clk_parent_data gcc_parent_data_gfx3d[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0_vote.hw },
+       { .hw = &gpll4_vote.hw },
+       { .hw = &gpll6_vote.hw },
+};
+
+static const struct freq_tbl ftbl_aps_0_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(300000000, P_GPLL4_OUT, 4, 0, 0),
+       F(540000000, P_GPLL6_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 aps_0_clk_src = {
+       .cmd_rcgr = 0x78008,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_5,
+       .freq_tbl = ftbl_aps_0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "aps_0_clk_src",
+               .parent_data = gcc_parent_data_5,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_5),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_aps_1_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(300000000, P_GPLL4_OUT, 4, 0, 0),
+       F(540000000, P_GPLL6_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 aps_1_clk_src = {
+       .cmd_rcgr = 0x79008,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_5,
+       .freq_tbl = ftbl_aps_1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "aps_1_clk_src",
+               .parent_data = gcc_parent_data_5,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_5),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_apss_ahb_clk_src[] = {
+       F(19200000, P_XO_A, 1, 0, 0),
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       F(88890000, P_GPLL0_OUT_MAIN, 9, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 apss_ahb_clk_src = {
+       .cmd_rcgr = 0x46000,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8_a,
+       .freq_tbl = ftbl_apss_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "apss_ahb_clk_src",
+               .parent_data = gcc_parent_data_8_a,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_8_a),
+               .ops = &clk_rcg2_ops,
+               /*
+                * This clock allows the CPUs to communicate with
+                * the rest of the SoC. Without it, the brain will
+                * operate without the rest of the body.
+                */
+               .flags = CLK_IS_CRITICAL,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp_i2c_apps_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x200c,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup1_i2c_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp_spi_apps_clk_src[] = {
+       F(960000, P_XO, 10, 1, 2),
+       F(4800000, P_XO, 4, 0, 0),
+       F(9600000, P_XO, 2, 0, 0),
+       F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5),
+       F(19200000, P_XO, 1, 0, 0),
+       F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2),
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
+       .cmd_rcgr = 0x2024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup1_spi_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x3000,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup2_i2c_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
+       .cmd_rcgr = 0x3014,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup2_spi_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x4000,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup3_i2c_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = {
+       .cmd_rcgr = 0x4024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup3_spi_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x5000,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup4_i2c_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = {
+       .cmd_rcgr = 0x5024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup4_spi_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp_uart_apps_clk_src[] = {
+       F(3686400, P_GPLL0_OUT_MAIN, 1, 72, 15625),
+       F(7372800, P_GPLL0_OUT_MAIN, 1, 144, 15625),
+       F(14745600, P_GPLL0_OUT_MAIN, 1, 288, 15625),
+       F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5),
+       F(19200000, P_XO, 1, 0, 0),
+       F(24000000, P_GPLL0_OUT_MAIN, 1, 3, 100),
+       F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2),
+       F(32000000, P_GPLL0_OUT_MAIN, 1, 1, 25),
+       F(40000000, P_GPLL0_OUT_MAIN, 1, 1, 20),
+       F(46400000, P_GPLL0_OUT_MAIN, 1, 29, 500),
+       F(48000000, P_GPLL0_OUT_MAIN, 1, 3, 50),
+       F(51200000, P_GPLL0_OUT_MAIN, 1, 8, 125),
+       F(56000000, P_GPLL0_OUT_MAIN, 1, 7, 100),
+       F(58982400, P_GPLL0_OUT_MAIN, 1, 1152, 15625),
+       F(60000000, P_GPLL0_OUT_MAIN, 1, 3, 40),
+       F(64000000, P_GPLL0_OUT_MAIN, 1, 2, 25),
+       { }
+};
+
+static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
+       .cmd_rcgr = 0x2044,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart1_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
+       .cmd_rcgr = 0x3034,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart2_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = {
+       .cmd_rcgr = 0xc00c,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup1_i2c_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = {
+       .cmd_rcgr = 0xc024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup1_spi_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = {
+       .cmd_rcgr = 0xd000,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup2_i2c_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = {
+       .cmd_rcgr = 0xd014,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup2_spi_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = {
+       .cmd_rcgr = 0xf000,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup3_i2c_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = {
+       .cmd_rcgr = 0xf024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup3_spi_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x18000,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup4_i2c_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = {
+       .cmd_rcgr = 0x18024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup4_spi_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_uart1_apps_clk_src = {
+       .cmd_rcgr = 0xc044,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart1_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_uart2_apps_clk_src = {
+       .cmd_rcgr = 0xd034,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart2_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cci_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(37500000, P_GPLL0_AUX, 1, 3, 64),
+       { }
+};
+
+static struct clk_rcg2 cci_clk_src = {
+       .cmd_rcgr = 0x51000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_cci,
+       .freq_tbl = ftbl_cci_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cci_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cpp_clk_src[] = {
+       F(160000000, P_GPLL0_OUT_MAIN, 5, 0, 0),
+       F(240000000, P_GPLL4_AUX, 5, 0, 0),
+       F(320000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+       F(400000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+       F(480000000, P_GPLL4_AUX, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cpp_clk_src = {
+       .cmd_rcgr = 0x58018,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_cpp,
+       .freq_tbl = ftbl_cpp_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cpp_clk_src",
+               .parent_data = gcc_parent_data_6,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_6),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_csi0_clk_src[] = {
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(266670000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 csi0_clk_src = {
+       .cmd_rcgr = 0x4e020,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_csi0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi0_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_csi1_clk_src[] = {
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(266670000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 csi1_clk_src = {
+       .cmd_rcgr = 0x4f020,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_csi1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi1_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_csi2_clk_src[] = {
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(266670000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 csi2_clk_src = {
+       .cmd_rcgr = 0x3c020,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_csi2_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi2_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_camss_gp0_clk_src[] = {
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(266670000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 camss_gp0_clk_src = {
+       .cmd_rcgr = 0x54000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8_gp,
+       .freq_tbl = ftbl_camss_gp0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "camss_gp0_clk_src",
+               .parent_data = gcc_parent_data_8_gp,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_8_gp),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_camss_gp1_clk_src[] = {
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(266670000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 camss_gp1_clk_src = {
+       .cmd_rcgr = 0x55000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8_gp,
+       .freq_tbl = ftbl_camss_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "camss_gp1_clk_src",
+               .parent_data = gcc_parent_data_8_gp,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_8_gp),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_jpeg0_clk_src[] = {
+       F(133330000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       F(320000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 jpeg0_clk_src = {
+       .cmd_rcgr = 0x57000,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_6,
+       .freq_tbl = ftbl_jpeg0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "jpeg0_clk_src",
+               .parent_data = gcc_parent_data_6,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_6),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_mclk_clk_src[] = {
+       F(8000000, P_GPLL0_OUT_MAIN, 1, 1, 100),
+       F(24000000, P_GPLL6_OUT, 1, 1, 45),
+       F(66670000, P_GPLL0_OUT_MAIN, 12, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 mclk0_clk_src = {
+       .cmd_rcgr = 0x52000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_7,
+       .freq_tbl = ftbl_mclk_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mclk0_clk_src",
+               .parent_data = gcc_parent_data_7,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_7),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 mclk1_clk_src = {
+       .cmd_rcgr = 0x53000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_7,
+       .freq_tbl = ftbl_mclk_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mclk1_clk_src",
+               .parent_data = gcc_parent_data_7,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_7),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 mclk2_clk_src = {
+       .cmd_rcgr = 0x5c000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_7,
+       .freq_tbl = ftbl_mclk_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mclk2_clk_src",
+               .parent_data = gcc_parent_data_7,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_7),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_csi0phytimer_clk_src[] = {
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(266670000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 csi0phytimer_clk_src = {
+       .cmd_rcgr = 0x4e000,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_csi0phytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi0phytimer_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_csi1phytimer_clk_src[] = {
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(266670000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 csi1phytimer_clk_src = {
+       .cmd_rcgr = 0x4f000,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_csi1phytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi1phytimer_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_camss_top_ahb_clk_src[] = {
+       F(40000000, P_GPLL0_OUT_MAIN, 10, 1, 2),
+       F(80000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 camss_top_ahb_clk_src = {
+       .cmd_rcgr = 0x5a000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_camss_top_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "camss_top_ahb_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_vfe0_clk_src[] = {
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       F(80000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(133333333, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       F(160000000, P_GPLL0_OUT_MAIN, 5, 0, 0),
+       F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       F(300000000, P_GPLL4_OUT, 4, 0, 0),
+       F(320000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+       F(466000000, P_GPLL2_AUX, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 vfe0_clk_src = {
+       .cmd_rcgr = 0x58000,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_vfe0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "vfe0_clk_src",
+               .parent_data = gcc_parent_data_2,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_2),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_vfe1_clk_src[] = {
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       F(80000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(133333333, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       F(160000000, P_GPLL0_OUT_MAIN, 5, 0, 0),
+       F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       F(300000000, P_GPLL4_OUT, 4, 0, 0),
+       F(320000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+       F(466000000, P_GPLL2_AUX, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 vfe1_clk_src = {
+       .cmd_rcgr = 0x58054,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_vfe1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "vfe1_clk_src",
+               .parent_data = gcc_parent_data_2,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_2),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_crypto_clk_src[] = {
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       F(80000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(160000000, P_GPLL0_OUT_MAIN, 5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 crypto_clk_src = {
+       .cmd_rcgr = 0x16004,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_crypto_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "crypto_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gp1_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gp1_clk_src = {
+       .cmd_rcgr = 0x8004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8_gp,
+       .freq_tbl = ftbl_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp1_clk_src",
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gpll0_vote.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gp2_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gp2_clk_src = {
+       .cmd_rcgr = 0x9004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8_gp,
+       .freq_tbl = ftbl_gp2_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp2_clk_src",
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gpll0_vote.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gp3_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gp3_clk_src = {
+       .cmd_rcgr = 0xa004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8_gp,
+       .freq_tbl = ftbl_gp3_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp3_clk_src",
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gpll0_vote.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 byte0_clk_src = {
+       .cmd_rcgr = 0x4d044,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_mdss_byte0,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "byte0_clk_src",
+               .parent_data = gcc_parent_data_mdss_byte0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_mdss_byte0),
+               .ops = &clk_byte2_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_rcg2 byte1_clk_src = {
+       .cmd_rcgr = 0x4d0b0,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_mdss_byte1,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "byte1_clk_src",
+               .parent_data = gcc_parent_data_mdss_byte1,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_mdss_byte1),
+               .ops = &clk_byte2_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static const struct freq_tbl ftbl_esc0_1_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 esc0_clk_src = {
+       .cmd_rcgr = 0x4d05c,
+       .hid_width = 5,
+       .freq_tbl = ftbl_esc0_1_clk_src,
+       .parent_map = gcc_parent_map_mdss_byte0,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "esc0_clk_src",
+               .parent_data = gcc_parent_data_mdss_byte0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_mdss_byte0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 esc1_clk_src = {
+       .cmd_rcgr = 0x4d0a8,
+       .hid_width = 5,
+       .freq_tbl = ftbl_esc0_1_clk_src,
+       .parent_map = gcc_parent_map_mdss_byte1,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "esc1_clk_src",
+               .parent_data = gcc_parent_data_mdss_byte1,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_mdss_byte1),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_mdp_clk_src[] = {
+       F(50000000, P_GPLL0_OUT_MDP, 16, 0, 0),
+       F(80000000, P_GPLL0_OUT_MDP, 10, 0, 0),
+       F(100000000, P_GPLL0_OUT_MDP, 8, 0, 0),
+       F(145454545, P_GPLL0_OUT_MDP, 5.5, 0, 0),
+       F(160000000, P_GPLL0_OUT_MDP, 5, 0, 0),
+       F(177777778, P_GPLL0_OUT_MDP, 4.5, 0, 0),
+       F(200000000, P_GPLL0_OUT_MDP, 4, 0, 0),
+       F(270000000, P_GPLL6_OUT, 4, 0, 0),
+       F(320000000, P_GPLL0_OUT_MDP, 2.5, 0, 0),
+       F(360000000, P_GPLL6_OUT, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 mdp_clk_src = {
+       .cmd_rcgr = 0x4d014,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_7_mdp,
+       .freq_tbl = ftbl_mdp_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mdp_clk_src",
+               .parent_data = gcc_parent_data_7_mdp,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_7_mdp),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 pclk0_clk_src = {
+       .cmd_rcgr = 0x4d000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_mdss_pix0,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pclk0_clk_src",
+               .parent_data = gcc_parent_data_mdss_pix0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_mdss_pix0),
+               .ops = &clk_pixel_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_rcg2 pclk1_clk_src = {
+       .cmd_rcgr = 0x4d0b8,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_mdss_pix1,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pclk1_clk_src",
+               .parent_data = gcc_parent_data_mdss_pix1,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_mdss_pix1),
+               .ops = &clk_pixel_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static const struct freq_tbl ftbl_vsync_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 vsync_clk_src = {
+       .cmd_rcgr = 0x4d02c,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_10,
+       .freq_tbl = ftbl_vsync_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "vsync_clk_src",
+               .parent_data = gcc_parent_data_10,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_10),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gfx3d_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       F(80000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(133333333, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       F(160000000, P_GPLL0_OUT_MAIN, 5, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(228571429, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
+       F(240000000, P_GPLL6_GFX3D, 4.5, 0, 0),
+       F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       F(300000000, P_GPLL4_GFX3D, 4, 0, 0),
+       F(360000000, P_GPLL6_GFX3D, 3, 0, 0),
+       F(400000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+       F(432000000, P_GPLL6_GFX3D, 2.5, 0, 0),
+       F(480000000, P_GPLL4_GFX3D, 2.5, 0, 0),
+       F(540000000, P_GPLL6_GFX3D, 2, 0, 0),
+       F(600000000, P_GPLL4_GFX3D, 2, 0, 0),
+       { }
+};
+
+static const struct clk_init_data gfx3d_clk_params = {
+       .name = "gfx3d_clk_src",
+       .parent_data = gcc_parent_data_gfx3d,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_gfx3d),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gfx3d_clk_src = {
+       .cmd_rcgr = 0x59000,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_gfx3d,
+       .freq_tbl = ftbl_gfx3d_clk_src,
+       .clkr.hw.init = &gfx3d_clk_params,
+};
+
+static const struct freq_tbl ftbl_pdm2_clk_src[] = {
+       F(64000000, P_GPLL0_OUT_MAIN, 12.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 pdm2_clk_src = {
+       .cmd_rcgr = 0x44010,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_pdm2_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pdm2_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_rbcpr_gfx_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 rbcpr_gfx_clk_src = {
+       .cmd_rcgr = 0x3a00c,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_rbcpr_gfx_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "rbcpr_gfx_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_sdcc1_apps_clk_src[] = {
+       F(144000, P_XO, 16, 3, 25),
+       F(400000, P_XO, 12, 1, 4),
+       F(20000000, P_GPLL0_OUT_MAIN, 10, 1, 4),
+       F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2),
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(342850000, P_GPLL4_OUT, 3.5, 0, 0),
+       F(400000000, P_GPLL4_OUT, 3, 0, 0),
+       { }
+};
+
+static const struct freq_tbl ftbl_sdcc1_8976_v1_1_apps_clk_src[] = {
+       F(144000, P_XO, 16, 3, 25),
+       F(400000, P_XO, 12, 1, 4),
+       F(20000000, P_GPLL0_OUT_MAIN, 10, 1, 4),
+       F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2),
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(186400000, P_GPLL2_OUT, 5, 0, 0),
+       F(372800000, P_GPLL2_OUT, 2.5, 0, 0),
+       { }
+};
+
+static const struct clk_init_data sdcc1_apps_clk_src_8976v1_1_init = {
+       .name = "sdcc1_apps_clk_src",
+       .parent_data = gcc_parent_data_v1_1,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_v1_1),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 sdcc1_apps_clk_src = {
+       .cmd_rcgr = 0x42004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_sdcc1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc1_apps_clk_src",
+               .parent_data = gcc_parent_data_1,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_sdcc1_ice_core_clk_src[] = {
+       F(100000000, P_GPLL0_OUT_M, 8, 0, 0),
+       F(200000000, P_GPLL0_OUT_M, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 sdcc1_ice_core_clk_src = {
+       .cmd_rcgr = 0x5d000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_sdcc_ice,
+       .freq_tbl = ftbl_sdcc1_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc1_ice_core_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_sdcc2_4_apps_clk_src[] = {
+       F(144000, P_XO, 16, 3, 25),
+       F(400000, P_XO, 12, 1, 4),
+       F(20000000, P_GPLL0_OUT_MAIN, 10, 1, 4),
+       F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2),
+       F(40000000, P_GPLL0_OUT_MAIN, 10, 1, 2),
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       F(80000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 sdcc2_apps_clk_src = {
+       .cmd_rcgr = 0x43004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4,
+       .freq_tbl = ftbl_sdcc2_4_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc2_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 sdcc3_apps_clk_src = {
+       .cmd_rcgr = 0x39004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4,
+       .freq_tbl = ftbl_sdcc2_4_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc3_apps_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_usb_fs_ic_clk_src[] = {
+       F(60000000, P_GPLL6_OUT_MAIN, 6, 1, 3),
+       { }
+};
+
+static struct clk_rcg2 usb_fs_ic_clk_src = {
+       .cmd_rcgr = 0x3f034,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_9,
+       .freq_tbl = ftbl_usb_fs_ic_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb_fs_ic_clk_src",
+               .parent_data = gcc_parent_data_9,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_9),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_usb_fs_system_clk_src[] = {
+       F(64000000, P_GPLL0_OUT, 12.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 usb_fs_system_clk_src = {
+       .cmd_rcgr = 0x3f010,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4_fs,
+       .freq_tbl = ftbl_usb_fs_system_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb_fs_system_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_usb_hs_system_clk_src[] = {
+       F(57140000, P_GPLL0_OUT_MAIN, 14, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(133333333, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       F(177780000, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 usb_hs_system_clk_src = {
+       .cmd_rcgr = 0x41010,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4,
+       .freq_tbl = ftbl_usb_hs_system_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb_hs_system_clk_src",
+               .parent_data = gcc_parent_data_4_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4_8),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_vcodec0_clk_src[] = {
+       F(72727200, P_GPLL0_OUT_MAIN, 11, 0, 0),
+       F(80000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(133333333, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       F(228570000, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
+       F(310667000, P_GPLL2_AUX, 3, 0, 0),
+       F(360000000, P_GPLL6_AUX, 3, 0, 0),
+       F(400000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+       F(466000000, P_GPLL2_AUX, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 vcodec0_clk_src = {
+       .cmd_rcgr = 0x4c000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_vcodec0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "vcodec0_clk_src",
+               .parent_data = gcc_parent_data_3,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_3),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_aps_0_clk = {
+       .halt_reg = 0x78004,
+       .clkr = {
+               .enable_reg = 0x78004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_aps_0_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &aps_0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_aps_1_clk = {
+       .halt_reg = 0x79004,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_aps_1_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &aps_1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
+       .halt_reg = 0x2008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup1_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp1_qup1_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
+       .halt_reg = 0x2004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup1_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp1_qup1_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
+       .halt_reg = 0x3010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup2_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp1_qup2_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
+       .halt_reg = 0x300c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x300c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup2_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp1_qup2_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
+       .halt_reg = 0x4020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup3_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp1_qup3_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
+       .halt_reg = 0x401c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x401c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup3_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp1_qup3_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
+       .halt_reg = 0x5020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup4_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp1_qup4_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
+       .halt_reg = 0x501c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x501c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup4_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp1_qup4_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart1_apps_clk = {
+       .halt_reg = 0x203c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x203c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_uart1_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp1_uart1_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart2_apps_clk = {
+       .halt_reg = 0x302c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x302c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_uart2_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp1_uart2_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup1_i2c_apps_clk = {
+       .halt_reg = 0xc008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xc008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_qup1_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp2_qup1_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup1_spi_apps_clk = {
+       .halt_reg = 0xc004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xc004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_qup1_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp2_qup1_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup2_i2c_apps_clk = {
+       .halt_reg = 0xd010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xd010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_qup2_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp2_qup2_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup2_spi_apps_clk = {
+       .halt_reg = 0xd00c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xd00c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_qup2_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp2_qup2_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup3_i2c_apps_clk = {
+       .halt_reg = 0xf020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xf020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_qup3_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp2_qup3_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup3_spi_apps_clk = {
+       .halt_reg = 0xf01c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xf01c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_qup3_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp2_qup3_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup4_i2c_apps_clk = {
+       .halt_reg = 0x18020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x18020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_qup4_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp2_qup4_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup4_spi_apps_clk = {
+       .halt_reg = 0x1801c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1801c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_qup4_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp2_qup4_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_uart1_apps_clk = {
+       .halt_reg = 0xc03c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xc03c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_uart1_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp2_uart1_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_uart2_apps_clk = {
+       .halt_reg = 0xd02c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xd02c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_uart2_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &blsp2_uart2_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_cci_ahb_clk = {
+       .halt_reg = 0x5101c,
+       .clkr = {
+               .enable_reg = 0x5101c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_cci_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_cci_clk = {
+       .halt_reg = 0x51018,
+       .clkr = {
+               .enable_reg = 0x51018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_cci_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &cci_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_cpp_ahb_clk = {
+       .halt_reg = 0x58040,
+       .clkr = {
+               .enable_reg = 0x58040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_cpp_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_cpp_axi_clk = {
+       .halt_reg = 0x58064,
+       .clkr = {
+               .enable_reg = 0x58064,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_cpp_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_cpp_clk = {
+       .halt_reg = 0x5803c,
+       .clkr = {
+               .enable_reg = 0x5803c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_cpp_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &cpp_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi0_ahb_clk = {
+       .halt_reg = 0x4e040,
+       .clkr = {
+               .enable_reg = 0x4e040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi0_clk = {
+       .halt_reg = 0x4e03c,
+       .clkr = {
+               .enable_reg = 0x4e03c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &csi0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi0phy_clk = {
+       .halt_reg = 0x4e048,
+       .clkr = {
+               .enable_reg = 0x4e048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0phy_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &csi0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi0pix_clk = {
+       .halt_reg = 0x4e058,
+       .clkr = {
+               .enable_reg = 0x4e058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0pix_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &csi0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi0rdi_clk = {
+       .halt_reg = 0x4e050,
+       .clkr = {
+               .enable_reg = 0x4e050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0rdi_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &csi0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi1_ahb_clk = {
+       .halt_reg = 0x4f040,
+       .clkr = {
+               .enable_reg = 0x4f040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi1_clk = {
+       .halt_reg = 0x4f03c,
+       .clkr = {
+               .enable_reg = 0x4f03c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &csi1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi1phy_clk = {
+       .halt_reg = 0x4f048,
+       .clkr = {
+               .enable_reg = 0x4f048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1phy_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &csi1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi1pix_clk = {
+       .halt_reg = 0x4f058,
+       .clkr = {
+               .enable_reg = 0x4f058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1pix_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &csi1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi1rdi_clk = {
+       .halt_reg = 0x4f050,
+       .clkr = {
+               .enable_reg = 0x4f050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1rdi_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &csi1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi2_ahb_clk = {
+       .halt_reg = 0x3c040,
+       .clkr = {
+               .enable_reg = 0x3c040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi2_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi2_clk = {
+       .halt_reg = 0x3c03c,
+       .clkr = {
+               .enable_reg = 0x3c03c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi2_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &csi2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi2phy_clk = {
+       .halt_reg = 0x3c048,
+       .clkr = {
+               .enable_reg = 0x3c048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi2phy_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &csi2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi2pix_clk = {
+       .halt_reg = 0x3c058,
+       .clkr = {
+               .enable_reg = 0x3c058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi2pix_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &csi2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi2rdi_clk = {
+       .halt_reg = 0x3c050,
+       .clkr = {
+               .enable_reg = 0x3c050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi2rdi_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &csi2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi_vfe0_clk = {
+       .halt_reg = 0x58050,
+       .clkr = {
+               .enable_reg = 0x58050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi_vfe0_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &vfe0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi_vfe1_clk = {
+       .halt_reg = 0x58074,
+       .clkr = {
+               .enable_reg = 0x58074,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi_vfe1_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &vfe1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_gp0_clk = {
+       .halt_reg = 0x54018,
+       .clkr = {
+               .enable_reg = 0x54018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_gp0_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &camss_gp0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_gp1_clk = {
+       .halt_reg = 0x55018,
+       .clkr = {
+               .enable_reg = 0x55018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_gp1_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &camss_gp1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_ispif_ahb_clk = {
+       .halt_reg = 0x50004,
+       .clkr = {
+               .enable_reg = 0x50004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_ispif_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_jpeg0_clk = {
+       .halt_reg = 0x57020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x57020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_jpeg0_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &jpeg0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_jpeg_ahb_clk = {
+       .halt_reg = 0x57024,
+       .clkr = {
+               .enable_reg = 0x57024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_jpeg_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_jpeg_axi_clk = {
+       .halt_reg = 0x57028,
+       .clkr = {
+               .enable_reg = 0x57028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_jpeg_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_mclk0_clk = {
+       .halt_reg = 0x52018,
+       .clkr = {
+               .enable_reg = 0x52018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_mclk0_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &mclk0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_mclk1_clk = {
+       .halt_reg = 0x53018,
+       .clkr = {
+               .enable_reg = 0x53018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_mclk1_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &mclk1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_mclk2_clk = {
+       .halt_reg = 0x5c018,
+       .clkr = {
+               .enable_reg = 0x5c018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_mclk2_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &mclk2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_micro_ahb_clk = {
+       .halt_reg = 0x5600c,
+       .clkr = {
+               .enable_reg = 0x5600c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_micro_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi0phytimer_clk = {
+       .halt_reg = 0x4e01c,
+       .clkr = {
+               .enable_reg = 0x4e01c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0phytimer_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &csi0phytimer_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi1phytimer_clk = {
+       .halt_reg = 0x4f01c,
+       .clkr = {
+               .enable_reg = 0x4f01c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1phytimer_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &csi1phytimer_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_ahb_clk = {
+       .halt_reg = 0x56004,
+       .clkr = {
+               .enable_reg = 0x56004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_top_ahb_clk = {
+       .halt_reg = 0x5a014,
+       .clkr = {
+               .enable_reg = 0x5a014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_top_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_vfe0_clk = {
+       .halt_reg = 0x58038,
+       .clkr = {
+               .enable_reg = 0x58038,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_vfe0_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &vfe0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_vfe_ahb_clk = {
+       .halt_reg = 0x58044,
+       .clkr = {
+               .enable_reg = 0x58044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_vfe_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_vfe_axi_clk = {
+       .halt_reg = 0x58048,
+       .clkr = {
+               .enable_reg = 0x58048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_vfe_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_vfe1_ahb_clk = {
+       .halt_reg = 0x58060,
+       .clkr = {
+               .enable_reg = 0x58060,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_vfe1_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_vfe1_axi_clk = {
+       .halt_reg = 0x58068,
+       .clkr = {
+               .enable_reg = 0x58068,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_vfe1_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_vfe1_clk = {
+       .halt_reg = 0x5805c,
+       .clkr = {
+               .enable_reg = 0x5805c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_vfe1_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &vfe1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_dcc_clk = {
+       .halt_reg = 0x77004,
+       .clkr = {
+               .enable_reg = 0x77004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_dcc_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_oxili_gmem_clk = {
+       .halt_reg = 0x59024,
+       .clkr = {
+               .enable_reg = 0x59024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_oxili_gmem_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &gfx3d_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp1_clk = {
+       .halt_reg = 0x8000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_gp1_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &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 = 0x9000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x9000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_gp2_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &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 = 0xa000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xa000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_gp3_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &gp3_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_ahb_clk = {
+       .halt_reg = 0x4d07c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d07c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_axi_clk = {
+       .halt_reg = 0x4d080,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d080,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_byte0_clk = {
+       .halt_reg = 0x4d094,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d094,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_byte0_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &byte0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_byte1_clk = {
+       .halt_reg = 0x4d0a0,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d0a0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_byte1_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &byte1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_esc0_clk = {
+       .halt_reg = 0x4d098,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d098,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_esc0_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &esc0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_esc1_clk = {
+       .halt_reg = 0x4d09c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d09c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_esc1_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &esc1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_mdp_clk = {
+       .halt_reg = 0x4d088,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d088,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_mdp_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &mdp_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_pclk0_clk = {
+       .halt_reg = 0x4d084,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d084,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_pclk0_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &pclk0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_pclk1_clk = {
+       .halt_reg = 0x4d0a4,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d0a4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_pclk1_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &pclk1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_vsync_clk = {
+       .halt_reg = 0x4d090,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d090,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_vsync_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &vsync_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mss_cfg_ahb_clk = {
+       .halt_reg = 0x49000,
+       .clkr = {
+               .enable_reg = 0x49000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mss_cfg_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
+       .halt_reg = 0x49004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x49004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mss_q6_bimc_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_bimc_gfx_clk = {
+       .halt_reg = 0x59048,
+       .clkr = {
+               .enable_reg = 0x59048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_bimc_gfx_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_oxili_ahb_clk = {
+       .halt_reg = 0x59028,
+       .clkr = {
+               .enable_reg = 0x59028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_oxili_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_oxili_aon_clk = {
+       .halt_reg = 0x59044,
+       .clkr = {
+               .enable_reg = 0x59044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_oxili_aon_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &gfx3d_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_oxili_gfx3d_clk = {
+       .halt_reg = 0x59020,
+       .clkr = {
+               .enable_reg = 0x59020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_oxili_gfx3d_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &gfx3d_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_oxili_timer_clk = {
+       .halt_reg = 0x59040,
+       .clkr = {
+               .enable_reg = 0x59040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_oxili_timer_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm2_clk = {
+       .halt_reg = 0x4400c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4400c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_pdm2_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &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 = 0x44004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x44004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_pdm_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_rbcpr_gfx_ahb_clk = {
+       .halt_reg = 0x3a008,
+       .clkr = {
+               .enable_reg = 0x3a008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_rbcpr_gfx_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_rbcpr_gfx_clk = {
+       .halt_reg = 0x3a004,
+       .clkr = {
+               .enable_reg = 0x3a004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_rbcpr_gfx_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &rbcpr_gfx_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+       .halt_reg = 0x4201c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4201c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_sdcc1_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+       .halt_reg = 0x42018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x42018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_sdcc1_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &sdcc1_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_ice_core_clk = {
+       .halt_reg = 0x5d014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5d014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_sdcc1_ice_core_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &sdcc1_ice_core_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc2_ahb_clk = {
+       .halt_reg = 0x4301c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4301c,
+               .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 = 0x43018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x43018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_sdcc2_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &sdcc2_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc3_ahb_clk = {
+       .halt_reg = 0x3901c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3901c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_sdcc3_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc3_apps_clk = {
+       .halt_reg = 0x39018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x39018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_sdcc3_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &sdcc3_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb2a_phy_sleep_clk = {
+       .halt_reg = 0x4102c,
+       .clkr = {
+               .enable_reg = 0x4102c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb2a_phy_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb_hs_phy_cfg_ahb_clk = {
+       .halt_reg = 0x41030,
+       .clkr = {
+               .enable_reg = 0x41030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb_hs_phy_cfg_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb_fs_ahb_clk = {
+       .halt_reg = 0x3f008,
+       .clkr = {
+               .enable_reg = 0x3f008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb_fs_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb_fs_ic_clk = {
+       .halt_reg = 0x3f030,
+       .clkr = {
+               .enable_reg = 0x3f030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb_fs_ic_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &usb_fs_ic_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb_fs_system_clk = {
+       .halt_reg = 0x3f004,
+       .clkr = {
+               .enable_reg = 0x3f004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb_fs_system_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &usb_fs_system_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb_hs_ahb_clk = {
+       .halt_reg = 0x41008,
+       .clkr = {
+               .enable_reg = 0x41008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb_hs_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb_hs_system_clk = {
+       .halt_reg = 0x41004,
+       .clkr = {
+               .enable_reg = 0x41004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb_hs_system_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &usb_hs_system_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_venus0_ahb_clk = {
+       .halt_reg = 0x4c020,
+       .clkr = {
+               .enable_reg = 0x4c020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_venus0_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_venus0_axi_clk = {
+       .halt_reg = 0x4c024,
+       .clkr = {
+               .enable_reg = 0x4c024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_venus0_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_venus0_core0_vcodec0_clk = {
+       .halt_reg = 0x4c02c,
+       .clkr = {
+               .enable_reg = 0x4c02c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_venus0_core0_vcodec0_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &vcodec0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_venus0_core1_vcodec0_clk = {
+       .halt_reg = 0x4c034,
+       .clkr = {
+               .enable_reg = 0x4c034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_venus0_core1_vcodec0_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &vcodec0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_venus0_vcodec0_clk = {
+       .halt_reg = 0x4c01c,
+       .clkr = {
+               .enable_reg = 0x4c01c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_venus0_vcodec0_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &vcodec0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+/* Vote clocks */
+static struct clk_branch gcc_apss_ahb_clk = {
+       .halt_reg = 0x4601c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(14),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_apss_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_apss_axi_clk = {
+       .halt_reg = 0x46020,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_apss_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_ahb_clk = {
+       .halt_reg = 0x1008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_ahb_clk = {
+       .halt_reg = 0xb008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(20),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_prng_ahb_clk = {
+       .halt_reg = 0x13004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(8),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_prng_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_boot_rom_ahb_clk = {
+       .halt_reg = 0x1300c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_boot_rom_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_crypto_ahb_clk = {
+       .halt_reg = 0x16024,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_crypto_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_crypto_axi_clk = {
+       .halt_reg = 0x16020,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_crypto_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_crypto_clk = {
+       .halt_reg = 0x1601c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_crypto_clk",
+                       .parent_hws = (const struct clk_hw *[]) {
+                               &crypto_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cpp_tbu_clk = {
+       .halt_reg = 0x12040,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(14),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cpp_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gfx_1_tbu_clk = {
+       .halt_reg = 0x12098,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(19),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gfx_1_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gfx_tbu_clk = {
+       .halt_reg = 0x12010,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(3),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gfx_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gfx_tcu_clk = {
+       .halt_reg = 0x12020,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gfx_tcu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_apss_tcu_clk = {
+       .halt_reg = 0x12018,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_apss_tcu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gtcu_ahb_clk = {
+       .halt_reg = 0x12044,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gtcu_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_jpeg_tbu_clk = {
+       .halt_reg = 0x12034,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_jpeg_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdp_rt_tbu_clk = {
+       .halt_reg = 0x1204c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(15),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mdp_rt_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdp_tbu_clk = {
+       .halt_reg = 0x1201c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mdp_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_smmu_cfg_clk = {
+       .halt_reg = 0x12038,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(12),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_smmu_cfg_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_venus_1_tbu_clk = {
+       .halt_reg = 0x1209c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(20),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_venus_1_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_venus_tbu_clk = {
+       .halt_reg = 0x12014,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(5),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_venus_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_vfe1_tbu_clk = {
+       .halt_reg = 0x12090,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(17),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_vfe1_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_vfe_tbu_clk = {
+       .halt_reg = 0x1203c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_vfe_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc venus_gdsc = {
+       .gdscr = 0x4c018,
+       .cxcs = (unsigned int []){ 0x4c024, 0x4c01c },
+       .cxc_count = 2,
+       .pd = {
+               .name = "venus_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc venus_core0_gdsc = {
+       .gdscr = 0x4c028,
+       .cxcs = (unsigned int []){ 0x4c02c },
+       .cxc_count = 1,
+       .pd = {
+               .name = "venus_core0_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc venus_core1_gdsc = {
+       .gdscr = 0x4c030,
+       .pd = {
+               .name = "venus_core1_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc mdss_gdsc = {
+       .gdscr = 0x4d078,
+       .cxcs = (unsigned int []){ 0x4d080, 0x4d088 },
+       .cxc_count = 2,
+       .pd = {
+               .name = "mdss_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc jpeg_gdsc = {
+       .gdscr = 0x5701c,
+       .cxcs = (unsigned int []){ 0x57020, 0x57028 },
+       .cxc_count = 2,
+       .pd = {
+               .name = "jpeg_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc vfe0_gdsc = {
+       .gdscr = 0x58034,
+       .cxcs = (unsigned int []){ 0x58038, 0x58048, 0x5600c, 0x58050 },
+       .cxc_count = 4,
+       .pd = {
+               .name = "vfe0_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc vfe1_gdsc = {
+       .gdscr = 0x5806c,
+       .cxcs = (unsigned int []){ 0x5805c, 0x58068, 0x5600c, 0x58074 },
+       .cxc_count = 4,
+       .pd = {
+               .name = "vfe1_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc cpp_gdsc = {
+       .gdscr = 0x58078,
+       .cxcs = (unsigned int []){ 0x5803c, 0x58064 },
+       .cxc_count = 2,
+       .pd = {
+               .name = "cpp_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxili_cx_gdsc = {
+       .gdscr = 0x5904c,
+       .cxcs = (unsigned int []){ 0x59020 },
+       .cxc_count = 1,
+       .pd = {
+               .name = "oxili_cx_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
+};
+
+static struct gdsc oxili_gx_gdsc = {
+       .gdscr = 0x5901c,
+       .clamp_io_ctrl = 0x5b00c,
+       .cxcs = (unsigned int []){ 0x59000, 0x59024 },
+       .cxc_count = 2,
+       .pd = {
+               .name = "oxili_gx_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .supply = "vdd_gfx",
+       .flags = CLAMP_IO,
+};
+
+static struct clk_regmap *gcc_msm8976_clocks[] = {
+       [GPLL0] = &gpll0.clkr,
+       [GPLL2] = &gpll2.clkr,
+       [GPLL3] = &gpll3.clkr,
+       [GPLL4] = &gpll4.clkr,
+       [GPLL6] = &gpll6.clkr,
+       [GPLL0_CLK_SRC] = &gpll0_vote,
+       [GPLL2_CLK_SRC] = &gpll2_vote,
+       [GPLL3_CLK_SRC] = &gpll3_vote,
+       [GPLL4_CLK_SRC] = &gpll4_vote,
+       [GPLL6_CLK_SRC] = &gpll6_vote,
+       [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr,
+       [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
+       [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,
+       [GCC_BLSP2_QUP1_I2C_APPS_CLK] = &gcc_blsp2_qup1_i2c_apps_clk.clkr,
+       [GCC_BLSP2_QUP1_SPI_APPS_CLK] = &gcc_blsp2_qup1_spi_apps_clk.clkr,
+       [GCC_BLSP2_QUP2_I2C_APPS_CLK] = &gcc_blsp2_qup2_i2c_apps_clk.clkr,
+       [GCC_BLSP2_QUP2_SPI_APPS_CLK] = &gcc_blsp2_qup2_spi_apps_clk.clkr,
+       [GCC_BLSP2_QUP3_I2C_APPS_CLK] = &gcc_blsp2_qup3_i2c_apps_clk.clkr,
+       [GCC_BLSP2_QUP3_SPI_APPS_CLK] = &gcc_blsp2_qup3_spi_apps_clk.clkr,
+       [GCC_BLSP2_QUP4_I2C_APPS_CLK] = &gcc_blsp2_qup4_i2c_apps_clk.clkr,
+       [GCC_BLSP2_QUP4_SPI_APPS_CLK] = &gcc_blsp2_qup4_spi_apps_clk.clkr,
+       [GCC_BLSP2_UART1_APPS_CLK] = &gcc_blsp2_uart1_apps_clk.clkr,
+       [GCC_BLSP2_UART2_APPS_CLK] = &gcc_blsp2_uart2_apps_clk.clkr,
+       [GCC_CAMSS_CCI_AHB_CLK] = &gcc_camss_cci_ahb_clk.clkr,
+       [GCC_CAMSS_CCI_CLK] = &gcc_camss_cci_clk.clkr,
+       [GCC_CAMSS_CPP_AHB_CLK] = &gcc_camss_cpp_ahb_clk.clkr,
+       [GCC_CAMSS_CPP_AXI_CLK] = &gcc_camss_cpp_axi_clk.clkr,
+       [GCC_CAMSS_CPP_CLK] = &gcc_camss_cpp_clk.clkr,
+       [GCC_CAMSS_CSI0_AHB_CLK] = &gcc_camss_csi0_ahb_clk.clkr,
+       [GCC_CAMSS_CSI0_CLK] = &gcc_camss_csi0_clk.clkr,
+       [GCC_CAMSS_CSI0PHY_CLK] = &gcc_camss_csi0phy_clk.clkr,
+       [GCC_CAMSS_CSI0PIX_CLK] = &gcc_camss_csi0pix_clk.clkr,
+       [GCC_CAMSS_CSI0RDI_CLK] = &gcc_camss_csi0rdi_clk.clkr,
+       [GCC_CAMSS_CSI1_AHB_CLK] = &gcc_camss_csi1_ahb_clk.clkr,
+       [GCC_CAMSS_CSI1_CLK] = &gcc_camss_csi1_clk.clkr,
+       [GCC_CAMSS_CSI1PHY_CLK] = &gcc_camss_csi1phy_clk.clkr,
+       [GCC_CAMSS_CSI1PIX_CLK] = &gcc_camss_csi1pix_clk.clkr,
+       [GCC_CAMSS_CSI1RDI_CLK] = &gcc_camss_csi1rdi_clk.clkr,
+       [GCC_CAMSS_CSI2_AHB_CLK] = &gcc_camss_csi2_ahb_clk.clkr,
+       [GCC_CAMSS_CSI2_CLK] = &gcc_camss_csi2_clk.clkr,
+       [GCC_CAMSS_CSI2PHY_CLK] = &gcc_camss_csi2phy_clk.clkr,
+       [GCC_CAMSS_CSI2PIX_CLK] = &gcc_camss_csi2pix_clk.clkr,
+       [GCC_CAMSS_CSI2RDI_CLK] = &gcc_camss_csi2rdi_clk.clkr,
+       [GCC_CAMSS_CSI_VFE0_CLK] = &gcc_camss_csi_vfe0_clk.clkr,
+       [GCC_CAMSS_CSI_VFE1_CLK] = &gcc_camss_csi_vfe1_clk.clkr,
+       [GCC_CAMSS_GP0_CLK] = &gcc_camss_gp0_clk.clkr,
+       [GCC_CAMSS_GP1_CLK] = &gcc_camss_gp1_clk.clkr,
+       [GCC_CAMSS_ISPIF_AHB_CLK] = &gcc_camss_ispif_ahb_clk.clkr,
+       [GCC_CAMSS_JPEG0_CLK] = &gcc_camss_jpeg0_clk.clkr,
+       [GCC_CAMSS_JPEG_AHB_CLK] = &gcc_camss_jpeg_ahb_clk.clkr,
+       [GCC_CAMSS_JPEG_AXI_CLK] = &gcc_camss_jpeg_axi_clk.clkr,
+       [GCC_CAMSS_MCLK0_CLK] = &gcc_camss_mclk0_clk.clkr,
+       [GCC_CAMSS_MCLK1_CLK] = &gcc_camss_mclk1_clk.clkr,
+       [GCC_CAMSS_MCLK2_CLK] = &gcc_camss_mclk2_clk.clkr,
+       [GCC_CAMSS_MICRO_AHB_CLK] = &gcc_camss_micro_ahb_clk.clkr,
+       [GCC_CAMSS_CSI0PHYTIMER_CLK] = &gcc_camss_csi0phytimer_clk.clkr,
+       [GCC_CAMSS_CSI1PHYTIMER_CLK] = &gcc_camss_csi1phytimer_clk.clkr,
+       [GCC_CAMSS_AHB_CLK] = &gcc_camss_ahb_clk.clkr,
+       [GCC_CAMSS_TOP_AHB_CLK] = &gcc_camss_top_ahb_clk.clkr,
+       [GCC_CAMSS_VFE0_CLK] = &gcc_camss_vfe0_clk.clkr,
+       [GCC_CAMSS_VFE_AHB_CLK] = &gcc_camss_vfe_ahb_clk.clkr,
+       [GCC_CAMSS_VFE_AXI_CLK] = &gcc_camss_vfe_axi_clk.clkr,
+       [GCC_CAMSS_VFE1_AHB_CLK] = &gcc_camss_vfe1_ahb_clk.clkr,
+       [GCC_CAMSS_VFE1_AXI_CLK] = &gcc_camss_vfe1_axi_clk.clkr,
+       [GCC_CAMSS_VFE1_CLK] = &gcc_camss_vfe1_clk.clkr,
+       [GCC_DCC_CLK] = &gcc_dcc_clk.clkr,
+       [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+       [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+       [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+       [GCC_MDSS_AHB_CLK] = &gcc_mdss_ahb_clk.clkr,
+       [GCC_MDSS_AXI_CLK] = &gcc_mdss_axi_clk.clkr,
+       [GCC_MDSS_ESC0_CLK] = &gcc_mdss_esc0_clk.clkr,
+       [GCC_MDSS_ESC1_CLK] = &gcc_mdss_esc1_clk.clkr,
+       [GCC_MDSS_MDP_CLK] = &gcc_mdss_mdp_clk.clkr,
+       [GCC_MDSS_VSYNC_CLK] = &gcc_mdss_vsync_clk.clkr,
+       [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr,
+       [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr,
+       [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
+       [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+       [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
+       [GCC_RBCPR_GFX_AHB_CLK] = &gcc_rbcpr_gfx_ahb_clk.clkr,
+       [GCC_RBCPR_GFX_CLK] = &gcc_rbcpr_gfx_clk.clkr,
+       [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
+       [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
+       [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr,
+       [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
+       [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
+       [GCC_SDCC3_AHB_CLK] = &gcc_sdcc3_ahb_clk.clkr,
+       [GCC_SDCC3_APPS_CLK] = &gcc_sdcc3_apps_clk.clkr,
+       [GCC_USB2A_PHY_SLEEP_CLK] = &gcc_usb2a_phy_sleep_clk.clkr,
+       [GCC_USB_HS_PHY_CFG_AHB_CLK] = &gcc_usb_hs_phy_cfg_ahb_clk.clkr,
+       [GCC_USB_FS_AHB_CLK] = &gcc_usb_fs_ahb_clk.clkr,
+       [GCC_USB_FS_IC_CLK] = &gcc_usb_fs_ic_clk.clkr,
+       [GCC_USB_FS_SYSTEM_CLK] = &gcc_usb_fs_system_clk.clkr,
+       [GCC_USB_HS_AHB_CLK] = &gcc_usb_hs_ahb_clk.clkr,
+       [GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr,
+       [GCC_VENUS0_AHB_CLK] = &gcc_venus0_ahb_clk.clkr,
+       [GCC_VENUS0_AXI_CLK] = &gcc_venus0_axi_clk.clkr,
+       [GCC_VENUS0_CORE0_VCODEC0_CLK] = &gcc_venus0_core0_vcodec0_clk.clkr,
+       [GCC_VENUS0_CORE1_VCODEC0_CLK] = &gcc_venus0_core1_vcodec0_clk.clkr,
+       [GCC_VENUS0_VCODEC0_CLK] = &gcc_venus0_vcodec0_clk.clkr,
+       [GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr,
+       [GCC_APSS_AXI_CLK] = &gcc_apss_axi_clk.clkr,
+       [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
+       [GCC_BLSP2_AHB_CLK] = &gcc_blsp2_ahb_clk.clkr,
+       [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
+       [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr,
+       [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr,
+       [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr,
+       [GCC_CPP_TBU_CLK] = &gcc_cpp_tbu_clk.clkr,
+       [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr,
+       [GCC_JPEG_TBU_CLK] = &gcc_jpeg_tbu_clk.clkr,
+       [GCC_MDP_RT_TBU_CLK] = &gcc_mdp_rt_tbu_clk.clkr,
+       [GCC_MDP_TBU_CLK] = &gcc_mdp_tbu_clk.clkr,
+       [GCC_SMMU_CFG_CLK] = &gcc_smmu_cfg_clk.clkr,
+       [GCC_VENUS_1_TBU_CLK] = &gcc_venus_1_tbu_clk.clkr,
+       [GCC_VENUS_TBU_CLK] = &gcc_venus_tbu_clk.clkr,
+       [GCC_VFE1_TBU_CLK] = &gcc_vfe1_tbu_clk.clkr,
+       [GCC_VFE_TBU_CLK] = &gcc_vfe_tbu_clk.clkr,
+       [GCC_APS_0_CLK] = &gcc_aps_0_clk.clkr,
+       [GCC_APS_1_CLK] = &gcc_aps_1_clk.clkr,
+       [APS_0_CLK_SRC] = &aps_0_clk_src.clkr,
+       [APS_1_CLK_SRC] = &aps_1_clk_src.clkr,
+       [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr,
+       [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
+       [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr,
+       [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr,
+       [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr,
+       [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr,
+       [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr,
+       [BLSP2_QUP1_I2C_APPS_CLK_SRC] = &blsp2_qup1_i2c_apps_clk_src.clkr,
+       [BLSP2_QUP1_SPI_APPS_CLK_SRC] = &blsp2_qup1_spi_apps_clk_src.clkr,
+       [BLSP2_QUP2_I2C_APPS_CLK_SRC] = &blsp2_qup2_i2c_apps_clk_src.clkr,
+       [BLSP2_QUP2_SPI_APPS_CLK_SRC] = &blsp2_qup2_spi_apps_clk_src.clkr,
+       [BLSP2_QUP3_I2C_APPS_CLK_SRC] = &blsp2_qup3_i2c_apps_clk_src.clkr,
+       [BLSP2_QUP3_SPI_APPS_CLK_SRC] = &blsp2_qup3_spi_apps_clk_src.clkr,
+       [BLSP2_QUP4_I2C_APPS_CLK_SRC] = &blsp2_qup4_i2c_apps_clk_src.clkr,
+       [BLSP2_QUP4_SPI_APPS_CLK_SRC] = &blsp2_qup4_spi_apps_clk_src.clkr,
+       [BLSP2_UART1_APPS_CLK_SRC] = &blsp2_uart1_apps_clk_src.clkr,
+       [BLSP2_UART2_APPS_CLK_SRC] = &blsp2_uart2_apps_clk_src.clkr,
+       [CCI_CLK_SRC] = &cci_clk_src.clkr,
+       [CPP_CLK_SRC] = &cpp_clk_src.clkr,
+       [CSI0_CLK_SRC] = &csi0_clk_src.clkr,
+       [CSI1_CLK_SRC] = &csi1_clk_src.clkr,
+       [CSI2_CLK_SRC] = &csi2_clk_src.clkr,
+       [CAMSS_GP0_CLK_SRC] = &camss_gp0_clk_src.clkr,
+       [CAMSS_GP1_CLK_SRC] = &camss_gp1_clk_src.clkr,
+       [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr,
+       [MCLK0_CLK_SRC] = &mclk0_clk_src.clkr,
+       [MCLK1_CLK_SRC] = &mclk1_clk_src.clkr,
+       [MCLK2_CLK_SRC] = &mclk2_clk_src.clkr,
+       [CSI0PHYTIMER_CLK_SRC] = &csi0phytimer_clk_src.clkr,
+       [CSI1PHYTIMER_CLK_SRC] = &csi1phytimer_clk_src.clkr,
+       [CAMSS_TOP_AHB_CLK_SRC] = &camss_top_ahb_clk_src.clkr,
+       [VFE0_CLK_SRC] = &vfe0_clk_src.clkr,
+       [VFE1_CLK_SRC] = &vfe1_clk_src.clkr,
+       [CRYPTO_CLK_SRC] = &crypto_clk_src.clkr,
+       [GP1_CLK_SRC] = &gp1_clk_src.clkr,
+       [GP2_CLK_SRC] = &gp2_clk_src.clkr,
+       [GP3_CLK_SRC] = &gp3_clk_src.clkr,
+       [ESC0_CLK_SRC] = &esc0_clk_src.clkr,
+       [ESC1_CLK_SRC] = &esc1_clk_src.clkr,
+       [MDP_CLK_SRC] = &mdp_clk_src.clkr,
+       [VSYNC_CLK_SRC] = &vsync_clk_src.clkr,
+       [PDM2_CLK_SRC] = &pdm2_clk_src.clkr,
+       [RBCPR_GFX_CLK_SRC] = &rbcpr_gfx_clk_src.clkr,
+       [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr,
+       [SDCC1_ICE_CORE_CLK_SRC] = &sdcc1_ice_core_clk_src.clkr,
+       [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr,
+       [SDCC3_APPS_CLK_SRC] = &sdcc3_apps_clk_src.clkr,
+       [USB_FS_IC_CLK_SRC] = &usb_fs_ic_clk_src.clkr,
+       [USB_FS_SYSTEM_CLK_SRC] = &usb_fs_system_clk_src.clkr,
+       [USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr,
+       [VCODEC0_CLK_SRC] = &vcodec0_clk_src.clkr,
+       [GCC_MDSS_BYTE0_CLK_SRC] = &byte0_clk_src.clkr,
+       [GCC_MDSS_BYTE1_CLK_SRC] = &byte1_clk_src.clkr,
+       [GCC_MDSS_BYTE0_CLK] = &gcc_mdss_byte0_clk.clkr,
+       [GCC_MDSS_BYTE1_CLK] = &gcc_mdss_byte1_clk.clkr,
+       [GCC_MDSS_PCLK0_CLK_SRC] = &pclk0_clk_src.clkr,
+       [GCC_MDSS_PCLK1_CLK_SRC] = &pclk1_clk_src.clkr,
+       [GCC_MDSS_PCLK0_CLK] = &gcc_mdss_pclk0_clk.clkr,
+       [GCC_MDSS_PCLK1_CLK] = &gcc_mdss_pclk1_clk.clkr,
+       [GCC_GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr,
+       [GCC_GFX3D_OXILI_CLK] = &gcc_oxili_gfx3d_clk.clkr,
+       [GCC_GFX3D_BIMC_CLK] = &gcc_bimc_gfx_clk.clkr,
+       [GCC_GFX3D_OXILI_AHB_CLK] = &gcc_oxili_ahb_clk.clkr,
+       [GCC_GFX3D_OXILI_AON_CLK] = &gcc_oxili_aon_clk.clkr,
+       [GCC_GFX3D_OXILI_GMEM_CLK] = &gcc_oxili_gmem_clk.clkr,
+       [GCC_GFX3D_OXILI_TIMER_CLK] = &gcc_oxili_timer_clk.clkr,
+       [GCC_GFX3D_TBU0_CLK] = &gcc_gfx_tbu_clk.clkr,
+       [GCC_GFX3D_TBU1_CLK] = &gcc_gfx_1_tbu_clk.clkr,
+       [GCC_GFX3D_TCU_CLK] = &gcc_gfx_tcu_clk.clkr,
+       [GCC_GFX3D_GTCU_AHB_CLK] = &gcc_gtcu_ahb_clk.clkr,
+};
+
+static const struct qcom_reset_map gcc_msm8976_resets[] = {
+       [RST_CAMSS_MICRO_BCR]           = { 0x56008 },
+       [RST_USB_HS_BCR]                = { 0x41000 },
+       [RST_QUSB2_PHY_BCR]             = { 0x4103c },
+       [RST_USB2_HS_PHY_ONLY_BCR]      = { 0x41034 },
+       [RST_USB_HS_PHY_CFG_AHB_BCR]    = { 0x41038 },
+       [RST_USB_FS_BCR]                = { 0x3f000 },
+       [RST_CAMSS_CSI1PIX_BCR]         = { 0x4f054 },
+       [RST_CAMSS_CSI_VFE1_BCR]        = { 0x58070 },
+       [RST_CAMSS_VFE1_BCR]            = { 0x5807c },
+       [RST_CAMSS_CPP_BCR]             = { 0x58080 },
+};
+
+static struct gdsc *gcc_msm8976_gdscs[] = {
+       [VENUS_GDSC] = &venus_gdsc,
+       [VENUS_CORE0_GDSC] = &venus_core0_gdsc,
+       [VENUS_CORE1_GDSC] = &venus_core1_gdsc,
+       [MDSS_GDSC] = &mdss_gdsc,
+       [JPEG_GDSC] = &jpeg_gdsc,
+       [VFE0_GDSC] = &vfe0_gdsc,
+       [VFE1_GDSC] = &vfe1_gdsc,
+       [CPP_GDSC] = &cpp_gdsc,
+       [OXILI_GX_GDSC] = &oxili_gx_gdsc,
+       [OXILI_CX_GDSC] = &oxili_cx_gdsc,
+};
+
+static const struct regmap_config gcc_msm8976_regmap_config = {
+       .reg_bits       = 32,
+       .reg_stride     = 4,
+       .val_bits       = 32,
+       .max_register   = 0x7fffc,
+       .fast_io        = true,
+};
+
+static const struct qcom_cc_desc gcc_msm8976_desc = {
+       .config         = &gcc_msm8976_regmap_config,
+       .clks           = gcc_msm8976_clocks,
+       .num_clks       = ARRAY_SIZE(gcc_msm8976_clocks),
+       .resets         = gcc_msm8976_resets,
+       .num_resets     = ARRAY_SIZE(gcc_msm8976_resets),
+       .gdscs          = gcc_msm8976_gdscs,
+       .num_gdscs      = ARRAY_SIZE(gcc_msm8976_gdscs),
+};
+
+static const struct of_device_id gcc_msm8976_match_table[] = {
+       { .compatible = "qcom,gcc-msm8976" }, /* Also valid for 8x56 */
+       { .compatible = "qcom,gcc-msm8976-v1.1" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gcc_msm8976_match_table);
+
+static int gcc_msm8976_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+       int ret;
+
+       if (of_device_is_compatible(pdev->dev.of_node, "qcom,gcc-msm8976-v1.1")) {
+               sdcc1_apps_clk_src.parent_map = gcc_parent_map_v1_1;
+               sdcc1_apps_clk_src.freq_tbl = ftbl_sdcc1_8976_v1_1_apps_clk_src;
+               sdcc1_apps_clk_src.clkr.hw.init = &sdcc1_apps_clk_src_8976v1_1_init;
+       }
+
+       regmap = qcom_cc_map(pdev, &gcc_msm8976_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       /* Set Sleep and Wakeup cycles to 0 for GMEM clock */
+       ret = regmap_update_bits(regmap, gcc_oxili_gmem_clk.clkr.enable_reg, 0xff0, 0);
+       if (ret)
+               return ret;
+
+       clk_pll_configure_sr_hpm_lp(&gpll3, regmap, &gpll3_config, true);
+
+       /* Enable AUX2 clock for APSS */
+       ret = regmap_update_bits(regmap, 0x60000, BIT(2), BIT(2));
+       if (ret)
+               return ret;
+
+       /* Set Sleep cycles to 0 for OXILI clock */
+       ret = regmap_update_bits(regmap, gcc_oxili_gfx3d_clk.clkr.enable_reg, 0xf0, 0);
+       if (ret)
+               return ret;
+
+       return qcom_cc_really_probe(pdev, &gcc_msm8976_desc, regmap);
+}
+
+static struct platform_driver gcc_msm8976_driver = {
+       .probe = gcc_msm8976_probe,
+       .driver = {
+               .name = "qcom,gcc-msm8976",
+               .of_match_table = gcc_msm8976_match_table,
+       },
+};
+
+static int __init gcc_msm8976_init(void)
+{
+       return platform_driver_register(&gcc_msm8976_driver);
+}
+core_initcall(gcc_msm8976_init);
+
+static void __exit gcc_msm8976_exit(void)
+{
+       platform_driver_unregister(&gcc_msm8976_driver);
+}
+module_exit(gcc_msm8976_exit);
+
+MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>");
+MODULE_LICENSE("GPL v2");
index 702a9bd..71aa630 100644 (file)
@@ -2,6 +2,7 @@
 /* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
  */
 
+#include <linux/clk-provider.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/err.h>
index 8fb6bd6..423627d 100644 (file)
@@ -2917,7 +2917,7 @@ static struct clk_branch gcc_cfg_noc_lpass_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_cfg_noc_lpass_clk",
-                       .ops = &clk_branch2_ops,
+                       .ops = &clk_branch2_aon_ops,
                },
        },
 };
diff --git a/drivers/clk/qcom/gcc-sdx65.c b/drivers/clk/qcom/gcc-sdx65.c
new file mode 100644 (file)
index 0000000..748ac15
--- /dev/null
@@ -0,0 +1,1611 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,gcc-sdx65.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+       P_BI_TCXO,
+       P_GPLL0_OUT_EVEN,
+       P_GPLL0_OUT_MAIN,
+       P_PCIE_PIPE_CLK,
+       P_SLEEP_CLK,
+       P_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK,
+};
+
+static struct clk_alpha_pll gpll0 = {
+       .offset = 0x0,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+       .clkr = {
+               .enable_reg = 0x6d000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll0",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_lucid_evo_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll0_out_even[] = {
+       { 0x1, 2 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll0_out_even = {
+       .offset = 0x0,
+       .post_div_shift = 10,
+       .post_div_table = post_div_table_gpll0_out_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll0_out_even",
+               .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_lucid_evo_ops,
+       },
+};
+
+static const struct parent_map gcc_parent_map_0[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_0[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+};
+
+static const struct clk_parent_data gcc_parent_data_0_ao[] = {
+       { .fw_name = "bi_tcxo_ao" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_2[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_SLEEP_CLK, 5 },
+       { P_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_2[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .fw_name = "sleep_clk" },
+       { .hw = &gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_3[] = {
+       { P_BI_TCXO, 0 },
+       { P_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data gcc_parent_data_3[] = {
+       { .fw_name = "bi_tcxo" },
+       { .fw_name = "sleep_clk" },
+};
+
+static const struct parent_map gcc_parent_map_4[] = {
+       { P_BI_TCXO, 2 },
+};
+
+static const struct parent_map gcc_parent_map_5[] = {
+       { P_PCIE_PIPE_CLK, 0 },
+       { P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_5[] = {
+       { .fw_name = "pcie_pipe_clk"},
+       { .fw_name = "bi_tcxo"},
+};
+
+static const struct parent_map gcc_parent_map_6[] = {
+       { P_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, 0 },
+       { P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_6[] = {
+       { .fw_name = "usb3_phy_wrapper_gcc_usb30_pipe_clk"},
+       { .fw_name = "bi_tcxo"},
+};
+
+static struct clk_regmap_mux gcc_pcie_aux_clk_src = {
+       .reg = 0x43060,
+       .shift = 0,
+       .width = 2,
+       .parent_map = gcc_parent_map_4,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_aux_clk_src",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_regmap_mux_closest_ops,
+               },
+       },
+};
+
+static struct clk_regmap_mux gcc_pcie_pipe_clk_src = {
+       .reg = 0x43044,
+       .shift = 0,
+       .width = 2,
+       .parent_map = gcc_parent_map_5,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_pipe_clk_src",
+                       .parent_data = gcc_parent_data_5,
+                       .num_parents = 2,
+                       .ops = &clk_regmap_mux_closest_ops,
+               },
+       },
+};
+
+static struct clk_regmap_mux gcc_usb3_phy_pipe_clk_src = {
+       .reg = 0x1706c,
+       .shift = 0,
+       .width = 2,
+       .parent_map = gcc_parent_map_6,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_phy_pipe_clk_src",
+                       .parent_data = gcc_parent_data_6,
+                       .num_parents = 2,
+                       .ops = &clk_regmap_mux_closest_ops,
+               },
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_blsp1_qup1_i2c_apps_clk_src[] = {
+       F(9600000, P_BI_TCXO, 2, 0, 0),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_blsp1_qup1_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x1c024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_blsp1_qup1_i2c_apps_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_blsp1_qup1_spi_apps_clk_src[] = {
+       F(960000, P_BI_TCXO, 10, 1, 2),
+       F(4800000, P_BI_TCXO, 4, 0, 0),
+       F(9600000, P_BI_TCXO, 2, 0, 0),
+       F(15000000, P_GPLL0_OUT_EVEN, 5, 1, 4),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(24000000, P_GPLL0_OUT_MAIN, 12.5, 1, 2),
+       F(25000000, P_GPLL0_OUT_MAIN, 12, 1, 2),
+       F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_blsp1_qup1_spi_apps_clk_src = {
+       .cmd_rcgr = 0x1c00c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_blsp1_qup1_spi_apps_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_blsp1_qup2_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x1e024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_blsp1_qup2_i2c_apps_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_blsp1_qup2_spi_apps_clk_src = {
+       .cmd_rcgr = 0x1e00c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_blsp1_qup2_spi_apps_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_blsp1_qup3_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x20024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_blsp1_qup3_i2c_apps_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_blsp1_qup3_spi_apps_clk_src = {
+       .cmd_rcgr = 0x2000c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_blsp1_qup3_spi_apps_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_blsp1_qup4_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x22024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_blsp1_qup4_i2c_apps_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_blsp1_qup4_spi_apps_clk_src = {
+       .cmd_rcgr = 0x2200c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_blsp1_qup4_spi_apps_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_blsp1_uart1_apps_clk_src[] = {
+       F(3686400, P_GPLL0_OUT_EVEN, 1, 192, 15625),
+       F(7372800, P_GPLL0_OUT_EVEN, 1, 384, 15625),
+       F(9600000, P_BI_TCXO, 2, 0, 0),
+       F(14745600, P_GPLL0_OUT_EVEN, 1, 768, 15625),
+       F(16000000, P_GPLL0_OUT_EVEN, 1, 4, 75),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(19354839, P_GPLL0_OUT_MAIN, 15.5, 1, 2),
+       F(20000000, P_GPLL0_OUT_MAIN, 15, 1, 2),
+       F(20689655, P_GPLL0_OUT_MAIN, 14.5, 1, 2),
+       F(21428571, P_GPLL0_OUT_MAIN, 14, 1, 2),
+       F(22222222, P_GPLL0_OUT_MAIN, 13.5, 1, 2),
+       F(23076923, P_GPLL0_OUT_MAIN, 13, 1, 2),
+       F(24000000, P_GPLL0_OUT_MAIN, 5, 1, 5),
+       F(25000000, P_GPLL0_OUT_MAIN, 12, 1, 2),
+       F(26086957, P_GPLL0_OUT_MAIN, 11.5, 1, 2),
+       F(27272727, P_GPLL0_OUT_MAIN, 11, 1, 2),
+       F(28571429, P_GPLL0_OUT_MAIN, 10.5, 1, 2),
+       F(32000000, P_GPLL0_OUT_MAIN, 1, 4, 75),
+       F(40000000, P_GPLL0_OUT_MAIN, 15, 0, 0),
+       F(46400000, P_GPLL0_OUT_MAIN, 1, 29, 375),
+       F(48000000, P_GPLL0_OUT_MAIN, 12.5, 0, 0),
+       F(51200000, P_GPLL0_OUT_MAIN, 1, 32, 375),
+       F(56000000, P_GPLL0_OUT_MAIN, 1, 7, 75),
+       F(58982400, P_GPLL0_OUT_MAIN, 1, 1536, 15625),
+       F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
+       F(63157895, P_GPLL0_OUT_MAIN, 9.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_blsp1_uart1_apps_clk_src = {
+       .cmd_rcgr = 0x1d00c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_blsp1_uart1_apps_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_blsp1_uart2_apps_clk_src = {
+       .cmd_rcgr = 0x1f00c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_blsp1_uart2_apps_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_blsp1_uart3_apps_clk_src = {
+       .cmd_rcgr = 0x2100c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_blsp1_uart3_apps_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_blsp1_uart4_apps_clk_src = {
+       .cmd_rcgr = 0x2300c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_blsp1_uart4_apps_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       F(133333333, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_cpuss_ahb_clk_src = {
+       .cmd_rcgr = 0x3000c,
+       .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_parent_data_0_ao,
+               .num_parents = 3,
+               .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(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 = 0x37004,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gcc_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_gp1_clk_src",
+               .parent_data = gcc_parent_data_2,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_gp2_clk_src = {
+       .cmd_rcgr = 0x38004,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gcc_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_gp2_clk_src",
+               .parent_data = gcc_parent_data_2,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_gp3_clk_src = {
+       .cmd_rcgr = 0x39004,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gcc_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_gp3_clk_src",
+               .parent_data = gcc_parent_data_2,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_pcie_aux_phy_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_pcie_aux_phy_clk_src = {
+       .cmd_rcgr = 0x43048,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_gcc_pcie_aux_phy_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_pcie_aux_phy_clk_src",
+               .parent_data = gcc_parent_data_3,
+               .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_pcie_rchng_phy_clk_src[] = {
+       F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_pcie_rchng_phy_clk_src = {
+       .cmd_rcgr = 0x43064,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gcc_pcie_rchng_phy_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_pcie_rchng_phy_clk_src",
+               .parent_data = gcc_parent_data_2,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = {
+       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 = 0x24010,
+       .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_parent_data_0,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = {
+       F(400000, P_BI_TCXO, 12, 1, 4),
+       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_sdcc1_apps_clk_src = {
+       .cmd_rcgr = 0x1a010,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_sdcc1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc1_apps_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_master_clk_src[] = {
+       F(200000000, P_GPLL0_OUT_EVEN, 1.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_usb30_master_clk_src = {
+       .cmd_rcgr = 0x17030,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_usb30_master_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb30_master_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_usb30_mock_utmi_clk_src = {
+       .cmd_rcgr = 0x17048,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_pcie_aux_phy_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb30_mock_utmi_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_usb3_phy_aux_clk_src[] = {
+       F(1000000, P_BI_TCXO, 1, 5, 96),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_usb3_phy_aux_clk_src = {
+       .cmd_rcgr = 0x17070,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_gcc_usb3_phy_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb3_phy_aux_clk_src",
+               .parent_data = gcc_parent_data_3,
+               .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_regmap_div gcc_cpuss_ahb_postdiv_clk_src = {
+       .reg = 0x30024,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gcc_cpuss_ahb_postdiv_clk_src",
+               .parent_data = &(const struct clk_parent_data){
+                       .hw = &gcc_cpuss_ahb_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_regmap_div gcc_usb30_mock_utmi_postdiv_clk_src = {
+       .reg = 0x17060,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gcc_usb30_mock_utmi_postdiv_clk_src",
+               .parent_data = &(const struct clk_parent_data){
+                       .hw = &gcc_usb30_mock_utmi_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_branch gcc_ahb_pcie_link_clk = {
+       .halt_reg = 0x2e004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2e004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ahb_pcie_link_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_ahb_clk = {
+       .halt_reg = 0x1b004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x6d008,
+               .enable_mask = BIT(14),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
+       .halt_reg = 0x1c008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1c008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup1_i2c_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_blsp1_qup1_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
+       .halt_reg = 0x1c004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1c004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup1_spi_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_blsp1_qup1_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
+       .halt_reg = 0x1e008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1e008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup2_i2c_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_blsp1_qup2_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
+       .halt_reg = 0x1e004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1e004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup2_spi_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_blsp1_qup2_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
+       .halt_reg = 0x20008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x20008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup3_i2c_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_blsp1_qup3_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
+       .halt_reg = 0x20004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x20004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup3_spi_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_blsp1_qup3_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
+       .halt_reg = 0x22008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x22008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup4_i2c_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_blsp1_qup4_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
+       .halt_reg = 0x22004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x22004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup4_spi_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_blsp1_qup4_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_sleep_clk = {
+       .halt_reg = 0x1b00c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x6d008,
+               .enable_mask = BIT(15),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart1_apps_clk = {
+       .halt_reg = 0x1d004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1d004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart1_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_blsp1_uart1_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart2_apps_clk = {
+       .halt_reg = 0x1f004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1f004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart2_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_blsp1_uart2_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart3_apps_clk = {
+       .halt_reg = 0x21004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x21004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart3_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_blsp1_uart3_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart4_apps_clk = {
+       .halt_reg = 0x23004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x23004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart4_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_blsp1_uart4_apps_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 = 0x27004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x27004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x6d008,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_boot_rom_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp1_clk = {
+       .halt_reg = 0x37000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x37000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp1_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x38000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x38000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp2_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x39000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x39000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp3_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_gp3_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_0_clkref_en = {
+       .halt_reg = 0x88004,
+       /*
+        * The clock controller does not handle the status bit for
+        * the clocks with gdscs(powerdomains) in hw controlled mode
+        * and hence avoid checking for the status bit of those clocks
+        * by setting the BRANCH_HALT_DELAY flag
+        */
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x88004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_clkref_en",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_aux_clk = {
+       .halt_reg = 0x43034,
+       /*
+        * The clock controller does not handle the status bit for
+        * the clocks with gdscs(powerdomains) in hw controlled mode
+        * and hence avoid checking for the status bit of those clocks
+        * by setting the BRANCH_HALT_DELAY flag
+        */
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0x43034,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x6d010,
+               .enable_mask = BIT(3),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_aux_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_pcie_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_cfg_ahb_clk = {
+       .halt_reg = 0x4302c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x4302c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x6d010,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_cfg_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_mstr_axi_clk = {
+       .halt_reg = 0x43024,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x43024,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x6d010,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_mstr_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_pipe_clk = {
+       .halt_reg = 0x4303c,
+       /*
+        * The clock controller does not handle the status bit for
+        * the clocks with gdscs(powerdomains) in hw controlled mode
+        * and hence avoid checking for the status bit of those clocks
+        * by setting the BRANCH_HALT_DELAY flag
+        */
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0x4303c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x6d010,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_pipe_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_pcie_pipe_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_rchng_phy_clk = {
+       .halt_reg = 0x43030,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x43030,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x6d010,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_rchng_phy_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_pcie_rchng_phy_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_sleep_clk = {
+       .halt_reg = 0x43038,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x43038,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x6d010,
+               .enable_mask = BIT(6),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_sleep_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_pcie_aux_phy_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_slv_axi_clk = {
+       .halt_reg = 0x4301c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x4301c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x6d010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_slv_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_slv_q2a_axi_clk = {
+       .halt_reg = 0x43018,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x43018,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x6d010,
+               .enable_mask = BIT(5),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_slv_q2a_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm2_clk = {
+       .halt_reg = 0x2400c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2400c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm2_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x24004,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x24004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x24004,
+               .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 = 0x24008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x24008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm_xo4_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_rx1_usb2_clkref_en = {
+       .halt_reg = 0x88008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x88008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_rx1_usb2_clkref_en",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+       .halt_reg = 0x1a00c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1a00c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+       .halt_reg = 0x1a004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1a004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_sdcc1_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_master_clk = {
+       .halt_reg = 0x17018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x17018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_master_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_usb30_master_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_mock_utmi_clk = {
+       .halt_reg = 0x1702c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1702c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_mock_utmi_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw =
+                                       &gcc_usb30_mock_utmi_postdiv_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_mstr_axi_clk = {
+       .halt_reg = 0x17020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x17020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_mstr_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_sleep_clk = {
+       .halt_reg = 0x17028,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x17028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_slv_ahb_clk = {
+       .halt_reg = 0x17024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x17024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_slv_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_phy_aux_clk = {
+       .halt_reg = 0x17064,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x17064,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_phy_aux_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_usb3_phy_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc usb30_gdsc = {
+       .gdscr = 0x17004,
+       .pd = {
+               .name = "usb30_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc pcie_gdsc = {
+       .gdscr = 0x43004,
+       .pd = {
+               .name = "pcie_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct clk_branch gcc_usb3_phy_pipe_clk = {
+       .halt_reg = 0x17068,
+       /*
+        * The clock controller does not handle the status bit for
+        * the clocks with gdscs(powerdomains) in hw controlled mode
+        * and hence avoid checking for the status bit of those clocks
+        * by setting the BRANCH_HALT_DELAY flag
+        */
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0x17068,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17068,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_phy_pipe_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_usb3_phy_pipe_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_prim_clkref_en = {
+       .halt_reg = 0x88000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x88000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_clkref_en",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = {
+       .halt_reg = 0x19008,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x19008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x19008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb_phy_cfg_ahb2phy_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_xo_div4_clk = {
+       .halt_reg = 0x2e010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2e010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_xo_div4_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_xo_pcie_link_clk = {
+       .halt_reg = 0x2e008,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x2e008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x2e008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_xo_pcie_link_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_regmap *gcc_sdx65_clocks[] = {
+       [GCC_AHB_PCIE_LINK_CLK] = &gcc_ahb_pcie_link_clk.clkr,
+       [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
+       [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP1_I2C_APPS_CLK_SRC] = &gcc_blsp1_qup1_i2c_apps_clk_src.clkr,
+       [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP1_SPI_APPS_CLK_SRC] = &gcc_blsp1_qup1_spi_apps_clk_src.clkr,
+       [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP2_I2C_APPS_CLK_SRC] = &gcc_blsp1_qup2_i2c_apps_clk_src.clkr,
+       [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP2_SPI_APPS_CLK_SRC] = &gcc_blsp1_qup2_spi_apps_clk_src.clkr,
+       [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP3_I2C_APPS_CLK_SRC] = &gcc_blsp1_qup3_i2c_apps_clk_src.clkr,
+       [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP3_SPI_APPS_CLK_SRC] = &gcc_blsp1_qup3_spi_apps_clk_src.clkr,
+       [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP4_I2C_APPS_CLK_SRC] = &gcc_blsp1_qup4_i2c_apps_clk_src.clkr,
+       [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP4_SPI_APPS_CLK_SRC] = &gcc_blsp1_qup4_spi_apps_clk_src.clkr,
+       [GCC_BLSP1_SLEEP_CLK] = &gcc_blsp1_sleep_clk.clkr,
+       [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
+       [GCC_BLSP1_UART1_APPS_CLK_SRC] = &gcc_blsp1_uart1_apps_clk_src.clkr,
+       [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,
+       [GCC_BLSP1_UART2_APPS_CLK_SRC] = &gcc_blsp1_uart2_apps_clk_src.clkr,
+       [GCC_BLSP1_UART3_APPS_CLK] = &gcc_blsp1_uart3_apps_clk.clkr,
+       [GCC_BLSP1_UART3_APPS_CLK_SRC] = &gcc_blsp1_uart3_apps_clk_src.clkr,
+       [GCC_BLSP1_UART4_APPS_CLK] = &gcc_blsp1_uart4_apps_clk.clkr,
+       [GCC_BLSP1_UART4_APPS_CLK_SRC] = &gcc_blsp1_uart4_apps_clk_src.clkr,
+       [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
+       [GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr,
+       [GCC_CPUSS_AHB_POSTDIV_CLK_SRC] = &gcc_cpuss_ahb_postdiv_clk_src.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_PCIE_0_CLKREF_EN] = &gcc_pcie_0_clkref_en.clkr,
+       [GCC_PCIE_AUX_CLK] = &gcc_pcie_aux_clk.clkr,
+       [GCC_PCIE_AUX_CLK_SRC] = &gcc_pcie_aux_clk_src.clkr,
+       [GCC_PCIE_AUX_PHY_CLK_SRC] = &gcc_pcie_aux_phy_clk_src.clkr,
+       [GCC_PCIE_CFG_AHB_CLK] = &gcc_pcie_cfg_ahb_clk.clkr,
+       [GCC_PCIE_MSTR_AXI_CLK] = &gcc_pcie_mstr_axi_clk.clkr,
+       [GCC_PCIE_PIPE_CLK] = &gcc_pcie_pipe_clk.clkr,
+       [GCC_PCIE_PIPE_CLK_SRC] = &gcc_pcie_pipe_clk_src.clkr,
+       [GCC_PCIE_RCHNG_PHY_CLK] = &gcc_pcie_rchng_phy_clk.clkr,
+       [GCC_PCIE_RCHNG_PHY_CLK_SRC] = &gcc_pcie_rchng_phy_clk_src.clkr,
+       [GCC_PCIE_SLEEP_CLK] = &gcc_pcie_sleep_clk.clkr,
+       [GCC_PCIE_SLV_AXI_CLK] = &gcc_pcie_slv_axi_clk.clkr,
+       [GCC_PCIE_SLV_Q2A_AXI_CLK] = &gcc_pcie_slv_q2a_axi_clk.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_RX1_USB2_CLKREF_EN] = &gcc_rx1_usb2_clkref_en.clkr,
+       [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
+       [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
+       [GCC_SDCC1_APPS_CLK_SRC] = &gcc_sdcc1_apps_clk_src.clkr,
+       [GCC_USB30_MASTER_CLK] = &gcc_usb30_master_clk.clkr,
+       [GCC_USB30_MASTER_CLK_SRC] = &gcc_usb30_master_clk_src.clkr,
+       [GCC_USB30_MOCK_UTMI_CLK] = &gcc_usb30_mock_utmi_clk.clkr,
+       [GCC_USB30_MOCK_UTMI_CLK_SRC] = &gcc_usb30_mock_utmi_clk_src.clkr,
+       [GCC_USB30_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_mock_utmi_postdiv_clk_src.clkr,
+       [GCC_USB30_MSTR_AXI_CLK] = &gcc_usb30_mstr_axi_clk.clkr,
+       [GCC_USB30_SLEEP_CLK] = &gcc_usb30_sleep_clk.clkr,
+       [GCC_USB30_SLV_AHB_CLK] = &gcc_usb30_slv_ahb_clk.clkr,
+       [GCC_USB3_PHY_AUX_CLK] = &gcc_usb3_phy_aux_clk.clkr,
+       [GCC_USB3_PHY_AUX_CLK_SRC] = &gcc_usb3_phy_aux_clk_src.clkr,
+       [GCC_USB3_PHY_PIPE_CLK] = &gcc_usb3_phy_pipe_clk.clkr,
+       [GCC_USB3_PHY_PIPE_CLK_SRC] = &gcc_usb3_phy_pipe_clk_src.clkr,
+       [GCC_USB3_PRIM_CLKREF_EN] = &gcc_usb3_prim_clkref_en.clkr,
+       [GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr,
+       [GCC_XO_DIV4_CLK] = &gcc_xo_div4_clk.clkr,
+       [GCC_XO_PCIE_LINK_CLK] = &gcc_xo_pcie_link_clk.clkr,
+       [GPLL0] = &gpll0.clkr,
+       [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr,
+};
+
+static const struct qcom_reset_map gcc_sdx65_resets[] = {
+       [GCC_BLSP1_QUP1_BCR] = { 0x1c000 },
+       [GCC_BLSP1_QUP2_BCR] = { 0x1e000 },
+       [GCC_BLSP1_QUP3_BCR] = { 0x20000 },
+       [GCC_BLSP1_QUP4_BCR] = { 0x22000 },
+       [GCC_BLSP1_UART1_BCR] = { 0x1d000 },
+       [GCC_BLSP1_UART2_BCR] = { 0x1f000 },
+       [GCC_BLSP1_UART3_BCR] = { 0x21000 },
+       [GCC_BLSP1_UART4_BCR] = { 0x23000 },
+       [GCC_PCIE_BCR] = { 0x43000 },
+       [GCC_PCIE_LINK_DOWN_BCR] = { 0x77000 },
+       [GCC_PCIE_NOCSR_COM_PHY_BCR] = { 0x78008 },
+       [GCC_PCIE_PHY_BCR] = { 0x44000 },
+       [GCC_PCIE_PHY_CFG_AHB_BCR] = { 0x78000 },
+       [GCC_PCIE_PHY_COM_BCR] = { 0x78004 },
+       [GCC_PCIE_PHY_NOCSR_COM_PHY_BCR] = { 0x7800c },
+       [GCC_PDM_BCR] = { 0x24000 },
+       [GCC_QUSB2PHY_BCR] = { 0x19000 },
+       [GCC_SDCC1_BCR] = { 0x1a000 },
+       [GCC_TCSR_PCIE_BCR] = { 0x57000 },
+       [GCC_USB30_BCR] = { 0x17000 },
+       [GCC_USB3_PHY_BCR] = { 0x18000 },
+       [GCC_USB3PHY_PHY_BCR] = { 0x18004 },
+       [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x19004 },
+};
+
+static struct gdsc *gcc_sdx65_gdscs[] = {
+       [USB30_GDSC] = &usb30_gdsc,
+       [PCIE_GDSC] = &pcie_gdsc,
+};
+
+static const struct regmap_config gcc_sdx65_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .max_register = 0x1f101c,
+       .fast_io = true,
+};
+
+static const struct qcom_cc_desc gcc_sdx65_desc = {
+       .config = &gcc_sdx65_regmap_config,
+       .clks = gcc_sdx65_clocks,
+       .num_clks = ARRAY_SIZE(gcc_sdx65_clocks),
+       .resets = gcc_sdx65_resets,
+       .num_resets = ARRAY_SIZE(gcc_sdx65_resets),
+       .gdscs = gcc_sdx65_gdscs,
+       .num_gdscs = ARRAY_SIZE(gcc_sdx65_gdscs),
+};
+
+static const struct of_device_id gcc_sdx65_match_table[] = {
+       { .compatible = "qcom,gcc-sdx65" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gcc_sdx65_match_table);
+
+static int gcc_sdx65_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+
+       regmap = qcom_cc_map(pdev, &gcc_sdx65_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+       /*
+        * Keep the clocks always-ON as they are critical to the functioning
+        * of the system:
+        * GCC_SYS_NOC_CPUSS_AHB_CLK, GCC_CPUSS_AHB_CLK, GCC_CPUSS_GNOC_CLK
+        */
+       regmap_update_bits(regmap, 0x6d008, BIT(0), BIT(0));
+       regmap_update_bits(regmap, 0x6d008, BIT(21), BIT(21));
+       regmap_update_bits(regmap, 0x6d008, BIT(22), BIT(22));
+
+       return qcom_cc_really_probe(pdev, &gcc_sdx65_desc, regmap);
+}
+
+static struct platform_driver gcc_sdx65_driver = {
+       .probe = gcc_sdx65_probe,
+       .driver = {
+               .name = "gcc-sdx65",
+               .of_match_table = gcc_sdx65_match_table,
+       },
+};
+
+static int __init gcc_sdx65_init(void)
+{
+       return platform_driver_register(&gcc_sdx65_driver);
+}
+subsys_initcall(gcc_sdx65_init);
+
+static void __exit gcc_sdx65_exit(void)
+{
+       platform_driver_unregister(&gcc_sdx65_driver);
+}
+module_exit(gcc_sdx65_exit);
+
+MODULE_DESCRIPTION("QTI GCC SDX65 Driver");
+MODULE_LICENSE("GPL v2");
index 3236706..a4f7fba 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright (c) 2021, Konrad Dybcio <konrad.dybcio@somainline.org>
  */
 
+#include <linux/clk-provider.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
index 6d0a9e2..c3731f9 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright (c) 2020-2021, Linaro Limited
  */
 
+#include <linux/clk-provider.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
diff --git a/drivers/clk/qcom/gcc-sm8450.c b/drivers/clk/qcom/gcc-sm8450.c
new file mode 100644 (file)
index 0000000..593a195
--- /dev/null
@@ -0,0 +1,3304 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021, Linaro Limited
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,gcc-sm8450.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+       P_BI_TCXO,
+       P_GCC_GPLL0_OUT_EVEN,
+       P_GCC_GPLL0_OUT_MAIN,
+       P_GCC_GPLL4_OUT_MAIN,
+       P_GCC_GPLL9_OUT_MAIN,
+       P_PCIE_0_PIPE_CLK,
+       P_PCIE_1_PHY_AUX_CLK,
+       P_PCIE_1_PIPE_CLK,
+       P_SLEEP_CLK,
+       P_UFS_PHY_RX_SYMBOL_0_CLK,
+       P_UFS_PHY_RX_SYMBOL_1_CLK,
+       P_UFS_PHY_TX_SYMBOL_0_CLK,
+       P_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK,
+};
+
+static struct clk_alpha_pll gcc_gpll0 = {
+       .offset = 0x0,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+       .clkr = {
+               .enable_reg = 0x62018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpll0",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_lucid_evo_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gcc_gpll0_out_even[] = {
+       { 0x1, 2 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gcc_gpll0_out_even = {
+       .offset = 0x0,
+       .post_div_shift = 10,
+       .post_div_table = post_div_table_gcc_gpll0_out_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_gcc_gpll0_out_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_gpll0_out_even",
+               .parent_data = &(const struct clk_parent_data){
+                       .hw = &gcc_gpll0.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_lucid_evo_ops,
+       },
+};
+
+static struct clk_alpha_pll gcc_gpll4 = {
+       .offset = 0x4000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+       .clkr = {
+               .enable_reg = 0x62018,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpll4",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_lucid_evo_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll gcc_gpll9 = {
+       .offset = 0x9000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+       .clkr = {
+               .enable_reg = 0x62018,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpll9",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_lucid_evo_ops,
+               },
+       },
+};
+
+static const struct parent_map gcc_parent_map_0[] = {
+       { P_BI_TCXO, 0 },
+       { P_GCC_GPLL0_OUT_MAIN, 1 },
+       { P_GCC_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_0[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gcc_gpll0.clkr.hw },
+       { .hw = &gcc_gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_1[] = {
+       { P_BI_TCXO, 0 },
+       { P_GCC_GPLL0_OUT_MAIN, 1 },
+       { P_SLEEP_CLK, 5 },
+       { P_GCC_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_1[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gcc_gpll0.clkr.hw },
+       { .fw_name = "sleep_clk" },
+       { .hw = &gcc_gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_2[] = {
+       { P_BI_TCXO, 0 },
+       { P_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data gcc_parent_data_2[] = {
+       { .fw_name = "bi_tcxo" },
+       { .fw_name = "sleep_clk" },
+};
+
+static const struct parent_map gcc_parent_map_3[] = {
+       { P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data gcc_parent_data_3[] = {
+       { .fw_name = "bi_tcxo" },
+};
+
+static const struct parent_map gcc_parent_map_4[] = {
+       { P_PCIE_0_PIPE_CLK, 0 },
+       { P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_4[] = {
+       { .fw_name = "pcie_0_pipe_clk", },
+       { .fw_name = "bi_tcxo", },
+};
+
+static const struct parent_map gcc_parent_map_5[] = {
+       { P_PCIE_1_PHY_AUX_CLK, 0 },
+       { P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_5[] = {
+       { .fw_name = "pcie_1_phy_aux_clk" },
+       { .fw_name = "bi_tcxo" },
+};
+
+static const struct parent_map gcc_parent_map_6[] = {
+       { P_PCIE_1_PIPE_CLK, 0 },
+       { P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_6[] = {
+       { .fw_name = "pcie_1_pipe_clk" },
+       { .fw_name = "bi_tcxo" },
+};
+
+static const struct parent_map gcc_parent_map_7[] = {
+       { P_BI_TCXO, 0 },
+       { P_GCC_GPLL0_OUT_MAIN, 1 },
+       { P_GCC_GPLL9_OUT_MAIN, 2 },
+       { P_GCC_GPLL4_OUT_MAIN, 5 },
+       { P_GCC_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_7[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gcc_gpll0.clkr.hw },
+       { .hw = &gcc_gpll9.clkr.hw },
+       { .hw = &gcc_gpll4.clkr.hw },
+       { .hw = &gcc_gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_8[] = {
+       { P_UFS_PHY_RX_SYMBOL_0_CLK, 0 },
+       { P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_8[] = {
+       { .fw_name = "ufs_phy_rx_symbol_0_clk" },
+       { .fw_name = "bi_tcxo" },
+};
+
+static const struct parent_map gcc_parent_map_9[] = {
+       { P_UFS_PHY_RX_SYMBOL_1_CLK, 0 },
+       { P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_9[] = {
+       { .fw_name = "ufs_phy_rx_symbol_1_clk" },
+       { .fw_name = "bi_tcxo" },
+};
+
+static const struct parent_map gcc_parent_map_10[] = {
+       { P_UFS_PHY_TX_SYMBOL_0_CLK, 0 },
+       { P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_10[] = {
+       { .fw_name = "ufs_phy_tx_symbol_0_clk" },
+       { .fw_name = "bi_tcxo" },
+};
+
+static const struct parent_map gcc_parent_map_11[] = {
+       { P_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, 0 },
+       { P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_11[] = {
+       { .fw_name = "usb3_phy_wrapper_gcc_usb30_pipe_clk" },
+       { .fw_name = "bi_tcxo" },
+};
+
+static struct clk_regmap_mux gcc_pcie_0_pipe_clk_src = {
+       .reg = 0x7b060,
+       .shift = 0,
+       .width = 2,
+       .parent_map = gcc_parent_map_4,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_pipe_clk_src",
+                       .parent_data = gcc_parent_data_4,
+                       .num_parents = ARRAY_SIZE(gcc_parent_data_4),
+                       .ops = &clk_regmap_mux_closest_ops,
+               },
+       },
+};
+
+static struct clk_regmap_mux gcc_pcie_1_phy_aux_clk_src = {
+       .reg = 0x9d080,
+       .shift = 0,
+       .width = 2,
+       .parent_map = gcc_parent_map_5,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_phy_aux_clk_src",
+                       .parent_data = gcc_parent_data_5,
+                       .num_parents = ARRAY_SIZE(gcc_parent_data_5),
+                       .ops = &clk_regmap_mux_closest_ops,
+               },
+       },
+};
+
+static struct clk_regmap_mux gcc_pcie_1_pipe_clk_src = {
+       .reg = 0x9d064,
+       .shift = 0,
+       .width = 2,
+       .parent_map = gcc_parent_map_6,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_pipe_clk_src",
+                       .parent_data = gcc_parent_data_6,
+                       .num_parents = ARRAY_SIZE(gcc_parent_data_6),
+                       .ops = &clk_regmap_mux_closest_ops,
+               },
+       },
+};
+
+static struct clk_regmap_mux gcc_ufs_phy_rx_symbol_0_clk_src = {
+       .reg = 0x87060,
+       .shift = 0,
+       .width = 2,
+       .parent_map = gcc_parent_map_8,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_rx_symbol_0_clk_src",
+                       .parent_data = gcc_parent_data_8,
+                       .num_parents = ARRAY_SIZE(gcc_parent_data_8),
+                       .ops = &clk_regmap_mux_closest_ops,
+               },
+       },
+};
+
+static struct clk_regmap_mux gcc_ufs_phy_rx_symbol_1_clk_src = {
+       .reg = 0x870d0,
+       .shift = 0,
+       .width = 2,
+       .parent_map = gcc_parent_map_9,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_rx_symbol_1_clk_src",
+                       .parent_data = gcc_parent_data_9,
+                       .num_parents = ARRAY_SIZE(gcc_parent_data_9),
+                       .ops = &clk_regmap_mux_closest_ops,
+               },
+       },
+};
+
+static struct clk_regmap_mux gcc_ufs_phy_tx_symbol_0_clk_src = {
+       .reg = 0x87050,
+       .shift = 0,
+       .width = 2,
+       .parent_map = gcc_parent_map_10,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_tx_symbol_0_clk_src",
+                       .parent_data = gcc_parent_data_10,
+                       .num_parents = ARRAY_SIZE(gcc_parent_data_10),
+                       .ops = &clk_regmap_mux_closest_ops,
+               },
+       },
+};
+
+static struct clk_regmap_mux gcc_usb3_prim_phy_pipe_clk_src = {
+       .reg = 0x49068,
+       .shift = 0,
+       .width = 2,
+       .parent_map = gcc_parent_map_11,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_phy_pipe_clk_src",
+                       .parent_data = gcc_parent_data_11,
+                       .num_parents = ARRAY_SIZE(gcc_parent_data_11),
+                       .ops = &clk_regmap_mux_closest_ops,
+               },
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = {
+       F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0),
+       F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+       F(200000000, P_GCC_GPLL0_OUT_MAIN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_gp1_clk_src = {
+       .cmd_rcgr = 0x74004,
+       .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_parent_data_1,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_gp2_clk_src = {
+       .cmd_rcgr = 0x75004,
+       .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_parent_data_1,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_gp3_clk_src = {
+       .cmd_rcgr = 0x76004,
+       .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_parent_data_1,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_pcie_0_aux_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_pcie_0_aux_clk_src = {
+       .cmd_rcgr = 0x7b064,
+       .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_parent_data_2,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_2),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_pcie_0_phy_rchng_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_pcie_0_phy_rchng_clk_src = {
+       .cmd_rcgr = 0x7b048,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_pcie_0_phy_rchng_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_pcie_1_aux_clk_src = {
+       .cmd_rcgr = 0x9d068,
+       .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_parent_data_2,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_2),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_pcie_1_phy_rchng_clk_src = {
+       .cmd_rcgr = 0x9d04c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_pcie_1_phy_rchng_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = {
+       F(60000000, P_GCC_GPLL0_OUT_MAIN, 10, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_pdm2_clk_src = {
+       .cmd_rcgr = 0x43010,
+       .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_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
+       F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625),
+       F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625),
+       F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75),
+       F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25),
+       F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75),
+       F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15),
+       F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25),
+       F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+       { }
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s0_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
+       .cmd_rcgr = 0x27014,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s1_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
+       .cmd_rcgr = 0x27148,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s2_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
+       .cmd_rcgr = 0x2727c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s3_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
+       .cmd_rcgr = 0x273b0,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s4_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
+       .cmd_rcgr = 0x274e4,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s5_clk_src[] = {
+       F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625),
+       F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625),
+       F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75),
+       F(37500000, P_GCC_GPLL0_OUT_EVEN, 8, 0, 0),
+       F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25),
+       F(50000000, P_GCC_GPLL0_OUT_MAIN, 12, 0, 0),
+       { }
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s5_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
+       .cmd_rcgr = 0x27618,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s5_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s6_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = {
+       .cmd_rcgr = 0x2774c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s7_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = {
+       .cmd_rcgr = 0x27880,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap1_s0_clk_src[] = {
+       F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625),
+       F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625),
+       F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75),
+       F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25),
+       F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75),
+       F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15),
+       F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25),
+       F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+       F(102400000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 375),
+       F(112000000, P_GCC_GPLL0_OUT_EVEN, 1, 28, 75),
+       F(117964800, P_GCC_GPLL0_OUT_EVEN, 1, 6144, 15625),
+       F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0),
+       { }
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = {
+       .name = "gcc_qupv3_wrap1_s0_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
+       .cmd_rcgr = 0x28014,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = {
+       .name = "gcc_qupv3_wrap1_s1_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
+       .cmd_rcgr = 0x28148,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = {
+       .name = "gcc_qupv3_wrap1_s2_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
+       .cmd_rcgr = 0x2827c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = {
+       .name = "gcc_qupv3_wrap1_s3_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
+       .cmd_rcgr = 0x283b0,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = {
+       .name = "gcc_qupv3_wrap1_s4_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
+       .cmd_rcgr = 0x284e4,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = {
+       .name = "gcc_qupv3_wrap1_s5_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
+       .cmd_rcgr = 0x28618,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = {
+       .name = "gcc_qupv3_wrap1_s6_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = {
+       .cmd_rcgr = 0x2874c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s6_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s0_clk_src_init = {
+       .name = "gcc_qupv3_wrap2_s0_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = {
+       .cmd_rcgr = 0x2e014,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap2_s0_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s1_clk_src_init = {
+       .name = "gcc_qupv3_wrap2_s1_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = {
+       .cmd_rcgr = 0x2e148,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap2_s1_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s2_clk_src_init = {
+       .name = "gcc_qupv3_wrap2_s2_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = {
+       .cmd_rcgr = 0x2e27c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap2_s2_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s3_clk_src_init = {
+       .name = "gcc_qupv3_wrap2_s3_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = {
+       .cmd_rcgr = 0x2e3b0,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap2_s3_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s4_clk_src_init = {
+       .name = "gcc_qupv3_wrap2_s4_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = {
+       .cmd_rcgr = 0x2e4e4,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap2_s4_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s5_clk_src_init = {
+       .name = "gcc_qupv3_wrap2_s5_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = {
+       .cmd_rcgr = 0x2e618,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap2_s5_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s6_clk_src_init = {
+       .name = "gcc_qupv3_wrap2_s6_clk_src",
+       .parent_data = gcc_parent_data_0,
+       .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+       .flags = CLK_SET_RATE_PARENT,
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s6_clk_src = {
+       .cmd_rcgr = 0x2e74c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap2_s6_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
+       F(400000, P_BI_TCXO, 12, 1, 4),
+       F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0),
+       F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0),
+       F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0),
+       F(202000000, P_GCC_GPLL9_OUT_MAIN, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
+       .cmd_rcgr = 0x24014,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_7,
+       .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc2_apps_clk_src",
+               .parent_data = gcc_parent_data_7,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_7),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc4_apps_clk_src[] = {
+       F(400000, P_BI_TCXO, 12, 1, 4),
+       F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0),
+       F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdcc4_apps_clk_src = {
+       .cmd_rcgr = 0x26014,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_sdcc4_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc4_apps_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
+       F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0),
+       F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(150000000, P_GCC_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(300000000, P_GCC_GPLL0_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = {
+       .cmd_rcgr = 0x8702c,
+       .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_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+       F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(150000000, P_GCC_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(300000000, P_GCC_GPLL0_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = {
+       .cmd_rcgr = 0x87074,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_ice_core_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_phy_aux_clk_src[] = {
+       F(9600000, P_BI_TCXO, 2, 0, 0),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = {
+       .cmd_rcgr = 0x870a8,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_phy_aux_clk_src",
+               .parent_data = gcc_parent_data_3,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_3),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = {
+       .cmd_rcgr = 0x8708c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_unipro_core_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
+       F(66666667, P_GCC_GPLL0_OUT_EVEN, 4.5, 0, 0),
+       F(133333333, P_GCC_GPLL0_OUT_MAIN, 4.5, 0, 0),
+       F(200000000, P_GCC_GPLL0_OUT_MAIN, 3, 0, 0),
+       F(240000000, P_GCC_GPLL0_OUT_MAIN, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_usb30_prim_master_clk_src = {
+       .cmd_rcgr = 0x49028,
+       .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_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = {
+       .cmd_rcgr = 0x49040,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb30_prim_mock_utmi_clk_src",
+               .parent_data = gcc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = {
+       .cmd_rcgr = 0x4906c,
+       .mnd_width = 0,
+       .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_usb3_prim_phy_aux_clk_src",
+               .parent_data = gcc_parent_data_2,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_2),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_regmap_div gcc_usb30_prim_mock_utmi_postdiv_clk_src = {
+       .reg = 0x49058,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gcc_usb30_prim_mock_utmi_postdiv_clk_src",
+               .parent_data = &(const struct clk_parent_data){
+                       .hw = &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_branch gcc_aggre_noc_pcie_0_axi_clk = {
+       .halt_reg = 0x7b08c,
+       .halt_check = BRANCH_HALT_SKIP,
+       .hwcg_reg = 0x7b08c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x62000,
+               .enable_mask = BIT(12),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre_noc_pcie_0_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_aggre_noc_pcie_1_axi_clk = {
+       .halt_reg = 0x9d098,
+       .halt_check = BRANCH_HALT_SKIP,
+       .hwcg_reg = 0x9d098,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x62000,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre_noc_pcie_1_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_aggre_ufs_phy_axi_clk = {
+       .halt_reg = 0x870d4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x870d4,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x870d4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre_ufs_phy_axi_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x870d4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x870d4,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x870d4,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre_ufs_phy_axi_hw_ctl_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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_usb3_prim_axi_clk = {
+       .halt_reg = 0x49088,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x49088,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x49088,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre_usb3_prim_axi_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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_boot_rom_ahb_clk = {
+       .halt_reg = 0x48004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x48004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x62000,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_boot_rom_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camera_hf_axi_clk = {
+       .halt_reg = 0x36010,
+       .halt_check = BRANCH_HALT_SKIP,
+       .hwcg_reg = 0x36010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x36010,
+               .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 = 0x36018,
+       .halt_check = BRANCH_HALT_SKIP,
+       .hwcg_reg = 0x36018,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x36018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camera_sf_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cfg_noc_pcie_anoc_ahb_clk = {
+       .halt_reg = 0x20030,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x20030,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x62000,
+               .enable_mask = BIT(20),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cfg_noc_pcie_anoc_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = {
+       .halt_reg = 0x49084,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x49084,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x49084,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cfg_noc_usb3_prim_axi_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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_ddrss_gpu_axi_clk = {
+       .halt_reg = 0x81154,
+       .halt_check = BRANCH_HALT_SKIP,
+       .hwcg_reg = 0x81154,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x81154,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ddrss_gpu_axi_clk",
+                       .ops = &clk_branch2_aon_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ddrss_pcie_sf_tbu_clk = {
+       .halt_reg = 0x9d094,
+       .halt_check = BRANCH_HALT_SKIP,
+       .hwcg_reg = 0x9d094,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x62000,
+               .enable_mask = BIT(19),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ddrss_pcie_sf_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_hf_axi_clk = {
+       .halt_reg = 0x3700c,
+       .halt_check = BRANCH_HALT_SKIP,
+       .hwcg_reg = 0x3700c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3700c,
+               .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 = 0x37014,
+       .halt_check = BRANCH_HALT_SKIP,
+       .hwcg_reg = 0x37014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x37014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_sf_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_eusb3_0_clkref_en = {
+       .halt_reg = 0x9c00c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x9c00c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_eusb3_0_clkref_en",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp1_clk = {
+       .halt_reg = 0x74000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x74000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp1_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x75000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x75000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp2_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x76000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x76000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp3_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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_gpll0_clk_src = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x62000,
+               .enable_mask = BIT(15),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_gpll0_clk_src",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_gpll0.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_gpll0_div_clk_src = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x62000,
+               .enable_mask = BIT(16),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_gpll0_div_clk_src",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_gpll0_out_even.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_memnoc_gfx_clk = {
+       .halt_reg = 0x81010,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x81010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x81010,
+               .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 = 0x81018,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x81018,
+               .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_pcie_0_aux_clk = {
+       .halt_reg = 0x7b034,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(3),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_aux_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x7b030,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x7b030,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .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_en = {
+       .halt_reg = 0x9c004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x9c004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_clkref_en",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_0_mstr_axi_clk = {
+       .halt_reg = 0x7b028,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_mstr_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_0_phy_rchng_clk = {
+       .halt_reg = 0x7b044,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62000,
+               .enable_mask = BIT(22),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_phy_rchng_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_pcie_0_phy_rchng_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_0_pipe_clk = {
+       .halt_reg = 0x7b03c,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_pipe_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_pcie_0_pipe_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_0_slv_axi_clk = {
+       .halt_reg = 0x7b020,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x7b020,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .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 = 0x7b01c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .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 = 0x9d030,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62000,
+               .enable_mask = BIT(29),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_aux_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x9d02c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x9d02c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x62000,
+               .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_en = {
+       .halt_reg = 0x9c008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x9c008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_clkref_en",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_1_mstr_axi_clk = {
+       .halt_reg = 0x9d024,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x62000,
+               .enable_mask = BIT(27),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_mstr_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_1_phy_aux_clk = {
+       .halt_reg = 0x9d038,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62000,
+               .enable_mask = BIT(24),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_phy_aux_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_pcie_1_phy_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_1_phy_rchng_clk = {
+       .halt_reg = 0x9d048,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62000,
+               .enable_mask = BIT(23),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_phy_rchng_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_pcie_1_phy_rchng_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_1_pipe_clk = {
+       .halt_reg = 0x9d040,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x62000,
+               .enable_mask = BIT(30),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_pipe_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_pcie_1_pipe_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_1_slv_axi_clk = {
+       .halt_reg = 0x9d01c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x9d01c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x62000,
+               .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 = 0x9d018,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62000,
+               .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_pdm2_clk = {
+       .halt_reg = 0x4300c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4300c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm2_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x43004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x43004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x43004,
+               .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 = 0x43008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x43008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm_xo4_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = {
+       .halt_reg = 0x36008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x36008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x36008,
+               .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 = 0x3600c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x3600c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3600c,
+               .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 = 0x37008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x37008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x37008,
+               .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_gpu_ahb_clk = {
+       .halt_reg = 0x81008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x81008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x81008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_gpu_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_pcie_ahb_clk = {
+       .halt_reg = 0x7b018,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x7b018,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7b018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_pcie_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_video_cv_cpu_ahb_clk = {
+       .halt_reg = 0x42014,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x42014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x42014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_video_cv_cpu_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_video_cvp_ahb_clk = {
+       .halt_reg = 0x42008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x42008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x42008,
+               .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_v_cpu_ahb_clk = {
+       .halt_reg = 0x42010,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x42010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x42010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_video_v_cpu_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_video_vcodec_ahb_clk = {
+       .halt_reg = 0x4200c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x4200c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x4200c,
+               .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_qupv3_wrap0_core_2x_clk = {
+       .halt_reg = 0x3300c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_core_2x_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_core_clk = {
+       .halt_reg = 0x33000,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(8),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_core_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s0_clk = {
+       .halt_reg = 0x2700c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s0_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x27140,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s1_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x27274,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(12),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s2_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x273a8,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s3_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x274dc,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(14),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s4_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x27610,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(15),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s5_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x27744,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(16),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s6_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x27878,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(17),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s7_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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_core_2x_clk = {
+       .halt_reg = 0x3314c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(18),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_core_2x_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_core_clk = {
+       .halt_reg = 0x33140,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(19),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_core_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s0_clk = {
+       .halt_reg = 0x2800c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(22),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s0_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x28140,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(23),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s1_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x28274,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(24),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s2_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x283a8,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(25),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s3_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x284dc,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(26),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s4_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x28610,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(27),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s5_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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_wrap1_s6_clk = {
+       .halt_reg = 0x28744,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .enable_mask = BIT(28),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s6_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_qupv3_wrap1_s6_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap2_core_2x_clk = {
+       .halt_reg = 0x3328c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62010,
+               .enable_mask = BIT(3),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap2_core_2x_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap2_core_clk = {
+       .halt_reg = 0x33280,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap2_core_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap2_s0_clk = {
+       .halt_reg = 0x2e00c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62010,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap2_s0_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x2e140,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62010,
+               .enable_mask = BIT(5),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap2_s1_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x2e274,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62010,
+               .enable_mask = BIT(6),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap2_s2_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x2e3a8,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62010,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap2_s3_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x2e4dc,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62010,
+               .enable_mask = BIT(8),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap2_s4_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x2e610,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62010,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap2_s5_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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_wrap2_s6_clk = {
+       .halt_reg = 0x2e744,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x62010,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap2_s6_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_qupv3_wrap2_s6_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 = 0x27004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x27004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .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 = 0x27008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x27008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .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 = 0x28004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x28004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .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 = 0x28008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x28008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x62008,
+               .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 = 0x2e004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x2e004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x62010,
+               .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 = 0x2e008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x2e008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x62010,
+               .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 = 0x2400c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2400c,
+               .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 = 0x24004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x24004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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_sdcc2_at_clk = {
+       .halt_reg = 0x24010,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x24010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x24010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_at_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc4_ahb_clk = {
+       .halt_reg = 0x2600c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2600c,
+               .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 = 0x26004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x26004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc4_apps_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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_sdcc4_at_clk = {
+       .halt_reg = 0x26010,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x26010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x26010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc4_at_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_0_clkref_en = {
+       .halt_reg = 0x9c000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x9c000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_0_clkref_en",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_ahb_clk = {
+       .halt_reg = 0x87020,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x87020,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x87020,
+               .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 = 0x87018,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x87018,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x87018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_axi_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x87018,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x87018,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x87018,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_axi_hw_ctl_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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_ice_core_clk = {
+       .halt_reg = 0x8706c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x8706c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x8706c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_ice_core_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x8706c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x8706c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x8706c,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_ice_core_hw_ctl_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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_phy_aux_clk = {
+       .halt_reg = 0x870a4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x870a4,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x870a4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_phy_aux_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x870a4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x870a4,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x870a4,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_phy_aux_hw_ctl_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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_rx_symbol_0_clk = {
+       .halt_reg = 0x87028,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x87028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_rx_symbol_0_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_ufs_phy_rx_symbol_0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = {
+       .halt_reg = 0x870c0,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x870c0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_rx_symbol_1_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_ufs_phy_rx_symbol_1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = {
+       .halt_reg = 0x87024,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x87024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_tx_symbol_0_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_ufs_phy_tx_symbol_0_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_clk = {
+       .halt_reg = 0x87064,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x87064,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x87064,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_unipro_core_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x87064,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x87064,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x87064,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_unipro_core_hw_ctl_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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_usb30_prim_master_clk = {
+       .halt_reg = 0x49018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x49018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_prim_master_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x49024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x49024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_prim_mock_utmi_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_usb30_prim_mock_utmi_postdiv_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 = 0x49020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x49020,
+               .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_usb3_0_clkref_en = {
+       .halt_reg = 0x9c010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x9c010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_0_clkref_en",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_prim_phy_aux_clk = {
+       .halt_reg = 0x4905c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4905c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_phy_aux_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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 = 0x49060,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x49060,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_phy_com_aux_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .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_pipe_clk = {
+       .halt_reg = 0x49064,
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0x49064,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x49064,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_phy_pipe_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &gcc_usb3_prim_phy_pipe_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_axi0_clk = {
+       .halt_reg = 0x42018,
+       .halt_check = BRANCH_HALT_SKIP,
+       .hwcg_reg = 0x42018,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x42018,
+               .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 = 0x42020,
+       .halt_check = BRANCH_HALT_SKIP,
+       .hwcg_reg = 0x42020,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x42020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_axi1_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc pcie_0_gdsc = {
+       .gdscr = 0x7b004,
+       .pd = {
+               .name = "pcie_0_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc pcie_1_gdsc = {
+       .gdscr = 0x9d004,
+       .pd = {
+               .name = "pcie_1_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc ufs_phy_gdsc = {
+       .gdscr = 0x87004,
+       .pd = {
+               .name = "ufs_phy_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc usb30_prim_gdsc = {
+       .gdscr = 0x49004,
+       .pd = {
+               .name = "usb30_prim_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct clk_regmap *gcc_sm8450_clocks[] = {
+       [GCC_AGGRE_NOC_PCIE_0_AXI_CLK] = &gcc_aggre_noc_pcie_0_axi_clk.clkr,
+       [GCC_AGGRE_NOC_PCIE_1_AXI_CLK] = &gcc_aggre_noc_pcie_1_axi_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_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_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_CFG_NOC_PCIE_ANOC_AHB_CLK] = &gcc_cfg_noc_pcie_anoc_ahb_clk.clkr,
+       [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr,
+       [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr,
+       [GCC_DDRSS_PCIE_SF_TBU_CLK] = &gcc_ddrss_pcie_sf_tbu_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_EUSB3_0_CLKREF_EN] = &gcc_eusb3_0_clkref_en.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_GPLL0] = &gcc_gpll0.clkr,
+       [GCC_GPLL0_OUT_EVEN] = &gcc_gpll0_out_even.clkr,
+       [GCC_GPLL4] = &gcc_gpll4.clkr,
+       [GCC_GPLL9] = &gcc_gpll9.clkr,
+       [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr,
+       [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.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_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_EN] = &gcc_pcie_0_clkref_en.clkr,
+       [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr,
+       [GCC_PCIE_0_PHY_RCHNG_CLK] = &gcc_pcie_0_phy_rchng_clk.clkr,
+       [GCC_PCIE_0_PHY_RCHNG_CLK_SRC] = &gcc_pcie_0_phy_rchng_clk_src.clkr,
+       [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr,
+       [GCC_PCIE_0_PIPE_CLK_SRC] = &gcc_pcie_0_pipe_clk_src.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_EN] = &gcc_pcie_1_clkref_en.clkr,
+       [GCC_PCIE_1_MSTR_AXI_CLK] = &gcc_pcie_1_mstr_axi_clk.clkr,
+       [GCC_PCIE_1_PHY_AUX_CLK] = &gcc_pcie_1_phy_aux_clk.clkr,
+       [GCC_PCIE_1_PHY_AUX_CLK_SRC] = &gcc_pcie_1_phy_aux_clk_src.clkr,
+       [GCC_PCIE_1_PHY_RCHNG_CLK] = &gcc_pcie_1_phy_rchng_clk.clkr,
+       [GCC_PCIE_1_PHY_RCHNG_CLK_SRC] = &gcc_pcie_1_phy_rchng_clk_src.clkr,
+       [GCC_PCIE_1_PIPE_CLK] = &gcc_pcie_1_pipe_clk.clkr,
+       [GCC_PCIE_1_PIPE_CLK_SRC] = &gcc_pcie_1_pipe_clk_src.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_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_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_GPU_AHB_CLK] = &gcc_qmip_gpu_ahb_clk.clkr,
+       [GCC_QMIP_PCIE_AHB_CLK] = &gcc_qmip_pcie_ahb_clk.clkr,
+       [GCC_QMIP_VIDEO_CV_CPU_AHB_CLK] = &gcc_qmip_video_cv_cpu_ahb_clk.clkr,
+       [GCC_QMIP_VIDEO_CVP_AHB_CLK] = &gcc_qmip_video_cvp_ahb_clk.clkr,
+       [GCC_QMIP_VIDEO_V_CPU_AHB_CLK] = &gcc_qmip_video_v_cpu_ahb_clk.clkr,
+       [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP0_CORE_2X_CLK] = &gcc_qupv3_wrap0_core_2x_clk.clkr,
+       [GCC_QUPV3_WRAP0_CORE_CLK] = &gcc_qupv3_wrap0_core_clk.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_CORE_2X_CLK] = &gcc_qupv3_wrap1_core_2x_clk.clkr,
+       [GCC_QUPV3_WRAP1_CORE_CLK] = &gcc_qupv3_wrap1_core_clk.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_WRAP1_S6_CLK] = &gcc_qupv3_wrap1_s6_clk.clkr,
+       [GCC_QUPV3_WRAP1_S6_CLK_SRC] = &gcc_qupv3_wrap1_s6_clk_src.clkr,
+       [GCC_QUPV3_WRAP2_CORE_2X_CLK] = &gcc_qupv3_wrap2_core_2x_clk.clkr,
+       [GCC_QUPV3_WRAP2_CORE_CLK] = &gcc_qupv3_wrap2_core_clk.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_WRAP2_S6_CLK] = &gcc_qupv3_wrap2_s6_clk.clkr,
+       [GCC_QUPV3_WRAP2_S6_CLK_SRC] = &gcc_qupv3_wrap2_s6_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_SDCC2_AT_CLK] = &gcc_sdcc2_at_clk.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_SDCC4_AT_CLK] = &gcc_sdcc4_at_clk.clkr,
+       [GCC_UFS_0_CLKREF_EN] = &gcc_ufs_0_clkref_en.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_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr,
+       [GCC_UFS_PHY_RX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_rx_symbol_0_clk_src.clkr,
+       [GCC_UFS_PHY_RX_SYMBOL_1_CLK] = &gcc_ufs_phy_rx_symbol_1_clk.clkr,
+       [GCC_UFS_PHY_RX_SYMBOL_1_CLK_SRC] = &gcc_ufs_phy_rx_symbol_1_clk_src.clkr,
+       [GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr,
+       [GCC_UFS_PHY_TX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_tx_symbol_0_clk_src.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_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr,
+       [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr,
+       [GCC_USB3_0_CLKREF_EN] = &gcc_usb3_0_clkref_en.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_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr,
+       [GCC_USB3_PRIM_PHY_PIPE_CLK_SRC] = &gcc_usb3_prim_phy_pipe_clk_src.clkr,
+       [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr,
+       [GCC_VIDEO_AXI1_CLK] = &gcc_video_axi1_clk.clkr,
+};
+
+static const struct qcom_reset_map gcc_sm8450_resets[] = {
+       [GCC_CAMERA_BCR] = { 0x36000 },
+       [GCC_DISPLAY_BCR] = { 0x37000 },
+       [GCC_GPU_BCR] = { 0x81000 },
+       [GCC_PCIE_0_BCR] = { 0x7b000 },
+       [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x7c014 },
+       [GCC_PCIE_0_NOCSR_COM_PHY_BCR] = { 0x7c020 },
+       [GCC_PCIE_0_PHY_BCR] = { 0x7c01c },
+       [GCC_PCIE_0_PHY_NOCSR_COM_PHY_BCR] = { 0x7c028 },
+       [GCC_PCIE_1_BCR] = { 0x9d000 },
+       [GCC_PCIE_1_LINK_DOWN_BCR] = { 0x9e014 },
+       [GCC_PCIE_1_NOCSR_COM_PHY_BCR] = { 0x9e020 },
+       [GCC_PCIE_1_PHY_BCR] = { 0x9e01c },
+       [GCC_PCIE_1_PHY_NOCSR_COM_PHY_BCR] = { 0x9e000 },
+       [GCC_PCIE_PHY_BCR] = { 0x7f000 },
+       [GCC_PCIE_PHY_CFG_AHB_BCR] = { 0x7f00c },
+       [GCC_PCIE_PHY_COM_BCR] = { 0x7f010 },
+       [GCC_PDM_BCR] = { 0x43000 },
+       [GCC_QUPV3_WRAPPER_0_BCR] = { 0x27000 },
+       [GCC_QUPV3_WRAPPER_1_BCR] = { 0x28000 },
+       [GCC_QUPV3_WRAPPER_2_BCR] = { 0x2e000 },
+       [GCC_QUSB2PHY_PRIM_BCR] = { 0x22000 },
+       [GCC_QUSB2PHY_SEC_BCR] = { 0x22004 },
+       [GCC_SDCC2_BCR] = { 0x24000 },
+       [GCC_SDCC4_BCR] = { 0x26000 },
+       [GCC_UFS_PHY_BCR] = { 0x87000 },
+       [GCC_USB30_PRIM_BCR] = { 0x49000 },
+       [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x60008 },
+       [GCC_USB3_DP_PHY_SEC_BCR] = { 0x60014 },
+       [GCC_USB3_PHY_PRIM_BCR] = { 0x60000 },
+       [GCC_USB3_PHY_SEC_BCR] = { 0x6000c },
+       [GCC_USB3PHY_PHY_PRIM_BCR] = { 0x60004 },
+       [GCC_USB3PHY_PHY_SEC_BCR] = { 0x60010 },
+       [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x7a000 },
+       [GCC_VIDEO_AXI0_CLK_ARES] = { 0x42018, 2 },
+       [GCC_VIDEO_AXI1_CLK_ARES] = { 0x42020, 2 },
+       [GCC_VIDEO_BCR] = { 0x42000 },
+};
+
+static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s6_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s6_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap2_s0_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap2_s1_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap2_s2_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap2_s3_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap2_s4_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap2_s5_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap2_s6_clk_src),
+};
+
+static struct gdsc *gcc_sm8450_gdscs[] = {
+       [PCIE_0_GDSC] = &pcie_0_gdsc,
+       [PCIE_1_GDSC] = &pcie_1_gdsc,
+       [UFS_PHY_GDSC] = &ufs_phy_gdsc,
+       [USB30_PRIM_GDSC] = &usb30_prim_gdsc,
+};
+
+static const struct regmap_config gcc_sm8450_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .max_register = 0x1f1030,
+       .fast_io = true,
+};
+
+static const struct qcom_cc_desc gcc_sm8450_desc = {
+       .config = &gcc_sm8450_regmap_config,
+       .clks = gcc_sm8450_clocks,
+       .num_clks = ARRAY_SIZE(gcc_sm8450_clocks),
+       .resets = gcc_sm8450_resets,
+       .num_resets = ARRAY_SIZE(gcc_sm8450_resets),
+       .gdscs = gcc_sm8450_gdscs,
+       .num_gdscs = ARRAY_SIZE(gcc_sm8450_gdscs),
+};
+
+static const struct of_device_id gcc_sm8450_match_table[] = {
+       { .compatible = "qcom,gcc-sm8450" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gcc_sm8450_match_table);
+
+static int gcc_sm8450_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+       int ret;
+
+       regmap = qcom_cc_map(pdev, &gcc_sm8450_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks,
+                                      ARRAY_SIZE(gcc_dfs_clocks));
+       if (ret)
+               return ret;
+
+       /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */
+       regmap_update_bits(regmap, gcc_ufs_phy_ice_core_clk.halt_reg, BIT(14), BIT(14));
+
+       /*
+        * Keep the critical clock always-On
+        * gcc_camera_ahb_clk, gcc_camera_xo_clk, gcc_disp_ahb_clk,
+        * gcc_disp_xo_clk, gcc_gpu_cfg_ahb_clk, gcc_video_ahb_clk,
+        * gcc_video_xo_clk
+        */
+       regmap_update_bits(regmap, 0x36004, BIT(0), BIT(0));
+       regmap_update_bits(regmap, 0x36020, BIT(0), BIT(0));
+       regmap_update_bits(regmap, 0x37004, BIT(0), BIT(0));
+       regmap_update_bits(regmap, 0x3701c, BIT(0), BIT(0));
+       regmap_update_bits(regmap, 0x81004, BIT(0), BIT(0));
+       regmap_update_bits(regmap, 0x42004, BIT(0), BIT(0));
+       regmap_update_bits(regmap, 0x42028, BIT(0), BIT(0));
+
+       return qcom_cc_really_probe(pdev, &gcc_sm8450_desc, regmap);
+}
+
+static struct platform_driver gcc_sm8450_driver = {
+       .probe = gcc_sm8450_probe,
+       .driver = {
+               .name = "gcc-sm8450",
+               .of_match_table = gcc_sm8450_match_table,
+       },
+};
+
+static int __init gcc_sm8450_init(void)
+{
+       return platform_driver_register(&gcc_sm8450_driver);
+}
+subsys_initcall(gcc_sm8450_init);
+
+static void __exit gcc_sm8450_exit(void)
+{
+       platform_driver_unregister(&gcc_sm8450_driver);
+}
+module_exit(gcc_sm8450_exit);
+
+MODULE_DESCRIPTION("QTI GCC SM8450 Driver");
+MODULE_LICENSE("GPL v2");
index 89f1ad6..b39ee1c 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
  */
 
+#include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <linux/pm_clock.h>
 #include <linux/pm_runtime.h>
index 56d3e99..7040da9 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
  */
 
+#include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
index fbfcf00..e9f9713 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
  */
 
+#include <linux/clk-provider.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
index 507386b..780074e 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <linux/bitops.h>
+#include <linux/clk-provider.h>
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
index 4543bda..4318445 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <linux/bitops.h>
+#include <linux/clk-provider.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
index 6d02807..be6e6ae 100644 (file)
@@ -31,6 +31,7 @@ config CLK_RENESAS
        select CLK_R8A77990 if ARCH_R8A77990
        select CLK_R8A77995 if ARCH_R8A77995
        select CLK_R8A779A0 if ARCH_R8A779A0
+       select CLK_R8A779F0 if ARCH_R8A779F0
        select CLK_R9A06G032 if ARCH_R9A06G032
        select CLK_R9A07G044 if ARCH_R9A07G044
        select CLK_SH73A0 if ARCH_SH73A0
@@ -149,8 +150,11 @@ config CLK_R8A77995
 
 config CLK_R8A779A0
        bool "R-Car V3U clock support" if COMPILE_TEST
-       select CLK_RCAR_CPG_LIB
-       select CLK_RENESAS_CPG_MSSR
+       select CLK_RCAR_GEN4_CPG
+
+config CLK_R8A779F0
+       bool "R-Car S4-8 clock support" if COMPILE_TEST
+       select CLK_RCAR_GEN4_CPG
 
 config CLK_R9A06G032
        bool "RZ/N1D clock support" if COMPILE_TEST
@@ -178,6 +182,11 @@ config CLK_RCAR_GEN3_CPG
        select CLK_RCAR_CPG_LIB
        select CLK_RENESAS_CPG_MSSR
 
+config CLK_RCAR_GEN4_CPG
+       bool "R-Car Gen4 clock support" if COMPILE_TEST
+       select CLK_RCAR_CPG_LIB
+       select CLK_RENESAS_CPG_MSSR
+
 config CLK_RCAR_USB2_CLOCK_SEL
        bool "Renesas R-Car USB2 clock selector support"
        depends on ARCH_RENESAS || COMPILE_TEST
index 7d01870..8b34db1 100644 (file)
@@ -28,6 +28,7 @@ obj-$(CONFIG_CLK_R8A77980)            += r8a77980-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A77990)             += r8a77990-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A77995)             += r8a77995-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A779A0)             += r8a779a0-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A779F0)             += r8a779f0-cpg-mssr.o
 obj-$(CONFIG_CLK_R9A06G032)            += r9a06g032-clocks.o
 obj-$(CONFIG_CLK_R9A07G044)            += r9a07g044-cpg.o
 obj-$(CONFIG_CLK_SH73A0)               += clk-sh73a0.o
@@ -36,6 +37,7 @@ obj-$(CONFIG_CLK_SH73A0)              += clk-sh73a0.o
 obj-$(CONFIG_CLK_RCAR_CPG_LIB)         += rcar-cpg-lib.o
 obj-$(CONFIG_CLK_RCAR_GEN2_CPG)                += rcar-gen2-cpg.o
 obj-$(CONFIG_CLK_RCAR_GEN3_CPG)                += rcar-gen3-cpg.o
+obj-$(CONFIG_CLK_RCAR_GEN4_CPG)                += rcar-gen4-cpg.o
 obj-$(CONFIG_CLK_RCAR_USB2_CLOCK_SEL)  += rcar-usb2-clock-sel.o
 obj-$(CONFIG_CLK_RZG2L)                        += rzg2l-cpg.o
 
index 39b185d..95dd56b 100644 (file)
@@ -100,10 +100,14 @@ static const struct cpg_core_clk r8a774a1_core_clks[] __initconst = {
        DEF_FIXED("s3d2",       R8A774A1_CLK_S3D2,  CLK_S3,         2, 1),
        DEF_FIXED("s3d4",       R8A774A1_CLK_S3D4,  CLK_S3,         4, 1),
 
-       DEF_GEN3_SD("sd0",      R8A774A1_CLK_SD0,   CLK_SDSRC,     0x074),
-       DEF_GEN3_SD("sd1",      R8A774A1_CLK_SD1,   CLK_SDSRC,     0x078),
-       DEF_GEN3_SD("sd2",      R8A774A1_CLK_SD2,   CLK_SDSRC,     0x268),
-       DEF_GEN3_SD("sd3",      R8A774A1_CLK_SD3,   CLK_SDSRC,     0x26c),
+       DEF_GEN3_SDH("sd0h",    R8A774A1_CLK_SD0H,  CLK_SDSRC,         0x074),
+       DEF_GEN3_SDH("sd1h",    R8A774A1_CLK_SD1H,  CLK_SDSRC,         0x078),
+       DEF_GEN3_SDH("sd2h",    R8A774A1_CLK_SD2H,  CLK_SDSRC,         0x268),
+       DEF_GEN3_SDH("sd3h",    R8A774A1_CLK_SD3H,  CLK_SDSRC,         0x26c),
+       DEF_GEN3_SD("sd0",      R8A774A1_CLK_SD0,   R8A774A1_CLK_SD0H, 0x074),
+       DEF_GEN3_SD("sd1",      R8A774A1_CLK_SD1,   R8A774A1_CLK_SD1H, 0x078),
+       DEF_GEN3_SD("sd2",      R8A774A1_CLK_SD2,   R8A774A1_CLK_SD2H, 0x268),
+       DEF_GEN3_SD("sd3",      R8A774A1_CLK_SD3,   R8A774A1_CLK_SD3H, 0x26c),
 
        DEF_FIXED("cl",         R8A774A1_CLK_CL,    CLK_PLL1_DIV2, 48, 1),
        DEF_FIXED("cp",         R8A774A1_CLK_CP,    CLK_EXTAL,      2, 1),
index af602d8..56061b9 100644 (file)
@@ -97,10 +97,14 @@ static const struct cpg_core_clk r8a774b1_core_clks[] __initconst = {
        DEF_FIXED("s3d2",       R8A774B1_CLK_S3D2,  CLK_S3,         2, 1),
        DEF_FIXED("s3d4",       R8A774B1_CLK_S3D4,  CLK_S3,         4, 1),
 
-       DEF_GEN3_SD("sd0",      R8A774B1_CLK_SD0,   CLK_SDSRC,     0x074),
-       DEF_GEN3_SD("sd1",      R8A774B1_CLK_SD1,   CLK_SDSRC,     0x078),
-       DEF_GEN3_SD("sd2",      R8A774B1_CLK_SD2,   CLK_SDSRC,     0x268),
-       DEF_GEN3_SD("sd3",      R8A774B1_CLK_SD3,   CLK_SDSRC,     0x26c),
+       DEF_GEN3_SDH("sd0h",    R8A774B1_CLK_SD0H,  CLK_SDSRC,         0x074),
+       DEF_GEN3_SDH("sd1h",    R8A774B1_CLK_SD1H,  CLK_SDSRC,         0x078),
+       DEF_GEN3_SDH("sd2h",    R8A774B1_CLK_SD2H,  CLK_SDSRC,         0x268),
+       DEF_GEN3_SDH("sd3h",    R8A774B1_CLK_SD3H,  CLK_SDSRC,         0x26c),
+       DEF_GEN3_SD("sd0",      R8A774B1_CLK_SD0,   R8A774B1_CLK_SD0H, 0x074),
+       DEF_GEN3_SD("sd1",      R8A774B1_CLK_SD1,   R8A774B1_CLK_SD1H, 0x078),
+       DEF_GEN3_SD("sd2",      R8A774B1_CLK_SD2,   R8A774B1_CLK_SD2H, 0x268),
+       DEF_GEN3_SD("sd3",      R8A774B1_CLK_SD3,   R8A774B1_CLK_SD3H, 0x26c),
 
        DEF_FIXED("cl",         R8A774B1_CLK_CL,    CLK_PLL1_DIV2, 48, 1),
        DEF_FIXED("cp",         R8A774B1_CLK_CP,    CLK_EXTAL,      2, 1),
index 5b938eb..b5eb5dc 100644 (file)
@@ -108,9 +108,12 @@ static const struct cpg_core_clk r8a774c0_core_clks[] __initconst = {
        DEF_FIXED("s3d2",      R8A774C0_CLK_S3D2,  CLK_S3,         2, 1),
        DEF_FIXED("s3d4",      R8A774C0_CLK_S3D4,  CLK_S3,         4, 1),
 
-       DEF_GEN3_SD("sd0",     R8A774C0_CLK_SD0,   CLK_SDSRC,     0x0074),
-       DEF_GEN3_SD("sd1",     R8A774C0_CLK_SD1,   CLK_SDSRC,     0x0078),
-       DEF_GEN3_SD("sd3",     R8A774C0_CLK_SD3,   CLK_SDSRC,     0x026c),
+       DEF_GEN3_SDH("sd0h",   R8A774C0_CLK_SD0H, CLK_SDSRC,         0x0074),
+       DEF_GEN3_SDH("sd1h",   R8A774C0_CLK_SD1H, CLK_SDSRC,         0x0078),
+       DEF_GEN3_SDH("sd3h",   R8A774C0_CLK_SD3H, CLK_SDSRC,         0x026c),
+       DEF_GEN3_SD("sd0",     R8A774C0_CLK_SD0,  R8A774C0_CLK_SD0H, 0x0074),
+       DEF_GEN3_SD("sd1",     R8A774C0_CLK_SD1,  R8A774C0_CLK_SD1H, 0x0078),
+       DEF_GEN3_SD("sd3",     R8A774C0_CLK_SD3,  R8A774C0_CLK_SD3H, 0x026c),
 
        DEF_FIXED("cl",        R8A774C0_CLK_CL,    CLK_PLL1,      48, 1),
        DEF_FIXED("cp",        R8A774C0_CLK_CP,    CLK_EXTAL,      2, 1),
index 40c7146..2950f0d 100644 (file)
@@ -100,10 +100,14 @@ static const struct cpg_core_clk r8a774e1_core_clks[] __initconst = {
        DEF_FIXED("s3d2",       R8A774E1_CLK_S3D2,  CLK_S3,         2, 1),
        DEF_FIXED("s3d4",       R8A774E1_CLK_S3D4,  CLK_S3,         4, 1),
 
-       DEF_GEN3_SD("sd0",      R8A774E1_CLK_SD0,   CLK_SDSRC,     0x074),
-       DEF_GEN3_SD("sd1",      R8A774E1_CLK_SD1,   CLK_SDSRC,     0x078),
-       DEF_GEN3_SD("sd2",      R8A774E1_CLK_SD2,   CLK_SDSRC,     0x268),
-       DEF_GEN3_SD("sd3",      R8A774E1_CLK_SD3,   CLK_SDSRC,     0x26c),
+       DEF_GEN3_SDH("sd0h",    R8A774E1_CLK_SD0H,  CLK_SDSRC,         0x074),
+       DEF_GEN3_SDH("sd1h",    R8A774E1_CLK_SD1H,  CLK_SDSRC,         0x078),
+       DEF_GEN3_SDH("sd2h",    R8A774E1_CLK_SD2H,  CLK_SDSRC,         0x268),
+       DEF_GEN3_SDH("sd3h",    R8A774E1_CLK_SD3H,  CLK_SDSRC,         0x26c),
+       DEF_GEN3_SD("sd0",      R8A774E1_CLK_SD0,   R8A774E1_CLK_SD0H, 0x074),
+       DEF_GEN3_SD("sd1",      R8A774E1_CLK_SD1,   R8A774E1_CLK_SD1H, 0x078),
+       DEF_GEN3_SD("sd2",      R8A774E1_CLK_SD2,   R8A774E1_CLK_SD2H, 0x268),
+       DEF_GEN3_SD("sd3",      R8A774E1_CLK_SD3,   R8A774E1_CLK_SD3H, 0x26c),
 
        DEF_FIXED("cl",         R8A774E1_CLK_CL,    CLK_PLL1_DIV2, 48, 1),
        DEF_FIXED("cr",         R8A774E1_CLK_CR,    CLK_PLL1_DIV4,  2, 1),
index d6b1d01..991a443 100644 (file)
@@ -104,10 +104,14 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = {
        DEF_FIXED("s3d2",       R8A7795_CLK_S3D2,  CLK_S3,         2, 1),
        DEF_FIXED("s3d4",       R8A7795_CLK_S3D4,  CLK_S3,         4, 1),
 
-       DEF_GEN3_SD("sd0",      R8A7795_CLK_SD0,   CLK_SDSRC,     0x074),
-       DEF_GEN3_SD("sd1",      R8A7795_CLK_SD1,   CLK_SDSRC,     0x078),
-       DEF_GEN3_SD("sd2",      R8A7795_CLK_SD2,   CLK_SDSRC,     0x268),
-       DEF_GEN3_SD("sd3",      R8A7795_CLK_SD3,   CLK_SDSRC,     0x26c),
+       DEF_GEN3_SDH("sd0h",    R8A7795_CLK_SD0H,  CLK_SDSRC,        0x074),
+       DEF_GEN3_SDH("sd1h",    R8A7795_CLK_SD1H,  CLK_SDSRC,        0x078),
+       DEF_GEN3_SDH("sd2h",    R8A7795_CLK_SD2H,  CLK_SDSRC,        0x268),
+       DEF_GEN3_SDH("sd3h",    R8A7795_CLK_SD3H,  CLK_SDSRC,        0x26c),
+       DEF_GEN3_SD("sd0",      R8A7795_CLK_SD0,   R8A7795_CLK_SD0H, 0x074),
+       DEF_GEN3_SD("sd1",      R8A7795_CLK_SD1,   R8A7795_CLK_SD1H, 0x078),
+       DEF_GEN3_SD("sd2",      R8A7795_CLK_SD2,   R8A7795_CLK_SD2H, 0x268),
+       DEF_GEN3_SD("sd3",      R8A7795_CLK_SD3,   R8A7795_CLK_SD3H, 0x26c),
 
        DEF_FIXED("cl",         R8A7795_CLK_CL,    CLK_PLL1_DIV2, 48, 1),
        DEF_FIXED("cr",         R8A7795_CLK_CR,    CLK_PLL1_DIV4,  2, 1),
index 9c22977..7950313 100644 (file)
@@ -106,10 +106,14 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = {
        DEF_FIXED("s3d2",       R8A7796_CLK_S3D2,  CLK_S3,         2, 1),
        DEF_FIXED("s3d4",       R8A7796_CLK_S3D4,  CLK_S3,         4, 1),
 
-       DEF_GEN3_SD("sd0",      R8A7796_CLK_SD0,   CLK_SDSRC,     0x074),
-       DEF_GEN3_SD("sd1",      R8A7796_CLK_SD1,   CLK_SDSRC,     0x078),
-       DEF_GEN3_SD("sd2",      R8A7796_CLK_SD2,   CLK_SDSRC,     0x268),
-       DEF_GEN3_SD("sd3",      R8A7796_CLK_SD3,   CLK_SDSRC,     0x26c),
+       DEF_GEN3_SDH("sd0h",    R8A7796_CLK_SD0H,  CLK_SDSRC,        0x074),
+       DEF_GEN3_SDH("sd1h",    R8A7796_CLK_SD1H,  CLK_SDSRC,        0x078),
+       DEF_GEN3_SDH("sd2h",    R8A7796_CLK_SD2H,  CLK_SDSRC,        0x268),
+       DEF_GEN3_SDH("sd3h",    R8A7796_CLK_SD3H,  CLK_SDSRC,        0x26c),
+       DEF_GEN3_SD("sd0",      R8A7796_CLK_SD0,   R8A7796_CLK_SD0H, 0x074),
+       DEF_GEN3_SD("sd1",      R8A7796_CLK_SD1,   R8A7796_CLK_SD1H, 0x078),
+       DEF_GEN3_SD("sd2",      R8A7796_CLK_SD2,   R8A7796_CLK_SD2H, 0x268),
+       DEF_GEN3_SD("sd3",      R8A7796_CLK_SD3,   R8A7796_CLK_SD3H, 0x26c),
 
        DEF_FIXED("cl",         R8A7796_CLK_CL,    CLK_PLL1_DIV2, 48, 1),
        DEF_FIXED("cr",         R8A7796_CLK_CR,    CLK_PLL1_DIV4,  2, 1),
index 7eee45a..d687c29 100644 (file)
@@ -101,10 +101,14 @@ static const struct cpg_core_clk r8a77965_core_clks[] __initconst = {
        DEF_FIXED("s3d2",       R8A77965_CLK_S3D2,      CLK_S3,         2, 1),
        DEF_FIXED("s3d4",       R8A77965_CLK_S3D4,      CLK_S3,         4, 1),
 
-       DEF_GEN3_SD("sd0",      R8A77965_CLK_SD0,       CLK_SDSRC,      0x074),
-       DEF_GEN3_SD("sd1",      R8A77965_CLK_SD1,       CLK_SDSRC,      0x078),
-       DEF_GEN3_SD("sd2",      R8A77965_CLK_SD2,       CLK_SDSRC,      0x268),
-       DEF_GEN3_SD("sd3",      R8A77965_CLK_SD3,       CLK_SDSRC,      0x26c),
+       DEF_GEN3_SDH("sd0h",    R8A77965_CLK_SD0H,      CLK_SDSRC,         0x074),
+       DEF_GEN3_SDH("sd1h",    R8A77965_CLK_SD1H,      CLK_SDSRC,         0x078),
+       DEF_GEN3_SDH("sd2h",    R8A77965_CLK_SD2H,      CLK_SDSRC,         0x268),
+       DEF_GEN3_SDH("sd3h",    R8A77965_CLK_SD3H,      CLK_SDSRC,         0x26c),
+       DEF_GEN3_SD("sd0",      R8A77965_CLK_SD0,       R8A77965_CLK_SD0H, 0x074),
+       DEF_GEN3_SD("sd1",      R8A77965_CLK_SD1,       R8A77965_CLK_SD1H, 0x078),
+       DEF_GEN3_SD("sd2",      R8A77965_CLK_SD2,       R8A77965_CLK_SD2H, 0x268),
+       DEF_GEN3_SD("sd3",      R8A77965_CLK_SD3,       R8A77965_CLK_SD3H, 0x26c),
 
        DEF_FIXED("cl",         R8A77965_CLK_CL,        CLK_PLL1_DIV2, 48, 1),
        DEF_FIXED("cr",         R8A77965_CLK_CR,        CLK_PLL1_DIV4,  2, 1),
index 9fe3722..f3cd64d 100644 (file)
@@ -96,7 +96,8 @@ static const struct cpg_core_clk r8a77980_core_clks[] __initconst = {
        DEF_FIXED("s3d2",       R8A77980_CLK_S3D2,  CLK_S3,         2, 1),
        DEF_FIXED("s3d4",       R8A77980_CLK_S3D4,  CLK_S3,         4, 1),
 
-       DEF_GEN3_SD("sd0",      R8A77980_CLK_SD0,   CLK_SDSRC,    0x0074),
+       DEF_GEN3_SDH("sd0h",    R8A77980_CLK_SD0H,  CLK_SDSRC,         0x0074),
+       DEF_GEN3_SD("sd0",      R8A77980_CLK_SD0,   R8A77980_CLK_SD0H, 0x0074),
 
        DEF_FIXED("cl",         R8A77980_CLK_CL,    CLK_PLL1_DIV2, 48, 1),
        DEF_FIXED("cp",         R8A77980_CLK_CP,    CLK_EXTAL,      2, 1),
index a582f2e..faf60f7 100644 (file)
@@ -100,9 +100,12 @@ static const struct cpg_core_clk r8a77990_core_clks[] __initconst = {
        DEF_FIXED("s3d2",      R8A77990_CLK_S3D2,  CLK_S3,         2, 1),
        DEF_FIXED("s3d4",      R8A77990_CLK_S3D4,  CLK_S3,         4, 1),
 
-       DEF_GEN3_SD("sd0",     R8A77990_CLK_SD0,   CLK_SDSRC,     0x0074),
-       DEF_GEN3_SD("sd1",     R8A77990_CLK_SD1,   CLK_SDSRC,     0x0078),
-       DEF_GEN3_SD("sd3",     R8A77990_CLK_SD3,   CLK_SDSRC,     0x026c),
+       DEF_GEN3_SDH("sd0h",   R8A77990_CLK_SD0H,  CLK_SDSRC,         0x0074),
+       DEF_GEN3_SDH("sd1h",   R8A77990_CLK_SD1H,  CLK_SDSRC,         0x0078),
+       DEF_GEN3_SDH("sd3h",   R8A77990_CLK_SD3H,  CLK_SDSRC,         0x026c),
+       DEF_GEN3_SD("sd0",     R8A77990_CLK_SD0,   R8A77990_CLK_SD0H, 0x0074),
+       DEF_GEN3_SD("sd1",     R8A77990_CLK_SD1,   R8A77990_CLK_SD1H, 0x0078),
+       DEF_GEN3_SD("sd3",     R8A77990_CLK_SD3,   R8A77990_CLK_SD3H, 0x026c),
 
        DEF_FIXED("cl",        R8A77990_CLK_CL,    CLK_PLL1,      48, 1),
        DEF_FIXED("cr",        R8A77990_CLK_CR,    CLK_PLL1D2,     2, 1),
index 81c0bc1..7713cfd 100644 (file)
@@ -103,7 +103,8 @@ static const struct cpg_core_clk r8a77995_core_clks[] __initconst = {
        DEF_GEN3_PE("s3d2c",   R8A77995_CLK_S3D2C, CLK_S3, 2, CLK_PE, 2),
        DEF_GEN3_PE("s3d4c",   R8A77995_CLK_S3D4C, CLK_S3, 4, CLK_PE, 4),
 
-       DEF_GEN3_SD("sd0",     R8A77995_CLK_SD0,   CLK_SDSRC,     0x268),
+       DEF_GEN3_SDH("sd0h",   R8A77995_CLK_SD0H, CLK_SDSRC,         0x268),
+       DEF_GEN3_SD("sd0",     R8A77995_CLK_SD0,  R8A77995_CLK_SD0H, 0x268),
 
        DEF_DIV6P1("canfd",    R8A77995_CLK_CANFD, CLK_PLL0D3,    0x244),
        DEF_DIV6P1("mso",      R8A77995_CLK_MSO,   CLK_PLL1D2,    0x014),
index fbd7454..1c09d4e 100644 (file)
  * Copyright (C) 2015 Renesas Electronics Corp.
  */
 
-#include <linux/bug.h>
 #include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/init.h>
-#include <linux/io.h>
 #include <linux/kernel.h>
-#include <linux/pm.h>
-#include <linux/slab.h>
 #include <linux/soc/renesas/rcar-rst.h>
 
 #include <dt-bindings/clock/r8a779a0-cpg-mssr.h>
 
-#include "rcar-cpg-lib.h"
 #include "renesas-cpg-mssr.h"
-
-enum rcar_r8a779a0_clk_types {
-       CLK_TYPE_R8A779A0_MAIN = CLK_TYPE_CUSTOM,
-       CLK_TYPE_R8A779A0_PLL1,
-       CLK_TYPE_R8A779A0_PLL2X_3X,     /* PLL[23][01] */
-       CLK_TYPE_R8A779A0_PLL5,
-       CLK_TYPE_R8A779A0_Z,
-       CLK_TYPE_R8A779A0_SD,
-       CLK_TYPE_R8A779A0_MDSEL,        /* Select parent/divider using mode pin */
-       CLK_TYPE_R8A779A0_OSC,  /* OSC EXTAL predivider and fixed divider */
-       CLK_TYPE_R8A779A0_RPCSRC,
-       CLK_TYPE_R8A779A0_RPC,
-       CLK_TYPE_R8A779A0_RPCD2,
-};
-
-struct rcar_r8a779a0_cpg_pll_config {
-       u8 extal_div;
-       u8 pll1_mult;
-       u8 pll1_div;
-       u8 pll5_mult;
-       u8 pll5_div;
-       u8 osc_prediv;
-};
+#include "rcar-gen4-cpg.h"
 
 enum clk_ids {
        /* Core Clock Outputs exported to DT */
@@ -85,33 +58,18 @@ enum clk_ids {
 };
 
 #define DEF_PLL(_name, _id, _offset)   \
-       DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_PLL2X_3X, CLK_MAIN, \
+       DEF_BASE(_name, _id, CLK_TYPE_GEN4_PLL2X_3X, CLK_MAIN, \
                 .offset = _offset)
 
-#define DEF_Z(_name, _id, _parent, _div, _offset)      \
-       DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_Z, _parent, .div = _div, \
-                .offset = _offset)
-
-#define DEF_SD(_name, _id, _parent, _offset)   \
-       DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_SD, _parent, .offset = _offset)
-
-#define DEF_MDSEL(_name, _id, _md, _parent0, _div0, _parent1, _div1) \
-       DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_MDSEL,   \
-                (_parent0) << 16 | (_parent1),         \
-                .div = (_div0) << 16 | (_div1), .offset = _md)
-
-#define DEF_OSC(_name, _id, _parent, _div)             \
-       DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_OSC, _parent, .div = _div)
-
 static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
        /* External Clock Inputs */
        DEF_INPUT("extal",  CLK_EXTAL),
        DEF_INPUT("extalr", CLK_EXTALR),
 
        /* Internal Core Clocks */
-       DEF_BASE(".main", CLK_MAIN,     CLK_TYPE_R8A779A0_MAIN, CLK_EXTAL),
-       DEF_BASE(".pll1", CLK_PLL1,     CLK_TYPE_R8A779A0_PLL1, CLK_MAIN),
-       DEF_BASE(".pll5", CLK_PLL5,     CLK_TYPE_R8A779A0_PLL5, CLK_MAIN),
+       DEF_BASE(".main", CLK_MAIN,     CLK_TYPE_GEN4_MAIN, CLK_EXTAL),
+       DEF_BASE(".pll1", CLK_PLL1,     CLK_TYPE_GEN4_PLL1, CLK_MAIN),
+       DEF_BASE(".pll5", CLK_PLL5,     CLK_TYPE_GEN4_PLL5, CLK_MAIN),
        DEF_PLL(".pll20", CLK_PLL20,    0x0834),
        DEF_PLL(".pll21", CLK_PLL21,    0x0838),
        DEF_PLL(".pll30", CLK_PLL30,    0x083c),
@@ -128,14 +86,14 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
        DEF_FIXED(".s3",                CLK_S3,         CLK_PLL1_DIV2,  4, 1),
        DEF_FIXED(".sdsrc",             CLK_SDSRC,      CLK_PLL5_DIV4,  1, 1),
        DEF_RATE(".oco",                CLK_OCO,        32768),
-       DEF_BASE(".rpcsrc",      CLK_RPCSRC,       CLK_TYPE_R8A779A0_RPCSRC, CLK_PLL5),
-       DEF_BASE("rpc",          R8A779A0_CLK_RPC, CLK_TYPE_R8A779A0_RPC, CLK_RPCSRC),
-       DEF_BASE("rpcd2",        R8A779A0_CLK_RPCD2, CLK_TYPE_R8A779A0_RPCD2,
+       DEF_BASE(".rpcsrc",      CLK_RPCSRC,       CLK_TYPE_GEN4_RPCSRC, CLK_PLL5),
+       DEF_BASE("rpc",          R8A779A0_CLK_RPC, CLK_TYPE_GEN4_RPC, CLK_RPCSRC),
+       DEF_BASE("rpcd2",        R8A779A0_CLK_RPCD2, CLK_TYPE_GEN4_RPCD2,
                 R8A779A0_CLK_RPC),
 
        /* Core Clock Outputs */
-       DEF_Z("z0",             R8A779A0_CLK_Z0,        CLK_PLL20,      2, 0),
-       DEF_Z("z1",             R8A779A0_CLK_Z1,        CLK_PLL21,      2, 8),
+       DEF_GEN4_Z("z0",        R8A779A0_CLK_Z0,        CLK_TYPE_GEN4_Z,        CLK_PLL20,      2, 0),
+       DEF_GEN4_Z("z1",        R8A779A0_CLK_Z1,        CLK_TYPE_GEN4_Z,        CLK_PLL21,      2, 8),
        DEF_FIXED("zx",         R8A779A0_CLK_ZX,        CLK_PLL20_DIV2, 2, 1),
        DEF_FIXED("s1d1",       R8A779A0_CLK_S1D1,      CLK_S1,         1, 1),
        DEF_FIXED("s1d2",       R8A779A0_CLK_S1D2,      CLK_S1,         2, 1),
@@ -159,15 +117,16 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
        DEF_FIXED("cp",         R8A779A0_CLK_CP,        CLK_EXTAL,      2, 1),
        DEF_FIXED("cl16mck",    R8A779A0_CLK_CL16MCK,   CLK_PLL1_DIV2,  64, 1),
 
-       DEF_SD("sd0",           R8A779A0_CLK_SD0,       CLK_SDSRC,      0x870),
+       DEF_GEN4_SDH("sdh0",    R8A779A0_CLK_SD0H,      CLK_SDSRC,         0x870),
+       DEF_GEN4_SD("sd0",      R8A779A0_CLK_SD0,       R8A779A0_CLK_SD0H, 0x870),
 
        DEF_DIV6P1("mso",       R8A779A0_CLK_MSO,       CLK_PLL5_DIV4,  0x87c),
        DEF_DIV6P1("canfd",     R8A779A0_CLK_CANFD,     CLK_PLL5_DIV4,  0x878),
        DEF_DIV6P1("csi0",      R8A779A0_CLK_CSI0,      CLK_PLL5_DIV4,  0x880),
        DEF_DIV6P1("dsi",       R8A779A0_CLK_DSI,       CLK_PLL5_DIV4,  0x884),
 
-       DEF_OSC("osc",          R8A779A0_CLK_OSC,       CLK_EXTAL,      8),
-       DEF_MDSEL("r",          R8A779A0_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1),
+       DEF_GEN4_OSC("osc",     R8A779A0_CLK_OSC,       CLK_EXTAL,      8),
+       DEF_GEN4_MDSEL("r",     R8A779A0_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1),
 };
 
 static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = {
@@ -271,256 +230,6 @@ static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = {
        DEF_MOD("vspx3",        1031,   R8A779A0_CLK_S1D1),
 };
 
-static const struct rcar_r8a779a0_cpg_pll_config *cpg_pll_config __initdata;
-static unsigned int cpg_clk_extalr __initdata;
-static u32 cpg_mode __initdata;
-
-/*
- * Z0 Clock & Z1 Clock
- */
-#define CPG_FRQCRB                     0x00000804
-#define CPG_FRQCRB_KICK                        BIT(31)
-#define CPG_FRQCRC                     0x00000808
-
-struct cpg_z_clk {
-       struct clk_hw hw;
-       void __iomem *reg;
-       void __iomem *kick_reg;
-       unsigned long max_rate;         /* Maximum rate for normal mode */
-       unsigned int fixed_div;
-       u32 mask;
-};
-
-#define to_z_clk(_hw)  container_of(_hw, struct cpg_z_clk, hw)
-
-static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw,
-                                          unsigned long parent_rate)
-{
-       struct cpg_z_clk *zclk = to_z_clk(hw);
-       unsigned int mult;
-       u32 val;
-
-       val = readl(zclk->reg) & zclk->mask;
-       mult = 32 - (val >> __ffs(zclk->mask));
-
-       return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult,
-                                    32 * zclk->fixed_div);
-}
-
-static int cpg_z_clk_determine_rate(struct clk_hw *hw,
-                                   struct clk_rate_request *req)
-{
-       struct cpg_z_clk *zclk = to_z_clk(hw);
-       unsigned int min_mult, max_mult, mult;
-       unsigned long rate, prate;
-
-       rate = min(req->rate, req->max_rate);
-       if (rate <= zclk->max_rate) {
-               /* Set parent rate to initial value for normal modes */
-               prate = zclk->max_rate;
-       } else {
-               /* Set increased parent rate for boost modes */
-               prate = rate;
-       }
-       req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
-                                                 prate * zclk->fixed_div);
-
-       prate = req->best_parent_rate / zclk->fixed_div;
-       min_mult = max(div64_ul(req->min_rate * 32ULL, prate), 1ULL);
-       max_mult = min(div64_ul(req->max_rate * 32ULL, prate), 32ULL);
-       if (max_mult < min_mult)
-               return -EINVAL;
-
-       mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL, prate);
-       mult = clamp(mult, min_mult, max_mult);
-
-       req->rate = DIV_ROUND_CLOSEST_ULL((u64)prate * mult, 32);
-       return 0;
-}
-
-static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
-                             unsigned long parent_rate)
-{
-       struct cpg_z_clk *zclk = to_z_clk(hw);
-       unsigned int mult;
-       unsigned int i;
-
-       mult = DIV64_U64_ROUND_CLOSEST(rate * 32ULL * zclk->fixed_div,
-                                      parent_rate);
-       mult = clamp(mult, 1U, 32U);
-
-       if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK)
-               return -EBUSY;
-
-       cpg_reg_modify(zclk->reg, zclk->mask, (32 - mult) << __ffs(zclk->mask));
-
-       /*
-        * Set KICK bit in FRQCRB to update hardware setting and wait for
-        * clock change completion.
-        */
-       cpg_reg_modify(zclk->kick_reg, 0, CPG_FRQCRB_KICK);
-
-       /*
-        * Note: There is no HW information about the worst case latency.
-        *
-        * Using experimental measurements, it seems that no more than
-        * ~10 iterations are needed, independently of the CPU rate.
-        * Since this value might be dependent on external xtal rate, pll1
-        * rate or even the other emulation clocks rate, use 1000 as a
-        * "super" safe value.
-        */
-       for (i = 1000; i; i--) {
-               if (!(readl(zclk->kick_reg) & CPG_FRQCRB_KICK))
-                       return 0;
-
-               cpu_relax();
-       }
-
-       return -ETIMEDOUT;
-}
-
-static const struct clk_ops cpg_z_clk_ops = {
-       .recalc_rate = cpg_z_clk_recalc_rate,
-       .determine_rate = cpg_z_clk_determine_rate,
-       .set_rate = cpg_z_clk_set_rate,
-};
-
-static struct clk * __init cpg_z_clk_register(const char *name,
-                                             const char *parent_name,
-                                             void __iomem *reg,
-                                             unsigned int div,
-                                             unsigned int offset)
-{
-       struct clk_init_data init = {};
-       struct cpg_z_clk *zclk;
-       struct clk *clk;
-
-       zclk = kzalloc(sizeof(*zclk), GFP_KERNEL);
-       if (!zclk)
-               return ERR_PTR(-ENOMEM);
-
-       init.name = name;
-       init.ops = &cpg_z_clk_ops;
-       init.flags = CLK_SET_RATE_PARENT;
-       init.parent_names = &parent_name;
-       init.num_parents = 1;
-
-       zclk->reg = reg + CPG_FRQCRC;
-       zclk->kick_reg = reg + CPG_FRQCRB;
-       zclk->hw.init = &init;
-       zclk->mask = GENMASK(offset + 4, offset);
-       zclk->fixed_div = div; /* PLLVCO x 1/div x SYS-CPU divider */
-
-       clk = clk_register(NULL, &zclk->hw);
-       if (IS_ERR(clk)) {
-               kfree(zclk);
-               return clk;
-       }
-
-       zclk->max_rate = clk_hw_get_rate(clk_hw_get_parent(&zclk->hw)) /
-                        zclk->fixed_div;
-       return clk;
-}
-
-/*
- * RPC Clocks
- */
-#define CPG_RPCCKCR 0x874
-
-static const struct clk_div_table cpg_rpcsrc_div_table[] = {
-       { 0, 4 }, { 1, 6 }, { 2, 5 }, { 3, 6 }, { 0, 0 },
-};
-
-static struct clk * __init rcar_r8a779a0_cpg_clk_register(struct device *dev,
-       const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
-       struct clk **clks, void __iomem *base,
-       struct raw_notifier_head *notifiers)
-{
-       const struct clk *parent;
-       unsigned int mult = 1;
-       unsigned int div = 1;
-       u32 value;
-
-       parent = clks[core->parent & 0xffff];   /* some types use high bits */
-       if (IS_ERR(parent))
-               return ERR_CAST(parent);
-
-       switch (core->type) {
-       case CLK_TYPE_R8A779A0_MAIN:
-               div = cpg_pll_config->extal_div;
-               break;
-
-       case CLK_TYPE_R8A779A0_PLL1:
-               mult = cpg_pll_config->pll1_mult;
-               div = cpg_pll_config->pll1_div;
-               break;
-
-       case CLK_TYPE_R8A779A0_PLL2X_3X:
-               value = readl(base + core->offset);
-               mult = (((value >> 24) & 0x7f) + 1) * 2;
-               break;
-
-       case CLK_TYPE_R8A779A0_PLL5:
-               mult = cpg_pll_config->pll5_mult;
-               div = cpg_pll_config->pll5_div;
-               break;
-
-       case CLK_TYPE_R8A779A0_Z:
-               return cpg_z_clk_register(core->name, __clk_get_name(parent),
-                                         base, core->div, core->offset);
-
-       case CLK_TYPE_R8A779A0_SD:
-               return cpg_sd_clk_register(core->name, base, core->offset,
-                                          __clk_get_name(parent), notifiers,
-                                          false);
-               break;
-
-       case CLK_TYPE_R8A779A0_MDSEL:
-               /*
-                * Clock selectable between two parents and two fixed dividers
-                * using a mode pin
-                */
-               if (cpg_mode & BIT(core->offset)) {
-                       div = core->div & 0xffff;
-               } else {
-                       parent = clks[core->parent >> 16];
-                       if (IS_ERR(parent))
-                               return ERR_CAST(parent);
-                       div = core->div >> 16;
-               }
-               mult = 1;
-               break;
-
-       case CLK_TYPE_R8A779A0_OSC:
-               /*
-                * Clock combining OSC EXTAL predivider and a fixed divider
-                */
-               div = cpg_pll_config->osc_prediv * core->div;
-               break;
-
-       case CLK_TYPE_R8A779A0_RPCSRC:
-               return clk_register_divider_table(NULL, core->name,
-                                                 __clk_get_name(parent), 0,
-                                                 base + CPG_RPCCKCR, 3, 2, 0,
-                                                 cpg_rpcsrc_div_table,
-                                                 &cpg_lock);
-
-       case CLK_TYPE_R8A779A0_RPC:
-               return cpg_rpc_clk_register(core->name, base + CPG_RPCCKCR,
-                                           __clk_get_name(parent), notifiers);
-
-       case CLK_TYPE_R8A779A0_RPCD2:
-               return cpg_rpcd2_clk_register(core->name, base + CPG_RPCCKCR,
-                                             __clk_get_name(parent));
-
-       default:
-               return ERR_PTR(-EINVAL);
-       }
-
-       return clk_register_fixed_factor(NULL, core->name,
-                                        __clk_get_name(parent), 0, mult, div);
-}
-
 static const unsigned int r8a779a0_crit_mod_clks[] __initconst = {
        MOD_CLK_ID(907),        /* RWDT */
 };
@@ -539,17 +248,19 @@ static const unsigned int r8a779a0_crit_mod_clks[] __initconst = {
  */
 #define CPG_PLL_CONFIG_INDEX(md)       ((((md) & BIT(14)) >> 13) | \
                                         (((md) & BIT(13)) >> 13))
-
-static const struct rcar_r8a779a0_cpg_pll_config cpg_pll_configs[4] = {
-       /* EXTAL div    PLL1 mult/div   PLL5 mult/div   OSC prediv */
-       { 1,            128,    1,      192,    1,      16,     },
-       { 1,            106,    1,      160,    1,      19,     },
-       { 0,            0,      0,      0,      0,      0,      },
-       { 2,            128,    1,      192,    1,      32,     },
+static const struct rcar_gen4_cpg_pll_config cpg_pll_configs[4] = {
+       /* EXTAL div    PLL1 mult/div   PLL2 mult/div   PLL3 mult/div   PLL5 mult/div   PLL6 mult/div   OSC prediv */
+       { 1,            128,    1,      0,      0,      0,      0,      192,    1,      0,      0,      16,     },
+       { 1,            106,    1,      0,      0,      0,      0,      160,    1,      0,      0,      19,     },
+       { 0,            0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      },
+       { 2,            128,    1,      0,      0,      0,      0,      192,    1,      0,      0,      32,     },
 };
 
+
 static int __init r8a779a0_cpg_mssr_init(struct device *dev)
 {
+       const struct rcar_gen4_cpg_pll_config *cpg_pll_config;
+       u32 cpg_mode;
        int error;
 
        error = rcar_rst_read_mode_pins(&cpg_mode);
@@ -557,10 +268,8 @@ static int __init r8a779a0_cpg_mssr_init(struct device *dev)
                return error;
 
        cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
-       cpg_clk_extalr = CLK_EXTALR;
-       spin_lock_init(&cpg_lock);
 
-       return 0;
+       return rcar_gen4_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode);
 }
 
 const struct cpg_mssr_info r8a779a0_cpg_mssr_info __initconst = {
@@ -581,7 +290,7 @@ const struct cpg_mssr_info r8a779a0_cpg_mssr_info __initconst = {
 
        /* Callbacks */
        .init = r8a779a0_cpg_mssr_init,
-       .cpg_clk_register = rcar_r8a779a0_cpg_clk_register,
+       .cpg_clk_register = rcar_gen4_cpg_clk_register,
 
-       .reg_layout = CLK_REG_LAYOUT_RCAR_V3U,
+       .reg_layout = CLK_REG_LAYOUT_RCAR_GEN4,
 };
diff --git a/drivers/clk/renesas/r8a779f0-cpg-mssr.c b/drivers/clk/renesas/r8a779f0-cpg-mssr.c
new file mode 100644 (file)
index 0000000..e6ec02c
--- /dev/null
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * r8a779f0 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ *
+ * Based on r8a779a0-cpg-mssr.c
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/soc/renesas/rcar-rst.h>
+
+#include <dt-bindings/clock/r8a779f0-cpg-mssr.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen4-cpg.h"
+
+enum clk_ids {
+       /* Core Clock Outputs exported to DT */
+       LAST_DT_CORE_CLK = R8A779F0_CLK_R,
+
+       /* External Input Clocks */
+       CLK_EXTAL,
+       CLK_EXTALR,
+
+       /* Internal Core Clocks */
+       CLK_MAIN,
+       CLK_PLL1,
+       CLK_PLL2,
+       CLK_PLL3,
+       CLK_PLL5,
+       CLK_PLL6,
+       CLK_PLL1_DIV2,
+       CLK_PLL2_DIV2,
+       CLK_PLL3_DIV2,
+       CLK_PLL5_DIV2,
+       CLK_PLL5_DIV4,
+       CLK_PLL6_DIV2,
+       CLK_S0,
+       CLK_SDSRC,
+       CLK_RPCSRC,
+       CLK_OCO,
+
+       /* Module Clocks */
+       MOD_CLK_BASE
+};
+
+static const struct cpg_core_clk r8a779f0_core_clks[] __initconst = {
+       /* External Clock Inputs */
+       DEF_INPUT("extal",      CLK_EXTAL),
+       DEF_INPUT("extalr",     CLK_EXTALR),
+
+       /* Internal Core Clocks */
+       DEF_BASE(".main", CLK_MAIN,     CLK_TYPE_GEN4_MAIN, CLK_EXTAL),
+       DEF_BASE(".pll1", CLK_PLL1,     CLK_TYPE_GEN4_PLL1, CLK_MAIN),
+       DEF_BASE(".pll2", CLK_PLL2,     CLK_TYPE_GEN4_PLL2, CLK_MAIN),
+       DEF_BASE(".pll3", CLK_PLL3,     CLK_TYPE_GEN4_PLL3, CLK_MAIN),
+       DEF_BASE(".pll5", CLK_PLL5,     CLK_TYPE_GEN4_PLL5, CLK_MAIN),
+       DEF_BASE(".pll6", CLK_PLL6,     CLK_TYPE_GEN4_PLL6, CLK_MAIN),
+
+       DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2,  CLK_PLL1,       2, 1),
+       DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2,  CLK_PLL2,       2, 1),
+       DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2,  CLK_PLL3,       2, 1),
+       DEF_FIXED(".pll5_div2", CLK_PLL5_DIV2,  CLK_PLL5,       2, 1),
+       DEF_FIXED(".pll5_div4", CLK_PLL5_DIV4,  CLK_PLL5_DIV2,  2, 1),
+       DEF_FIXED(".pll6_div2", CLK_PLL6_DIV2,  CLK_PLL6,       2, 1),
+       DEF_FIXED(".s0",        CLK_S0,         CLK_PLL1_DIV2,  2, 1),
+       DEF_BASE(".sdsrc",      CLK_SDSRC,      CLK_TYPE_GEN4_SDSRC, CLK_PLL5),
+       DEF_RATE(".oco",        CLK_OCO,        32768),
+
+       DEF_BASE(".rpcsrc",     CLK_RPCSRC,             CLK_TYPE_GEN4_RPCSRC, CLK_PLL5),
+       DEF_BASE(".rpc",        R8A779F0_CLK_RPC,       CLK_TYPE_GEN4_RPC, CLK_RPCSRC),
+       DEF_BASE("rpcd2",       R8A779F0_CLK_RPCD2,     CLK_TYPE_GEN4_RPCD2, R8A779F0_CLK_RPC),
+
+       /* Core Clock Outputs */
+       DEF_FIXED("s0d2",       R8A779F0_CLK_S0D2,      CLK_S0,         2, 1),
+       DEF_FIXED("s0d3",       R8A779F0_CLK_S0D3,      CLK_S0,         3, 1),
+       DEF_FIXED("s0d4",       R8A779F0_CLK_S0D4,      CLK_S0,         4, 1),
+       DEF_FIXED("cl16m",      R8A779F0_CLK_CL16M,     CLK_S0,         48, 1),
+       DEF_FIXED("s0d2_mm",    R8A779F0_CLK_S0D2_MM,   CLK_S0,         2, 1),
+       DEF_FIXED("s0d3_mm",    R8A779F0_CLK_S0D3_MM,   CLK_S0,         3, 1),
+       DEF_FIXED("s0d4_mm",    R8A779F0_CLK_S0D4_MM,   CLK_S0,         4, 1),
+       DEF_FIXED("cl16m_mm",   R8A779F0_CLK_CL16M_MM,  CLK_S0,         48, 1),
+       DEF_FIXED("s0d2_rt",    R8A779F0_CLK_S0D2_RT,   CLK_S0,         2, 1),
+       DEF_FIXED("s0d3_rt",    R8A779F0_CLK_S0D3_RT,   CLK_S0,         3, 1),
+       DEF_FIXED("s0d4_rt",    R8A779F0_CLK_S0D4_RT,   CLK_S0,         4, 1),
+       DEF_FIXED("s0d6_rt",    R8A779F0_CLK_S0D6_RT,   CLK_S0,         6, 1),
+       DEF_FIXED("cl16m_rt",   R8A779F0_CLK_CL16M_RT,  CLK_S0,         48, 1),
+       DEF_FIXED("s0d3_per",   R8A779F0_CLK_S0D3_PER,  CLK_S0,         3, 1),
+       DEF_FIXED("s0d6_per",   R8A779F0_CLK_S0D6_PER,  CLK_S0,         6, 1),
+       DEF_FIXED("s0d12_per",  R8A779F0_CLK_S0D12_PER, CLK_S0,         12, 1),
+       DEF_FIXED("s0d24_per",  R8A779F0_CLK_S0D24_PER, CLK_S0,         24, 1),
+       DEF_FIXED("cl16m_per",  R8A779F0_CLK_CL16M_PER, CLK_S0,         48, 1),
+       DEF_FIXED("s0d2_hsc",   R8A779F0_CLK_S0D2_HSC,  CLK_S0,         2, 1),
+       DEF_FIXED("s0d3_hsc",   R8A779F0_CLK_S0D3_HSC,  CLK_S0,         3, 1),
+       DEF_FIXED("s0d4_hsc",   R8A779F0_CLK_S0D4_HSC,  CLK_S0,         4, 1),
+       DEF_FIXED("s0d6_hsc",   R8A779F0_CLK_S0D6_HSC,  CLK_S0,         6, 1),
+       DEF_FIXED("s0d12_hsc",  R8A779F0_CLK_S0D12_HSC, CLK_S0,         12, 1),
+       DEF_FIXED("cl16m_hsc",  R8A779F0_CLK_CL16M_HSC, CLK_S0,         48, 1),
+       DEF_FIXED("s0d2_cc",    R8A779F0_CLK_S0D2_CC,   CLK_S0,         2, 1),
+       DEF_FIXED("rsw2",       R8A779F0_CLK_RSW2,      CLK_PLL5,       2, 1),
+       DEF_FIXED("cbfusa",     R8A779F0_CLK_CBFUSA,    CLK_EXTAL,      2, 1),
+       DEF_FIXED("cpex",       R8A779F0_CLK_CPEX,      CLK_EXTAL,      2, 1),
+
+       DEF_GEN4_SD("sd0",      R8A779F0_CLK_SD0,       CLK_SDSRC,      0x870),
+       DEF_DIV6P1("mso",       R8A779F0_CLK_MSO,       CLK_PLL5_DIV4,  0x87c),
+
+       DEF_GEN4_OSC("osc",     R8A779F0_CLK_OSC,       CLK_EXTAL,      8),
+       DEF_GEN4_MDSEL("r",     R8A779F0_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1),
+};
+
+static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = {
+       DEF_MOD("scif0",        702,    R8A779F0_CLK_S0D12_PER),
+       DEF_MOD("scif1",        703,    R8A779F0_CLK_S0D12_PER),
+       DEF_MOD("scif3",        704,    R8A779F0_CLK_S0D12_PER),
+       DEF_MOD("scif4",        705,    R8A779F0_CLK_S0D12_PER),
+};
+
+/*
+ * CPG Clock Data
+ */
+/*
+ *   MD         EXTAL          PLL1    PLL2    PLL3    PLL5    PLL6    OSC
+ * 14 13 (MHz)
+ * ----------------------------------------------------------------
+ * 0  0         16    / 1      x200    x150    x200    x200    x134    /15
+ * 0  1         20    / 1      x160    x120    x160    x160    x106    /19
+ * 1  0         Prohibited setting
+ * 1  1         40    / 2      x160    x120    x160    x160    x106    /38
+ */
+#define CPG_PLL_CONFIG_INDEX(md)       ((((md) & BIT(14)) >> 13) | \
+                                        (((md) & BIT(13)) >> 13))
+
+static const struct rcar_gen4_cpg_pll_config cpg_pll_configs[4] = {
+       /* EXTAL div    PLL1 mult/div   PLL2 mult/div   PLL3 mult/div   PLL5 mult/div   PLL6 mult/div   OSC prediv */
+       { 1,            200,    1,      150,    1,      200,    1,      200,    1,      134,    1,      15,     },
+       { 1,            160,    1,      120,    1,      160,    1,      160,    1,      106,    1,      19,     },
+       { 0,            0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      },
+       { 2,            160,    1,      120,    1,      160,    1,      160,    1,      106,    1,      38,     },
+};
+
+static int __init r8a779f0_cpg_mssr_init(struct device *dev)
+{
+       const struct rcar_gen4_cpg_pll_config *cpg_pll_config;
+       u32 cpg_mode;
+       int error;
+
+       error = rcar_rst_read_mode_pins(&cpg_mode);
+       if (error)
+               return error;
+
+       cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+       if (!cpg_pll_config->extal_div) {
+               dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode);
+               return -EINVAL;
+       }
+
+       return rcar_gen4_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode);
+}
+
+const struct cpg_mssr_info r8a779f0_cpg_mssr_info __initconst = {
+       /* Core Clocks */
+       .core_clks = r8a779f0_core_clks,
+       .num_core_clks = ARRAY_SIZE(r8a779f0_core_clks),
+       .last_dt_core_clk = LAST_DT_CORE_CLK,
+       .num_total_core_clks = MOD_CLK_BASE,
+
+       /* Module Clocks */
+       .mod_clks = r8a779f0_mod_clks,
+       .num_mod_clks = ARRAY_SIZE(r8a779f0_mod_clks),
+       .num_hw_mod_clks = 28 * 32,
+
+       /* Callbacks */
+       .init = r8a779f0_cpg_mssr_init,
+       .cpg_clk_register = rcar_gen4_cpg_clk_register,
+
+       .reg_layout = CLK_REG_LAYOUT_RCAR_GEN4,
+};
index 47c1626..79042bf 100644 (file)
@@ -26,15 +26,15 @@ enum clk_ids {
        CLK_PLL1,
        CLK_PLL2,
        CLK_PLL2_DIV2,
-       CLK_PLL2_DIV16,
-       CLK_PLL2_DIV20,
+       CLK_PLL2_DIV2_8,
+       CLK_PLL2_DIV2_10,
        CLK_PLL3,
        CLK_PLL3_400,
        CLK_PLL3_533,
        CLK_PLL3_DIV2,
+       CLK_PLL3_DIV2_2,
        CLK_PLL3_DIV2_4,
        CLK_PLL3_DIV2_4_2,
-       CLK_PLL3_DIV4,
        CLK_SEL_PLL3_3,
        CLK_DIV_PLL3_C,
        CLK_PLL4,
@@ -50,12 +50,21 @@ enum clk_ids {
        CLK_PLL2_SDHI_266,
        CLK_SD0_DIV4,
        CLK_SD1_DIV4,
+       CLK_SEL_GPU2,
 
        /* Module Clocks */
        MOD_CLK_BASE,
 };
 
 /* Divider tables */
+static const struct clk_div_table dtable_1_8[] = {
+       {0, 1},
+       {1, 2},
+       {2, 4},
+       {3, 8},
+       {0, 0},
+};
+
 static const struct clk_div_table dtable_1_32[] = {
        {0, 1},
        {1, 2},
@@ -69,6 +78,7 @@ static const struct clk_div_table dtable_1_32[] = {
 static const char * const sel_pll3_3[] = { ".pll3_533", ".pll3_400" };
 static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" };
 static const char * const sel_shdi[] = { ".clk_533", ".clk_400", ".clk_266" };
+static const char * const sel_gpu2[] = { ".pll6", ".pll3_div2_2" };
 
 static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
        /* External Clock Inputs */
@@ -94,13 +104,13 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
        DEF_FIXED(".clk_400", CLK_PLL2_SDHI_400, CLK_PLL2_800, 1, 2),
        DEF_FIXED(".clk_266", CLK_PLL2_SDHI_266, CLK_PLL2_SDHI_533, 1, 2),
 
-       DEF_FIXED(".pll2_div16", CLK_PLL2_DIV16, CLK_PLL2, 1, 16),
-       DEF_FIXED(".pll2_div20", CLK_PLL2_DIV20, CLK_PLL2, 1, 20),
+       DEF_FIXED(".pll2_div2_8", CLK_PLL2_DIV2_8, CLK_PLL2_DIV2, 1, 8),
+       DEF_FIXED(".pll2_div2_10", CLK_PLL2_DIV2_10, CLK_PLL2_DIV2, 1, 10),
 
        DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2, CLK_PLL3, 1, 2),
+       DEF_FIXED(".pll3_div2_2", CLK_PLL3_DIV2_2, CLK_PLL3_DIV2, 1, 2),
        DEF_FIXED(".pll3_div2_4", CLK_PLL3_DIV2_4, CLK_PLL3_DIV2, 1, 4),
        DEF_FIXED(".pll3_div2_4_2", CLK_PLL3_DIV2_4_2, CLK_PLL3_DIV2_4, 1, 2),
-       DEF_FIXED(".pll3_div4", CLK_PLL3_DIV4, CLK_PLL3, 1, 4),
        DEF_MUX(".sel_pll3_3", CLK_SEL_PLL3_3, SEL_PLL3_3,
                sel_pll3_3, ARRAY_SIZE(sel_pll3_3), 0, CLK_MUX_READ_ONLY),
        DEF_DIV("divpl3c", CLK_DIV_PLL3_C, CLK_SEL_PLL3_3,
@@ -108,13 +118,16 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
 
        DEF_FIXED(".pll5_250", CLK_PLL5_250, CLK_PLL5_FOUT3, 1, 2),
        DEF_FIXED(".pll6_250", CLK_PLL6_250, CLK_PLL6, 1, 2),
+       DEF_MUX(".sel_gpu2", CLK_SEL_GPU2, SEL_GPU2,
+               sel_gpu2, ARRAY_SIZE(sel_gpu2), 0, CLK_MUX_READ_ONLY),
 
        /* Core output clk */
-       DEF_FIXED("I", R9A07G044_CLK_I, CLK_PLL1, 1, 1),
-       DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV16, DIVPL2A,
+       DEF_DIV("I", R9A07G044_CLK_I, CLK_PLL1, DIVPL1A, dtable_1_8,
+               CLK_DIVIDER_HIWORD_MASK),
+       DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV2_8, DIVPL2A,
                dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
        DEF_FIXED("P0_DIV2", R9A07G044_CLK_P0_DIV2, R9A07G044_CLK_P0, 1, 2),
-       DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV20, 1, 1),
+       DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV2_10, 1, 1),
        DEF_DIV("P1", R9A07G044_CLK_P1, CLK_PLL3_DIV2_4,
                DIVPL3B, dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
        DEF_FIXED("P1_DIV2", CLK_P1_DIV2, R9A07G044_CLK_P1, 1, 2),
@@ -132,6 +145,8 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
                   sel_shdi, ARRAY_SIZE(sel_shdi)),
        DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G044_CLK_SD0, 1, 4),
        DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G044_CLK_SD1, 1, 4),
+       DEF_DIV("G", R9A07G044_CLK_G, CLK_SEL_GPU2, DIVGPU, dtable_1_8,
+               CLK_DIVIDER_HIWORD_MASK),
 };
 
 static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
@@ -145,6 +160,24 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
                                0x52c, 0),
        DEF_MOD("dmac_pclk",    R9A07G044_DMAC_PCLK, CLK_P1_DIV2,
                                0x52c, 1),
+       DEF_MOD("ostm0_pclk",   R9A07G044_OSTM0_PCLK, R9A07G044_CLK_P0,
+                               0x534, 0),
+       DEF_MOD("ostm1_clk",    R9A07G044_OSTM1_PCLK, R9A07G044_CLK_P0,
+                               0x534, 1),
+       DEF_MOD("ostm2_pclk",   R9A07G044_OSTM2_PCLK, R9A07G044_CLK_P0,
+                               0x534, 2),
+       DEF_MOD("wdt0_pclk",    R9A07G044_WDT0_PCLK, R9A07G044_CLK_P0,
+                               0x548, 0),
+       DEF_MOD("wdt0_clk",     R9A07G044_WDT0_CLK, R9A07G044_OSCCLK,
+                               0x548, 1),
+       DEF_MOD("wdt1_pclk",    R9A07G044_WDT1_PCLK, R9A07G044_CLK_P0,
+                               0x548, 2),
+       DEF_MOD("wdt1_clk",     R9A07G044_WDT1_CLK, R9A07G044_OSCCLK,
+                               0x548, 3),
+       DEF_MOD("wdt2_pclk",    R9A07G044_WDT2_PCLK, R9A07G044_CLK_P0,
+                               0x548, 4),
+       DEF_MOD("wdt2_clk",     R9A07G044_WDT2_CLK, R9A07G044_OSCCLK,
+                               0x548, 5),
        DEF_MOD("spi_clk2",     R9A07G044_SPI_CLK2, R9A07G044_CLK_SPI1,
                                0x550, 0),
        DEF_MOD("spi_clk",      R9A07G044_SPI_CLK, R9A07G044_CLK_SPI0,
@@ -165,6 +198,12 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
                                0x554, 6),
        DEF_MOD("sdhi1_aclk",   R9A07G044_SDHI1_ACLK, R9A07G044_CLK_P1,
                                0x554, 7),
+       DEF_MOD("gpu_clk",      R9A07G044_GPU_CLK, R9A07G044_CLK_G,
+                               0x558, 0),
+       DEF_MOD("gpu_axi_clk",  R9A07G044_GPU_AXI_CLK, R9A07G044_CLK_P1,
+                               0x558, 1),
+       DEF_MOD("gpu_ace_clk",  R9A07G044_GPU_ACE_CLK, R9A07G044_CLK_P1,
+                               0x558, 2),
        DEF_MOD("ssi0_pclk",    R9A07G044_SSI0_PCLK2, R9A07G044_CLK_P0,
                                0x570, 0),
        DEF_MOD("ssi0_sfr",     R9A07G044_SSI0_PCLK_SFR, R9A07G044_CLK_P0,
@@ -217,6 +256,14 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
                                0x584, 4),
        DEF_MOD("sci0",         R9A07G044_SCI0_CLKP, R9A07G044_CLK_P0,
                                0x588, 0),
+       DEF_MOD("sci1",         R9A07G044_SCI1_CLKP, R9A07G044_CLK_P0,
+                               0x588, 1),
+       DEF_MOD("rspi0",        R9A07G044_RSPI0_CLKB, R9A07G044_CLK_P0,
+                               0x590, 0),
+       DEF_MOD("rspi1",        R9A07G044_RSPI1_CLKB, R9A07G044_CLK_P0,
+                               0x590, 1),
+       DEF_MOD("rspi2",        R9A07G044_RSPI2_CLKB, R9A07G044_CLK_P0,
+                               0x590, 2),
        DEF_MOD("canfd",        R9A07G044_CANFD_PCLK, R9A07G044_CLK_P0,
                                0x594, 0),
        DEF_MOD("gpio",         R9A07G044_GPIO_HCLK, R9A07G044_OSCCLK,
@@ -225,6 +272,8 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
                                0x5a8, 0),
        DEF_MOD("adc_pclk",     R9A07G044_ADC_PCLK, R9A07G044_CLK_P0,
                                0x5a8, 1),
+       DEF_MOD("tsu_pclk",     R9A07G044_TSU_PCLK, R9A07G044_CLK_TSU,
+                               0x5ac, 0),
 };
 
 static struct rzg2l_reset r9a07g044_resets[] = {
@@ -233,9 +282,18 @@ static struct rzg2l_reset r9a07g044_resets[] = {
        DEF_RST(R9A07G044_IA55_RESETN, 0x818, 0),
        DEF_RST(R9A07G044_DMAC_ARESETN, 0x82c, 0),
        DEF_RST(R9A07G044_DMAC_RST_ASYNC, 0x82c, 1),
+       DEF_RST(R9A07G044_OSTM0_PRESETZ, 0x834, 0),
+       DEF_RST(R9A07G044_OSTM1_PRESETZ, 0x834, 1),
+       DEF_RST(R9A07G044_OSTM2_PRESETZ, 0x834, 2),
+       DEF_RST(R9A07G044_WDT0_PRESETN, 0x848, 0),
+       DEF_RST(R9A07G044_WDT1_PRESETN, 0x848, 1),
+       DEF_RST(R9A07G044_WDT2_PRESETN, 0x848, 2),
        DEF_RST(R9A07G044_SPI_RST, 0x850, 0),
        DEF_RST(R9A07G044_SDHI0_IXRST, 0x854, 0),
        DEF_RST(R9A07G044_SDHI1_IXRST, 0x854, 1),
+       DEF_RST(R9A07G044_GPU_RESETN, 0x858, 0),
+       DEF_RST(R9A07G044_GPU_AXI_RESETN, 0x858, 1),
+       DEF_RST(R9A07G044_GPU_ACE_RESETN, 0x858, 2),
        DEF_RST(R9A07G044_SSI0_RST_M2_REG, 0x870, 0),
        DEF_RST(R9A07G044_SSI1_RST_M2_REG, 0x870, 1),
        DEF_RST(R9A07G044_SSI2_RST_M2_REG, 0x870, 2),
@@ -256,6 +314,10 @@ static struct rzg2l_reset r9a07g044_resets[] = {
        DEF_RST(R9A07G044_SCIF3_RST_SYSTEM_N, 0x884, 3),
        DEF_RST(R9A07G044_SCIF4_RST_SYSTEM_N, 0x884, 4),
        DEF_RST(R9A07G044_SCI0_RST, 0x888, 0),
+       DEF_RST(R9A07G044_SCI1_RST, 0x888, 1),
+       DEF_RST(R9A07G044_RSPI0_RST, 0x890, 0),
+       DEF_RST(R9A07G044_RSPI1_RST, 0x890, 1),
+       DEF_RST(R9A07G044_RSPI2_RST, 0x890, 2),
        DEF_RST(R9A07G044_CANFD_RSTP_N, 0x894, 0),
        DEF_RST(R9A07G044_CANFD_RSTC_N, 0x894, 1),
        DEF_RST(R9A07G044_GPIO_RSTN, 0x898, 0),
@@ -263,6 +325,7 @@ static struct rzg2l_reset r9a07g044_resets[] = {
        DEF_RST(R9A07G044_GPIO_SPARE_RESETN, 0x898, 2),
        DEF_RST(R9A07G044_ADC_PRESETN, 0x8a8, 0),
        DEF_RST(R9A07G044_ADC_ADRST_N, 0x8a8, 1),
+       DEF_RST(R9A07G044_TSU_PRESETN, 0x8ac, 0),
 };
 
 static const unsigned int r9a07g044_crit_mod_clks[] __initconst = {
index e93f001..e2e0447 100644 (file)
@@ -65,206 +65,49 @@ void cpg_simple_notifier_register(struct raw_notifier_head *notifiers,
 /*
  * SDn Clock
  */
-#define CPG_SD_STP_HCK         BIT(9)
-#define CPG_SD_STP_CK          BIT(8)
-
-#define CPG_SD_STP_MASK                (CPG_SD_STP_HCK | CPG_SD_STP_CK)
-#define CPG_SD_FC_MASK         (0x7 << 2 | 0x3 << 0)
-
-#define CPG_SD_DIV_TABLE_DATA(stp_hck, sd_srcfc, sd_fc, sd_div) \
-{ \
-       .val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \
-              ((sd_srcfc) << 2) | \
-              ((sd_fc) << 0), \
-       .div = (sd_div), \
-}
 
-struct sd_div_table {
-       u32 val;
-       unsigned int div;
-};
+#define SDnSRCFC_SHIFT 2
+#define STPnHCK        BIT(9 - SDnSRCFC_SHIFT)
 
-struct sd_clock {
-       struct clk_hw hw;
-       const struct sd_div_table *div_table;
-       struct cpg_simple_notifier csn;
-       unsigned int div_num;
-       unsigned int cur_div_idx;
-};
-
-/* SDn divider
- *           sd_srcfc   sd_fc   div
- * stp_hck   (div)      (div)     = sd_srcfc x sd_fc
- *---------------------------------------------------------
- *  0         0 (1)      1 (4)      4 : SDR104 / HS200 / HS400 (8 TAP)
- *  0         1 (2)      1 (4)      8 : SDR50
- *  1         2 (4)      1 (4)     16 : HS / SDR25
- *  1         3 (8)      1 (4)     32 : NS / SDR12
- *  1         4 (16)     1 (4)     64
- *  0         0 (1)      0 (2)      2
- *  0         1 (2)      0 (2)      4 : SDR104 / HS200 / HS400 (4 TAP)
- *  1         2 (4)      0 (2)      8
- *  1         3 (8)      0 (2)     16
- *  1         4 (16)     0 (2)     32
- *
- *  NOTE: There is a quirk option to ignore the first row of the dividers
- *  table when searching for suitable settings. This is because HS400 on
- *  early ES versions of H3 and M3-W requires a specific setting to work.
- */
-static const struct sd_div_table cpg_sd_div_table[] = {
-/*     CPG_SD_DIV_TABLE_DATA(stp_hck,  sd_srcfc,   sd_fc,  sd_div) */
-       CPG_SD_DIV_TABLE_DATA(0,        0,          1,        4),
-       CPG_SD_DIV_TABLE_DATA(0,        1,          1,        8),
-       CPG_SD_DIV_TABLE_DATA(1,        2,          1,       16),
-       CPG_SD_DIV_TABLE_DATA(1,        3,          1,       32),
-       CPG_SD_DIV_TABLE_DATA(1,        4,          1,       64),
-       CPG_SD_DIV_TABLE_DATA(0,        0,          0,        2),
-       CPG_SD_DIV_TABLE_DATA(0,        1,          0,        4),
-       CPG_SD_DIV_TABLE_DATA(1,        2,          0,        8),
-       CPG_SD_DIV_TABLE_DATA(1,        3,          0,       16),
-       CPG_SD_DIV_TABLE_DATA(1,        4,          0,       32),
+static const struct clk_div_table cpg_sdh_div_table[] = {
+       { 0, 1 }, { 1, 2 }, { STPnHCK | 2, 4 }, { STPnHCK | 3, 8 },
+       { STPnHCK | 4, 16 }, { 0, 0 },
 };
 
-#define to_sd_clock(_hw) container_of(_hw, struct sd_clock, hw)
-
-static int cpg_sd_clock_enable(struct clk_hw *hw)
-{
-       struct sd_clock *clock = to_sd_clock(hw);
-
-       cpg_reg_modify(clock->csn.reg, CPG_SD_STP_MASK,
-                      clock->div_table[clock->cur_div_idx].val &
-                      CPG_SD_STP_MASK);
-
-       return 0;
-}
-
-static void cpg_sd_clock_disable(struct clk_hw *hw)
-{
-       struct sd_clock *clock = to_sd_clock(hw);
-
-       cpg_reg_modify(clock->csn.reg, 0, CPG_SD_STP_MASK);
-}
-
-static int cpg_sd_clock_is_enabled(struct clk_hw *hw)
+struct clk * __init cpg_sdh_clk_register(const char *name,
+       void __iomem *sdnckcr, const char *parent_name,
+       struct raw_notifier_head *notifiers)
 {
-       struct sd_clock *clock = to_sd_clock(hw);
-
-       return !(readl(clock->csn.reg) & CPG_SD_STP_MASK);
-}
+       struct cpg_simple_notifier *csn;
+       struct clk *clk;
 
-static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw,
-                                               unsigned long parent_rate)
-{
-       struct sd_clock *clock = to_sd_clock(hw);
+       csn = kzalloc(sizeof(*csn), GFP_KERNEL);
+       if (!csn)
+               return ERR_PTR(-ENOMEM);
 
-       return DIV_ROUND_CLOSEST(parent_rate,
-                                clock->div_table[clock->cur_div_idx].div);
-}
+       csn->reg = sdnckcr;
 
-static int cpg_sd_clock_determine_rate(struct clk_hw *hw,
-                                      struct clk_rate_request *req)
-{
-       unsigned long best_rate = ULONG_MAX, diff_min = ULONG_MAX;
-       struct sd_clock *clock = to_sd_clock(hw);
-       unsigned long calc_rate, diff;
-       unsigned int i;
-
-       for (i = 0; i < clock->div_num; i++) {
-               calc_rate = DIV_ROUND_CLOSEST(req->best_parent_rate,
-                                             clock->div_table[i].div);
-               if (calc_rate < req->min_rate || calc_rate > req->max_rate)
-                       continue;
-
-               diff = calc_rate > req->rate ? calc_rate - req->rate
-                                            : req->rate - calc_rate;
-               if (diff < diff_min) {
-                       best_rate = calc_rate;
-                       diff_min = diff;
-               }
+       clk = clk_register_divider_table(NULL, name, parent_name, 0, sdnckcr,
+                                        SDnSRCFC_SHIFT, 8, 0, cpg_sdh_div_table,
+                                        &cpg_lock);
+       if (IS_ERR(clk)) {
+               kfree(csn);
+               return clk;
        }
 
-       if (best_rate == ULONG_MAX)
-               return -EINVAL;
-
-       req->rate = best_rate;
-       return 0;
-}
-
-static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate,
-                                unsigned long parent_rate)
-{
-       struct sd_clock *clock = to_sd_clock(hw);
-       unsigned int i;
-
-       for (i = 0; i < clock->div_num; i++)
-               if (rate == DIV_ROUND_CLOSEST(parent_rate,
-                                             clock->div_table[i].div))
-                       break;
-
-       if (i >= clock->div_num)
-               return -EINVAL;
-
-       clock->cur_div_idx = i;
-
-       cpg_reg_modify(clock->csn.reg, CPG_SD_STP_MASK | CPG_SD_FC_MASK,
-                      clock->div_table[i].val &
-                      (CPG_SD_STP_MASK | CPG_SD_FC_MASK));
-
-       return 0;
+       cpg_simple_notifier_register(notifiers, csn);
+       return clk;
 }
 
-static const struct clk_ops cpg_sd_clock_ops = {
-       .enable = cpg_sd_clock_enable,
-       .disable = cpg_sd_clock_disable,
-       .is_enabled = cpg_sd_clock_is_enabled,
-       .recalc_rate = cpg_sd_clock_recalc_rate,
-       .determine_rate = cpg_sd_clock_determine_rate,
-       .set_rate = cpg_sd_clock_set_rate,
+static const struct clk_div_table cpg_sd_div_table[] = {
+       { 0, 2 }, { 1, 4 }, { 0, 0 },
 };
 
 struct clk * __init cpg_sd_clk_register(const char *name,
-       void __iomem *base, unsigned int offset, const char *parent_name,
-       struct raw_notifier_head *notifiers, bool skip_first)
+       void __iomem *sdnckcr, const char *parent_name)
 {
-       struct clk_init_data init = {};
-       struct sd_clock *clock;
-       struct clk *clk;
-       u32 val;
-
-       clock = kzalloc(sizeof(*clock), GFP_KERNEL);
-       if (!clock)
-               return ERR_PTR(-ENOMEM);
-
-       init.name = name;
-       init.ops = &cpg_sd_clock_ops;
-       init.flags = CLK_SET_RATE_PARENT;
-       init.parent_names = &parent_name;
-       init.num_parents = 1;
-
-       clock->csn.reg = base + offset;
-       clock->hw.init = &init;
-       clock->div_table = cpg_sd_div_table;
-       clock->div_num = ARRAY_SIZE(cpg_sd_div_table);
-
-       if (skip_first) {
-               clock->div_table++;
-               clock->div_num--;
-       }
-
-       val = readl(clock->csn.reg) & ~CPG_SD_FC_MASK;
-       val |= CPG_SD_STP_MASK | (clock->div_table[0].val & CPG_SD_FC_MASK);
-       writel(val, clock->csn.reg);
-
-       clk = clk_register(NULL, &clock->hw);
-       if (IS_ERR(clk))
-               goto free_clock;
-
-       cpg_simple_notifier_register(notifiers, &clock->csn);
-       return clk;
-
-free_clock:
-       kfree(clock);
-       return clk;
+       return clk_register_divider_table(NULL, name, parent_name, 0, sdnckcr,
+                                         0, 2, 0, cpg_sd_div_table, &cpg_lock);
 }
 
 struct rpc_clock {
index 35c0217..94627df 100644 (file)
@@ -26,9 +26,12 @@ void cpg_simple_notifier_register(struct raw_notifier_head *notifiers,
 
 void cpg_reg_modify(void __iomem *reg, u32 clear, u32 set);
 
+struct clk * __init cpg_sdh_clk_register(const char *name,
+       void __iomem *sdnckcr, const char *parent_name,
+       struct raw_notifier_head *notifiers);
+
 struct clk * __init cpg_sd_clk_register(const char *name,
-       void __iomem *base, unsigned int offset, const char *parent_name,
-       struct raw_notifier_head *notifiers, bool skip_first);
+       void __iomem *sdnckcr, const char *parent_name);
 
 struct clk * __init cpg_rpc_clk_register(const char *name,
        void __iomem *rpcckcr, const char *parent_name,
index 741f6e7..e668f23 100644 (file)
@@ -312,29 +312,20 @@ static u32 cpg_quirks __initdata;
 
 #define PLL_ERRATA     BIT(0)          /* Missing PLL0/2/4 post-divider */
 #define RCKCR_CKSEL    BIT(1)          /* Manual RCLK parent selection */
-#define SD_SKIP_FIRST  BIT(2)          /* Skip first clock in SD table */
 
 
 static const struct soc_device_attribute cpg_quirks_match[] __initconst = {
        {
                .soc_id = "r8a7795", .revision = "ES1.0",
-               .data = (void *)(PLL_ERRATA | RCKCR_CKSEL | SD_SKIP_FIRST),
+               .data = (void *)(PLL_ERRATA | RCKCR_CKSEL),
        },
        {
                .soc_id = "r8a7795", .revision = "ES1.*",
-               .data = (void *)(RCKCR_CKSEL | SD_SKIP_FIRST),
-       },
-       {
-               .soc_id = "r8a7795", .revision = "ES2.0",
-               .data = (void *)SD_SKIP_FIRST,
+               .data = (void *)(RCKCR_CKSEL),
        },
        {
                .soc_id = "r8a7796", .revision = "ES1.0",
-               .data = (void *)(RCKCR_CKSEL | SD_SKIP_FIRST),
-       },
-       {
-               .soc_id = "r8a7796", .revision = "ES1.1",
-               .data = (void *)SD_SKIP_FIRST,
+               .data = (void *)(RCKCR_CKSEL),
        },
        { /* sentinel */ }
 };
@@ -401,10 +392,13 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
                        mult *= 2;
                break;
 
+       case CLK_TYPE_GEN3_SDH:
+               return cpg_sdh_clk_register(core->name, base + core->offset,
+                                          __clk_get_name(parent), notifiers);
+
        case CLK_TYPE_GEN3_SD:
-               return cpg_sd_clk_register(core->name, base, core->offset,
-                                          __clk_get_name(parent), notifiers,
-                                          cpg_quirks & SD_SKIP_FIRST);
+               return cpg_sd_clk_register(core->name, base + core->offset,
+                                          __clk_get_name(parent));
 
        case CLK_TYPE_GEN3_R:
                if (cpg_quirks & RCKCR_CKSEL) {
index 3d949c4..2bc0afa 100644 (file)
@@ -17,6 +17,7 @@ enum rcar_gen3_clk_types {
        CLK_TYPE_GEN3_PLL2,
        CLK_TYPE_GEN3_PLL3,
        CLK_TYPE_GEN3_PLL4,
+       CLK_TYPE_GEN3_SDH,
        CLK_TYPE_GEN3_SD,
        CLK_TYPE_GEN3_R,
        CLK_TYPE_GEN3_MDSEL,    /* Select parent/divider using mode pin */
@@ -32,6 +33,9 @@ enum rcar_gen3_clk_types {
        CLK_TYPE_GEN3_SOC_BASE,
 };
 
+#define DEF_GEN3_SDH(_name, _id, _parent, _offset)     \
+       DEF_BASE(_name, _id, CLK_TYPE_GEN3_SDH, _parent, .offset = _offset)
+
 #define DEF_GEN3_SD(_name, _id, _parent, _offset)      \
        DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset)
 
diff --git a/drivers/clk/renesas/rcar-gen4-cpg.c b/drivers/clk/renesas/rcar-gen4-cpg.c
new file mode 100644 (file)
index 0000000..54ebf4b
--- /dev/null
@@ -0,0 +1,305 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * R-Car Gen4 Clock Pulse Generator
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ *
+ * Based on rcar-gen3-cpg.c
+ *
+ * Copyright (C) 2015-2018 Glider bvba
+ * Copyright (C) 2019 Renesas Electronics Corp.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen4-cpg.h"
+#include "rcar-cpg-lib.h"
+
+static const struct rcar_gen4_cpg_pll_config *cpg_pll_config __initconst;
+static unsigned int cpg_clk_extalr __initdata;
+static u32 cpg_mode __initdata;
+
+/*
+ * Z0 Clock & Z1 Clock
+ */
+#define CPG_FRQCRB                     0x00000804
+#define CPG_FRQCRB_KICK                        BIT(31)
+#define CPG_FRQCRC                     0x00000808
+
+struct cpg_z_clk {
+       struct clk_hw hw;
+       void __iomem *reg;
+       void __iomem *kick_reg;
+       unsigned long max_rate;         /* Maximum rate for normal mode */
+       unsigned int fixed_div;
+       u32 mask;
+};
+
+#define to_z_clk(_hw)  container_of(_hw, struct cpg_z_clk, hw)
+
+static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw,
+                                          unsigned long parent_rate)
+{
+       struct cpg_z_clk *zclk = to_z_clk(hw);
+       unsigned int mult;
+       u32 val;
+
+       val = readl(zclk->reg) & zclk->mask;
+       mult = 32 - (val >> __ffs(zclk->mask));
+
+       return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult,
+                                    32 * zclk->fixed_div);
+}
+
+static int cpg_z_clk_determine_rate(struct clk_hw *hw,
+                                   struct clk_rate_request *req)
+{
+       struct cpg_z_clk *zclk = to_z_clk(hw);
+       unsigned int min_mult, max_mult, mult;
+       unsigned long rate, prate;
+
+       rate = min(req->rate, req->max_rate);
+       if (rate <= zclk->max_rate) {
+               /* Set parent rate to initial value for normal modes */
+               prate = zclk->max_rate;
+       } else {
+               /* Set increased parent rate for boost modes */
+               prate = rate;
+       }
+       req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
+                                                 prate * zclk->fixed_div);
+
+       prate = req->best_parent_rate / zclk->fixed_div;
+       min_mult = max(div64_ul(req->min_rate * 32ULL, prate), 1ULL);
+       max_mult = min(div64_ul(req->max_rate * 32ULL, prate), 32ULL);
+       if (max_mult < min_mult)
+               return -EINVAL;
+
+       mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL, prate);
+       mult = clamp(mult, min_mult, max_mult);
+
+       req->rate = DIV_ROUND_CLOSEST_ULL((u64)prate * mult, 32);
+       return 0;
+}
+
+static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+                             unsigned long parent_rate)
+{
+       struct cpg_z_clk *zclk = to_z_clk(hw);
+       unsigned int mult;
+       unsigned int i;
+
+       mult = DIV64_U64_ROUND_CLOSEST(rate * 32ULL * zclk->fixed_div,
+                                      parent_rate);
+       mult = clamp(mult, 1U, 32U);
+
+       if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK)
+               return -EBUSY;
+
+       cpg_reg_modify(zclk->reg, zclk->mask, (32 - mult) << __ffs(zclk->mask));
+
+       /*
+        * Set KICK bit in FRQCRB to update hardware setting and wait for
+        * clock change completion.
+        */
+       cpg_reg_modify(zclk->kick_reg, 0, CPG_FRQCRB_KICK);
+
+       /*
+        * Note: There is no HW information about the worst case latency.
+        *
+        * Using experimental measurements, it seems that no more than
+        * ~10 iterations are needed, independently of the CPU rate.
+        * Since this value might be dependent on external xtal rate, pll1
+        * rate or even the other emulation clocks rate, use 1000 as a
+        * "super" safe value.
+        */
+       for (i = 1000; i; i--) {
+               if (!(readl(zclk->kick_reg) & CPG_FRQCRB_KICK))
+                       return 0;
+
+               cpu_relax();
+       }
+
+       return -ETIMEDOUT;
+}
+
+static const struct clk_ops cpg_z_clk_ops = {
+       .recalc_rate = cpg_z_clk_recalc_rate,
+       .determine_rate = cpg_z_clk_determine_rate,
+       .set_rate = cpg_z_clk_set_rate,
+};
+
+static struct clk * __init cpg_z_clk_register(const char *name,
+                                             const char *parent_name,
+                                             void __iomem *reg,
+                                             unsigned int div,
+                                             unsigned int offset)
+{
+       struct clk_init_data init = {};
+       struct cpg_z_clk *zclk;
+       struct clk *clk;
+
+       zclk = kzalloc(sizeof(*zclk), GFP_KERNEL);
+       if (!zclk)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &cpg_z_clk_ops;
+       init.flags = CLK_SET_RATE_PARENT;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       zclk->reg = reg + CPG_FRQCRC;
+       zclk->kick_reg = reg + CPG_FRQCRB;
+       zclk->hw.init = &init;
+       zclk->mask = GENMASK(offset + 4, offset);
+       zclk->fixed_div = div; /* PLLVCO x 1/div x SYS-CPU divider */
+
+       clk = clk_register(NULL, &zclk->hw);
+       if (IS_ERR(clk)) {
+               kfree(zclk);
+               return clk;
+       }
+
+       zclk->max_rate = clk_hw_get_rate(clk_hw_get_parent(&zclk->hw)) /
+                        zclk->fixed_div;
+       return clk;
+}
+
+/*
+ * RPC Clocks
+ */
+static const struct clk_div_table cpg_rpcsrc_div_table[] = {
+       { 0, 4 }, { 1, 6 }, { 2, 5 }, { 3, 6 }, { 0, 0 },
+};
+
+struct clk * __init rcar_gen4_cpg_clk_register(struct device *dev,
+       const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
+       struct clk **clks, void __iomem *base,
+       struct raw_notifier_head *notifiers)
+{
+       const struct clk *parent;
+       unsigned int mult = 1;
+       unsigned int div = 1;
+       u32 value;
+
+       parent = clks[core->parent & 0xffff];   /* some types use high bits */
+       if (IS_ERR(parent))
+               return ERR_CAST(parent);
+
+       switch (core->type) {
+       case CLK_TYPE_GEN4_MAIN:
+               div = cpg_pll_config->extal_div;
+               break;
+
+       case CLK_TYPE_GEN4_PLL1:
+               mult = cpg_pll_config->pll1_mult;
+               div = cpg_pll_config->pll1_div;
+               break;
+
+       case CLK_TYPE_GEN4_PLL2:
+               mult = cpg_pll_config->pll2_mult;
+               div = cpg_pll_config->pll2_div;
+               break;
+
+       case CLK_TYPE_GEN4_PLL3:
+               mult = cpg_pll_config->pll3_mult;
+               div = cpg_pll_config->pll3_div;
+               break;
+
+       case CLK_TYPE_GEN4_PLL5:
+               mult = cpg_pll_config->pll5_mult;
+               div = cpg_pll_config->pll5_div;
+               break;
+
+       case CLK_TYPE_GEN4_PLL6:
+               mult = cpg_pll_config->pll6_mult;
+               div = cpg_pll_config->pll6_div;
+               break;
+
+       case CLK_TYPE_GEN4_PLL2X_3X:
+               value = readl(base + core->offset);
+               mult = (((value >> 24) & 0x7f) + 1) * 2;
+               break;
+
+       case CLK_TYPE_GEN4_Z:
+               return cpg_z_clk_register(core->name, __clk_get_name(parent),
+                                         base, core->div, core->offset);
+
+       case CLK_TYPE_GEN4_SDSRC:
+               div = ((readl(base + SD0CKCR1) >> 29) & 0x03) + 4;
+               break;
+
+       case CLK_TYPE_GEN4_SDH:
+               return cpg_sdh_clk_register(core->name, base + core->offset,
+                                          __clk_get_name(parent), notifiers);
+
+       case CLK_TYPE_GEN4_SD:
+               return cpg_sd_clk_register(core->name, base + core->offset,
+                                          __clk_get_name(parent));
+
+       case CLK_TYPE_GEN4_MDSEL:
+               /*
+                * Clock selectable between two parents and two fixed dividers
+                * using a mode pin
+                */
+               if (cpg_mode & BIT(core->offset)) {
+                       div = core->div & 0xffff;
+               } else {
+                       parent = clks[core->parent >> 16];
+                       if (IS_ERR(parent))
+                               return ERR_CAST(parent);
+                       div = core->div >> 16;
+               }
+               mult = 1;
+               break;
+
+       case CLK_TYPE_GEN4_OSC:
+               /*
+                * Clock combining OSC EXTAL predivider and a fixed divider
+                */
+               div = cpg_pll_config->osc_prediv * core->div;
+               break;
+
+       case CLK_TYPE_GEN4_RPCSRC:
+               return clk_register_divider_table(NULL, core->name,
+                                                 __clk_get_name(parent), 0,
+                                                 base + CPG_RPCCKCR, 3, 2, 0,
+                                                 cpg_rpcsrc_div_table,
+                                                 &cpg_lock);
+
+       case CLK_TYPE_GEN4_RPC:
+               return cpg_rpc_clk_register(core->name, base + CPG_RPCCKCR,
+                                           __clk_get_name(parent), notifiers);
+
+       case CLK_TYPE_GEN4_RPCD2:
+               return cpg_rpcd2_clk_register(core->name, base + CPG_RPCCKCR,
+                                             __clk_get_name(parent));
+
+       default:
+               return ERR_PTR(-EINVAL);
+       }
+
+       return clk_register_fixed_factor(NULL, core->name,
+                                        __clk_get_name(parent), 0, mult, div);
+}
+
+int __init rcar_gen4_cpg_init(const struct rcar_gen4_cpg_pll_config *config,
+                             unsigned int clk_extalr, u32 mode)
+{
+       cpg_pll_config = config;
+       cpg_clk_extalr = clk_extalr;
+       cpg_mode = mode;
+
+       spin_lock_init(&cpg_lock);
+
+       return 0;
+}
diff --git a/drivers/clk/renesas/rcar-gen4-cpg.h b/drivers/clk/renesas/rcar-gen4-cpg.h
new file mode 100644 (file)
index 0000000..afc8c02
--- /dev/null
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * R-Car Gen4 Clock Pulse Generator
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ *
+ */
+
+#ifndef __CLK_RENESAS_RCAR_GEN4_CPG_H__
+#define __CLK_RENESAS_RCAR_GEN4_CPG_H__
+
+enum rcar_gen4_clk_types {
+       CLK_TYPE_GEN4_MAIN = CLK_TYPE_CUSTOM,
+       CLK_TYPE_GEN4_PLL1,
+       CLK_TYPE_GEN4_PLL2,
+       CLK_TYPE_GEN4_PLL2X_3X, /* r8a779a0 only */
+       CLK_TYPE_GEN4_PLL3,
+       CLK_TYPE_GEN4_PLL5,
+       CLK_TYPE_GEN4_PLL6,
+       CLK_TYPE_GEN4_SDSRC,
+       CLK_TYPE_GEN4_SDH,
+       CLK_TYPE_GEN4_SD,
+       CLK_TYPE_GEN4_MDSEL,    /* Select parent/divider using mode pin */
+       CLK_TYPE_GEN4_Z,
+       CLK_TYPE_GEN4_OSC,      /* OSC EXTAL predivider and fixed divider */
+       CLK_TYPE_GEN4_RPCSRC,
+       CLK_TYPE_GEN4_RPC,
+       CLK_TYPE_GEN4_RPCD2,
+
+       /* SoC specific definitions start here */
+       CLK_TYPE_GEN4_SOC_BASE,
+};
+
+#define DEF_GEN4_SDH(_name, _id, _parent, _offset)     \
+       DEF_BASE(_name, _id, CLK_TYPE_GEN4_SDH, _parent, .offset = _offset)
+
+#define DEF_GEN4_SD(_name, _id, _parent, _offset)      \
+       DEF_BASE(_name, _id, CLK_TYPE_GEN4_SD, _parent, .offset = _offset)
+
+#define DEF_GEN4_MDSEL(_name, _id, _md, _parent0, _div0, _parent1, _div1) \
+       DEF_BASE(_name, _id, CLK_TYPE_GEN4_MDSEL,       \
+                (_parent0) << 16 | (_parent1),         \
+                .div = (_div0) << 16 | (_div1), .offset = _md)
+
+#define DEF_GEN4_OSC(_name, _id, _parent, _div)                \
+       DEF_BASE(_name, _id, CLK_TYPE_GEN4_OSC, _parent, .div = _div)
+
+#define DEF_GEN4_Z(_name, _id, _type, _parent, _div, _offset)  \
+       DEF_BASE(_name, _id, _type, _parent, .div = _div, .offset = _offset)
+
+struct rcar_gen4_cpg_pll_config {
+       u8 extal_div;
+       u8 pll1_mult;
+       u8 pll1_div;
+       u8 pll2_mult;
+       u8 pll2_div;
+       u8 pll3_mult;
+       u8 pll3_div;
+       u8 pll5_mult;
+       u8 pll5_div;
+       u8 pll6_mult;
+       u8 pll6_div;
+       u8 osc_prediv;
+};
+
+#define CPG_RPCCKCR    0x874
+#define SD0CKCR1       0x8a4
+
+struct clk *rcar_gen4_cpg_clk_register(struct device *dev,
+       const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
+       struct clk **clks, void __iomem *base,
+       struct raw_notifier_head *notifiers);
+int rcar_gen4_cpg_init(const struct rcar_gen4_cpg_pll_config *config,
+                      unsigned int clk_extalr, u32 mode);
+
+#endif
index 21f762a..5d2c3ed 100644 (file)
@@ -57,9 +57,11 @@ static const u16 mstpsr[] = {
        0x9A0, 0x9A4, 0x9A8, 0x9AC,
 };
 
-static const u16 mstpsr_for_v3u[] = {
+static const u16 mstpsr_for_gen4[] = {
        0x2E00, 0x2E04, 0x2E08, 0x2E0C, 0x2E10, 0x2E14, 0x2E18, 0x2E1C,
-       0x2E20, 0x2E24, 0x2E28, 0x2E2C, 0x2E30, 0x2E34, 0x2E38,
+       0x2E20, 0x2E24, 0x2E28, 0x2E2C, 0x2E30, 0x2E34, 0x2E38, 0x2E3C,
+       0x2E40, 0x2E44, 0x2E48, 0x2E4C, 0x2E50, 0x2E54, 0x2E58, 0x2E5C,
+       0x2E60, 0x2E64, 0x2E68, 0x2E6C,
 };
 
 /*
@@ -71,9 +73,11 @@ static const u16 smstpcr[] = {
        0x990, 0x994, 0x998, 0x99C,
 };
 
-static const u16 mstpcr_for_v3u[] = {
+static const u16 mstpcr_for_gen4[] = {
        0x2D00, 0x2D04, 0x2D08, 0x2D0C, 0x2D10, 0x2D14, 0x2D18, 0x2D1C,
-       0x2D20, 0x2D24, 0x2D28, 0x2D2C, 0x2D30, 0x2D34, 0x2D38,
+       0x2D20, 0x2D24, 0x2D28, 0x2D2C, 0x2D30, 0x2D34, 0x2D38, 0x2D3C,
+       0x2D40, 0x2D44, 0x2D48, 0x2D4C, 0x2D50, 0x2D54, 0x2D58, 0x2D5C,
+       0x2D60, 0x2D64, 0x2D68, 0x2D6C,
 };
 
 /*
@@ -95,9 +99,11 @@ static const u16 srcr[] = {
        0x920, 0x924, 0x928, 0x92C,
 };
 
-static const u16 srcr_for_v3u[] = {
+static const u16 srcr_for_gen4[] = {
        0x2C00, 0x2C04, 0x2C08, 0x2C0C, 0x2C10, 0x2C14, 0x2C18, 0x2C1C,
-       0x2C20, 0x2C24, 0x2C28, 0x2C2C, 0x2C30, 0x2C34, 0x2C38,
+       0x2C20, 0x2C24, 0x2C28, 0x2C2C, 0x2C30, 0x2C34, 0x2C38, 0x2C3C,
+       0x2C40, 0x2C44, 0x2C48, 0x2C4C, 0x2C50, 0x2C54, 0x2C58, 0x2C5C,
+       0x2C60, 0x2C64, 0x2C68, 0x2C6C,
 };
 
 /*
@@ -109,9 +115,11 @@ static const u16 srstclr[] = {
        0x960, 0x964, 0x968, 0x96C,
 };
 
-static const u16 srstclr_for_v3u[] = {
+static const u16 srstclr_for_gen4[] = {
        0x2C80, 0x2C84, 0x2C88, 0x2C8C, 0x2C90, 0x2C94, 0x2C98, 0x2C9C,
-       0x2CA0, 0x2CA4, 0x2CA8, 0x2CAC, 0x2CB0, 0x2CB4, 0x2CB8,
+       0x2CA0, 0x2CA4, 0x2CA8, 0x2CAC, 0x2CB0, 0x2CB4, 0x2CB8, 0x2CBC,
+       0x2CC0, 0x2CC4, 0x2CC8, 0x2CCC, 0x2CD0, 0x2CD4, 0x2CD8, 0x2CDC,
+       0x2CE0, 0x2CE4, 0x2CE8, 0x2CEC,
 };
 
 /**
@@ -158,7 +166,7 @@ struct cpg_mssr_priv {
        struct {
                u32 mask;
                u32 val;
-       } smstpcr_saved[ARRAY_SIZE(mstpsr_for_v3u)];
+       } smstpcr_saved[ARRAY_SIZE(mstpsr_for_gen4)];
 
        struct clk *clks[];
 };
@@ -552,6 +560,11 @@ void cpg_mssr_detach_dev(struct generic_pm_domain *unused, struct device *dev)
                pm_clk_destroy(dev);
 }
 
+static void cpg_mssr_genpd_remove(void *data)
+{
+       pm_genpd_remove(data);
+}
+
 static int __init cpg_mssr_add_clk_domain(struct device *dev,
                                          const unsigned int *core_pm_clks,
                                          unsigned int num_core_pm_clks)
@@ -560,6 +573,7 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev,
        struct generic_pm_domain *genpd;
        struct cpg_mssr_clk_domain *pd;
        size_t pm_size = num_core_pm_clks * sizeof(core_pm_clks[0]);
+       int ret;
 
        pd = devm_kzalloc(dev, sizeof(*pd) + pm_size, GFP_KERNEL);
        if (!pd)
@@ -574,11 +588,17 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev,
                       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);
+       ret = pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
+       if (ret)
+               return ret;
+
+       ret = devm_add_action_or_reset(dev, cpg_mssr_genpd_remove, genpd);
+       if (ret)
+               return ret;
+
        cpg_mssr_clk_domain = pd;
 
-       of_genpd_add_provider_simple(np, genpd);
-       return 0;
+       return of_genpd_add_provider_simple(np, genpd);
 }
 
 #ifdef CONFIG_RESET_CONTROLLER
@@ -827,6 +847,12 @@ static const struct of_device_id cpg_mssr_match[] = {
                .compatible = "renesas,r8a779a0-cpg-mssr",
                .data = &r8a779a0_cpg_mssr_info,
        },
+#endif
+#ifdef CONFIG_CLK_R8A779F0
+       {
+               .compatible = "renesas,r8a779f0-cpg-mssr",
+               .data = &r8a779f0_cpg_mssr_info,
+       },
 #endif
        { /* sentinel */ }
 };
@@ -970,11 +996,11 @@ static int __init cpg_mssr_common_init(struct device *dev,
                priv->reset_clear_regs = srstclr;
        } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
                priv->control_regs = stbcr;
-       } else if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_V3U) {
-               priv->status_regs = mstpsr_for_v3u;
-               priv->control_regs = mstpcr_for_v3u;
-               priv->reset_regs = srcr_for_v3u;
-               priv->reset_clear_regs = srstclr_for_v3u;
+       } else if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) {
+               priv->status_regs = mstpsr_for_gen4;
+               priv->control_regs = mstpcr_for_gen4;
+               priv->reset_regs = srcr_for_gen4;
+               priv->reset_clear_regs = srstclr_for_gen4;
        } else {
                error = -EINVAL;
                goto out_err;
index 6b2a0ad..16810dd 100644 (file)
@@ -88,7 +88,7 @@ struct device_node;
 enum clk_reg_layout {
        CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3 = 0,
        CLK_REG_LAYOUT_RZ_A,
-       CLK_REG_LAYOUT_RCAR_V3U,
+       CLK_REG_LAYOUT_RCAR_GEN4,
 };
 
     /**
@@ -178,6 +178,7 @@ extern const struct cpg_mssr_info r8a77980_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a77990_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a77995_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a779a0_cpg_mssr_info;
+extern const struct cpg_mssr_info r8a779f0_cpg_mssr_info;
 
 void __init cpg_mssr_early_init(struct device_node *np,
                                const struct cpg_mssr_info *info);
index 4021f6c..edd0abe 100644 (file)
@@ -74,6 +74,7 @@ struct sd_hw_data {
  * @clks: Array containing all Core and Module Clocks
  * @num_core_clks: Number of Core Clocks in clks[]
  * @num_mod_clks: Number of Module Clocks in clks[]
+ * @num_resets: Number of Module Resets in info->resets[]
  * @last_dt_core_clk: ID of the last Core Clock exported to DT
  * @notifiers: Notifier chain to save/restore clock state for system resume
  * @info: Pointer to platform data
@@ -850,10 +851,16 @@ static void rzg2l_cpg_detach_dev(struct generic_pm_domain *unused, struct device
                pm_clk_destroy(dev);
 }
 
+static void rzg2l_cpg_genpd_remove(void *data)
+{
+       pm_genpd_remove(data);
+}
+
 static int __init rzg2l_cpg_add_clk_domain(struct device *dev)
 {
        struct device_node *np = dev->of_node;
        struct generic_pm_domain *genpd;
+       int ret;
 
        genpd = devm_kzalloc(dev, sizeof(*genpd), GFP_KERNEL);
        if (!genpd)
@@ -864,10 +871,15 @@ static int __init rzg2l_cpg_add_clk_domain(struct device *dev)
                       GENPD_FLAG_ACTIVE_WAKEUP;
        genpd->attach_dev = rzg2l_cpg_attach_dev;
        genpd->detach_dev = rzg2l_cpg_detach_dev;
-       pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
+       ret = pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
+       if (ret)
+               return ret;
 
-       of_genpd_add_provider_simple(np, genpd);
-       return 0;
+       ret = devm_add_action_or_reset(dev, rzg2l_cpg_genpd_remove, genpd);
+       if (ret)
+               return ret;
+
+       return of_genpd_add_provider_simple(np, genpd);
 }
 
 static int __init rzg2l_cpg_probe(struct platform_device *pdev)
index 7fb6b40..5729d10 100644 (file)
@@ -9,11 +9,14 @@
 #ifndef __RENESAS_RZG2L_CPG_H__
 #define __RENESAS_RZG2L_CPG_H__
 
+#define CPG_PL1_DDIV           (0x200)
 #define CPG_PL2_DDIV           (0x204)
 #define CPG_PL3A_DDIV          (0x208)
+#define CPG_PL6_DDIV           (0x210)
 #define CPG_PL2SDHI_DSEL       (0x218)
 #define CPG_CLKSTATUS          (0x280)
 #define CPG_PL3_SSEL           (0x408)
+#define CPG_PL6_SSEL           (0x414)
 #define CPG_PL6_ETH_SSEL       (0x418)
 
 #define CPG_CLKSTATUS_SELSDHI0_STS     BIT(28)
 
 #define DDIV_PACK(offset, bitpos, size) \
                (((offset) << 20) | ((bitpos) << 12) | ((size) << 8))
+#define DIVPL1A                DDIV_PACK(CPG_PL1_DDIV, 0, 2)
 #define DIVPL2A                DDIV_PACK(CPG_PL2_DDIV, 0, 3)
 #define DIVPL3A                DDIV_PACK(CPG_PL3A_DDIV, 0, 3)
 #define DIVPL3B                DDIV_PACK(CPG_PL3A_DDIV, 4, 3)
 #define DIVPL3C                DDIV_PACK(CPG_PL3A_DDIV, 8, 3)
+#define DIVGPU         DDIV_PACK(CPG_PL6_DDIV, 0, 2)
 
 #define SEL_PLL_PACK(offset, bitpos, size) \
                (((offset) << 20) | ((bitpos) << 12) | ((size) << 8))
 
 #define SEL_PLL3_3     SEL_PLL_PACK(CPG_PL3_SSEL, 8, 1)
 #define SEL_PLL6_2     SEL_PLL_PACK(CPG_PL6_ETH_SSEL, 0, 1)
+#define SEL_GPU2       SEL_PLL_PACK(CPG_PL6_SSEL, 12, 1)
 
 #define SEL_SDHI0      DDIV_PACK(CPG_PL2SDHI_DSEL, 0, 2)
 #define SEL_SDHI1      DDIV_PACK(CPG_PL2SDHI_DSEL, 4, 2)
@@ -168,6 +174,9 @@ struct rzg2l_reset {
  * @num_mod_clks: Number of entries in mod_clks[]
  * @num_hw_mod_clks: Number of Module Clocks supported by the hardware
  *
+ * @resets: Array of Module Reset definitions
+ * @num_resets: Number of entries in resets[]
+ *
  * @crit_mod_clks: Array with Module Clock IDs of critical clocks that
  *                 should not be disabled without a knowledgeable driver
  * @num_crit_mod_clks: Number of entries in crit_mod_clks[]
index c46cf11..0df7491 100644 (file)
@@ -16,7 +16,9 @@ obj-$(CONFIG_EXYNOS_5420_COMMON_CLK)  += clk-exynos5-subcmu.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)  += clk-exynos5433.o
 obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
 obj-$(CONFIG_EXYNOS_CLKOUT)    += clk-exynos-clkout.o
+obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)  += clk-exynos-arm64.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)  += clk-exynos7.o
+obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)  += clk-exynos7885.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)  += clk-exynos850.o
 obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
 obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
index 7f20d9a..3e62ade 100644 (file)
@@ -400,7 +400,7 @@ static int exynos5433_cpuclk_notifier_cb(struct notifier_block *nb,
 }
 
 /* helper function to register a CPU clock */
-int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
+static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
                unsigned int lookup_id, const char *name,
                const struct clk_hw *parent, const struct clk_hw *alt_parent,
                unsigned long offset, const struct exynos_cpuclk_cfg_data *cfg,
index af74686..fc9f67a 100644 (file)
@@ -62,11 +62,4 @@ struct exynos_cpuclk {
 #define CLK_CPU_HAS_E5433_REGS_LAYOUT  (1 << 2)
 };
 
-int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
-                       unsigned int lookup_id, const char *name,
-                       const struct clk_hw *parent, const struct clk_hw *alt_parent,
-                       unsigned long offset,
-                       const struct exynos_cpuclk_cfg_data *cfg,
-                       unsigned long num_cfgs, unsigned long flags);
-
 #endif /* __SAMSUNG_CLK_CPU_H */
diff --git a/drivers/clk/samsung/clk-exynos-arm64.c b/drivers/clk/samsung/clk-exynos-arm64.c
new file mode 100644 (file)
index 0000000..b921b9a
--- /dev/null
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Linaro Ltd.
+ * Copyright (C) 2021 Dávid Virág <virag.david003@gmail.com>
+ * Author: Sam Protsenko <semen.protsenko@linaro.org>
+ * Author: Dávid Virág <virag.david003@gmail.com>
+ *
+ * This file contains shared functions used by some arm64 Exynos SoCs,
+ * such as Exynos7885 or Exynos850 to register and init CMUs.
+ */
+#include <linux/clk.h>
+#include <linux/of_address.h>
+
+#include "clk-exynos-arm64.h"
+
+/* Gate register bits */
+#define GATE_MANUAL            BIT(20)
+#define GATE_ENABLE_HWACG      BIT(28)
+
+/* Gate register offsets range */
+#define GATE_OFF_START         0x2000
+#define GATE_OFF_END           0x2fff
+
+/**
+ * exynos_arm64_init_clocks - Set clocks initial configuration
+ * @np:                        CMU device tree node with "reg" property (CMU addr)
+ * @reg_offs:          Register offsets array for clocks to init
+ * @reg_offs_len:      Number of register offsets in reg_offs array
+ *
+ * Set manual control mode for all gate clocks.
+ */
+static void __init exynos_arm64_init_clocks(struct device_node *np,
+               const unsigned long *reg_offs, size_t reg_offs_len)
+{
+       void __iomem *reg_base;
+       size_t i;
+
+       reg_base = of_iomap(np, 0);
+       if (!reg_base)
+               panic("%s: failed to map registers\n", __func__);
+
+       for (i = 0; i < reg_offs_len; ++i) {
+               void __iomem *reg = reg_base + reg_offs[i];
+               u32 val;
+
+               /* Modify only gate clock registers */
+               if (reg_offs[i] < GATE_OFF_START || reg_offs[i] > GATE_OFF_END)
+                       continue;
+
+               val = readl(reg);
+               val |= GATE_MANUAL;
+               val &= ~GATE_ENABLE_HWACG;
+               writel(val, reg);
+       }
+
+       iounmap(reg_base);
+}
+
+/**
+ * exynos_arm64_register_cmu - Register specified Exynos CMU domain
+ * @dev:       Device object; may be NULL if this function is not being
+ *             called from platform driver probe function
+ * @np:                CMU device tree node
+ * @cmu:       CMU data
+ *
+ * Register specified CMU domain, which includes next steps:
+ *
+ * 1. Enable parent clock of @cmu CMU
+ * 2. Set initial registers configuration for @cmu CMU clocks
+ * 3. Register @cmu CMU clocks using Samsung clock framework API
+ */
+void __init exynos_arm64_register_cmu(struct device *dev,
+               struct device_node *np, const struct samsung_cmu_info *cmu)
+{
+       /* Keep CMU parent clock running (needed for CMU registers access) */
+       if (cmu->clk_name) {
+               struct clk *parent_clk;
+
+               if (dev)
+                       parent_clk = clk_get(dev, cmu->clk_name);
+               else
+                       parent_clk = of_clk_get_by_name(np, cmu->clk_name);
+
+               if (IS_ERR(parent_clk)) {
+                       pr_err("%s: could not find bus clock %s; err = %ld\n",
+                              __func__, cmu->clk_name, PTR_ERR(parent_clk));
+               } else {
+                       clk_prepare_enable(parent_clk);
+               }
+       }
+
+       exynos_arm64_init_clocks(np, cmu->clk_regs, cmu->nr_clk_regs);
+       samsung_cmu_register_one(np, cmu);
+}
diff --git a/drivers/clk/samsung/clk-exynos-arm64.h b/drivers/clk/samsung/clk-exynos-arm64.h
new file mode 100644 (file)
index 0000000..0dd1746
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Linaro Ltd.
+ * Copyright (C) 2021 Dávid Virág <virag.david003@gmail.com>
+ * Author: Sam Protsenko <semen.protsenko@linaro.org>
+ * Author: Dávid Virág <virag.david003@gmail.com>
+ *
+ * This file contains shared functions used by some arm64 Exynos SoCs,
+ * such as Exynos7885 or Exynos850 to register and init CMUs.
+ */
+
+#ifndef __CLK_EXYNOS_ARM64_H
+#define __CLK_EXYNOS_ARM64_H
+
+#include "clk.h"
+
+void exynos_arm64_register_cmu(struct device *dev,
+               struct device_node *np, const struct samsung_cmu_info *cmu);
+
+#endif /* __CLK_EXYNOS_ARM64_H */
index 17df7f9..6cc65cc 100644 (file)
@@ -748,6 +748,31 @@ static const struct samsung_pll_clock exynos3250_plls[] __initconst = {
                        UPLL_LOCK, UPLL_CON0, exynos3250_pll_rates),
 };
 
+#define E3250_CPU_DIV0(apll, pclk_dbg, atb, corem)                     \
+               (((apll) << 24) | ((pclk_dbg) << 20) | ((atb) << 16) |  \
+               ((corem) << 4))
+#define E3250_CPU_DIV1(hpm, copy)                                      \
+               (((hpm) << 4) | ((copy) << 0))
+
+static const struct exynos_cpuclk_cfg_data e3250_armclk_d[] __initconst = {
+       { 1000000, E3250_CPU_DIV0(1, 7, 4, 1), E3250_CPU_DIV1(7, 7), },
+       {  900000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), },
+       {  800000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), },
+       {  700000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), },
+       {  600000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), },
+       {  500000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), },
+       {  400000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), },
+       {  300000, E3250_CPU_DIV0(1, 5, 3, 1), E3250_CPU_DIV1(7, 7), },
+       {  200000, E3250_CPU_DIV0(1, 3, 3, 1), E3250_CPU_DIV1(7, 7), },
+       {  100000, E3250_CPU_DIV0(1, 1, 1, 1), E3250_CPU_DIV1(7, 7), },
+       {  0 },
+};
+
+static const struct samsung_cpu_clock exynos3250_cpu_clks[] __initconst = {
+       CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
+                       CLK_CPU_HAS_DIV1, 0x14200, e3250_armclk_d),
+};
+
 static void __init exynos3_core_down_clock(void __iomem *reg_base)
 {
        unsigned int tmp;
@@ -780,46 +805,21 @@ static const struct samsung_cmu_info cmu_info __initconst = {
        .nr_gate_clks           = ARRAY_SIZE(gate_clks),
        .fixed_factor_clks      = fixed_factor_clks,
        .nr_fixed_factor_clks   = ARRAY_SIZE(fixed_factor_clks),
+       .cpu_clks               = exynos3250_cpu_clks,
+       .nr_cpu_clks            = ARRAY_SIZE(exynos3250_cpu_clks),
        .nr_clk_ids             = CLK_NR_CLKS,
        .clk_regs               = exynos3250_cmu_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(exynos3250_cmu_clk_regs),
 };
 
-#define E3250_CPU_DIV0(apll, pclk_dbg, atb, corem)                     \
-               (((apll) << 24) | ((pclk_dbg) << 20) | ((atb) << 16) |  \
-               ((corem) << 4))
-#define E3250_CPU_DIV1(hpm, copy)                                      \
-               (((hpm) << 4) | ((copy) << 0))
-
-static const struct exynos_cpuclk_cfg_data e3250_armclk_d[] __initconst = {
-       { 1000000, E3250_CPU_DIV0(1, 7, 4, 1), E3250_CPU_DIV1(7, 7), },
-       {  900000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), },
-       {  800000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), },
-       {  700000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), },
-       {  600000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), },
-       {  500000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), },
-       {  400000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), },
-       {  300000, E3250_CPU_DIV0(1, 5, 3, 1), E3250_CPU_DIV1(7, 7), },
-       {  200000, E3250_CPU_DIV0(1, 3, 3, 1), E3250_CPU_DIV1(7, 7), },
-       {  100000, E3250_CPU_DIV0(1, 1, 1, 1), E3250_CPU_DIV1(7, 7), },
-       {  0 },
-};
-
 static void __init exynos3250_cmu_init(struct device_node *np)
 {
        struct samsung_clk_provider *ctx;
-       struct clk_hw **hws;
 
        ctx = samsung_cmu_register_one(np, &cmu_info);
        if (!ctx)
                return;
 
-       hws = ctx->clk_data.hws;
-       exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
-                       hws[CLK_MOUT_APLL], hws[CLK_MOUT_MPLL_USER_C],
-                       0x14200, e3250_armclk_d, ARRAY_SIZE(e3250_armclk_d),
-                       CLK_CPU_HAS_DIV1);
-
        exynos3_core_down_clock(ctx->reg_base);
 }
 CLK_OF_DECLARE(exynos3250_cmu, "samsung,exynos3250-cmu", exynos3250_cmu_init);
index bf13e29..22009cb 100644 (file)
@@ -437,7 +437,7 @@ static const struct samsung_mux_clock exynos4_mux_clks[] __initconst = {
 
 /* list of mux clocks supported in exynos4210 soc */
 static const struct samsung_mux_clock exynos4210_mux_early[] __initconst = {
-       MUX(0, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP1, 0, 1),
+       MUX(CLK_MOUT_VPLLSRC, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP1, 0, 1),
 };
 
 static const struct samsung_mux_clock exynos4210_mux_clks[] __initconst = {
@@ -603,7 +603,7 @@ static const struct samsung_div_clock exynos4_div_clks[] __initconst = {
        DIV(0, "div_periph", "div_core2", DIV_CPU0, 12, 3),
        DIV(0, "div_atb", "mout_core", DIV_CPU0, 16, 3),
        DIV(0, "div_pclk_dbg", "div_atb", DIV_CPU0, 20, 3),
-       DIV(0, "div_core2", "div_core", DIV_CPU0, 28, 3),
+       DIV(CLK_DIV_CORE2, "div_core2", "div_core", DIV_CPU0, 28, 3),
        DIV(0, "div_copy", "mout_hpm", DIV_CPU1, 0, 3),
        DIV(0, "div_hpm", "div_copy", DIV_CPU1, 4, 3),
        DIV(0, "div_clkout_cpu", "mout_clkout_cpu", CLKOUT_CMU_CPU, 8, 6),
@@ -1228,6 +1228,16 @@ static const struct exynos_cpuclk_cfg_data e4412_armclk_d[] __initconst = {
        {  0 },
 };
 
+static const struct samsung_cpu_clock exynos4210_cpu_clks[] __initconst = {
+       CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_SCLK_MPLL,
+                       CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14200, e4210_armclk_d),
+};
+
+static const struct samsung_cpu_clock exynos4412_cpu_clks[] __initconst = {
+       CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
+                       CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14200, e4412_armclk_d),
+};
+
 /* register exynos4 clocks */
 static void __init exynos4_clk_init(struct device_node *np,
                                    enum exynos4_soc soc)
@@ -1254,21 +1264,21 @@ static void __init exynos4_clk_init(struct device_node *np,
                samsung_clk_register_mux(ctx, exynos4210_mux_early,
                                        ARRAY_SIZE(exynos4210_mux_early));
 
-               if (_get_rate("fin_pll") == 24000000) {
+               if (clk_hw_get_rate(hws[CLK_FIN_PLL]) == 24000000) {
                        exynos4210_plls[apll].rate_table =
                                                        exynos4210_apll_rates;
                        exynos4210_plls[epll].rate_table =
                                                        exynos4210_epll_rates;
                }
 
-               if (_get_rate("mout_vpllsrc") == 24000000)
+               if (clk_hw_get_rate(hws[CLK_MOUT_VPLLSRC]) == 24000000)
                        exynos4210_plls[vpll].rate_table =
                                                        exynos4210_vpll_rates;
 
                samsung_clk_register_pll(ctx, exynos4210_plls,
                                        ARRAY_SIZE(exynos4210_plls), reg_base);
        } else {
-               if (_get_rate("fin_pll") == 24000000) {
+               if (clk_hw_get_rate(hws[CLK_FIN_PLL]) == 24000000) {
                        exynos4x12_plls[apll].rate_table =
                                                        exynos4x12_apll_rates;
                        exynos4x12_plls[epll].rate_table =
@@ -1304,10 +1314,8 @@ static void __init exynos4_clk_init(struct device_node *np,
                samsung_clk_register_fixed_factor(ctx,
                        exynos4210_fixed_factor_clks,
                        ARRAY_SIZE(exynos4210_fixed_factor_clks));
-               exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
-                       hws[CLK_MOUT_APLL], hws[CLK_SCLK_MPLL], 0x14200,
-                       e4210_armclk_d, ARRAY_SIZE(e4210_armclk_d),
-                       CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
+               samsung_clk_register_cpu(ctx, exynos4210_cpu_clks,
+                               ARRAY_SIZE(exynos4210_cpu_clks));
        } else {
                samsung_clk_register_mux(ctx, exynos4x12_mux_clks,
                        ARRAY_SIZE(exynos4x12_mux_clks));
@@ -1318,11 +1326,8 @@ static void __init exynos4_clk_init(struct device_node *np,
                samsung_clk_register_fixed_factor(ctx,
                        exynos4x12_fixed_factor_clks,
                        ARRAY_SIZE(exynos4x12_fixed_factor_clks));
-
-               exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
-                       hws[CLK_MOUT_APLL], hws[CLK_MOUT_MPLL_USER_C], 0x14200,
-                       e4412_armclk_d, ARRAY_SIZE(e4412_armclk_d),
-                       CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
+               samsung_clk_register_cpu(ctx, exynos4412_cpu_clks,
+                               ARRAY_SIZE(exynos4412_cpu_clks));
        }
 
        if (soc == EXYNOS4X12)
@@ -1344,9 +1349,11 @@ static void __init exynos4_clk_init(struct device_node *np,
        pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n"
                "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n",
                exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12",
-               _get_rate("sclk_apll"), _get_rate("sclk_mpll"),
-               _get_rate("sclk_epll"), _get_rate("sclk_vpll"),
-               _get_rate("div_core2"));
+               clk_hw_get_rate(hws[CLK_SCLK_APLL]),
+               clk_hw_get_rate(hws[CLK_SCLK_MPLL]),
+               clk_hw_get_rate(hws[CLK_SCLK_EPLL]),
+               clk_hw_get_rate(hws[CLK_SCLK_VPLL]),
+               clk_hw_get_rate(hws[CLK_DIV_CORE2]));
 }
 
 
index 06588fa..113df77 100644 (file)
@@ -239,7 +239,7 @@ static const struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __
 };
 
 static const struct samsung_mux_clock exynos5250_pll_pmux_clks[] __initconst = {
-       MUX(0, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1),
+       MUX(CLK_MOUT_VPLLSRC, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1),
 };
 
 static const struct samsung_mux_clock exynos5250_mux_clks[] __initconst = {
@@ -351,7 +351,7 @@ static const struct samsung_div_clock exynos5250_div_clks[] __initconst = {
         */
        DIV(0, "div_arm", "mout_cpu", DIV_CPU0, 0, 3),
        DIV(0, "div_apll", "mout_apll", DIV_CPU0, 24, 3),
-       DIV(0, "div_arm2", "div_arm", DIV_CPU0, 28, 3),
+       DIV(CLK_DIV_ARM2, "div_arm2", "div_arm", DIV_CPU0, 28, 3),
 
        /*
         * CMU_TOP
@@ -772,6 +772,11 @@ static const struct exynos_cpuclk_cfg_data exynos5250_armclk_d[] __initconst = {
        {  0 },
 };
 
+static const struct samsung_cpu_clock exynos5250_cpu_clks[] __initconst = {
+       CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL, CLK_CPU_HAS_DIV1, 0x200,
+                       exynos5250_armclk_d),
+};
+
 static const struct of_device_id ext_clk_match[] __initconst = {
        { .compatible = "samsung,clock-xxti", .data = (void *)0, },
        { },
@@ -801,12 +806,12 @@ static void __init exynos5250_clk_init(struct device_node *np)
        samsung_clk_register_mux(ctx, exynos5250_pll_pmux_clks,
                                ARRAY_SIZE(exynos5250_pll_pmux_clks));
 
-       if (_get_rate("fin_pll") == 24 * MHZ) {
+       if (clk_hw_get_rate(hws[CLK_FIN_PLL]) == 24 * MHZ) {
                exynos5250_plls[epll].rate_table = epll_24mhz_tbl;
                exynos5250_plls[apll].rate_table = apll_24mhz_tbl;
        }
 
-       if (_get_rate("mout_vpllsrc") == 24 * MHZ)
+       if (clk_hw_get_rate(hws[CLK_MOUT_VPLLSRC]) == 24 * MHZ)
                exynos5250_plls[vpll].rate_table =  vpll_24mhz_tbl;
 
        samsung_clk_register_pll(ctx, exynos5250_plls,
@@ -822,10 +827,8 @@ static void __init exynos5250_clk_init(struct device_node *np)
                        ARRAY_SIZE(exynos5250_div_clks));
        samsung_clk_register_gate(ctx, exynos5250_gate_clks,
                        ARRAY_SIZE(exynos5250_gate_clks));
-       exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
-                       hws[CLK_MOUT_APLL], hws[CLK_MOUT_MPLL], 0x200,
-                       exynos5250_armclk_d, ARRAY_SIZE(exynos5250_armclk_d),
-                       CLK_CPU_HAS_DIV1);
+       samsung_clk_register_cpu(ctx, exynos5250_cpu_clks,
+                       ARRAY_SIZE(exynos5250_cpu_clks));
 
        /*
         * Enable arm clock down (in idle) and set arm divider
@@ -855,6 +858,6 @@ static void __init exynos5250_clk_init(struct device_node *np)
        samsung_clk_of_add_provider(np, ctx);
 
        pr_info("Exynos5250: clock setup completed, armclk=%ld\n",
-                       _get_rate("div_arm2"));
+               clk_hw_get_rate(hws[CLK_DIV_ARM2]));
 }
 CLK_OF_DECLARE_DRIVER(exynos5250_clk, "samsung,exynos5250-clock", exynos5250_clk_init);
index 3ccd4ea..caad74d 100644 (file)
@@ -1551,6 +1551,20 @@ static const struct exynos_cpuclk_cfg_data exynos5420_kfcclk_d[] __initconst = {
        {  0 },
 };
 
+static const struct samsung_cpu_clock exynos5420_cpu_clks[] __initconst = {
+       CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0, 0x200,
+                       exynos5420_eglclk_d),
+       CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0, 0x28200,
+                       exynos5420_kfcclk_d),
+};
+
+static const struct samsung_cpu_clock exynos5800_cpu_clks[] __initconst = {
+       CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0, 0x200,
+                       exynos5800_eglclk_d),
+       CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0, 0x28200,
+                       exynos5420_kfcclk_d),
+};
+
 static const struct of_device_id ext_clk_match[] __initconst = {
        { .compatible = "samsung,exynos5420-oscclk", .data = (void *)0, },
        { },
@@ -1580,7 +1594,7 @@ static void __init exynos5x_clk_init(struct device_node *np,
                        ARRAY_SIZE(exynos5x_fixed_rate_ext_clks),
                        ext_clk_match);
 
-       if (_get_rate("fin_pll") == 24 * MHZ) {
+       if (clk_hw_get_rate(hws[CLK_FIN_PLL]) == 24 * MHZ) {
                exynos5x_plls[apll].rate_table = exynos5420_pll2550x_24mhz_tbl;
                exynos5x_plls[epll].rate_table = exynos5420_epll_24mhz_tbl;
                exynos5x_plls[kpll].rate_table = exynos5420_pll2550x_24mhz_tbl;
@@ -1625,17 +1639,12 @@ static void __init exynos5x_clk_init(struct device_node *np,
        }
 
        if (soc == EXYNOS5420) {
-               exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
-                       hws[CLK_MOUT_APLL], hws[CLK_MOUT_MSPLL_CPU], 0x200,
-                       exynos5420_eglclk_d, ARRAY_SIZE(exynos5420_eglclk_d), 0);
+               samsung_clk_register_cpu(ctx, exynos5420_cpu_clks,
+                               ARRAY_SIZE(exynos5420_cpu_clks));
        } else {
-               exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
-                       hws[CLK_MOUT_APLL], hws[CLK_MOUT_MSPLL_CPU], 0x200,
-                       exynos5800_eglclk_d, ARRAY_SIZE(exynos5800_eglclk_d), 0);
+               samsung_clk_register_cpu(ctx, exynos5800_cpu_clks,
+                               ARRAY_SIZE(exynos5800_cpu_clks));
        }
-       exynos_register_cpu_clock(ctx, CLK_KFC_CLK, "kfcclk",
-               hws[CLK_MOUT_KPLL], hws[CLK_MOUT_MSPLL_KFC],  0x28200,
-               exynos5420_kfcclk_d, ARRAY_SIZE(exynos5420_kfcclk_d), 0);
 
        samsung_clk_extended_sleep_init(reg_base,
                exynos5x_clk_regs, ARRAY_SIZE(exynos5x_clk_regs),
diff --git a/drivers/clk/samsung/clk-exynos7885.c b/drivers/clk/samsung/clk-exynos7885.c
new file mode 100644 (file)
index 0000000..a7b1063
--- /dev/null
@@ -0,0 +1,597 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Dávid Virág <virag.david003@gmail.com>
+ * Author: Dávid Virág <virag.david003@gmail.com>
+ *
+ * Common Clock Framework support for Exynos7885 SoC.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/exynos7885.h>
+
+#include "clk.h"
+#include "clk-exynos-arm64.h"
+
+/* ---- CMU_TOP ------------------------------------------------------------- */
+
+/* Register Offset definitions for CMU_TOP (0x12060000) */
+#define PLL_LOCKTIME_PLL_SHARED0               0x0000
+#define PLL_LOCKTIME_PLL_SHARED1               0x0004
+#define PLL_CON0_PLL_SHARED0                   0x0100
+#define PLL_CON0_PLL_SHARED1                   0x0120
+#define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS                0x1014
+#define CLK_CON_MUX_MUX_CLKCMU_CORE_CCI                0x1018
+#define CLK_CON_MUX_MUX_CLKCMU_CORE_G3D                0x101c
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS                0x1058
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_SPI0       0x105c
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_SPI1       0x1060
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_UART0      0x1064
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_UART1      0x1068
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_UART2      0x106c
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_USI0       0x1070
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_USI1       0x1074
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_USI2       0x1078
+#define CLK_CON_DIV_CLKCMU_CORE_BUS            0x181c
+#define CLK_CON_DIV_CLKCMU_CORE_CCI            0x1820
+#define CLK_CON_DIV_CLKCMU_CORE_G3D            0x1824
+#define CLK_CON_DIV_CLKCMU_PERI_BUS            0x1874
+#define CLK_CON_DIV_CLKCMU_PERI_SPI0           0x1878
+#define CLK_CON_DIV_CLKCMU_PERI_SPI1           0x187c
+#define CLK_CON_DIV_CLKCMU_PERI_UART0          0x1880
+#define CLK_CON_DIV_CLKCMU_PERI_UART1          0x1884
+#define CLK_CON_DIV_CLKCMU_PERI_UART2          0x1888
+#define CLK_CON_DIV_CLKCMU_PERI_USI0           0x188c
+#define CLK_CON_DIV_CLKCMU_PERI_USI1           0x1890
+#define CLK_CON_DIV_CLKCMU_PERI_USI2           0x1894
+#define CLK_CON_DIV_PLL_SHARED0_DIV2           0x189c
+#define CLK_CON_DIV_PLL_SHARED0_DIV3           0x18a0
+#define CLK_CON_DIV_PLL_SHARED0_DIV4           0x18a4
+#define CLK_CON_DIV_PLL_SHARED0_DIV5           0x18a8
+#define CLK_CON_DIV_PLL_SHARED1_DIV2           0x18ac
+#define CLK_CON_DIV_PLL_SHARED1_DIV3           0x18b0
+#define CLK_CON_DIV_PLL_SHARED1_DIV4           0x18b4
+#define CLK_CON_GAT_GATE_CLKCMUC_PERI_UART1    0x2004
+#define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS       0x201c
+#define CLK_CON_GAT_GATE_CLKCMU_CORE_CCI       0x2020
+#define CLK_CON_GAT_GATE_CLKCMU_CORE_G3D       0x2024
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_BUS       0x207c
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_SPI0      0x2080
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_SPI1      0x2084
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_UART0     0x2088
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_UART2     0x208c
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_USI0      0x2090
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_USI1      0x2094
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_USI2      0x2098
+
+static const unsigned long top_clk_regs[] __initconst = {
+       PLL_LOCKTIME_PLL_SHARED0,
+       PLL_LOCKTIME_PLL_SHARED1,
+       PLL_CON0_PLL_SHARED0,
+       PLL_CON0_PLL_SHARED1,
+       CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
+       CLK_CON_MUX_MUX_CLKCMU_CORE_CCI,
+       CLK_CON_MUX_MUX_CLKCMU_CORE_G3D,
+       CLK_CON_MUX_MUX_CLKCMU_PERI_BUS,
+       CLK_CON_MUX_MUX_CLKCMU_PERI_SPI0,
+       CLK_CON_MUX_MUX_CLKCMU_PERI_SPI1,
+       CLK_CON_MUX_MUX_CLKCMU_PERI_UART0,
+       CLK_CON_MUX_MUX_CLKCMU_PERI_UART1,
+       CLK_CON_MUX_MUX_CLKCMU_PERI_UART2,
+       CLK_CON_MUX_MUX_CLKCMU_PERI_USI0,
+       CLK_CON_MUX_MUX_CLKCMU_PERI_USI1,
+       CLK_CON_MUX_MUX_CLKCMU_PERI_USI2,
+       CLK_CON_DIV_CLKCMU_CORE_BUS,
+       CLK_CON_DIV_CLKCMU_CORE_CCI,
+       CLK_CON_DIV_CLKCMU_CORE_G3D,
+       CLK_CON_DIV_CLKCMU_PERI_BUS,
+       CLK_CON_DIV_CLKCMU_PERI_SPI0,
+       CLK_CON_DIV_CLKCMU_PERI_SPI1,
+       CLK_CON_DIV_CLKCMU_PERI_UART0,
+       CLK_CON_DIV_CLKCMU_PERI_UART1,
+       CLK_CON_DIV_CLKCMU_PERI_UART2,
+       CLK_CON_DIV_CLKCMU_PERI_USI0,
+       CLK_CON_DIV_CLKCMU_PERI_USI1,
+       CLK_CON_DIV_CLKCMU_PERI_USI2,
+       CLK_CON_DIV_PLL_SHARED0_DIV2,
+       CLK_CON_DIV_PLL_SHARED0_DIV3,
+       CLK_CON_DIV_PLL_SHARED0_DIV4,
+       CLK_CON_DIV_PLL_SHARED0_DIV5,
+       CLK_CON_DIV_PLL_SHARED1_DIV2,
+       CLK_CON_DIV_PLL_SHARED1_DIV3,
+       CLK_CON_DIV_PLL_SHARED1_DIV4,
+       CLK_CON_GAT_GATE_CLKCMUC_PERI_UART1,
+       CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
+       CLK_CON_GAT_GATE_CLKCMU_CORE_CCI,
+       CLK_CON_GAT_GATE_CLKCMU_CORE_G3D,
+       CLK_CON_GAT_GATE_CLKCMU_PERI_BUS,
+       CLK_CON_GAT_GATE_CLKCMU_PERI_SPI0,
+       CLK_CON_GAT_GATE_CLKCMU_PERI_SPI1,
+       CLK_CON_GAT_GATE_CLKCMU_PERI_UART0,
+       CLK_CON_GAT_GATE_CLKCMU_PERI_UART2,
+       CLK_CON_GAT_GATE_CLKCMU_PERI_USI0,
+       CLK_CON_GAT_GATE_CLKCMU_PERI_USI1,
+       CLK_CON_GAT_GATE_CLKCMU_PERI_USI2,
+};
+
+static const struct samsung_pll_clock top_pll_clks[] __initconst = {
+       PLL(pll_1417x, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk",
+           PLL_LOCKTIME_PLL_SHARED0, PLL_CON0_PLL_SHARED0,
+           NULL),
+       PLL(pll_1417x, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk",
+           PLL_LOCKTIME_PLL_SHARED1, PLL_CON0_PLL_SHARED1,
+           NULL),
+};
+
+/* List of parent clocks for Muxes in CMU_TOP: for CMU_CORE */
+PNAME(mout_core_bus_p)         = { "dout_shared0_div2", "dout_shared1_div2",
+                                   "dout_shared0_div3", "dout_shared0_div3" };
+PNAME(mout_core_cci_p)         = { "dout_shared0_div2", "dout_shared1_div2",
+                                   "dout_shared0_div3", "dout_shared0_div3" };
+PNAME(mout_core_g3d_p)         = { "dout_shared0_div2", "dout_shared1_div2",
+                                   "dout_shared0_div3", "dout_shared0_div3" };
+
+/* List of parent clocks for Muxes in CMU_TOP: for CMU_PERI */
+PNAME(mout_peri_bus_p)         = { "dout_shared0_div4", "dout_shared1_div4" };
+PNAME(mout_peri_spi0_p)                = { "oscclk", "dout_shared0_div4" };
+PNAME(mout_peri_spi1_p)                = { "oscclk", "dout_shared0_div4" };
+PNAME(mout_peri_uart0_p)       = { "oscclk", "dout_shared0_div4" };
+PNAME(mout_peri_uart1_p)       = { "oscclk", "dout_shared0_div4" };
+PNAME(mout_peri_uart2_p)       = { "oscclk", "dout_shared0_div4" };
+PNAME(mout_peri_usi0_p)                = { "oscclk", "dout_shared0_div4" };
+PNAME(mout_peri_usi1_p)                = { "oscclk", "dout_shared0_div4" };
+PNAME(mout_peri_usi2_p)                = { "oscclk", "dout_shared0_div4" };
+
+static const struct samsung_mux_clock top_mux_clks[] __initconst = {
+       /* CORE */
+       MUX(CLK_MOUT_CORE_BUS, "mout_core_bus", mout_core_bus_p,
+           CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 0, 2),
+       MUX(CLK_MOUT_CORE_CCI, "mout_core_cci", mout_core_cci_p,
+           CLK_CON_MUX_MUX_CLKCMU_CORE_CCI, 0, 2),
+       MUX(CLK_MOUT_CORE_G3D, "mout_core_g3d", mout_core_g3d_p,
+           CLK_CON_MUX_MUX_CLKCMU_CORE_G3D, 0, 2),
+
+       /* PERI */
+       MUX(CLK_MOUT_PERI_BUS, "mout_peri_bus", mout_peri_bus_p,
+           CLK_CON_MUX_MUX_CLKCMU_PERI_BUS, 0, 1),
+       MUX(CLK_MOUT_PERI_SPI0, "mout_peri_spi0", mout_peri_spi0_p,
+           CLK_CON_MUX_MUX_CLKCMU_PERI_SPI0, 0, 1),
+       MUX(CLK_MOUT_PERI_SPI1, "mout_peri_spi1", mout_peri_spi1_p,
+           CLK_CON_MUX_MUX_CLKCMU_PERI_SPI1, 0, 1),
+       MUX(CLK_MOUT_PERI_UART0, "mout_peri_uart0", mout_peri_uart0_p,
+           CLK_CON_MUX_MUX_CLKCMU_PERI_UART0, 0, 1),
+       MUX(CLK_MOUT_PERI_UART1, "mout_peri_uart1", mout_peri_uart1_p,
+           CLK_CON_MUX_MUX_CLKCMU_PERI_UART1, 0, 1),
+       MUX(CLK_MOUT_PERI_UART2, "mout_peri_uart2", mout_peri_uart2_p,
+           CLK_CON_MUX_MUX_CLKCMU_PERI_UART2, 0, 1),
+       MUX(CLK_MOUT_PERI_USI0, "mout_peri_usi0", mout_peri_usi0_p,
+           CLK_CON_MUX_MUX_CLKCMU_PERI_USI0, 0, 1),
+       MUX(CLK_MOUT_PERI_USI1, "mout_peri_usi1", mout_peri_usi1_p,
+           CLK_CON_MUX_MUX_CLKCMU_PERI_USI1, 0, 1),
+       MUX(CLK_MOUT_PERI_USI2, "mout_peri_usi2", mout_peri_usi2_p,
+           CLK_CON_MUX_MUX_CLKCMU_PERI_USI2, 0, 1),
+};
+
+static const struct samsung_div_clock top_div_clks[] __initconst = {
+       /* TOP */
+       DIV(CLK_DOUT_SHARED0_DIV2, "dout_shared0_div2", "fout_shared0_pll",
+           CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1),
+       DIV(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "fout_shared0_pll",
+           CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2),
+       DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "fout_shared0_pll",
+           CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1),
+       DIV(CLK_DOUT_SHARED0_DIV5, "dout_shared0_div5", "fout_shared0_pll",
+           CLK_CON_DIV_PLL_SHARED0_DIV5, 0, 3),
+       DIV(CLK_DOUT_SHARED1_DIV2, "dout_shared1_div2", "fout_shared1_pll",
+           CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1),
+       DIV(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "fout_shared1_pll",
+           CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2),
+       DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "fout_shared1_pll",
+           CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1),
+
+       /* CORE */
+       DIV(CLK_DOUT_CORE_BUS, "dout_core_bus", "gout_core_bus",
+           CLK_CON_DIV_CLKCMU_CORE_BUS, 0, 3),
+       DIV(CLK_DOUT_CORE_CCI, "dout_core_cci", "gout_core_cci",
+           CLK_CON_DIV_CLKCMU_CORE_CCI, 0, 3),
+       DIV(CLK_DOUT_CORE_G3D, "dout_core_g3d", "gout_core_g3d",
+           CLK_CON_DIV_CLKCMU_CORE_G3D, 0, 3),
+
+       /* PERI */
+       DIV(CLK_DOUT_PERI_BUS, "dout_peri_bus", "gout_peri_bus",
+           CLK_CON_DIV_CLKCMU_PERI_BUS, 0, 4),
+       DIV(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "gout_peri_spi0",
+           CLK_CON_DIV_CLKCMU_PERI_SPI0, 0, 6),
+       DIV(CLK_DOUT_PERI_SPI1, "dout_peri_spi1", "gout_peri_spi1",
+           CLK_CON_DIV_CLKCMU_PERI_SPI1, 0, 6),
+       DIV(CLK_DOUT_PERI_UART0, "dout_peri_uart0", "gout_peri_uart0",
+           CLK_CON_DIV_CLKCMU_PERI_UART0, 0, 4),
+       DIV(CLK_DOUT_PERI_UART1, "dout_peri_uart1", "gout_peri_uart1",
+           CLK_CON_DIV_CLKCMU_PERI_UART1, 0, 4),
+       DIV(CLK_DOUT_PERI_UART2, "dout_peri_uart2", "gout_peri_uart2",
+           CLK_CON_DIV_CLKCMU_PERI_UART2, 0, 4),
+       DIV(CLK_DOUT_PERI_USI0, "dout_peri_usi0", "gout_peri_usi0",
+           CLK_CON_DIV_CLKCMU_PERI_USI0, 0, 4),
+       DIV(CLK_DOUT_PERI_USI1, "dout_peri_usi1", "gout_peri_usi1",
+           CLK_CON_DIV_CLKCMU_PERI_USI1, 0, 4),
+       DIV(CLK_DOUT_PERI_USI2, "dout_peri_usi2", "gout_peri_usi2",
+           CLK_CON_DIV_CLKCMU_PERI_USI2, 0, 4),
+};
+
+static const struct samsung_gate_clock top_gate_clks[] __initconst = {
+       /* CORE */
+       GATE(CLK_GOUT_CORE_BUS, "gout_core_bus", "mout_core_bus",
+            CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, 21, 0, 0),
+       GATE(CLK_GOUT_CORE_CCI, "gout_core_cci", "mout_core_cci",
+            CLK_CON_GAT_GATE_CLKCMU_CORE_CCI, 21, 0, 0),
+       GATE(CLK_GOUT_CORE_G3D, "gout_core_g3d", "mout_core_g3d",
+            CLK_CON_GAT_GATE_CLKCMU_CORE_G3D, 21, 0, 0),
+
+       /* PERI */
+       GATE(CLK_GOUT_PERI_BUS, "gout_peri_bus", "mout_peri_bus",
+            CLK_CON_GAT_GATE_CLKCMU_PERI_BUS, 21, 0, 0),
+       GATE(CLK_GOUT_PERI_SPI0, "gout_peri_spi0", "mout_peri_spi0",
+            CLK_CON_GAT_GATE_CLKCMU_PERI_SPI0, 21, 0, 0),
+       GATE(CLK_GOUT_PERI_SPI1, "gout_peri_spi1", "mout_peri_spi1",
+            CLK_CON_GAT_GATE_CLKCMU_PERI_SPI1, 21, 0, 0),
+       GATE(CLK_GOUT_PERI_UART0, "gout_peri_uart0", "mout_peri_uart0",
+            CLK_CON_GAT_GATE_CLKCMU_PERI_UART0, 21, 0, 0),
+       GATE(CLK_GOUT_PERI_UART1, "gout_peri_uart1", "mout_peri_uart1",
+            CLK_CON_GAT_GATE_CLKCMUC_PERI_UART1, 21, 0, 0),
+       GATE(CLK_GOUT_PERI_UART2, "gout_peri_uart2", "mout_peri_uart2",
+            CLK_CON_GAT_GATE_CLKCMU_PERI_UART2, 21, 0, 0),
+       GATE(CLK_GOUT_PERI_USI0, "gout_peri_usi0", "mout_peri_usi0",
+            CLK_CON_GAT_GATE_CLKCMU_PERI_USI0, 21, 0, 0),
+       GATE(CLK_GOUT_PERI_USI1, "gout_peri_usi1", "mout_peri_usi1",
+            CLK_CON_GAT_GATE_CLKCMU_PERI_USI1, 21, 0, 0),
+       GATE(CLK_GOUT_PERI_USI2, "gout_peri_usi2", "mout_peri_usi2",
+            CLK_CON_GAT_GATE_CLKCMU_PERI_USI2, 21, 0, 0),
+};
+
+static const struct samsung_cmu_info top_cmu_info __initconst = {
+       .pll_clks               = top_pll_clks,
+       .nr_pll_clks            = ARRAY_SIZE(top_pll_clks),
+       .mux_clks               = top_mux_clks,
+       .nr_mux_clks            = ARRAY_SIZE(top_mux_clks),
+       .div_clks               = top_div_clks,
+       .nr_div_clks            = ARRAY_SIZE(top_div_clks),
+       .gate_clks              = top_gate_clks,
+       .nr_gate_clks           = ARRAY_SIZE(top_gate_clks),
+       .nr_clk_ids             = TOP_NR_CLK,
+       .clk_regs               = top_clk_regs,
+       .nr_clk_regs            = ARRAY_SIZE(top_clk_regs),
+};
+
+static void __init exynos7885_cmu_top_init(struct device_node *np)
+{
+       exynos_arm64_register_cmu(NULL, np, &top_cmu_info);
+}
+
+/* Register CMU_TOP early, as it's a dependency for other early domains */
+CLK_OF_DECLARE(exynos7885_cmu_top, "samsung,exynos7885-cmu-top",
+              exynos7885_cmu_top_init);
+
+/* ---- CMU_PERI ------------------------------------------------------------ */
+
+/* Register Offset definitions for CMU_PERI (0x10010000) */
+#define PLL_CON0_MUX_CLKCMU_PERI_BUS_USER      0x0100
+#define PLL_CON0_MUX_CLKCMU_PERI_SPI0_USER     0x0120
+#define PLL_CON0_MUX_CLKCMU_PERI_SPI1_USER     0x0140
+#define PLL_CON0_MUX_CLKCMU_PERI_UART0_USER    0x0160
+#define PLL_CON0_MUX_CLKCMU_PERI_UART1_USER    0x0180
+#define PLL_CON0_MUX_CLKCMU_PERI_UART2_USER    0x01a0
+#define PLL_CON0_MUX_CLKCMU_PERI_USI0_USER     0x01c0
+#define PLL_CON0_MUX_CLKCMU_PERI_USI1_USER     0x01e0
+#define PLL_CON0_MUX_CLKCMU_PERI_USI2_USER     0x0200
+#define CLK_CON_GAT_GOUT_PERI_GPIO_TOP_PCLK    0x2024
+#define CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK     0x2028
+#define CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK     0x202c
+#define CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK     0x2030
+#define CLK_CON_GAT_GOUT_PERI_HSI2C_3_PCLK     0x2034
+#define CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK       0x2038
+#define CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK       0x203c
+#define CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK       0x2040
+#define CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK       0x2044
+#define CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK       0x2048
+#define CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK       0x204c
+#define CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK       0x2050
+#define CLK_CON_GAT_GOUT_PERI_I2C_7_PCLK       0x2054
+#define CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK   0x2058
+#define CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK       0x205c
+#define CLK_CON_GAT_GOUT_PERI_SPI_0_EXT_CLK    0x2060
+#define CLK_CON_GAT_GOUT_PERI_SPI_1_PCLK       0x2064
+#define CLK_CON_GAT_GOUT_PERI_SPI_1_EXT_CLK    0x2068
+#define CLK_CON_GAT_GOUT_PERI_UART_0_EXT_UCLK  0x206c
+#define CLK_CON_GAT_GOUT_PERI_UART_0_PCLK      0x2070
+#define CLK_CON_GAT_GOUT_PERI_UART_1_EXT_UCLK  0x2074
+#define CLK_CON_GAT_GOUT_PERI_UART_1_PCLK      0x2078
+#define CLK_CON_GAT_GOUT_PERI_UART_2_EXT_UCLK  0x207c
+#define CLK_CON_GAT_GOUT_PERI_UART_2_PCLK      0x2080
+#define CLK_CON_GAT_GOUT_PERI_USI0_PCLK                0x2084
+#define CLK_CON_GAT_GOUT_PERI_USI0_SCLK                0x2088
+#define CLK_CON_GAT_GOUT_PERI_USI1_PCLK                0x208c
+#define CLK_CON_GAT_GOUT_PERI_USI1_SCLK                0x2090
+#define CLK_CON_GAT_GOUT_PERI_USI2_PCLK                0x2094
+#define CLK_CON_GAT_GOUT_PERI_USI2_SCLK                0x2098
+#define CLK_CON_GAT_GOUT_PERI_MCT_PCLK         0x20a0
+#define CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK 0x20b0
+#define CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER0_PCLK        0x20b4
+#define CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER1_PCLK        0x20b8
+
+static const unsigned long peri_clk_regs[] __initconst = {
+       PLL_CON0_MUX_CLKCMU_PERI_BUS_USER,
+       PLL_CON0_MUX_CLKCMU_PERI_SPI0_USER,
+       PLL_CON0_MUX_CLKCMU_PERI_SPI1_USER,
+       PLL_CON0_MUX_CLKCMU_PERI_UART0_USER,
+       PLL_CON0_MUX_CLKCMU_PERI_UART1_USER,
+       PLL_CON0_MUX_CLKCMU_PERI_UART2_USER,
+       PLL_CON0_MUX_CLKCMU_PERI_USI0_USER,
+       PLL_CON0_MUX_CLKCMU_PERI_USI1_USER,
+       PLL_CON0_MUX_CLKCMU_PERI_USI2_USER,
+       CLK_CON_GAT_GOUT_PERI_GPIO_TOP_PCLK,
+       CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK,
+       CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK,
+       CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK,
+       CLK_CON_GAT_GOUT_PERI_HSI2C_3_PCLK,
+       CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK,
+       CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK,
+       CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK,
+       CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK,
+       CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK,
+       CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK,
+       CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK,
+       CLK_CON_GAT_GOUT_PERI_I2C_7_PCLK,
+       CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK,
+       CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK,
+       CLK_CON_GAT_GOUT_PERI_SPI_0_EXT_CLK,
+       CLK_CON_GAT_GOUT_PERI_SPI_1_PCLK,
+       CLK_CON_GAT_GOUT_PERI_SPI_1_EXT_CLK,
+       CLK_CON_GAT_GOUT_PERI_UART_0_EXT_UCLK,
+       CLK_CON_GAT_GOUT_PERI_UART_0_PCLK,
+       CLK_CON_GAT_GOUT_PERI_UART_1_EXT_UCLK,
+       CLK_CON_GAT_GOUT_PERI_UART_1_PCLK,
+       CLK_CON_GAT_GOUT_PERI_UART_2_EXT_UCLK,
+       CLK_CON_GAT_GOUT_PERI_UART_2_PCLK,
+       CLK_CON_GAT_GOUT_PERI_USI0_PCLK,
+       CLK_CON_GAT_GOUT_PERI_USI0_SCLK,
+       CLK_CON_GAT_GOUT_PERI_USI1_PCLK,
+       CLK_CON_GAT_GOUT_PERI_USI1_SCLK,
+       CLK_CON_GAT_GOUT_PERI_USI2_PCLK,
+       CLK_CON_GAT_GOUT_PERI_USI2_SCLK,
+       CLK_CON_GAT_GOUT_PERI_MCT_PCLK,
+       CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK,
+       CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER0_PCLK,
+       CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER1_PCLK,
+};
+
+/* List of parent clocks for Muxes in CMU_PERI */
+PNAME(mout_peri_bus_user_p)    = { "oscclk", "dout_peri_bus" };
+PNAME(mout_peri_spi0_user_p)   = { "oscclk", "dout_peri_spi0" };
+PNAME(mout_peri_spi1_user_p)   = { "oscclk", "dout_peri_spi1" };
+PNAME(mout_peri_uart0_user_p)  = { "oscclk", "dout_peri_uart0" };
+PNAME(mout_peri_uart1_user_p)  = { "oscclk", "dout_peri_uart1" };
+PNAME(mout_peri_uart2_user_p)  = { "oscclk", "dout_peri_uart2" };
+PNAME(mout_peri_usi0_user_p)   = { "oscclk", "dout_peri_usi0" };
+PNAME(mout_peri_usi1_user_p)   = { "oscclk", "dout_peri_usi1" };
+PNAME(mout_peri_usi2_user_p)   = { "oscclk", "dout_peri_usi2" };
+
+static const struct samsung_mux_clock peri_mux_clks[] __initconst = {
+       MUX(CLK_MOUT_PERI_BUS_USER, "mout_peri_bus_user", mout_peri_bus_user_p,
+           PLL_CON0_MUX_CLKCMU_PERI_BUS_USER, 4, 1),
+       MUX(CLK_MOUT_PERI_SPI0_USER, "mout_peri_spi0_user", mout_peri_spi0_user_p,
+           PLL_CON0_MUX_CLKCMU_PERI_SPI0_USER, 4, 1),
+       MUX(CLK_MOUT_PERI_SPI1_USER, "mout_peri_spi1_user", mout_peri_spi1_user_p,
+           PLL_CON0_MUX_CLKCMU_PERI_SPI1_USER, 4, 1),
+       MUX(CLK_MOUT_PERI_UART0_USER, "mout_peri_uart0_user",
+           mout_peri_uart0_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART0_USER, 4, 1),
+       MUX(CLK_MOUT_PERI_UART1_USER, "mout_peri_uart1_user",
+           mout_peri_uart1_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART1_USER, 4, 1),
+       MUX(CLK_MOUT_PERI_UART2_USER, "mout_peri_uart2_user",
+           mout_peri_uart2_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART2_USER, 4, 1),
+       MUX(CLK_MOUT_PERI_USI0_USER, "mout_peri_usi0_user",
+           mout_peri_usi0_user_p, PLL_CON0_MUX_CLKCMU_PERI_USI0_USER, 4, 1),
+       MUX(CLK_MOUT_PERI_USI1_USER, "mout_peri_usi1_user",
+           mout_peri_usi1_user_p, PLL_CON0_MUX_CLKCMU_PERI_USI1_USER, 4, 1),
+       MUX(CLK_MOUT_PERI_USI2_USER, "mout_peri_usi2_user",
+           mout_peri_usi2_user_p, PLL_CON0_MUX_CLKCMU_PERI_USI2_USER, 4, 1),
+};
+
+static const struct samsung_gate_clock peri_gate_clks[] __initconst = {
+       /* TODO: Should be enabled in GPIO driver (or made CLK_IS_CRITICAL) */
+       GATE(CLK_GOUT_GPIO_TOP_PCLK, "gout_gpio_top_pclk",
+            "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_GPIO_TOP_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+       GATE(CLK_GOUT_HSI2C0_PCLK, "gout_hsi2c0_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_HSI2C1_PCLK, "gout_hsi2c1_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_HSI2C2_PCLK, "gout_hsi2c2_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_HSI2C3_PCLK, "gout_hsi2c3_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_HSI2C_3_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_I2C0_PCLK, "gout_i2c0_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_I2C1_PCLK, "gout_i2c1_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_I2C2_PCLK, "gout_i2c2_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_I2C3_PCLK, "gout_i2c3_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_I2C4_PCLK, "gout_i2c4_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_I2C5_PCLK, "gout_i2c5_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_I2C6_PCLK, "gout_i2c6_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_I2C7_PCLK, "gout_i2c7_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_I2C_7_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_PWM_MOTOR_PCLK, "gout_pwm_motor_pclk",
+            "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_SPI0_PCLK, "gout_spi0_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_SPI0_EXT_CLK, "gout_spi0_ipclk", "mout_peri_spi0_user",
+            CLK_CON_GAT_GOUT_PERI_SPI_0_EXT_CLK, 21, 0, 0),
+       GATE(CLK_GOUT_SPI1_PCLK, "gout_spi1_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_SPI_1_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_SPI1_EXT_CLK, "gout_spi1_ipclk", "mout_peri_spi1_user",
+            CLK_CON_GAT_GOUT_PERI_SPI_1_EXT_CLK, 21, 0, 0),
+       GATE(CLK_GOUT_UART0_EXT_UCLK, "gout_uart0_ext_uclk", "mout_peri_uart0_user",
+            CLK_CON_GAT_GOUT_PERI_UART_0_EXT_UCLK, 21, 0, 0),
+       GATE(CLK_GOUT_UART0_PCLK, "gout_uart0_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_UART_0_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_UART1_EXT_UCLK, "gout_uart1_ext_uclk", "mout_peri_uart1_user",
+            CLK_CON_GAT_GOUT_PERI_UART_1_EXT_UCLK, 21, 0, 0),
+       GATE(CLK_GOUT_UART1_PCLK, "gout_uart1_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_UART_1_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_UART2_EXT_UCLK, "gout_uart2_ext_uclk", "mout_peri_uart2_user",
+            CLK_CON_GAT_GOUT_PERI_UART_2_EXT_UCLK, 21, 0, 0),
+       GATE(CLK_GOUT_UART2_PCLK, "gout_uart2_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_UART_2_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_USI0_PCLK, "gout_usi0_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_USI0_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_USI0_SCLK, "gout_usi0_sclk", "mout_peri_usi0_user",
+            CLK_CON_GAT_GOUT_PERI_USI0_SCLK, 21, 0, 0),
+       GATE(CLK_GOUT_USI1_PCLK, "gout_usi1_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_USI1_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_USI1_SCLK, "gout_usi1_sclk", "mout_peri_usi1_user",
+            CLK_CON_GAT_GOUT_PERI_USI1_SCLK, 21, 0, 0),
+       GATE(CLK_GOUT_USI2_PCLK, "gout_usi2_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_USI2_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_USI2_SCLK, "gout_usi2_sclk", "mout_peri_usi2_user",
+            CLK_CON_GAT_GOUT_PERI_USI2_SCLK, 21, 0, 0),
+       GATE(CLK_GOUT_MCT_PCLK, "gout_mct_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_MCT_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_SYSREG_PERI_PCLK, "gout_sysreg_peri_pclk",
+            "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_WDT0_PCLK, "gout_wdt0_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER0_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_WDT1_PCLK, "gout_wdt1_pclk", "mout_peri_bus_user",
+            CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER1_PCLK, 21, 0, 0),
+};
+
+static const struct samsung_cmu_info peri_cmu_info __initconst = {
+       .mux_clks               = peri_mux_clks,
+       .nr_mux_clks            = ARRAY_SIZE(peri_mux_clks),
+       .gate_clks              = peri_gate_clks,
+       .nr_gate_clks           = ARRAY_SIZE(peri_gate_clks),
+       .nr_clk_ids             = PERI_NR_CLK,
+       .clk_regs               = peri_clk_regs,
+       .nr_clk_regs            = ARRAY_SIZE(peri_clk_regs),
+       .clk_name               = "dout_peri_bus",
+};
+
+static void __init exynos7885_cmu_peri_init(struct device_node *np)
+{
+       exynos_arm64_register_cmu(NULL, np, &peri_cmu_info);
+}
+
+/* Register CMU_PERI early, as it's needed for MCT timer */
+CLK_OF_DECLARE(exynos7885_cmu_peri, "samsung,exynos7885-cmu-peri",
+              exynos7885_cmu_peri_init);
+
+/* ---- CMU_CORE ------------------------------------------------------------ */
+
+/* Register Offset definitions for CMU_CORE (0x12000000) */
+#define PLL_CON0_MUX_CLKCMU_CORE_BUS_USER      0x0100
+#define PLL_CON0_MUX_CLKCMU_CORE_CCI_USER      0x0120
+#define PLL_CON0_MUX_CLKCMU_CORE_G3D_USER      0x0140
+#define CLK_CON_MUX_MUX_CLK_CORE_GIC           0x1000
+#define CLK_CON_DIV_DIV_CLK_CORE_BUSP          0x1800
+#define CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK     0x2054
+#define CLK_CON_GAT_GOUT_CORE_GIC400_CLK       0x2058
+
+static const unsigned long core_clk_regs[] __initconst = {
+       PLL_CON0_MUX_CLKCMU_CORE_BUS_USER,
+       PLL_CON0_MUX_CLKCMU_CORE_CCI_USER,
+       PLL_CON0_MUX_CLKCMU_CORE_G3D_USER,
+       CLK_CON_MUX_MUX_CLK_CORE_GIC,
+       CLK_CON_DIV_DIV_CLK_CORE_BUSP,
+       CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK,
+       CLK_CON_GAT_GOUT_CORE_GIC400_CLK,
+};
+
+/* List of parent clocks for Muxes in CMU_CORE */
+PNAME(mout_core_bus_user_p)            = { "oscclk", "dout_core_bus" };
+PNAME(mout_core_cci_user_p)            = { "oscclk", "dout_core_cci" };
+PNAME(mout_core_g3d_user_p)            = { "oscclk", "dout_core_g3d" };
+PNAME(mout_core_gic_p)                 = { "dout_core_busp", "oscclk" };
+
+static const struct samsung_mux_clock core_mux_clks[] __initconst = {
+       MUX(CLK_MOUT_CORE_BUS_USER, "mout_core_bus_user", mout_core_bus_user_p,
+           PLL_CON0_MUX_CLKCMU_CORE_BUS_USER, 4, 1),
+       MUX(CLK_MOUT_CORE_CCI_USER, "mout_core_cci_user", mout_core_cci_user_p,
+           PLL_CON0_MUX_CLKCMU_CORE_CCI_USER, 4, 1),
+       MUX(CLK_MOUT_CORE_G3D_USER, "mout_core_g3d_user", mout_core_g3d_user_p,
+           PLL_CON0_MUX_CLKCMU_CORE_G3D_USER, 4, 1),
+       MUX(CLK_MOUT_CORE_GIC, "mout_core_gic", mout_core_gic_p,
+           CLK_CON_MUX_MUX_CLK_CORE_GIC, 0, 1),
+};
+
+static const struct samsung_div_clock core_div_clks[] __initconst = {
+       DIV(CLK_DOUT_CORE_BUSP, "dout_core_busp", "mout_core_bus_user",
+           CLK_CON_DIV_DIV_CLK_CORE_BUSP, 0, 2),
+};
+
+static const struct samsung_gate_clock core_gate_clks[] __initconst = {
+       /* CCI (interconnect) clock must be always running */
+       GATE(CLK_GOUT_CCI_ACLK, "gout_cci_aclk", "mout_core_cci_user",
+            CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK, 21, CLK_IS_CRITICAL, 0),
+       /* GIC (interrupt controller) clock must be always running */
+       GATE(CLK_GOUT_GIC400_CLK, "gout_gic400_clk", "mout_core_gic",
+            CLK_CON_GAT_GOUT_CORE_GIC400_CLK, 21, CLK_IS_CRITICAL, 0),
+};
+
+static const struct samsung_cmu_info core_cmu_info __initconst = {
+       .mux_clks               = core_mux_clks,
+       .nr_mux_clks            = ARRAY_SIZE(core_mux_clks),
+       .div_clks               = core_div_clks,
+       .nr_div_clks            = ARRAY_SIZE(core_div_clks),
+       .gate_clks              = core_gate_clks,
+       .nr_gate_clks           = ARRAY_SIZE(core_gate_clks),
+       .nr_clk_ids             = CORE_NR_CLK,
+       .clk_regs               = core_clk_regs,
+       .nr_clk_regs            = ARRAY_SIZE(core_clk_regs),
+       .clk_name               = "dout_core_bus",
+};
+
+/* ---- platform_driver ----------------------------------------------------- */
+
+static int __init exynos7885_cmu_probe(struct platform_device *pdev)
+{
+       const struct samsung_cmu_info *info;
+       struct device *dev = &pdev->dev;
+
+       info = of_device_get_match_data(dev);
+       exynos_arm64_register_cmu(dev, dev->of_node, info);
+
+       return 0;
+}
+
+static const struct of_device_id exynos7885_cmu_of_match[] = {
+       {
+               .compatible = "samsung,exynos7885-cmu-core",
+               .data = &core_cmu_info,
+       }, {
+       },
+};
+
+static struct platform_driver exynos7885_cmu_driver __refdata = {
+       .driver = {
+               .name = "exynos7885-cmu",
+               .of_match_table = exynos7885_cmu_of_match,
+               .suppress_bind_attrs = true,
+       },
+       .probe = exynos7885_cmu_probe,
+};
+
+static int __init exynos7885_cmu_init(void)
+{
+       return platform_driver_register(&exynos7885_cmu_driver);
+}
+core_initcall(exynos7885_cmu_init);
index 2294989..cd9725f 100644 (file)
@@ -9,56 +9,13 @@
 #include <linux/clk.h>
 #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 <dt-bindings/clock/exynos850.h>
 
 #include "clk.h"
-
-/* Gate register bits */
-#define GATE_MANUAL            BIT(20)
-#define GATE_ENABLE_HWACG      BIT(28)
-
-/* Gate register offsets range */
-#define GATE_OFF_START         0x2000
-#define GATE_OFF_END           0x2fff
-
-/**
- * exynos850_init_clocks - Set clocks initial configuration
- * @np:                        CMU device tree node with "reg" property (CMU addr)
- * @reg_offs:          Register offsets array for clocks to init
- * @reg_offs_len:      Number of register offsets in reg_offs array
- *
- * Set manual control mode for all gate clocks.
- */
-static void __init exynos850_init_clocks(struct device_node *np,
-               const unsigned long *reg_offs, size_t reg_offs_len)
-{
-       void __iomem *reg_base;
-       size_t i;
-
-       reg_base = of_iomap(np, 0);
-       if (!reg_base)
-               panic("%s: failed to map registers\n", __func__);
-
-       for (i = 0; i < reg_offs_len; ++i) {
-               void __iomem *reg = reg_base + reg_offs[i];
-               u32 val;
-
-               /* Modify only gate clock registers */
-               if (reg_offs[i] < GATE_OFF_START || reg_offs[i] > GATE_OFF_END)
-                       continue;
-
-               val = readl(reg);
-               val |= GATE_MANUAL;
-               val &= ~GATE_ENABLE_HWACG;
-               writel(val, reg);
-       }
-
-       iounmap(reg_base);
-}
+#include "clk-exynos-arm64.h"
 
 /* ---- CMU_TOP ------------------------------------------------------------- */
 
@@ -72,6 +29,7 @@ static void __init exynos850_init_clocks(struct device_node *np,
 #define PLL_CON3_PLL_SHARED0                   0x014c
 #define PLL_CON0_PLL_SHARED1                   0x0180
 #define PLL_CON3_PLL_SHARED1                   0x018c
+#define CLK_CON_MUX_MUX_CLKCMU_APM_BUS         0x1000
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS                0x1014
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_CCI                0x1018
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD   0x101c
@@ -83,6 +41,7 @@ static void __init exynos850_init_clocks(struct device_node *np,
 #define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS                0x1070
 #define CLK_CON_MUX_MUX_CLKCMU_PERI_IP         0x1074
 #define CLK_CON_MUX_MUX_CLKCMU_PERI_UART       0x1078
+#define CLK_CON_DIV_CLKCMU_APM_BUS             0x180c
 #define CLK_CON_DIV_CLKCMU_CORE_BUS            0x1820
 #define CLK_CON_DIV_CLKCMU_CORE_CCI            0x1824
 #define CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD       0x1828
@@ -100,6 +59,7 @@ static void __init exynos850_init_clocks(struct device_node *np,
 #define CLK_CON_DIV_PLL_SHARED1_DIV2           0x1898
 #define CLK_CON_DIV_PLL_SHARED1_DIV3           0x189c
 #define CLK_CON_DIV_PLL_SHARED1_DIV4           0x18a0
+#define CLK_CON_GAT_GATE_CLKCMU_APM_BUS                0x2008
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS       0x201c
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_CCI       0x2020
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD  0x2024
@@ -122,6 +82,7 @@ static const unsigned long top_clk_regs[] __initconst = {
        PLL_CON3_PLL_SHARED0,
        PLL_CON0_PLL_SHARED1,
        PLL_CON3_PLL_SHARED1,
+       CLK_CON_MUX_MUX_CLKCMU_APM_BUS,
        CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
        CLK_CON_MUX_MUX_CLKCMU_CORE_CCI,
        CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD,
@@ -133,6 +94,7 @@ static const unsigned long top_clk_regs[] __initconst = {
        CLK_CON_MUX_MUX_CLKCMU_PERI_BUS,
        CLK_CON_MUX_MUX_CLKCMU_PERI_IP,
        CLK_CON_MUX_MUX_CLKCMU_PERI_UART,
+       CLK_CON_DIV_CLKCMU_APM_BUS,
        CLK_CON_DIV_CLKCMU_CORE_BUS,
        CLK_CON_DIV_CLKCMU_CORE_CCI,
        CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD,
@@ -150,6 +112,7 @@ static const unsigned long top_clk_regs[] __initconst = {
        CLK_CON_DIV_PLL_SHARED1_DIV2,
        CLK_CON_DIV_PLL_SHARED1_DIV3,
        CLK_CON_DIV_PLL_SHARED1_DIV4,
+       CLK_CON_GAT_GATE_CLKCMU_APM_BUS,
        CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
        CLK_CON_GAT_GATE_CLKCMU_CORE_CCI,
        CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD,
@@ -183,6 +146,8 @@ static const struct samsung_pll_clock top_pll_clks[] __initconst = {
 PNAME(mout_shared0_pll_p)      = { "oscclk", "fout_shared0_pll" };
 PNAME(mout_shared1_pll_p)      = { "oscclk", "fout_shared1_pll" };
 PNAME(mout_mmc_pll_p)          = { "oscclk", "fout_mmc_pll" };
+/* List of parent clocks for Muxes in CMU_TOP: for CMU_APM */
+PNAME(mout_clkcmu_apm_bus_p)   = { "dout_shared0_div4", "pll_shared1_div4" };
 /* List of parent clocks for Muxes in CMU_TOP: for CMU_CORE */
 PNAME(mout_core_bus_p)         = { "dout_shared1_div2", "dout_shared0_div3",
                                    "dout_shared1_div3", "dout_shared0_div4" };
@@ -222,6 +187,10 @@ static const struct samsung_mux_clock top_mux_clks[] __initconst = {
        MUX(CLK_MOUT_MMC_PLL, "mout_mmc_pll", mout_mmc_pll_p,
            PLL_CON0_PLL_MMC, 4, 1),
 
+       /* APM */
+       MUX(CLK_MOUT_CLKCMU_APM_BUS, "mout_clkcmu_apm_bus",
+           mout_clkcmu_apm_bus_p, CLK_CON_MUX_MUX_CLKCMU_APM_BUS, 0, 1),
+
        /* CORE */
        MUX(CLK_MOUT_CORE_BUS, "mout_core_bus", mout_core_bus_p,
            CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 0, 2),
@@ -268,6 +237,10 @@ static const struct samsung_div_clock top_div_clks[] __initconst = {
        DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "dout_shared1_div2",
            CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1),
 
+       /* APM */
+       DIV(CLK_DOUT_CLKCMU_APM_BUS, "dout_clkcmu_apm_bus",
+           "gout_clkcmu_apm_bus", CLK_CON_DIV_CLKCMU_APM_BUS, 0, 3),
+
        /* CORE */
        DIV(CLK_DOUT_CORE_BUS, "dout_core_bus", "gout_core_bus",
            CLK_CON_DIV_CLKCMU_CORE_BUS, 0, 4),
@@ -310,6 +283,10 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
        GATE(CLK_GOUT_CORE_SSS, "gout_core_sss", "mout_core_sss",
             CLK_CON_GAT_GATE_CLKCMU_CORE_SSS, 21, 0, 0),
 
+       /* APM */
+       GATE(CLK_GOUT_CLKCMU_APM_BUS, "gout_clkcmu_apm_bus",
+            "mout_clkcmu_apm_bus", CLK_CON_GAT_GATE_CLKCMU_APM_BUS, 21, 0, 0),
+
        /* DPU */
        GATE(CLK_GOUT_DPU, "gout_dpu", "mout_dpu",
             CLK_CON_GAT_GATE_CLKCMU_DPU, 21, 0, 0),
@@ -347,13 +324,248 @@ static const struct samsung_cmu_info top_cmu_info __initconst = {
 
 static void __init exynos850_cmu_top_init(struct device_node *np)
 {
-       exynos850_init_clocks(np, top_clk_regs, ARRAY_SIZE(top_clk_regs));
-       samsung_cmu_register_one(np, &top_cmu_info);
+       exynos_arm64_register_cmu(NULL, np, &top_cmu_info);
 }
 
+/* Register CMU_TOP early, as it's a dependency for other early domains */
 CLK_OF_DECLARE(exynos850_cmu_top, "samsung,exynos850-cmu-top",
               exynos850_cmu_top_init);
 
+/* ---- CMU_APM ------------------------------------------------------------- */
+
+/* Register Offset definitions for CMU_APM (0x11800000) */
+#define PLL_CON0_MUX_CLKCMU_APM_BUS_USER               0x0600
+#define PLL_CON0_MUX_CLK_RCO_APM_I3C_USER              0x0610
+#define PLL_CON0_MUX_CLK_RCO_APM_USER                  0x0620
+#define PLL_CON0_MUX_DLL_USER                          0x0630
+#define CLK_CON_MUX_MUX_CLKCMU_CHUB_BUS                        0x1000
+#define CLK_CON_MUX_MUX_CLK_APM_BUS                    0x1004
+#define CLK_CON_MUX_MUX_CLK_APM_I3C                    0x1008
+#define CLK_CON_DIV_CLKCMU_CHUB_BUS                    0x1800
+#define CLK_CON_DIV_DIV_CLK_APM_BUS                    0x1804
+#define CLK_CON_DIV_DIV_CLK_APM_I3C                    0x1808
+#define CLK_CON_GAT_CLKCMU_CMGP_BUS                    0x2000
+#define CLK_CON_GAT_GATE_CLKCMU_CHUB_BUS               0x2014
+#define CLK_CON_GAT_GOUT_APM_APBIF_GPIO_ALIVE_PCLK     0x2018
+#define CLK_CON_GAT_GOUT_APM_APBIF_PMU_ALIVE_PCLK      0x2020
+#define CLK_CON_GAT_GOUT_APM_APBIF_RTC_PCLK            0x2024
+#define CLK_CON_GAT_GOUT_APM_APBIF_TOP_RTC_PCLK                0x2028
+#define CLK_CON_GAT_GOUT_APM_I3C_APM_PMIC_I_PCLK       0x2034
+#define CLK_CON_GAT_GOUT_APM_I3C_APM_PMIC_I_SCLK       0x2038
+#define CLK_CON_GAT_GOUT_APM_SPEEDY_APM_PCLK           0x20bc
+#define CLK_CON_GAT_GOUT_APM_SYSREG_APM_PCLK           0x20c0
+
+static const unsigned long apm_clk_regs[] __initconst = {
+       PLL_CON0_MUX_CLKCMU_APM_BUS_USER,
+       PLL_CON0_MUX_CLK_RCO_APM_I3C_USER,
+       PLL_CON0_MUX_CLK_RCO_APM_USER,
+       PLL_CON0_MUX_DLL_USER,
+       CLK_CON_MUX_MUX_CLKCMU_CHUB_BUS,
+       CLK_CON_MUX_MUX_CLK_APM_BUS,
+       CLK_CON_MUX_MUX_CLK_APM_I3C,
+       CLK_CON_DIV_CLKCMU_CHUB_BUS,
+       CLK_CON_DIV_DIV_CLK_APM_BUS,
+       CLK_CON_DIV_DIV_CLK_APM_I3C,
+       CLK_CON_GAT_CLKCMU_CMGP_BUS,
+       CLK_CON_GAT_GATE_CLKCMU_CHUB_BUS,
+       CLK_CON_GAT_GOUT_APM_APBIF_GPIO_ALIVE_PCLK,
+       CLK_CON_GAT_GOUT_APM_APBIF_PMU_ALIVE_PCLK,
+       CLK_CON_GAT_GOUT_APM_APBIF_RTC_PCLK,
+       CLK_CON_GAT_GOUT_APM_APBIF_TOP_RTC_PCLK,
+       CLK_CON_GAT_GOUT_APM_I3C_APM_PMIC_I_PCLK,
+       CLK_CON_GAT_GOUT_APM_I3C_APM_PMIC_I_SCLK,
+       CLK_CON_GAT_GOUT_APM_SPEEDY_APM_PCLK,
+       CLK_CON_GAT_GOUT_APM_SYSREG_APM_PCLK,
+};
+
+/* List of parent clocks for Muxes in CMU_APM */
+PNAME(mout_apm_bus_user_p)     = { "oscclk_rco_apm", "dout_clkcmu_apm_bus" };
+PNAME(mout_rco_apm_i3c_user_p) = { "oscclk_rco_apm", "clk_rco_i3c_pmic" };
+PNAME(mout_rco_apm_user_p)     = { "oscclk_rco_apm", "clk_rco_apm__alv" };
+PNAME(mout_dll_user_p)         = { "oscclk_rco_apm", "clk_dll_dco" };
+PNAME(mout_clkcmu_chub_bus_p)  = { "mout_apm_bus_user", "mout_dll_user" };
+PNAME(mout_apm_bus_p)          = { "mout_rco_apm_user", "mout_apm_bus_user",
+                                   "mout_dll_user", "oscclk_rco_apm" };
+PNAME(mout_apm_i3c_p)          = { "dout_apm_i3c", "mout_rco_apm_i3c_user" };
+
+static const struct samsung_fixed_rate_clock apm_fixed_clks[] __initconst = {
+       FRATE(CLK_RCO_I3C_PMIC, "clk_rco_i3c_pmic", NULL, 0, 491520000),
+       FRATE(OSCCLK_RCO_APM, "oscclk_rco_apm", NULL, 0, 24576000),
+       FRATE(CLK_RCO_APM__ALV, "clk_rco_apm__alv", NULL, 0, 49152000),
+       FRATE(CLK_DLL_DCO, "clk_dll_dco", NULL, 0, 360000000),
+};
+
+static const struct samsung_mux_clock apm_mux_clks[] __initconst = {
+       MUX(CLK_MOUT_APM_BUS_USER, "mout_apm_bus_user", mout_apm_bus_user_p,
+           PLL_CON0_MUX_CLKCMU_APM_BUS_USER, 4, 1),
+       MUX(CLK_MOUT_RCO_APM_I3C_USER, "mout_rco_apm_i3c_user",
+           mout_rco_apm_i3c_user_p, PLL_CON0_MUX_CLK_RCO_APM_I3C_USER, 4, 1),
+       MUX(CLK_MOUT_RCO_APM_USER, "mout_rco_apm_user", mout_rco_apm_user_p,
+           PLL_CON0_MUX_CLK_RCO_APM_USER, 4, 1),
+       MUX(CLK_MOUT_DLL_USER, "mout_dll_user", mout_dll_user_p,
+           PLL_CON0_MUX_DLL_USER, 4, 1),
+       MUX(CLK_MOUT_CLKCMU_CHUB_BUS, "mout_clkcmu_chub_bus",
+           mout_clkcmu_chub_bus_p, CLK_CON_MUX_MUX_CLKCMU_CHUB_BUS, 0, 1),
+       MUX(CLK_MOUT_APM_BUS, "mout_apm_bus", mout_apm_bus_p,
+           CLK_CON_MUX_MUX_CLK_APM_BUS, 0, 2),
+       MUX(CLK_MOUT_APM_I3C, "mout_apm_i3c", mout_apm_i3c_p,
+           CLK_CON_MUX_MUX_CLK_APM_I3C, 0, 1),
+};
+
+static const struct samsung_div_clock apm_div_clks[] __initconst = {
+       DIV(CLK_DOUT_CLKCMU_CHUB_BUS, "dout_clkcmu_chub_bus",
+           "gout_clkcmu_chub_bus",
+           CLK_CON_DIV_CLKCMU_CHUB_BUS, 0, 3),
+       DIV(CLK_DOUT_APM_BUS, "dout_apm_bus", "mout_apm_bus",
+           CLK_CON_DIV_DIV_CLK_APM_BUS, 0, 3),
+       DIV(CLK_DOUT_APM_I3C, "dout_apm_i3c", "mout_apm_bus",
+           CLK_CON_DIV_DIV_CLK_APM_I3C, 0, 3),
+};
+
+static const struct samsung_gate_clock apm_gate_clks[] __initconst = {
+       GATE(CLK_GOUT_CLKCMU_CMGP_BUS, "gout_clkcmu_cmgp_bus", "dout_apm_bus",
+            CLK_CON_GAT_CLKCMU_CMGP_BUS, 21, 0, 0),
+       GATE(CLK_GOUT_CLKCMU_CHUB_BUS, "gout_clkcmu_chub_bus",
+            "mout_clkcmu_chub_bus",
+            CLK_CON_GAT_GATE_CLKCMU_CHUB_BUS, 21, 0, 0),
+       GATE(CLK_GOUT_RTC_PCLK, "gout_rtc_pclk", "dout_apm_bus",
+            CLK_CON_GAT_GOUT_APM_APBIF_RTC_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_TOP_RTC_PCLK, "gout_top_rtc_pclk", "dout_apm_bus",
+            CLK_CON_GAT_GOUT_APM_APBIF_TOP_RTC_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_I3C_PCLK, "gout_i3c_pclk", "dout_apm_bus",
+            CLK_CON_GAT_GOUT_APM_I3C_APM_PMIC_I_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_I3C_SCLK, "gout_i3c_sclk", "mout_apm_i3c",
+            CLK_CON_GAT_GOUT_APM_I3C_APM_PMIC_I_SCLK, 21, 0, 0),
+       GATE(CLK_GOUT_SPEEDY_PCLK, "gout_speedy_pclk", "dout_apm_bus",
+            CLK_CON_GAT_GOUT_APM_SPEEDY_APM_PCLK, 21, 0, 0),
+       /* TODO: Should be enabled in GPIO driver (or made CLK_IS_CRITICAL) */
+       GATE(CLK_GOUT_GPIO_ALIVE_PCLK, "gout_gpio_alive_pclk", "dout_apm_bus",
+            CLK_CON_GAT_GOUT_APM_APBIF_GPIO_ALIVE_PCLK, 21, CLK_IGNORE_UNUSED,
+            0),
+       GATE(CLK_GOUT_PMU_ALIVE_PCLK, "gout_pmu_alive_pclk", "dout_apm_bus",
+            CLK_CON_GAT_GOUT_APM_APBIF_PMU_ALIVE_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_SYSREG_APM_PCLK, "gout_sysreg_apm_pclk", "dout_apm_bus",
+            CLK_CON_GAT_GOUT_APM_SYSREG_APM_PCLK, 21, 0, 0),
+};
+
+static const struct samsung_cmu_info apm_cmu_info __initconst = {
+       .mux_clks               = apm_mux_clks,
+       .nr_mux_clks            = ARRAY_SIZE(apm_mux_clks),
+       .div_clks               = apm_div_clks,
+       .nr_div_clks            = ARRAY_SIZE(apm_div_clks),
+       .gate_clks              = apm_gate_clks,
+       .nr_gate_clks           = ARRAY_SIZE(apm_gate_clks),
+       .fixed_clks             = apm_fixed_clks,
+       .nr_fixed_clks          = ARRAY_SIZE(apm_fixed_clks),
+       .nr_clk_ids             = APM_NR_CLK,
+       .clk_regs               = apm_clk_regs,
+       .nr_clk_regs            = ARRAY_SIZE(apm_clk_regs),
+       .clk_name               = "dout_clkcmu_apm_bus",
+};
+
+/* ---- CMU_CMGP ------------------------------------------------------------ */
+
+/* Register Offset definitions for CMU_CMGP (0x11c00000) */
+#define CLK_CON_MUX_CLK_CMGP_ADC               0x1000
+#define CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP0     0x1004
+#define CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP1     0x1008
+#define CLK_CON_DIV_DIV_CLK_CMGP_ADC           0x1800
+#define CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP0     0x1804
+#define CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP1     0x1808
+#define CLK_CON_GAT_GOUT_CMGP_ADC_PCLK_S0      0x200c
+#define CLK_CON_GAT_GOUT_CMGP_ADC_PCLK_S1      0x2010
+#define CLK_CON_GAT_GOUT_CMGP_GPIO_PCLK                0x2018
+#define CLK_CON_GAT_GOUT_CMGP_SYSREG_CMGP_PCLK 0x2040
+#define CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_IPCLK  0x2044
+#define CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_PCLK   0x2048
+#define CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_IPCLK  0x204c
+#define CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_PCLK   0x2050
+
+static const unsigned long cmgp_clk_regs[] __initconst = {
+       CLK_CON_MUX_CLK_CMGP_ADC,
+       CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP0,
+       CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP1,
+       CLK_CON_DIV_DIV_CLK_CMGP_ADC,
+       CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP0,
+       CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP1,
+       CLK_CON_GAT_GOUT_CMGP_ADC_PCLK_S0,
+       CLK_CON_GAT_GOUT_CMGP_ADC_PCLK_S1,
+       CLK_CON_GAT_GOUT_CMGP_GPIO_PCLK,
+       CLK_CON_GAT_GOUT_CMGP_SYSREG_CMGP_PCLK,
+       CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_IPCLK,
+       CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_PCLK,
+       CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_IPCLK,
+       CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_PCLK,
+};
+
+/* List of parent clocks for Muxes in CMU_CMGP */
+PNAME(mout_cmgp_usi0_p)        = { "clk_rco_cmgp", "gout_clkcmu_cmgp_bus" };
+PNAME(mout_cmgp_usi1_p)        = { "clk_rco_cmgp", "gout_clkcmu_cmgp_bus" };
+PNAME(mout_cmgp_adc_p) = { "oscclk", "dout_cmgp_adc" };
+
+static const struct samsung_fixed_rate_clock cmgp_fixed_clks[] __initconst = {
+       FRATE(CLK_RCO_CMGP, "clk_rco_cmgp", NULL, 0, 49152000),
+};
+
+static const struct samsung_mux_clock cmgp_mux_clks[] __initconst = {
+       MUX(CLK_MOUT_CMGP_ADC, "mout_cmgp_adc", mout_cmgp_adc_p,
+           CLK_CON_MUX_CLK_CMGP_ADC, 0, 1),
+       MUX(CLK_MOUT_CMGP_USI0, "mout_cmgp_usi0", mout_cmgp_usi0_p,
+           CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP0, 0, 1),
+       MUX(CLK_MOUT_CMGP_USI1, "mout_cmgp_usi1", mout_cmgp_usi1_p,
+           CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP1, 0, 1),
+};
+
+static const struct samsung_div_clock cmgp_div_clks[] __initconst = {
+       DIV(CLK_DOUT_CMGP_ADC, "dout_cmgp_adc", "gout_clkcmu_cmgp_bus",
+           CLK_CON_DIV_DIV_CLK_CMGP_ADC, 0, 4),
+       DIV(CLK_DOUT_CMGP_USI0, "dout_cmgp_usi0", "mout_cmgp_usi0",
+           CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP0, 0, 5),
+       DIV(CLK_DOUT_CMGP_USI1, "dout_cmgp_usi1", "mout_cmgp_usi1",
+           CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP1, 0, 5),
+};
+
+static const struct samsung_gate_clock cmgp_gate_clks[] __initconst = {
+       GATE(CLK_GOUT_CMGP_ADC_S0_PCLK, "gout_adc_s0_pclk",
+            "gout_clkcmu_cmgp_bus",
+            CLK_CON_GAT_GOUT_CMGP_ADC_PCLK_S0, 21, 0, 0),
+       GATE(CLK_GOUT_CMGP_ADC_S1_PCLK, "gout_adc_s1_pclk",
+            "gout_clkcmu_cmgp_bus",
+            CLK_CON_GAT_GOUT_CMGP_ADC_PCLK_S1, 21, 0, 0),
+       /* TODO: Should be enabled in GPIO driver (or made CLK_IS_CRITICAL) */
+       GATE(CLK_GOUT_CMGP_GPIO_PCLK, "gout_gpio_cmgp_pclk",
+            "gout_clkcmu_cmgp_bus",
+            CLK_CON_GAT_GOUT_CMGP_GPIO_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+       GATE(CLK_GOUT_CMGP_USI0_IPCLK, "gout_cmgp_usi0_ipclk", "dout_cmgp_usi0",
+            CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_IPCLK, 21, 0, 0),
+       GATE(CLK_GOUT_CMGP_USI0_PCLK, "gout_cmgp_usi0_pclk",
+            "gout_clkcmu_cmgp_bus",
+            CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_CMGP_USI1_IPCLK, "gout_cmgp_usi1_ipclk", "dout_cmgp_usi1",
+            CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_IPCLK, 21, 0, 0),
+       GATE(CLK_GOUT_CMGP_USI1_PCLK, "gout_cmgp_usi1_pclk",
+            "gout_clkcmu_cmgp_bus",
+            CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_PCLK, 21, 0, 0),
+       GATE(CLK_GOUT_SYSREG_CMGP_PCLK, "gout_sysreg_cmgp_pclk",
+            "gout_clkcmu_cmgp_bus",
+            CLK_CON_GAT_GOUT_CMGP_SYSREG_CMGP_PCLK, 21, 0, 0),
+};
+
+static const struct samsung_cmu_info cmgp_cmu_info __initconst = {
+       .mux_clks               = cmgp_mux_clks,
+       .nr_mux_clks            = ARRAY_SIZE(cmgp_mux_clks),
+       .div_clks               = cmgp_div_clks,
+       .nr_div_clks            = ARRAY_SIZE(cmgp_div_clks),
+       .gate_clks              = cmgp_gate_clks,
+       .nr_gate_clks           = ARRAY_SIZE(cmgp_gate_clks),
+       .fixed_clks             = cmgp_fixed_clks,
+       .nr_fixed_clks          = ARRAY_SIZE(cmgp_fixed_clks),
+       .nr_clk_ids             = CMGP_NR_CLK,
+       .clk_regs               = cmgp_clk_regs,
+       .nr_clk_regs            = ARRAY_SIZE(cmgp_clk_regs),
+       .clk_name               = "gout_clkcmu_cmgp_bus",
+};
+
 /* ---- CMU_HSI ------------------------------------------------------------- */
 
 /* Register Offset definitions for CMU_HSI (0x13400000) */
@@ -413,8 +625,9 @@ static const struct samsung_gate_clock hsi_gate_clks[] __initconst = {
             CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50, 21, 0, 0),
        GATE(CLK_GOUT_USB_PHY_REF_CLK, "gout_usb_phy_ref", "oscclk",
             CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26, 21, 0, 0),
+       /* TODO: Should be enabled in GPIO driver (or made CLK_IS_CRITICAL) */
        GATE(CLK_GOUT_GPIO_HSI_PCLK, "gout_gpio_hsi_pclk", "mout_hsi_bus_user",
-            CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK, 21, 0, 0),
+            CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK, 21, CLK_IGNORE_UNUSED, 0),
        GATE(CLK_GOUT_MMC_CARD_ACLK, "gout_mmc_card_aclk", "mout_hsi_bus_user",
             CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK, 21, 0, 0),
        GATE(CLK_GOUT_MMC_CARD_SDCLKIN, "gout_mmc_card_sdclkin",
@@ -597,9 +810,10 @@ static const struct samsung_gate_clock peri_gate_clks[] __initconst = {
             CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK, 21, 0, 0),
        GATE(CLK_GOUT_WDT1_PCLK, "gout_wdt1_pclk", "mout_peri_bus_user",
             CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK, 21, 0, 0),
+       /* TODO: Should be enabled in GPIO driver (or made CLK_IS_CRITICAL) */
        GATE(CLK_GOUT_GPIO_PERI_PCLK, "gout_gpio_peri_pclk",
             "mout_peri_bus_user",
-            CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK, 21, 0, 0),
+            CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK, 21, CLK_IGNORE_UNUSED, 0),
 };
 
 static const struct samsung_cmu_info peri_cmu_info __initconst = {
@@ -615,6 +829,15 @@ static const struct samsung_cmu_info peri_cmu_info __initconst = {
        .clk_name               = "dout_peri_bus",
 };
 
+static void __init exynos850_cmu_peri_init(struct device_node *np)
+{
+       exynos_arm64_register_cmu(NULL, np, &peri_cmu_info);
+}
+
+/* Register CMU_PERI early, as it's needed for MCT timer */
+CLK_OF_DECLARE(exynos850_cmu_peri, "samsung,exynos850-cmu-peri",
+              exynos850_cmu_peri_init);
+
 /* ---- CMU_CORE ------------------------------------------------------------ */
 
 /* Register Offset definitions for CMU_CORE (0x12000000) */
@@ -626,10 +849,12 @@ static const struct samsung_cmu_info peri_cmu_info __initconst = {
 #define CLK_CON_DIV_DIV_CLK_CORE_BUSP          0x1800
 #define CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK     0x2038
 #define CLK_CON_GAT_GOUT_CORE_GIC_CLK          0x2040
+#define CLK_CON_GAT_GOUT_CORE_GPIO_CORE_PCLK   0x2044
 #define CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK  0x20e8
 #define CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN 0x20ec
 #define CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK       0x2128
 #define CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK       0x212c
+#define CLK_CON_GAT_GOUT_CORE_SYSREG_CORE_PCLK 0x2130
 
 static const unsigned long core_clk_regs[] __initconst = {
        PLL_CON0_MUX_CLKCMU_CORE_BUS_USER,
@@ -640,10 +865,12 @@ static const unsigned long core_clk_regs[] __initconst = {
        CLK_CON_DIV_DIV_CLK_CORE_BUSP,
        CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK,
        CLK_CON_GAT_GOUT_CORE_GIC_CLK,
+       CLK_CON_GAT_GOUT_CORE_GPIO_CORE_PCLK,
        CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK,
        CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN,
        CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK,
        CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK,
+       CLK_CON_GAT_GOUT_CORE_SYSREG_CORE_PCLK,
 };
 
 /* List of parent clocks for Muxes in CMU_CORE */
@@ -673,10 +900,12 @@ static const struct samsung_div_clock core_div_clks[] __initconst = {
 };
 
 static const struct samsung_gate_clock core_gate_clks[] __initconst = {
+       /* CCI (interconnect) clock must be always running */
        GATE(CLK_GOUT_CCI_ACLK, "gout_cci_aclk", "mout_core_cci_user",
-            CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK, 21, 0, 0),
+            CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK, 21, CLK_IS_CRITICAL, 0),
+       /* GIC (interrupt controller) clock must be always running */
        GATE(CLK_GOUT_GIC_CLK, "gout_gic_clk", "mout_core_gic",
-            CLK_CON_GAT_GOUT_CORE_GIC_CLK, 21, 0, 0),
+            CLK_CON_GAT_GOUT_CORE_GIC_CLK, 21, CLK_IS_CRITICAL, 0),
        GATE(CLK_GOUT_MMC_EMBD_ACLK, "gout_mmc_embd_aclk", "dout_core_busp",
             CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK, 21, 0, 0),
        GATE(CLK_GOUT_MMC_EMBD_SDCLKIN, "gout_mmc_embd_sdclkin",
@@ -686,6 +915,12 @@ static const struct samsung_gate_clock core_gate_clks[] __initconst = {
             CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK, 21, 0, 0),
        GATE(CLK_GOUT_SSS_PCLK, "gout_sss_pclk", "dout_core_busp",
             CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK, 21, 0, 0),
+       /* TODO: Should be enabled in GPIO driver (or made CLK_IS_CRITICAL) */
+       GATE(CLK_GOUT_GPIO_CORE_PCLK, "gout_gpio_core_pclk", "dout_core_busp",
+            CLK_CON_GAT_GOUT_CORE_GPIO_CORE_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+       GATE(CLK_GOUT_SYSREG_CORE_PCLK, "gout_sysreg_core_pclk",
+            "dout_core_busp",
+            CLK_CON_GAT_GOUT_CORE_SYSREG_CORE_PCLK, 21, 0, 0),
 };
 
 static const struct samsung_cmu_info core_cmu_info __initconst = {
@@ -742,8 +977,10 @@ static const struct samsung_div_clock dpu_div_clks[] __initconst = {
 };
 
 static const struct samsung_gate_clock dpu_gate_clks[] __initconst = {
+       /* TODO: Should be enabled in DSIM driver */
        GATE(CLK_GOUT_DPU_CMU_DPU_PCLK, "gout_dpu_cmu_dpu_pclk",
-            "dout_dpu_busp", CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK, 21, 0, 0),
+            "dout_dpu_busp",
+            CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK, 21, CLK_IGNORE_UNUSED, 0),
        GATE(CLK_GOUT_DPU_DECON0_ACLK, "gout_dpu_decon0_aclk", "mout_dpu_user",
             CLK_CON_GAT_GOUT_DPU_ACLK_DECON0, 21, 0, 0),
        GATE(CLK_GOUT_DPU_DMA_ACLK, "gout_dpu_dma_aclk", "mout_dpu_user",
@@ -779,36 +1016,23 @@ static int __init exynos850_cmu_probe(struct platform_device *pdev)
 {
        const struct samsung_cmu_info *info;
        struct device *dev = &pdev->dev;
-       struct device_node *np = dev->of_node;
 
        info = of_device_get_match_data(dev);
-       exynos850_init_clocks(np, info->clk_regs, info->nr_clk_regs);
-       samsung_cmu_register_one(np, info);
-
-       /* Keep bus clock running, so it's possible to access CMU registers */
-       if (info->clk_name) {
-               struct clk *bus_clk;
-
-               bus_clk = clk_get(dev, info->clk_name);
-               if (IS_ERR(bus_clk)) {
-                       pr_err("%s: could not find bus clock %s; err = %ld\n",
-                              __func__, info->clk_name, PTR_ERR(bus_clk));
-               } else {
-                       clk_prepare_enable(bus_clk);
-               }
-       }
+       exynos_arm64_register_cmu(dev, dev->of_node, info);
 
        return 0;
 }
 
-/* CMUs which belong to Power Domains and need runtime PM to be implemented */
 static const struct of_device_id exynos850_cmu_of_match[] = {
        {
+               .compatible = "samsung,exynos850-cmu-apm",
+               .data = &apm_cmu_info,
+       }, {
+               .compatible = "samsung,exynos850-cmu-cmgp",
+               .data = &cmgp_cmu_info,
+       }, {
                .compatible = "samsung,exynos850-cmu-hsi",
                .data = &hsi_cmu_info,
-       }, {
-               .compatible = "samsung,exynos850-cmu-peri",
-               .data = &peri_cmu_info,
        }, {
                .compatible = "samsung,exynos850-cmu-core",
                .data = &core_cmu_info,
index 83d1b03..70cdc87 100644 (file)
@@ -1476,6 +1476,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
                else
                        init.ops = &samsung_pll35xx_clk_ops;
                break;
+       case pll_1417x:
        case pll_0822x:
                pll->enable_offs = PLL0822X_ENABLE_SHIFT;
                pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT;
index a739f2b..c83a201 100644 (file)
@@ -32,6 +32,7 @@ enum samsung_pll_type {
        pll_2550xx,
        pll_2650x,
        pll_2650xx,
+       pll_1417x,
        pll_1450x,
        pll_1451x,
        pll_1452x,
index 5831d06..3d152a4 100644 (file)
@@ -323,6 +323,7 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
                                    void __iomem *base)
 {
        struct samsung_clk_provider *ctx;
+       struct clk_hw **hws;
        reg_base = base;
 
        if (np) {
@@ -332,13 +333,14 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
        }
 
        ctx = samsung_clk_init(np, reg_base, NR_CLKS);
+       hws = ctx->clk_data.hws;
 
        /* Register external clocks only in non-dt cases */
        if (!np)
                s3c2410_common_clk_register_fixed_ext(ctx, xti_f);
 
        if (current_soc == S3C2410) {
-               if (_get_rate("xti") == 12 * MHZ) {
+               if (clk_hw_get_rate(hws[XTI]) == 12 * MHZ) {
                        s3c2410_plls[mpll].rate_table = pll_s3c2410_12mhz_tbl;
                        s3c2410_plls[upll].rate_table = pll_s3c2410_12mhz_tbl;
                }
@@ -348,7 +350,7 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
                                ARRAY_SIZE(s3c2410_plls), reg_base);
 
        } else { /* S3C2440, S3C2442 */
-               if (_get_rate("xti") == 12 * MHZ) {
+               if (clk_hw_get_rate(hws[XTI]) == 12 * MHZ) {
                        /*
                         * plls follow different calculation schemes, with the
                         * upll following the same scheme as the s3c2410 plls
index 56f95b6..d6b432a 100644 (file)
@@ -394,6 +394,7 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
                             void __iomem *base)
 {
        struct samsung_clk_provider *ctx;
+       struct clk_hw **hws;
 
        reg_base = base;
        is_s3c6400 = s3c6400;
@@ -405,6 +406,7 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
        }
 
        ctx = samsung_clk_init(np, reg_base, NR_CLKS);
+       hws = ctx->clk_data.hws;
 
        /* Register external clocks. */
        if (!np)
@@ -459,8 +461,10 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
        pr_info("%s clocks: apll = %lu, mpll = %lu\n"
                "\tepll = %lu, arm_clk = %lu\n",
                is_s3c6400 ? "S3C6400" : "S3C6410",
-               _get_rate("fout_apll"), _get_rate("fout_mpll"),
-               _get_rate("fout_epll"), _get_rate("armclk"));
+               clk_hw_get_rate(hws[MOUT_APLL]),
+               clk_hw_get_rate(hws[MOUT_MPLL]),
+               clk_hw_get_rate(hws[MOUT_EPLL]),
+               clk_hw_get_rate(hws[ARMCLK]));
 }
 
 static void __init s3c6400_clk_init(struct device_node *np)
index e7b68ff..4425186 100644 (file)
@@ -741,8 +741,10 @@ static void __init __s5pv210_clk_init(struct device_node *np,
                                      bool is_s5p6442)
 {
        struct samsung_clk_provider *ctx;
+       struct clk_hw **hws;
 
        ctx = samsung_clk_init(np, reg_base, NR_CLKS);
+       hws = ctx->clk_data.hws;
 
        samsung_clk_register_mux(ctx, early_mux_clks,
                                        ARRAY_SIZE(early_mux_clks));
@@ -789,8 +791,10 @@ static void __init __s5pv210_clk_init(struct device_node *np,
        pr_info("%s clocks: mout_apll = %ld, mout_mpll = %ld\n"
                "\tmout_epll = %ld, mout_vpll = %ld\n",
                is_s5p6442 ? "S5P6442" : "S5PV210",
-               _get_rate("mout_apll"), _get_rate("mout_mpll"),
-               _get_rate("mout_epll"), _get_rate("mout_vpll"));
+               clk_hw_get_rate(hws[MOUT_APLL]),
+               clk_hw_get_rate(hws[MOUT_MPLL]),
+               clk_hw_get_rate(hws[MOUT_EPLL]),
+               clk_hw_get_rate(hws[MOUT_VPLL]));
 }
 
 static void __init s5pv210_clk_dt_init(struct device_node *np)
index 336243c..bca4731 100644 (file)
@@ -268,20 +268,6 @@ void __init samsung_clk_of_register_fixed_ext(struct samsung_clk_provider *ctx,
        samsung_clk_register_fixed_rate(ctx, fixed_rate_clk, nr_fixed_rate_clk);
 }
 
-/* utility function to get the rate of a specified clock */
-unsigned long _get_rate(const char *clk_name)
-{
-       struct clk *clk;
-
-       clk = __clk_lookup(clk_name);
-       if (!clk) {
-               pr_err("%s: could not find clock %s\n", __func__, clk_name);
-               return 0;
-       }
-
-       return clk_get_rate(clk);
-}
-
 #ifdef CONFIG_PM_SLEEP
 static int samsung_clk_suspend(void)
 {
index 26499e9..b46e83a 100644 (file)
@@ -337,54 +337,52 @@ struct samsung_cmu_info {
        const char *clk_name;
 };
 
-extern struct samsung_clk_provider *__init samsung_clk_init(
+struct samsung_clk_provider * samsung_clk_init(
                        struct device_node *np, void __iomem *base,
                        unsigned long nr_clks);
-extern void __init samsung_clk_of_add_provider(struct device_node *np,
+void samsung_clk_of_add_provider(struct device_node *np,
                        struct samsung_clk_provider *ctx);
-extern void __init samsung_clk_of_register_fixed_ext(
+void samsung_clk_of_register_fixed_ext(
                        struct samsung_clk_provider *ctx,
                        struct samsung_fixed_rate_clock *fixed_rate_clk,
                        unsigned int nr_fixed_rate_clk,
                        const struct of_device_id *clk_matches);
 
-extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
+void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
                        struct clk_hw *clk_hw, unsigned int id);
 
-extern void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx,
+void samsung_clk_register_alias(struct samsung_clk_provider *ctx,
                        const struct samsung_clock_alias *list,
                        unsigned int nr_clk);
-extern void __init samsung_clk_register_fixed_rate(
+void samsung_clk_register_fixed_rate(
                        struct samsung_clk_provider *ctx,
                        const struct samsung_fixed_rate_clock *clk_list,
                        unsigned int nr_clk);
-extern void __init samsung_clk_register_fixed_factor(
+void samsung_clk_register_fixed_factor(
                        struct samsung_clk_provider *ctx,
                        const struct samsung_fixed_factor_clock *list,
                        unsigned int nr_clk);
-extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
+void samsung_clk_register_mux(struct samsung_clk_provider *ctx,
                        const struct samsung_mux_clock *clk_list,
                        unsigned int nr_clk);
-extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
+void samsung_clk_register_div(struct samsung_clk_provider *ctx,
                        const struct samsung_div_clock *clk_list,
                        unsigned int nr_clk);
-extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
+void samsung_clk_register_gate(struct samsung_clk_provider *ctx,
                        const struct samsung_gate_clock *clk_list,
                        unsigned int nr_clk);
-extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
+void samsung_clk_register_pll(struct samsung_clk_provider *ctx,
                        const struct samsung_pll_clock *pll_list,
                        unsigned int nr_clk, void __iomem *base);
-extern void samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
+void samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
                const struct samsung_cpu_clock *list, unsigned int nr_clk);
 
-extern struct samsung_clk_provider __init *samsung_cmu_register_one(
+struct samsung_clk_provider *samsung_cmu_register_one(
                        struct device_node *,
                        const struct samsung_cmu_info *);
 
-extern unsigned long _get_rate(const char *clk_name);
-
 #ifdef CONFIG_PM_SLEEP
-extern void samsung_clk_extended_sleep_init(void __iomem *reg_base,
+void samsung_clk_extended_sleep_init(void __iomem *reg_base,
                        const unsigned long *rdump,
                        unsigned long nr_rdump,
                        const struct samsung_clk_reg_dump *rsuspend,
@@ -399,13 +397,13 @@ static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base,
 #define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \
        samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0)
 
-extern void samsung_clk_save(void __iomem *base,
+void samsung_clk_save(void __iomem *base,
                        struct samsung_clk_reg_dump *rd,
                        unsigned int num_regs);
-extern void samsung_clk_restore(void __iomem *base,
+void samsung_clk_restore(void __iomem *base,
                        const struct samsung_clk_reg_dump *rd,
                        unsigned int num_regs);
-extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
+struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
                        const unsigned long *rdump,
                        unsigned long nr_rdump);
 
index bf8cd92..74d21bd 100644 (file)
@@ -500,12 +500,10 @@ static int n5x_clkmgr_init(struct platform_device *pdev)
        struct device_node *np = pdev->dev.of_node;
        struct device *dev = &pdev->dev;
        struct stratix10_clock_data *clk_data;
-       struct resource *res;
        void __iomem *base;
        int i, num_clks;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       base = devm_ioremap_resource(dev, res);
+       base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(base))
                return PTR_ERR(base);
 
index 1ec9678..53d6e3e 100644 (file)
@@ -34,7 +34,7 @@ static u8 socfpga_clk_get_parent(struct clk_hw *hwclk)
 
        if (streq(name, SOCFPGA_L4_MP_CLK)) {
                l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
-               return l4_src &= 0x1;
+               return l4_src & 0x1;
        }
        if (streq(name, SOCFPGA_L4_SP_CLK)) {
                l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
@@ -43,7 +43,7 @@ static u8 socfpga_clk_get_parent(struct clk_hw *hwclk)
 
        perpll_src = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
        if (streq(name, SOCFPGA_MMC_CLK))
-               return perpll_src &= 0x3;
+               return perpll_src & 0x3;
        if (streq(name, SOCFPGA_NAND_CLK) ||
            streq(name, SOCFPGA_NAND_X_CLK))
                return (perpll_src >> 2) & 3;
index 70076a8..e444e4a 100644 (file)
@@ -113,7 +113,7 @@ static unsigned long clk_boot_clk_recalc_rate(struct clk_hw *hwclk,
                SWCTRLBTCLKSEL_MASK) >>
                SWCTRLBTCLKSEL_SHIFT);
        div += 1;
-       return parent_rate /= div;
+       return parent_rate / div;
 }
 
 
index b532d51..4e508a8 100644 (file)
@@ -388,12 +388,10 @@ static int s10_clkmgr_init(struct platform_device *pdev)
        struct device_node *np = pdev->dev.of_node;
        struct device *dev = &pdev->dev;
        struct stratix10_clock_data *clk_data;
-       struct resource *res;
        void __iomem *base;
        int i, num_clks;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       base = devm_ioremap_resource(dev, res);
+       base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(base)) {
                pr_err("%s: failed to map clock registers\n", __func__);
                return PTR_ERR(base);
index 164285d..582a22c 100644 (file)
@@ -988,9 +988,18 @@ static void __init st_of_quadfs_setup(struct device_node *np,
        void __iomem *reg;
        spinlock_t *lock;
 
+       /*
+        * First check for reg property within the node to keep backward
+        * compatibility, then if reg doesn't exist look at the parent node
+        */
        reg = of_iomap(np, 0);
-       if (!reg)
-               return;
+       if (!reg) {
+               reg = of_iomap(of_get_parent(np), 0);
+               if (!reg) {
+                       pr_err("%s: Failed to get base address\n", __func__);
+                       return;
+               }
+       }
 
        clk_parent_name = of_clk_get_parent_name(np, 0);
        if (!clk_parent_name)
index ce583de..ee39af7 100644 (file)
@@ -57,10 +57,17 @@ static void __init st_of_clkgen_mux_setup(struct device_node *np,
        const char **parents;
        int num_parents = 0;
 
+       /*
+        * First check for reg property within the node to keep backward
+        * compatibility, then if reg doesn't exist look at the parent node
+        */
        reg = of_iomap(np, 0);
        if (!reg) {
-               pr_err("%s: Failed to get base address\n", __func__);
-               return;
+               reg = of_iomap(of_get_parent(np), 0);
+               if (!reg) {
+                       pr_err("%s: Failed to get base address\n", __func__);
+                       return;
+               }
        }
 
        parents = clkgen_mux_get_parents(np, &num_parents);
index e76e167..68a94e5 100644 (file)
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config SUNXI_CCU
-       bool "Clock support for Allwinner SoCs"
+       tristate "Clock support for Allwinner SoCs"
        depends on ARCH_SUNXI || COMPILE_TEST
        select RESET_CONTROLLER
        default ARCH_SUNXI
@@ -8,42 +8,52 @@ config SUNXI_CCU
 if SUNXI_CCU
 
 config SUNIV_F1C100S_CCU
-       bool "Support for the Allwinner newer F1C100s CCU"
+       tristate "Support for the Allwinner newer F1C100s CCU"
        default MACH_SUNIV
        depends on MACH_SUNIV || COMPILE_TEST
 
+config SUN20I_D1_CCU
+       tristate "Support for the Allwinner D1 CCU"
+       default RISCV && ARCH_SUNXI
+       depends on (RISCV && ARCH_SUNXI) || COMPILE_TEST
+
+config SUN20I_D1_R_CCU
+       tristate "Support for the Allwinner D1 PRCM CCU"
+       default RISCV && ARCH_SUNXI
+       depends on (RISCV && ARCH_SUNXI) || COMPILE_TEST
+
 config SUN50I_A64_CCU
-       bool "Support for the Allwinner A64 CCU"
+       tristate "Support for the Allwinner A64 CCU"
        default ARM64 && ARCH_SUNXI
        depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
 config SUN50I_A100_CCU
-       bool "Support for the Allwinner A100 CCU"
+       tristate "Support for the Allwinner A100 CCU"
        default ARM64 && ARCH_SUNXI
        depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
 config SUN50I_A100_R_CCU
-       bool "Support for the Allwinner A100 PRCM CCU"
+       tristate "Support for the Allwinner A100 PRCM CCU"
        default ARM64 && ARCH_SUNXI
        depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
 config SUN50I_H6_CCU
-       bool "Support for the Allwinner H6 CCU"
+       tristate "Support for the Allwinner H6 CCU"
        default ARM64 && ARCH_SUNXI
        depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
 config SUN50I_H616_CCU
-       bool "Support for the Allwinner H616 CCU"
+       tristate "Support for the Allwinner H616 CCU"
        default ARM64 && ARCH_SUNXI
        depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
 config SUN50I_H6_R_CCU
-       bool "Support for the Allwinner H6 and H616 PRCM CCU"
+       tristate "Support for the Allwinner H6 and H616 PRCM CCU"
        default ARM64 && ARCH_SUNXI
        depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
 config SUN4I_A10_CCU
-       bool "Support for the Allwinner A10/A20 CCU"
+       tristate "Support for the Allwinner A10/A20 CCU"
        default MACH_SUN4I
        default MACH_SUN7I
        depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST
@@ -52,53 +62,54 @@ config SUN5I_CCU
        bool "Support for the Allwinner sun5i family CCM"
        default MACH_SUN5I
        depends on MACH_SUN5I || COMPILE_TEST
+       depends on SUNXI_CCU=y
 
 config SUN6I_A31_CCU
-       bool "Support for the Allwinner A31/A31s CCU"
+       tristate "Support for the Allwinner A31/A31s CCU"
        default MACH_SUN6I
        depends on MACH_SUN6I || COMPILE_TEST
 
 config SUN8I_A23_CCU
-       bool "Support for the Allwinner A23 CCU"
+       tristate "Support for the Allwinner A23 CCU"
        default MACH_SUN8I
        depends on MACH_SUN8I || COMPILE_TEST
 
 config SUN8I_A33_CCU
-       bool "Support for the Allwinner A33 CCU"
+       tristate "Support for the Allwinner A33 CCU"
        default MACH_SUN8I
        depends on MACH_SUN8I || COMPILE_TEST
 
 config SUN8I_A83T_CCU
-       bool "Support for the Allwinner A83T CCU"
+       tristate "Support for the Allwinner A83T CCU"
        default MACH_SUN8I
        depends on MACH_SUN8I || COMPILE_TEST
 
 config SUN8I_H3_CCU
-       bool "Support for the Allwinner H3 CCU"
+       tristate "Support for the Allwinner H3 CCU"
        default MACH_SUN8I || (ARM64 && ARCH_SUNXI)
        depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
 config SUN8I_V3S_CCU
-       bool "Support for the Allwinner V3s CCU"
+       tristate "Support for the Allwinner V3s CCU"
        default MACH_SUN8I
        depends on MACH_SUN8I || COMPILE_TEST
 
 config SUN8I_DE2_CCU
-       bool "Support for the Allwinner SoCs DE2 CCU"
+       tristate "Support for the Allwinner SoCs DE2 CCU"
        default MACH_SUN8I || (ARM64 && ARCH_SUNXI)
 
 config SUN8I_R40_CCU
-       bool "Support for the Allwinner R40 CCU"
+       tristate "Support for the Allwinner R40 CCU"
        default MACH_SUN8I
        depends on MACH_SUN8I || COMPILE_TEST
 
 config SUN9I_A80_CCU
-       bool "Support for the Allwinner A80 CCU"
+       tristate "Support for the Allwinner A80 CCU"
        default MACH_SUN9I
        depends on MACH_SUN9I || COMPILE_TEST
 
 config SUN8I_R_CCU
-       bool "Support for Allwinner SoCs' PRCM CCUs"
+       tristate "Support for Allwinner SoCs' PRCM CCUs"
        default MACH_SUN8I || (ARCH_SUNXI && ARM64)
 
 endif
index 96c3243..ec931cb 100644 (file)
@@ -1,44 +1,73 @@
 # SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_SUNXI_CCU)                += sunxi-ccu.o
+
 # Common objects
-obj-y                          += ccu_common.o
-obj-y                          += ccu_mmc_timing.o
-obj-y                          += ccu_reset.o
+sunxi-ccu-y                    += ccu_common.o
+sunxi-ccu-y                    += ccu_mmc_timing.o
+sunxi-ccu-y                    += ccu_reset.o
 
 # Base clock types
-obj-y                          += ccu_div.o
-obj-y                          += ccu_frac.o
-obj-y                          += ccu_gate.o
-obj-y                          += ccu_mux.o
-obj-y                          += ccu_mult.o
-obj-y                          += ccu_phase.o
-obj-y                          += ccu_sdm.o
+sunxi-ccu-y                    += ccu_div.o
+sunxi-ccu-y                    += ccu_frac.o
+sunxi-ccu-y                    += ccu_gate.o
+sunxi-ccu-y                    += ccu_mux.o
+sunxi-ccu-y                    += ccu_mult.o
+sunxi-ccu-y                    += ccu_phase.o
+sunxi-ccu-y                    += ccu_sdm.o
 
 # Multi-factor clocks
-obj-y                          += ccu_nk.o
-obj-y                          += ccu_nkm.o
-obj-y                          += ccu_nkmp.o
-obj-y                          += ccu_nm.o
-obj-y                          += ccu_mp.o
+sunxi-ccu-y                    += ccu_nk.o
+sunxi-ccu-y                    += ccu_nkm.o
+sunxi-ccu-y                    += ccu_nkmp.o
+sunxi-ccu-y                    += ccu_nm.o
+sunxi-ccu-y                    += ccu_mp.o
 
 # SoC support
-obj-$(CONFIG_SUNIV_F1C100S_CCU)        += ccu-suniv-f1c100s.o
-obj-$(CONFIG_SUN50I_A64_CCU)   += ccu-sun50i-a64.o
-obj-$(CONFIG_SUN50I_A100_CCU)  += ccu-sun50i-a100.o
-obj-$(CONFIG_SUN50I_A100_R_CCU)        += ccu-sun50i-a100-r.o
-obj-$(CONFIG_SUN50I_H6_CCU)    += ccu-sun50i-h6.o
-obj-$(CONFIG_SUN50I_H616_CCU)  += ccu-sun50i-h616.o
-obj-$(CONFIG_SUN50I_H6_R_CCU)  += ccu-sun50i-h6-r.o
-obj-$(CONFIG_SUN4I_A10_CCU)    += ccu-sun4i-a10.o
-obj-$(CONFIG_SUN5I_CCU)                += ccu-sun5i.o
-obj-$(CONFIG_SUN6I_A31_CCU)    += ccu-sun6i-a31.o
-obj-$(CONFIG_SUN8I_A23_CCU)    += ccu-sun8i-a23.o
-obj-$(CONFIG_SUN8I_A33_CCU)    += ccu-sun8i-a33.o
-obj-$(CONFIG_SUN8I_A83T_CCU)   += ccu-sun8i-a83t.o
-obj-$(CONFIG_SUN8I_H3_CCU)     += ccu-sun8i-h3.o
-obj-$(CONFIG_SUN8I_V3S_CCU)    += ccu-sun8i-v3s.o
-obj-$(CONFIG_SUN8I_DE2_CCU)    += ccu-sun8i-de2.o
-obj-$(CONFIG_SUN8I_R_CCU)      += ccu-sun8i-r.o
-obj-$(CONFIG_SUN8I_R40_CCU)    += ccu-sun8i-r40.o
-obj-$(CONFIG_SUN9I_A80_CCU)    += ccu-sun9i-a80.o
-obj-$(CONFIG_SUN9I_A80_CCU)    += ccu-sun9i-a80-de.o
-obj-$(CONFIG_SUN9I_A80_CCU)    += ccu-sun9i-a80-usb.o
+obj-$(CONFIG_SUNIV_F1C100S_CCU)        += suniv-f1c100s-ccu.o
+obj-$(CONFIG_SUN20I_D1_CCU)    += sun20i-d1-ccu.o
+obj-$(CONFIG_SUN20I_D1_R_CCU)  += sun20i-d1-r-ccu.o
+obj-$(CONFIG_SUN50I_A64_CCU)   += sun50i-a64-ccu.o
+obj-$(CONFIG_SUN50I_A100_CCU)  += sun50i-a100-ccu.o
+obj-$(CONFIG_SUN50I_A100_R_CCU)        += sun50i-a100-r-ccu.o
+obj-$(CONFIG_SUN50I_H6_CCU)    += sun50i-h6-ccu.o
+obj-$(CONFIG_SUN50I_H6_R_CCU)  += sun50i-h6-r-ccu.o
+obj-$(CONFIG_SUN50I_H616_CCU)  += sun50i-h616-ccu.o
+obj-$(CONFIG_SUN4I_A10_CCU)    += sun4i-a10-ccu.o
+obj-$(CONFIG_SUN5I_CCU)                += sun5i-ccu.o
+obj-$(CONFIG_SUN6I_A31_CCU)    += sun6i-a31-ccu.o
+obj-$(CONFIG_SUN8I_A23_CCU)    += sun8i-a23-ccu.o
+obj-$(CONFIG_SUN8I_A33_CCU)    += sun8i-a33-ccu.o
+obj-$(CONFIG_SUN8I_A83T_CCU)   += sun8i-a83t-ccu.o
+obj-$(CONFIG_SUN8I_H3_CCU)     += sun8i-h3-ccu.o
+obj-$(CONFIG_SUN8I_R40_CCU)    += sun8i-r40-ccu.o
+obj-$(CONFIG_SUN8I_V3S_CCU)    += sun8i-v3s-ccu.o
+obj-$(CONFIG_SUN8I_DE2_CCU)    += sun8i-de2-ccu.o
+obj-$(CONFIG_SUN8I_R_CCU)      += sun8i-r-ccu.o
+obj-$(CONFIG_SUN9I_A80_CCU)    += sun9i-a80-ccu.o
+obj-$(CONFIG_SUN9I_A80_CCU)    += sun9i-a80-de-ccu.o
+obj-$(CONFIG_SUN9I_A80_CCU)    += sun9i-a80-usb-ccu.o
+
+suniv-f1c100s-ccu-y            += ccu-suniv-f1c100s.o
+sun20i-d1-ccu-y                        += ccu-sun20i-d1.o
+sun20i-d1-r-ccu-y              += ccu-sun20i-d1-r.o
+sun50i-a64-ccu-y               += ccu-sun50i-a64.o
+sun50i-a100-ccu-y              += ccu-sun50i-a100.o
+sun50i-a100-r-ccu-y            += ccu-sun50i-a100-r.o
+sun50i-h6-ccu-y                        += ccu-sun50i-h6.o
+sun50i-h6-r-ccu-y              += ccu-sun50i-h6-r.o
+sun50i-h616-ccu-y              += ccu-sun50i-h616.o
+sun4i-a10-ccu-y                        += ccu-sun4i-a10.o
+sun5i-ccu-y                    += ccu-sun5i.o
+sun6i-a31-ccu-y                        += ccu-sun6i-a31.o
+sun8i-a23-ccu-y                        += ccu-sun8i-a23.o
+sun8i-a33-ccu-y                        += ccu-sun8i-a33.o
+sun8i-a83t-ccu-y               += ccu-sun8i-a83t.o
+sun8i-h3-ccu-y                 += ccu-sun8i-h3.o
+sun8i-r40-ccu-y                        += ccu-sun8i-r40.o
+sun8i-v3s-ccu-y                        += ccu-sun8i-v3s.o
+sun8i-de2-ccu-y                        += ccu-sun8i-de2.o
+sun8i-r-ccu-y                  += ccu-sun8i-r.o
+sun9i-a80-ccu-y                        += ccu-sun9i-a80.o
+sun9i-a80-de-ccu-y             += ccu-sun9i-a80-de.o
+sun9i-a80-usb-ccu-y            += ccu-sun9i-a80-usb.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun20i-d1-r.c b/drivers/clk/sunxi-ng/ccu-sun20i-d1-r.c
new file mode 100644 (file)
index 0000000..9d3ffd3
--- /dev/null
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 huangzhenwei@allwinnertech.com
+ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+
+#include "ccu-sun20i-d1-r.h"
+
+static const struct clk_parent_data r_ahb_apb0_parents[] = {
+       { .fw_name = "hosc" },
+       { .fw_name = "losc" },
+       { .fw_name = "iosc" },
+       { .fw_name = "pll-periph" },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX(r_ahb_clk, "r-ahb",
+                                 r_ahb_apb0_parents, 0x000,
+                                 0, 5,         /* M */
+                                 8, 2,         /* P */
+                                 24, 3,        /* mux */
+                                 0);
+static const struct clk_hw *r_ahb_hw = &r_ahb_clk.common.hw;
+
+static SUNXI_CCU_MP_DATA_WITH_MUX(r_apb0_clk, "r-apb0",
+                                 r_ahb_apb0_parents, 0x00c,
+                                 0, 5,         /* M */
+                                 8, 2,         /* P */
+                                 24, 3,        /* mux */
+                                 0);
+static const struct clk_hw *r_apb0_hw = &r_apb0_clk.common.hw;
+
+static SUNXI_CCU_GATE_HWS(bus_r_timer_clk,     "bus-r-timer",  &r_apb0_hw,
+                         0x11c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_r_twd_clk,       "bus-r-twd",    &r_apb0_hw,
+                         0x12c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_r_ppu_clk,       "bus-r-ppu",    &r_apb0_hw,
+                         0x1ac, BIT(0), 0);
+
+static const struct clk_parent_data r_ir_rx_parents[] = {
+       { .fw_name = "losc" },
+       { .fw_name = "hosc" },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(r_ir_rx_clk, "r-ir-rx",
+                                      r_ir_rx_parents, 0x1c0,
+                                      0, 5,    /* M */
+                                      8, 2,    /* P */
+                                      24, 2,   /* mux */
+                                      BIT(31), /* gate */
+                                      0);
+
+static SUNXI_CCU_GATE_HWS(bus_r_ir_rx_clk,     "bus-r-ir-rx",  &r_apb0_hw,
+                         0x1cc, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_r_rtc_clk,       "bus-r-rtc",    &r_ahb_hw,
+                         0x20c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_r_cpucfg_clk,    "bus-r-cpucfg", &r_apb0_hw,
+                         0x22c, BIT(0), 0);
+
+static struct ccu_common *sun20i_d1_r_ccu_clks[] = {
+       &r_ahb_clk.common,
+       &r_apb0_clk.common,
+       &bus_r_timer_clk.common,
+       &bus_r_twd_clk.common,
+       &bus_r_ppu_clk.common,
+       &r_ir_rx_clk.common,
+       &bus_r_ir_rx_clk.common,
+       &bus_r_rtc_clk.common,
+       &bus_r_cpucfg_clk.common,
+};
+
+static struct clk_hw_onecell_data sun20i_d1_r_hw_clks = {
+       .num    = CLK_NUMBER,
+       .hws    = {
+               [CLK_R_AHB]             = &r_ahb_clk.common.hw,
+               [CLK_R_APB0]            = &r_apb0_clk.common.hw,
+               [CLK_BUS_R_TIMER]       = &bus_r_timer_clk.common.hw,
+               [CLK_BUS_R_TWD]         = &bus_r_twd_clk.common.hw,
+               [CLK_BUS_R_PPU]         = &bus_r_ppu_clk.common.hw,
+               [CLK_R_IR_RX]           = &r_ir_rx_clk.common.hw,
+               [CLK_BUS_R_IR_RX]       = &bus_r_ir_rx_clk.common.hw,
+               [CLK_BUS_R_RTC]         = &bus_r_rtc_clk.common.hw,
+               [CLK_BUS_R_CPUCFG]      = &bus_r_cpucfg_clk.common.hw,
+       },
+};
+
+static struct ccu_reset_map sun20i_d1_r_ccu_resets[] = {
+       [RST_BUS_R_TIMER]       = { 0x11c, BIT(16) },
+       [RST_BUS_R_TWD]         = { 0x12c, BIT(16) },
+       [RST_BUS_R_PPU]         = { 0x1ac, BIT(16) },
+       [RST_BUS_R_IR_RX]       = { 0x1cc, BIT(16) },
+       [RST_BUS_R_RTC]         = { 0x20c, BIT(16) },
+       [RST_BUS_R_CPUCFG]      = { 0x22c, BIT(16) },
+};
+
+static const struct sunxi_ccu_desc sun20i_d1_r_ccu_desc = {
+       .ccu_clks       = sun20i_d1_r_ccu_clks,
+       .num_ccu_clks   = ARRAY_SIZE(sun20i_d1_r_ccu_clks),
+
+       .hw_clks        = &sun20i_d1_r_hw_clks,
+
+       .resets         = sun20i_d1_r_ccu_resets,
+       .num_resets     = ARRAY_SIZE(sun20i_d1_r_ccu_resets),
+};
+
+static int sun20i_d1_r_ccu_probe(struct platform_device *pdev)
+{
+       void __iomem *reg;
+
+       reg = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
+
+       return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun20i_d1_r_ccu_desc);
+}
+
+static const struct of_device_id sun20i_d1_r_ccu_ids[] = {
+       { .compatible = "allwinner,sun20i-d1-r-ccu" },
+       { }
+};
+
+static struct platform_driver sun20i_d1_r_ccu_driver = {
+       .probe  = sun20i_d1_r_ccu_probe,
+       .driver = {
+               .name                   = "sun20i-d1-r-ccu",
+               .suppress_bind_attrs    = true,
+               .of_match_table         = sun20i_d1_r_ccu_ids,
+       },
+};
+module_platform_driver(sun20i_d1_r_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/ccu-sun20i-d1-r.h b/drivers/clk/sunxi-ng/ccu-sun20i-d1-r.h
new file mode 100644 (file)
index 0000000..afd4342
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 frank@allwinnertech.com
+ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
+ */
+
+#ifndef _CCU_SUN20I_D1_R_H
+#define _CCU_SUN20I_D1_R_H
+
+#include <dt-bindings/clock/sun20i-d1-r-ccu.h>
+#include <dt-bindings/reset/sun20i-d1-r-ccu.h>
+
+#define CLK_R_APB0             1
+
+#define CLK_NUMBER             (CLK_BUS_R_CPUCFG + 1)
+
+#endif /* _CCU_SUN20I_D1_R_H */
diff --git a/drivers/clk/sunxi-ng/ccu-sun20i-d1.c b/drivers/clk/sunxi-ng/ccu-sun20i-d1.c
new file mode 100644 (file)
index 0000000..51058ba
--- /dev/null
@@ -0,0 +1,1390 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 huangzhenwei@allwinnertech.com
+ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "../clk.h"
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mult.h"
+#include "ccu_nk.h"
+#include "ccu_nkm.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+
+#include "ccu-sun20i-d1.h"
+
+static const struct clk_parent_data osc24M[] = {
+       { .fw_name = "hosc" }
+};
+
+/*
+ * For the CPU PLL, the output divider is described as "only for testing"
+ * in the user manual. So it's not modelled and forced to 0.
+ */
+#define SUN20I_D1_PLL_CPUX_REG         0x000
+static struct ccu_mult pll_cpux_clk = {
+       .enable         = BIT(27),
+       .lock           = BIT(28),
+       .mult           = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .common         = {
+               .reg            = 0x000,
+               .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-cpux", osc24M,
+                                                          &ccu_mult_ops,
+                                                          CLK_SET_RATE_UNGATE),
+       },
+};
+
+/* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */
+#define SUN20I_D1_PLL_DDR0_REG         0x010
+static struct ccu_nkmp pll_ddr0_clk = {
+       .enable         = BIT(27),
+       .lock           = BIT(28),
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
+       .p              = _SUNXI_CCU_DIV(0, 1), /* output divider */
+       .common         = {
+               .reg            = 0x010,
+               .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-ddr0", osc24M,
+                                                          &ccu_nkmp_ops,
+                                                          CLK_SET_RATE_UNGATE),
+       },
+};
+
+#define SUN20I_D1_PLL_PERIPH0_REG      0x020
+static struct ccu_nm pll_periph0_4x_clk = {
+       .enable         = BIT(27),
+       .lock           = BIT(28),
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
+       .common         = {
+               .reg            = 0x020,
+               .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-periph0-4x", osc24M,
+                                                          &ccu_nm_ops,
+                                                          CLK_SET_RATE_UNGATE),
+       },
+};
+
+static const struct clk_hw *pll_periph0_4x_hws[] = {
+       &pll_periph0_4x_clk.common.hw
+};
+static SUNXI_CCU_M_HWS(pll_periph0_2x_clk, "pll-periph0-2x",
+                      pll_periph0_4x_hws, 0x020, 16, 3, 0);
+static SUNXI_CCU_M_HWS(pll_periph0_800M_clk, "pll-periph0-800M",
+                      pll_periph0_4x_hws, 0x020, 20, 3, 0);
+
+static const struct clk_hw *pll_periph0_2x_hws[] = {
+       &pll_periph0_2x_clk.common.hw
+};
+static CLK_FIXED_FACTOR_HWS(pll_periph0_clk, "pll-periph0",
+                           pll_periph0_2x_hws, 2, 1, 0);
+
+static const struct clk_hw *pll_periph0_hws[] = { &pll_periph0_clk.hw };
+static CLK_FIXED_FACTOR_HWS(pll_periph0_div3_clk, "pll-periph0-div3",
+                           pll_periph0_2x_hws, 6, 1, 0);
+
+/*
+ * For Video PLLs, the output divider is described as "only for testing"
+ * in the user manual. So it's not modelled and forced to 0.
+ */
+#define SUN20I_D1_PLL_VIDEO0_REG       0x040
+static struct ccu_nm pll_video0_4x_clk = {
+       .enable         = BIT(27),
+       .lock           = BIT(28),
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
+       .common         = {
+               .reg            = 0x040,
+               .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-video0-4x", osc24M,
+                                                          &ccu_nm_ops,
+                                                          CLK_SET_RATE_UNGATE),
+       },
+};
+
+static const struct clk_hw *pll_video0_4x_hws[] = {
+       &pll_video0_4x_clk.common.hw
+};
+static CLK_FIXED_FACTOR_HWS(pll_video0_2x_clk, "pll-video0-2x",
+                           pll_video0_4x_hws, 2, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HWS(pll_video0_clk, "pll-video0",
+                           pll_video0_4x_hws, 4, 1, CLK_SET_RATE_PARENT);
+
+#define SUN20I_D1_PLL_VIDEO1_REG       0x048
+static struct ccu_nm pll_video1_4x_clk = {
+       .enable         = BIT(27),
+       .lock           = BIT(28),
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
+       .common         = {
+               .reg            = 0x048,
+               .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-video1-4x", osc24M,
+                                                          &ccu_nm_ops,
+                                                          CLK_SET_RATE_UNGATE),
+       },
+};
+
+static const struct clk_hw *pll_video1_4x_hws[] = {
+       &pll_video1_4x_clk.common.hw
+};
+static CLK_FIXED_FACTOR_HWS(pll_video1_2x_clk, "pll-video1-2x",
+                           pll_video1_4x_hws, 2, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HWS(pll_video1_clk, "pll-video1",
+                           pll_video1_4x_hws, 4, 1, CLK_SET_RATE_PARENT);
+
+#define SUN20I_D1_PLL_VE_REG           0x058
+static struct ccu_nkmp pll_ve_clk = {
+       .enable         = BIT(27),
+       .lock           = BIT(28),
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
+       .p              = _SUNXI_CCU_DIV(0, 1), /* output divider */
+       .common         = {
+               .reg            = 0x058,
+               .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-ve", osc24M,
+                                                          &ccu_nkmp_ops,
+                                                          CLK_SET_RATE_UNGATE),
+       },
+};
+
+/*
+ * PLL_AUDIO0 has m0, m1 dividers in addition to the usual N, M factors.
+ * Since we only need one frequency from this PLL (22.5792 x 4 == 90.3168 MHz),
+ * ignore them for now. Enforce the default for them, which is m1 = 0, m0 = 0.
+ * The M factor must be an even number to produce a 50% duty cycle output.
+ */
+#define SUN20I_D1_PLL_AUDIO0_REG               0x078
+static struct ccu_sdm_setting pll_audio0_sdm_table[] = {
+       { .rate = 90316800, .pattern = 0xc001288d, .m = 6, .n = 22 },
+};
+
+static struct ccu_nm pll_audio0_4x_clk = {
+       .enable         = BIT(27),
+       .lock           = BIT(28),
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(16, 6),
+       .sdm            = _SUNXI_CCU_SDM(pll_audio0_sdm_table, BIT(24),
+                                        0x178, BIT(31)),
+       .common         = {
+               .reg            = 0x078,
+               .features       = CCU_FEATURE_SIGMA_DELTA_MOD,
+               .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-audio0-4x", osc24M,
+                                                          &ccu_nm_ops,
+                                                          CLK_SET_RATE_UNGATE),
+       },
+};
+
+static const struct clk_hw *pll_audio0_4x_hws[] = {
+       &pll_audio0_4x_clk.common.hw
+};
+static CLK_FIXED_FACTOR_HWS(pll_audio0_2x_clk, "pll-audio0-2x",
+                           pll_audio0_4x_hws, 2, 1, 0);
+static CLK_FIXED_FACTOR_HWS(pll_audio0_clk, "pll-audio0",
+                           pll_audio0_4x_hws, 4, 1, 0);
+
+/*
+ * PLL_AUDIO1 doesn't need Fractional-N. The output is usually 614.4 MHz for
+ * audio. The ADC or DAC should divide the PLL output further to 24.576 MHz.
+ */
+#define SUN20I_D1_PLL_AUDIO1_REG               0x080
+static struct ccu_nm pll_audio1_clk = {
+       .enable         = BIT(27),
+       .lock           = BIT(28),
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(1, 1),
+       .common         = {
+               .reg            = 0x080,
+               .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-audio1", osc24M,
+                                                          &ccu_nm_ops,
+                                                          CLK_SET_RATE_UNGATE),
+       },
+};
+
+static const struct clk_hw *pll_audio1_hws[] = {
+       &pll_audio1_clk.common.hw
+};
+static SUNXI_CCU_M_HWS(pll_audio1_div2_clk, "pll-audio1-div2",
+                      pll_audio1_hws, 0x080, 16, 3, 0);
+static SUNXI_CCU_M_HWS(pll_audio1_div5_clk, "pll-audio1-div5",
+                      pll_audio1_hws, 0x080, 20, 3, 0);
+
+/*
+ * The CPUX gate is not modelled - it is in a separate register (0x504)
+ * and has a special key field. The clock does not need to be ungated anyway.
+ */
+static const struct clk_parent_data cpux_parents[] = {
+       { .fw_name = "hosc" },
+       { .fw_name = "losc" },
+       { .fw_name = "iosc" },
+       { .hw = &pll_cpux_clk.common.hw },
+       { .hw = &pll_periph0_clk.hw },
+       { .hw = &pll_periph0_2x_clk.common.hw },
+       { .hw = &pll_periph0_800M_clk.common.hw },
+};
+static SUNXI_CCU_MUX_DATA(cpux_clk, "cpux", cpux_parents,
+                         0x500, 24, 3, CLK_SET_RATE_PARENT);
+
+static const struct clk_hw *cpux_hws[] = { &cpux_clk.common.hw };
+static SUNXI_CCU_M_HWS(cpux_axi_clk, "cpux-axi",
+                      cpux_hws, 0x500, 0, 2, 0);
+static SUNXI_CCU_M_HWS(cpux_apb_clk, "cpux-apb",
+                      cpux_hws, 0x500, 8, 2, 0);
+
+static const struct clk_parent_data psi_ahb_parents[] = {
+       { .fw_name = "hosc" },
+       { .fw_name = "losc" },
+       { .fw_name = "iosc" },
+       { .hw = &pll_periph0_clk.hw },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX(psi_ahb_clk, "psi-ahb", psi_ahb_parents, 0x510,
+                                 0, 2,         /* M */
+                                 8, 2,         /* P */
+                                 24, 2,        /* mux */
+                                 0);
+
+static const struct clk_parent_data apb0_apb1_parents[] = {
+       { .fw_name = "hosc" },
+       { .fw_name = "losc" },
+       { .hw = &psi_ahb_clk.common.hw },
+       { .hw = &pll_periph0_clk.hw },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX(apb0_clk, "apb0", apb0_apb1_parents, 0x520,
+                                 0, 5,         /* M */
+                                 8, 2,         /* P */
+                                 24, 2,        /* mux */
+                                 0);
+
+static SUNXI_CCU_MP_DATA_WITH_MUX(apb1_clk, "apb1", apb0_apb1_parents, 0x524,
+                                 0, 5,         /* M */
+                                 8, 2,         /* P */
+                                 24, 2,        /* mux */
+                                 0);
+
+static const struct clk_hw *psi_ahb_hws[] = { &psi_ahb_clk.common.hw };
+static const struct clk_hw *apb0_hws[] = { &apb0_clk.common.hw };
+static const struct clk_hw *apb1_hws[] = { &apb1_clk.common.hw };
+
+static const struct clk_hw *de_di_g2d_parents[] = {
+       &pll_periph0_2x_clk.common.hw,
+       &pll_video0_4x_clk.common.hw,
+       &pll_video1_4x_clk.common.hw,
+       &pll_audio1_div2_clk.common.hw,
+};
+static SUNXI_CCU_M_HW_WITH_MUX_GATE(de_clk, "de", de_di_g2d_parents, 0x600,
+                                   0, 5,       /* M */
+                                   24, 3,      /* mux */
+                                   BIT(31),    /* gate */
+                                   CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_GATE_HWS(bus_de_clk, "bus-de", psi_ahb_hws,
+                         0x60c, BIT(0), 0);
+
+static SUNXI_CCU_M_HW_WITH_MUX_GATE(di_clk, "di", de_di_g2d_parents, 0x620,
+                                   0, 5,       /* M */
+                                   24, 3,      /* mux */
+                                   BIT(31),    /* gate */
+                                   CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_GATE_HWS(bus_di_clk, "bus-di", psi_ahb_hws,
+                         0x62c, BIT(0), 0);
+
+static SUNXI_CCU_M_HW_WITH_MUX_GATE(g2d_clk, "g2d", de_di_g2d_parents, 0x630,
+                                   0, 5,       /* M */
+                                   24, 3,      /* mux */
+                                   BIT(31),    /* gate */
+                                   0);
+
+static SUNXI_CCU_GATE_HWS(bus_g2d_clk, "bus-g2d", psi_ahb_hws,
+                         0x63c, BIT(0), 0);
+
+static const struct clk_parent_data ce_parents[] = {
+       { .fw_name = "hosc" },
+       { .hw = &pll_periph0_2x_clk.common.hw },
+       { .hw = &pll_periph0_clk.hw },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680,
+                                      0, 4,    /* M */
+                                      8, 2,    /* P */
+                                      24, 3,   /* mux */
+                                      BIT(31), /* gate */
+                                      0);
+
+static SUNXI_CCU_GATE_HWS(bus_ce_clk, "bus-ce", psi_ahb_hws,
+                         0x68c, BIT(0), 0);
+
+static const struct clk_hw *ve_parents[] = {
+       &pll_ve_clk.common.hw,
+       &pll_periph0_2x_clk.common.hw,
+};
+static SUNXI_CCU_M_HW_WITH_MUX_GATE(ve_clk, "ve", ve_parents, 0x690,
+                                   0, 5,       /* M */
+                                   24, 1,      /* mux */
+                                   BIT(31),    /* gate */
+                                   CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_GATE_HWS(bus_ve_clk, "bus-ve", psi_ahb_hws,
+                         0x69c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_dma_clk, "bus-dma", psi_ahb_hws,
+                         0x70c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_msgbox0_clk, "bus-msgbox0", psi_ahb_hws,
+                         0x71c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_msgbox1_clk, "bus-msgbox1", psi_ahb_hws,
+                         0x71c, BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(bus_msgbox2_clk, "bus-msgbox2", psi_ahb_hws,
+                         0x71c, BIT(2), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_spinlock_clk, "bus-spinlock", psi_ahb_hws,
+                         0x72c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_hstimer_clk, "bus-hstimer", psi_ahb_hws,
+                         0x73c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_DATA(avs_clk, "avs", osc24M,
+                          0x740, BIT(31), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_dbg_clk, "bus-dbg", psi_ahb_hws,
+                         0x78c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_pwm_clk, "bus-pwm", apb0_hws,
+                         0x7ac, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_iommu_clk, "bus-iommu", apb0_hws,
+                         0x7bc, BIT(0), 0);
+
+static const struct clk_hw *dram_parents[] = {
+       &pll_ddr0_clk.common.hw,
+       &pll_audio1_div2_clk.common.hw,
+       &pll_periph0_2x_clk.common.hw,
+       &pll_periph0_800M_clk.common.hw,
+};
+static SUNXI_CCU_MP_HW_WITH_MUX_GATE(dram_clk, "dram", dram_parents, 0x800,
+                                    0, 2,      /* M */
+                                    8, 2,      /* P */
+                                    24, 2,     /* mux */
+                                    BIT(31), CLK_IS_CRITICAL);
+
+static CLK_FIXED_FACTOR_HW(mbus_clk, "mbus",
+                          &dram_clk.common.hw, 4, 1, 0);
+
+static const struct clk_hw *mbus_hws[] = { &mbus_clk.hw };
+
+static SUNXI_CCU_GATE_HWS(mbus_dma_clk, "mbus-dma", mbus_hws,
+                         0x804, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(mbus_ve_clk, "mbus-ve", mbus_hws,
+                         0x804, BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(mbus_ce_clk, "mbus-ce", mbus_hws,
+                         0x804, BIT(2), 0);
+static SUNXI_CCU_GATE_HWS(mbus_tvin_clk, "mbus-tvin", mbus_hws,
+                         0x804, BIT(7), 0);
+static SUNXI_CCU_GATE_HWS(mbus_csi_clk, "mbus-csi", mbus_hws,
+                         0x804, BIT(8), 0);
+static SUNXI_CCU_GATE_HWS(mbus_g2d_clk, "mbus-g2d", mbus_hws,
+                         0x804, BIT(10), 0);
+static SUNXI_CCU_GATE_HWS(mbus_riscv_clk, "mbus-riscv", mbus_hws,
+                         0x804, BIT(11), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_dram_clk, "bus-dram", psi_ahb_hws,
+                         0x80c, BIT(0), CLK_IS_CRITICAL);
+
+static const struct clk_parent_data mmc0_mmc1_parents[] = {
+       { .fw_name = "hosc" },
+       { .hw = &pll_periph0_clk.hw },
+       { .hw = &pll_periph0_2x_clk.common.hw },
+       { .hw = &pll_audio1_div2_clk.common.hw },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(mmc0_clk, "mmc0", mmc0_mmc1_parents, 0x830,
+                                      0, 4,    /* M */
+                                      8, 2,    /* P */
+                                      24, 3,   /* mux */
+                                      BIT(31), /* gate */
+                                      0);
+
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(mmc1_clk, "mmc1", mmc0_mmc1_parents, 0x834,
+                                      0, 4,    /* M */
+                                      8, 2,    /* P */
+                                      24, 3,   /* mux */
+                                      BIT(31), /* gate */
+                                      0);
+
+static const struct clk_parent_data mmc2_parents[] = {
+       { .fw_name = "hosc" },
+       { .hw = &pll_periph0_clk.hw },
+       { .hw = &pll_periph0_2x_clk.common.hw },
+       { .hw = &pll_periph0_800M_clk.common.hw },
+       { .hw = &pll_audio1_div2_clk.common.hw },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(mmc2_clk, "mmc2", mmc2_parents, 0x838,
+                                      0, 4,    /* M */
+                                      8, 2,    /* P */
+                                      24, 3,   /* mux */
+                                      BIT(31), /* gate */
+                                      0);
+
+static SUNXI_CCU_GATE_HWS(bus_mmc0_clk, "bus-mmc0", psi_ahb_hws,
+                         0x84c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_mmc1_clk, "bus-mmc1", psi_ahb_hws,
+                         0x84c, BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(bus_mmc2_clk, "bus-mmc2", psi_ahb_hws,
+                         0x84c, BIT(2), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_uart0_clk, "bus-uart0", apb1_hws,
+                         0x90c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_uart1_clk, "bus-uart1", apb1_hws,
+                         0x90c, BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(bus_uart2_clk, "bus-uart2", apb1_hws,
+                         0x90c, BIT(2), 0);
+static SUNXI_CCU_GATE_HWS(bus_uart3_clk, "bus-uart3", apb1_hws,
+                         0x90c, BIT(3), 0);
+static SUNXI_CCU_GATE_HWS(bus_uart4_clk, "bus-uart4", apb1_hws,
+                         0x90c, BIT(4), 0);
+static SUNXI_CCU_GATE_HWS(bus_uart5_clk, "bus-uart5", apb1_hws,
+                         0x90c, BIT(5), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_i2c0_clk, "bus-i2c0", apb1_hws,
+                         0x91c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c1_clk, "bus-i2c1", apb1_hws,
+                         0x91c, BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c2_clk, "bus-i2c2", apb1_hws,
+                         0x91c, BIT(2), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c3_clk, "bus-i2c3", apb1_hws,
+                         0x91c, BIT(3), 0);
+
+static const struct clk_parent_data spi_parents[] = {
+       { .fw_name = "hosc" },
+       { .hw = &pll_periph0_clk.hw },
+       { .hw = &pll_periph0_2x_clk.common.hw },
+       { .hw = &pll_audio1_div2_clk.common.hw },
+       { .hw = &pll_audio1_div5_clk.common.hw },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(spi0_clk, "spi0", spi_parents, 0x940,
+                                      0, 4,    /* M */
+                                      8, 2,    /* P */
+                                      24, 3,   /* mux */
+                                      BIT(31), /* gate */
+                                      0);
+
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(spi1_clk, "spi1", spi_parents, 0x944,
+                                      0, 4,    /* M */
+                                      8, 2,    /* P */
+                                      24, 3,   /* mux */
+                                      BIT(31), /* gate */
+                                      0);
+
+static SUNXI_CCU_GATE_HWS(bus_spi0_clk, "bus-spi0", psi_ahb_hws,
+                         0x96c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_spi1_clk, "bus-spi1", psi_ahb_hws,
+                         0x96c, BIT(1), 0);
+
+static SUNXI_CCU_GATE_HWS_WITH_PREDIV(emac_25M_clk, "emac-25M", pll_periph0_hws,
+                                     0x970, BIT(31) | BIT(30), 24, 0);
+
+static SUNXI_CCU_GATE_HWS(bus_emac_clk, "bus-emac", psi_ahb_hws,
+                         0x97c, BIT(0), 0);
+
+static const struct clk_parent_data ir_tx_ledc_parents[] = {
+       { .fw_name = "hosc" },
+       { .hw = &pll_periph0_clk.hw },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(ir_tx_clk, "ir-tx", ir_tx_ledc_parents, 0x9c0,
+                                      0, 4,    /* M */
+                                      8, 2,    /* P */
+                                      24, 3,   /* mux */
+                                      BIT(31), /* gate */
+                                      0);
+
+static SUNXI_CCU_GATE_HWS(bus_ir_tx_clk, "bus-ir-tx", apb0_hws,
+                         0x9cc, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_gpadc_clk, "bus-gpadc", apb0_hws,
+                         0x9ec, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_ths_clk, "bus-ths", apb0_hws,
+                         0x9fc, BIT(0), 0);
+
+static const struct clk_hw *i2s_spdif_tx_parents[] = {
+       &pll_audio0_clk.hw,
+       &pll_audio0_4x_clk.common.hw,
+       &pll_audio1_div2_clk.common.hw,
+       &pll_audio1_div5_clk.common.hw,
+};
+static SUNXI_CCU_MP_HW_WITH_MUX_GATE(i2s0_clk, "i2s0", i2s_spdif_tx_parents, 0xa10,
+                                    0, 5,      /* M */
+                                    8, 2,      /* P */
+                                    24, 3,     /* mux */
+                                    BIT(31),   /* gate */
+                                    0);
+
+static SUNXI_CCU_MP_HW_WITH_MUX_GATE(i2s1_clk, "i2s1", i2s_spdif_tx_parents, 0xa14,
+                                    0, 5,      /* M */
+                                    8, 2,      /* P */
+                                    24, 3,     /* mux */
+                                    BIT(31),   /* gate */
+                                    0);
+
+static SUNXI_CCU_MP_HW_WITH_MUX_GATE(i2s2_clk, "i2s2", i2s_spdif_tx_parents, 0xa18,
+                                    0, 5,      /* M */
+                                    8, 2,      /* P */
+                                    24, 3,     /* mux */
+                                    BIT(31),   /* gate */
+                                    0);
+
+static const struct clk_hw *i2s2_asrc_parents[] = {
+       &pll_audio0_4x_clk.common.hw,
+       &pll_periph0_clk.hw,
+       &pll_audio1_div2_clk.common.hw,
+       &pll_audio1_div5_clk.common.hw,
+};
+static SUNXI_CCU_MP_HW_WITH_MUX_GATE(i2s2_asrc_clk, "i2s2-asrc", i2s2_asrc_parents, 0xa1c,
+                                    0, 5,      /* M */
+                                    8, 2,      /* P */
+                                    24, 3,     /* mux */
+                                    BIT(31),   /* gate */
+                                    0);
+
+static SUNXI_CCU_GATE_HWS(bus_i2s0_clk, "bus-i2s0", apb0_hws,
+                         0xa20, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2s1_clk, "bus-i2s1", apb0_hws,
+                         0xa20, BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2s2_clk, "bus-i2s2", apb0_hws,
+                         0xa20, BIT(2), 0);
+
+static SUNXI_CCU_MP_HW_WITH_MUX_GATE(spdif_tx_clk, "spdif-tx", i2s_spdif_tx_parents, 0xa24,
+                                    0, 5,      /* M */
+                                    8, 2,      /* P */
+                                    24, 3,     /* mux */
+                                    BIT(31),   /* gate */
+                                    0);
+
+static const struct clk_hw *spdif_rx_parents[] = {
+       &pll_periph0_clk.hw,
+       &pll_audio1_div2_clk.common.hw,
+       &pll_audio1_div5_clk.common.hw,
+};
+static SUNXI_CCU_MP_HW_WITH_MUX_GATE(spdif_rx_clk, "spdif-rx", spdif_rx_parents, 0xa28,
+                                    0, 5,      /* M */
+                                    8, 2,      /* P */
+                                    24, 3,     /* mux */
+                                    BIT(31),   /* gate */
+                                    0);
+
+static SUNXI_CCU_GATE_HWS(bus_spdif_clk, "bus-spdif", apb0_hws,
+                         0xa2c, BIT(0), 0);
+
+static const struct clk_hw *dmic_codec_parents[] = {
+       &pll_audio0_clk.hw,
+       &pll_audio1_div2_clk.common.hw,
+       &pll_audio1_div5_clk.common.hw,
+};
+static SUNXI_CCU_MP_HW_WITH_MUX_GATE(dmic_clk, "dmic", dmic_codec_parents, 0xa40,
+                                    0, 5,      /* M */
+                                    8, 2,      /* P */
+                                    24, 3,     /* mux */
+                                    BIT(31),   /* gate */
+                                    0);
+
+static SUNXI_CCU_GATE_HWS(bus_dmic_clk, "bus-dmic", apb0_hws,
+                         0xa4c, BIT(0), 0);
+
+static SUNXI_CCU_MP_HW_WITH_MUX_GATE(audio_dac_clk, "audio-dac", dmic_codec_parents, 0xa50,
+                                    0, 5,      /* M */
+                                    8, 2,      /* P */
+                                    24, 3,     /* mux */
+                                    BIT(31),   /* gate */
+                                    0);
+
+static SUNXI_CCU_MP_HW_WITH_MUX_GATE(audio_adc_clk, "audio-adc", dmic_codec_parents, 0xa54,
+                                    0, 5,      /* M */
+                                    8, 2,      /* P */
+                                    24, 3,     /* mux */
+                                    BIT(31),   /* gate */
+                                    0);
+
+static SUNXI_CCU_GATE_HWS(bus_audio_clk, "bus-audio", apb0_hws,
+                         0xa5c, BIT(0), 0);
+
+
+/*
+ * The first parent is a 48 MHz input clock divided by 4. That 48 MHz clock is
+ * a 2x multiplier from osc24M synchronized by pll-periph0, and is also used by
+ * the OHCI module.
+ */
+static const struct clk_parent_data usb_ohci_parents[] = {
+       { .hw = &pll_periph0_clk.hw },
+       { .fw_name = "hosc" },
+       { .fw_name = "losc" },
+};
+static const struct ccu_mux_fixed_prediv usb_ohci_predivs[] = {
+       { .index = 0, .div = 50 },
+       { .index = 1, .div = 2 },
+};
+
+static struct ccu_mux usb_ohci0_clk = {
+       .enable         = BIT(31),
+       .mux            = {
+               .shift          = 24,
+               .width          = 2,
+               .fixed_predivs  = usb_ohci_predivs,
+               .n_predivs      = ARRAY_SIZE(usb_ohci_predivs),
+       },
+       .common         = {
+               .reg            = 0xa70,
+               .features       = CCU_FEATURE_FIXED_PREDIV,
+               .hw.init        = CLK_HW_INIT_PARENTS_DATA("usb-ohci0",
+                                                          usb_ohci_parents,
+                                                          &ccu_mux_ops,
+                                                          0),
+       },
+};
+
+static struct ccu_mux usb_ohci1_clk = {
+       .enable         = BIT(31),
+       .mux            = {
+               .shift          = 24,
+               .width          = 2,
+               .fixed_predivs  = usb_ohci_predivs,
+               .n_predivs      = ARRAY_SIZE(usb_ohci_predivs),
+       },
+       .common         = {
+               .reg            = 0xa74,
+               .features       = CCU_FEATURE_FIXED_PREDIV,
+               .hw.init        = CLK_HW_INIT_PARENTS_DATA("usb-ohci1",
+                                                          usb_ohci_parents,
+                                                          &ccu_mux_ops,
+                                                          0),
+       },
+};
+
+static SUNXI_CCU_GATE_HWS(bus_ohci0_clk, "bus-ohci0", psi_ahb_hws,
+                         0xa8c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_ohci1_clk, "bus-ohci1", psi_ahb_hws,
+                         0xa8c, BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(bus_ehci0_clk, "bus-ehci0", psi_ahb_hws,
+                         0xa8c, BIT(4), 0);
+static SUNXI_CCU_GATE_HWS(bus_ehci1_clk, "bus-ehci1", psi_ahb_hws,
+                         0xa8c, BIT(5), 0);
+static SUNXI_CCU_GATE_HWS(bus_otg_clk, "bus-otg", psi_ahb_hws,
+                         0xa8c, BIT(8), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_lradc_clk, "bus-lradc", apb0_hws,
+                         0xa9c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_dpss_top_clk, "bus-dpss-top", psi_ahb_hws,
+                         0xabc, BIT(0), 0);
+
+static SUNXI_CCU_GATE_DATA(hdmi_24M_clk, "hdmi-24M", osc24M,
+                          0xb04, BIT(31), 0);
+
+static SUNXI_CCU_GATE_HWS_WITH_PREDIV(hdmi_cec_32k_clk, "hdmi-cec-32k",
+                                     pll_periph0_2x_hws,
+                                     0xb10, BIT(30), 36621, 0);
+
+static const struct clk_parent_data hdmi_cec_parents[] = {
+       { .fw_name = "losc" },
+       { .hw = &hdmi_cec_32k_clk.common.hw },
+};
+static SUNXI_CCU_MUX_DATA_WITH_GATE(hdmi_cec_clk, "hdmi-cec", hdmi_cec_parents, 0xb10,
+                                   24, 1,      /* mux */
+                                   BIT(31),    /* gate */
+                                   0);
+
+static SUNXI_CCU_GATE_HWS(bus_hdmi_clk, "bus-hdmi", psi_ahb_hws,
+                         0xb1c, BIT(0), 0);
+
+static const struct clk_parent_data mipi_dsi_parents[] = {
+       { .fw_name = "hosc" },
+       { .hw = &pll_periph0_clk.hw },
+       { .hw = &pll_video0_2x_clk.hw },
+       { .hw = &pll_video1_2x_clk.hw },
+       { .hw = &pll_audio1_div2_clk.common.hw },
+};
+static SUNXI_CCU_M_DATA_WITH_MUX_GATE(mipi_dsi_clk, "mipi-dsi", mipi_dsi_parents, 0xb24,
+                                     0, 4,     /* M */
+                                     24, 3,    /* mux */
+                                     BIT(31),  /* gate */
+                                     CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_GATE_HWS(bus_mipi_dsi_clk, "bus-mipi-dsi", psi_ahb_hws,
+                         0xb4c, BIT(0), 0);
+
+static const struct clk_hw *tcon_tve_parents[] = {
+       &pll_video0_clk.hw,
+       &pll_video0_4x_clk.common.hw,
+       &pll_video1_clk.hw,
+       &pll_video1_4x_clk.common.hw,
+       &pll_periph0_2x_clk.common.hw,
+       &pll_audio1_div2_clk.common.hw,
+};
+static SUNXI_CCU_MP_HW_WITH_MUX_GATE(tcon_lcd0_clk, "tcon-lcd0", tcon_tve_parents, 0xb60,
+                                    0, 4,      /* M */
+                                    8, 2,      /* P */
+                                    24, 3,     /* mux */
+                                    BIT(31),   /* gate */
+                                    CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_GATE_HWS(bus_tcon_lcd0_clk, "bus-tcon-lcd0", psi_ahb_hws,
+                         0xb7c, BIT(0), 0);
+
+static SUNXI_CCU_MP_HW_WITH_MUX_GATE(tcon_tv_clk, "tcon-tv", tcon_tve_parents, 0xb80,
+                                    0, 4,      /* M */
+                                    8, 2,      /* P */
+                                    24, 3,     /* mux */
+                                    BIT(31),   /* gate */
+                                    CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_GATE_HWS(bus_tcon_tv_clk, "bus-tcon-tv", psi_ahb_hws,
+                         0xb9c, BIT(0), 0);
+
+static SUNXI_CCU_MP_HW_WITH_MUX_GATE(tve_clk, "tve", tcon_tve_parents, 0xbb0,
+                                    0, 4,      /* M */
+                                    8, 2,      /* P */
+                                    24, 3,     /* mux */
+                                    BIT(31),   /* gate */
+                                    0);
+
+static SUNXI_CCU_GATE_HWS(bus_tve_top_clk, "bus-tve-top", psi_ahb_hws,
+                         0xbbc, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_tve_clk, "bus-tve", psi_ahb_hws,
+                         0xbbc, BIT(1), 0);
+
+static const struct clk_parent_data tvd_parents[] = {
+       { .fw_name = "hosc" },
+       { .hw = &pll_video0_clk.hw },
+       { .hw = &pll_video1_clk.hw },
+       { .hw = &pll_periph0_clk.hw },
+};
+static SUNXI_CCU_M_DATA_WITH_MUX_GATE(tvd_clk, "tvd", tvd_parents, 0xbc0,
+                                     0, 5,     /* M */
+                                     24, 3,    /* mux */
+                                     BIT(31),  /* gate */
+                                     0);
+
+static SUNXI_CCU_GATE_HWS(bus_tvd_top_clk, "bus-tvd-top", psi_ahb_hws,
+                         0xbdc, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_tvd_clk, "bus-tvd", psi_ahb_hws,
+                         0xbdc, BIT(1), 0);
+
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(ledc_clk, "ledc", ir_tx_ledc_parents, 0xbf0,
+                                      0, 4,    /* M */
+                                      8, 2,    /* P */
+                                      24, 1,   /* mux */
+                                      BIT(31), /* gate */
+                                      0);
+
+static SUNXI_CCU_GATE_HWS(bus_ledc_clk, "bus-ledc", psi_ahb_hws,
+                         0xbfc, BIT(0), 0);
+
+static const struct clk_hw *csi_top_parents[] = {
+       &pll_periph0_2x_clk.common.hw,
+       &pll_video0_2x_clk.hw,
+       &pll_video1_2x_clk.hw,
+};
+static SUNXI_CCU_M_HW_WITH_MUX_GATE(csi_top_clk, "csi-top", csi_top_parents, 0xc04,
+                                   0, 4,       /* M */
+                                   24, 3,      /* mux */
+                                   BIT(31),    /* gate */
+                                   0);
+
+static const struct clk_parent_data csi_mclk_parents[] = {
+       { .fw_name = "hosc" },
+       { .hw = &pll_periph0_clk.hw },
+       { .hw = &pll_video0_clk.hw },
+       { .hw = &pll_video1_clk.hw },
+       { .hw = &pll_audio1_div2_clk.common.hw },
+       { .hw = &pll_audio1_div5_clk.common.hw },
+};
+static SUNXI_CCU_M_DATA_WITH_MUX_GATE(csi_mclk_clk, "csi-mclk", csi_mclk_parents, 0xc08,
+                                     0, 5,     /* M */
+                                     24, 3,    /* mux */
+                                     BIT(31),  /* gate */
+                                     0);
+
+static SUNXI_CCU_GATE_HWS(bus_csi_clk, "bus-csi", psi_ahb_hws,
+                         0xc1c, BIT(0), 0);
+
+static const struct clk_parent_data tpadc_parents[] = {
+       { .fw_name = "hosc" },
+       { .hw = &pll_audio0_clk.hw },
+};
+static SUNXI_CCU_MUX_DATA_WITH_GATE(tpadc_clk, "tpadc", tpadc_parents, 0xc50,
+                                   24, 3,      /* mux */
+                                   BIT(31),    /* gate */
+                                   0);
+
+static SUNXI_CCU_GATE_HWS(bus_tpadc_clk, "bus-tpadc", apb0_hws,
+                         0xc5c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_tzma_clk, "bus-tzma", apb0_hws,
+                         0xc6c, BIT(0), 0);
+
+static const struct clk_parent_data dsp_parents[] = {
+       { .fw_name = "hosc" },
+       { .fw_name = "losc" },
+       { .fw_name = "iosc" },
+       { .hw = &pll_periph0_2x_clk.common.hw },
+       { .hw = &pll_audio1_div2_clk.common.hw },
+};
+static SUNXI_CCU_M_DATA_WITH_MUX_GATE(dsp_clk, "dsp", dsp_parents, 0xc70,
+                                     0, 5,     /* M */
+                                     24, 3,    /* mux */
+                                     BIT(31),  /* gate */
+                                     0);
+
+static SUNXI_CCU_GATE_HWS(bus_dsp_cfg_clk, "bus-dsp-cfg", psi_ahb_hws,
+                         0xc7c, BIT(1), 0);
+
+/*
+ * The RISC-V gate is not modelled - it is in a separate register (0xd04)
+ * and has a special key field. The clock is critical anyway.
+ */
+static const struct clk_parent_data riscv_parents[] = {
+       { .fw_name = "hosc" },
+       { .fw_name = "losc" },
+       { .fw_name = "iosc" },
+       { .hw = &pll_periph0_800M_clk.common.hw },
+       { .hw = &pll_periph0_clk.hw },
+       { .hw = &pll_cpux_clk.common.hw },
+       { .hw = &pll_audio1_div2_clk.common.hw },
+};
+static SUNXI_CCU_M_DATA_WITH_MUX(riscv_clk, "riscv", riscv_parents, 0xd00,
+                                0, 5,  /* M */
+                                24, 3, /* mux */
+                                CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
+
+/* The riscv-axi clk must be divided by at least 2. */
+static struct clk_div_table riscv_axi_table[] = {
+       { .val = 1, .div = 2 },
+       { .val = 2, .div = 3 },
+       { .val = 3, .div = 4 },
+       { /* Sentinel */ }
+};
+static SUNXI_CCU_DIV_TABLE_HW(riscv_axi_clk, "riscv-axi", &riscv_clk.common.hw,
+                             0xd00, 8, 2, riscv_axi_table, 0);
+
+static SUNXI_CCU_GATE_HWS(bus_riscv_cfg_clk, "bus-riscv-cfg", psi_ahb_hws,
+                         0xd0c, BIT(0), CLK_IS_CRITICAL);
+
+static SUNXI_CCU_GATE_DATA(fanout_24M_clk, "fanout-24M", osc24M,
+                          0xf30, BIT(0), 0);
+static SUNXI_CCU_GATE_DATA_WITH_PREDIV(fanout_12M_clk, "fanout-12M", osc24M,
+                                      0xf30, BIT(1), 2, 0);
+static SUNXI_CCU_GATE_HWS_WITH_PREDIV(fanout_16M_clk, "fanout-16M", pll_periph0_2x_hws,
+                                     0xf30, BIT(2), 75, 0);
+static SUNXI_CCU_GATE_HWS_WITH_PREDIV(fanout_25M_clk, "fanout-25M", pll_periph0_hws,
+                                     0xf30, BIT(3), 24, 0);
+static SUNXI_CCU_GATE_HWS_WITH_PREDIV(fanout_32k_clk, "fanout-32k", pll_periph0_2x_hws,
+                                     0xf30, BIT(4), 36621, 0);
+
+/* This clock has a second divider that is not modelled and forced to 0. */
+#define SUN20I_D1_FANOUT_27M_REG       0xf34
+static const struct clk_hw *fanout_27M_parents[] = {
+       &pll_video0_clk.hw,
+       &pll_video1_clk.hw,
+};
+static SUNXI_CCU_M_HW_WITH_MUX_GATE(fanout_27M_clk, "fanout-27M", fanout_27M_parents, 0xf34,
+                                   0, 5,       /* M */
+                                   24, 2,      /* mux */
+                                   BIT(31),    /* gate */
+                                   0);
+
+static SUNXI_CCU_M_HWS_WITH_GATE(fanout_pclk_clk, "fanout-pclk", apb0_hws, 0xf38,
+                                0, 5,          /* M */
+                                BIT(31),       /* gate */
+                                0);
+
+static const struct clk_hw *fanout_parents[] = {
+       &fanout_32k_clk.common.hw,
+       &fanout_12M_clk.common.hw,
+       &fanout_16M_clk.common.hw,
+       &fanout_24M_clk.common.hw,
+       &fanout_25M_clk.common.hw,
+       &fanout_27M_clk.common.hw,
+       &fanout_pclk_clk.common.hw,
+};
+static SUNXI_CCU_MUX_HW_WITH_GATE(fanout0_clk, "fanout0", fanout_parents, 0xf3c,
+                                 0, 3,         /* mux */
+                                 BIT(21),      /* gate */
+                                 0);
+static SUNXI_CCU_MUX_HW_WITH_GATE(fanout1_clk, "fanout1", fanout_parents, 0xf3c,
+                                 3, 3,         /* mux */
+                                 BIT(22),      /* gate */
+                                 0);
+static SUNXI_CCU_MUX_HW_WITH_GATE(fanout2_clk, "fanout2", fanout_parents, 0xf3c,
+                                 6, 3,         /* mux */
+                                 BIT(23),      /* gate */
+                                 0);
+
+static struct ccu_common *sun20i_d1_ccu_clks[] = {
+       &pll_cpux_clk.common,
+       &pll_ddr0_clk.common,
+       &pll_periph0_4x_clk.common,
+       &pll_periph0_2x_clk.common,
+       &pll_periph0_800M_clk.common,
+       &pll_video0_4x_clk.common,
+       &pll_video1_4x_clk.common,
+       &pll_ve_clk.common,
+       &pll_audio0_4x_clk.common,
+       &pll_audio1_clk.common,
+       &pll_audio1_div2_clk.common,
+       &pll_audio1_div5_clk.common,
+       &cpux_clk.common,
+       &cpux_axi_clk.common,
+       &cpux_apb_clk.common,
+       &psi_ahb_clk.common,
+       &apb0_clk.common,
+       &apb1_clk.common,
+       &de_clk.common,
+       &bus_de_clk.common,
+       &di_clk.common,
+       &bus_di_clk.common,
+       &g2d_clk.common,
+       &bus_g2d_clk.common,
+       &ce_clk.common,
+       &bus_ce_clk.common,
+       &ve_clk.common,
+       &bus_ve_clk.common,
+       &bus_dma_clk.common,
+       &bus_msgbox0_clk.common,
+       &bus_msgbox1_clk.common,
+       &bus_msgbox2_clk.common,
+       &bus_spinlock_clk.common,
+       &bus_hstimer_clk.common,
+       &avs_clk.common,
+       &bus_dbg_clk.common,
+       &bus_pwm_clk.common,
+       &bus_iommu_clk.common,
+       &dram_clk.common,
+       &mbus_dma_clk.common,
+       &mbus_ve_clk.common,
+       &mbus_ce_clk.common,
+       &mbus_tvin_clk.common,
+       &mbus_csi_clk.common,
+       &mbus_g2d_clk.common,
+       &mbus_riscv_clk.common,
+       &bus_dram_clk.common,
+       &mmc0_clk.common,
+       &mmc1_clk.common,
+       &mmc2_clk.common,
+       &bus_mmc0_clk.common,
+       &bus_mmc1_clk.common,
+       &bus_mmc2_clk.common,
+       &bus_uart0_clk.common,
+       &bus_uart1_clk.common,
+       &bus_uart2_clk.common,
+       &bus_uart3_clk.common,
+       &bus_uart4_clk.common,
+       &bus_uart5_clk.common,
+       &bus_i2c0_clk.common,
+       &bus_i2c1_clk.common,
+       &bus_i2c2_clk.common,
+       &bus_i2c3_clk.common,
+       &spi0_clk.common,
+       &spi1_clk.common,
+       &bus_spi0_clk.common,
+       &bus_spi1_clk.common,
+       &emac_25M_clk.common,
+       &bus_emac_clk.common,
+       &ir_tx_clk.common,
+       &bus_ir_tx_clk.common,
+       &bus_gpadc_clk.common,
+       &bus_ths_clk.common,
+       &i2s0_clk.common,
+       &i2s1_clk.common,
+       &i2s2_clk.common,
+       &i2s2_asrc_clk.common,
+       &bus_i2s0_clk.common,
+       &bus_i2s1_clk.common,
+       &bus_i2s2_clk.common,
+       &spdif_tx_clk.common,
+       &spdif_rx_clk.common,
+       &bus_spdif_clk.common,
+       &dmic_clk.common,
+       &bus_dmic_clk.common,
+       &audio_dac_clk.common,
+       &audio_adc_clk.common,
+       &bus_audio_clk.common,
+       &usb_ohci0_clk.common,
+       &usb_ohci1_clk.common,
+       &bus_ohci0_clk.common,
+       &bus_ohci1_clk.common,
+       &bus_ehci0_clk.common,
+       &bus_ehci1_clk.common,
+       &bus_otg_clk.common,
+       &bus_lradc_clk.common,
+       &bus_dpss_top_clk.common,
+       &hdmi_24M_clk.common,
+       &hdmi_cec_32k_clk.common,
+       &hdmi_cec_clk.common,
+       &bus_hdmi_clk.common,
+       &mipi_dsi_clk.common,
+       &bus_mipi_dsi_clk.common,
+       &tcon_lcd0_clk.common,
+       &bus_tcon_lcd0_clk.common,
+       &tcon_tv_clk.common,
+       &bus_tcon_tv_clk.common,
+       &tve_clk.common,
+       &bus_tve_top_clk.common,
+       &bus_tve_clk.common,
+       &tvd_clk.common,
+       &bus_tvd_top_clk.common,
+       &bus_tvd_clk.common,
+       &ledc_clk.common,
+       &bus_ledc_clk.common,
+       &csi_top_clk.common,
+       &csi_mclk_clk.common,
+       &bus_csi_clk.common,
+       &tpadc_clk.common,
+       &bus_tpadc_clk.common,
+       &bus_tzma_clk.common,
+       &dsp_clk.common,
+       &bus_dsp_cfg_clk.common,
+       &riscv_clk.common,
+       &riscv_axi_clk.common,
+       &bus_riscv_cfg_clk.common,
+       &fanout_24M_clk.common,
+       &fanout_12M_clk.common,
+       &fanout_16M_clk.common,
+       &fanout_25M_clk.common,
+       &fanout_32k_clk.common,
+       &fanout_27M_clk.common,
+       &fanout_pclk_clk.common,
+       &fanout0_clk.common,
+       &fanout1_clk.common,
+       &fanout2_clk.common,
+};
+
+static struct clk_hw_onecell_data sun20i_d1_hw_clks = {
+       .num    = CLK_NUMBER,
+       .hws    = {
+               [CLK_PLL_CPUX]          = &pll_cpux_clk.common.hw,
+               [CLK_PLL_DDR0]          = &pll_ddr0_clk.common.hw,
+               [CLK_PLL_PERIPH0_4X]    = &pll_periph0_4x_clk.common.hw,
+               [CLK_PLL_PERIPH0_2X]    = &pll_periph0_2x_clk.common.hw,
+               [CLK_PLL_PERIPH0_800M]  = &pll_periph0_800M_clk.common.hw,
+               [CLK_PLL_PERIPH0]       = &pll_periph0_clk.hw,
+               [CLK_PLL_PERIPH0_DIV3]  = &pll_periph0_div3_clk.hw,
+               [CLK_PLL_VIDEO0_4X]     = &pll_video0_4x_clk.common.hw,
+               [CLK_PLL_VIDEO0_2X]     = &pll_video0_2x_clk.hw,
+               [CLK_PLL_VIDEO0]        = &pll_video0_clk.hw,
+               [CLK_PLL_VIDEO1_4X]     = &pll_video1_4x_clk.common.hw,
+               [CLK_PLL_VIDEO1_2X]     = &pll_video1_2x_clk.hw,
+               [CLK_PLL_VIDEO1]        = &pll_video1_clk.hw,
+               [CLK_PLL_VE]            = &pll_ve_clk.common.hw,
+               [CLK_PLL_AUDIO0_4X]     = &pll_audio0_4x_clk.common.hw,
+               [CLK_PLL_AUDIO0_2X]     = &pll_audio0_2x_clk.hw,
+               [CLK_PLL_AUDIO0]        = &pll_audio0_clk.hw,
+               [CLK_PLL_AUDIO1]        = &pll_audio1_clk.common.hw,
+               [CLK_PLL_AUDIO1_DIV2]   = &pll_audio1_div2_clk.common.hw,
+               [CLK_PLL_AUDIO1_DIV5]   = &pll_audio1_div5_clk.common.hw,
+               [CLK_CPUX]              = &cpux_clk.common.hw,
+               [CLK_CPUX_AXI]          = &cpux_axi_clk.common.hw,
+               [CLK_CPUX_APB]          = &cpux_apb_clk.common.hw,
+               [CLK_PSI_AHB]           = &psi_ahb_clk.common.hw,
+               [CLK_APB0]              = &apb0_clk.common.hw,
+               [CLK_APB1]              = &apb1_clk.common.hw,
+               [CLK_MBUS]              = &mbus_clk.hw,
+               [CLK_DE]                = &de_clk.common.hw,
+               [CLK_BUS_DE]            = &bus_de_clk.common.hw,
+               [CLK_DI]                = &di_clk.common.hw,
+               [CLK_BUS_DI]            = &bus_di_clk.common.hw,
+               [CLK_G2D]               = &g2d_clk.common.hw,
+               [CLK_BUS_G2D]           = &bus_g2d_clk.common.hw,
+               [CLK_CE]                = &ce_clk.common.hw,
+               [CLK_BUS_CE]            = &bus_ce_clk.common.hw,
+               [CLK_VE]                = &ve_clk.common.hw,
+               [CLK_BUS_VE]            = &bus_ve_clk.common.hw,
+               [CLK_BUS_DMA]           = &bus_dma_clk.common.hw,
+               [CLK_BUS_MSGBOX0]       = &bus_msgbox0_clk.common.hw,
+               [CLK_BUS_MSGBOX1]       = &bus_msgbox1_clk.common.hw,
+               [CLK_BUS_MSGBOX2]       = &bus_msgbox2_clk.common.hw,
+               [CLK_BUS_SPINLOCK]      = &bus_spinlock_clk.common.hw,
+               [CLK_BUS_HSTIMER]       = &bus_hstimer_clk.common.hw,
+               [CLK_AVS]               = &avs_clk.common.hw,
+               [CLK_BUS_DBG]           = &bus_dbg_clk.common.hw,
+               [CLK_BUS_PWM]           = &bus_pwm_clk.common.hw,
+               [CLK_BUS_IOMMU]         = &bus_iommu_clk.common.hw,
+               [CLK_DRAM]              = &dram_clk.common.hw,
+               [CLK_MBUS_DMA]          = &mbus_dma_clk.common.hw,
+               [CLK_MBUS_VE]           = &mbus_ve_clk.common.hw,
+               [CLK_MBUS_CE]           = &mbus_ce_clk.common.hw,
+               [CLK_MBUS_TVIN]         = &mbus_tvin_clk.common.hw,
+               [CLK_MBUS_CSI]          = &mbus_csi_clk.common.hw,
+               [CLK_MBUS_G2D]          = &mbus_g2d_clk.common.hw,
+               [CLK_MBUS_RISCV]        = &mbus_riscv_clk.common.hw,
+               [CLK_BUS_DRAM]          = &bus_dram_clk.common.hw,
+               [CLK_MMC0]              = &mmc0_clk.common.hw,
+               [CLK_MMC1]              = &mmc1_clk.common.hw,
+               [CLK_MMC2]              = &mmc2_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_UART0]         = &bus_uart0_clk.common.hw,
+               [CLK_BUS_UART1]         = &bus_uart1_clk.common.hw,
+               [CLK_BUS_UART2]         = &bus_uart2_clk.common.hw,
+               [CLK_BUS_UART3]         = &bus_uart3_clk.common.hw,
+               [CLK_BUS_UART4]         = &bus_uart4_clk.common.hw,
+               [CLK_BUS_UART5]         = &bus_uart5_clk.common.hw,
+               [CLK_BUS_I2C0]          = &bus_i2c0_clk.common.hw,
+               [CLK_BUS_I2C1]          = &bus_i2c1_clk.common.hw,
+               [CLK_BUS_I2C2]          = &bus_i2c2_clk.common.hw,
+               [CLK_BUS_I2C3]          = &bus_i2c3_clk.common.hw,
+               [CLK_SPI0]              = &spi0_clk.common.hw,
+               [CLK_SPI1]              = &spi1_clk.common.hw,
+               [CLK_BUS_SPI0]          = &bus_spi0_clk.common.hw,
+               [CLK_BUS_SPI1]          = &bus_spi1_clk.common.hw,
+               [CLK_EMAC_25M]          = &emac_25M_clk.common.hw,
+               [CLK_BUS_EMAC]          = &bus_emac_clk.common.hw,
+               [CLK_IR_TX]             = &ir_tx_clk.common.hw,
+               [CLK_BUS_IR_TX]         = &bus_ir_tx_clk.common.hw,
+               [CLK_BUS_GPADC]         = &bus_gpadc_clk.common.hw,
+               [CLK_BUS_THS]           = &bus_ths_clk.common.hw,
+               [CLK_I2S0]              = &i2s0_clk.common.hw,
+               [CLK_I2S1]              = &i2s1_clk.common.hw,
+               [CLK_I2S2]              = &i2s2_clk.common.hw,
+               [CLK_I2S2_ASRC]         = &i2s2_asrc_clk.common.hw,
+               [CLK_BUS_I2S0]          = &bus_i2s0_clk.common.hw,
+               [CLK_BUS_I2S1]          = &bus_i2s1_clk.common.hw,
+               [CLK_BUS_I2S2]          = &bus_i2s2_clk.common.hw,
+               [CLK_SPDIF_TX]          = &spdif_tx_clk.common.hw,
+               [CLK_SPDIF_RX]          = &spdif_rx_clk.common.hw,
+               [CLK_BUS_SPDIF]         = &bus_spdif_clk.common.hw,
+               [CLK_DMIC]              = &dmic_clk.common.hw,
+               [CLK_BUS_DMIC]          = &bus_dmic_clk.common.hw,
+               [CLK_AUDIO_DAC]         = &audio_dac_clk.common.hw,
+               [CLK_AUDIO_ADC]         = &audio_adc_clk.common.hw,
+               [CLK_BUS_AUDIO]         = &bus_audio_clk.common.hw,
+               [CLK_USB_OHCI0]         = &usb_ohci0_clk.common.hw,
+               [CLK_USB_OHCI1]         = &usb_ohci1_clk.common.hw,
+               [CLK_BUS_OHCI0]         = &bus_ohci0_clk.common.hw,
+               [CLK_BUS_OHCI1]         = &bus_ohci1_clk.common.hw,
+               [CLK_BUS_EHCI0]         = &bus_ehci0_clk.common.hw,
+               [CLK_BUS_EHCI1]         = &bus_ehci1_clk.common.hw,
+               [CLK_BUS_OTG]           = &bus_otg_clk.common.hw,
+               [CLK_BUS_LRADC]         = &bus_lradc_clk.common.hw,
+               [CLK_BUS_DPSS_TOP]      = &bus_dpss_top_clk.common.hw,
+               [CLK_HDMI_24M]          = &hdmi_24M_clk.common.hw,
+               [CLK_HDMI_CEC_32K]      = &hdmi_cec_32k_clk.common.hw,
+               [CLK_HDMI_CEC]          = &hdmi_cec_clk.common.hw,
+               [CLK_BUS_HDMI]          = &bus_hdmi_clk.common.hw,
+               [CLK_MIPI_DSI]          = &mipi_dsi_clk.common.hw,
+               [CLK_BUS_MIPI_DSI]      = &bus_mipi_dsi_clk.common.hw,
+               [CLK_TCON_LCD0]         = &tcon_lcd0_clk.common.hw,
+               [CLK_BUS_TCON_LCD0]     = &bus_tcon_lcd0_clk.common.hw,
+               [CLK_TCON_TV]           = &tcon_tv_clk.common.hw,
+               [CLK_BUS_TCON_TV]       = &bus_tcon_tv_clk.common.hw,
+               [CLK_TVE]               = &tve_clk.common.hw,
+               [CLK_BUS_TVE_TOP]       = &bus_tve_top_clk.common.hw,
+               [CLK_BUS_TVE]           = &bus_tve_clk.common.hw,
+               [CLK_TVD]               = &tvd_clk.common.hw,
+               [CLK_BUS_TVD_TOP]       = &bus_tvd_top_clk.common.hw,
+               [CLK_BUS_TVD]           = &bus_tvd_clk.common.hw,
+               [CLK_LEDC]              = &ledc_clk.common.hw,
+               [CLK_BUS_LEDC]          = &bus_ledc_clk.common.hw,
+               [CLK_CSI_TOP]           = &csi_top_clk.common.hw,
+               [CLK_CSI_MCLK]          = &csi_mclk_clk.common.hw,
+               [CLK_BUS_CSI]           = &bus_csi_clk.common.hw,
+               [CLK_TPADC]             = &tpadc_clk.common.hw,
+               [CLK_BUS_TPADC]         = &bus_tpadc_clk.common.hw,
+               [CLK_BUS_TZMA]          = &bus_tzma_clk.common.hw,
+               [CLK_DSP]               = &dsp_clk.common.hw,
+               [CLK_BUS_DSP_CFG]       = &bus_dsp_cfg_clk.common.hw,
+               [CLK_RISCV]             = &riscv_clk.common.hw,
+               [CLK_RISCV_AXI]         = &riscv_axi_clk.common.hw,
+               [CLK_BUS_RISCV_CFG]     = &bus_riscv_cfg_clk.common.hw,
+               [CLK_FANOUT_24M]        = &fanout_24M_clk.common.hw,
+               [CLK_FANOUT_12M]        = &fanout_12M_clk.common.hw,
+               [CLK_FANOUT_16M]        = &fanout_16M_clk.common.hw,
+               [CLK_FANOUT_25M]        = &fanout_25M_clk.common.hw,
+               [CLK_FANOUT_32K]        = &fanout_32k_clk.common.hw,
+               [CLK_FANOUT_27M]        = &fanout_27M_clk.common.hw,
+               [CLK_FANOUT_PCLK]       = &fanout_pclk_clk.common.hw,
+               [CLK_FANOUT0]           = &fanout0_clk.common.hw,
+               [CLK_FANOUT1]           = &fanout1_clk.common.hw,
+               [CLK_FANOUT2]           = &fanout2_clk.common.hw,
+       },
+};
+
+static struct ccu_reset_map sun20i_d1_ccu_resets[] = {
+       [RST_MBUS]              = { 0x540, BIT(30) },
+       [RST_BUS_DE]            = { 0x60c, BIT(16) },
+       [RST_BUS_DI]            = { 0x62c, BIT(16) },
+       [RST_BUS_G2D]           = { 0x63c, BIT(16) },
+       [RST_BUS_CE]            = { 0x68c, BIT(16) },
+       [RST_BUS_VE]            = { 0x69c, BIT(16) },
+       [RST_BUS_DMA]           = { 0x70c, BIT(16) },
+       [RST_BUS_MSGBOX0]       = { 0x71c, BIT(16) },
+       [RST_BUS_MSGBOX1]       = { 0x71c, BIT(17) },
+       [RST_BUS_MSGBOX2]       = { 0x71c, BIT(18) },
+       [RST_BUS_SPINLOCK]      = { 0x72c, BIT(16) },
+       [RST_BUS_HSTIMER]       = { 0x73c, BIT(16) },
+       [RST_BUS_DBG]           = { 0x78c, BIT(16) },
+       [RST_BUS_PWM]           = { 0x7ac, BIT(16) },
+       [RST_BUS_DRAM]          = { 0x80c, BIT(16) },
+       [RST_BUS_MMC0]          = { 0x84c, BIT(16) },
+       [RST_BUS_MMC1]          = { 0x84c, BIT(17) },
+       [RST_BUS_MMC2]          = { 0x84c, BIT(18) },
+       [RST_BUS_UART0]         = { 0x90c, BIT(16) },
+       [RST_BUS_UART1]         = { 0x90c, BIT(17) },
+       [RST_BUS_UART2]         = { 0x90c, BIT(18) },
+       [RST_BUS_UART3]         = { 0x90c, BIT(19) },
+       [RST_BUS_UART4]         = { 0x90c, BIT(20) },
+       [RST_BUS_UART5]         = { 0x90c, BIT(21) },
+       [RST_BUS_I2C0]          = { 0x91c, BIT(16) },
+       [RST_BUS_I2C1]          = { 0x91c, BIT(17) },
+       [RST_BUS_I2C2]          = { 0x91c, BIT(18) },
+       [RST_BUS_I2C3]          = { 0x91c, BIT(19) },
+       [RST_BUS_SPI0]          = { 0x96c, BIT(16) },
+       [RST_BUS_SPI1]          = { 0x96c, BIT(17) },
+       [RST_BUS_EMAC]          = { 0x97c, BIT(16) },
+       [RST_BUS_IR_TX]         = { 0x9cc, BIT(16) },
+       [RST_BUS_GPADC]         = { 0x9ec, BIT(16) },
+       [RST_BUS_THS]           = { 0x9fc, BIT(16) },
+       [RST_BUS_I2S0]          = { 0xa20, BIT(16) },
+       [RST_BUS_I2S1]          = { 0xa20, BIT(17) },
+       [RST_BUS_I2S2]          = { 0xa20, BIT(18) },
+       [RST_BUS_SPDIF]         = { 0xa2c, BIT(16) },
+       [RST_BUS_DMIC]          = { 0xa4c, BIT(16) },
+       [RST_BUS_AUDIO]         = { 0xa5c, BIT(16) },
+       [RST_USB_PHY0]          = { 0xa70, BIT(30) },
+       [RST_USB_PHY1]          = { 0xa74, BIT(30) },
+       [RST_BUS_OHCI0]         = { 0xa8c, BIT(16) },
+       [RST_BUS_OHCI1]         = { 0xa8c, BIT(17) },
+       [RST_BUS_EHCI0]         = { 0xa8c, BIT(20) },
+       [RST_BUS_EHCI1]         = { 0xa8c, BIT(21) },
+       [RST_BUS_OTG]           = { 0xa8c, BIT(24) },
+       [RST_BUS_LRADC]         = { 0xa9c, BIT(16) },
+       [RST_BUS_DPSS_TOP]      = { 0xabc, BIT(16) },
+       [RST_BUS_HDMI_MAIN]     = { 0xb1c, BIT(16) },
+       [RST_BUS_HDMI_SUB]      = { 0xb1c, BIT(17) },
+       [RST_BUS_MIPI_DSI]      = { 0xb4c, BIT(16) },
+       [RST_BUS_TCON_LCD0]     = { 0xb7c, BIT(16) },
+       [RST_BUS_TCON_TV]       = { 0xb9c, BIT(16) },
+       [RST_BUS_LVDS0]         = { 0xbac, BIT(16) },
+       [RST_BUS_TVE_TOP]       = { 0xbbc, BIT(16) },
+       [RST_BUS_TVE]           = { 0xbbc, BIT(17) },
+       [RST_BUS_TVD_TOP]       = { 0xbdc, BIT(16) },
+       [RST_BUS_TVD]           = { 0xbdc, BIT(17) },
+       [RST_BUS_LEDC]          = { 0xbfc, BIT(16) },
+       [RST_BUS_CSI]           = { 0xc1c, BIT(16) },
+       [RST_BUS_TPADC]         = { 0xc5c, BIT(16) },
+       [RST_DSP]               = { 0xc7c, BIT(16) },
+       [RST_BUS_DSP_CFG]       = { 0xc7c, BIT(17) },
+       [RST_BUS_DSP_DBG]       = { 0xc7c, BIT(18) },
+       [RST_BUS_RISCV_CFG]     = { 0xd0c, BIT(16) },
+};
+
+static const struct sunxi_ccu_desc sun20i_d1_ccu_desc = {
+       .ccu_clks       = sun20i_d1_ccu_clks,
+       .num_ccu_clks   = ARRAY_SIZE(sun20i_d1_ccu_clks),
+
+       .hw_clks        = &sun20i_d1_hw_clks,
+
+       .resets         = sun20i_d1_ccu_resets,
+       .num_resets     = ARRAY_SIZE(sun20i_d1_ccu_resets),
+};
+
+static const u32 pll_regs[] = {
+       SUN20I_D1_PLL_CPUX_REG,
+       SUN20I_D1_PLL_DDR0_REG,
+       SUN20I_D1_PLL_PERIPH0_REG,
+       SUN20I_D1_PLL_VIDEO0_REG,
+       SUN20I_D1_PLL_VIDEO1_REG,
+       SUN20I_D1_PLL_VE_REG,
+       SUN20I_D1_PLL_AUDIO0_REG,
+       SUN20I_D1_PLL_AUDIO1_REG,
+};
+
+static const u32 pll_video_regs[] = {
+       SUN20I_D1_PLL_VIDEO0_REG,
+       SUN20I_D1_PLL_VIDEO1_REG,
+};
+
+static struct ccu_mux_nb sun20i_d1_riscv_nb = {
+       .common         = &riscv_clk.common,
+       .cm             = &riscv_clk.mux,
+       .delay_us       = 1,
+       .bypass_index   = 4, /* index of pll-periph0 */
+};
+
+static int sun20i_d1_ccu_probe(struct platform_device *pdev)
+{
+       void __iomem *reg;
+       u32 val;
+       int i, ret;
+
+       reg = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
+
+       /* Enable the enable, LDO, and lock bits on all PLLs. */
+       for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
+               val = readl(reg + pll_regs[i]);
+               val |= BIT(31) | BIT(30) | BIT(29);
+               writel(val, reg + pll_regs[i]);
+       }
+
+       /* Force PLL_CPUX factor M to 0. */
+       val = readl(reg + SUN20I_D1_PLL_CPUX_REG);
+       val &= ~GENMASK(1, 0);
+       writel(val, reg + SUN20I_D1_PLL_CPUX_REG);
+
+       /*
+        * Force the output divider of video PLLs to 0.
+        *
+        * See the comment before pll-video0 definition for the reason.
+        */
+       for (i = 0; i < ARRAY_SIZE(pll_video_regs); i++) {
+               val = readl(reg + pll_video_regs[i]);
+               val &= ~BIT(0);
+               writel(val, reg + pll_video_regs[i]);
+       }
+
+       /* Enforce m1 = 0, m0 = 0 for PLL_AUDIO0 */
+       val = readl(reg + SUN20I_D1_PLL_AUDIO0_REG);
+       val &= ~BIT(1) | BIT(0);
+       writel(val, reg + SUN20I_D1_PLL_AUDIO0_REG);
+
+       /* Force fanout-27M factor N to 0. */
+       val = readl(reg + SUN20I_D1_FANOUT_27M_REG);
+       val &= ~GENMASK(9, 8);
+       writel(val, reg + SUN20I_D1_FANOUT_27M_REG);
+
+       ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun20i_d1_ccu_desc);
+       if (ret)
+               return ret;
+
+       /* Reparent CPU during PLL CPUX rate changes */
+       ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
+                                 &sun20i_d1_riscv_nb);
+
+       return 0;
+}
+
+static const struct of_device_id sun20i_d1_ccu_ids[] = {
+       { .compatible = "allwinner,sun20i-d1-ccu" },
+       { }
+};
+
+static struct platform_driver sun20i_d1_ccu_driver = {
+       .probe  = sun20i_d1_ccu_probe,
+       .driver = {
+               .name                   = "sun20i-d1-ccu",
+               .suppress_bind_attrs    = true,
+               .of_match_table         = sun20i_d1_ccu_ids,
+       },
+};
+module_platform_driver(sun20i_d1_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/ccu-sun20i-d1.h b/drivers/clk/sunxi-ng/ccu-sun20i-d1.h
new file mode 100644 (file)
index 0000000..e303176
--- /dev/null
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 frank@allwinnertech.com
+ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
+ */
+
+#ifndef _CCU_SUN20I_D1_H_
+#define _CCU_SUN20I_D1_H_
+
+#include <dt-bindings/clock/sun20i-d1-ccu.h>
+#include <dt-bindings/reset/sun20i-d1-ccu.h>
+
+#define CLK_NUMBER             (CLK_FANOUT2 + 1)
+
+#endif /* _CCU_SUN20I_D1_H_ */
index bd9a878..c19828f 100644 (file)
@@ -7,7 +7,9 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
 
 #include "ccu_common.h"
 #include "ccu_reset.h"
@@ -1425,18 +1427,19 @@ static const struct sunxi_ccu_desc sun7i_a20_ccu_desc = {
        .num_resets     = ARRAY_SIZE(sunxi_a10_a20_ccu_resets),
 };
 
-static void __init sun4i_ccu_init(struct device_node *node,
-                                 const struct sunxi_ccu_desc *desc)
+static int sun4i_a10_ccu_probe(struct platform_device *pdev)
 {
+       const struct sunxi_ccu_desc *desc;
        void __iomem *reg;
        u32 val;
 
-       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-       if (IS_ERR(reg)) {
-               pr_err("%s: Could not map the clock registers\n",
-                      of_node_full_name(node));
-               return;
-       }
+       desc = of_device_get_match_data(&pdev->dev);
+       if (!desc)
+               return -EINVAL;
+
+       reg = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
 
        val = readl(reg + SUN4I_PLL_AUDIO_REG);
 
@@ -1464,19 +1467,30 @@ static void __init sun4i_ccu_init(struct device_node *node,
        val &= ~GENMASK(7, 6);
        writel(val | (2 << 6), reg + SUN4I_AHB_REG);
 
-       of_sunxi_ccu_probe(node, reg, desc);
+       return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
 }
 
-static void __init sun4i_a10_ccu_setup(struct device_node *node)
-{
-       sun4i_ccu_init(node, &sun4i_a10_ccu_desc);
-}
-CLK_OF_DECLARE(sun4i_a10_ccu, "allwinner,sun4i-a10-ccu",
-              sun4i_a10_ccu_setup);
+static const struct of_device_id sun4i_a10_ccu_ids[] = {
+       {
+               .compatible = "allwinner,sun4i-a10-ccu",
+               .data = &sun4i_a10_ccu_desc,
+       },
+       {
+               .compatible = "allwinner,sun7i-a20-ccu",
+               .data = &sun7i_a20_ccu_desc,
+       },
+       { }
+};
 
-static void __init sun7i_a20_ccu_setup(struct device_node *node)
-{
-       sun4i_ccu_init(node, &sun7i_a20_ccu_desc);
-}
-CLK_OF_DECLARE(sun7i_a20_ccu, "allwinner,sun7i-a20-ccu",
-              sun7i_a20_ccu_setup);
+static struct platform_driver sun4i_a10_ccu_driver = {
+       .probe  = sun4i_a10_ccu_probe,
+       .driver = {
+               .name                   = "sun4i-a10-ccu",
+               .suppress_bind_attrs    = true,
+               .of_match_table         = sun4i_a10_ccu_ids,
+       },
+};
+module_platform_driver(sun4i_a10_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index 804729e..fddd6c8 100644 (file)
@@ -5,7 +5,6 @@
 
 #include <linux/clk-provider.h>
 #include <linux/module.h>
-#include <linux/of_address.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -213,3 +212,6 @@ static struct platform_driver sun50i_a100_r_ccu_driver = {
        },
 };
 module_platform_driver(sun50i_a100_r_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index 1d475d5..5f93b55 100644 (file)
@@ -6,7 +6,6 @@
 #include <linux/clk-provider.h>
 #include <linux/io.h>
 #include <linux/module.h>
-#include <linux/of_address.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -1275,3 +1274,6 @@ static struct platform_driver sun50i_a100_ccu_driver = {
        },
 };
 module_platform_driver(sun50i_a100_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index a8c5a92..4151918 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -980,4 +980,7 @@ static struct platform_driver sun50i_a64_ccu_driver = {
                .of_match_table = sun50i_a64_ccu_ids,
        },
 };
-builtin_platform_driver(sun50i_a64_ccu_driver);
+module_platform_driver(sun50i_a64_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index f30d7eb..712e103 100644 (file)
@@ -4,7 +4,8 @@
  */
 
 #include <linux/clk-provider.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -221,30 +222,43 @@ static const struct sunxi_ccu_desc sun50i_h616_r_ccu_desc = {
        .num_resets     = ARRAY_SIZE(sun50i_h616_r_ccu_resets),
 };
 
-static void __init sunxi_r_ccu_init(struct device_node *node,
-                                   const struct sunxi_ccu_desc *desc)
+static int sun50i_h6_r_ccu_probe(struct platform_device *pdev)
 {
+       const struct sunxi_ccu_desc *desc;
        void __iomem *reg;
 
-       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-       if (IS_ERR(reg)) {
-               pr_err("%pOF: Could not map the clock registers\n", node);
-               return;
-       }
+       desc = of_device_get_match_data(&pdev->dev);
+       if (!desc)
+               return -EINVAL;
 
-       of_sunxi_ccu_probe(node, reg, desc);
-}
+       reg = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
 
-static void __init sun50i_h6_r_ccu_setup(struct device_node *node)
-{
-       sunxi_r_ccu_init(node, &sun50i_h6_r_ccu_desc);
+       return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
 }
-CLK_OF_DECLARE(sun50i_h6_r_ccu, "allwinner,sun50i-h6-r-ccu",
-              sun50i_h6_r_ccu_setup);
 
-static void __init sun50i_h616_r_ccu_setup(struct device_node *node)
-{
-       sunxi_r_ccu_init(node, &sun50i_h616_r_ccu_desc);
-}
-CLK_OF_DECLARE(sun50i_h616_r_ccu, "allwinner,sun50i-h616-r-ccu",
-              sun50i_h616_r_ccu_setup);
+static const struct of_device_id sun50i_h6_r_ccu_ids[] = {
+       {
+               .compatible = "allwinner,sun50i-h6-r-ccu",
+               .data = &sun50i_h6_r_ccu_desc,
+       },
+       {
+               .compatible = "allwinner,sun50i-h616-r-ccu",
+               .data = &sun50i_h616_r_ccu_desc,
+       },
+       { }
+};
+
+static struct platform_driver sun50i_h6_r_ccu_driver = {
+       .probe  = sun50i_h6_r_ccu_probe,
+       .driver = {
+               .name                   = "sun50i-h6-r-ccu",
+               .suppress_bind_attrs    = true,
+               .of_match_table         = sun50i_h6_r_ccu_ids,
+       },
+};
+module_platform_driver(sun50i_h6_r_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index e5672c1..1a5e418 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -1254,4 +1254,7 @@ static struct platform_driver sun50i_h6_ccu_driver = {
                .of_match_table = sun50i_h6_ccu_ids,
        },
 };
-builtin_platform_driver(sun50i_h6_ccu_driver);
+module_platform_driver(sun50i_h6_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index 22eb180..49a2474 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -1082,17 +1082,15 @@ static const u32 usb2_clk_regs[] = {
        SUN50I_H616_USB3_CLK_REG,
 };
 
-static void __init sun50i_h616_ccu_setup(struct device_node *node)
+static int sun50i_h616_ccu_probe(struct platform_device *pdev)
 {
        void __iomem *reg;
        u32 val;
        int i;
 
-       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-       if (IS_ERR(reg)) {
-               pr_err("%pOF: Could not map clock registers\n", node);
-               return;
-       }
+       reg = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
 
        /* Enable the lock bits and the output enable bits on all PLLs */
        for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
@@ -1141,8 +1139,23 @@ static void __init sun50i_h616_ccu_setup(struct device_node *node)
        val |= BIT(24);
        writel(val, reg + SUN50I_H616_HDMI_CEC_CLK_REG);
 
-       of_sunxi_ccu_probe(node, reg, &sun50i_h616_ccu_desc);
+       return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h616_ccu_desc);
 }
 
-CLK_OF_DECLARE(sun50i_h616_ccu, "allwinner,sun50i-h616-ccu",
-              sun50i_h616_ccu_setup);
+static const struct of_device_id sun50i_h616_ccu_ids[] = {
+       { .compatible = "allwinner,sun50i-h616-ccu" },
+       { }
+};
+
+static struct platform_driver sun50i_h616_ccu_driver = {
+       .probe  = sun50i_h616_ccu_probe,
+       .driver = {
+               .name                   = "sun50i-h616-ccu",
+               .suppress_bind_attrs    = true,
+               .of_match_table         = sun50i_h616_ccu_ids,
+       },
+};
+module_platform_driver(sun50i_h616_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index 3df5c0b..0762def 100644 (file)
@@ -9,7 +9,8 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 
 #include "ccu_common.h"
 #include "ccu_reset.h"
@@ -1226,16 +1227,15 @@ static struct ccu_mux_nb sun6i_a31_cpu_nb = {
        .bypass_index   = 1, /* index of 24 MHz oscillator */
 };
 
-static void __init sun6i_a31_ccu_setup(struct device_node *node)
+static int sun6i_a31_ccu_probe(struct platform_device *pdev)
 {
        void __iomem *reg;
+       int ret;
        u32 val;
 
-       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-       if (IS_ERR(reg)) {
-               pr_err("%pOF: Could not map the clock registers\n", node);
-               return;
-       }
+       reg = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
 
        /* Force the PLL-Audio-1x divider to 1 */
        val = readl(reg + SUN6I_A31_PLL_AUDIO_REG);
@@ -1257,10 +1257,30 @@ static void __init sun6i_a31_ccu_setup(struct device_node *node)
        val |= 0x3 << 12;
        writel(val, reg + SUN6I_A31_AHB1_REG);
 
-       of_sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc);
+       ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun6i_a31_ccu_desc);
+       if (ret)
+               return ret;
 
        ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk,
                                  &sun6i_a31_cpu_nb);
+
+       return 0;
 }
-CLK_OF_DECLARE(sun6i_a31_ccu, "allwinner,sun6i-a31-ccu",
-              sun6i_a31_ccu_setup);
+
+static const struct of_device_id sun6i_a31_ccu_ids[] = {
+       { .compatible = "allwinner,sun6i-a31-ccu" },
+       { }
+};
+
+static struct platform_driver sun6i_a31_ccu_driver = {
+       .probe  = sun6i_a31_ccu_probe,
+       .driver = {
+               .name                   = "sun6i-a31-ccu",
+               .suppress_bind_attrs    = true,
+               .of_match_table         = sun6i_a31_ccu_ids,
+       },
+};
+module_platform_driver(sun6i_a31_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index 577bb23..e80cc38 100644 (file)
@@ -5,7 +5,8 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 
 #include "ccu_common.h"
 #include "ccu_reset.h"
@@ -724,16 +725,14 @@ static const struct sunxi_ccu_desc sun8i_a23_ccu_desc = {
        .num_resets     = ARRAY_SIZE(sun8i_a23_ccu_resets),
 };
 
-static void __init sun8i_a23_ccu_setup(struct device_node *node)
+static int sun8i_a23_ccu_probe(struct platform_device *pdev)
 {
        void __iomem *reg;
        u32 val;
 
-       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-       if (IS_ERR(reg)) {
-               pr_err("%pOF: Could not map the clock registers\n", node);
-               return;
-       }
+       reg = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
 
        /* Force the PLL-Audio-1x divider to 1 */
        val = readl(reg + SUN8I_A23_PLL_AUDIO_REG);
@@ -745,7 +744,23 @@ static void __init sun8i_a23_ccu_setup(struct device_node *node)
        val &= ~BIT(16);
        writel(val, reg + SUN8I_A23_PLL_MIPI_REG);
 
-       of_sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc);
+       return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_a23_ccu_desc);
 }
-CLK_OF_DECLARE(sun8i_a23_ccu, "allwinner,sun8i-a23-ccu",
-              sun8i_a23_ccu_setup);
+
+static const struct of_device_id sun8i_a23_ccu_ids[] = {
+       { .compatible = "allwinner,sun8i-a23-ccu" },
+       { }
+};
+
+static struct platform_driver sun8i_a23_ccu_driver = {
+       .probe  = sun8i_a23_ccu_probe,
+       .driver = {
+               .name                   = "sun8i-a23-ccu",
+               .suppress_bind_attrs    = true,
+               .of_match_table         = sun8i_a23_ccu_ids,
+       },
+};
+module_platform_driver(sun8i_a23_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index 8f65cd0..d12878a 100644 (file)
@@ -5,7 +5,8 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 
 #include "ccu_common.h"
 #include "ccu_reset.h"
@@ -784,16 +785,15 @@ static struct ccu_mux_nb sun8i_a33_cpu_nb = {
        .bypass_index   = 1, /* index of 24 MHz oscillator */
 };
 
-static void __init sun8i_a33_ccu_setup(struct device_node *node)
+static int sun8i_a33_ccu_probe(struct platform_device *pdev)
 {
        void __iomem *reg;
+       int ret;
        u32 val;
 
-       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-       if (IS_ERR(reg)) {
-               pr_err("%pOF: Could not map the clock registers\n", node);
-               return;
-       }
+       reg = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
 
        /* Force the PLL-Audio-1x divider to 1 */
        val = readl(reg + SUN8I_A33_PLL_AUDIO_REG);
@@ -805,7 +805,9 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node)
        val &= ~BIT(16);
        writel(val, reg + SUN8I_A33_PLL_MIPI_REG);
 
-       of_sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc);
+       ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_a33_ccu_desc);
+       if (ret)
+               return ret;
 
        /* Gate then ungate PLL CPU after any rate changes */
        ccu_pll_notifier_register(&sun8i_a33_pll_cpu_nb);
@@ -813,6 +815,24 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node)
        /* Reparent CPU during PLL CPU rate changes */
        ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
                                  &sun8i_a33_cpu_nb);
+
+       return 0;
 }
-CLK_OF_DECLARE(sun8i_a33_ccu, "allwinner,sun8i-a33-ccu",
-              sun8i_a33_ccu_setup);
+
+static const struct of_device_id sun8i_a33_ccu_ids[] = {
+       { .compatible = "allwinner,sun8i-a33-ccu" },
+       { }
+};
+
+static struct platform_driver sun8i_a33_ccu_driver = {
+       .probe  = sun8i_a33_ccu_probe,
+       .driver = {
+               .name                   = "sun8i-a33-ccu",
+               .suppress_bind_attrs    = true,
+               .of_match_table         = sun8i_a33_ccu_ids,
+       },
+};
+module_platform_driver(sun8i_a33_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index 3c310ae..76cbd9e 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -920,4 +920,7 @@ static struct platform_driver sun8i_a83t_ccu_driver = {
                .of_match_table = sun8i_a83t_ccu_ids,
        },
 };
-builtin_platform_driver(sun8i_a83t_ccu_driver);
+module_platform_driver(sun8i_a83t_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index 573b505..e7e3ddf 100644 (file)
@@ -5,8 +5,8 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/reset.h>
 
@@ -394,4 +394,7 @@ static struct platform_driver sunxi_de2_clk_driver = {
                .of_match_table = sunxi_de2_clk_ids,
        },
 };
-builtin_platform_driver(sunxi_de2_clk_driver);
+module_platform_driver(sunxi_de2_clk_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index d2fc290..e058cf6 100644 (file)
@@ -5,7 +5,9 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
 
 #include "ccu_common.h"
 #include "ccu_reset.h"
@@ -1137,24 +1139,29 @@ static struct ccu_mux_nb sun8i_h3_cpu_nb = {
        .bypass_index   = 1, /* index of 24 MHz oscillator */
 };
 
-static void __init sunxi_h3_h5_ccu_init(struct device_node *node,
-                                       const struct sunxi_ccu_desc *desc)
+static int sun8i_h3_ccu_probe(struct platform_device *pdev)
 {
+       const struct sunxi_ccu_desc *desc;
        void __iomem *reg;
+       int ret;
        u32 val;
 
-       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-       if (IS_ERR(reg)) {
-               pr_err("%pOF: Could not map the clock registers\n", node);
-               return;
-       }
+       desc = of_device_get_match_data(&pdev->dev);
+       if (!desc)
+               return -EINVAL;
+
+       reg = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
 
        /* Force the PLL-Audio-1x divider to 1 */
        val = readl(reg + SUN8I_H3_PLL_AUDIO_REG);
        val &= ~GENMASK(19, 16);
        writel(val | (0 << 16), reg + SUN8I_H3_PLL_AUDIO_REG);
 
-       of_sunxi_ccu_probe(node, reg, desc);
+       ret = devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
+       if (ret)
+               return ret;
 
        /* Gate then ungate PLL CPU after any rate changes */
        ccu_pll_notifier_register(&sun8i_h3_pll_cpu_nb);
@@ -1162,18 +1169,31 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node,
        /* Reparent CPU during PLL CPU rate changes */
        ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
                                  &sun8i_h3_cpu_nb);
-}
 
-static void __init sun8i_h3_ccu_setup(struct device_node *node)
-{
-       sunxi_h3_h5_ccu_init(node, &sun8i_h3_ccu_desc);
+       return 0;
 }
-CLK_OF_DECLARE(sun8i_h3_ccu, "allwinner,sun8i-h3-ccu",
-              sun8i_h3_ccu_setup);
 
-static void __init sun50i_h5_ccu_setup(struct device_node *node)
-{
-       sunxi_h3_h5_ccu_init(node, &sun50i_h5_ccu_desc);
-}
-CLK_OF_DECLARE(sun50i_h5_ccu, "allwinner,sun50i-h5-ccu",
-              sun50i_h5_ccu_setup);
+static const struct of_device_id sun8i_h3_ccu_ids[] = {
+       {
+               .compatible = "allwinner,sun8i-h3-ccu",
+               .data = &sun8i_h3_ccu_desc,
+       },
+       {
+               .compatible = "allwinner,sun50i-h5-ccu",
+               .data = &sun50i_h5_ccu_desc,
+       },
+       { }
+};
+
+static struct platform_driver sun8i_h3_ccu_driver = {
+       .probe  = sun8i_h3_ccu_probe,
+       .driver = {
+               .name                   = "sun8i-h3-ccu",
+               .suppress_bind_attrs    = true,
+               .of_match_table         = sun8i_h3_ccu_ids,
+       },
+};
+module_platform_driver(sun8i_h3_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index 9e754d1..5b7fab8 100644 (file)
@@ -4,7 +4,8 @@
  */
 
 #include <linux/clk-provider.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -254,37 +255,47 @@ static const struct sunxi_ccu_desc sun50i_a64_r_ccu_desc = {
        .num_resets     = ARRAY_SIZE(sun50i_a64_r_ccu_resets),
 };
 
-static void __init sunxi_r_ccu_init(struct device_node *node,
-                                   const struct sunxi_ccu_desc *desc)
+static int sun8i_r_ccu_probe(struct platform_device *pdev)
 {
+       const struct sunxi_ccu_desc *desc;
        void __iomem *reg;
 
-       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-       if (IS_ERR(reg)) {
-               pr_err("%pOF: Could not map the clock registers\n", node);
-               return;
-       }
+       desc = of_device_get_match_data(&pdev->dev);
+       if (!desc)
+               return -EINVAL;
 
-       of_sunxi_ccu_probe(node, reg, desc);
-}
+       reg = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
 
-static void __init sun8i_a83t_r_ccu_setup(struct device_node *node)
-{
-       sunxi_r_ccu_init(node, &sun8i_a83t_r_ccu_desc);
+       return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
 }
-CLK_OF_DECLARE(sun8i_a83t_r_ccu, "allwinner,sun8i-a83t-r-ccu",
-              sun8i_a83t_r_ccu_setup);
 
-static void __init sun8i_h3_r_ccu_setup(struct device_node *node)
-{
-       sunxi_r_ccu_init(node, &sun8i_h3_r_ccu_desc);
-}
-CLK_OF_DECLARE(sun8i_h3_r_ccu, "allwinner,sun8i-h3-r-ccu",
-              sun8i_h3_r_ccu_setup);
+static const struct of_device_id sun8i_r_ccu_ids[] = {
+       {
+               .compatible = "allwinner,sun8i-a83t-r-ccu",
+               .data = &sun8i_a83t_r_ccu_desc,
+       },
+       {
+               .compatible = "allwinner,sun8i-h3-r-ccu",
+               .data = &sun8i_h3_r_ccu_desc,
+       },
+       {
+               .compatible = "allwinner,sun50i-a64-r-ccu",
+               .data = &sun50i_a64_r_ccu_desc,
+       },
+       { }
+};
 
-static void __init sun50i_a64_r_ccu_setup(struct device_node *node)
-{
-       sunxi_r_ccu_init(node, &sun50i_a64_r_ccu_desc);
-}
-CLK_OF_DECLARE(sun50i_a64_r_ccu, "allwinner,sun50i-a64-r-ccu",
-              sun50i_a64_r_ccu_setup);
+static struct platform_driver sun8i_r_ccu_driver = {
+       .probe  = sun8i_r_ccu_probe,
+       .driver = {
+               .name                   = "sun8i-r-ccu",
+               .suppress_bind_attrs    = true,
+               .of_match_table         = sun8i_r_ccu_ids,
+       },
+};
+module_platform_driver(sun8i_r_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index 8bb18d9..31eca0d 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
@@ -1371,4 +1372,7 @@ static struct platform_driver sun8i_r40_ccu_driver = {
                .of_match_table = sun8i_r40_ccu_ids,
        },
 };
-builtin_platform_driver(sun8i_r40_ccu_driver);
+module_platform_driver(sun8i_r40_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index ce150f8..87f87d6 100644 (file)
@@ -8,7 +8,9 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
 
 #include "ccu_common.h"
 #include "ccu_reset.h"
@@ -805,38 +807,49 @@ static const struct sunxi_ccu_desc sun8i_v3_ccu_desc = {
        .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)
+static int sun8i_v3s_ccu_probe(struct platform_device *pdev)
 {
+       const struct sunxi_ccu_desc *desc;
        void __iomem *reg;
        u32 val;
 
-       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-       if (IS_ERR(reg)) {
-               pr_err("%pOF: Could not map the clock registers\n", node);
-               return;
-       }
+       desc = of_device_get_match_data(&pdev->dev);
+       if (!desc)
+               return -EINVAL;
+
+       reg = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
 
        /* Force the PLL-Audio-1x divider to 1 */
        val = readl(reg + SUN8I_V3S_PLL_AUDIO_REG);
        val &= ~GENMASK(19, 16);
        writel(val, reg + SUN8I_V3S_PLL_AUDIO_REG);
 
-       of_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);
+       return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
 }
 
-static void __init sun8i_v3_ccu_setup(struct device_node *node)
-{
-       sun8i_v3_v3s_ccu_init(node, &sun8i_v3_ccu_desc);
-}
+static const struct of_device_id sun8i_v3s_ccu_ids[] = {
+       {
+               .compatible = "allwinner,sun8i-v3-ccu",
+               .data = &sun8i_v3_ccu_desc,
+       },
+       {
+               .compatible = "allwinner,sun8i-v3s-ccu",
+               .data = &sun8i_v3s_ccu_desc,
+       },
+       { }
+};
 
-CLK_OF_DECLARE(sun8i_v3s_ccu, "allwinner,sun8i-v3s-ccu",
-              sun8i_v3s_ccu_setup);
+static struct platform_driver sun8i_v3s_ccu_driver = {
+       .probe  = sun8i_v3s_ccu_probe,
+       .driver = {
+               .name                   = "sun8i-v3s-ccu",
+               .suppress_bind_attrs    = true,
+               .of_match_table         = sun8i_v3s_ccu_ids,
+       },
+};
+module_platform_driver(sun8i_v3s_ccu_driver);
 
-CLK_OF_DECLARE(sun8i_v3_ccu, "allwinner,sun8i-v3-ccu",
-              sun8i_v3_ccu_setup);
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index 3cde261..f2fe0e1 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/reset.h>
 
@@ -270,4 +270,7 @@ static struct platform_driver sun9i_a80_de_clk_driver = {
                .of_match_table = sun9i_a80_de_clk_ids,
        },
 };
-builtin_platform_driver(sun9i_a80_de_clk_driver);
+module_platform_driver(sun9i_a80_de_clk_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index 0740e89..575ae4c 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -138,4 +138,7 @@ static struct platform_driver sun9i_a80_usb_clk_driver = {
                .of_match_table = sun9i_a80_usb_clk_ids,
        },
 };
-builtin_platform_driver(sun9i_a80_usb_clk_driver);
+module_platform_driver(sun9i_a80_usb_clk_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index d416af2..730fd8e 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -1245,4 +1245,7 @@ static struct platform_driver sun9i_a80_ccu_driver = {
                .of_match_table = sun9i_a80_ccu_ids,
        },
 };
-builtin_platform_driver(sun9i_a80_ccu_driver);
+module_platform_driver(sun9i_a80_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index 61ad7ee..ed097c4 100644 (file)
@@ -6,7 +6,8 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 
 #include "ccu_common.h"
 #include "ccu_reset.h"
@@ -522,23 +523,24 @@ static struct ccu_mux_nb suniv_cpu_nb = {
        .bypass_index   = 1, /* index of 24 MHz oscillator */
 };
 
-static void __init suniv_f1c100s_ccu_setup(struct device_node *node)
+static int suniv_f1c100s_ccu_probe(struct platform_device *pdev)
 {
        void __iomem *reg;
+       int ret;
        u32 val;
 
-       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-       if (IS_ERR(reg)) {
-               pr_err("%pOF: Could not map the clock registers\n", node);
-               return;
-       }
+       reg = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
 
        /* Force the PLL-Audio-1x divider to 4 */
        val = readl(reg + SUNIV_PLL_AUDIO_REG);
        val &= ~GENMASK(19, 16);
        writel(val | (3 << 16), reg + SUNIV_PLL_AUDIO_REG);
 
-       of_sunxi_ccu_probe(node, reg, &suniv_ccu_desc);
+       ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &suniv_ccu_desc);
+       if (ret)
+               return ret;
 
        /* Gate then ungate PLL CPU after any rate changes */
        ccu_pll_notifier_register(&suniv_pll_cpu_nb);
@@ -546,6 +548,24 @@ static void __init suniv_f1c100s_ccu_setup(struct device_node *node)
        /* Reparent CPU during PLL CPU rate changes */
        ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk,
                                  &suniv_cpu_nb);
+
+       return 0;
 }
-CLK_OF_DECLARE(suniv_f1c100s_ccu, "allwinner,suniv-f1c100s-ccu",
-              suniv_f1c100s_ccu_setup);
+
+static const struct of_device_id suniv_f1c100s_ccu_ids[] = {
+       { .compatible = "allwinner,suniv-f1c100s-ccu" },
+       { }
+};
+
+static struct platform_driver suniv_f1c100s_ccu_driver = {
+       .probe  = suniv_f1c100s_ccu_probe,
+       .driver = {
+               .name                   = "suniv-f1c100s-ccu",
+               .suppress_bind_attrs    = true,
+               .of_match_table         = suniv_f1c100s_ccu_ids,
+       },
+};
+module_platform_driver(suniv_f1c100s_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
index 31af8b6..8d28a7a 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/clk-provider.h>
 #include <linux/device.h>
 #include <linux/iopoll.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
 #include "ccu_common.h"
@@ -36,6 +37,7 @@ void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock)
 
        WARN_ON(readl_relaxed_poll_timeout(addr, reg, reg & lock, 100, 70000));
 }
+EXPORT_SYMBOL_NS_GPL(ccu_helper_wait_for_lock, SUNXI_CCU);
 
 /*
  * This clock notifier is called when the frequency of a PLL clock is
@@ -83,6 +85,7 @@ int ccu_pll_notifier_register(struct ccu_pll_nb *pll_nb)
        return clk_notifier_register(pll_nb->common->hw.clk,
                                     &pll_nb->clk_nb);
 }
+EXPORT_SYMBOL_NS_GPL(ccu_pll_notifier_register, SUNXI_CCU);
 
 static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
                           struct device_node *node, void __iomem *reg,
@@ -194,6 +197,7 @@ int devm_sunxi_ccu_probe(struct device *dev, void __iomem *reg,
 
        return 0;
 }
+EXPORT_SYMBOL_NS_GPL(devm_sunxi_ccu_probe, SUNXI_CCU);
 
 void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
                        const struct sunxi_ccu_desc *desc)
@@ -211,3 +215,5 @@ void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
                kfree(ccu);
        }
 }
+
+MODULE_LICENSE("GPL");
index 4c29708..cb10a3e 100644 (file)
@@ -141,3 +141,4 @@ const struct clk_ops ccu_div_ops = {
        .recalc_rate    = ccu_div_recalc_rate,
        .set_rate       = ccu_div_set_rate,
 };
+EXPORT_SYMBOL_NS_GPL(ccu_div_ops, SUNXI_CCU);
index 6682fde..948e2b0 100644 (file)
@@ -108,6 +108,22 @@ struct ccu_div {
                                      _shift, _width, _table, 0,        \
                                      _flags)
 
+#define SUNXI_CCU_DIV_TABLE_HW(_struct, _name, _parent, _reg,          \
+                              _shift, _width,                          \
+                              _table, _flags)                          \
+       struct ccu_div _struct = {                                      \
+               .div            = _SUNXI_CCU_DIV_TABLE(_shift, _width,  \
+                                                      _table),         \
+               .common = {                                             \
+                       .reg            = _reg,                         \
+                       .hw.init        = CLK_HW_INIT_HW(_name,         \
+                                                        _parent,       \
+                                                        &ccu_div_ops,  \
+                                                        _flags),       \
+               }                                                       \
+       }
+
+
 #define SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name,                        \
                                        _parents, _table,               \
                                        _reg,                           \
@@ -166,6 +182,68 @@ struct ccu_div {
        SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg,            \
                              _mshift, _mwidth, 0, _flags)
 
+#define SUNXI_CCU_M_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
+                                      _mshift, _mwidth,                \
+                                      _muxshift, _muxwidth,            \
+                                      _gate, _flags)                   \
+       struct ccu_div _struct = {                                      \
+               .enable = _gate,                                        \
+               .div    = _SUNXI_CCU_DIV(_mshift, _mwidth),             \
+               .mux    = _SUNXI_CCU_MUX(_muxshift, _muxwidth),         \
+               .common = {                                             \
+                       .reg            = _reg,                         \
+                       .hw.init        = CLK_HW_INIT_PARENTS_DATA(_name, \
+                                                                  _parents, \
+                                                                  &ccu_div_ops, \
+                                                                  _flags), \
+               },                                                      \
+       }
+
+#define SUNXI_CCU_M_DATA_WITH_MUX(_struct, _name, _parents, _reg,      \
+                                 _mshift, _mwidth,                     \
+                                 _muxshift, _muxwidth,                 \
+                                 _flags)                               \
+       SUNXI_CCU_M_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg,  \
+                                      _mshift, _mwidth,                \
+                                      _muxshift, _muxwidth,            \
+                                      0, _flags)
+
+#define SUNXI_CCU_M_HW_WITH_MUX_GATE(_struct, _name, _parents, _reg,   \
+                                    _mshift, _mwidth, _muxshift, _muxwidth, \
+                                    _gate, _flags)                     \
+       struct ccu_div _struct = {                                      \
+               .enable = _gate,                                        \
+               .div    = _SUNXI_CCU_DIV(_mshift, _mwidth),             \
+               .mux    = _SUNXI_CCU_MUX(_muxshift, _muxwidth),         \
+               .common = {                                             \
+                       .reg            = _reg,                         \
+                       .hw.init        = CLK_HW_INIT_PARENTS_HW(_name, \
+                                                                _parents, \
+                                                                &ccu_div_ops, \
+                                                                _flags), \
+               },                                                      \
+       }
+
+#define SUNXI_CCU_M_HWS_WITH_GATE(_struct, _name, _parent, _reg,       \
+                                 _mshift, _mwidth, _gate,              \
+                                 _flags)                               \
+       struct ccu_div _struct = {                                      \
+               .enable = _gate,                                        \
+               .div    = _SUNXI_CCU_DIV(_mshift, _mwidth),             \
+               .common = {                                             \
+                       .reg            = _reg,                         \
+                       .hw.init        = CLK_HW_INIT_HWS(_name,        \
+                                                         _parent,      \
+                                                         &ccu_div_ops, \
+                                                         _flags),      \
+               },                                                      \
+       }
+
+#define SUNXI_CCU_M_HWS(_struct, _name, _parent, _reg, _mshift,                \
+                       _mwidth, _flags)                                \
+       SUNXI_CCU_M_HWS_WITH_GATE(_struct, _name, _parent, _reg,        \
+                                 _mshift, _mwidth, 0, _flags)
+
 static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw)
 {
        struct ccu_common *common = hw_to_ccu_common(hw);
index 44fcded..b31f3ad 100644 (file)
@@ -18,6 +18,7 @@ bool ccu_frac_helper_is_enabled(struct ccu_common *common,
 
        return !(readl(common->base + common->reg) & cf->enable);
 }
+EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_is_enabled, SUNXI_CCU);
 
 void ccu_frac_helper_enable(struct ccu_common *common,
                            struct ccu_frac_internal *cf)
@@ -33,6 +34,7 @@ void ccu_frac_helper_enable(struct ccu_common *common,
        writel(reg & ~cf->enable, common->base + common->reg);
        spin_unlock_irqrestore(common->lock, flags);
 }
+EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_enable, SUNXI_CCU);
 
 void ccu_frac_helper_disable(struct ccu_common *common,
                             struct ccu_frac_internal *cf)
@@ -48,6 +50,7 @@ void ccu_frac_helper_disable(struct ccu_common *common,
        writel(reg | cf->enable, common->base + common->reg);
        spin_unlock_irqrestore(common->lock, flags);
 }
+EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_disable, SUNXI_CCU);
 
 bool ccu_frac_helper_has_rate(struct ccu_common *common,
                              struct ccu_frac_internal *cf,
@@ -58,6 +61,7 @@ bool ccu_frac_helper_has_rate(struct ccu_common *common,
 
        return (cf->rates[0] == rate) || (cf->rates[1] == rate);
 }
+EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_has_rate, SUNXI_CCU);
 
 unsigned long ccu_frac_helper_read_rate(struct ccu_common *common,
                                        struct ccu_frac_internal *cf)
@@ -79,6 +83,7 @@ unsigned long ccu_frac_helper_read_rate(struct ccu_common *common,
 
        return (reg & cf->select) ? cf->rates[1] : cf->rates[0];
 }
+EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_read_rate, SUNXI_CCU);
 
 int ccu_frac_helper_set_rate(struct ccu_common *common,
                             struct ccu_frac_internal *cf,
@@ -107,3 +112,4 @@ int ccu_frac_helper_set_rate(struct ccu_common *common,
 
        return 0;
 }
+EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_set_rate, SUNXI_CCU);
index 3d5ca09..a2115a2 100644 (file)
@@ -24,6 +24,7 @@ void ccu_gate_helper_disable(struct ccu_common *common, u32 gate)
 
        spin_unlock_irqrestore(common->lock, flags);
 }
+EXPORT_SYMBOL_NS_GPL(ccu_gate_helper_disable, SUNXI_CCU);
 
 static void ccu_gate_disable(struct clk_hw *hw)
 {
@@ -49,6 +50,7 @@ int ccu_gate_helper_enable(struct ccu_common *common, u32 gate)
 
        return 0;
 }
+EXPORT_SYMBOL_NS_GPL(ccu_gate_helper_enable, SUNXI_CCU);
 
 static int ccu_gate_enable(struct clk_hw *hw)
 {
@@ -64,6 +66,7 @@ int ccu_gate_helper_is_enabled(struct ccu_common *common, u32 gate)
 
        return readl(common->base + common->reg) & gate;
 }
+EXPORT_SYMBOL_NS_GPL(ccu_gate_helper_is_enabled, SUNXI_CCU);
 
 static int ccu_gate_is_enabled(struct clk_hw *hw)
 {
@@ -124,3 +127,4 @@ const struct clk_ops ccu_gate_ops = {
        .set_rate       = ccu_gate_set_rate,
        .recalc_rate    = ccu_gate_recalc_rate,
 };
+EXPORT_SYMBOL_NS_GPL(ccu_gate_ops, SUNXI_CCU);
index c386689..dc05ce0 100644 (file)
@@ -53,7 +53,7 @@ struct ccu_gate {
        }
 
 /*
- * The following two macros allow the re-use of the data structure
+ * The following macros allow the re-use of the data structure
  * holding the parent info.
  */
 #define SUNXI_CCU_GATE_HWS(_struct, _name, _parent, _reg, _gate, _flags) \
@@ -68,6 +68,21 @@ struct ccu_gate {
                }                                                       \
        }
 
+#define SUNXI_CCU_GATE_HWS_WITH_PREDIV(_struct, _name, _parent, _reg,  \
+                                      _gate, _prediv, _flags)          \
+       struct ccu_gate _struct = {                                     \
+               .enable = _gate,                                        \
+               .common = {                                             \
+                       .reg            = _reg,                         \
+                       .prediv         = _prediv,                      \
+                       .features       = CCU_FEATURE_ALL_PREDIV,       \
+                       .hw.init        = CLK_HW_INIT_HWS(_name,        \
+                                                         _parent,      \
+                                                         &ccu_gate_ops, \
+                                                         _flags),      \
+               }                                                       \
+       }
+
 #define SUNXI_CCU_GATE_DATA(_struct, _name, _data, _reg, _gate, _flags)        \
        struct ccu_gate _struct = {                                     \
                .enable = _gate,                                        \
@@ -81,6 +96,21 @@ struct ccu_gate {
                }                                                       \
        }
 
+#define SUNXI_CCU_GATE_DATA_WITH_PREDIV(_struct, _name, _parent, _reg, \
+                                       _gate, _prediv, _flags)         \
+       struct ccu_gate _struct = {                                     \
+               .enable = _gate,                                        \
+               .common = {                                             \
+                       .reg            = _reg,                         \
+                       .prediv         = _prediv,                      \
+                       .features       = CCU_FEATURE_ALL_PREDIV,       \
+                       .hw.init        = CLK_HW_INIT_PARENTS_DATA(_name, \
+                                                                  _parent, \
+                                                                  &ccu_gate_ops, \
+                                                                  _flags), \
+               }                                                       \
+       }
+
 static inline struct ccu_gate *hw_to_ccu_gate(struct clk_hw *hw)
 {
        struct ccu_common *common = hw_to_ccu_common(hw);
index 9d3a766..57cf2d6 100644 (file)
@@ -245,6 +245,7 @@ const struct clk_ops ccu_mp_ops = {
        .recalc_rate    = ccu_mp_recalc_rate,
        .set_rate       = ccu_mp_set_rate,
 };
+EXPORT_SYMBOL_NS_GPL(ccu_mp_ops, SUNXI_CCU);
 
 /*
  * Support for MMC timing mode switching
@@ -325,3 +326,4 @@ const struct clk_ops ccu_mp_mmc_ops = {
        .recalc_rate    = ccu_mp_mmc_recalc_rate,
        .set_rate       = ccu_mp_mmc_set_rate,
 };
+EXPORT_SYMBOL_NS_GPL(ccu_mp_mmc_ops, SUNXI_CCU);
index b392e0d..6e50f37 100644 (file)
@@ -82,6 +82,55 @@ struct ccu_mp {
                                   _muxshift, _muxwidth,                \
                                   0, _flags)
 
+#define SUNXI_CCU_MP_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg,        \
+                                       _mshift, _mwidth,               \
+                                       _pshift, _pwidth,               \
+                                       _muxshift, _muxwidth,           \
+                                       _gate, _flags)                  \
+       struct ccu_mp _struct = {                                       \
+               .enable = _gate,                                        \
+               .m      = _SUNXI_CCU_DIV(_mshift, _mwidth),             \
+               .p      = _SUNXI_CCU_DIV(_pshift, _pwidth),             \
+               .mux    = _SUNXI_CCU_MUX(_muxshift, _muxwidth),         \
+               .common = {                                             \
+                       .reg            = _reg,                         \
+                       .hw.init        = CLK_HW_INIT_PARENTS_DATA(_name, \
+                                                                  _parents, \
+                                                                  &ccu_mp_ops, \
+                                                                  _flags), \
+               }                                                       \
+       }
+
+#define SUNXI_CCU_MP_DATA_WITH_MUX(_struct, _name, _parents, _reg,     \
+                                  _mshift, _mwidth,                    \
+                                  _pshift, _pwidth,                    \
+                                  _muxshift, _muxwidth,                \
+                                  _flags)                              \
+       SUNXI_CCU_MP_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
+                                       _mshift, _mwidth,               \
+                                       _pshift, _pwidth,               \
+                                       _muxshift, _muxwidth,           \
+                                       0, _flags)
+
+#define SUNXI_CCU_MP_HW_WITH_MUX_GATE(_struct, _name, _parents, _reg,  \
+                                     _mshift, _mwidth,                 \
+                                     _pshift, _pwidth,                 \
+                                     _muxshift, _muxwidth,             \
+                                     _gate, _flags)                    \
+       struct ccu_mp _struct = {                                       \
+               .enable = _gate,                                        \
+               .m      = _SUNXI_CCU_DIV(_mshift, _mwidth),             \
+               .p      = _SUNXI_CCU_DIV(_pshift, _pwidth),             \
+               .mux    = _SUNXI_CCU_MUX(_muxshift, _muxwidth),         \
+               .common = {                                             \
+                       .reg            = _reg,                         \
+                       .hw.init        = CLK_HW_INIT_PARENTS_HW(_name, \
+                                                                _parents, \
+                                                                &ccu_mp_ops, \
+                                                                _flags), \
+               }                                                       \
+       }
+
 static inline struct ccu_mp *hw_to_ccu_mp(struct clk_hw *hw)
 {
        struct ccu_common *common = hw_to_ccu_common(hw);
index 7c8cf2e..7bee217 100644 (file)
@@ -170,3 +170,4 @@ const struct clk_ops ccu_mult_ops = {
        .recalc_rate    = ccu_mult_recalc_rate,
        .set_rate       = ccu_mult_set_rate,
 };
+EXPORT_SYMBOL_NS_GPL(ccu_mult_ops, SUNXI_CCU);
index 7d75da9..2306a1c 100644 (file)
@@ -64,6 +64,7 @@ unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common,
 {
        return parent_rate / ccu_mux_get_prediv(common, cm, parent_index);
 }
+EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_apply_prediv, SUNXI_CCU);
 
 static unsigned long ccu_mux_helper_unapply_prediv(struct ccu_common *common,
                                            struct ccu_mux_internal *cm,
@@ -152,6 +153,7 @@ out:
        req->rate = best_rate;
        return 0;
 }
+EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_determine_rate, SUNXI_CCU);
 
 u8 ccu_mux_helper_get_parent(struct ccu_common *common,
                             struct ccu_mux_internal *cm)
@@ -174,6 +176,7 @@ u8 ccu_mux_helper_get_parent(struct ccu_common *common,
 
        return parent;
 }
+EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_get_parent, SUNXI_CCU);
 
 int ccu_mux_helper_set_parent(struct ccu_common *common,
                              struct ccu_mux_internal *cm,
@@ -195,6 +198,7 @@ int ccu_mux_helper_set_parent(struct ccu_common *common,
 
        return 0;
 }
+EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_set_parent, SUNXI_CCU);
 
 static void ccu_mux_disable(struct clk_hw *hw)
 {
@@ -251,6 +255,7 @@ const struct clk_ops ccu_mux_ops = {
        .determine_rate = __clk_mux_determine_rate,
        .recalc_rate    = ccu_mux_recalc_rate,
 };
+EXPORT_SYMBOL_NS_GPL(ccu_mux_ops, SUNXI_CCU);
 
 /*
  * This clock notifier is called when the frequency of the of the parent
@@ -285,3 +290,4 @@ int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb)
 
        return clk_notifier_register(clk, &mux_nb->clk_nb);
 }
+EXPORT_SYMBOL_NS_GPL(ccu_mux_notifier_register, SUNXI_CCU);
index e31efc5..2c1811a 100644 (file)
@@ -72,6 +72,39 @@ struct ccu_mux {
        SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL,   \
                                      _reg, _shift, _width, 0, _flags)
 
+#define SUNXI_CCU_MUX_DATA_WITH_GATE(_struct, _name, _parents, _reg,   \
+                                    _shift, _width, _gate, _flags)     \
+       struct ccu_mux _struct = {                                      \
+               .enable = _gate,                                        \
+               .mux    = _SUNXI_CCU_MUX(_shift, _width),               \
+               .common = {                                             \
+                       .reg            = _reg,                         \
+                       .hw.init        = CLK_HW_INIT_PARENTS_DATA(_name, \
+                                                                  _parents, \
+                                                                  &ccu_mux_ops, \
+                                                                  _flags), \
+               }                                                       \
+       }
+
+#define SUNXI_CCU_MUX_DATA(_struct, _name, _parents, _reg,             \
+                     _shift, _width, _flags)                           \
+       SUNXI_CCU_MUX_DATA_WITH_GATE(_struct, _name, _parents, _reg,    \
+                                    _shift, _width, 0, _flags)
+
+#define SUNXI_CCU_MUX_HW_WITH_GATE(_struct, _name, _parents, _reg,     \
+                                  _shift, _width, _gate, _flags)       \
+       struct ccu_mux _struct = {                                      \
+               .enable = _gate,                                        \
+               .mux    = _SUNXI_CCU_MUX(_shift, _width),               \
+               .common = {                                             \
+                       .reg            = _reg,                         \
+                       .hw.init        = CLK_HW_INIT_PARENTS_HW(_name, \
+                                                                _parents, \
+                                                                &ccu_mux_ops, \
+                                                                _flags), \
+               }                                                       \
+       }
+
 static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw)
 {
        struct ccu_common *common = hw_to_ccu_common(hw);
index aee68b0..c4fb82a 100644 (file)
@@ -157,3 +157,4 @@ const struct clk_ops ccu_nk_ops = {
        .round_rate     = ccu_nk_round_rate,
        .set_rate       = ccu_nk_set_rate,
 };
+EXPORT_SYMBOL_NS_GPL(ccu_nk_ops, SUNXI_CCU);
index b9cfee0..67da2c1 100644 (file)
@@ -206,3 +206,4 @@ const struct clk_ops ccu_nkm_ops = {
        .recalc_rate    = ccu_nkm_recalc_rate,
        .set_rate       = ccu_nkm_set_rate,
 };
+EXPORT_SYMBOL_NS_GPL(ccu_nkm_ops, SUNXI_CCU);
index bda87b3..39413cb 100644 (file)
@@ -230,3 +230,4 @@ const struct clk_ops ccu_nkmp_ops = {
        .round_rate     = ccu_nkmp_round_rate,
        .set_rate       = ccu_nkmp_set_rate,
 };
+EXPORT_SYMBOL_NS_GPL(ccu_nkmp_ops, SUNXI_CCU);
index e6bcc0a..9ca9257 100644 (file)
@@ -238,3 +238,4 @@ const struct clk_ops ccu_nm_ops = {
        .round_rate     = ccu_nm_round_rate,
        .set_rate       = ccu_nm_set_rate,
 };
+EXPORT_SYMBOL_NS_GPL(ccu_nm_ops, SUNXI_CCU);
index 92ab8bd..e4cae2a 100644 (file)
@@ -121,3 +121,4 @@ const struct clk_ops ccu_phase_ops = {
        .get_phase      = ccu_phase_get_phase,
        .set_phase      = ccu_phase_set_phase,
 };
+EXPORT_SYMBOL_NS_GPL(ccu_phase_ops, SUNXI_CCU);
index 483100e..6577aa1 100644 (file)
@@ -75,3 +75,4 @@ const struct reset_control_ops ccu_reset_ops = {
        .reset          = ccu_reset_reset,
        .status         = ccu_reset_status,
 };
+EXPORT_SYMBOL_NS_GPL(ccu_reset_ops, SUNXI_CCU);
index 79581a1..41937ed 100644 (file)
@@ -20,6 +20,7 @@ bool ccu_sdm_helper_is_enabled(struct ccu_common *common,
 
        return !!(readl(common->base + sdm->tuning_reg) & sdm->tuning_enable);
 }
+EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_is_enabled, SUNXI_CCU);
 
 void ccu_sdm_helper_enable(struct ccu_common *common,
                           struct ccu_sdm_internal *sdm,
@@ -49,6 +50,7 @@ void ccu_sdm_helper_enable(struct ccu_common *common,
        writel(reg | sdm->enable, common->base + common->reg);
        spin_unlock_irqrestore(common->lock, flags);
 }
+EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_enable, SUNXI_CCU);
 
 void ccu_sdm_helper_disable(struct ccu_common *common,
                            struct ccu_sdm_internal *sdm)
@@ -69,6 +71,7 @@ void ccu_sdm_helper_disable(struct ccu_common *common,
        writel(reg & ~sdm->tuning_enable, common->base + sdm->tuning_reg);
        spin_unlock_irqrestore(common->lock, flags);
 }
+EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_disable, SUNXI_CCU);
 
 /*
  * Sigma delta modulation provides a way to do fractional-N frequency
@@ -102,6 +105,7 @@ bool ccu_sdm_helper_has_rate(struct ccu_common *common,
 
        return false;
 }
+EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_has_rate, SUNXI_CCU);
 
 unsigned long ccu_sdm_helper_read_rate(struct ccu_common *common,
                                       struct ccu_sdm_internal *sdm,
@@ -132,6 +136,7 @@ unsigned long ccu_sdm_helper_read_rate(struct ccu_common *common,
        /* We can't calculate the effective clock rate, so just fail. */
        return 0;
 }
+EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_read_rate, SUNXI_CCU);
 
 int ccu_sdm_helper_get_factors(struct ccu_common *common,
                               struct ccu_sdm_internal *sdm,
@@ -153,3 +158,4 @@ int ccu_sdm_helper_get_factors(struct ccu_common *common,
        /* nothing found */
        return -EINVAL;
 }
+EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_get_factors, SUNXI_CCU);
index 7b18168..a0715cd 100644 (file)
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-y                                  += clk.o
 obj-y                                  += clk-audio-sync.o
+obj-y                                  += clk-device.o
 obj-y                                  += clk-dfll.o
 obj-y                                  += clk-divider.o
 obj-y                                  += clk-periph.o
diff --git a/drivers/clk/tegra/clk-device.c b/drivers/clk/tegra/clk-device.c
new file mode 100644 (file)
index 0000000..c58beaf
--- /dev/null
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+
+#include <soc/tegra/common.h>
+
+#include "clk.h"
+
+/*
+ * This driver manages performance state of the core power domain for the
+ * independent PLLs and system clocks.  We created a virtual clock device
+ * for such clocks, see tegra_clk_dev_register().
+ */
+
+struct tegra_clk_device {
+       struct notifier_block clk_nb;
+       struct device *dev;
+       struct clk_hw *hw;
+       struct mutex lock;
+};
+
+static int tegra_clock_set_pd_state(struct tegra_clk_device *clk_dev,
+                                   unsigned long rate)
+{
+       struct device *dev = clk_dev->dev;
+       struct dev_pm_opp *opp;
+       unsigned int pstate;
+
+       opp = dev_pm_opp_find_freq_ceil(dev, &rate);
+       if (opp == ERR_PTR(-ERANGE)) {
+               /*
+                * Some clocks may be unused by a particular board and they
+                * may have uninitiated clock rate that is overly high.  In
+                * this case clock is expected to be disabled, but still we
+                * need to set up performance state of the power domain and
+                * not error out clk initialization.  A typical example is
+                * a PCIe clock on Android tablets.
+                */
+               dev_dbg(dev, "failed to find ceil OPP for %luHz\n", rate);
+               opp = dev_pm_opp_find_freq_floor(dev, &rate);
+       }
+
+       if (IS_ERR(opp)) {
+               dev_err(dev, "failed to find OPP for %luHz: %pe\n", rate, opp);
+               return PTR_ERR(opp);
+       }
+
+       pstate = dev_pm_opp_get_required_pstate(opp, 0);
+       dev_pm_opp_put(opp);
+
+       return dev_pm_genpd_set_performance_state(dev, pstate);
+}
+
+static int tegra_clock_change_notify(struct notifier_block *nb,
+                                    unsigned long msg, void *data)
+{
+       struct clk_notifier_data *cnd = data;
+       struct tegra_clk_device *clk_dev;
+       int err = 0;
+
+       clk_dev = container_of(nb, struct tegra_clk_device, clk_nb);
+
+       mutex_lock(&clk_dev->lock);
+       switch (msg) {
+       case PRE_RATE_CHANGE:
+               if (cnd->new_rate > cnd->old_rate)
+                       err = tegra_clock_set_pd_state(clk_dev, cnd->new_rate);
+               break;
+
+       case ABORT_RATE_CHANGE:
+               err = tegra_clock_set_pd_state(clk_dev, cnd->old_rate);
+               break;
+
+       case POST_RATE_CHANGE:
+               if (cnd->new_rate < cnd->old_rate)
+                       err = tegra_clock_set_pd_state(clk_dev, cnd->new_rate);
+               break;
+
+       default:
+               break;
+       }
+       mutex_unlock(&clk_dev->lock);
+
+       return notifier_from_errno(err);
+}
+
+static int tegra_clock_sync_pd_state(struct tegra_clk_device *clk_dev)
+{
+       unsigned long rate;
+       int ret;
+
+       mutex_lock(&clk_dev->lock);
+
+       rate = clk_hw_get_rate(clk_dev->hw);
+       ret = tegra_clock_set_pd_state(clk_dev, rate);
+
+       mutex_unlock(&clk_dev->lock);
+
+       return ret;
+}
+
+static int tegra_clock_probe(struct platform_device *pdev)
+{
+       struct tegra_core_opp_params opp_params = {};
+       struct tegra_clk_device *clk_dev;
+       struct device *dev = &pdev->dev;
+       struct clk *clk;
+       int err;
+
+       if (!dev->pm_domain)
+               return -EINVAL;
+
+       clk_dev = devm_kzalloc(dev, sizeof(*clk_dev), GFP_KERNEL);
+       if (!clk_dev)
+               return -ENOMEM;
+
+       clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+
+       clk_dev->dev = dev;
+       clk_dev->hw = __clk_get_hw(clk);
+       clk_dev->clk_nb.notifier_call = tegra_clock_change_notify;
+       mutex_init(&clk_dev->lock);
+
+       platform_set_drvdata(pdev, clk_dev);
+
+       /*
+        * Runtime PM was already enabled for this device by the parent clk
+        * driver and power domain state should be synced under clk_dev lock,
+        * hence we don't use the common OPP helper that initializes OPP
+        * state. For some clocks common OPP helper may fail to find ceil
+        * rate, it's handled by this driver.
+        */
+       err = devm_tegra_core_dev_init_opp_table(dev, &opp_params);
+       if (err)
+               return err;
+
+       err = clk_notifier_register(clk, &clk_dev->clk_nb);
+       if (err) {
+               dev_err(dev, "failed to register clk notifier: %d\n", err);
+               return err;
+       }
+
+       /*
+        * The driver is attaching to a potentially active/resumed clock, hence
+        * we need to sync the power domain performance state in a accordance to
+        * the clock rate if clock is resumed.
+        */
+       err = tegra_clock_sync_pd_state(clk_dev);
+       if (err)
+               goto unreg_clk;
+
+       return 0;
+
+unreg_clk:
+       clk_notifier_unregister(clk, &clk_dev->clk_nb);
+
+       return err;
+}
+
+/*
+ * Tegra GENPD driver enables clocks during NOIRQ phase. It can't be done
+ * for clocks served by this driver because runtime PM is unavailable in
+ * NOIRQ phase. We will keep clocks resumed during suspend to mitigate this
+ * problem. In practice this makes no difference from a power management
+ * perspective since voltage is kept at a nominal level during suspend anyways.
+ */
+static const struct dev_pm_ops tegra_clock_pm = {
+       SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_resume_and_get, pm_runtime_put)
+};
+
+static const struct of_device_id tegra_clock_match[] = {
+       { .compatible = "nvidia,tegra20-sclk" },
+       { .compatible = "nvidia,tegra30-sclk" },
+       { .compatible = "nvidia,tegra30-pllc" },
+       { .compatible = "nvidia,tegra30-plle" },
+       { .compatible = "nvidia,tegra30-pllm" },
+       { }
+};
+
+static struct platform_driver tegra_clock_driver = {
+       .driver = {
+               .name = "tegra-clock",
+               .of_match_table = tegra_clock_match,
+               .pm = &tegra_clock_pm,
+               .suppress_bind_attrs = true,
+       },
+       .probe = tegra_clock_probe,
+};
+builtin_platform_driver(tegra_clock_driver);
index eaa079c..100b5d9 100644 (file)
@@ -1914,7 +1914,7 @@ static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll,
        /* Data in .init is copied by clk_register(), so stack variable OK */
        pll->hw.init = &init;
 
-       return clk_register(NULL, &pll->hw);
+       return tegra_clk_dev_register(&pll->hw);
 }
 
 struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
index 6099c6e..a98a420 100644 (file)
@@ -226,7 +226,7 @@ struct clk *tegra_clk_register_super_mux(const char *name,
        /* Data in .init is copied by clk_register(), so stack variable OK */
        super->hw.init = &init;
 
-       clk = clk_register(NULL, &super->hw);
+       clk = tegra_clk_dev_register(&super->hw);
        if (IS_ERR(clk))
                kfree(super);
 
index bc9e47a..ef718c4 100644 (file)
@@ -1158,7 +1158,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
        { TEGRA114_CLK_XUSB_HS_SRC, TEGRA114_CLK_XUSB_SS_DIV2, 61200000, 0 },
        { TEGRA114_CLK_XUSB_FALCON_SRC, TEGRA114_CLK_PLL_P, 204000000, 0 },
        { TEGRA114_CLK_XUSB_HOST_SRC, TEGRA114_CLK_PLL_P, 102000000, 0 },
-       { TEGRA114_CLK_VDE, TEGRA114_CLK_CLK_MAX, 600000000, 0 },
+       { TEGRA114_CLK_VDE, TEGRA114_CLK_PLL_P, 408000000, 0 },
        { TEGRA114_CLK_SPDIF_IN_SYNC, TEGRA114_CLK_CLK_MAX, 24000000, 0 },
        { TEGRA114_CLK_I2S0_SYNC, TEGRA114_CLK_CLK_MAX, 24000000, 0 },
        { TEGRA114_CLK_I2S1_SYNC, TEGRA114_CLK_CLK_MAX, 24000000, 0 },
index 3664593..be3c334 100644 (file)
@@ -6,8 +6,11 @@
 #include <linux/io.h>
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
+#include <linux/init.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
 #include <linux/clk/tegra.h>
 #include <linux/delay.h>
 #include <dt-bindings/clock/tegra20-car.h>
@@ -414,7 +417,7 @@ static struct tegra_clk_pll_params pll_e_params = {
        .fixed_rate = 100000000,
 };
 
-static struct tegra_devclk devclks[] __initdata = {
+static struct tegra_devclk devclks[] = {
        { .con_id = "pll_c", .dt_id = TEGRA20_CLK_PLL_C },
        { .con_id = "pll_c_out1", .dt_id = TEGRA20_CLK_PLL_C_OUT1 },
        { .con_id = "pll_p", .dt_id = TEGRA20_CLK_PLL_P },
@@ -710,13 +713,6 @@ static void tegra20_super_clk_init(void)
                              NULL);
        clks[TEGRA20_CLK_CCLK] = clk;
 
-       /* SCLK */
-       clk = tegra_clk_register_super_mux("sclk", sclk_parents,
-                             ARRAY_SIZE(sclk_parents),
-                             CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
-                             clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL);
-       clks[TEGRA20_CLK_SCLK] = clk;
-
        /* twd */
        clk = clk_register_fixed_factor(NULL, "twd", "cclk", 0, 1, 4);
        clks[TEGRA20_CLK_TWD] = clk;
@@ -1014,7 +1010,7 @@ static struct tegra_cpu_car_ops tegra20_cpu_car_ops = {
 #endif
 };
 
-static struct tegra_clk_init_table init_table[] __initdata = {
+static struct tegra_clk_init_table init_table[] = {
        { TEGRA20_CLK_PLL_P, TEGRA20_CLK_CLK_MAX, 216000000, 1 },
        { TEGRA20_CLK_PLL_P_OUT1, TEGRA20_CLK_CLK_MAX, 28800000, 1 },
        { TEGRA20_CLK_PLL_P_OUT2, TEGRA20_CLK_CLK_MAX, 48000000, 1 },
@@ -1052,11 +1048,6 @@ static struct tegra_clk_init_table init_table[] __initdata = {
        { TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0 },
 };
 
-static void __init tegra20_clock_apply_init_table(void)
-{
-       tegra_init_from_table(init_table, clks, TEGRA20_CLK_CLK_MAX);
-}
-
 /*
  * Some clocks may be used by different drivers depending on the board
  * configuration.  List those here to register them twice in the clock lookup
@@ -1076,6 +1067,8 @@ static const struct of_device_id pmc_match[] __initconst = {
        { },
 };
 
+static bool tegra20_car_initialized;
+
 static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec,
                                               void *data)
 {
@@ -1083,6 +1076,16 @@ static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec,
        struct clk_hw *hw;
        struct clk *clk;
 
+       /*
+        * Timer clocks are needed early, the rest of the clocks shouldn't be
+        * available to device drivers until clock tree is fully initialized.
+        */
+       if (clkspec->args[0] != TEGRA20_CLK_RTC &&
+           clkspec->args[0] != TEGRA20_CLK_TWD &&
+           clkspec->args[0] != TEGRA20_CLK_TIMER &&
+           !tegra20_car_initialized)
+               return ERR_PTR(-EPROBE_DEFER);
+
        clk = of_clk_src_onecell_get(clkspec, data);
        if (IS_ERR(clk))
                return clk;
@@ -1149,10 +1152,48 @@ static void __init tegra20_clock_init(struct device_node *np)
        tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA20_CLK_CLK_MAX);
 
        tegra_add_of_provider(np, tegra20_clk_src_onecell_get);
-       tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
-
-       tegra_clk_apply_init_table = tegra20_clock_apply_init_table;
 
        tegra_cpu_car_ops = &tegra20_cpu_car_ops;
 }
-CLK_OF_DECLARE(tegra20, "nvidia,tegra20-car", tegra20_clock_init);
+CLK_OF_DECLARE_DRIVER(tegra20, "nvidia,tegra20-car", tegra20_clock_init);
+
+/*
+ * Clocks that use runtime PM can't be created at the tegra20_clock_init
+ * time because drivers' base isn't initialized yet, and thus platform
+ * devices can't be created for the clocks.  Hence we need to split the
+ * registration of the clocks into two phases.  The first phase registers
+ * essential clocks which don't require RPM and are actually used during
+ * early boot.  The second phase registers clocks which use RPM and this
+ * is done when device drivers' core API is ready.
+ */
+static int tegra20_car_probe(struct platform_device *pdev)
+{
+       struct clk *clk;
+
+       clk = tegra_clk_register_super_mux("sclk", sclk_parents,
+                             ARRAY_SIZE(sclk_parents),
+                             CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+                             clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL);
+       clks[TEGRA20_CLK_SCLK] = clk;
+
+       tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
+       tegra_init_from_table(init_table, clks, TEGRA20_CLK_CLK_MAX);
+       tegra20_car_initialized = true;
+
+       return 0;
+}
+
+static const struct of_device_id tegra20_car_match[] = {
+       { .compatible = "nvidia,tegra20-car" },
+       { }
+};
+
+static struct platform_driver tegra20_car_driver = {
+       .driver = {
+               .name = "tegra20-car",
+               .of_match_table = tegra20_car_match,
+               .suppress_bind_attrs = true,
+       },
+       .probe = tegra20_car_probe,
+};
+builtin_platform_driver(tegra20_car_driver);
index 64121bc..04b4961 100644 (file)
@@ -7,8 +7,11 @@
 #include <linux/delay.h>
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
+#include <linux/init.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
 #include <linux/clk/tegra.h>
 
 #include <soc/tegra/pmc.h>
@@ -532,7 +535,7 @@ static unsigned long tegra30_input_freq[] = {
        [12] = 26000000,
 };
 
-static struct tegra_devclk devclks[] __initdata = {
+static struct tegra_devclk devclks[] = {
        { .con_id = "pll_c", .dt_id = TEGRA30_CLK_PLL_C },
        { .con_id = "pll_c_out1", .dt_id = TEGRA30_CLK_PLL_C_OUT1 },
        { .con_id = "pll_p", .dt_id = TEGRA30_CLK_PLL_P },
@@ -812,11 +815,6 @@ static void __init tegra30_pll_init(void)
 {
        struct clk *clk;
 
-       /* PLLC */
-       clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, pmc_base, 0,
-                                    &pll_c_params, NULL);
-       clks[TEGRA30_CLK_PLL_C] = clk;
-
        /* PLLC_OUT1 */
        clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c",
                                clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
@@ -826,11 +824,6 @@ static void __init tegra30_pll_init(void)
                                0, NULL);
        clks[TEGRA30_CLK_PLL_C_OUT1] = clk;
 
-       /* PLLM */
-       clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base,
-                           CLK_SET_RATE_GATE, &pll_m_params, NULL);
-       clks[TEGRA30_CLK_PLL_M] = clk;
-
        /* PLLM_OUT1 */
        clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m",
                                clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
@@ -880,9 +873,6 @@ static void __init tegra30_pll_init(void)
                               ARRAY_SIZE(pll_e_parents),
                               CLK_SET_RATE_NO_REPARENT,
                               clk_base + PLLE_AUX, 2, 1, 0, NULL);
-       clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base, pmc_base,
-                            CLK_GET_RATE_NOCACHE, &pll_e_params, NULL);
-       clks[TEGRA30_CLK_PLL_E] = clk;
 }
 
 static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m",
@@ -971,14 +961,6 @@ static void __init tegra30_super_clk_init(void)
                              NULL);
        clks[TEGRA30_CLK_CCLK_LP] = clk;
 
-       /* SCLK */
-       clk = tegra_clk_register_super_mux("sclk", sclk_parents,
-                                 ARRAY_SIZE(sclk_parents),
-                                 CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
-                                 clk_base + SCLK_BURST_POLICY,
-                                 0, 4, 0, 0, NULL);
-       clks[TEGRA30_CLK_SCLK] = clk;
-
        /* twd */
        clk = clk_register_fixed_factor(NULL, "twd", "cclk_g",
                                        CLK_SET_RATE_PARENT, 1, 2);
@@ -1214,7 +1196,7 @@ static struct tegra_cpu_car_ops tegra30_cpu_car_ops = {
 #endif
 };
 
-static struct tegra_clk_init_table init_table[] __initdata = {
+static struct tegra_clk_init_table init_table[] = {
        { TEGRA30_CLK_UARTA, TEGRA30_CLK_PLL_P, 408000000, 0 },
        { TEGRA30_CLK_UARTB, TEGRA30_CLK_PLL_P, 408000000, 0 },
        { TEGRA30_CLK_UARTC, TEGRA30_CLK_PLL_P, 408000000, 0 },
@@ -1259,11 +1241,6 @@ static struct tegra_clk_init_table init_table[] __initdata = {
        { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 },
 };
 
-static void __init tegra30_clock_apply_init_table(void)
-{
-       tegra_init_from_table(init_table, clks, TEGRA30_CLK_CLK_MAX);
-}
-
 /*
  * Some clocks may be used by different drivers depending on the board
  * configuration.  List those here to register them twice in the clock lookup
@@ -1294,12 +1271,24 @@ static struct tegra_audio_clk_info tegra30_audio_plls[] = {
        { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" },
 };
 
+static bool tegra30_car_initialized;
+
 static struct clk *tegra30_clk_src_onecell_get(struct of_phandle_args *clkspec,
                                               void *data)
 {
        struct clk_hw *hw;
        struct clk *clk;
 
+       /*
+        * Timer clocks are needed early, the rest of the clocks shouldn't be
+        * available to device drivers until clock tree is fully initialized.
+        */
+       if (clkspec->args[0] != TEGRA30_CLK_RTC &&
+           clkspec->args[0] != TEGRA30_CLK_TWD &&
+           clkspec->args[0] != TEGRA30_CLK_TIMER &&
+           !tegra30_car_initialized)
+               return ERR_PTR(-EPROBE_DEFER);
+
        clk = of_clk_src_onecell_get(clkspec, data);
        if (IS_ERR(clk))
                return clk;
@@ -1357,10 +1346,75 @@ static void __init tegra30_clock_init(struct device_node *np)
        tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX);
 
        tegra_add_of_provider(np, tegra30_clk_src_onecell_get);
+
+       tegra_cpu_car_ops = &tegra30_cpu_car_ops;
+}
+CLK_OF_DECLARE_DRIVER(tegra30, "nvidia,tegra30-car", tegra30_clock_init);
+
+/*
+ * Clocks that use runtime PM can't be created at the tegra30_clock_init
+ * time because drivers' base isn't initialized yet, and thus platform
+ * devices can't be created for the clocks.  Hence we need to split the
+ * registration of the clocks into two phases.  The first phase registers
+ * essential clocks which don't require RPM and are actually used during
+ * early boot.  The second phase registers clocks which use RPM and this
+ * is done when device drivers' core API is ready.
+ */
+static int tegra30_car_probe(struct platform_device *pdev)
+{
+       struct clk *clk;
+
+       /* PLLC */
+       clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, pmc_base, 0,
+                                    &pll_c_params, NULL);
+       clks[TEGRA30_CLK_PLL_C] = clk;
+
+       /* PLLE */
+       clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base, pmc_base,
+                                     CLK_GET_RATE_NOCACHE, &pll_e_params, NULL);
+       clks[TEGRA30_CLK_PLL_E] = clk;
+
+       /* PLLM */
+       clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base,
+                                    CLK_SET_RATE_GATE, &pll_m_params, NULL);
+       clks[TEGRA30_CLK_PLL_M] = clk;
+
+       /* SCLK */
+       clk = tegra_clk_register_super_mux("sclk", sclk_parents,
+                                          ARRAY_SIZE(sclk_parents),
+                                          CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+                                          clk_base + SCLK_BURST_POLICY,
+                                          0, 4, 0, 0, NULL);
+       clks[TEGRA30_CLK_SCLK] = clk;
+
        tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
+       tegra_init_from_table(init_table, clks, TEGRA30_CLK_CLK_MAX);
+       tegra30_car_initialized = true;
 
-       tegra_clk_apply_init_table = tegra30_clock_apply_init_table;
+       return 0;
+}
 
-       tegra_cpu_car_ops = &tegra30_cpu_car_ops;
+static const struct of_device_id tegra30_car_match[] = {
+       { .compatible = "nvidia,tegra30-car" },
+       { }
+};
+
+static struct platform_driver tegra30_car_driver = {
+       .driver = {
+               .name = "tegra30-car",
+               .of_match_table = tegra30_car_match,
+               .suppress_bind_attrs = true,
+       },
+       .probe = tegra30_car_probe,
+};
+
+/*
+ * Clock driver must be registered before memory controller driver,
+ * which doesn't support deferred probing for today and is registered
+ * from arch init-level.
+ */
+static int tegra30_car_init(void)
+{
+       return platform_driver_register(&tegra30_car_driver);
 }
-CLK_OF_DECLARE(tegra30, "nvidia,tegra30-car", tegra30_clock_init);
+postcore_initcall(tegra30_car_init);
index f6cdce4..26bda45 100644 (file)
@@ -9,14 +9,19 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/clk/tegra.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/reset-controller.h>
+#include <linux/string.h>
 
 #include <soc/tegra/fuse.h>
 
 #include "clk.h"
 
 /* Global data of Tegra CPU CAR ops */
+static struct device_node *tegra_car_np;
 static struct tegra_cpu_car_ops dummy_car_ops;
 struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops;
 
@@ -261,8 +266,8 @@ void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
        }
 }
 
-void __init tegra_init_from_table(struct tegra_clk_init_table *tbl,
-                                 struct clk *clks[], int clk_max)
+void tegra_init_from_table(struct tegra_clk_init_table *tbl,
+                          struct clk *clks[], int clk_max)
 {
        struct clk *clk;
 
@@ -320,6 +325,8 @@ void __init tegra_add_of_provider(struct device_node *np,
 {
        int i;
 
+       tegra_car_np = np;
+
        for (i = 0; i < clk_num; i++) {
                if (IS_ERR(clks[i])) {
                        pr_err
@@ -348,7 +355,7 @@ void __init tegra_init_special_resets(unsigned int num,
        special_reset_deassert = deassert;
 }
 
-void __init tegra_register_devclks(struct tegra_devclk *dev_clks, int num)
+void tegra_register_devclks(struct tegra_devclk *dev_clks, int num)
 {
        int i;
 
@@ -372,6 +379,68 @@ struct clk ** __init tegra_lookup_dt_id(int clk_id,
                return NULL;
 }
 
+static struct device_node *tegra_clk_get_of_node(struct clk_hw *hw)
+{
+       struct device_node *np;
+       char *node_name;
+
+       node_name = kstrdup(hw->init->name, GFP_KERNEL);
+       if (!node_name)
+               return NULL;
+
+       strreplace(node_name, '_', '-');
+
+       for_each_child_of_node(tegra_car_np, np) {
+               if (!strcmp(np->name, node_name))
+                       break;
+       }
+
+       kfree(node_name);
+
+       return np;
+}
+
+struct clk *tegra_clk_dev_register(struct clk_hw *hw)
+{
+       struct platform_device *pdev, *parent;
+       const char *dev_name = NULL;
+       struct device *dev = NULL;
+       struct device_node *np;
+
+       np = tegra_clk_get_of_node(hw);
+
+       if (!of_device_is_available(np))
+               goto put_node;
+
+       dev_name = kasprintf(GFP_KERNEL, "tegra_clk_%s", hw->init->name);
+       if (!dev_name)
+               goto put_node;
+
+       parent = of_find_device_by_node(tegra_car_np);
+       if (parent) {
+               pdev = of_platform_device_create(np, dev_name, &parent->dev);
+               put_device(&parent->dev);
+
+               if (!pdev) {
+                       pr_err("%s: failed to create device for %pOF\n",
+                              __func__, np);
+                       goto free_name;
+               }
+
+               dev = &pdev->dev;
+               pm_runtime_enable(dev);
+       } else {
+               WARN(1, "failed to find device for %pOF\n", tegra_car_np);
+       }
+
+free_name:
+       kfree(dev_name);
+put_node:
+       of_node_put(np);
+
+       return clk_register(dev, hw);
+}
+
 tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
 
 static int __init tegra_clocks_apply_init_table(void)
index 0c3ba0c..5d80d8b 100644 (file)
@@ -927,4 +927,6 @@ struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter);
 struct clk *tegra210_clk_register_emc(struct device_node *np,
                                      void __iomem *regs);
 
+struct clk *tegra_clk_dev_register(struct clk_hw *hw);
+
 #endif /* TEGRA_CLK_H */
index b341cd9..962502c 100644 (file)
@@ -807,7 +807,7 @@ static int ti_adpll_init_registers(struct ti_adpll_data *d)
 
 static int ti_adpll_init_inputs(struct ti_adpll_data *d)
 {
-       const char *error = "need at least %i inputs";
+       static const char error[] = "need at least %i inputs";
        struct clk *clock;
        int nr_inputs;
 
diff --git a/drivers/clk/visconti/Kconfig b/drivers/clk/visconti/Kconfig
new file mode 100644 (file)
index 0000000..1661097
--- /dev/null
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config COMMON_CLK_VISCONTI
+       bool "Support for Toshiba Visconti5 ARM SoC clock controllers"
+       depends on ARCH_VISCONTI || COMPILE_TEST
+       default ARCH_VISCONTI
+       help
+         Support for the Toshiba Visconti5 ARM SoC clock controller.
+         Say Y if you want to include clock support.
diff --git a/drivers/clk/visconti/Makefile b/drivers/clk/visconti/Makefile
new file mode 100644 (file)
index 0000000..c1254fd
--- /dev/null
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-only
+# Makefile for Toshiba Visconti clock
+
+obj-y  += clkc.o pll.o reset.o
+obj-y  += pll-tmpv770x.o clkc-tmpv770x.o
diff --git a/drivers/clk/visconti/clkc-tmpv770x.c b/drivers/clk/visconti/clkc-tmpv770x.c
new file mode 100644 (file)
index 0000000..c2b2f41
--- /dev/null
@@ -0,0 +1,291 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Toshiba Visconti clock controller
+ *
+ * Copyright (c) 2021 TOSHIBA CORPORATION
+ * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/toshiba,tmpv770x.h>
+#include <dt-bindings/reset/toshiba,tmpv770x.h>
+
+#include "clkc.h"
+#include "reset.h"
+
+static DEFINE_SPINLOCK(tmpv770x_clk_lock);
+static DEFINE_SPINLOCK(tmpv770x_rst_lock);
+
+static const struct clk_parent_data clks_parent_data[] = {
+       { .fw_name = "pipll1", .name = "pipll1", },
+};
+
+static const struct clk_parent_data pietherplls_parent_data[] = {
+       { .fw_name = "pietherpll", .name = "pietherpll", },
+};
+
+static const struct visconti_fixed_clk fixed_clk_tables[] = {
+       /* PLL1 */
+       /* PICMPT0/1, PITSC, PIUWDT, PISWDT, PISBUS, PIPMU, PIGPMU, PITMU */
+       /* PIEMM, PIMISC, PIGCOMM, PIDCOMM, PIMBUS, PIGPIO, PIPGM */
+       { TMPV770X_CLK_PIPLL1_DIV4, "pipll1_div4", "pipll1", 0, 1, 4, },
+       /* PISBUS */
+       { TMPV770X_CLK_PIPLL1_DIV2, "pipll1_div2", "pipll1", 0, 1, 2, },
+       /* PICOBUS_CLK */
+       { TMPV770X_CLK_PIPLL1_DIV1, "pipll1_div1", "pipll1", 0, 1, 1, },
+       /* PIDNNPLL */
+       /* CONN_CLK, PIMBUS, PICRC0/1 */
+       { TMPV770X_CLK_PIDNNPLL_DIV1, "pidnnpll_div1", "pidnnpll", 0, 1, 1, },
+       { TMPV770X_CLK_PIREFCLK, "pirefclk", "osc2-clk", 0, 1, 1, },
+       { TMPV770X_CLK_WDTCLK, "wdtclk", "osc2-clk", 0, 1, 1, },
+};
+
+static const struct visconti_clk_gate_table pietherpll_clk_gate_tables[] = {
+       /* pietherpll */
+       { TMPV770X_CLK_PIETHER_2P5M, "piether_2p5m",
+               pietherplls_parent_data, ARRAY_SIZE(pietherplls_parent_data),
+               CLK_SET_RATE_PARENT, 0x34, 0x134, 4, 200,
+               TMPV770X_RESET_PIETHER_2P5M, },
+       { TMPV770X_CLK_PIETHER_25M, "piether_25m",
+               pietherplls_parent_data, ARRAY_SIZE(pietherplls_parent_data),
+               CLK_SET_RATE_PARENT, 0x34, 0x134, 5, 20,
+               TMPV770X_RESET_PIETHER_25M, },
+       { TMPV770X_CLK_PIETHER_50M, "piether_50m",
+               pietherplls_parent_data, ARRAY_SIZE(pietherplls_parent_data),
+               CLK_SET_RATE_PARENT, 0x34, 0x134, 6, 10,
+               TMPV770X_RESET_PIETHER_50M, },
+       { TMPV770X_CLK_PIETHER_125M, "piether_125m",
+               pietherplls_parent_data, ARRAY_SIZE(pietherplls_parent_data),
+               CLK_SET_RATE_PARENT, 0x34, 0x134, 7, 4,
+               TMPV770X_RESET_PIETHER_125M, },
+};
+
+static const struct visconti_clk_gate_table clk_gate_tables[] = {
+       { TMPV770X_CLK_HOX, "hox",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x4c, 0x14c, 0, 1,
+               TMPV770X_RESET_HOX, },
+       { TMPV770X_CLK_PCIE_MSTR, "pcie_mstr",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x38, 0x138, 0, 1,
+               TMPV770X_RESET_PCIE_MSTR, },
+       { TMPV770X_CLK_PCIE_AUX, "pcie_aux",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x38, 0x138, 1, 24,
+               TMPV770X_RESET_PCIE_AUX, },
+       { TMPV770X_CLK_PIINTC, "piintc",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               CLK_IGNORE_UNUSED, 0x8, 0x108, 0, 2, //FIX!!
+               TMPV770X_RESET_PIINTC,},
+       { TMPV770X_CLK_PIETHER_BUS, "piether_bus",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x34, 0x134, 0, 2,
+               TMPV770X_RESET_PIETHER_BUS, }, /* BUS_CLK */
+       { TMPV770X_CLK_PISPI0, "pispi0",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x28, 0x128, 0, 2,
+               TMPV770X_RESET_PISPI0, },
+       { TMPV770X_CLK_PISPI1, "pispi1",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x28, 0x128, 1, 2,
+               TMPV770X_RESET_PISPI1, },
+       { TMPV770X_CLK_PISPI2, "pispi2",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x28, 0x128, 2, 2,
+               TMPV770X_RESET_PISPI2, },
+       { TMPV770X_CLK_PISPI3, "pispi3",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x28, 0x128, 3, 2,
+               TMPV770X_RESET_PISPI3,},
+       { TMPV770X_CLK_PISPI4, "pispi4",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x28, 0x128, 4, 2,
+               TMPV770X_RESET_PISPI4, },
+       { TMPV770X_CLK_PISPI5, "pispi5",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x28, 0x128, 5, 2,
+               TMPV770X_RESET_PISPI5},
+       { TMPV770X_CLK_PISPI6, "pispi6",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x28, 0x128, 6, 2,
+               TMPV770X_RESET_PISPI6,},
+       { TMPV770X_CLK_PIUART0, "piuart0",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               //CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x2c, 0x12c, 0, 4,
+               0, 0x2c, 0x12c, 0, 4,
+               TMPV770X_RESET_PIUART0,},
+       { TMPV770X_CLK_PIUART1, "piuart1",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               //CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x2c, 0x12c, 1, 4,
+               0, 0x2c, 0x12c, 1, 4,
+               TMPV770X_RESET_PIUART1, },
+       { TMPV770X_CLK_PIUART2, "piuart2",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x2c, 0x12c, 2, 4,
+               TMPV770X_RESET_PIUART2, },
+       { TMPV770X_CLK_PIUART3, "piuart3",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x2c, 0x12c, 3, 4,
+               TMPV770X_RESET_PIUART3, },
+       { TMPV770X_CLK_PII2C0, "pii2c0",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x30, 0x130, 0, 4,
+               TMPV770X_RESET_PII2C0, },
+       { TMPV770X_CLK_PII2C1, "pii2c1",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x30, 0x130, 1, 4,
+               TMPV770X_RESET_PII2C1, },
+       { TMPV770X_CLK_PII2C2, "pii2c2",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x30, 0x130, 2, 4,
+               TMPV770X_RESET_PII2C2, },
+       { TMPV770X_CLK_PII2C3, "pii2c3",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x30, 0x130, 3, 4,
+               TMPV770X_RESET_PII2C3,},
+       { TMPV770X_CLK_PII2C4, "pii2c4",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x30, 0x130, 4, 4,
+               TMPV770X_RESET_PII2C4, },
+       { TMPV770X_CLK_PII2C5, "pii2c5",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x30, 0x130, 5, 4,
+               TMPV770X_RESET_PII2C5, },
+       { TMPV770X_CLK_PII2C6, "pii2c6",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x30, 0x130, 6, 4,
+               TMPV770X_RESET_PII2C6, },
+       { TMPV770X_CLK_PII2C7, "pii2c7",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x30, 0x130, 7, 4,
+               TMPV770X_RESET_PII2C7, },
+       { TMPV770X_CLK_PII2C8, "pii2c8",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x30, 0x130, 8, 4,
+               TMPV770X_RESET_PII2C8, },
+       /* PIPCMIF */
+       { TMPV770X_CLK_PIPCMIF, "pipcmif",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x64, 0x164, 0, 4,
+               TMPV770X_RESET_PIPCMIF, },
+       /* PISYSTEM */
+       { TMPV770X_CLK_WRCK, "wrck",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x68, 0x168, 9, 32,
+               -1, }, /* No reset */
+       { TMPV770X_CLK_PICKMON, "pickmon",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x10, 0x110, 8, 4,
+               TMPV770X_RESET_PICKMON, },
+       { TMPV770X_CLK_SBUSCLK, "sbusclk",
+               clks_parent_data, ARRAY_SIZE(clks_parent_data),
+               0, 0x14, 0x114, 0, 4,
+               TMPV770X_RESET_SBUSCLK, },
+};
+
+static const struct visconti_reset_data clk_reset_data[] = {
+       [TMPV770X_RESET_PIETHER_2P5M]   = { 0x434, 0x534, 4, },
+       [TMPV770X_RESET_PIETHER_25M]    = { 0x434, 0x534, 5, },
+       [TMPV770X_RESET_PIETHER_50M]    = { 0x434, 0x534, 6, },
+       [TMPV770X_RESET_PIETHER_125M]   = { 0x434, 0x534, 7, },
+       [TMPV770X_RESET_HOX]            = { 0x44c, 0x54c, 0, },
+       [TMPV770X_RESET_PCIE_MSTR]      = { 0x438, 0x538, 0, },
+       [TMPV770X_RESET_PCIE_AUX]       = { 0x438, 0x538, 1, },
+       [TMPV770X_RESET_PIINTC]         = { 0x408, 0x508, 0, },
+       [TMPV770X_RESET_PIETHER_BUS]    = { 0x434, 0x534, 0, },
+       [TMPV770X_RESET_PISPI0]         = { 0x428, 0x528, 0, },
+       [TMPV770X_RESET_PISPI1]         = { 0x428, 0x528, 1, },
+       [TMPV770X_RESET_PISPI2]         = { 0x428, 0x528, 2, },
+       [TMPV770X_RESET_PISPI3]         = { 0x428, 0x528, 3, },
+       [TMPV770X_RESET_PISPI4]         = { 0x428, 0x528, 4, },
+       [TMPV770X_RESET_PISPI5]         = { 0x428, 0x528, 5, },
+       [TMPV770X_RESET_PISPI6]         = { 0x428, 0x528, 6, },
+       [TMPV770X_RESET_PIUART0]        = { 0x42c, 0x52c, 0, },
+       [TMPV770X_RESET_PIUART1]        = { 0x42c, 0x52c, 1, },
+       [TMPV770X_RESET_PIUART2]        = { 0x42c, 0x52c, 2, },
+       [TMPV770X_RESET_PIUART3]        = { 0x42c, 0x52c, 3, },
+       [TMPV770X_RESET_PII2C0]         = { 0x430, 0x530, 0, },
+       [TMPV770X_RESET_PII2C1]         = { 0x430, 0x530, 1, },
+       [TMPV770X_RESET_PII2C2]         = { 0x430, 0x530, 2, },
+       [TMPV770X_RESET_PII2C3]         = { 0x430, 0x530, 3, },
+       [TMPV770X_RESET_PII2C4]         = { 0x430, 0x530, 4, },
+       [TMPV770X_RESET_PII2C5]         = { 0x430, 0x530, 5, },
+       [TMPV770X_RESET_PII2C6]         = { 0x430, 0x530, 6, },
+       [TMPV770X_RESET_PII2C7]         = { 0x430, 0x530, 7, },
+       [TMPV770X_RESET_PII2C8]         = { 0x430, 0x530, 8, },
+       [TMPV770X_RESET_PIPCMIF]        = { 0x464, 0x564, 0, },
+       [TMPV770X_RESET_PICKMON]        = { 0x410, 0x510, 8, },
+       [TMPV770X_RESET_SBUSCLK]        = { 0x414, 0x514, 0, },
+};
+
+static int visconti_clk_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct visconti_clk_provider *ctx;
+       struct device *dev = &pdev->dev;
+       struct regmap *regmap;
+       int ret, i;
+
+       regmap = syscon_node_to_regmap(np);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       ctx = visconti_init_clk(dev, regmap, TMPV770X_NR_CLK);
+       if (IS_ERR(ctx))
+               return PTR_ERR(ctx);
+
+       ret = visconti_register_reset_controller(dev, regmap, clk_reset_data,
+                                                TMPV770X_NR_RESET,
+                                                &visconti_reset_ops,
+                                                &tmpv770x_rst_lock);
+       if (ret) {
+               dev_err(dev, "Failed to register reset controller: %d\n", ret);
+               return ret;
+       }
+
+       for (i = 0; i < (ARRAY_SIZE(fixed_clk_tables)); i++)
+               ctx->clk_data.hws[fixed_clk_tables[i].id] =
+                       clk_hw_register_fixed_factor(NULL,
+                                                    fixed_clk_tables[i].name,
+                                                    fixed_clk_tables[i].parent,
+                                                    fixed_clk_tables[i].flag,
+                                                    fixed_clk_tables[i].mult,
+                                                    fixed_clk_tables[i].div);
+
+       ret = visconti_clk_register_gates(ctx, clk_gate_tables,
+                                   ARRAY_SIZE(clk_gate_tables), clk_reset_data,
+                                   &tmpv770x_clk_lock);
+       if (ret) {
+               dev_err(dev, "Failed to register main clock gate: %d\n", ret);
+               return ret;
+       }
+
+       ret = visconti_clk_register_gates(ctx, pietherpll_clk_gate_tables,
+                                   ARRAY_SIZE(pietherpll_clk_gate_tables),
+                                   clk_reset_data, &tmpv770x_clk_lock);
+       if (ret) {
+               dev_err(dev, "Failed to register pietherpll clock gate: %d\n", ret);
+               return ret;
+       }
+
+       return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &ctx->clk_data);
+}
+
+static const struct of_device_id visconti_clk_ids[] = {
+       { .compatible = "toshiba,tmpv7708-pismu", },
+       { }
+};
+
+static struct platform_driver visconti_clk_driver = {
+       .probe  = visconti_clk_probe,
+       .driver = {
+               .name   = "visconti-clk",
+               .of_match_table = visconti_clk_ids,
+       },
+};
+
+builtin_platform_driver(visconti_clk_driver);
diff --git a/drivers/clk/visconti/clkc.c b/drivers/clk/visconti/clkc.c
new file mode 100644 (file)
index 0000000..56a8a4f
--- /dev/null
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Toshiba Visconti clock controller
+ *
+ * Copyright (c) 2021 TOSHIBA CORPORATION
+ * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include "clkc.h"
+
+static inline struct visconti_clk_gate *to_visconti_clk_gate(struct clk_hw *hw)
+{
+       return container_of(hw, struct visconti_clk_gate, hw);
+}
+
+static int visconti_gate_clk_is_enabled(struct clk_hw *hw)
+{
+       struct visconti_clk_gate *gate = to_visconti_clk_gate(hw);
+       u32 clk = BIT(gate->ck_idx);
+       u32 val;
+
+       regmap_read(gate->regmap, gate->ckon_offset, &val);
+       return (val & clk) ? 1 : 0;
+}
+
+static void visconti_gate_clk_disable(struct clk_hw *hw)
+{
+       struct visconti_clk_gate *gate = to_visconti_clk_gate(hw);
+       u32 clk = BIT(gate->ck_idx);
+       unsigned long flags;
+
+       spin_lock_irqsave(gate->lock, flags);
+
+       if (!visconti_gate_clk_is_enabled(hw)) {
+               spin_unlock_irqrestore(gate->lock, flags);
+               return;
+       }
+
+       regmap_update_bits(gate->regmap, gate->ckoff_offset, clk, clk);
+       spin_unlock_irqrestore(gate->lock, flags);
+}
+
+static int visconti_gate_clk_enable(struct clk_hw *hw)
+{
+       struct visconti_clk_gate *gate = to_visconti_clk_gate(hw);
+       u32 clk = BIT(gate->ck_idx);
+       unsigned long flags;
+
+       spin_lock_irqsave(gate->lock, flags);
+       regmap_update_bits(gate->regmap, gate->ckon_offset, clk, clk);
+       spin_unlock_irqrestore(gate->lock, flags);
+
+       return 0;
+}
+
+static const struct clk_ops visconti_clk_gate_ops = {
+       .enable = visconti_gate_clk_enable,
+       .disable = visconti_gate_clk_disable,
+       .is_enabled = visconti_gate_clk_is_enabled,
+};
+
+static struct clk_hw *visconti_clk_register_gate(struct device *dev,
+                                                const char *name,
+                                                const char *parent_name,
+                                                struct regmap *regmap,
+                                                const struct visconti_clk_gate_table *clks,
+                                                u32    rson_offset,
+                                                u32    rsoff_offset,
+                                                u8     rs_idx,
+                                                spinlock_t *lock)
+{
+       struct visconti_clk_gate *gate;
+       struct clk_parent_data *pdata;
+       struct clk_init_data init;
+       struct clk_hw *hw;
+       int ret;
+
+       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return ERR_PTR(-ENOMEM);
+
+       pdata->name = pdata->fw_name = parent_name;
+
+       gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
+       if (!gate)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &visconti_clk_gate_ops;
+       init.flags = clks->flags;
+       init.parent_data = pdata;
+       init.num_parents = 1;
+
+       gate->regmap = regmap;
+       gate->ckon_offset = clks->ckon_offset;
+       gate->ckoff_offset = clks->ckoff_offset;
+       gate->ck_idx = clks->ck_idx;
+       gate->rson_offset = rson_offset;
+       gate->rsoff_offset = rsoff_offset;
+       gate->rs_idx = rs_idx;
+       gate->lock = lock;
+       gate->hw.init = &init;
+
+       hw = &gate->hw;
+       ret = devm_clk_hw_register(dev, hw);
+       if (ret)
+               hw = ERR_PTR(ret);
+
+       return hw;
+}
+
+int visconti_clk_register_gates(struct visconti_clk_provider *ctx,
+                               const struct visconti_clk_gate_table *clks,
+                               int num_gate,
+                               const struct visconti_reset_data *reset,
+                               spinlock_t *lock)
+{
+       struct device *dev = ctx->dev;
+       int i;
+
+       for (i = 0; i < num_gate; i++) {
+               const char *parent_div_name = clks[i].parent_data[0].name;
+               struct clk_parent_data *pdata;
+               u32 rson_offset, rsoff_offset;
+               struct clk_hw *gate_clk;
+               struct clk_hw *div_clk;
+               char *dev_name;
+               u8 rs_idx;
+
+               pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+               if (!pdata)
+                       return -ENOMEM;
+
+               dev_name = devm_kasprintf(dev, GFP_KERNEL, "%s_div", clks[i].name);
+               if (!dev_name)
+                       return -ENOMEM;
+
+               if (clks[i].rs_id >= 0) {
+                       rson_offset = reset[clks[i].rs_id].rson_offset;
+                       rsoff_offset = reset[clks[i].rs_id].rsoff_offset;
+                       rs_idx = reset[clks[i].rs_id].rs_idx;
+               } else {
+                       rson_offset = rsoff_offset = rs_idx = -1;
+               }
+
+               div_clk = devm_clk_hw_register_fixed_factor(dev,
+                                                           dev_name,
+                                                           parent_div_name,
+                                                           0, 1,
+                                                           clks[i].div);
+               if (IS_ERR(div_clk))
+                       return PTR_ERR(div_clk);
+
+               gate_clk = visconti_clk_register_gate(dev,
+                                                     clks[i].name,
+                                                     dev_name,
+                                                     ctx->regmap,
+                                                     &clks[i],
+                                                     rson_offset,
+                                                     rsoff_offset,
+                                                     rs_idx,
+                                                     lock);
+               if (IS_ERR(gate_clk)) {
+                       dev_err(dev, "%s: failed to register clock %s\n",
+                               __func__, clks[i].name);
+                       return PTR_ERR(gate_clk);
+               }
+
+               ctx->clk_data.hws[clks[i].id] = gate_clk;
+       }
+
+       return 0;
+}
+
+struct visconti_clk_provider *visconti_init_clk(struct device *dev,
+                                               struct regmap *regmap,
+                                               unsigned long nr_clks)
+{
+       struct visconti_clk_provider *ctx;
+       int i;
+
+       ctx = devm_kzalloc(dev, struct_size(ctx, clk_data.hws, nr_clks), GFP_KERNEL);
+       if (!ctx)
+               return ERR_PTR(-ENOMEM);
+
+       for (i = 0; i < nr_clks; ++i)
+               ctx->clk_data.hws[i] = ERR_PTR(-ENOENT);
+       ctx->clk_data.num = nr_clks;
+
+       ctx->dev = dev;
+       ctx->regmap = regmap;
+
+       return ctx;
+}
diff --git a/drivers/clk/visconti/clkc.h b/drivers/clk/visconti/clkc.h
new file mode 100644 (file)
index 0000000..09ed82f
--- /dev/null
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Toshiba Visconti clock controller
+ *
+ * Copyright (c) 2021 TOSHIBA CORPORATION
+ * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
+ */
+
+#ifndef _VISCONTI_CLKC_H_
+#define _VISCONTI_CLKC_H_
+
+#include <linux/mfd/syscon.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/delay.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include "reset.h"
+
+struct visconti_clk_provider {
+       struct device           *dev;
+       struct regmap           *regmap;
+       struct clk_hw_onecell_data clk_data;
+};
+
+struct visconti_clk_gate_table {
+       unsigned int    id;
+       const char      *name;
+       const struct clk_parent_data *parent_data;
+       u8              num_parents;
+       u8              flags;
+       u32             ckon_offset;
+       u32             ckoff_offset;
+       u8              ck_idx;
+       unsigned int    div;
+       u8              rs_id;
+};
+
+struct visconti_fixed_clk {
+       unsigned int    id;
+       const char      *name;
+       const char      *parent;
+       unsigned long   flag;
+       unsigned int    mult;
+       unsigned int    div;
+};
+
+struct visconti_clk_gate {
+       struct clk_hw   hw;
+       struct regmap   *regmap;
+       u32             ckon_offset;
+       u32             ckoff_offset;
+       u8              ck_idx;
+       u8              flags;
+       u32             rson_offset;
+       u32             rsoff_offset;
+       u8              rs_idx;
+       spinlock_t      *lock;
+};
+
+struct visconti_clk_provider *visconti_init_clk(struct device *dev,
+                                               struct regmap *regmap,
+                                               unsigned long nr_clks);
+int visconti_clk_register_gates(struct visconti_clk_provider *data,
+                                const struct visconti_clk_gate_table *clks,
+                                int num_gate,
+                                const struct visconti_reset_data *reset,
+                                spinlock_t *lock);
+#endif /* _VISCONTI_CLKC_H_ */
diff --git a/drivers/clk/visconti/pll-tmpv770x.c b/drivers/clk/visconti/pll-tmpv770x.c
new file mode 100644 (file)
index 0000000..8360ccf
--- /dev/null
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Toshiba Visconti PLL controller
+ *
+ * Copyright (c) 2021 TOSHIBA CORPORATION
+ * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/clock/toshiba,tmpv770x.h>
+
+#include "pll.h"
+
+static DEFINE_SPINLOCK(tmpv770x_pll_lock);
+
+static const struct visconti_pll_rate_table pipll0_rates[] __initconst = {
+       VISCONTI_PLL_RATE(840000000, 0x1, 0x0, 0x1, 0x54, 0x000000, 0x2, 0x1),
+       VISCONTI_PLL_RATE(780000000, 0x1, 0x0, 0x1, 0x4e, 0x000000, 0x2, 0x1),
+       VISCONTI_PLL_RATE(600000000, 0x1, 0x0, 0x1, 0x3c, 0x000000, 0x2, 0x1),
+       { /* sentinel */ },
+};
+
+static const struct visconti_pll_rate_table piddrcpll_rates[] __initconst = {
+       VISCONTI_PLL_RATE(780000000, 0x1, 0x0, 0x1, 0x4e, 0x000000, 0x2, 0x1),
+       VISCONTI_PLL_RATE(760000000, 0x1, 0x0, 0x1, 0x4c, 0x000000, 0x2, 0x1),
+       { /* sentinel */ },
+};
+
+static const struct visconti_pll_rate_table pivoifpll_rates[] __initconst = {
+       VISCONTI_PLL_RATE(165000000, 0x1, 0x0, 0x1, 0x42, 0x000000, 0x4, 0x2),
+       VISCONTI_PLL_RATE(148500000, 0x1, 0x1, 0x1, 0x3b, 0x666666, 0x4, 0x2),
+       VISCONTI_PLL_RATE(96000000, 0x1, 0x0, 0x1, 0x30, 0x000000, 0x5, 0x2),
+       VISCONTI_PLL_RATE(74250000, 0x1, 0x1, 0x1, 0x3b, 0x666666, 0x4, 0x4),
+       VISCONTI_PLL_RATE(54000000, 0x1, 0x0, 0x1, 0x36, 0x000000, 0x5, 0x4),
+       VISCONTI_PLL_RATE(48000000, 0x1, 0x0, 0x1, 0x30, 0x000000, 0x5, 0x4),
+       VISCONTI_PLL_RATE(35750000, 0x1, 0x1, 0x1, 0x32, 0x0ccccc, 0x7, 0x4),
+       { /* sentinel */ },
+};
+
+static const struct visconti_pll_rate_table piimgerpll_rates[] __initconst = {
+       VISCONTI_PLL_RATE(165000000, 0x1, 0x0, 0x1, 0x42, 0x000000, 0x4, 0x2),
+       VISCONTI_PLL_RATE(96000000, 0x1, 0x0, 0x1, 0x30, 0x000000, 0x5, 0x2),
+       VISCONTI_PLL_RATE(54000000, 0x1, 0x0, 0x1, 0x36, 0x000000, 0x5, 0x4),
+       VISCONTI_PLL_RATE(48000000, 0x1, 0x0, 0x1, 0x30, 0x000000, 0x5, 0x4),
+       { /* sentinel */ },
+};
+
+static const struct visconti_pll_info pll_info[] __initconst = {
+       { TMPV770X_PLL_PIPLL0, "pipll0", "osc2-clk", 0x0, pipll0_rates },
+       { TMPV770X_PLL_PIDDRCPLL, "piddrcpll", "osc2-clk", 0x500, piddrcpll_rates },
+       { TMPV770X_PLL_PIVOIFPLL, "pivoifpll", "osc2-clk", 0x600, pivoifpll_rates },
+       { TMPV770X_PLL_PIIMGERPLL, "piimgerpll", "osc2-clk", 0x700, piimgerpll_rates },
+};
+
+static void __init tmpv770x_setup_plls(struct device_node *np)
+{
+       struct visconti_pll_provider *ctx;
+       void __iomem *reg_base;
+
+       reg_base = of_iomap(np, 0);
+       if (!reg_base)
+               return;
+
+       ctx = visconti_init_pll(np, reg_base, TMPV770X_NR_PLL);
+       if (IS_ERR(ctx)) {
+               iounmap(reg_base);
+               return;
+       }
+
+       ctx->clk_data.hws[TMPV770X_PLL_PIPLL1] =
+               clk_hw_register_fixed_rate(NULL, "pipll1", NULL, 0, 600000000);
+       ctx->clk_data.hws[TMPV770X_PLL_PIDNNPLL] =
+               clk_hw_register_fixed_rate(NULL, "pidnnpll", NULL, 0, 500000000);
+       ctx->clk_data.hws[TMPV770X_PLL_PIETHERPLL] =
+               clk_hw_register_fixed_rate(NULL, "pietherpll", NULL, 0, 500000000);
+
+       visconti_register_plls(ctx, pll_info, ARRAY_SIZE(pll_info), &tmpv770x_pll_lock);
+}
+
+CLK_OF_DECLARE(tmpv770x_plls, "toshiba,tmpv7708-pipllct", tmpv770x_setup_plls);
diff --git a/drivers/clk/visconti/pll.c b/drivers/clk/visconti/pll.c
new file mode 100644 (file)
index 0000000..a2398bc
--- /dev/null
@@ -0,0 +1,340 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Toshiba Visconti PLL driver
+ *
+ * Copyright (c) 2021 TOSHIBA CORPORATION
+ * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+#include "pll.h"
+
+struct visconti_pll {
+       struct clk_hw   hw;
+       void __iomem    *pll_base;
+       spinlock_t      *lock;
+       unsigned long flags;
+       const struct visconti_pll_rate_table *rate_table;
+       size_t rate_count;
+       struct visconti_pll_provider *ctx;
+};
+
+#define PLL_CONF_REG           0x0000
+#define PLL_CTRL_REG           0x0004
+#define PLL_FRACMODE_REG       0x0010
+#define PLL_INTIN_REG          0x0014
+#define PLL_FRACIN_REG         0x0018
+#define PLL_REFDIV_REG         0x001c
+#define PLL_POSTDIV_REG                0x0020
+
+#define PLL_CONFIG_SEL         BIT(0)
+#define PLL_PLLEN              BIT(4)
+#define PLL_BYPASS             BIT(16)
+#define PLL_INTIN_MASK         GENMASK(11, 0)
+#define PLL_FRACIN_MASK                GENMASK(23, 0)
+#define PLL_REFDIV_MASK                GENMASK(5, 0)
+#define PLL_POSTDIV_MASK       GENMASK(2, 0)
+
+#define PLL0_FRACMODE_DACEN    BIT(4)
+#define PLL0_FRACMODE_DSMEN    BIT(0)
+
+#define PLL_CREATE_FRACMODE(table) (table->dacen << 4 | table->dsmen)
+#define PLL_CREATE_OSTDIV(table) (table->postdiv2 << 4 | table->postdiv1)
+
+static inline struct visconti_pll *to_visconti_pll(struct clk_hw *hw)
+{
+       return container_of(hw, struct visconti_pll, hw);
+}
+
+static void visconti_pll_get_params(struct visconti_pll *pll,
+                                   struct visconti_pll_rate_table *rate_table)
+{
+       u32 postdiv, val;
+
+       val = readl(pll->pll_base + PLL_FRACMODE_REG);
+
+       rate_table->dacen = FIELD_GET(PLL0_FRACMODE_DACEN, val);
+       rate_table->dsmen = FIELD_GET(PLL0_FRACMODE_DSMEN, val);
+
+       rate_table->fracin = readl(pll->pll_base + PLL_FRACIN_REG) & PLL_FRACIN_MASK;
+       rate_table->intin = readl(pll->pll_base + PLL_INTIN_REG) & PLL_INTIN_MASK;
+       rate_table->refdiv = readl(pll->pll_base + PLL_REFDIV_REG) & PLL_REFDIV_MASK;
+
+       postdiv = readl(pll->pll_base + PLL_POSTDIV_REG);
+       rate_table->postdiv1 = postdiv & PLL_POSTDIV_MASK;
+       rate_table->postdiv2 = (postdiv >> 4) & PLL_POSTDIV_MASK;
+}
+
+static const struct visconti_pll_rate_table *visconti_get_pll_settings(struct visconti_pll *pll,
+                                                                      unsigned long rate)
+{
+       const struct visconti_pll_rate_table *rate_table = pll->rate_table;
+       int i;
+
+       for (i = 0; i < pll->rate_count; i++)
+               if (rate == rate_table[i].rate)
+                       return &rate_table[i];
+
+       return NULL;
+}
+
+static unsigned long visconti_get_pll_rate_from_data(struct visconti_pll *pll,
+                                                    const struct visconti_pll_rate_table *rate)
+{
+       const struct visconti_pll_rate_table *rate_table = pll->rate_table;
+       int i;
+
+       for (i = 0; i < pll->rate_count; i++)
+               if (memcmp(&rate_table[i].dacen, &rate->dacen,
+                       sizeof(*rate) - sizeof(unsigned long)) == 0)
+                       return rate_table[i].rate;
+
+       /* set default */
+       return rate_table[0].rate;
+}
+
+static long visconti_pll_round_rate(struct clk_hw *hw,
+                                   unsigned long rate, unsigned long *prate)
+{
+       struct visconti_pll *pll = to_visconti_pll(hw);
+       const struct visconti_pll_rate_table *rate_table = pll->rate_table;
+       int i;
+
+       /* Assumming rate_table is in descending order */
+       for (i = 0; i < pll->rate_count; i++)
+               if (rate >= rate_table[i].rate)
+                       return rate_table[i].rate;
+
+       /* return minimum supported value */
+       return rate_table[i - 1].rate;
+}
+
+static unsigned long visconti_pll_recalc_rate(struct clk_hw *hw,
+                                             unsigned long parent_rate)
+{
+       struct visconti_pll *pll = to_visconti_pll(hw);
+       struct visconti_pll_rate_table rate_table;
+
+       memset(&rate_table, 0, sizeof(rate_table));
+       visconti_pll_get_params(pll, &rate_table);
+
+       return visconti_get_pll_rate_from_data(pll, &rate_table);
+}
+
+static int visconti_pll_set_params(struct visconti_pll *pll,
+                                  const struct visconti_pll_rate_table *rate_table)
+{
+       writel(PLL_CREATE_FRACMODE(rate_table), pll->pll_base + PLL_FRACMODE_REG);
+       writel(PLL_CREATE_OSTDIV(rate_table), pll->pll_base + PLL_POSTDIV_REG);
+       writel(rate_table->intin, pll->pll_base + PLL_INTIN_REG);
+       writel(rate_table->fracin, pll->pll_base + PLL_FRACIN_REG);
+       writel(rate_table->refdiv, pll->pll_base + PLL_REFDIV_REG);
+
+       return 0;
+}
+
+static int visconti_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+                           unsigned long parent_rate)
+{
+       struct visconti_pll *pll = to_visconti_pll(hw);
+       const struct visconti_pll_rate_table *rate_table;
+
+       rate_table = visconti_get_pll_settings(pll, rate);
+       if (!rate_table)
+               return -EINVAL;
+
+       return visconti_pll_set_params(pll, rate_table);
+}
+
+static int visconti_pll_is_enabled(struct clk_hw *hw)
+{
+       struct visconti_pll *pll = to_visconti_pll(hw);
+       u32 reg;
+
+       reg = readl(pll->pll_base + PLL_CTRL_REG);
+
+       return (reg & PLL_PLLEN);
+}
+
+static int visconti_pll_enable(struct clk_hw *hw)
+{
+       struct visconti_pll *pll = to_visconti_pll(hw);
+       const struct visconti_pll_rate_table *rate_table = pll->rate_table;
+       unsigned long flags;
+       u32 reg;
+
+       if (visconti_pll_is_enabled(hw))
+               return 0;
+
+       spin_lock_irqsave(pll->lock, flags);
+
+       writel(PLL_CONFIG_SEL, pll->pll_base + PLL_CONF_REG);
+
+       reg = readl(pll->pll_base + PLL_CTRL_REG);
+       reg |= PLL_BYPASS;
+       writel(reg, pll->pll_base + PLL_CTRL_REG);
+
+       visconti_pll_set_params(pll, &rate_table[0]);
+
+       reg = readl(pll->pll_base + PLL_CTRL_REG);
+       reg &= ~PLL_PLLEN;
+       writel(reg, pll->pll_base + PLL_CTRL_REG);
+
+       udelay(1);
+
+       reg = readl(pll->pll_base + PLL_CTRL_REG);
+       reg |= PLL_PLLEN;
+       writel(reg, pll->pll_base + PLL_CTRL_REG);
+
+       udelay(40);
+
+       reg = readl(pll->pll_base + PLL_CTRL_REG);
+       reg &= ~PLL_BYPASS;
+       writel(reg, pll->pll_base + PLL_CTRL_REG);
+
+       spin_unlock_irqrestore(pll->lock, flags);
+
+       return 0;
+}
+
+static void visconti_pll_disable(struct clk_hw *hw)
+{
+       struct visconti_pll *pll = to_visconti_pll(hw);
+       unsigned long flags;
+       u32 reg;
+
+       if (!visconti_pll_is_enabled(hw))
+               return;
+
+       spin_lock_irqsave(pll->lock, flags);
+
+       writel(PLL_CONFIG_SEL, pll->pll_base + PLL_CONF_REG);
+
+       reg = readl(pll->pll_base + PLL_CTRL_REG);
+       reg |= PLL_BYPASS;
+       writel(reg, pll->pll_base + PLL_CTRL_REG);
+
+       reg = readl(pll->pll_base + PLL_CTRL_REG);
+       reg &= ~PLL_PLLEN;
+       writel(reg, pll->pll_base + PLL_CTRL_REG);
+
+       spin_unlock_irqrestore(pll->lock, flags);
+}
+
+static const struct clk_ops visconti_pll_ops = {
+       .enable = visconti_pll_enable,
+       .disable = visconti_pll_disable,
+       .is_enabled = visconti_pll_is_enabled,
+       .round_rate = visconti_pll_round_rate,
+       .recalc_rate = visconti_pll_recalc_rate,
+       .set_rate = visconti_pll_set_rate,
+};
+
+static struct clk_hw *visconti_register_pll(struct visconti_pll_provider *ctx,
+                                           const char *name,
+                                           const char *parent_name,
+                                           int offset,
+                                           const struct visconti_pll_rate_table *rate_table,
+                                           spinlock_t *lock)
+{
+       struct clk_init_data init;
+       struct visconti_pll *pll;
+       struct clk *pll_clk;
+       struct clk_hw *pll_hw_clk;
+       size_t len;
+       int ret;
+
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.flags = CLK_IGNORE_UNUSED;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       for (len = 0; rate_table[len].rate != 0; )
+               len++;
+       pll->rate_count = len;
+       pll->rate_table = kmemdup(rate_table,
+                                 pll->rate_count * sizeof(struct visconti_pll_rate_table),
+                                 GFP_KERNEL);
+       WARN(!pll->rate_table, "%s: could not allocate rate table for %s\n", __func__, name);
+
+       init.ops = &visconti_pll_ops;
+       pll->hw.init = &init;
+       pll->pll_base = ctx->reg_base + offset;
+       pll->lock = lock;
+       pll->ctx = ctx;
+
+       pll_hw_clk = &pll->hw;
+       ret = clk_hw_register(NULL, &pll->hw);
+       if (ret) {
+               pr_err("failed to register pll clock %s : %ld\n", name, PTR_ERR(pll_clk));
+               kfree(pll);
+               pll_hw_clk = ERR_PTR(ret);
+       }
+
+       return pll_hw_clk;
+}
+
+static void visconti_pll_add_lookup(struct visconti_pll_provider *ctx,
+                                   struct clk_hw *hw_clk,
+                                   unsigned int id)
+{
+       if (id)
+               ctx->clk_data.hws[id] = hw_clk;
+}
+
+void __init visconti_register_plls(struct visconti_pll_provider *ctx,
+                                  const struct visconti_pll_info *list,
+                                  unsigned int nr_plls,
+                                  spinlock_t *lock)
+{
+       int idx;
+
+       for (idx = 0; idx < nr_plls; idx++, list++) {
+               struct clk_hw *clk;
+
+               clk = visconti_register_pll(ctx,
+                                           list->name,
+                                           list->parent,
+                                           list->base_reg,
+                                           list->rate_table,
+                                           lock);
+               if (IS_ERR(clk)) {
+                       pr_err("failed to register clock %s\n", list->name);
+                       continue;
+               }
+
+               visconti_pll_add_lookup(ctx, clk, list->id);
+       }
+}
+
+struct visconti_pll_provider * __init visconti_init_pll(struct device_node *np,
+                                                       void __iomem *base,
+                                                       unsigned long nr_plls)
+{
+       struct visconti_pll_provider *ctx;
+       int i;
+
+       ctx = kzalloc(struct_size(ctx, clk_data.hws, nr_plls), GFP_KERNEL);
+       if (!ctx)
+               return ERR_PTR(-ENOMEM);
+
+       for (i = 0; i < nr_plls; ++i)
+               ctx->clk_data.hws[i] = ERR_PTR(-ENOENT);
+
+       ctx->node = np;
+       ctx->reg_base = base;
+       ctx->clk_data.num = nr_plls;
+
+       return ctx;
+}
diff --git a/drivers/clk/visconti/pll.h b/drivers/clk/visconti/pll.h
new file mode 100644 (file)
index 0000000..16dae35
--- /dev/null
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 TOSHIBA CORPORATION
+ * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
+ */
+
+#ifndef _VISCONTI_PLL_H_
+#define _VISCONTI_PLL_H_
+
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/spinlock.h>
+
+struct visconti_pll_provider {
+       void __iomem *reg_base;
+       struct regmap *regmap;
+       struct clk_hw_onecell_data clk_data;
+       struct device_node *node;
+};
+
+#define VISCONTI_PLL_RATE(_rate, _dacen, _dsmen, \
+       _refdiv, _intin, _fracin, _postdiv1, _postdiv2) \
+{                              \
+       .rate = _rate,          \
+       .dacen = _dacen,        \
+       .dsmen = _dsmen,        \
+       .refdiv = _refdiv,      \
+       .intin = _intin,        \
+       .fracin = _fracin,      \
+       .postdiv1 = _postdiv1,  \
+       .postdiv2 = _postdiv2   \
+}
+
+struct visconti_pll_rate_table {
+       unsigned long rate;
+       unsigned int dacen;
+       unsigned int dsmen;
+       unsigned int refdiv;
+       unsigned long intin;
+       unsigned long fracin;
+       unsigned int postdiv1;
+       unsigned int postdiv2;
+};
+
+struct visconti_pll_info {
+       unsigned int id;
+       const char *name;
+       const char *parent;
+       unsigned long base_reg;
+       const struct visconti_pll_rate_table *rate_table;
+};
+
+struct visconti_pll_provider * __init visconti_init_pll(struct device_node *np,
+                                                       void __iomem *base,
+                                                       unsigned long nr_plls);
+void visconti_register_plls(struct visconti_pll_provider *ctx,
+                           const struct visconti_pll_info *list,
+                           unsigned int nr_plls, spinlock_t *lock);
+
+#endif /* _VISCONTI_PLL_H_ */
diff --git a/drivers/clk/visconti/reset.c b/drivers/clk/visconti/reset.c
new file mode 100644 (file)
index 0000000..e3c3d78
--- /dev/null
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Toshiba Visconti ARM SoC reset controller
+ *
+ * Copyright (c) 2021 TOSHIBA CORPORATION
+ * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
+ */
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#include "reset.h"
+
+static inline struct visconti_reset *to_visconti_reset(struct reset_controller_dev *rcdev)
+{
+       return container_of(rcdev, struct visconti_reset, rcdev);
+}
+
+static int visconti_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+       struct visconti_reset *reset = to_visconti_reset(rcdev);
+       const struct visconti_reset_data *data = &reset->resets[id];
+       u32 rst = BIT(data->rs_idx);
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(reset->lock, flags);
+       ret = regmap_update_bits(reset->regmap, data->rson_offset, rst, rst);
+       spin_unlock_irqrestore(reset->lock, flags);
+
+       return ret;
+}
+
+static int visconti_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+       struct visconti_reset *reset = to_visconti_reset(rcdev);
+       const struct visconti_reset_data *data = &reset->resets[id];
+       u32 rst = BIT(data->rs_idx);
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(reset->lock, flags);
+       ret = regmap_update_bits(reset->regmap, data->rsoff_offset, rst, rst);
+       spin_unlock_irqrestore(reset->lock, flags);
+
+       return ret;
+}
+
+static int visconti_reset_reset(struct reset_controller_dev *rcdev, unsigned long id)
+{
+       visconti_reset_assert(rcdev, id);
+       udelay(1);
+       visconti_reset_deassert(rcdev, id);
+
+       return 0;
+}
+
+static int visconti_reset_status(struct reset_controller_dev *rcdev, unsigned long id)
+{
+       struct visconti_reset *reset = to_visconti_reset(rcdev);
+       const struct visconti_reset_data *data = &reset->resets[id];
+       unsigned long flags;
+       u32 reg;
+       int ret;
+
+       spin_lock_irqsave(reset->lock, flags);
+       ret = regmap_read(reset->regmap, data->rson_offset, &reg);
+       spin_unlock_irqrestore(reset->lock, flags);
+       if (ret)
+               return ret;
+
+       return !(reg & data->rs_idx);
+}
+
+const struct reset_control_ops visconti_reset_ops = {
+       .assert         = visconti_reset_assert,
+       .deassert       = visconti_reset_deassert,
+       .reset          = visconti_reset_reset,
+       .status         = visconti_reset_status,
+};
+
+int visconti_register_reset_controller(struct device *dev,
+                                      struct regmap *regmap,
+                                      const struct visconti_reset_data *resets,
+                                      unsigned int num_resets,
+                                      const struct reset_control_ops *reset_ops,
+                                      spinlock_t *lock)
+{
+       struct visconti_reset *reset;
+
+       reset = devm_kzalloc(dev, sizeof(*reset), GFP_KERNEL);
+       if (!reset)
+               return -ENOMEM;
+
+       reset->regmap = regmap;
+       reset->resets = resets;
+       reset->rcdev.ops = reset_ops;
+       reset->rcdev.nr_resets = num_resets;
+       reset->rcdev.of_node = dev->of_node;
+       reset->lock = lock;
+
+       return devm_reset_controller_register(dev, &reset->rcdev);
+}
diff --git a/drivers/clk/visconti/reset.h b/drivers/clk/visconti/reset.h
new file mode 100644 (file)
index 0000000..229dffc
--- /dev/null
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Toshiba ARM SoC reset controller driver
+ *
+ * Copyright (c) 2021 TOSHIBA CORPORATION
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
+ */
+
+#ifndef _VISCONTI_RESET_H_
+#define _VISCONTI_RESET_H_
+
+#include <linux/reset-controller.h>
+
+struct visconti_reset_data {
+       u32     rson_offset;
+       u32     rsoff_offset;
+       u8      rs_idx;
+};
+
+struct visconti_reset {
+       struct reset_controller_dev rcdev;
+       struct regmap *regmap;
+       const struct visconti_reset_data *resets;
+       spinlock_t *lock;
+};
+
+extern const struct reset_control_ops visconti_reset_ops;
+
+int visconti_register_reset_controller(struct device *dev,
+                                      struct regmap *regmap,
+                                      const struct visconti_reset_data *resets,
+                                      unsigned int num_resets,
+                                      const struct reset_control_ops *reset_ops,
+                                      spinlock_t *lock);
+#endif /* _VISCONTI_RESET_H_ */
index 8f7c514..fdc060e 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: MIT
 /*
- * clock framework for AMD Stoney based clocks
+ * clock framework for AMD FCH controller block
  *
  * Copyright 2018 Advanced Micro Devices, Inc.
  */
@@ -8,6 +8,7 @@
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/clk-provider.h>
+#include <linux/pci.h>
 #include <linux/platform_data/clk-fch.h>
 #include <linux/platform_device.h>
 
 #define ST_CLK_GATE    3
 #define ST_MAX_CLKS    4
 
-#define RV_CLK_48M     0
-#define RV_CLK_GATE    1
-#define RV_MAX_CLKS    2
+#define CLK_48M_FIXED  0
+#define CLK_GATE_FIXED 1
+#define CLK_MAX_FIXED  2
+
+/* List of supported CPU ids for clk mux with 25Mhz clk support */
+#define AMD_CPU_ID_ST                  0x1576
 
 static const char * const clk_oscout1_parents[] = { "clk48MHz", "clk25MHz" };
 static struct clk_hw *hws[ST_MAX_CLKS];
 
+static const struct pci_device_id fch_pci_ids[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_ST) },
+       { }
+};
+
 static int fch_clk_probe(struct platform_device *pdev)
 {
        struct fch_clk_data *fch_data;
+       struct pci_dev *rdev;
 
        fch_data = dev_get_platdata(&pdev->dev);
        if (!fch_data || !fch_data->base)
                return -EINVAL;
 
-       if (!fch_data->is_rv) {
+       rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
+       if (!rdev) {
+               dev_err(&pdev->dev, "FCH device not found\n");
+               return -ENODEV;
+       }
+
+       if (pci_match_id(fch_pci_ids, rdev)) {
                hws[ST_CLK_48M] = clk_hw_register_fixed_rate(NULL, "clk48MHz",
                        NULL, 0, 48000000);
                hws[ST_CLK_25M] = clk_hw_register_fixed_rate(NULL, "clk25MHz",
@@ -59,34 +75,38 @@ static int fch_clk_probe(struct platform_device *pdev)
                        OSCCLKENB, CLK_GATE_SET_TO_DISABLE, NULL);
 
                devm_clk_hw_register_clkdev(&pdev->dev, hws[ST_CLK_GATE],
-                       "oscout1", NULL);
+                                           fch_data->name, NULL);
        } else {
-               hws[RV_CLK_48M] = clk_hw_register_fixed_rate(NULL, "clk48MHz",
+               hws[CLK_48M_FIXED] = clk_hw_register_fixed_rate(NULL, "clk48MHz",
                        NULL, 0, 48000000);
 
-               hws[RV_CLK_GATE] = clk_hw_register_gate(NULL, "oscout1",
+               hws[CLK_GATE_FIXED] = clk_hw_register_gate(NULL, "oscout1",
                        "clk48MHz", 0, fch_data->base + MISCCLKCNTL1,
-                       OSCCLKENB, CLK_GATE_SET_TO_DISABLE, NULL);
+                       OSCCLKENB, 0, NULL);
 
-               devm_clk_hw_register_clkdev(&pdev->dev, hws[RV_CLK_GATE],
-                       "oscout1", NULL);
+               devm_clk_hw_register_clkdev(&pdev->dev, hws[CLK_GATE_FIXED],
+                                           fch_data->name, NULL);
        }
 
+       pci_dev_put(rdev);
        return 0;
 }
 
 static int fch_clk_remove(struct platform_device *pdev)
 {
        int i, clks;
-       struct fch_clk_data *fch_data;
+       struct pci_dev *rdev;
 
-       fch_data = dev_get_platdata(&pdev->dev);
+       rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
+       if (!rdev)
+               return -ENODEV;
 
-       clks = fch_data->is_rv ? RV_MAX_CLKS : ST_MAX_CLKS;
+       clks = pci_match_id(fch_pci_ids, rdev) ? CLK_MAX_FIXED : ST_MAX_CLKS;
 
        for (i = 0; i < clks; i++)
                clk_hw_unregister(hws[i]);
 
+       pci_dev_put(rdev);
        return 0;
 }
 
index 54f4184..e5f8fb7 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/io.h>
 
 /**
- * struct zynq_pll
+ * struct zynq_pll - pll clock
  * @hw:                Handle between common and hardware-specific interfaces
  * @pll_ctrl:  PLL control register
  * @pll_status:        PLL status register
@@ -46,7 +46,7 @@ struct zynq_pll {
  * @hw:                Handle between common and hardware-specific interfaces
  * @rate:      Desired clock frequency
  * @prate:     Clock frequency of parent clock
- * Returns frequency closest to @rate the hardware can generate.
+ * Return:     frequency closest to @rate the hardware can generate.
  */
 static long zynq_pll_round_rate(struct clk_hw *hw, unsigned long rate,
                unsigned long *prate)
@@ -66,7 +66,7 @@ static long zynq_pll_round_rate(struct clk_hw *hw, unsigned long rate,
  * zynq_pll_recalc_rate() - Recalculate clock frequency
  * @hw:                        Handle between common and hardware-specific interfaces
  * @parent_rate:       Clock frequency of parent clock
- * Returns current clock frequency.
+ * Return:             current clock frequency.
  */
 static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw,
                unsigned long parent_rate)
@@ -87,7 +87,7 @@ static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw,
 /**
  * zynq_pll_is_enabled - Check if a clock is enabled
  * @hw:                Handle between common and hardware-specific interfaces
- * Returns 1 if the clock is enabled, 0 otherwise.
+ * Return:     1 if the clock is enabled, 0 otherwise.
  *
  * Not sure this is a good idea, but since disabled means bypassed for
  * this clock implementation we say we are always enabled.
@@ -110,7 +110,7 @@ static int zynq_pll_is_enabled(struct clk_hw *hw)
 /**
  * zynq_pll_enable - Enable clock
  * @hw:                Handle between common and hardware-specific interfaces
- * Returns 0 on success
+ * Return: 0 on success
  */
 static int zynq_pll_enable(struct clk_hw *hw)
 {
@@ -179,7 +179,7 @@ static const struct clk_ops zynq_pll_ops = {
  * @pll_status:        Pointer to PLL status register
  * @lock_index:        Bit index to this PLL's lock status bit in @pll_status
  * @lock:      Register lock
- * Returns handle to the registered clock.
+ * Return:     handle to the registered clock.
  */
 struct clk *clk_register_zynq_pll(const char *name, const char *parent,
                void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index,
index 5af8494..52b0b27 100644 (file)
@@ -966,6 +966,7 @@ config MMC_REALTEK_USB
 config MMC_SUNXI
        tristate "Allwinner sunxi SD/MMC Host Controller support"
        depends on ARCH_SUNXI || COMPILE_TEST
+       depends on SUNXI_CCU
        help
          This selects support for the SD/MMC Host Controller on
          Allwinner sunxi SoCs.
index 0c45e82..66d308e 100644 (file)
@@ -18,6 +18,8 @@ struct renesas_sdhi_scc {
        u32 tap_hs400_4tap;     /* sampling clock position for HS400 (4 TAP) */
 };
 
+#define SDHI_FLAG_NEED_CLKH_FALLBACK   BIT(0)
+
 struct renesas_sdhi_of_data {
        unsigned long tmio_flags;
        u32           tmio_ocr_mask;
@@ -31,6 +33,7 @@ struct renesas_sdhi_of_data {
        int taps_num;
        unsigned int max_blk_count;
        unsigned short max_segs;
+       unsigned long sdhi_flags;
 };
 
 #define SDHI_CALIB_TABLE_MAX 32
@@ -57,6 +60,7 @@ struct tmio_mmc_dma {
 
 struct renesas_sdhi {
        struct clk *clk;
+       struct clk *clkh;
        struct clk *clk_cd;
        struct tmio_mmc_data mmc_data;
        struct tmio_mmc_dma dma_priv;
index f5b2684..084c61b 100644 (file)
@@ -127,10 +127,12 @@ static int renesas_sdhi_clk_enable(struct tmio_mmc_host *host)
 }
 
 static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
-                                           unsigned int new_clock)
+                                           unsigned int wanted_clock)
 {
        struct renesas_sdhi *priv = host_to_priv(host);
+       struct clk *ref_clk = priv->clk;
        unsigned int freq, diff, best_freq = 0, diff_min = ~0;
+       unsigned int new_clock, clkh_shift = 0;
        int i;
 
        /*
@@ -141,6 +143,16 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
        if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2) || mmc_doing_tune(host->mmc))
                return clk_get_rate(priv->clk);
 
+       if (priv->clkh) {
+               bool use_4tap = priv->quirks && priv->quirks->hs400_4taps;
+               bool need_slow_clkh = (host->mmc->ios.timing == MMC_TIMING_UHS_SDR104) ||
+                                     (host->mmc->ios.timing == MMC_TIMING_MMC_HS400);
+               clkh_shift = use_4tap && need_slow_clkh ? 1 : 2;
+               ref_clk = priv->clkh;
+       }
+
+       new_clock = wanted_clock << clkh_shift;
+
        /*
         * We want the bus clock to be as close as possible to, but no
         * greater than, new_clock.  As we can divide by 1 << i for
@@ -148,11 +160,10 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
         * possible, but no greater than, new_clock << i.
         */
        for (i = min(9, ilog2(UINT_MAX / new_clock)); i >= 0; i--) {
-               freq = clk_round_rate(priv->clk, new_clock << i);
+               freq = clk_round_rate(ref_clk, new_clock << i);
                if (freq > (new_clock << i)) {
                        /* Too fast; look for a slightly slower option */
-                       freq = clk_round_rate(priv->clk,
-                                             (new_clock << i) / 4 * 3);
+                       freq = clk_round_rate(ref_clk, (new_clock << i) / 4 * 3);
                        if (freq > (new_clock << i))
                                continue;
                }
@@ -164,7 +175,10 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
                }
        }
 
-       clk_set_rate(priv->clk, best_freq);
+       clk_set_rate(ref_clk, best_freq);
+
+       if (priv->clkh)
+               clk_set_rate(priv->clk, best_freq >> clkh_shift);
 
        return clk_get_rate(priv->clk);
 }
@@ -904,11 +918,12 @@ int renesas_sdhi_probe(struct platform_device *pdev,
        dma_priv = &priv->dma_priv;
 
        priv->clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(priv->clk)) {
-               ret = PTR_ERR(priv->clk);
-               dev_err(&pdev->dev, "cannot get clock: %d\n", ret);
-               return ret;
-       }
+       if (IS_ERR(priv->clk))
+               return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk), "cannot get clock");
+
+       priv->clkh = devm_clk_get_optional(&pdev->dev, "clkh");
+       if (IS_ERR(priv->clkh))
+               return dev_err_probe(&pdev->dev, PTR_ERR(priv->clkh), "cannot get clkh");
 
        /*
         * Some controllers provide a 2nd clock just to run the internal card
@@ -921,9 +936,9 @@ int renesas_sdhi_probe(struct platform_device *pdev,
         * to the card detect circuit. That leaves us with if separate clocks
         * are presented, we must treat them both as virtually 1 clock.
         */
-       priv->clk_cd = devm_clk_get(&pdev->dev, "cd");
+       priv->clk_cd = devm_clk_get_optional(&pdev->dev, "cd");
        if (IS_ERR(priv->clk_cd))
-               priv->clk_cd = NULL;
+               return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cd), "cannot get cd clock");
 
        priv->pinctrl = devm_pinctrl_get(&pdev->dev);
        if (!IS_ERR(priv->pinctrl)) {
@@ -947,6 +962,10 @@ int renesas_sdhi_probe(struct platform_device *pdev,
                mmc_data->max_segs = of_data->max_segs;
                dma_priv->dma_buswidth = of_data->dma_buswidth;
                host->bus_shift = of_data->bus_shift;
+               /* Fallback for old DTs */
+               if (!priv->clkh && of_data->sdhi_flags & SDHI_FLAG_NEED_CLKH_FALLBACK)
+                       priv->clkh = clk_get_parent(clk_get_parent(priv->clk));
+
        }
 
        host->write16_hook      = renesas_sdhi_write16_hook;
@@ -1044,7 +1063,7 @@ int renesas_sdhi_probe(struct platform_device *pdev,
             host->mmc->caps2 & (MMC_CAP2_HS200_1_8V_SDR |
                                 MMC_CAP2_HS400_1_8V))) {
                const struct renesas_sdhi_scc *taps = of_data->taps;
-               bool use_4tap = priv->quirks && priv->quirks->hs400_4taps;
+               bool use_4tap = quirks && quirks->hs400_4taps;
                bool hit = false;
 
                for (i = 0; i < of_data->taps_num; i++) {
index 7660f7e..9d2c600 100644 (file)
@@ -125,6 +125,22 @@ static const struct renesas_sdhi_of_data of_data_rcar_gen3 = {
        /* DMAC can handle 32bit blk count but only 1 segment */
        .max_blk_count  = UINT_MAX / TMIO_MAX_BLK_SIZE,
        .max_segs       = 1,
+       .sdhi_flags     = SDHI_FLAG_NEED_CLKH_FALLBACK,
+};
+
+static const struct renesas_sdhi_of_data of_data_rcar_gen3_no_fallback = {
+       .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |
+                         TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2,
+       .capabilities   = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
+                         MMC_CAP_CMD23 | MMC_CAP_WAIT_WHILE_BUSY,
+       .capabilities2  = MMC_CAP2_NO_WRITE_PROTECT | MMC_CAP2_MERGE_CAPABLE,
+       .bus_shift      = 2,
+       .scc_offset     = 0x1000,
+       .taps           = rcar_gen3_scc_taps,
+       .taps_num       = ARRAY_SIZE(rcar_gen3_scc_taps),
+       /* DMAC can handle 32bit blk count but only 1 segment */
+       .max_blk_count  = UINT_MAX / TMIO_MAX_BLK_SIZE,
+       .max_segs       = 1,
 };
 
 static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
@@ -214,6 +230,10 @@ static const struct renesas_sdhi_of_data_with_quirks of_r8a77965_compatible = {
        .quirks = &sdhi_quirks_r8a77965,
 };
 
+static const struct renesas_sdhi_of_data_with_quirks of_r8a77970_compatible = {
+       .of_data = &of_data_rcar_gen3_no_fallback,
+};
+
 static const struct renesas_sdhi_of_data_with_quirks of_r8a77980_compatible = {
        .of_data = &of_data_rcar_gen3,
        .quirks = &sdhi_quirks_nohs400,
@@ -235,6 +255,7 @@ static const struct of_device_id renesas_sdhi_internal_dmac_of_match[] = {
        { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, },
        { .compatible = "renesas,sdhi-r8a77961", .data = &of_r8a77961_compatible, },
        { .compatible = "renesas,sdhi-r8a77965", .data = &of_r8a77965_compatible, },
+       { .compatible = "renesas,sdhi-r8a77970", .data = &of_r8a77970_compatible, },
        { .compatible = "renesas,sdhi-r8a77980", .data = &of_r8a77980_compatible, },
        { .compatible = "renesas,sdhi-r8a77990", .data = &of_r8a77990_compatible, },
        { .compatible = "renesas,rcar-gen3-sdhi", .data = &of_rcar_gen3_compatible, },
index 88ec396..acbfbab 100644 (file)
 #define CLK_ACLK400_MCUISP     395 /* Exynos4x12 only */
 #define CLK_MOUT_HDMI          396
 #define CLK_MOUT_MIXER         397
+#define CLK_MOUT_VPLLSRC       398
 
 /* gate clocks - ppmu */
 #define CLK_PPMULEFT           400
 #define CLK_DIV_C2C            458 /* Exynos4x12 only */
 #define CLK_DIV_GDL            459
 #define CLK_DIV_GDR            460
+#define CLK_DIV_CORE2          461
 
 /* must be greater than maximal clock id */
-#define CLK_NR_CLKS            461
+#define CLK_NR_CLKS            462
 
 /* Exynos4x12 ISP clocks */
 #define CLK_ISP_FIMC_ISP                1
index e259cc0..4680da7 100644 (file)
@@ -19,6 +19,7 @@
 #define CLK_FOUT_EPLL          7
 #define CLK_FOUT_VPLL          8
 #define CLK_ARM_CLK            9
+#define CLK_DIV_ARM2           10
 
 /* gate for special clocks (sclk) */
 #define CLK_SCLK_CAM_BAYER     128
 #define CLK_MOUT_ACLK300_DISP1_SUB     1027
 #define CLK_MOUT_APLL          1028
 #define CLK_MOUT_MPLL          1029
+#define CLK_MOUT_VPLLSRC       1030
 
 /* must be greater than maximal clock id */
-#define CLK_NR_CLKS            1030
+#define CLK_NR_CLKS            1031
 
 #endif /* _DT_BINDINGS_CLOCK_EXYNOS_5250_H */
diff --git a/include/dt-bindings/clock/exynos7885.h b/include/dt-bindings/clock/exynos7885.h
new file mode 100644 (file)
index 0000000..1f87016
--- /dev/null
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2021 Dávid Virág
+ *
+ * Device Tree binding constants for Exynos7885 clock controller.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_EXYNOS_7885_H
+#define _DT_BINDINGS_CLOCK_EXYNOS_7885_H
+
+/* CMU_TOP */
+#define CLK_FOUT_SHARED0_PLL           1
+#define CLK_FOUT_SHARED1_PLL           2
+#define CLK_DOUT_SHARED0_DIV2          3
+#define CLK_DOUT_SHARED0_DIV3          4
+#define CLK_DOUT_SHARED0_DIV4          5
+#define CLK_DOUT_SHARED0_DIV5          6
+#define CLK_DOUT_SHARED1_DIV2          7
+#define CLK_DOUT_SHARED1_DIV3          8
+#define CLK_DOUT_SHARED1_DIV4          9
+#define CLK_MOUT_CORE_BUS              10
+#define CLK_MOUT_CORE_CCI              11
+#define CLK_MOUT_CORE_G3D              12
+#define CLK_DOUT_CORE_BUS              13
+#define CLK_DOUT_CORE_CCI              14
+#define CLK_DOUT_CORE_G3D              15
+#define CLK_GOUT_CORE_BUS              16
+#define CLK_GOUT_CORE_CCI              17
+#define CLK_GOUT_CORE_G3D              18
+#define CLK_MOUT_PERI_BUS              19
+#define CLK_MOUT_PERI_SPI0             20
+#define CLK_MOUT_PERI_SPI1             21
+#define CLK_MOUT_PERI_UART0            22
+#define CLK_MOUT_PERI_UART1            23
+#define CLK_MOUT_PERI_UART2            24
+#define CLK_MOUT_PERI_USI0             25
+#define CLK_MOUT_PERI_USI1             26
+#define CLK_MOUT_PERI_USI2             27
+#define CLK_DOUT_PERI_BUS              28
+#define CLK_DOUT_PERI_SPI0             29
+#define CLK_DOUT_PERI_SPI1             30
+#define CLK_DOUT_PERI_UART0            31
+#define CLK_DOUT_PERI_UART1            32
+#define CLK_DOUT_PERI_UART2            33
+#define CLK_DOUT_PERI_USI0             34
+#define CLK_DOUT_PERI_USI1             35
+#define CLK_DOUT_PERI_USI2             36
+#define CLK_GOUT_PERI_BUS              37
+#define CLK_GOUT_PERI_SPI0             38
+#define CLK_GOUT_PERI_SPI1             39
+#define CLK_GOUT_PERI_UART0            40
+#define CLK_GOUT_PERI_UART1            41
+#define CLK_GOUT_PERI_UART2            42
+#define CLK_GOUT_PERI_USI0             43
+#define CLK_GOUT_PERI_USI1             44
+#define CLK_GOUT_PERI_USI2             45
+#define TOP_NR_CLK                     46
+
+/* CMU_CORE */
+#define CLK_MOUT_CORE_BUS_USER         1
+#define CLK_MOUT_CORE_CCI_USER         2
+#define CLK_MOUT_CORE_G3D_USER         3
+#define CLK_MOUT_CORE_GIC              4
+#define CLK_DOUT_CORE_BUSP             5
+#define CLK_GOUT_CCI_ACLK              6
+#define CLK_GOUT_GIC400_CLK            7
+#define CORE_NR_CLK                    8
+
+/* CMU_PERI */
+#define CLK_MOUT_PERI_BUS_USER         1
+#define CLK_MOUT_PERI_SPI0_USER                2
+#define CLK_MOUT_PERI_SPI1_USER                3
+#define CLK_MOUT_PERI_UART0_USER       4
+#define CLK_MOUT_PERI_UART1_USER       5
+#define CLK_MOUT_PERI_UART2_USER       6
+#define CLK_MOUT_PERI_USI0_USER                7
+#define CLK_MOUT_PERI_USI1_USER                8
+#define CLK_MOUT_PERI_USI2_USER                9
+#define CLK_GOUT_GPIO_TOP_PCLK         10
+#define CLK_GOUT_HSI2C0_PCLK           11
+#define CLK_GOUT_HSI2C1_PCLK           12
+#define CLK_GOUT_HSI2C2_PCLK           13
+#define CLK_GOUT_HSI2C3_PCLK           14
+#define CLK_GOUT_I2C0_PCLK             15
+#define CLK_GOUT_I2C1_PCLK             16
+#define CLK_GOUT_I2C2_PCLK             17
+#define CLK_GOUT_I2C3_PCLK             18
+#define CLK_GOUT_I2C4_PCLK             19
+#define CLK_GOUT_I2C5_PCLK             20
+#define CLK_GOUT_I2C6_PCLK             21
+#define CLK_GOUT_I2C7_PCLK             22
+#define CLK_GOUT_PWM_MOTOR_PCLK                23
+#define CLK_GOUT_SPI0_PCLK             24
+#define CLK_GOUT_SPI0_EXT_CLK          25
+#define CLK_GOUT_SPI1_PCLK             26
+#define CLK_GOUT_SPI1_EXT_CLK          27
+#define CLK_GOUT_UART0_EXT_UCLK                28
+#define CLK_GOUT_UART0_PCLK            29
+#define CLK_GOUT_UART1_EXT_UCLK                30
+#define CLK_GOUT_UART1_PCLK            31
+#define CLK_GOUT_UART2_EXT_UCLK                32
+#define CLK_GOUT_UART2_PCLK            33
+#define CLK_GOUT_USI0_PCLK             34
+#define CLK_GOUT_USI0_SCLK             35
+#define CLK_GOUT_USI1_PCLK             36
+#define CLK_GOUT_USI1_SCLK             37
+#define CLK_GOUT_USI2_PCLK             38
+#define CLK_GOUT_USI2_SCLK             39
+#define CLK_GOUT_MCT_PCLK              40
+#define CLK_GOUT_SYSREG_PERI_PCLK      41
+#define CLK_GOUT_WDT0_PCLK             42
+#define CLK_GOUT_WDT1_PCLK             43
+#define PERI_NR_CLK                    44
+
+#endif /* _DT_BINDINGS_CLOCK_EXYNOS_7885_H */
index 8999184..0b6a3c6 100644 (file)
 #define CLK_GOUT_PERI_BUS              43
 #define CLK_GOUT_PERI_UART             44
 #define CLK_GOUT_PERI_IP               45
-#define TOP_NR_CLK                     46
+#define CLK_MOUT_CLKCMU_APM_BUS                46
+#define CLK_DOUT_CLKCMU_APM_BUS                47
+#define CLK_GOUT_CLKCMU_APM_BUS                48
+#define TOP_NR_CLK                     49
+
+/* CMU_APM */
+#define CLK_RCO_I3C_PMIC               1
+#define OSCCLK_RCO_APM                 2
+#define CLK_RCO_APM__ALV               3
+#define CLK_DLL_DCO                    4
+#define CLK_MOUT_APM_BUS_USER          5
+#define CLK_MOUT_RCO_APM_I3C_USER      6
+#define CLK_MOUT_RCO_APM_USER          7
+#define CLK_MOUT_DLL_USER              8
+#define CLK_MOUT_CLKCMU_CHUB_BUS       9
+#define CLK_MOUT_APM_BUS               10
+#define CLK_MOUT_APM_I3C               11
+#define CLK_DOUT_CLKCMU_CHUB_BUS       12
+#define CLK_DOUT_APM_BUS               13
+#define CLK_DOUT_APM_I3C               14
+#define CLK_GOUT_CLKCMU_CMGP_BUS       15
+#define CLK_GOUT_CLKCMU_CHUB_BUS       16
+#define CLK_GOUT_RTC_PCLK              17
+#define CLK_GOUT_TOP_RTC_PCLK          18
+#define CLK_GOUT_I3C_PCLK              19
+#define CLK_GOUT_I3C_SCLK              20
+#define CLK_GOUT_SPEEDY_PCLK           21
+#define CLK_GOUT_GPIO_ALIVE_PCLK       22
+#define CLK_GOUT_PMU_ALIVE_PCLK                23
+#define CLK_GOUT_SYSREG_APM_PCLK       24
+#define APM_NR_CLK                     25
+
+/* CMU_CMGP */
+#define CLK_RCO_CMGP                   1
+#define CLK_MOUT_CMGP_ADC              2
+#define CLK_MOUT_CMGP_USI0             3
+#define CLK_MOUT_CMGP_USI1             4
+#define CLK_DOUT_CMGP_ADC              5
+#define CLK_DOUT_CMGP_USI0             6
+#define CLK_DOUT_CMGP_USI1             7
+#define CLK_GOUT_CMGP_ADC_S0_PCLK      8
+#define CLK_GOUT_CMGP_ADC_S1_PCLK      9
+#define CLK_GOUT_CMGP_GPIO_PCLK                10
+#define CLK_GOUT_CMGP_USI0_IPCLK       11
+#define CLK_GOUT_CMGP_USI0_PCLK                12
+#define CLK_GOUT_CMGP_USI1_IPCLK       13
+#define CLK_GOUT_CMGP_USI1_PCLK                14
+#define CLK_GOUT_SYSREG_CMGP_PCLK      15
+#define CMGP_NR_CLK                    16
 
 /* CMU_HSI */
 #define CLK_MOUT_HSI_BUS_USER          1
 #define CLK_GOUT_MMC_EMBD_SDCLKIN      10
 #define CLK_GOUT_SSS_ACLK              11
 #define CLK_GOUT_SSS_PCLK              12
-#define CORE_NR_CLK                    13
+#define CLK_GOUT_GPIO_CORE_PCLK                13
+#define CLK_GOUT_SYSREG_CORE_PCLK      14
+#define CORE_NR_CLK                    15
 
 /* CMU_DPU */
 #define CLK_MOUT_DPU_USER              1
index 43927a1..235c7a0 100644 (file)
 #define IMX8MP_CLK_AUDIO_AHB                   108
 #define IMX8MP_CLK_MIPI_DSI_ESC_RX             109
 #define IMX8MP_CLK_IPG_ROOT                    110
-#define IMX8MP_CLK_IPG_AUDIO_ROOT              111
 #define IMX8MP_CLK_DRAM_ALT                    112
 #define IMX8MP_CLK_DRAM_APB                    113
 #define IMX8MP_CLK_VPU_G1                      114
index 4bb2e19..9fb04eb 100644 (file)
@@ -50,5 +50,7 @@
 #define JZ4760_CLK_LPCLK_DIV   41
 #define JZ4760_CLK_TVE         42
 #define JZ4760_CLK_LPCLK       43
+#define JZ4760_CLK_MDMA                44
+#define JZ4760_CLK_BDMA                45
 
 #endif /* __DT_BINDINGS_CLOCK_JZ4760_CGU_H__ */
index d68a769..0b475e8 100644 (file)
@@ -54,5 +54,6 @@
 #define JZ4770_CLK_OTG_PHY     45
 #define JZ4770_CLK_EXT512      46
 #define JZ4770_CLK_RTC         47
+#define JZ4770_CLK_BDMA                48
 
 #endif /* __DT_BINDINGS_CLOCK_JZ4770_CGU_H__ */
diff --git a/include/dt-bindings/clock/microchip,lan966x.h b/include/dt-bindings/clock/microchip,lan966x.h
new file mode 100644 (file)
index 0000000..6f9d43d
--- /dev/null
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2021 Microchip Inc.
+ *
+ * Author: Kavyasree Kotagiri <kavyasree.kotagiri@microchip.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_LAN966X_H
+#define _DT_BINDINGS_CLK_LAN966X_H
+
+#define GCK_ID_QSPI0           0
+#define GCK_ID_QSPI1           1
+#define GCK_ID_QSPI2           2
+#define GCK_ID_SDMMC0          3
+#define GCK_ID_PI              4
+#define GCK_ID_MCAN0           5
+#define GCK_ID_MCAN1           6
+#define GCK_ID_FLEXCOM0                7
+#define GCK_ID_FLEXCOM1                8
+#define GCK_ID_FLEXCOM2                9
+#define GCK_ID_FLEXCOM3                10
+#define GCK_ID_FLEXCOM4                11
+#define GCK_ID_TIMER           12
+#define GCK_ID_USB_REFCLK      13
+
+/* Gate clocks */
+#define GCK_GATE_UHPHS         14
+#define GCK_GATE_UDPHS         15
+#define GCK_GATE_MCRAMC                16
+#define GCK_GATE_HMATRIX       17
+
+#define N_CLOCKS               18
+
+#endif
diff --git a/include/dt-bindings/clock/mt7986-clk.h b/include/dt-bindings/clock/mt7986-clk.h
new file mode 100644 (file)
index 0000000..5a9b169
--- /dev/null
@@ -0,0 +1,169 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT7986_H
+#define _DT_BINDINGS_CLK_MT7986_H
+
+/* APMIXEDSYS */
+
+#define CLK_APMIXED_ARMPLL             0
+#define CLK_APMIXED_NET2PLL            1
+#define CLK_APMIXED_MMPLL              2
+#define CLK_APMIXED_SGMPLL             3
+#define CLK_APMIXED_WEDMCUPLL          4
+#define CLK_APMIXED_NET1PLL            5
+#define CLK_APMIXED_MPLL               6
+#define CLK_APMIXED_APLL2              7
+
+/* TOPCKGEN */
+
+#define CLK_TOP_XTAL                   0
+#define CLK_TOP_XTAL_D2                        1
+#define CLK_TOP_RTC_32K                        2
+#define CLK_TOP_RTC_32P7K              3
+#define CLK_TOP_MPLL_D2                        4
+#define CLK_TOP_MPLL_D4                        5
+#define CLK_TOP_MPLL_D8                        6
+#define CLK_TOP_MPLL_D8_D2             7
+#define CLK_TOP_MPLL_D3_D2             8
+#define CLK_TOP_MMPLL_D2               9
+#define CLK_TOP_MMPLL_D4               10
+#define CLK_TOP_MMPLL_D8               11
+#define CLK_TOP_MMPLL_D8_D2            12
+#define CLK_TOP_MMPLL_D3_D8            13
+#define CLK_TOP_MMPLL_U2PHY            14
+#define CLK_TOP_APLL2_D4               15
+#define CLK_TOP_NET1PLL_D4             16
+#define CLK_TOP_NET1PLL_D5             17
+#define CLK_TOP_NET1PLL_D5_D2          18
+#define CLK_TOP_NET1PLL_D5_D4          19
+#define CLK_TOP_NET1PLL_D8_D2          20
+#define CLK_TOP_NET1PLL_D8_D4          21
+#define CLK_TOP_NET2PLL_D4             22
+#define CLK_TOP_NET2PLL_D4_D2          23
+#define CLK_TOP_NET2PLL_D3_D2          24
+#define CLK_TOP_WEDMCUPLL_D5_D2                25
+#define CLK_TOP_NFI1X_SEL              26
+#define CLK_TOP_SPINFI_SEL             27
+#define CLK_TOP_SPI_SEL                        28
+#define CLK_TOP_SPIM_MST_SEL           29
+#define CLK_TOP_UART_SEL               30
+#define CLK_TOP_PWM_SEL                        31
+#define CLK_TOP_I2C_SEL                        32
+#define CLK_TOP_PEXTP_TL_SEL           33
+#define CLK_TOP_EMMC_250M_SEL          34
+#define CLK_TOP_EMMC_416M_SEL          35
+#define CLK_TOP_F_26M_ADC_SEL          36
+#define CLK_TOP_DRAMC_SEL              37
+#define CLK_TOP_DRAMC_MD32_SEL         38
+#define CLK_TOP_SYSAXI_SEL             39
+#define CLK_TOP_SYSAPB_SEL             40
+#define CLK_TOP_ARM_DB_MAIN_SEL                41
+#define CLK_TOP_ARM_DB_JTSEL           42
+#define CLK_TOP_NETSYS_SEL             43
+#define CLK_TOP_NETSYS_500M_SEL                44
+#define CLK_TOP_NETSYS_MCU_SEL         45
+#define CLK_TOP_NETSYS_2X_SEL          46
+#define CLK_TOP_SGM_325M_SEL           47
+#define CLK_TOP_SGM_REG_SEL            48
+#define CLK_TOP_A1SYS_SEL              49
+#define CLK_TOP_CONN_MCUSYS_SEL                50
+#define CLK_TOP_EIP_B_SEL              51
+#define CLK_TOP_PCIE_PHY_SEL           52
+#define CLK_TOP_USB3_PHY_SEL           53
+#define CLK_TOP_F26M_SEL               54
+#define CLK_TOP_AUD_L_SEL              55
+#define CLK_TOP_A_TUNER_SEL            56
+#define CLK_TOP_U2U3_SEL               57
+#define CLK_TOP_U2U3_SYS_SEL           58
+#define CLK_TOP_U2U3_XHCI_SEL          59
+#define CLK_TOP_DA_U2_REFSEL           60
+#define CLK_TOP_DA_U2_CK_1P_SEL                61
+#define CLK_TOP_AP2CNN_HOST_SEL                62
+#define CLK_TOP_JTAG                   63
+
+/* INFRACFG */
+
+#define CLK_INFRA_SYSAXI_D2            0
+#define CLK_INFRA_UART0_SEL            1
+#define CLK_INFRA_UART1_SEL            2
+#define CLK_INFRA_UART2_SEL            3
+#define CLK_INFRA_SPI0_SEL             4
+#define CLK_INFRA_SPI1_SEL             5
+#define CLK_INFRA_PWM1_SEL             6
+#define CLK_INFRA_PWM2_SEL             7
+#define CLK_INFRA_PWM_BSEL             8
+#define CLK_INFRA_PCIE_SEL             9
+#define CLK_INFRA_GPT_STA              10
+#define CLK_INFRA_PWM_HCK              11
+#define CLK_INFRA_PWM_STA              12
+#define CLK_INFRA_PWM1_CK              13
+#define CLK_INFRA_PWM2_CK              14
+#define CLK_INFRA_CQ_DMA_CK            15
+#define CLK_INFRA_EIP97_CK             16
+#define CLK_INFRA_AUD_BUS_CK           17
+#define CLK_INFRA_AUD_26M_CK           18
+#define CLK_INFRA_AUD_L_CK             19
+#define CLK_INFRA_AUD_AUD_CK           20
+#define CLK_INFRA_AUD_EG2_CK           21
+#define CLK_INFRA_DRAMC_26M_CK         22
+#define CLK_INFRA_DBG_CK               23
+#define CLK_INFRA_AP_DMA_CK            24
+#define CLK_INFRA_SEJ_CK               25
+#define CLK_INFRA_SEJ_13M_CK           26
+#define CLK_INFRA_THERM_CK             27
+#define CLK_INFRA_I2C0_CK              28
+#define CLK_INFRA_UART0_CK             29
+#define CLK_INFRA_UART1_CK             30
+#define CLK_INFRA_UART2_CK             31
+#define CLK_INFRA_NFI1_CK              32
+#define CLK_INFRA_SPINFI1_CK           33
+#define CLK_INFRA_NFI_HCK_CK           34
+#define CLK_INFRA_SPI0_CK              35
+#define CLK_INFRA_SPI1_CK              36
+#define CLK_INFRA_SPI0_HCK_CK          37
+#define CLK_INFRA_SPI1_HCK_CK          38
+#define CLK_INFRA_FRTC_CK              39
+#define CLK_INFRA_MSDC_CK              40
+#define CLK_INFRA_MSDC_HCK_CK          41
+#define CLK_INFRA_MSDC_133M_CK         42
+#define CLK_INFRA_MSDC_66M_CK          43
+#define CLK_INFRA_ADC_26M_CK           44
+#define CLK_INFRA_ADC_FRC_CK           45
+#define CLK_INFRA_FBIST2FPC_CK         46
+#define CLK_INFRA_IUSB_133_CK          47
+#define CLK_INFRA_IUSB_66M_CK          48
+#define CLK_INFRA_IUSB_SYS_CK          49
+#define CLK_INFRA_IUSB_CK              50
+#define CLK_INFRA_IPCIE_CK             51
+#define CLK_INFRA_IPCIE_PIPE_CK                52
+#define CLK_INFRA_IPCIER_CK            53
+#define CLK_INFRA_IPCIEB_CK            54
+#define CLK_INFRA_TRNG_CK              55
+
+/* SGMIISYS_0 */
+
+#define CLK_SGMII0_TX250M_EN           0
+#define CLK_SGMII0_RX250M_EN           1
+#define CLK_SGMII0_CDR_REF             2
+#define CLK_SGMII0_CDR_FB              3
+
+/* SGMIISYS_1 */
+
+#define CLK_SGMII1_TX250M_EN           0
+#define CLK_SGMII1_RX250M_EN           1
+#define CLK_SGMII1_CDR_REF             2
+#define CLK_SGMII1_CDR_FB              3
+
+/* ETHSYS */
+
+#define CLK_ETH_FE_EN                  0
+#define CLK_ETH_GP2_EN                 1
+#define CLK_ETH_GP1_EN                 2
+#define CLK_ETH_WOCPU1_EN              3
+#define CLK_ETH_WOCPU0_EN              4
+
+#endif /* _DT_BINDINGS_CLK_MT7986_H */
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8976.h b/include/dt-bindings/clock/qcom,gcc-msm8976.h
new file mode 100644 (file)
index 0000000..51955fd
--- /dev/null
@@ -0,0 +1,240 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2016-2021, AngeloGioacchino Del Regno
+ *                     <angelogioacchino.delregno@somainline.org>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MSM_GCC_8976_H
+#define _DT_BINDINGS_CLK_MSM_GCC_8976_H
+
+#define GPLL0                                  0
+#define GPLL2                                  1
+#define GPLL3                                  2
+#define GPLL4                                  3
+#define GPLL6                                  4
+#define GPLL0_CLK_SRC                          5
+#define GPLL2_CLK_SRC                          6
+#define GPLL3_CLK_SRC                          7
+#define GPLL4_CLK_SRC                          8
+#define GPLL6_CLK_SRC                          9
+#define GCC_BLSP1_QUP1_SPI_APPS_CLK            10
+#define GCC_BLSP1_QUP1_I2C_APPS_CLK            11
+#define GCC_BLSP1_QUP2_I2C_APPS_CLK            12
+#define GCC_BLSP1_QUP2_SPI_APPS_CLK            13
+#define GCC_BLSP1_QUP3_I2C_APPS_CLK            14
+#define GCC_BLSP1_QUP3_SPI_APPS_CLK            15
+#define GCC_BLSP1_QUP4_I2C_APPS_CLK            16
+#define GCC_BLSP1_QUP4_SPI_APPS_CLK            17
+#define GCC_BLSP1_UART1_APPS_CLK               18
+#define GCC_BLSP1_UART2_APPS_CLK               19
+#define GCC_BLSP2_QUP1_I2C_APPS_CLK            20
+#define GCC_BLSP2_QUP1_SPI_APPS_CLK            21
+#define GCC_BLSP2_QUP2_I2C_APPS_CLK            22
+#define GCC_BLSP2_QUP2_SPI_APPS_CLK            23
+#define GCC_BLSP2_QUP3_I2C_APPS_CLK            24
+#define GCC_BLSP2_QUP3_SPI_APPS_CLK            25
+#define GCC_BLSP2_QUP4_I2C_APPS_CLK            26
+#define GCC_BLSP2_QUP4_SPI_APPS_CLK            27
+#define GCC_BLSP2_UART1_APPS_CLK               28
+#define GCC_BLSP2_UART2_APPS_CLK               29
+#define GCC_CAMSS_CCI_AHB_CLK                  30
+#define GCC_CAMSS_CCI_CLK                      31
+#define GCC_CAMSS_CPP_AHB_CLK                  32
+#define GCC_CAMSS_CPP_AXI_CLK                  33
+#define GCC_CAMSS_CPP_CLK                      34
+#define GCC_CAMSS_CSI0_AHB_CLK                 35
+#define GCC_CAMSS_CSI0_CLK                     36
+#define GCC_CAMSS_CSI0PHY_CLK                  37
+#define GCC_CAMSS_CSI0PIX_CLK                  38
+#define GCC_CAMSS_CSI0RDI_CLK                  39
+#define GCC_CAMSS_CSI1_AHB_CLK                 40
+#define GCC_CAMSS_CSI1_CLK                     41
+#define GCC_CAMSS_CSI1PHY_CLK                  42
+#define GCC_CAMSS_CSI1PIX_CLK                  43
+#define GCC_CAMSS_CSI1RDI_CLK                  44
+#define GCC_CAMSS_CSI2_AHB_CLK                 45
+#define GCC_CAMSS_CSI2_CLK                     46
+#define GCC_CAMSS_CSI2PHY_CLK                  47
+#define GCC_CAMSS_CSI2PIX_CLK                  48
+#define GCC_CAMSS_CSI2RDI_CLK                  49
+#define GCC_CAMSS_CSI_VFE0_CLK                 50
+#define GCC_CAMSS_CSI_VFE1_CLK                 51
+#define GCC_CAMSS_GP0_CLK                      52
+#define GCC_CAMSS_GP1_CLK                      53
+#define GCC_CAMSS_ISPIF_AHB_CLK                        54
+#define GCC_CAMSS_JPEG0_CLK                    55
+#define GCC_CAMSS_JPEG_AHB_CLK                 56
+#define GCC_CAMSS_JPEG_AXI_CLK                 57
+#define GCC_CAMSS_MCLK0_CLK                    58
+#define GCC_CAMSS_MCLK1_CLK                    59
+#define GCC_CAMSS_MCLK2_CLK                    60
+#define GCC_CAMSS_MICRO_AHB_CLK                        61
+#define GCC_CAMSS_CSI0PHYTIMER_CLK             62
+#define GCC_CAMSS_CSI1PHYTIMER_CLK             63
+#define GCC_CAMSS_AHB_CLK                      64
+#define GCC_CAMSS_TOP_AHB_CLK                  65
+#define GCC_CAMSS_VFE0_CLK                     66
+#define GCC_CAMSS_VFE_AHB_CLK                  67
+#define GCC_CAMSS_VFE_AXI_CLK                  68
+#define GCC_CAMSS_VFE1_AHB_CLK                 69
+#define GCC_CAMSS_VFE1_AXI_CLK                 70
+#define GCC_CAMSS_VFE1_CLK                     71
+#define GCC_DCC_CLK                            72
+#define GCC_GP1_CLK                            73
+#define GCC_GP2_CLK                            74
+#define GCC_GP3_CLK                            75
+#define GCC_MDSS_AHB_CLK                       76
+#define GCC_MDSS_AXI_CLK                       77
+#define GCC_MDSS_ESC0_CLK                      78
+#define GCC_MDSS_ESC1_CLK                      79
+#define GCC_MDSS_MDP_CLK                       80
+#define GCC_MDSS_VSYNC_CLK                     81
+#define GCC_MSS_CFG_AHB_CLK                    82
+#define GCC_MSS_Q6_BIMC_AXI_CLK                        83
+#define GCC_PDM2_CLK                           84
+#define GCC_PRNG_AHB_CLK                       85
+#define GCC_PDM_AHB_CLK                                86
+#define GCC_RBCPR_GFX_AHB_CLK                  87
+#define GCC_RBCPR_GFX_CLK                      88
+#define GCC_SDCC1_AHB_CLK                      89
+#define GCC_SDCC1_APPS_CLK                     90
+#define GCC_SDCC1_ICE_CORE_CLK                 91
+#define GCC_SDCC2_AHB_CLK                      92
+#define GCC_SDCC2_APPS_CLK                     93
+#define GCC_SDCC3_AHB_CLK                      94
+#define GCC_SDCC3_APPS_CLK                     95
+#define GCC_USB2A_PHY_SLEEP_CLK                        96
+#define GCC_USB_HS_PHY_CFG_AHB_CLK             97
+#define GCC_USB_FS_AHB_CLK                     98
+#define GCC_USB_FS_IC_CLK                      99
+#define GCC_USB_FS_SYSTEM_CLK                  100
+#define GCC_USB_HS_AHB_CLK                     101
+#define GCC_USB_HS_SYSTEM_CLK                  102
+#define GCC_VENUS0_AHB_CLK                     103
+#define GCC_VENUS0_AXI_CLK                     104
+#define GCC_VENUS0_CORE0_VCODEC0_CLK           105
+#define GCC_VENUS0_CORE1_VCODEC0_CLK           106
+#define GCC_VENUS0_VCODEC0_CLK                 107
+#define GCC_APSS_AHB_CLK                       108
+#define GCC_APSS_AXI_CLK                       109
+#define GCC_BLSP1_AHB_CLK                      110
+#define GCC_BLSP2_AHB_CLK                      111
+#define GCC_BOOT_ROM_AHB_CLK                   112
+#define GCC_CRYPTO_AHB_CLK                     113
+#define GCC_CRYPTO_AXI_CLK                     114
+#define GCC_CRYPTO_CLK                         115
+#define GCC_CPP_TBU_CLK                                116
+#define GCC_APSS_TCU_CLK                       117
+#define GCC_JPEG_TBU_CLK                       118
+#define GCC_MDP_RT_TBU_CLK                     119
+#define GCC_MDP_TBU_CLK                                120
+#define GCC_SMMU_CFG_CLK                       121
+#define GCC_VENUS_1_TBU_CLK                    122
+#define GCC_VENUS_TBU_CLK                      123
+#define GCC_VFE1_TBU_CLK                       124
+#define GCC_VFE_TBU_CLK                                125
+#define GCC_APS_0_CLK                          126
+#define GCC_APS_1_CLK                          127
+#define APS_0_CLK_SRC                          128
+#define APS_1_CLK_SRC                          129
+#define APSS_AHB_CLK_SRC                       130
+#define BLSP1_QUP1_I2C_APPS_CLK_SRC            131
+#define BLSP1_QUP1_SPI_APPS_CLK_SRC            132
+#define BLSP1_QUP2_I2C_APPS_CLK_SRC            133
+#define BLSP1_QUP2_SPI_APPS_CLK_SRC            134
+#define BLSP1_QUP3_I2C_APPS_CLK_SRC            135
+#define BLSP1_QUP3_SPI_APPS_CLK_SRC            136
+#define BLSP1_QUP4_I2C_APPS_CLK_SRC            137
+#define BLSP1_QUP4_SPI_APPS_CLK_SRC            138
+#define BLSP1_UART1_APPS_CLK_SRC               139
+#define BLSP1_UART2_APPS_CLK_SRC               140
+#define BLSP2_QUP1_I2C_APPS_CLK_SRC            141
+#define BLSP2_QUP1_SPI_APPS_CLK_SRC            142
+#define BLSP2_QUP2_I2C_APPS_CLK_SRC            143
+#define BLSP2_QUP2_SPI_APPS_CLK_SRC            144
+#define BLSP2_QUP3_I2C_APPS_CLK_SRC            145
+#define BLSP2_QUP3_SPI_APPS_CLK_SRC            146
+#define BLSP2_QUP4_I2C_APPS_CLK_SRC            147
+#define BLSP2_QUP4_SPI_APPS_CLK_SRC            148
+#define BLSP2_UART1_APPS_CLK_SRC               149
+#define BLSP2_UART2_APPS_CLK_SRC               150
+#define CCI_CLK_SRC                            151
+#define CPP_CLK_SRC                            152
+#define CSI0_CLK_SRC                           153
+#define CSI1_CLK_SRC                           154
+#define CSI2_CLK_SRC                           155
+#define CAMSS_GP0_CLK_SRC                      156
+#define CAMSS_GP1_CLK_SRC                      157
+#define JPEG0_CLK_SRC                          158
+#define MCLK0_CLK_SRC                          159
+#define MCLK1_CLK_SRC                          160
+#define MCLK2_CLK_SRC                          161
+#define CSI0PHYTIMER_CLK_SRC                   162
+#define CSI1PHYTIMER_CLK_SRC                   163
+#define CAMSS_TOP_AHB_CLK_SRC                  164
+#define VFE0_CLK_SRC                           165
+#define VFE1_CLK_SRC                           166
+#define CRYPTO_CLK_SRC                         167
+#define GP1_CLK_SRC                            168
+#define GP2_CLK_SRC                            169
+#define GP3_CLK_SRC                            170
+#define ESC0_CLK_SRC                           171
+#define ESC1_CLK_SRC                           172
+#define MDP_CLK_SRC                            173
+#define VSYNC_CLK_SRC                          174
+#define PDM2_CLK_SRC                           175
+#define RBCPR_GFX_CLK_SRC                      176
+#define SDCC1_APPS_CLK_SRC                     177
+#define SDCC1_ICE_CORE_CLK_SRC                 178
+#define SDCC2_APPS_CLK_SRC                     179
+#define SDCC3_APPS_CLK_SRC                     180
+#define USB_FS_IC_CLK_SRC                      181
+#define USB_FS_SYSTEM_CLK_SRC                  182
+#define USB_HS_SYSTEM_CLK_SRC                  183
+#define VCODEC0_CLK_SRC                                184
+#define GCC_MDSS_BYTE0_CLK_SRC                 185
+#define GCC_MDSS_BYTE1_CLK_SRC                 186
+#define GCC_MDSS_BYTE0_CLK                     187
+#define GCC_MDSS_BYTE1_CLK                     188
+#define GCC_MDSS_PCLK0_CLK_SRC                 189
+#define GCC_MDSS_PCLK1_CLK_SRC                 190
+#define GCC_MDSS_PCLK0_CLK                     191
+#define GCC_MDSS_PCLK1_CLK                     192
+#define GCC_GFX3D_CLK_SRC                      193
+#define GCC_GFX3D_OXILI_CLK                    194
+#define GCC_GFX3D_BIMC_CLK                     195
+#define GCC_GFX3D_OXILI_AHB_CLK                        196
+#define GCC_GFX3D_OXILI_AON_CLK                        197
+#define GCC_GFX3D_OXILI_GMEM_CLK               198
+#define GCC_GFX3D_OXILI_TIMER_CLK              199
+#define GCC_GFX3D_TBU0_CLK                     200
+#define GCC_GFX3D_TBU1_CLK                     201
+#define GCC_GFX3D_TCU_CLK                      202
+#define GCC_GFX3D_GTCU_AHB_CLK                 203
+
+/* GCC block resets */
+#define RST_CAMSS_MICRO_BCR                    0
+#define RST_USB_HS_BCR                         1
+#define RST_QUSB2_PHY_BCR                      2
+#define RST_USB2_HS_PHY_ONLY_BCR               3
+#define RST_USB_HS_PHY_CFG_AHB_BCR             4
+#define RST_USB_FS_BCR                         5
+#define RST_CAMSS_CSI1PIX_BCR                  6
+#define RST_CAMSS_CSI_VFE1_BCR                 7
+#define RST_CAMSS_VFE1_BCR                     8
+#define RST_CAMSS_CPP_BCR                      9
+
+/* GDSCs */
+#define VENUS_GDSC                             0
+#define VENUS_CORE0_GDSC                       1
+#define VENUS_CORE1_GDSC                       2
+#define MDSS_GDSC                              3
+#define JPEG_GDSC                              4
+#define VFE0_GDSC                              5
+#define VFE1_GDSC                              6
+#define CPP_GDSC                               7
+#define OXILI_GX_GDSC                          8
+#define OXILI_CX_GDSC                          9
+
+#endif /* _DT_BINDINGS_CLK_MSM_GCC_8976_H */
diff --git a/include/dt-bindings/clock/sun20i-d1-ccu.h b/include/dt-bindings/clock/sun20i-d1-ccu.h
new file mode 100644 (file)
index 0000000..e3ac533
--- /dev/null
@@ -0,0 +1,156 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (C) 2020 huangzhenwei@allwinnertech.com
+ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN20I_D1_CCU_H_
+#define _DT_BINDINGS_CLK_SUN20I_D1_CCU_H_
+
+#define CLK_PLL_CPUX           0
+#define CLK_PLL_DDR0           1
+#define CLK_PLL_PERIPH0_4X     2
+#define CLK_PLL_PERIPH0_2X     3
+#define CLK_PLL_PERIPH0_800M   4
+#define CLK_PLL_PERIPH0                5
+#define CLK_PLL_PERIPH0_DIV3   6
+#define CLK_PLL_VIDEO0_4X      7
+#define CLK_PLL_VIDEO0_2X      8
+#define CLK_PLL_VIDEO0         9
+#define CLK_PLL_VIDEO1_4X      10
+#define CLK_PLL_VIDEO1_2X      11
+#define CLK_PLL_VIDEO1         12
+#define CLK_PLL_VE             13
+#define CLK_PLL_AUDIO0_4X      14
+#define CLK_PLL_AUDIO0_2X      15
+#define CLK_PLL_AUDIO0         16
+#define CLK_PLL_AUDIO1         17
+#define CLK_PLL_AUDIO1_DIV2    18
+#define CLK_PLL_AUDIO1_DIV5    19
+#define CLK_CPUX               20
+#define CLK_CPUX_AXI           21
+#define CLK_CPUX_APB           22
+#define CLK_PSI_AHB            23
+#define CLK_APB0               24
+#define CLK_APB1               25
+#define CLK_MBUS               26
+#define CLK_DE                 27
+#define CLK_BUS_DE             28
+#define CLK_DI                 29
+#define CLK_BUS_DI             30
+#define CLK_G2D                        31
+#define CLK_BUS_G2D            32
+#define CLK_CE                 33
+#define CLK_BUS_CE             34
+#define CLK_VE                 35
+#define CLK_BUS_VE             36
+#define CLK_BUS_DMA            37
+#define CLK_BUS_MSGBOX0                38
+#define CLK_BUS_MSGBOX1                39
+#define CLK_BUS_MSGBOX2                40
+#define CLK_BUS_SPINLOCK       41
+#define CLK_BUS_HSTIMER                42
+#define CLK_AVS                        43
+#define CLK_BUS_DBG            44
+#define CLK_BUS_PWM            45
+#define CLK_BUS_IOMMU          46
+#define CLK_DRAM               47
+#define CLK_MBUS_DMA           48
+#define CLK_MBUS_VE            49
+#define CLK_MBUS_CE            50
+#define CLK_MBUS_TVIN          51
+#define CLK_MBUS_CSI           52
+#define CLK_MBUS_G2D           53
+#define CLK_MBUS_RISCV         54
+#define CLK_BUS_DRAM           55
+#define CLK_MMC0               56
+#define CLK_MMC1               57
+#define CLK_MMC2               58
+#define CLK_BUS_MMC0           59
+#define CLK_BUS_MMC1           60
+#define CLK_BUS_MMC2           61
+#define CLK_BUS_UART0          62
+#define CLK_BUS_UART1          63
+#define CLK_BUS_UART2          64
+#define CLK_BUS_UART3          65
+#define CLK_BUS_UART4          66
+#define CLK_BUS_UART5          67
+#define CLK_BUS_I2C0           68
+#define CLK_BUS_I2C1           69
+#define CLK_BUS_I2C2           70
+#define CLK_BUS_I2C3           71
+#define CLK_SPI0               72
+#define CLK_SPI1               73
+#define CLK_BUS_SPI0           74
+#define CLK_BUS_SPI1           75
+#define CLK_EMAC_25M           76
+#define CLK_BUS_EMAC           77
+#define CLK_IR_TX              78
+#define CLK_BUS_IR_TX          79
+#define CLK_BUS_GPADC          80
+#define CLK_BUS_THS            81
+#define CLK_I2S0               82
+#define CLK_I2S1               83
+#define CLK_I2S2               84
+#define CLK_I2S2_ASRC          85
+#define CLK_BUS_I2S0           86
+#define CLK_BUS_I2S1           87
+#define CLK_BUS_I2S2           88
+#define CLK_SPDIF_TX           89
+#define CLK_SPDIF_RX           90
+#define CLK_BUS_SPDIF          91
+#define CLK_DMIC               92
+#define CLK_BUS_DMIC           93
+#define CLK_AUDIO_DAC          94
+#define CLK_AUDIO_ADC          95
+#define CLK_BUS_AUDIO          96
+#define CLK_USB_OHCI0          97
+#define CLK_USB_OHCI1          98
+#define CLK_BUS_OHCI0          99
+#define CLK_BUS_OHCI1          100
+#define CLK_BUS_EHCI0          101
+#define CLK_BUS_EHCI1          102
+#define CLK_BUS_OTG            103
+#define CLK_BUS_LRADC          104
+#define CLK_BUS_DPSS_TOP       105
+#define CLK_HDMI_24M           106
+#define CLK_HDMI_CEC_32K       107
+#define CLK_HDMI_CEC           108
+#define CLK_BUS_HDMI           109
+#define CLK_MIPI_DSI           110
+#define CLK_BUS_MIPI_DSI       111
+#define CLK_TCON_LCD0          112
+#define CLK_BUS_TCON_LCD0      113
+#define CLK_TCON_TV            114
+#define CLK_BUS_TCON_TV                115
+#define CLK_TVE                        116
+#define CLK_BUS_TVE_TOP                117
+#define CLK_BUS_TVE            118
+#define CLK_TVD                        119
+#define CLK_BUS_TVD_TOP                120
+#define CLK_BUS_TVD            121
+#define CLK_LEDC               122
+#define CLK_BUS_LEDC           123
+#define CLK_CSI_TOP            124
+#define CLK_CSI_MCLK           125
+#define CLK_BUS_CSI            126
+#define CLK_TPADC              127
+#define CLK_BUS_TPADC          128
+#define CLK_BUS_TZMA           129
+#define CLK_DSP                        130
+#define CLK_BUS_DSP_CFG                131
+#define CLK_RISCV              132
+#define CLK_RISCV_AXI          133
+#define CLK_BUS_RISCV_CFG      134
+#define CLK_FANOUT_24M         135
+#define CLK_FANOUT_12M         136
+#define CLK_FANOUT_16M         137
+#define CLK_FANOUT_25M         138
+#define CLK_FANOUT_32K         139
+#define CLK_FANOUT_27M         140
+#define CLK_FANOUT_PCLK                141
+#define CLK_FANOUT0            142
+#define CLK_FANOUT1            143
+#define CLK_FANOUT2            144
+
+#endif /* _DT_BINDINGS_CLK_SUN20I_D1_CCU_H_ */
diff --git a/include/dt-bindings/clock/sun20i-d1-r-ccu.h b/include/dt-bindings/clock/sun20i-d1-r-ccu.h
new file mode 100644 (file)
index 0000000..4c2697f
--- /dev/null
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN20I_D1_R_CCU_H_
+#define _DT_BINDINGS_CLK_SUN20I_D1_R_CCU_H_
+
+#define CLK_R_AHB              0
+
+#define CLK_BUS_R_TIMER                2
+#define CLK_BUS_R_TWD          3
+#define CLK_BUS_R_PPU          4
+#define CLK_R_IR_RX            5
+#define CLK_BUS_R_IR_RX                6
+#define CLK_BUS_R_RTC          7
+#define CLK_BUS_R_CPUCFG       8
+
+#endif /* _DT_BINDINGS_CLK_SUN20I_D1_R_CCU_H_ */
diff --git a/include/dt-bindings/clock/toshiba,tmpv770x.h b/include/dt-bindings/clock/toshiba,tmpv770x.h
new file mode 100644 (file)
index 0000000..5fce713
--- /dev/null
@@ -0,0 +1,181 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+
+#ifndef _DT_BINDINGS_CLOCK_TOSHIBA_TMPV770X_H_
+#define _DT_BINDINGS_CLOCK_TOSHIBA_TMPV770X_H_
+
+/* PLL */
+#define TMPV770X_PLL_PIPLL0            0
+#define TMPV770X_PLL_PIPLL1            1
+#define TMPV770X_PLL_PIDNNPLL          2
+#define TMPV770X_PLL_PIETHERPLL                3
+#define TMPV770X_PLL_PIDDRCPLL         4
+#define TMPV770X_PLL_PIVOIFPLL         5
+#define TMPV770X_PLL_PIIMGERPLL                6
+#define TMPV770X_NR_PLL                7
+
+/* Clocks */
+#define TMPV770X_CLK_PIPLL1_DIV1       0
+#define TMPV770X_CLK_PIPLL1_DIV2       1
+#define TMPV770X_CLK_PIPLL1_DIV4       2
+#define TMPV770X_CLK_PIDNNPLL_DIV1     3
+#define TMPV770X_CLK_DDRC_PHY_PLL0     4
+#define TMPV770X_CLK_DDRC_PHY_PLL1     5
+#define TMPV770X_CLK_D_PHYPLL          6
+#define TMPV770X_CLK_PHY_PCIEPLL       7
+#define TMPV770X_CLK_CA53CL0           8
+#define TMPV770X_CLK_CA53CL1           9
+#define TMPV770X_CLK_PISDMAC           10
+#define TMPV770X_CLK_PIPDMAC0          11
+#define TMPV770X_CLK_PIPDMAC1          12
+#define TMPV770X_CLK_PIWRAM            13
+#define TMPV770X_CLK_DDRC0             14
+#define TMPV770X_CLK_DDRC0_SCLK                15
+#define TMPV770X_CLK_DDRC0_NCLK                16
+#define TMPV770X_CLK_DDRC0_MCLK                17
+#define TMPV770X_CLK_DDRC0_APBCLK      18
+#define TMPV770X_CLK_DDRC1             19
+#define TMPV770X_CLK_DDRC1_SCLK                20
+#define TMPV770X_CLK_DDRC1_NCLK                21
+#define TMPV770X_CLK_DDRC1_MCLK                22
+#define TMPV770X_CLK_DDRC1_APBCLK      23
+#define TMPV770X_CLK_HOX               24
+#define TMPV770X_CLK_PCIE_MSTR         25
+#define TMPV770X_CLK_PCIE_AUX          26
+#define TMPV770X_CLK_PIINTC            27
+#define TMPV770X_CLK_PIETHER_BUS       28
+#define TMPV770X_CLK_PISPI0            29
+#define TMPV770X_CLK_PISPI1            30
+#define TMPV770X_CLK_PISPI2            31
+#define TMPV770X_CLK_PISPI3            32
+#define TMPV770X_CLK_PISPI4            33
+#define TMPV770X_CLK_PISPI5            34
+#define TMPV770X_CLK_PISPI6            35
+#define TMPV770X_CLK_PIUART0           36
+#define TMPV770X_CLK_PIUART1           37
+#define TMPV770X_CLK_PIUART2           38
+#define TMPV770X_CLK_PIUART3           39
+#define TMPV770X_CLK_PII2C0            40
+#define TMPV770X_CLK_PII2C1            41
+#define TMPV770X_CLK_PII2C2            42
+#define TMPV770X_CLK_PII2C3            43
+#define TMPV770X_CLK_PII2C4            44
+#define TMPV770X_CLK_PII2C5            45
+#define TMPV770X_CLK_PII2C6            46
+#define TMPV770X_CLK_PII2C7            47
+#define TMPV770X_CLK_PII2C8            48
+#define TMPV770X_CLK_PIGPIO            49
+#define TMPV770X_CLK_PIPGM             50
+#define TMPV770X_CLK_PIPCMIF           51
+#define TMPV770X_CLK_PIPCMIF_AUDIO_O   52
+#define TMPV770X_CLK_PIPCMIF_AUDIO_I   53
+#define TMPV770X_CLK_PICMPT0           54
+#define TMPV770X_CLK_PICMPT1           55
+#define TMPV770X_CLK_PITSC             56
+#define TMPV770X_CLK_PIUWDT            57
+#define TMPV770X_CLK_PISWDT            58
+#define TMPV770X_CLK_WDTCLK            59
+#define TMPV770X_CLK_PISUBUS_150M      60
+#define TMPV770X_CLK_PISUBUS_300M      61
+#define TMPV770X_CLK_PIPMU             62
+#define TMPV770X_CLK_PIGPMU            63
+#define TMPV770X_CLK_PITMU             64
+#define TMPV770X_CLK_WRCK              65
+#define TMPV770X_CLK_PIEMM             66
+#define TMPV770X_CLK_PIMISC            67
+#define TMPV770X_CLK_PIGCOMM           68
+#define TMPV770X_CLK_PIDCOMM           69
+#define TMPV770X_CLK_PICKMON           70
+#define TMPV770X_CLK_PIMBUS            71
+#define TMPV770X_CLK_SBUSCLK           72
+#define TMPV770X_CLK_DDR0_APBCLKCLK    73
+#define TMPV770X_CLK_DDR1_APBCLKCLK    74
+#define TMPV770X_CLK_DSP0_PBCLK                75
+#define TMPV770X_CLK_DSP1_PBCLK                76
+#define TMPV770X_CLK_DSP2_PBCLK                77
+#define TMPV770X_CLK_DSP3_PBCLK                78
+#define TMPV770X_CLK_DSVIIF0_APBCLK    79
+#define TMPV770X_CLK_VIIF0_APBCLK      80
+#define TMPV770X_CLK_VIIF0_CFGCLK      81
+#define TMPV770X_CLK_VIIF1_APBCLK      82
+#define TMPV770X_CLK_VIIF1_CFGCLK      83
+#define TMPV770X_CLK_VIIF2_APBCLK      84
+#define TMPV770X_CLK_VIIF2_CFGCLK      85
+#define TMPV770X_CLK_VIIF3_APBCLK      86
+#define TMPV770X_CLK_VIIF3_CFGCLK      87
+#define TMPV770X_CLK_VIIF4_APBCLK      88
+#define TMPV770X_CLK_VIIF4_CFGCLK      89
+#define TMPV770X_CLK_VIIF5_APBCLK      90
+#define TMPV770X_CLK_VIIF5_CFGCLK      91
+#define TMPV770X_CLK_VOIF_SBUSCLK      92
+#define TMPV770X_CLK_VOIF_PROCCLK      93
+#define TMPV770X_CLK_VOIF_DPHYCFGCLK   94
+#define TMPV770X_CLK_DNN0              95
+#define TMPV770X_CLK_STMAT             96
+#define TMPV770X_CLK_HWA0              97
+#define TMPV770X_CLK_AFFINE0           98
+#define TMPV770X_CLK_HAMAT             99
+#define TMPV770X_CLK_SMLDB             100
+#define TMPV770X_CLK_HWA0_ASYNC                101
+#define TMPV770X_CLK_HWA2              102
+#define TMPV770X_CLK_FLMAT             103
+#define TMPV770X_CLK_PYRAMID           104
+#define TMPV770X_CLK_HWA2_ASYNC                105
+#define TMPV770X_CLK_DSP0              106
+#define TMPV770X_CLK_VIIFBS0           107
+#define TMPV770X_CLK_VIIFBS0_L2ISP     108
+#define TMPV770X_CLK_VIIFBS0_L1ISP     109
+#define TMPV770X_CLK_VIIFBS0_PROC      110
+#define TMPV770X_CLK_VIIFBS1           111
+#define TMPV770X_CLK_VIIFBS2           112
+#define TMPV770X_CLK_VIIFOP_MBUS       113
+#define TMPV770X_CLK_VIIFOP0_PROC      114
+#define TMPV770X_CLK_PIETHER_2P5M      115
+#define TMPV770X_CLK_PIETHER_25M       116
+#define TMPV770X_CLK_PIETHER_50M       117
+#define TMPV770X_CLK_PIETHER_125M      118
+#define TMPV770X_CLK_VOIF0_DPHYCFG     119
+#define TMPV770X_CLK_VOIF0_PROC                120
+#define TMPV770X_CLK_VOIF0_SBUS                121
+#define TMPV770X_CLK_VOIF0_DSIREF      122
+#define TMPV770X_CLK_VOIF0_PIXEL       123
+#define TMPV770X_CLK_PIREFCLK          124
+#define TMPV770X_CLK_SBUS              125
+#define TMPV770X_CLK_BUSLCK            126
+#define TMPV770X_NR_CLK                        127
+
+/* Reset */
+#define TMPV770X_RESET_PIETHER_2P5M    0
+#define TMPV770X_RESET_PIETHER_25M     1
+#define TMPV770X_RESET_PIETHER_50M     2
+#define TMPV770X_RESET_PIETHER_125M    3
+#define TMPV770X_RESET_HOX             4
+#define TMPV770X_RESET_PCIE_MSTR       5
+#define TMPV770X_RESET_PCIE_AUX                6
+#define TMPV770X_RESET_PIINTC          7
+#define TMPV770X_RESET_PIETHER_BUS     8
+#define TMPV770X_RESET_PISPI0          9
+#define TMPV770X_RESET_PISPI1          10
+#define TMPV770X_RESET_PISPI2          11
+#define TMPV770X_RESET_PISPI3          12
+#define TMPV770X_RESET_PISPI4          13
+#define TMPV770X_RESET_PISPI5          14
+#define TMPV770X_RESET_PISPI6          15
+#define TMPV770X_RESET_PIUART0         16
+#define TMPV770X_RESET_PIUART1         17
+#define TMPV770X_RESET_PIUART2         18
+#define TMPV770X_RESET_PIUART3         19
+#define TMPV770X_RESET_PII2C0          20
+#define TMPV770X_RESET_PII2C1          21
+#define TMPV770X_RESET_PII2C2          22
+#define TMPV770X_RESET_PII2C3          23
+#define TMPV770X_RESET_PII2C4          24
+#define TMPV770X_RESET_PII2C5          25
+#define TMPV770X_RESET_PII2C6          26
+#define TMPV770X_RESET_PII2C7          27
+#define TMPV770X_RESET_PII2C8          28
+#define TMPV770X_RESET_PIPCMIF         29
+#define TMPV770X_RESET_PICKMON         30
+#define TMPV770X_RESET_SBUSCLK         31
+#define TMPV770X_NR_RESET              32
+
+#endif /*_DT_BINDINGS_CLOCK_TOSHIBA_TMPV770X_H_ */
diff --git a/include/dt-bindings/reset/sun20i-d1-ccu.h b/include/dt-bindings/reset/sun20i-d1-ccu.h
new file mode 100644 (file)
index 0000000..de9ff52
--- /dev/null
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (c) 2020 huangzhenwei@allwinnertech.com
+ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
+ */
+
+#ifndef _DT_BINDINGS_RST_SUN20I_D1_CCU_H_
+#define _DT_BINDINGS_RST_SUN20I_D1_CCU_H_
+
+#define RST_MBUS               0
+#define RST_BUS_DE             1
+#define RST_BUS_DI             2
+#define RST_BUS_G2D            3
+#define RST_BUS_CE             4
+#define RST_BUS_VE             5
+#define RST_BUS_DMA            6
+#define RST_BUS_MSGBOX0                7
+#define RST_BUS_MSGBOX1                8
+#define RST_BUS_MSGBOX2                9
+#define RST_BUS_SPINLOCK       10
+#define RST_BUS_HSTIMER                11
+#define RST_BUS_DBG            12
+#define RST_BUS_PWM            13
+#define RST_BUS_DRAM           14
+#define RST_BUS_MMC0           15
+#define RST_BUS_MMC1           16
+#define RST_BUS_MMC2           17
+#define RST_BUS_UART0          18
+#define RST_BUS_UART1          19
+#define RST_BUS_UART2          20
+#define RST_BUS_UART3          21
+#define RST_BUS_UART4          22
+#define RST_BUS_UART5          23
+#define RST_BUS_I2C0           24
+#define RST_BUS_I2C1           25
+#define RST_BUS_I2C2           26
+#define RST_BUS_I2C3           27
+#define RST_BUS_SPI0           28
+#define RST_BUS_SPI1           29
+#define RST_BUS_EMAC           30
+#define RST_BUS_IR_TX          31
+#define RST_BUS_GPADC          32
+#define RST_BUS_THS            33
+#define RST_BUS_I2S0           34
+#define RST_BUS_I2S1           35
+#define RST_BUS_I2S2           36
+#define RST_BUS_SPDIF          37
+#define RST_BUS_DMIC           38
+#define RST_BUS_AUDIO          39
+#define RST_USB_PHY0           40
+#define RST_USB_PHY1           41
+#define RST_BUS_OHCI0          42
+#define RST_BUS_OHCI1          43
+#define RST_BUS_EHCI0          44
+#define RST_BUS_EHCI1          45
+#define RST_BUS_OTG            46
+#define RST_BUS_LRADC          47
+#define RST_BUS_DPSS_TOP       48
+#define RST_BUS_HDMI_SUB       49
+#define RST_BUS_HDMI_MAIN      50
+#define RST_BUS_MIPI_DSI       51
+#define RST_BUS_TCON_LCD0      52
+#define RST_BUS_TCON_TV                53
+#define RST_BUS_LVDS0          54
+#define RST_BUS_TVE            55
+#define RST_BUS_TVE_TOP                56
+#define RST_BUS_TVD            57
+#define RST_BUS_TVD_TOP                58
+#define RST_BUS_LEDC           59
+#define RST_BUS_CSI            60
+#define RST_BUS_TPADC          61
+#define RST_DSP                        62
+#define RST_BUS_DSP_CFG                63
+#define RST_BUS_DSP_DBG                64
+#define RST_BUS_RISCV_CFG      65
+
+#endif /* _DT_BINDINGS_RST_SUN20I_D1_CCU_H_ */
diff --git a/include/dt-bindings/reset/sun20i-d1-r-ccu.h b/include/dt-bindings/reset/sun20i-d1-r-ccu.h
new file mode 100644 (file)
index 0000000..d93d642
--- /dev/null
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
+ */
+
+#ifndef _DT_BINDINGS_RST_SUN20I_D1_R_CCU_H_
+#define _DT_BINDINGS_RST_SUN20I_D1_R_CCU_H_
+
+#define RST_BUS_R_TIMER                0
+#define RST_BUS_R_TWD          1
+#define RST_BUS_R_PPU          2
+#define RST_BUS_R_IR_RX                3
+#define RST_BUS_R_RTC          4
+#define RST_BUS_R_CPUCFG       5
+
+#endif /* _DT_BINDINGS_RST_SUN20I_D1_R_CCU_H_ */
diff --git a/include/dt-bindings/reset/toshiba,tmpv770x.h b/include/dt-bindings/reset/toshiba,tmpv770x.h
new file mode 100644 (file)
index 0000000..c1007ac
--- /dev/null
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+
+#ifndef _DT_BINDINGS_RESET_TOSHIBA_TMPV770X_H_
+#define _DT_BINDINGS_RESET_TOSHIBA_TMPV770X_H_
+
+/* Reset */
+#define TMPV770X_RESET_PIETHER_2P5M    0
+#define TMPV770X_RESET_PIETHER_25M     1
+#define TMPV770X_RESET_PIETHER_50M     2
+#define TMPV770X_RESET_PIETHER_125M    3
+#define TMPV770X_RESET_HOX             4
+#define TMPV770X_RESET_PCIE_MSTR       5
+#define TMPV770X_RESET_PCIE_AUX                6
+#define TMPV770X_RESET_PIINTC          7
+#define TMPV770X_RESET_PIETHER_BUS     8
+#define TMPV770X_RESET_PISPI0          9
+#define TMPV770X_RESET_PISPI1          10
+#define TMPV770X_RESET_PISPI2          11
+#define TMPV770X_RESET_PISPI3          12
+#define TMPV770X_RESET_PISPI4          13
+#define TMPV770X_RESET_PISPI5          14
+#define TMPV770X_RESET_PISPI6          15
+#define TMPV770X_RESET_PIUART0         16
+#define TMPV770X_RESET_PIUART1         17
+#define TMPV770X_RESET_PIUART2         18
+#define TMPV770X_RESET_PIUART3         19
+#define TMPV770X_RESET_PII2C0          20
+#define TMPV770X_RESET_PII2C1          21
+#define TMPV770X_RESET_PII2C2          22
+#define TMPV770X_RESET_PII2C3          23
+#define TMPV770X_RESET_PII2C4          24
+#define TMPV770X_RESET_PII2C5          25
+#define TMPV770X_RESET_PII2C6          26
+#define TMPV770X_RESET_PII2C7          27
+#define TMPV770X_RESET_PII2C8          28
+#define TMPV770X_RESET_PIPCMIF         29
+#define TMPV770X_RESET_PICKMON         30
+#define TMPV770X_RESET_SBUSCLK         31
+#define TMPV770X_NR_RESET              32
+
+#endif /*_DT_BINDINGS_RESET_TOSHIBA_TMPV770X_H_ */
index f59c875..2faa6f7 100644 (file)
@@ -490,6 +490,13 @@ struct clk_hw *__clk_hw_register_gate(struct device *dev,
                unsigned long flags,
                void __iomem *reg, u8 bit_idx,
                u8 clk_gate_flags, spinlock_t *lock);
+struct clk_hw *__devm_clk_hw_register_gate(struct device *dev,
+               struct device_node *np, const char *name,
+               const char *parent_name, const struct clk_hw *parent_hw,
+               const struct clk_parent_data *parent_data,
+               unsigned long flags,
+               void __iomem *reg, u8 bit_idx,
+               u8 clk_gate_flags, spinlock_t *lock);
 struct clk *clk_register_gate(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                void __iomem *reg, u8 bit_idx,
@@ -544,6 +551,22 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
        __clk_hw_register_gate((dev), NULL, (name), NULL, NULL, (parent_data), \
                               (flags), (reg), (bit_idx),                     \
                               (clk_gate_flags), (lock))
+/**
+ * devm_clk_hw_register_gate - register a gate clock with the clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of this clock's parent
+ * @flags: framework-specific flags for this clock
+ * @reg: register address to control gating of this clock
+ * @bit_idx: which bit in the register controls gating of this clock
+ * @clk_gate_flags: gate-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define devm_clk_hw_register_gate(dev, name, parent_name, flags, reg, bit_idx,\
+                                 clk_gate_flags, lock)                       \
+       __devm_clk_hw_register_gate((dev), NULL, (name), (parent_name), NULL, \
+                              NULL, (flags), (reg), (bit_idx),               \
+                              (clk_gate_flags), (lock))
 void clk_unregister_gate(struct clk *clk);
 void clk_hw_unregister_gate(struct clk_hw *hw);
 int clk_gate_is_enabled(struct clk_hw *hw);
index 3cd14ac..cf32123 100644 (file)
@@ -6,22 +6,7 @@
 #ifndef _LINUX_CLK_SUNXI_NG_H_
 #define _LINUX_CLK_SUNXI_NG_H_
 
-#include <linux/errno.h>
-
-#ifdef CONFIG_SUNXI_CCU
 int sunxi_ccu_set_mmc_timing_mode(struct clk *clk, bool new_mode);
 int sunxi_ccu_get_mmc_timing_mode(struct clk *clk);
-#else
-static inline int sunxi_ccu_set_mmc_timing_mode(struct clk *clk,
-                                               bool new_mode)
-{
-       return -ENOTSUPP;
-}
-
-static inline int sunxi_ccu_get_mmc_timing_mode(struct clk *clk)
-{
-       return -ENOTSUPP;
-}
-#endif
 
 #endif
index ffe8112..7807fa3 100644 (file)
 #define TPS68470_CLKCFG1_MODE_A_MASK   GENMASK(1, 0)
 #define TPS68470_CLKCFG1_MODE_B_MASK   GENMASK(3, 2)
 
+#define TPS68470_CLKCFG2_DRV_STR_2MA   0x05
+#define TPS68470_PLL_OUTPUT_ENABLE     0x02
+#define TPS68470_CLK_SRC_XTAL          BIT(0)
+#define TPS68470_PLLSWR_DEFAULT                GENMASK(1, 0)
+#define TPS68470_OSC_EXT_CAP_DEFAULT   0x05
+
+#define TPS68470_OUTPUT_A_SHIFT                0x00
+#define TPS68470_OUTPUT_B_SHIFT                0x02
+#define TPS68470_CLK_SRC_SHIFT         GENMASK(2, 0)
+#define TPS68470_OSC_EXT_CAP_SHIFT     BIT(2)
+
 #define TPS68470_GPIO_CTL_REG_A(x)     (TPS68470_REG_GPCTL0A + (x) * 2)
 #define TPS68470_GPIO_CTL_REG_B(x)     (TPS68470_REG_GPCTL0B + (x) * 2)
 #define TPS68470_GPIO_MODE_MASK                GENMASK(1, 0)
index b9f6824..11a2a23 100644 (file)
@@ -12,7 +12,7 @@
 
 struct fch_clk_data {
        void __iomem *base;
-       u32 is_rv;
+       char *name;
 };
 
 #endif /* __CLK_FCH_H */