Merge branches 'clk-tegra', 'clk-imx', 'clk-zynq', 'clk-socfpga', 'clk-at91' and...
authorStephen Boyd <sboyd@kernel.org>
Mon, 1 Jun 2020 20:00:00 +0000 (13:00 -0700)
committerStephen Boyd <sboyd@kernel.org>
Mon, 1 Jun 2020 20:00:00 +0000 (13:00 -0700)
 - Support custom flags in Xilinx zynq firmware
 - Various small fixes to the Xilinx clk driver
 - Support for Intel Agilex clks

* clk-tegra:
  clk: tegra: Add Tegra210 CSI TPG clock gate
  clk: tegra30: Use custom CCLK implementation
  clk: tegra20: Use custom CCLK implementation
  clk: tegra: cclk: Add helpers for handling PLLX rate changes
  clk: tegra: pll: Add pre/post rate-change hooks
  clk: tegra: Add custom CCLK implementation
  clk: tegra: Remove the old emc_mux clock for Tegra210
  clk: tegra: Implement Tegra210 EMC clock
  clk: tegra: Export functions for EMC clock scaling
  clk: tegra: Add PLLP_UD and PLLMB_UD for Tegra210
  clk: tegra: Rename Tegra124 EMC clock source file
  dt-bindings: clock: tegra: Add clock ID for CSI TPG clock

* clk-imx:
  clk: imx: use imx8m_clk_hw_composite_bus for i.MX8M bus clk slice
  clk: imx: add imx8m_clk_hw_composite_bus
  clk: imx: add mux ops for i.MX8M composite clk
  clk: imx8m: migrate A53 clk root to use composite core
  clk: imx8mp: use imx8m_clk_hw_composite_core to simplify code
  clk: imx8mp: Define gates for pll1/2 fixed dividers
  clk: imx: imx8mp: fix pll mux bit
  clk: imx8m: drop clk_hw_set_parent for A53
  dt-bindings: clocks: imx8mp: Add ids for audiomix clocks
  clk: imx: Add helpers for passing the device as argument
  clk: imx: pll14xx: Add the device as argument when registering
  clk: imx: gate2: Allow single bit gating clock
  clk: imx: clk-pllv3: Use readl_relaxed_poll_timeout() for PLL lock wait
  clk: imx: clk-sscg-pll: Remove unnecessary blank lines
  clk: imx: drop the dependency on ARM64 for i.MX8M
  clk: imx7ulp: make it easy to change ARM core clk
  clk: imx: imx6ul: change flexcan clock to support CiA bitrates

* clk-zynq:
  clk: zynqmp: Make zynqmp_clk_get_max_divisor static
  clk: zynqmp: Update fraction clock check from custom type flags
  clk: zynqmp: Add support for custom type flags
  clk: zynqmp: fix memory leak in zynqmp_register_clocks
  clk: zynqmp: Fix invalid clock name queries
  clk: zynqmp: Fix divider2 calculation
  clk: zynqmp: Limit bestdiv with maxdiv

* clk-socfpga:
  clk: socfpga: agilex: add clock driver for the Agilex platform
  dt-bindings: documentation: add clock bindings information for Agilex
  clk: socfpga: add const to _ops data structures
  clk: socfpga: remove clk_ops enable/disable methods
  clk: socfpga: stratix10: use new parent data scheme

* clk-at91:
  clk: at91: allow setting all PMC clock parents via DT
  clk: at91: allow setting PCKx parent via DT
  clk: at91: optimize pmc data allocation
  clk: at91: pmc: decrement node's refcount
  clk: at91: pmc: do not continue if compatible not located
  clk: at91: Add peripheral clock for PTC

* clk-ti:
  clk: ti: dra7: remove two unused symbols
  clk: ti: dra7xx: fix RNG clock parent
  clk: ti: dra7xx: mark MCAN clock as DRA76x only
  clk: ti: dra7xx: fix gpu clkctrl parent
  clk: ti: omap5: Add proper parent clocks for l4-secure clocks
  clk: ti: omap4: Add proper parent clocks for l4-secure clocks
  clk: ti: composite: fix memory leak

107 files changed:
Documentation/devicetree/bindings/clock/intel,agilex.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/renesas,cpg-div6-clock.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt [deleted file]
Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt [deleted file]
Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt
MAINTAINERS
arch/Kconfig
arch/arm/Kconfig
arch/arm/mach-actions/Kconfig
arch/arm/mach-clps711x/Kconfig
arch/arm/mach-mmp/Kconfig
arch/arm/mach-mmp/Makefile
arch/arm/mach-mmp/clock-mmp2.c [deleted file]
arch/arm/mach-mmp/clock-pxa168.c [deleted file]
arch/arm/mach-mmp/clock-pxa910.c [deleted file]
arch/arm/mach-mmp/clock.c [deleted file]
arch/arm/mach-mmp/clock.h [deleted file]
arch/arm/mach-mmp/pxa168.c
arch/arm/mach-mmp/time.c
arch/arm/mach-vt8500/Kconfig
arch/arm64/Kconfig.platforms
arch/c6x/Kconfig
arch/h8300/Kconfig
arch/m68k/Kconfig.cpu
arch/mips/Kconfig
arch/mips/loongson2ef/Kconfig
arch/mips/loongson64/smp.c
arch/mips/ralink/Kconfig
arch/sh/boards/Kconfig
arch/unicore32/Kconfig
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/at91/at91rm9200.c
drivers/clk/at91/at91sam9260.c
drivers/clk/at91/at91sam9g45.c
drivers/clk/at91/at91sam9n12.c
drivers/clk/at91/at91sam9rl.c
drivers/clk/at91/at91sam9x5.c
drivers/clk/at91/pmc.c
drivers/clk/at91/pmc.h
drivers/clk/at91/sam9x60.c
drivers/clk/at91/sama5d2.c
drivers/clk/at91/sama5d3.c
drivers/clk/at91/sama5d4.c
drivers/clk/imx/Kconfig
drivers/clk/imx/clk-composite-8m.c
drivers/clk/imx/clk-gate2.c
drivers/clk/imx/clk-imx6ul.c
drivers/clk/imx/clk-imx7ulp.c
drivers/clk/imx/clk-imx8mm.c
drivers/clk/imx/clk-imx8mn.c
drivers/clk/imx/clk-imx8mp.c
drivers/clk/imx/clk-imx8mq.c
drivers/clk/imx/clk-pll14xx.c
drivers/clk/imx/clk-pllv3.c
drivers/clk/imx/clk-sscg-pll.c
drivers/clk/imx/clk.h
drivers/clk/meson/g12a.c
drivers/clk/meson/gxbb.c
drivers/clk/meson/meson8b.c
drivers/clk/meson/meson8b.h
drivers/clk/renesas/Kconfig
drivers/clk/renesas/Makefile
drivers/clk/renesas/r8a7742-cpg-mssr.c [new file with mode: 0644]
drivers/clk/renesas/r9a06g032-clocks.c
drivers/clk/renesas/renesas-cpg-mssr.c
drivers/clk/renesas/renesas-cpg-mssr.h
drivers/clk/samsung/clk-exynos5420.c
drivers/clk/samsung/clk-exynos5433.c
drivers/clk/samsung/clk-s3c2443.c
drivers/clk/socfpga/Makefile
drivers/clk/socfpga/clk-agilex.c [new file with mode: 0644]
drivers/clk/socfpga/clk-gate-s10.c
drivers/clk/socfpga/clk-periph-s10.c
drivers/clk/socfpga/clk-pll-a10.c
drivers/clk/socfpga/clk-pll-s10.c
drivers/clk/socfpga/clk-pll.c
drivers/clk/socfpga/clk-s10.c
drivers/clk/socfpga/stratix10-clk.h
drivers/clk/sunxi/clk-sunxi.c
drivers/clk/tegra/Kconfig
drivers/clk/tegra/Makefile
drivers/clk/tegra/clk-pll.c
drivers/clk/tegra/clk-tegra-super-cclk.c [new file with mode: 0644]
drivers/clk/tegra/clk-tegra124-emc.c [moved from drivers/clk/tegra/clk-emc.c with 100% similarity]
drivers/clk/tegra/clk-tegra20.c
drivers/clk/tegra/clk-tegra210-emc.c [new file with mode: 0644]
drivers/clk/tegra/clk-tegra210.c
drivers/clk/tegra/clk-tegra30.c
drivers/clk/tegra/clk.h
drivers/clk/ti/clk-44xx.c
drivers/clk/ti/clk-54xx.c
drivers/clk/ti/clk-7xx.c
drivers/clk/ti/composite.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/mmc/host/Kconfig
include/dt-bindings/clock/agilex-clock.h [new file with mode: 0644]
include/dt-bindings/clock/at91.h
include/dt-bindings/clock/imx7ulp-clock.h
include/dt-bindings/clock/imx8mp-clock.h
include/dt-bindings/clock/meson8b-clkc.h
include/dt-bindings/clock/r8a7742-cpg-mssr.h [new file with mode: 0644]
include/dt-bindings/clock/tegra210-car.h
include/dt-bindings/power/r8a7742-sysc.h [new file with mode: 0644]
include/linux/clk/tegra.h

diff --git a/Documentation/devicetree/bindings/clock/intel,agilex.yaml b/Documentation/devicetree/bindings/clock/intel,agilex.yaml
new file mode 100644 (file)
index 0000000..cf5a9eb
--- /dev/null
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/intel,agilex.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Intel SoCFPGA Agilex platform clock controller binding
+
+maintainers:
+  - Dinh Nguyen <dinguyen@kernel.org>
+
+description:
+  The Intel Agilex Clock controller is an integrated clock controller, which
+  generates and supplies to all modules.
+
+properties:
+  compatible:
+    const: intel,agilex-clkmgr
+
+  '#clock-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  # Clock controller node:
+  - |
+    clkmgr: clock-controller@ffd10000 {
+      compatible = "intel,agilex-clkmgr";
+      reg = <0xffd10000 0x1000>;
+      clocks = <&osc1>;
+      #clock-cells = <1>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clock.yaml b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clock.yaml
new file mode 100644 (file)
index 0000000..c55a7c4
--- /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/renesas,cpg-div6-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas CPG DIV6 Clock
+
+maintainers:
+  - Geert Uytterhoeven <geert+renesas@glider.be>
+
+description:
+  The CPG DIV6 clocks are variable factor clocks provided by the Clock Pulse
+  Generator (CPG). Their clock input is divided by a configurable factor from 1
+  to 64.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - renesas,r8a73a4-div6-clock # R-Mobile APE6
+          - renesas,r8a7740-div6-clock # R-Mobile A1
+          - renesas,sh73a0-div6-clock  # SH-Mobile AG5
+      - const: renesas,cpg-div6-clock
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    oneOf:
+      - maxItems: 1
+      - maxItems: 4
+      - maxItems: 8
+    description:
+      For clocks with multiple parents, invalid settings must be specified as
+      "<0>".
+
+  '#clock-cells':
+    const: 0
+
+  clock-output-names: true
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/r8a73a4-clock.h>
+    sdhi2_clk: sdhi2_clk@e615007c {
+            compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
+            reg = <0xe615007c 4>;
+            clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>, <0>,
+                     <&extal2_clk>;
+            #clock-cells = <0>;
+    };
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
deleted file mode 100644 (file)
index ae36ab8..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-* Renesas CPG DIV6 Clock
-
-The CPG DIV6 clocks are variable factor clocks provided by the Clock Pulse
-Generator (CPG). Their clock input is divided by a configurable factor from 1
-to 64.
-
-Required Properties:
-
-  - compatible: Must be one of the following
-    - "renesas,r8a73a4-div6-clock" for R8A73A4 (R-Mobile APE6) DIV6 clocks
-    - "renesas,r8a7740-div6-clock" for R8A7740 (R-Mobile A1) DIV6 clocks
-    - "renesas,r8a7790-div6-clock" for R8A7790 (R-Car H2) DIV6 clocks
-    - "renesas,r8a7791-div6-clock" for R8A7791 (R-Car M2-W) DIV6 clocks
-    - "renesas,r8a7793-div6-clock" for R8A7793 (R-Car M2-N) DIV6 clocks
-    - "renesas,r8a7794-div6-clock" for R8A7794 (R-Car E2) DIV6 clocks
-    - "renesas,sh73a0-div6-clock" for SH73A0 (SH-Mobile AG5) DIV6 clocks
-    and "renesas,cpg-div6-clock" as a fallback.
-  - reg: Base address and length of the memory resource used by the DIV6 clock
-  - clocks: Reference to the parent clock(s); either one, four, or eight
-    clocks must be specified.  For clocks with multiple parents, invalid
-    settings must be specified as "<0>".
-  - #clock-cells: Must be 0
-
-
-Optional Properties:
-
-  - clock-output-names: The name of the clock as a free-form string
-
-
-Example
--------
-
-       sdhi2_clk: sdhi2_clk@e615007c {
-               compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
-               reg = <0 0xe615007c 0 4>;
-               clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>,
-                        <0>, <&extal2_clk>;
-               #clock-cells = <0>;
-               clock-output-names = "sdhi2ck";
-       };
index 9cd102e..c745bd6 100644 (file)
@@ -25,6 +25,7 @@ properties:
   compatible:
     enum:
       - renesas,r7s9210-cpg-mssr  # RZ/A2
+      - renesas,r8a7742-cpg-mssr  # RZ/G1H
       - renesas,r8a7743-cpg-mssr  # RZ/G1M
       - renesas,r8a7744-cpg-mssr  # RZ/G1N
       - renesas,r8a7745-cpg-mssr  # RZ/G1E
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
deleted file mode 100644 (file)
index da578eb..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-* Renesas CPG Module Stop (MSTP) Clocks
-
-The CPG can gate SoC device clocks. The gates are organized in groups of up to
-32 gates.
-
-This device tree binding describes a single 32 gate clocks group per node.
-Clocks are referenced by user nodes by the MSTP node phandle and the clock
-index in the group, from 0 to 31.
-
-Required Properties:
-
-  - compatible: Must be one of the following
-    - "renesas,r7s72100-mstp-clocks" for R7S72100 (RZ) MSTP gate clocks
-    - "renesas,r8a73a4-mstp-clocks" for R8A73A4 (R-Mobile APE6) MSTP gate clocks
-    - "renesas,r8a7740-mstp-clocks" for R8A7740 (R-Mobile A1) MSTP gate clocks
-    - "renesas,r8a7778-mstp-clocks" for R8A7778 (R-Car M1) MSTP gate clocks
-    - "renesas,r8a7779-mstp-clocks" for R8A7779 (R-Car H1) MSTP gate clocks
-    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks
-    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2-W) MSTP gate clocks
-    - "renesas,r8a7792-mstp-clocks" for R8A7792 (R-Car V2H) MSTP gate clocks
-    - "renesas,r8a7793-mstp-clocks" for R8A7793 (R-Car M2-N) MSTP gate clocks
-    - "renesas,r8a7794-mstp-clocks" for R8A7794 (R-Car E2) MSTP gate clocks
-    - "renesas,sh73a0-mstp-clocks" for SH73A0 (SH-MobileAG5) MSTP gate clocks
-    and "renesas,cpg-mstp-clocks" as a fallback.
-  - reg: Base address and length of the I/O mapped registers used by the MSTP
-    clocks. The first register is the clock control register and is mandatory.
-    The second register is the clock status register and is optional when not
-    implemented in hardware.
-  - clocks: Reference to the parent clocks, one per output clock. The parents
-    must appear in the same order as the output clocks.
-  - #clock-cells: Must be 1
-  - clock-output-names: The name of the clocks as free-form strings
-  - clock-indices: Indices of the gate clocks into the group (0 to 31)
-
-The clocks, clock-output-names and clock-indices properties contain one entry
-per gate clock. The MSTP groups are sparsely populated. Unimplemented gate
-clocks must not be declared.
-
-
-Example
--------
-
-       #include <dt-bindings/clock/r8a7790-clock.h>
-
-       mstp3_clks: mstp3_clks@e615013c {
-               compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
-               reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
-               clocks = <&cp_clk>, <&mmc1_clk>, <&sd3_clk>, <&sd2_clk>,
-                        <&cpg_clocks R8A7790_CLK_SD1>, <&cpg_clocks R8A7790_CLK_SD0>,
-                        <&mmc0_clk>;
-               #clock-cells = <1>;
-               clock-output-names =
-                       "tpu0", "mmcif1", "sdhi3", "sdhi2",
-                        "sdhi1", "sdhi0", "mmcif0";
-               clock-indices = <
-                       R8A7790_CLK_TPU0 R8A7790_CLK_MMCIF1 R8A7790_CLK_SDHI3
-                       R8A7790_CLK_SDHI2 R8A7790_CLK_SDHI1 R8A7790_CLK_SDHI0
-                       R8A7790_CLK_MMCIF0
-               >;
-       };
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.yaml b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.yaml
new file mode 100644 (file)
index 0000000..9752ac6
--- /dev/null
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/renesas,cpg-mstp-clocks.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas Clock Pulse Generator (CPG) Module Stop (MSTP) Clocks
+
+maintainers:
+  - Geert Uytterhoeven <geert+renesas@glider.be>
+
+description:
+  The Clock Pulse Generator (CPG) can gate SoC device clocks. The gates are
+  organized in groups of up to 32 gates.
+
+  This device tree binding describes a single 32 gate clocks group per node.
+  Clocks are referenced by user nodes by the Module Stop (MSTP) node phandle
+  and the clock index in the group, from 0 to 31.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - renesas,r7s72100-mstp-clocks # RZ/A1
+          - renesas,r8a73a4-mstp-clocks  # R-Mobile APE6
+          - renesas,r8a7740-mstp-clocks  # R-Mobile A1
+          - renesas,r8a7778-mstp-clocks  # R-Car M1
+          - renesas,r8a7779-mstp-clocks  # R-Car H1
+          - renesas,sh73a0-mstp-clocks   # SH-Mobile AG5
+      - const: renesas,cpg-mstp-clocks
+
+  reg:
+    minItems: 1
+    items:
+      - description: Module Stop Control Register (MSTPCR)
+      - description: Module Stop Status Register (MSTPSR)
+
+  clocks:
+    minItems: 1
+    maxItems: 32
+
+  '#clock-cells':
+    const: 1
+
+  clock-indices:
+    minItems: 1
+    maxItems: 32
+
+  clock-output-names:
+    minItems: 1
+    maxItems: 32
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#clock-cells'
+  - clock-indices
+  - clock-output-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/r8a73a4-clock.h>
+    mstp2_clks: mstp2_clks@e6150138 {
+            compatible = "renesas,r8a73a4-mstp-clocks",
+                         "renesas,cpg-mstp-clocks";
+            reg = <0xe6150138 4>, <0xe6150040 4>;
+            clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>,
+                     <&mp_clk>, <&cpg_clocks R8A73A4_CLK_HP>;
+            #clock-cells = <1>;
+            clock-indices = <
+                    R8A73A4_CLK_SCIFA0 R8A73A4_CLK_SCIFA1
+                    R8A73A4_CLK_SCIFB0 R8A73A4_CLK_SCIFB1
+                    R8A73A4_CLK_SCIFB2 R8A73A4_CLK_SCIFB3
+                    R8A73A4_CLK_DMAC
+            >;
+            clock-output-names =
+                    "scifa0", "scifa1", "scifb0", "scifb1", "scifb2", "scifb3",
+                    "dmac";
+    };
index 4bf6f53..da92f57 100644 (file)
@@ -27,7 +27,9 @@ Required properties:
 - compatible: "renesas,r8a7795-rcar-usb2-clock-sel" if the device is a part of
              an R8A7795 SoC.
              "renesas,r8a7796-rcar-usb2-clock-sel" if the device if a part of
-             an R8A7796 SoC.
+             an R8A77960 SoC.
+             "renesas,r8a77961-rcar-usb2-clock-sel" if the device if a part of
+             an R8A77961 SoC.
              "renesas,rcar-gen3-usb2-clock-sel" for a generic R-Car Gen3
              compatible device.
 
index e64e5db..1c4f7c6 100644 (file)
@@ -14334,6 +14334,7 @@ M:      Geert Uytterhoeven <geert+renesas@glider.be>
 L:     linux-renesas-soc@vger.kernel.org
 S:     Supported
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git clk-renesas
+F:     Documentation/devicetree/bindings/clock/renesas,*
 F:     drivers/clk/renesas/
 
 RENESAS EMEV2 I2C DRIVER
index 786a85d..84fe540 100644 (file)
@@ -328,12 +328,6 @@ config HAVE_FUNCTION_ARG_ACCESS_API
          the API needed to access function arguments from pt_regs,
          declared in asm/ptrace.h
 
-config HAVE_CLK
-       bool
-       help
-         The <linux/clk.h> calls support software clock gating and
-         thus are a key power management tool on many systems.
-
 config HAVE_HW_BREAKPOINT
        bool
        depends on PERF_EVENTS
index 66a04f6..6e15460 100644 (file)
@@ -363,6 +363,7 @@ config ARCH_EP93XX
        select CPU_ARM920T
        select GENERIC_CLOCKEVENTS
        select GPIOLIB
+       select HAVE_LEGACY_CLK
        help
          This enables support for the Cirrus EP93xx series of CPUs.
 
@@ -434,7 +435,6 @@ config ARCH_PXA
        select ARM_CPU_SUSPEND if PM
        select AUTO_ZRELADDR
        select COMMON_CLK
-       select CLKDEV_LOOKUP
        select CLKSRC_PXA
        select CLKSRC_MMIO
        select TIMER_OF
@@ -473,7 +473,6 @@ config ARCH_SA1100
        bool "SA1100-based"
        select ARCH_MTD_XIP
        select ARCH_SPARSEMEM_ENABLE
-       select CLKDEV_LOOKUP
        select CLKSRC_MMIO
        select CLKSRC_PXA
        select TIMER_OF if OF
@@ -494,7 +493,6 @@ config ARCH_SA1100
 config ARCH_S3C24XX
        bool "Samsung S3C24XX SoCs"
        select ATAGS
-       select CLKDEV_LOOKUP
        select CLKSRC_SAMSUNG_PWM
        select GENERIC_CLOCKEVENTS
        select GPIO_SAMSUNG
@@ -524,6 +522,7 @@ config ARCH_OMAP1
        select GENERIC_IRQ_MULTI_HANDLER
        select GPIOLIB
        select HAVE_IDE
+       select HAVE_LEGACY_CLK
        select IRQ_DOMAIN
        select NEED_MACH_IO_H if PCCARD
        select NEED_MACH_MEMORY_H
index b5e0ac9..00fb4ba 100644 (file)
@@ -7,7 +7,6 @@ menuconfig ARCH_ACTIONS
        select ARM_GLOBAL_TIMER
        select CACHE_L2X0
        select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
-       select COMMON_CLK
        select GENERIC_IRQ_CHIP
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
index fc9188b..ba497a2 100644 (file)
@@ -5,7 +5,6 @@ menuconfig ARCH_CLPS711X
        select AUTO_ZRELADDR
        select TIMER_OF
        select CLPS711X_TIMER
-       select COMMON_CLK
        select CPU_ARM720T
        select GENERIC_CLOCKEVENTS
        select GPIOLIB
index b58a03b..6fe1550 100644 (file)
@@ -110,7 +110,6 @@ config MACH_MMP_DT
        depends on ARCH_MULTI_V5
        select PINCTRL
        select PINCTRL_SINGLE
-       select COMMON_CLK
        select ARCH_HAS_RESET_CONTROLLER
        select CPU_MOHAWK
        help
index 7b3a7f9..e3758f7 100644 (file)
@@ -12,12 +12,6 @@ obj-$(CONFIG_CPU_PXA910)     += pxa910.o
 obj-$(CONFIG_CPU_MMP2)         += mmp2.o
 obj-$(CONFIG_MMP_SRAM)         += sram.o
 
-ifeq ($(CONFIG_COMMON_CLK), )
-obj-y                          += clock.o
-obj-$(CONFIG_CPU_PXA168)       += clock-pxa168.o
-obj-$(CONFIG_CPU_PXA910)       += clock-pxa910.o
-obj-$(CONFIG_CPU_MMP2)         += clock-mmp2.o
-endif
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_CPU_PXA910)       += pm-pxa910.o
 obj-$(CONFIG_CPU_MMP2)         += pm-mmp2.o
diff --git a/arch/arm/mach-mmp/clock-mmp2.c b/arch/arm/mach-mmp/clock-mmp2.c
deleted file mode 100644 (file)
index 7536398..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/clk/mmp.h>
-
-#include "addr-map.h"
-
-#include "common.h"
-#include "clock.h"
-
-/*
- * APB Clock register offsets for MMP2
- */
-#define APBC_RTC       APBC_REG(0x000)
-#define APBC_TWSI1     APBC_REG(0x004)
-#define APBC_TWSI2     APBC_REG(0x008)
-#define APBC_TWSI3     APBC_REG(0x00c)
-#define APBC_TWSI4     APBC_REG(0x010)
-#define APBC_KPC       APBC_REG(0x018)
-#define APBC_UART1     APBC_REG(0x02c)
-#define APBC_UART2     APBC_REG(0x030)
-#define APBC_UART3     APBC_REG(0x034)
-#define APBC_GPIO      APBC_REG(0x038)
-#define APBC_PWM0      APBC_REG(0x03c)
-#define APBC_PWM1      APBC_REG(0x040)
-#define APBC_PWM2      APBC_REG(0x044)
-#define APBC_PWM3      APBC_REG(0x048)
-#define APBC_SSP0      APBC_REG(0x04c)
-#define APBC_SSP1      APBC_REG(0x050)
-#define APBC_SSP2      APBC_REG(0x054)
-#define APBC_SSP3      APBC_REG(0x058)
-#define APBC_SSP4      APBC_REG(0x05c)
-#define APBC_SSP5      APBC_REG(0x060)
-#define APBC_TWSI5     APBC_REG(0x07c)
-#define APBC_TWSI6     APBC_REG(0x080)
-#define APBC_UART4     APBC_REG(0x088)
-
-#define APMU_USB       APMU_REG(0x05c)
-#define APMU_NAND      APMU_REG(0x060)
-#define APMU_SDH0      APMU_REG(0x054)
-#define APMU_SDH1      APMU_REG(0x058)
-#define APMU_SDH2      APMU_REG(0x0e8)
-#define APMU_SDH3      APMU_REG(0x0ec)
-
-static void sdhc_clk_enable(struct clk *clk)
-{
-       uint32_t clk_rst;
-
-       clk_rst  =  __raw_readl(clk->clk_rst);
-       clk_rst |= clk->enable_val;
-       __raw_writel(clk_rst, clk->clk_rst);
-}
-
-static void sdhc_clk_disable(struct clk *clk)
-{
-       uint32_t clk_rst;
-
-       clk_rst  =  __raw_readl(clk->clk_rst);
-       clk_rst &= ~clk->enable_val;
-       __raw_writel(clk_rst, clk->clk_rst);
-}
-
-struct clkops sdhc_clk_ops = {
-       .enable         = sdhc_clk_enable,
-       .disable        = sdhc_clk_disable,
-};
-
-/* APB peripheral clocks */
-static APBC_CLK(uart1, UART1, 1, 26000000);
-static APBC_CLK(uart2, UART2, 1, 26000000);
-static APBC_CLK(uart3, UART3, 1, 26000000);
-static APBC_CLK(uart4, UART4, 1, 26000000);
-static APBC_CLK(twsi1, TWSI1, 0, 26000000);
-static APBC_CLK(twsi2, TWSI2, 0, 26000000);
-static APBC_CLK(twsi3, TWSI3, 0, 26000000);
-static APBC_CLK(twsi4, TWSI4, 0, 26000000);
-static APBC_CLK(twsi5, TWSI5, 0, 26000000);
-static APBC_CLK(twsi6, TWSI6, 0, 26000000);
-static APBC_CLK(gpio, GPIO, 0, 26000000);
-
-static APMU_CLK(nand, NAND, 0xbf, 100000000);
-static APMU_CLK_OPS(sdh0, SDH0, 0x1b, 200000000, &sdhc_clk_ops);
-static APMU_CLK_OPS(sdh1, SDH1, 0x1b, 200000000, &sdhc_clk_ops);
-static APMU_CLK_OPS(sdh2, SDH2, 0x1b, 200000000, &sdhc_clk_ops);
-static APMU_CLK_OPS(sdh3, SDH3, 0x1b, 200000000, &sdhc_clk_ops);
-
-static struct clk_lookup mmp2_clkregs[] = {
-       INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
-       INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
-       INIT_CLKREG(&clk_uart3, "pxa2xx-uart.2", NULL),
-       INIT_CLKREG(&clk_uart4, "pxa2xx-uart.3", NULL),
-       INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.0", NULL),
-       INIT_CLKREG(&clk_twsi2, "pxa2xx-i2c.1", NULL),
-       INIT_CLKREG(&clk_twsi3, "pxa2xx-i2c.2", NULL),
-       INIT_CLKREG(&clk_twsi4, "pxa2xx-i2c.3", NULL),
-       INIT_CLKREG(&clk_twsi5, "pxa2xx-i2c.4", NULL),
-       INIT_CLKREG(&clk_twsi6, "pxa2xx-i2c.5", NULL),
-       INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
-       INIT_CLKREG(&clk_gpio, "mmp2-gpio", NULL),
-       INIT_CLKREG(&clk_sdh0, "sdhci-pxav3.0", "PXA-SDHCLK"),
-       INIT_CLKREG(&clk_sdh1, "sdhci-pxav3.1", "PXA-SDHCLK"),
-       INIT_CLKREG(&clk_sdh2, "sdhci-pxav3.2", "PXA-SDHCLK"),
-       INIT_CLKREG(&clk_sdh3, "sdhci-pxav3.3", "PXA-SDHCLK"),
-};
-
-void __init mmp2_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
-                         phys_addr_t apbc_phys)
-{
-       clkdev_add_table(ARRAY_AND_SIZE(mmp2_clkregs));
-}
diff --git a/arch/arm/mach-mmp/clock-pxa168.c b/arch/arm/mach-mmp/clock-pxa168.c
deleted file mode 100644 (file)
index 2d4a5d9..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/clk/mmp.h>
-
-#include "addr-map.h"
-
-#include "common.h"
-#include "clock.h"
-
-/*
- * APB clock register offsets for PXA168
- */
-#define APBC_UART1     APBC_REG(0x000)
-#define APBC_UART2     APBC_REG(0x004)
-#define APBC_GPIO      APBC_REG(0x008)
-#define APBC_PWM1      APBC_REG(0x00c)
-#define APBC_PWM2      APBC_REG(0x010)
-#define APBC_PWM3      APBC_REG(0x014)
-#define APBC_PWM4      APBC_REG(0x018)
-#define APBC_RTC       APBC_REG(0x028)
-#define APBC_TWSI0     APBC_REG(0x02c)
-#define APBC_KPC       APBC_REG(0x030)
-#define APBC_TWSI1     APBC_REG(0x06c)
-#define APBC_UART3     APBC_REG(0x070)
-#define APBC_SSP1      APBC_REG(0x81c)
-#define APBC_SSP2      APBC_REG(0x820)
-#define APBC_SSP3      APBC_REG(0x84c)
-#define APBC_SSP4      APBC_REG(0x858)
-#define APBC_SSP5      APBC_REG(0x85c)
-
-#define APMU_NAND      APMU_REG(0x060)
-#define APMU_LCD       APMU_REG(0x04c)
-#define APMU_ETH       APMU_REG(0x0fc)
-#define APMU_USB       APMU_REG(0x05c)
-
-/* APB peripheral clocks */
-static APBC_CLK(uart1, UART1, 1, 14745600);
-static APBC_CLK(uart2, UART2, 1, 14745600);
-static APBC_CLK(uart3, UART3, 1, 14745600);
-static APBC_CLK(twsi0, TWSI0, 1, 33000000);
-static APBC_CLK(twsi1, TWSI1, 1, 33000000);
-static APBC_CLK(pwm1, PWM1, 1, 13000000);
-static APBC_CLK(pwm2, PWM2, 1, 13000000);
-static APBC_CLK(pwm3, PWM3, 1, 13000000);
-static APBC_CLK(pwm4, PWM4, 1, 13000000);
-static APBC_CLK(ssp1, SSP1, 4, 0);
-static APBC_CLK(ssp2, SSP2, 4, 0);
-static APBC_CLK(ssp3, SSP3, 4, 0);
-static APBC_CLK(ssp4, SSP4, 4, 0);
-static APBC_CLK(ssp5, SSP5, 4, 0);
-static APBC_CLK(gpio, GPIO, 0, 13000000);
-static APBC_CLK(keypad, KPC, 0, 32000);
-static APBC_CLK(rtc, RTC, 8, 32768);
-
-static APMU_CLK(nand, NAND, 0x19b, 156000000);
-static APMU_CLK(lcd, LCD, 0x7f, 312000000);
-static APMU_CLK(eth, ETH, 0x09, 0);
-static APMU_CLK(usb, USB, 0x12, 0);
-
-/* device and clock bindings */
-static struct clk_lookup pxa168_clkregs[] = {
-       INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
-       INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
-       INIT_CLKREG(&clk_uart3, "pxa2xx-uart.2", NULL),
-       INIT_CLKREG(&clk_twsi0, "pxa2xx-i2c.0", NULL),
-       INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.1", NULL),
-       INIT_CLKREG(&clk_pwm1, "pxa168-pwm.0", NULL),
-       INIT_CLKREG(&clk_pwm2, "pxa168-pwm.1", NULL),
-       INIT_CLKREG(&clk_pwm3, "pxa168-pwm.2", NULL),
-       INIT_CLKREG(&clk_pwm4, "pxa168-pwm.3", NULL),
-       INIT_CLKREG(&clk_ssp1, "pxa168-ssp.0", NULL),
-       INIT_CLKREG(&clk_ssp2, "pxa168-ssp.1", NULL),
-       INIT_CLKREG(&clk_ssp3, "pxa168-ssp.2", NULL),
-       INIT_CLKREG(&clk_ssp4, "pxa168-ssp.3", NULL),
-       INIT_CLKREG(&clk_ssp5, "pxa168-ssp.4", NULL),
-       INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
-       INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL),
-       INIT_CLKREG(&clk_gpio, "mmp-gpio", NULL),
-       INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL),
-       INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"),
-       INIT_CLKREG(&clk_usb, NULL, "PXA168-USBCLK"),
-       INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
-};
-
-void __init pxa168_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
-                           phys_addr_t apbc_phys)
-{
-       clkdev_add_table(ARRAY_AND_SIZE(pxa168_clkregs));
-}
diff --git a/arch/arm/mach-mmp/clock-pxa910.c b/arch/arm/mach-mmp/clock-pxa910.c
deleted file mode 100644 (file)
index 3cd83ff..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/clk/mmp.h>
-
-#include "addr-map.h"
-
-#include "common.h"
-#include "clock.h"
-
-/*
- * APB Clock register offsets for PXA910
- */
-#define APBC_UART0     APBC_REG(0x000)
-#define APBC_UART1     APBC_REG(0x004)
-#define APBC_GPIO      APBC_REG(0x008)
-#define APBC_PWM1      APBC_REG(0x00c)
-#define APBC_PWM2      APBC_REG(0x010)
-#define APBC_PWM3      APBC_REG(0x014)
-#define APBC_PWM4      APBC_REG(0x018)
-#define APBC_SSP1      APBC_REG(0x01c)
-#define APBC_SSP2      APBC_REG(0x020)
-#define APBC_RTC       APBC_REG(0x028)
-#define APBC_TWSI0     APBC_REG(0x02c)
-#define APBC_KPC       APBC_REG(0x030)
-#define APBC_SSP3      APBC_REG(0x04c)
-#define APBC_TWSI1     APBC_REG(0x06c)
-
-#define APMU_NAND      APMU_REG(0x060)
-#define APMU_USB       APMU_REG(0x05c)
-
-static APBC_CLK(uart1, UART0, 1, 14745600);
-static APBC_CLK(uart2, UART1, 1, 14745600);
-static APBC_CLK(twsi0, TWSI0, 1, 33000000);
-static APBC_CLK(twsi1, TWSI1, 1, 33000000);
-static APBC_CLK(pwm1, PWM1, 1, 13000000);
-static APBC_CLK(pwm2, PWM2, 1, 13000000);
-static APBC_CLK(pwm3, PWM3, 1, 13000000);
-static APBC_CLK(pwm4, PWM4, 1, 13000000);
-static APBC_CLK(gpio, GPIO, 0, 13000000);
-static APBC_CLK(rtc, RTC, 8, 32768);
-
-static APMU_CLK(nand, NAND, 0x19b, 156000000);
-static APMU_CLK(u2o, USB, 0x1b, 480000000);
-
-/* device and clock bindings */
-static struct clk_lookup pxa910_clkregs[] = {
-       INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
-       INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
-       INIT_CLKREG(&clk_twsi0, "pxa2xx-i2c.0", NULL),
-       INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.1", NULL),
-       INIT_CLKREG(&clk_pwm1, "pxa910-pwm.0", NULL),
-       INIT_CLKREG(&clk_pwm2, "pxa910-pwm.1", NULL),
-       INIT_CLKREG(&clk_pwm3, "pxa910-pwm.2", NULL),
-       INIT_CLKREG(&clk_pwm4, "pxa910-pwm.3", NULL),
-       INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
-       INIT_CLKREG(&clk_gpio, "mmp-gpio", NULL),
-       INIT_CLKREG(&clk_u2o, NULL, "U2OCLK"),
-       INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
-};
-
-void __init pxa910_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
-                           phys_addr_t apbc_phys, phys_addr_t apbcp_phys)
-{
-       clkdev_add_table(ARRAY_AND_SIZE(pxa910_clkregs));
-}
diff --git a/arch/arm/mach-mmp/clock.c b/arch/arm/mach-mmp/clock.c
deleted file mode 100644 (file)
index 291fe41..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *  linux/arch/arm/mach-mmp/clock.c
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include "regs-apbc.h"
-#include "clock.h"
-
-static void apbc_clk_enable(struct clk *clk)
-{
-       uint32_t clk_rst;
-
-       clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(clk->fnclksel);
-       __raw_writel(clk_rst, clk->clk_rst);
-}
-
-static void apbc_clk_disable(struct clk *clk)
-{
-       __raw_writel(0, clk->clk_rst);
-}
-
-struct clkops apbc_clk_ops = {
-       .enable         = apbc_clk_enable,
-       .disable        = apbc_clk_disable,
-};
-
-static void apmu_clk_enable(struct clk *clk)
-{
-       __raw_writel(clk->enable_val, clk->clk_rst);
-}
-
-static void apmu_clk_disable(struct clk *clk)
-{
-       __raw_writel(0, clk->clk_rst);
-}
-
-struct clkops apmu_clk_ops = {
-       .enable         = apmu_clk_enable,
-       .disable        = apmu_clk_disable,
-};
-
-static DEFINE_SPINLOCK(clocks_lock);
-
-int clk_enable(struct clk *clk)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&clocks_lock, flags);
-       if (clk->enabled++ == 0)
-               clk->ops->enable(clk);
-       spin_unlock_irqrestore(&clocks_lock, flags);
-       return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-       unsigned long flags;
-
-       if (!clk)
-               return;
-
-       WARN_ON(clk->enabled == 0);
-
-       spin_lock_irqsave(&clocks_lock, flags);
-       if (--clk->enabled == 0)
-               clk->ops->disable(clk);
-       spin_unlock_irqrestore(&clocks_lock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-       unsigned long rate;
-
-       if (clk->ops->getrate)
-               rate = clk->ops->getrate(clk);
-       else
-               rate = clk->rate;
-
-       return rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-       unsigned long flags;
-       int ret = -EINVAL;
-
-       if (clk->ops->setrate) {
-               spin_lock_irqsave(&clocks_lock, flags);
-               ret = clk->ops->setrate(clk, rate);
-               spin_unlock_irqrestore(&clocks_lock, flags);
-       }
-
-       return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
diff --git a/arch/arm/mach-mmp/clock.h b/arch/arm/mach-mmp/clock.h
deleted file mode 100644 (file)
index 0256c89..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#include <linux/clkdev.h>
-
-struct clkops {
-       void                    (*enable)(struct clk *);
-       void                    (*disable)(struct clk *);
-       unsigned long           (*getrate)(struct clk *);
-       int                     (*setrate)(struct clk *, unsigned long);
-};
-
-struct clk {
-       const struct clkops     *ops;
-
-       void __iomem    *clk_rst;       /* clock reset control register */
-       int             fnclksel;       /* functional clock select (APBC) */
-       uint32_t        enable_val;     /* value for clock enable (APMU) */
-       unsigned long   rate;
-       int             enabled;
-};
-
-extern struct clkops apbc_clk_ops;
-extern struct clkops apmu_clk_ops;
-
-#define APBC_CLK(_name, _reg, _fnclksel, _rate)                        \
-struct clk clk_##_name = {                                     \
-               .clk_rst        = APBC_##_reg,                  \
-               .fnclksel       = _fnclksel,                    \
-               .rate           = _rate,                        \
-               .ops            = &apbc_clk_ops,                \
-}
-
-#define APBC_CLK_OPS(_name, _reg, _fnclksel, _rate, _ops)      \
-struct clk clk_##_name = {                                     \
-               .clk_rst        = APBC_##_reg,                  \
-               .fnclksel       = _fnclksel,                    \
-               .rate           = _rate,                        \
-               .ops            = _ops,                         \
-}
-
-#define APMU_CLK(_name, _reg, _eval, _rate)                    \
-struct clk clk_##_name = {                                     \
-               .clk_rst        = APMU_##_reg,                  \
-               .enable_val     = _eval,                        \
-               .rate           = _rate,                        \
-               .ops            = &apmu_clk_ops,                \
-}
-
-#define APMU_CLK_OPS(_name, _reg, _eval, _rate, _ops)          \
-struct clk clk_##_name = {                                     \
-               .clk_rst        = APMU_##_reg,                  \
-               .enable_val     = _eval,                        \
-               .rate           = _rate,                        \
-               .ops            = _ops,                         \
-}
-
-#define INIT_CLKREG(_clk, _devname, _conname)                  \
-       {                                                       \
-               .clk            = _clk,                         \
-               .dev_id         = _devname,                     \
-               .con_id         = _conname,                     \
-       }
-
-extern struct clk clk_pxa168_gpio;
-extern struct clk clk_pxa168_timers;
index b642e90..1e93892 100644 (file)
@@ -19,7 +19,6 @@
 #include <asm/system_misc.h>
 
 #include "addr-map.h"
-#include "clock.h"
 #include "common.h"
 #include <linux/soc/mmp/cputype.h>
 #include "devices.h"
index 049a65f..41b2e8a 100644 (file)
@@ -34,7 +34,6 @@
 #include "regs-apbc.h"
 #include "irqs.h"
 #include <linux/soc/mmp/cputype.h>
-#include "clock.h"
 
 #define TIMERS_VIRT_BASE       TIMERS1_VIRT_BASE
 
index 8841199..d01cdd9 100644 (file)
@@ -2,7 +2,6 @@
 config ARCH_VT8500
        bool
        select GPIOLIB
-       select CLKDEV_LOOKUP
        select VT8500_TIMER
        select PINCTRL
        help
index 55d70cf..0c7fcde 100644 (file)
@@ -235,7 +235,6 @@ config ARCH_TEGRA
        bool "NVIDIA Tegra SoC Family"
        select ARCH_HAS_RESET_CONTROLLER
        select ARM_GIC_PM
-       select CLKDEV_LOOKUP
        select CLKSRC_MMIO
        select TIMER_OF
        select GENERIC_CLOCKEVENTS
index e65e8d8..6444ebf 100644 (file)
@@ -11,6 +11,7 @@ config C6X
        select ARCH_HAS_SYNC_DMA_FOR_CPU
        select ARCH_HAS_SYNC_DMA_FOR_DEVICE
        select CLKDEV_LOOKUP
+       select HAVE_LEGACY_CLK
        select GENERIC_ATOMIC64
        select GENERIC_IRQ_SHOW
        select HAVE_ARCH_TRACEHOOK
index ec800e9..d11666d 100644 (file)
@@ -13,7 +13,6 @@ config H8300
        select GENERIC_CPU_DEVICES
        select MODULES_USE_ELF_RELA
        select GENERIC_CLOCKEVENTS
-       select CLKDEV_LOOKUP
        select COMMON_CLK
        select ARCH_WANT_FRAME_POINTERS
        select OF
index 60ac1cd..bd2d29c 100644 (file)
@@ -28,7 +28,7 @@ config COLDFIRE
        select CPU_HAS_NO_MULDIV64
        select GENERIC_CSUM
        select GPIOLIB
-       select HAVE_CLK
+       select HAVE_LEGACY_CLK
 
 endchoice
 
index 690718b..da75306 100644 (file)
@@ -181,7 +181,7 @@ config AR7
        select SYS_SUPPORTS_ZBOOT_UART16550
        select GPIOLIB
        select VLYNQ
-       select HAVE_CLK
+       select HAVE_LEGACY_CLK
        help
          Support for the Texas Instruments AR7 System-on-a-Chip
          family: TNETD7100, 7200 and 7300.
@@ -209,9 +209,7 @@ config ATH79
        select DMA_NONCOHERENT
        select GPIOLIB
        select PINCTRL
-       select HAVE_CLK
        select COMMON_CLK
-       select CLKDEV_LOOKUP
        select IRQ_MIPS_CPU
        select SYS_HAS_CPU_MIPS32_R2
        select SYS_HAS_EARLY_PRINTK
@@ -298,9 +296,9 @@ config BCM63XX
        select SYS_HAS_EARLY_PRINTK
        select SWAP_IO_SPACE
        select GPIOLIB
-       select HAVE_CLK
        select MIPS_L1_CACHE_SHIFT_4
        select CLKDEV_LOOKUP
+       select HAVE_LEGACY_CLK
        help
          Support for BCM63XX based boards
 
@@ -421,6 +419,7 @@ config LANTIQ
        select SWAP_IO_SPACE
        select BOOT_RAW
        select CLKDEV_LOOKUP
+       select HAVE_LEGACY_CLK
        select USE_OF
        select PINCTRL
        select PINCTRL_LANTIQ
index 595dd48..c9ec43a 100644 (file)
@@ -46,7 +46,7 @@ config LEMOTE_MACH2F
        select CSRC_R4K if ! MIPS_EXTERNAL_TIMER
        select DMA_NONCOHERENT
        select GENERIC_ISA_DMA_SUPPORT_BROKEN
-       select HAVE_CLK
+       select HAVE_LEGACY_CLK
        select FORCE_PCI
        select I8259
        select IRQ_MIPS_CPU
index e1fe8bb..e744e1b 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/kexec.h>
 #include <asm/processor.h>
 #include <asm/time.h>
-#include <asm/clock.h>
 #include <asm/tlbflush.h>
 #include <asm/cacheflush.h>
 #include <loongson.h>
index 35c2ebd..c10d8b2 100644 (file)
@@ -27,18 +27,22 @@ choice
        config SOC_RT288X
                bool "RT288x"
                select MIPS_L1_CACHE_SHIFT_4
+               select HAVE_LEGACY_CLK
                select HAVE_PCI
 
        config SOC_RT305X
                bool "RT305x"
+               select HAVE_LEGACY_CLK
 
        config SOC_RT3883
                bool "RT3883"
+               select HAVE_LEGACY_CLK
                select HAVE_PCI
 
        config SOC_MT7620
                bool "MT7620/8"
                select CPU_MIPSR2_IRQ_VI
+               select HAVE_LEGACY_CLK
                select HAVE_PCI
 
        config SOC_MT7621
index cee24c3..fb0ca0c 100644 (file)
@@ -7,6 +7,11 @@ config SOLUTION_ENGINE
 config SH_ALPHA_BOARD
        bool
 
+config SH_CUSTOM_CLK
+       def_bool y
+       depends on !SH_DEVICE_TREE
+       select HAVE_LEGACY_CLK
+
 config SH_DEVICE_TREE
        bool
        select OF
index 41fe944..11ba183 100644 (file)
@@ -70,7 +70,7 @@ config ARCH_PUV3
        def_bool y
        select CPU_UCV2
        select GENERIC_CLOCKEVENTS
-       select HAVE_CLK
+       select HAVE_LEGACY_CLK
        select GPIOLIB
 
 # CONFIGs for ARCH_PUV3
index bcb257b..6ea0631 100644 (file)
@@ -1,5 +1,11 @@
 # SPDX-License-Identifier: GPL-2.0
 
+config HAVE_CLK
+       bool
+       help
+         The <linux/clk.h> calls support software clock gating and
+         thus are a key power management tool on many systems.
+
 config CLKDEV_LOOKUP
        bool
        select HAVE_CLK
@@ -7,8 +13,18 @@ config CLKDEV_LOOKUP
 config HAVE_CLK_PREPARE
        bool
 
-config COMMON_CLK
+config HAVE_LEGACY_CLK # TODO: Remove once all legacy users are migrated
        bool
+       select HAVE_CLK
+       help
+         Select this option when the clock API in <linux/clk.h> is implemented
+         by platform/architecture code. This method is deprecated. Modern
+         code should select COMMON_CLK instead and not define a custom
+         'struct clk'.
+
+menuconfig COMMON_CLK
+       bool "Common Clock Framework"
+       depends on !HAVE_LEGACY_CLK
        select HAVE_CLK_PREPARE
        select CLKDEV_LOOKUP
        select SRCU
@@ -20,8 +36,7 @@ config COMMON_CLK
          Architectures utilizing the common struct clk should select
          this option.
 
-menu "Common Clock Framework"
-       depends on COMMON_CLK
+if COMMON_CLK
 
 config COMMON_CLK_WM831X
        tristate "Clock driver for WM831x/2x PMICs"
@@ -362,4 +377,4 @@ source "drivers/clk/ti/Kconfig"
 source "drivers/clk/uniphier/Kconfig"
 source "drivers/clk/zynqmp/Kconfig"
 
-endmenu
+endif
index f4169cc..a178e4b 100644 (file)
@@ -104,10 +104,11 @@ obj-$(CONFIG_COMMON_CLK_SAMSUNG)  += samsung/
 obj-$(CONFIG_CLK_SIFIVE)               += sifive/
 obj-$(CONFIG_ARCH_SIRF)                        += sirf/
 obj-$(CONFIG_ARCH_SOCFPGA)             += socfpga/
+obj-$(CONFIG_ARCH_AGILEX)              += socfpga/
+obj-$(CONFIG_ARCH_STRATIX10)           += socfpga/
 obj-$(CONFIG_PLAT_SPEAR)               += spear/
 obj-$(CONFIG_ARCH_SPRD)                        += sprd/
 obj-$(CONFIG_ARCH_STI)                 += st/
-obj-$(CONFIG_ARCH_STRATIX10)           += socfpga/
 obj-$(CONFIG_ARCH_SUNXI)               += sunxi/
 obj-$(CONFIG_SUNXI_CCU)                        += sunxi-ng/
 obj-$(CONFIG_ARCH_TEGRA)               += tegra/
index c44a431..38bdb49 100644 (file)
@@ -98,9 +98,9 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
        if (IS_ERR(regmap))
                return;
 
-       at91rm9200_pmc = pmc_data_allocate(PMC_MAIN + 1,
+       at91rm9200_pmc = pmc_data_allocate(PMC_PLLBCK + 1,
                                            nck(at91rm9200_systemck),
-                                           nck(at91rm9200_periphck), 0);
+                                           nck(at91rm9200_periphck), 0, 4);
        if (!at91rm9200_pmc)
                return;
 
@@ -123,12 +123,16 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
        if (IS_ERR(hw))
                goto err_free;
 
+       at91rm9200_pmc->chws[PMC_PLLACK] = hw;
+
        hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1,
                                   &at91rm9200_pll_layout,
                                   &rm9200_pll_characteristics);
        if (IS_ERR(hw))
                goto err_free;
 
+       at91rm9200_pmc->chws[PMC_PLLBCK] = hw;
+
        parent_names[0] = slowxtal_name;
        parent_names[1] = "mainck";
        parent_names[2] = "pllack";
@@ -159,6 +163,8 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
                                                    &at91rm9200_programmable_layout);
                if (IS_ERR(hw))
                        goto err_free;
+
+               at91rm9200_pmc->pchws[i] = hw;
        }
 
        for (i = 0; i < ARRAY_SIZE(at91rm9200_systemck); i++) {
@@ -187,7 +193,7 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
        return;
 
 err_free:
-       pmc_data_free(at91rm9200_pmc);
+       kfree(at91rm9200_pmc);
 }
 /*
  * While the TCB can be used as the clocksource, the system timer is most likely
index a9d4234..6d0723a 100644 (file)
@@ -352,9 +352,10 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
        if (IS_ERR(regmap))
                return;
 
-       at91sam9260_pmc = pmc_data_allocate(PMC_MAIN + 1,
+       at91sam9260_pmc = pmc_data_allocate(PMC_PLLBCK + 1,
                                            ndck(data->sck, data->num_sck),
-                                           ndck(data->pck, data->num_pck), 0);
+                                           ndck(data->pck, data->num_pck),
+                                           0, data->num_progck);
        if (!at91sam9260_pmc)
                return;
 
@@ -398,12 +399,16 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
        if (IS_ERR(hw))
                goto err_free;
 
+       at91sam9260_pmc->chws[PMC_PLLACK] = hw;
+
        hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1,
                                   data->pllb_layout,
                                   data->pllb_characteristics);
        if (IS_ERR(hw))
                goto err_free;
 
+       at91sam9260_pmc->chws[PMC_PLLBCK] = hw;
+
        parent_names[0] = slck_name;
        parent_names[1] = "mainck";
        parent_names[2] = "pllack";
@@ -434,6 +439,8 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
                                                    &at91rm9200_programmable_layout);
                if (IS_ERR(hw))
                        goto err_free;
+
+               at91sam9260_pmc->pchws[i] = hw;
        }
 
        for (i = 0; i < data->num_sck; i++) {
@@ -462,7 +469,7 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
        return;
 
 err_free:
-       pmc_data_free(at91sam9260_pmc);
+       kfree(at91sam9260_pmc);
 }
 
 static void __init at91sam9260_pmc_setup(struct device_node *np)
index 38a7d2d..9873b58 100644 (file)
@@ -115,9 +115,9 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
        if (IS_ERR(regmap))
                return;
 
-       at91sam9g45_pmc = pmc_data_allocate(PMC_MAIN + 1,
+       at91sam9g45_pmc = pmc_data_allocate(PMC_PLLACK + 1,
                                            nck(at91sam9g45_systemck),
-                                           nck(at91sam9g45_periphck), 0);
+                                           nck(at91sam9g45_periphck), 0, 2);
        if (!at91sam9g45_pmc)
                return;
 
@@ -143,6 +143,8 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
        if (IS_ERR(hw))
                goto err_free;
 
+       at91sam9g45_pmc->chws[PMC_PLLACK] = hw;
+
        hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
        if (IS_ERR(hw))
                goto err_free;
@@ -182,6 +184,8 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
                                                    &at91sam9g45_programmable_layout);
                if (IS_ERR(hw))
                        goto err_free;
+
+               at91sam9g45_pmc->pchws[i] = hw;
        }
 
        for (i = 0; i < ARRAY_SIZE(at91sam9g45_systemck); i++) {
@@ -210,7 +214,7 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
        return;
 
 err_free:
-       pmc_data_free(at91sam9g45_pmc);
+       kfree(at91sam9g45_pmc);
 }
 /*
  * The TCB is used as the clocksource so its clock is needed early. This means
index 8bb39d2..630dc5d 100644 (file)
@@ -128,8 +128,8 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
        if (IS_ERR(regmap))
                return;
 
-       at91sam9n12_pmc = pmc_data_allocate(PMC_MAIN + 1,
-                                          nck(at91sam9n12_systemck), 31, 0);
+       at91sam9n12_pmc = pmc_data_allocate(PMC_PLLBCK + 1,
+                                          nck(at91sam9n12_systemck), 31, 0, 2);
        if (!at91sam9n12_pmc)
                return;
 
@@ -162,11 +162,15 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
        if (IS_ERR(hw))
                goto err_free;
 
+       at91sam9n12_pmc->chws[PMC_PLLACK] = hw;
+
        hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1,
                                   &at91rm9200_pll_layout, &pllb_characteristics);
        if (IS_ERR(hw))
                goto err_free;
 
+       at91sam9n12_pmc->chws[PMC_PLLBCK] = hw;
+
        parent_names[0] = slck_name;
        parent_names[1] = "mainck";
        parent_names[2] = "plladivck";
@@ -198,6 +202,8 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
                                                    &at91sam9x5_programmable_layout);
                if (IS_ERR(hw))
                        goto err_free;
+
+               at91sam9n12_pmc->pchws[i] = hw;
        }
 
        for (i = 0; i < ARRAY_SIZE(at91sam9n12_systemck); i++) {
@@ -228,7 +234,7 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
        return;
 
 err_free:
-       pmc_data_free(at91sam9n12_pmc);
+       kfree(at91sam9n12_pmc);
 }
 /*
  * The TCB is used as the clocksource so its clock is needed early. This means
index 77fe83a..0d1cc44 100644 (file)
@@ -87,9 +87,9 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
        if (IS_ERR(regmap))
                return;
 
-       at91sam9rl_pmc = pmc_data_allocate(PMC_MAIN + 1,
+       at91sam9rl_pmc = pmc_data_allocate(PMC_PLLACK + 1,
                                           nck(at91sam9rl_systemck),
-                                          nck(at91sam9rl_periphck), 0);
+                                          nck(at91sam9rl_periphck), 0, 2);
        if (!at91sam9rl_pmc)
                return;
 
@@ -105,6 +105,8 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
        if (IS_ERR(hw))
                goto err_free;
 
+       at91sam9rl_pmc->chws[PMC_PLLACK] = hw;
+
        hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
        if (IS_ERR(hw))
                goto err_free;
@@ -138,6 +140,8 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
                                                    &at91rm9200_programmable_layout);
                if (IS_ERR(hw))
                        goto err_free;
+
+               at91sam9rl_pmc->pchws[i] = hw;
        }
 
        for (i = 0; i < ARRAY_SIZE(at91sam9rl_systemck); i++) {
@@ -166,6 +170,6 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
        return;
 
 err_free:
-       pmc_data_free(at91sam9rl_pmc);
+       kfree(at91sam9rl_pmc);
 }
 CLK_OF_DECLARE_DRIVER(at91sam9rl_pmc, "atmel,at91sam9rl-pmc", at91sam9rl_pmc_setup);
index 086cf0b..0ce3da0 100644 (file)
@@ -150,8 +150,8 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
        if (IS_ERR(regmap))
                return;
 
-       at91sam9x5_pmc = pmc_data_allocate(PMC_MAIN + 1,
-                                          nck(at91sam9x5_systemck), 31, 0);
+       at91sam9x5_pmc = pmc_data_allocate(PMC_PLLACK + 1,
+                                          nck(at91sam9x5_systemck), 31, 0, 2);
        if (!at91sam9x5_pmc)
                return;
 
@@ -184,6 +184,8 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
        if (IS_ERR(hw))
                goto err_free;
 
+       at91sam9x5_pmc->chws[PMC_PLLACK] = hw;
+
        hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
        if (IS_ERR(hw))
                goto err_free;
@@ -227,6 +229,8 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
                                                    &at91sam9x5_programmable_layout);
                if (IS_ERR(hw))
                        goto err_free;
+
+               at91sam9x5_pmc->pchws[i] = hw;
        }
 
        for (i = 0; i < ARRAY_SIZE(at91sam9x5_systemck); i++) {
@@ -278,7 +282,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
        return;
 
 err_free:
-       pmc_data_free(at91sam9x5_pmc);
+       kfree(at91sam9x5_pmc);
 }
 
 static void __init at91sam9g15_pmc_setup(struct device_node *np)
index b71515a..20ee9dc 100644 (file)
@@ -67,6 +67,10 @@ struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
                if (idx < pmc_data->ngck)
                        return pmc_data->ghws[idx];
                break;
+       case PMC_TYPE_PROGRAMMABLE:
+               if (idx < pmc_data->npck)
+                       return pmc_data->pchws[idx];
+               break;
        default:
                break;
        }
@@ -76,48 +80,34 @@ struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
        return ERR_PTR(-EINVAL);
 }
 
-void pmc_data_free(struct pmc_data *pmc_data)
-{
-       kfree(pmc_data->chws);
-       kfree(pmc_data->shws);
-       kfree(pmc_data->phws);
-       kfree(pmc_data->ghws);
-}
-
 struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
-                                  unsigned int nperiph, unsigned int ngck)
+                                  unsigned int nperiph, unsigned int ngck,
+                                  unsigned int npck)
 {
-       struct pmc_data *pmc_data = kzalloc(sizeof(*pmc_data), GFP_KERNEL);
+       unsigned int num_clks = ncore + nsystem + nperiph + ngck + npck;
+       struct pmc_data *pmc_data;
 
+       pmc_data = kzalloc(struct_size(pmc_data, hwtable, num_clks),
+                          GFP_KERNEL);
        if (!pmc_data)
                return NULL;
 
        pmc_data->ncore = ncore;
-       pmc_data->chws = kcalloc(ncore, sizeof(struct clk_hw *), GFP_KERNEL);
-       if (!pmc_data->chws)
-               goto err;
+       pmc_data->chws = pmc_data->hwtable;
 
        pmc_data->nsystem = nsystem;
-       pmc_data->shws = kcalloc(nsystem, sizeof(struct clk_hw *), GFP_KERNEL);
-       if (!pmc_data->shws)
-               goto err;
+       pmc_data->shws = pmc_data->chws + ncore;
 
        pmc_data->nperiph = nperiph;
-       pmc_data->phws = kcalloc(nperiph, sizeof(struct clk_hw *), GFP_KERNEL);
-       if (!pmc_data->phws)
-               goto err;
+       pmc_data->phws = pmc_data->shws + nsystem;
 
        pmc_data->ngck = ngck;
-       pmc_data->ghws = kcalloc(ngck, sizeof(struct clk_hw *), GFP_KERNEL);
-       if (!pmc_data->ghws)
-               goto err;
+       pmc_data->ghws = pmc_data->phws + nperiph;
 
-       return pmc_data;
-
-err:
-       pmc_data_free(pmc_data);
+       pmc_data->npck = npck;
+       pmc_data->pchws = pmc_data->ghws + ngck;
 
-       return NULL;
+       return pmc_data;
 }
 
 #ifdef CONFIG_PM
@@ -274,8 +264,11 @@ static int __init pmc_register_ops(void)
        struct device_node *np;
 
        np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids);
+       if (!np)
+               return -ENODEV;
 
        pmcreg = device_node_to_regmap(np);
+       of_node_put(np);
        if (IS_ERR(pmcreg))
                return PTR_ERR(pmcreg);
 
index 9b8db9c..df616f2 100644 (file)
@@ -24,6 +24,10 @@ struct pmc_data {
        struct clk_hw **phws;
        unsigned int ngck;
        struct clk_hw **ghws;
+       unsigned int npck;
+       struct clk_hw **pchws;
+
+       struct clk_hw *hwtable[];
 };
 
 struct clk_range {
@@ -94,8 +98,8 @@ struct clk_pcr_layout {
 #define ndck(a, s) (a[s - 1].id + 1)
 #define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)
 struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
-                                  unsigned int nperiph, unsigned int ngck);
-void pmc_data_free(struct pmc_data *pmc_data);
+                                  unsigned int nperiph, unsigned int ngck,
+                                  unsigned int npck);
 
 int of_at91_get_clk_range(struct device_node *np, const char *propname,
                          struct clk_range *range);
index cc19e8f..3e20aa6 100644 (file)
@@ -182,10 +182,10 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
        if (IS_ERR(regmap))
                return;
 
-       sam9x60_pmc = pmc_data_allocate(PMC_MAIN + 1,
+       sam9x60_pmc = pmc_data_allocate(PMC_PLLACK + 1,
                                        nck(sam9x60_systemck),
                                        nck(sam9x60_periphck),
-                                       nck(sam9x60_gck));
+                                       nck(sam9x60_gck), 8);
        if (!sam9x60_pmc)
                return;
 
@@ -214,6 +214,8 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
        if (IS_ERR(hw))
                goto err_free;
 
+       sam9x60_pmc->chws[PMC_PLLACK] = hw;
+
        hw = sam9x60_clk_register_pll(regmap, &pmc_pll_lock, "upllck",
                                      "main_osc", 1, &upll_characteristics);
        if (IS_ERR(hw))
@@ -255,6 +257,8 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
                                                    &sam9x60_programmable_layout);
                if (IS_ERR(hw))
                        goto err_free;
+
+               sam9x60_pmc->pchws[i] = hw;
        }
 
        for (i = 0; i < ARRAY_SIZE(sam9x60_systemck); i++) {
@@ -299,7 +303,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
        return;
 
 err_free:
-       pmc_data_free(sam9x60_pmc);
+       kfree(sam9x60_pmc);
 }
 /* Some clks are used for a clocksource */
 CLK_OF_DECLARE(sam9x60_pmc, "microchip,sam9x60-pmc", sam9x60_pmc_setup);
index ff7e3f7..d69421d 100644 (file)
@@ -89,6 +89,7 @@ static const struct {
        { .n = "i2s1_clk",    .id = 55, .r = { .min = 0, .max = 83000000 }, },
        { .n = "can0_clk",    .id = 56, .r = { .min = 0, .max = 83000000 }, },
        { .n = "can1_clk",    .id = 57, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "ptc_clk",     .id = 58, .r = { .min = 0, .max = 83000000 }, },
        { .n = "classd_clk",  .id = 59, .r = { .min = 0, .max = 83000000 }, },
 };
 
@@ -166,10 +167,10 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
        if (IS_ERR(regmap))
                return;
 
-       sama5d2_pmc = pmc_data_allocate(PMC_I2S1_MUX + 1,
+       sama5d2_pmc = pmc_data_allocate(PMC_AUDIOPLLCK + 1,
                                        nck(sama5d2_systemck),
                                        nck(sama5d2_periph32ck),
-                                       nck(sama5d2_gck));
+                                       nck(sama5d2_gck), 3);
        if (!sama5d2_pmc)
                return;
 
@@ -202,6 +203,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
        if (IS_ERR(hw))
                goto err_free;
 
+       sama5d2_pmc->chws[PMC_PLLACK] = hw;
+
        hw = at91_clk_register_audio_pll_frac(regmap, "audiopll_fracck",
                                              "mainck");
        if (IS_ERR(hw))
@@ -217,6 +220,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
        if (IS_ERR(hw))
                goto err_free;
 
+       sama5d2_pmc->chws[PMC_AUDIOPLLCK] = hw;
+
        regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
        if (IS_ERR(regmap_sfr))
                regmap_sfr = NULL;
@@ -267,6 +272,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
                                                    &sama5d2_programmable_layout);
                if (IS_ERR(hw))
                        goto err_free;
+
+               sama5d2_pmc->pchws[i] = hw;
        }
 
        for (i = 0; i < ARRAY_SIZE(sama5d2_systemck); i++) {
@@ -350,6 +357,6 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
        return;
 
 err_free:
-       pmc_data_free(sama5d2_pmc);
+       kfree(sama5d2_pmc);
 }
 CLK_OF_DECLARE_DRIVER(sama5d2_pmc, "atmel,sama5d2-pmc", sama5d2_pmc_setup);
index 88506f9..5e4e44d 100644 (file)
@@ -125,9 +125,9 @@ static void __init sama5d3_pmc_setup(struct device_node *np)
        if (IS_ERR(regmap))
                return;
 
-       sama5d3_pmc = pmc_data_allocate(PMC_MAIN + 1,
+       sama5d3_pmc = pmc_data_allocate(PMC_PLLACK + 1,
                                        nck(sama5d3_systemck),
-                                       nck(sama5d3_periphck), 0);
+                                       nck(sama5d3_periphck), 0, 3);
        if (!sama5d3_pmc)
                return;
 
@@ -158,6 +158,8 @@ static void __init sama5d3_pmc_setup(struct device_node *np)
        if (IS_ERR(hw))
                goto err_free;
 
+       sama5d3_pmc->chws[PMC_PLLACK] = hw;
+
        hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
        if (IS_ERR(hw))
                goto err_free;
@@ -201,6 +203,8 @@ static void __init sama5d3_pmc_setup(struct device_node *np)
                                                    &at91sam9x5_programmable_layout);
                if (IS_ERR(hw))
                        goto err_free;
+
+               sama5d3_pmc->pchws[i] = hw;
        }
 
        for (i = 0; i < ARRAY_SIZE(sama5d3_systemck); i++) {
@@ -231,7 +235,7 @@ static void __init sama5d3_pmc_setup(struct device_node *np)
        return;
 
 err_free:
-       pmc_data_free(sama5d3_pmc);
+       kfree(sama5d3_pmc);
 }
 /*
  * The TCB is used as the clocksource so its clock is needed early. This means
index a6dee4a..662ff5f 100644 (file)
@@ -140,9 +140,9 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
        if (IS_ERR(regmap))
                return;
 
-       sama5d4_pmc = pmc_data_allocate(PMC_MCK2 + 1,
+       sama5d4_pmc = pmc_data_allocate(PMC_PLLACK + 1,
                                        nck(sama5d4_systemck),
-                                       nck(sama5d4_periph32ck), 0);
+                                       nck(sama5d4_periph32ck), 0, 3);
        if (!sama5d4_pmc)
                return;
 
@@ -173,6 +173,8 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
        if (IS_ERR(hw))
                goto err_free;
 
+       sama5d4_pmc->chws[PMC_PLLACK] = hw;
+
        hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
        if (IS_ERR(hw))
                goto err_free;
@@ -224,6 +226,8 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
                                                    &at91sam9x5_programmable_layout);
                if (IS_ERR(hw))
                        goto err_free;
+
+               sama5d4_pmc->pchws[i] = hw;
        }
 
        for (i = 0; i < ARRAY_SIZE(sama5d4_systemck); i++) {
@@ -267,6 +271,6 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
        return;
 
 err_free:
-       pmc_data_free(sama5d4_pmc);
+       kfree(sama5d4_pmc);
 }
 CLK_OF_DECLARE_DRIVER(sama5d4_pmc, "atmel,sama5d4-pmc", sama5d4_pmc_setup);
index 01eadee..db0253f 100644 (file)
@@ -10,25 +10,25 @@ config MXC_CLK_SCU
 
 config CLK_IMX8MM
        bool "IMX8MM CCM Clock Driver"
-       depends on ARCH_MXC && ARM64
+       depends on ARCH_MXC
        help
            Build the driver for i.MX8MM CCM Clock Driver
 
 config CLK_IMX8MN
        bool "IMX8MN CCM Clock Driver"
-       depends on ARCH_MXC && ARM64
+       depends on ARCH_MXC
        help
            Build the driver for i.MX8MN CCM Clock Driver
 
 config CLK_IMX8MP
        bool "IMX8MP CCM Clock Driver"
-       depends on ARCH_MXC && ARM64
+       depends on ARCH_MXC
        help
            Build the driver for i.MX8MP CCM Clock Driver
 
 config CLK_IMX8MQ
        bool "IMX8MQ CCM Clock Driver"
-       depends on ARCH_MXC && ARM64
+       depends on ARCH_MXC
        help
            Build the driver for i.MX8MQ CCM Clock Driver
 
index 9977351..d2b5af8 100644 (file)
@@ -124,6 +124,52 @@ static const struct clk_ops imx8m_clk_composite_divider_ops = {
        .set_rate = imx8m_clk_composite_divider_set_rate,
 };
 
+static u8 imx8m_clk_composite_mux_get_parent(struct clk_hw *hw)
+{
+       return clk_mux_ops.get_parent(hw);
+}
+
+static int imx8m_clk_composite_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct clk_mux *mux = to_clk_mux(hw);
+       u32 val = clk_mux_index_to_val(mux->table, mux->flags, index);
+       unsigned long flags = 0;
+       u32 reg;
+
+       if (mux->lock)
+               spin_lock_irqsave(mux->lock, flags);
+
+       reg = readl(mux->reg);
+       reg &= ~(mux->mask << mux->shift);
+       val = val << mux->shift;
+       reg |= val;
+       /*
+        * write twice to make sure non-target interface
+        * SEL_A/B point the same clk input.
+        */
+       writel(reg, mux->reg);
+       writel(reg, mux->reg);
+
+       if (mux->lock)
+               spin_unlock_irqrestore(mux->lock, flags);
+
+       return 0;
+}
+
+static int
+imx8m_clk_composite_mux_determine_rate(struct clk_hw *hw,
+                                      struct clk_rate_request *req)
+{
+       return clk_mux_ops.determine_rate(hw, req);
+}
+
+
+static const struct clk_ops imx8m_clk_composite_mux_ops = {
+       .get_parent = imx8m_clk_composite_mux_get_parent,
+       .set_parent = imx8m_clk_composite_mux_set_parent,
+       .determine_rate = imx8m_clk_composite_mux_determine_rate,
+};
+
 struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
                                        const char * const *parent_names,
                                        int num_parents, void __iomem *reg,
@@ -136,6 +182,7 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
        struct clk_gate *gate = NULL;
        struct clk_mux *mux = NULL;
        const struct clk_ops *divider_ops;
+       const struct clk_ops *mux_ops;
 
        mux = kzalloc(sizeof(*mux), GFP_KERNEL);
        if (!mux)
@@ -157,10 +204,17 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
                div->shift = PCG_DIV_SHIFT;
                div->width = PCG_CORE_DIV_WIDTH;
                divider_ops = &clk_divider_ops;
+               mux_ops = &imx8m_clk_composite_mux_ops;
+       } else if (composite_flags & IMX_COMPOSITE_BUS) {
+               div->shift = PCG_PREDIV_SHIFT;
+               div->width = PCG_PREDIV_WIDTH;
+               divider_ops = &imx8m_clk_composite_divider_ops;
+               mux_ops = &imx8m_clk_composite_mux_ops;
        } else {
                div->shift = PCG_PREDIV_SHIFT;
                div->width = PCG_PREDIV_WIDTH;
                divider_ops = &imx8m_clk_composite_divider_ops;
+               mux_ops = &clk_mux_ops;
        }
 
        div->lock = &imx_ccm_lock;
@@ -176,7 +230,7 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
        gate->lock = &imx_ccm_lock;
 
        hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
-                       mux_hw, &clk_mux_ops, div_hw,
+                       mux_hw, mux_ops, div_hw,
                        divider_ops, gate_hw, &clk_gate_ops, flags);
        if (IS_ERR(hw))
                goto fail;
index ce0060e..b87ab3c 100644 (file)
@@ -41,21 +41,26 @@ static int clk_gate2_enable(struct clk_hw *hw)
        struct clk_gate2 *gate = to_clk_gate2(hw);
        u32 reg;
        unsigned long flags;
+       int ret = 0;
 
        spin_lock_irqsave(gate->lock, flags);
 
        if (gate->share_count && (*gate->share_count)++ > 0)
                goto out;
 
-       reg = readl(gate->reg);
-       reg &= ~(3 << gate->bit_idx);
-       reg |= gate->cgr_val << gate->bit_idx;
-       writel(reg, gate->reg);
+       if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT) {
+               ret = clk_gate_ops.enable(hw);
+       } else {
+               reg = readl(gate->reg);
+               reg &= ~(3 << gate->bit_idx);
+               reg |= gate->cgr_val << gate->bit_idx;
+               writel(reg, gate->reg);
+       }
 
 out:
        spin_unlock_irqrestore(gate->lock, flags);
 
-       return 0;
+       return ret;
 }
 
 static void clk_gate2_disable(struct clk_hw *hw)
@@ -73,9 +78,13 @@ static void clk_gate2_disable(struct clk_hw *hw)
                        goto out;
        }
 
-       reg = readl(gate->reg);
-       reg &= ~(3 << gate->bit_idx);
-       writel(reg, gate->reg);
+       if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT) {
+               clk_gate_ops.disable(hw);
+       } else {
+               reg = readl(gate->reg);
+               reg &= ~(3 << gate->bit_idx);
+               writel(reg, gate->reg);
+       }
 
 out:
        spin_unlock_irqrestore(gate->lock, flags);
@@ -95,6 +104,9 @@ static int clk_gate2_is_enabled(struct clk_hw *hw)
 {
        struct clk_gate2 *gate = to_clk_gate2(hw);
 
+       if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT)
+               return clk_gate_ops.is_enabled(hw);
+
        return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx);
 }
 
@@ -104,6 +116,9 @@ static void clk_gate2_disable_unused(struct clk_hw *hw)
        unsigned long flags;
        u32 reg;
 
+       if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT)
+               return;
+
        spin_lock_irqsave(gate->lock, flags);
 
        if (!gate->share_count || *gate->share_count == 0) {
index dafc880..5dbb6a9 100644 (file)
@@ -503,7 +503,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
                clk_prepare_enable(hws[IMX6UL_CLK_USBPHY2_GATE]->clk);
        }
 
-       clk_set_parent(hws[IMX6UL_CLK_CAN_SEL]->clk, hws[IMX6UL_CLK_PLL3_60M]->clk);
+       clk_set_parent(hws[IMX6UL_CLK_CAN_SEL]->clk, hws[IMX6UL_CLK_PLL3_80M]->clk);
        if (clk_on_imx6ul())
                clk_set_parent(hws[IMX6UL_CLK_SIM_PRE_SEL]->clk, hws[IMX6UL_CLK_PLL3_USB_OTG]->clk);
        else if (clk_on_imx6ull())
index 3710aa0..634c0b6 100644 (file)
@@ -29,7 +29,7 @@ static const char * const ddr_sels[]          = { "apll_pfd_sel", "dummy", "dummy", "dum
 static const char * const nic_sels[]           = { "firc", "ddr_clk", };
 static const char * const periph_plat_sels[]   = { "dummy", "nic1_bus_clk", "nic1_clk", "ddr_clk", "apll_pfd2", "apll_pfd1", "apll_pfd0", "upll", };
 static const char * const periph_bus_sels[]    = { "dummy", "sosc_bus_clk", "dummy", "firc_bus_clk", "rosc", "nic1_bus_clk", "nic1_clk", "spll_bus_clk", };
-static const char * const arm_sels[]           = { "divcore", "dummy", "dummy", "hsrun_divcore", };
+static const char * const arm_sels[]           = { "core", "dummy", "dummy", "hsrun_core", };
 
 /* used by sosc/sirc/firc/ddr/spll/apll dividers */
 static const struct clk_div_table ulp_div_table[] = {
@@ -121,7 +121,9 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np)
        hws[IMX7ULP_CLK_DDR_SEL]        = imx_clk_hw_mux_flags("ddr_sel", base + 0x30, 24, 2, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
 
        hws[IMX7ULP_CLK_CORE_DIV]       = imx_clk_hw_divider_flags("divcore",   "scs_sel",  base + 0x14, 16, 4, CLK_SET_RATE_PARENT);
+       hws[IMX7ULP_CLK_CORE]           = imx_clk_hw_cpu("core", "divcore", hws[IMX7ULP_CLK_CORE_DIV]->clk, hws[IMX7ULP_CLK_SYS_SEL]->clk, hws[IMX7ULP_CLK_SPLL_SEL]->clk, hws[IMX7ULP_CLK_FIRC]->clk);
        hws[IMX7ULP_CLK_HSRUN_CORE_DIV] = imx_clk_hw_divider_flags("hsrun_divcore", "hsrun_scs_sel", base + 0x1c, 16, 4, CLK_SET_RATE_PARENT);
+       hws[IMX7ULP_CLK_HSRUN_CORE] = imx_clk_hw_cpu("hsrun_core", "hsrun_divcore", hws[IMX7ULP_CLK_HSRUN_CORE_DIV]->clk, hws[IMX7ULP_CLK_HSRUN_SYS_SEL]->clk, hws[IMX7ULP_CLK_SPLL_SEL]->clk, hws[IMX7ULP_CLK_FIRC]->clk);
 
        hws[IMX7ULP_CLK_DDR_DIV]        = imx_clk_hw_divider_gate("ddr_clk", "ddr_sel", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, base + 0x30, 0, 3,
                                                               0, ulp_div_table, &imx_ccm_lock);
@@ -270,7 +272,7 @@ static void __init imx7ulp_clk_smc1_init(struct device_node *np)
        base = of_iomap(np, 0);
        WARN_ON(!base);
 
-       hws[IMX7ULP_CLK_ARM] = imx_clk_hw_mux_flags("arm", base + 0x10, 8, 2, arm_sels, ARRAY_SIZE(arm_sels), CLK_IS_CRITICAL);
+       hws[IMX7ULP_CLK_ARM] = imx_clk_hw_mux_flags("arm", base + 0x10, 8, 2, arm_sels, ARRAY_SIZE(arm_sels), CLK_SET_RATE_PARENT);
 
        imx_check_clk_hws(hws, clk_data->num);
 
index 9256704..b793264 100644 (file)
@@ -416,9 +416,9 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
                return PTR_ERR(base);
 
        /* Core Slice */
-       hws[IMX8MM_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels));
-       hws[IMX8MM_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
-       hws[IMX8MM_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
+       hws[IMX8MM_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mm_a53_sels, base + 0x8000);
+       hws[IMX8MM_CLK_A53_CG] = hws[IMX8MM_CLK_A53_DIV];
+       hws[IMX8MM_CLK_A53_SRC] = hws[IMX8MM_CLK_A53_DIV];
 
        hws[IMX8MM_CLK_M4_CORE] = imx8m_clk_hw_composite_core("arm_m4_core", imx8mm_m4_sels, base + 0x8080);
        hws[IMX8MM_CLK_VPU_CORE] = imx8m_clk_hw_composite_core("vpu_core", imx8mm_vpu_sels, base + 0x8100);
@@ -444,21 +444,21 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
 
        /* BUS */
        hws[IMX8MM_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi",  imx8mm_main_axi_sels, base + 0x8800);
-       hws[IMX8MM_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mm_enet_axi_sels, base + 0x8880);
+       hws[IMX8MM_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mm_enet_axi_sels, base + 0x8880);
        hws[IMX8MM_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900);
-       hws[IMX8MM_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980);
-       hws[IMX8MM_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00);
-       hws[IMX8MM_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80);
-       hws[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_hw_composite("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00);
-       hws[IMX8MM_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80);
-       hws[IMX8MM_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00);
-       hws[IMX8MM_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80);
+       hws[IMX8MM_CLK_VPU_BUS] = imx8m_clk_hw_composite_bus("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980);
+       hws[IMX8MM_CLK_DISP_AXI] = imx8m_clk_hw_composite_bus("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00);
+       hws[IMX8MM_CLK_DISP_APB] = imx8m_clk_hw_composite_bus("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80);
+       hws[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_hw_composite_bus("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00);
+       hws[IMX8MM_CLK_USB_BUS] = imx8m_clk_hw_composite_bus("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80);
+       hws[IMX8MM_CLK_GPU_AXI] = imx8m_clk_hw_composite_bus("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00);
+       hws[IMX8MM_CLK_GPU_AHB] = imx8m_clk_hw_composite_bus("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80);
        hws[IMX8MM_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mm_noc_sels, base + 0x8d00);
        hws[IMX8MM_CLK_NOC_APB] = imx8m_clk_hw_composite_critical("noc_apb", imx8mm_noc_apb_sels, base + 0x8d80);
 
        /* AHB */
        hws[IMX8MM_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mm_ahb_sels, base + 0x9000);
-       hws[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100);
+       hws[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100);
 
        /* IPG */
        hws[IMX8MM_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
@@ -614,9 +614,6 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
                                           hws[IMX8MM_ARM_PLL_OUT]->clk,
                                           hws[IMX8MM_CLK_A53_DIV]->clk);
 
-       clk_hw_set_parent(hws[IMX8MM_CLK_A53_SRC], hws[IMX8MM_SYS_PLL1_800M]);
-       clk_hw_set_parent(hws[IMX8MM_CLK_A53_CORE], hws[IMX8MM_ARM_PLL_OUT]);
-
        imx_check_clk_hws(hws, IMX8MM_CLK_END);
 
        ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
index 0bc7070..213cc37 100644 (file)
@@ -413,9 +413,9 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
        }
 
        /* CORE */
-       hws[IMX8MN_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mn_a53_sels, ARRAY_SIZE(imx8mn_a53_sels));
-       hws[IMX8MN_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
-       hws[IMX8MN_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
+       hws[IMX8MN_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mn_a53_sels, base + 0x8000);
+       hws[IMX8MN_CLK_A53_SRC] = hws[IMX8MN_CLK_A53_DIV];
+       hws[IMX8MN_CLK_A53_CG] = hws[IMX8MN_CLK_A53_DIV];
 
        hws[IMX8MN_CLK_GPU_CORE] = imx8m_clk_hw_composite_core("gpu_core", imx8mn_gpu_core_sels, base + 0x8180);
        hws[IMX8MN_CLK_GPU_SHADER] = imx8m_clk_hw_composite_core("gpu_shader", imx8mn_gpu_shader_sels, base + 0x8200);
@@ -432,17 +432,17 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 
        /* BUS */
        hws[IMX8MN_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mn_main_axi_sels, base + 0x8800);
-       hws[IMX8MN_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mn_enet_axi_sels, base + 0x8880);
-       hws[IMX8MN_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900);
-       hws[IMX8MN_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mn_disp_axi_sels, base + 0x8a00);
-       hws[IMX8MN_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mn_disp_apb_sels, base + 0x8a80);
-       hws[IMX8MN_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80);
-       hws[IMX8MN_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mn_gpu_axi_sels, base + 0x8c00);
-       hws[IMX8MN_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mn_gpu_ahb_sels, base + 0x8c80);
+       hws[IMX8MN_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mn_enet_axi_sels, base + 0x8880);
+       hws[IMX8MN_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_bus("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900);
+       hws[IMX8MN_CLK_DISP_AXI] = imx8m_clk_hw_composite_bus("disp_axi", imx8mn_disp_axi_sels, base + 0x8a00);
+       hws[IMX8MN_CLK_DISP_APB] = imx8m_clk_hw_composite_bus("disp_apb", imx8mn_disp_apb_sels, base + 0x8a80);
+       hws[IMX8MN_CLK_USB_BUS] = imx8m_clk_hw_composite_bus("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80);
+       hws[IMX8MN_CLK_GPU_AXI] = imx8m_clk_hw_composite_bus("gpu_axi", imx8mn_gpu_axi_sels, base + 0x8c00);
+       hws[IMX8MN_CLK_GPU_AHB] = imx8m_clk_hw_composite_bus("gpu_ahb", imx8mn_gpu_ahb_sels, base + 0x8c80);
        hws[IMX8MN_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mn_noc_sels, base + 0x8d00);
 
        hws[IMX8MN_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mn_ahb_sels, base + 0x9000);
-       hws[IMX8MN_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mn_audio_ahb_sels, base + 0x9100);
+       hws[IMX8MN_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mn_audio_ahb_sels, base + 0x9100);
        hws[IMX8MN_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
        hws[IMX8MN_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
        hws[IMX8MN_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mn_dram_core_sels, ARRAY_SIZE(imx8mn_dram_core_sels), CLK_IS_CRITICAL);
@@ -565,9 +565,6 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
                                           hws[IMX8MN_ARM_PLL_OUT]->clk,
                                           hws[IMX8MN_CLK_A53_DIV]->clk);
 
-       clk_hw_set_parent(hws[IMX8MN_CLK_A53_SRC], hws[IMX8MN_SYS_PLL1_800M]);
-       clk_hw_set_parent(hws[IMX8MN_CLK_A53_CORE], hws[IMX8MN_ARM_PLL_OUT]);
-
        imx_check_clk_hws(hws, IMX8MN_CLK_END);
 
        ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
index 41469e2..b4d9db9 100644 (file)
@@ -486,16 +486,16 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
        hws[IMX8MP_SYS_PLL2] = imx_clk_hw_pll14xx("sys_pll2", "sys_pll2_ref_sel", anatop_base + 0x104, &imx_1416x_pll);
        hws[IMX8MP_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", anatop_base + 0x114, &imx_1416x_pll);
 
-       hws[IMX8MP_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", anatop_base, 4, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
-       hws[IMX8MP_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", anatop_base + 0x14, 4, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
-       hws[IMX8MP_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", anatop_base + 0x28, 4, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
-       hws[IMX8MP_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", anatop_base + 0x50, 4, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       hws[IMX8MP_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", anatop_base + 0x64, 4, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       hws[IMX8MP_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", anatop_base + 0x74, 4, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       hws[IMX8MP_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", anatop_base + 0x84, 4, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       hws[IMX8MP_SYS_PLL1_BYPASS] = imx_clk_hw_mux_flags("sys_pll1_bypass", anatop_base + 0x94, 4, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
-       hws[IMX8MP_SYS_PLL2_BYPASS] = imx_clk_hw_mux_flags("sys_pll2_bypass", anatop_base + 0x104, 4, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
-       hws[IMX8MP_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", anatop_base + 0x114, 4, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", anatop_base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", anatop_base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", anatop_base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", anatop_base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", anatop_base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", anatop_base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", anatop_base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_SYS_PLL1_BYPASS] = imx_clk_hw_mux_flags("sys_pll1_bypass", anatop_base + 0x94, 28, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_SYS_PLL2_BYPASS] = imx_clk_hw_mux_flags("sys_pll2_bypass", anatop_base + 0x104, 28, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", anatop_base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
 
        hws[IMX8MP_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", anatop_base, 13);
        hws[IMX8MP_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", anatop_base + 0x14, 13);
@@ -504,79 +504,82 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
        hws[IMX8MP_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", anatop_base + 0x64, 11);
        hws[IMX8MP_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", anatop_base + 0x74, 11);
        hws[IMX8MP_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", anatop_base + 0x84, 11);
-       hws[IMX8MP_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1_bypass", anatop_base + 0x94, 11);
-       hws[IMX8MP_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2_bypass", anatop_base + 0x104, 11);
        hws[IMX8MP_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", anatop_base + 0x114, 11);
 
-       hws[IMX8MP_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
-       hws[IMX8MP_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
-       hws[IMX8MP_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
-       hws[IMX8MP_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
-       hws[IMX8MP_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
-       hws[IMX8MP_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
-       hws[IMX8MP_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
-       hws[IMX8MP_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
+       hws[IMX8MP_SYS_PLL1_40M_CG] = imx_clk_hw_gate("sys_pll1_40m_cg", "sys_pll1_bypass", anatop_base + 0x94, 27);
+       hws[IMX8MP_SYS_PLL1_80M_CG] = imx_clk_hw_gate("sys_pll1_80m_cg", "sys_pll1_bypass", anatop_base + 0x94, 25);
+       hws[IMX8MP_SYS_PLL1_100M_CG] = imx_clk_hw_gate("sys_pll1_100m_cg", "sys_pll1_bypass", anatop_base + 0x94, 23);
+       hws[IMX8MP_SYS_PLL1_133M_CG] = imx_clk_hw_gate("sys_pll1_133m_cg", "sys_pll1_bypass", anatop_base + 0x94, 21);
+       hws[IMX8MP_SYS_PLL1_160M_CG] = imx_clk_hw_gate("sys_pll1_160m_cg", "sys_pll1_bypass", anatop_base + 0x94, 19);
+       hws[IMX8MP_SYS_PLL1_200M_CG] = imx_clk_hw_gate("sys_pll1_200m_cg", "sys_pll1_bypass", anatop_base + 0x94, 17);
+       hws[IMX8MP_SYS_PLL1_266M_CG] = imx_clk_hw_gate("sys_pll1_266m_cg", "sys_pll1_bypass", anatop_base + 0x94, 15);
+       hws[IMX8MP_SYS_PLL1_400M_CG] = imx_clk_hw_gate("sys_pll1_400m_cg", "sys_pll1_bypass", anatop_base + 0x94, 13);
+       hws[IMX8MP_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1_bypass", anatop_base + 0x94, 11);
+
+       hws[IMX8MP_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20);
+       hws[IMX8MP_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10);
+       hws[IMX8MP_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8);
+       hws[IMX8MP_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6);
+       hws[IMX8MP_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5);
+       hws[IMX8MP_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4);
+       hws[IMX8MP_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3);
+       hws[IMX8MP_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2);
        hws[IMX8MP_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
 
-       hws[IMX8MP_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
-       hws[IMX8MP_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
-       hws[IMX8MP_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
-       hws[IMX8MP_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
-       hws[IMX8MP_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
-       hws[IMX8MP_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
-       hws[IMX8MP_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
-       hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
+       hws[IMX8MP_SYS_PLL2_50M_CG] = imx_clk_hw_gate("sys_pll2_50m_cg", "sys_pll2_bypass", anatop_base + 0x104, 27);
+       hws[IMX8MP_SYS_PLL2_100M_CG] = imx_clk_hw_gate("sys_pll2_100m_cg", "sys_pll2_bypass", anatop_base + 0x104, 25);
+       hws[IMX8MP_SYS_PLL2_125M_CG] = imx_clk_hw_gate("sys_pll2_125m_cg", "sys_pll2_bypass", anatop_base + 0x104, 23);
+       hws[IMX8MP_SYS_PLL2_166M_CG] = imx_clk_hw_gate("sys_pll2_166m_cg", "sys_pll2_bypass", anatop_base + 0x104, 21);
+       hws[IMX8MP_SYS_PLL2_200M_CG] = imx_clk_hw_gate("sys_pll2_200m_cg", "sys_pll2_bypass", anatop_base + 0x104, 19);
+       hws[IMX8MP_SYS_PLL2_250M_CG] = imx_clk_hw_gate("sys_pll2_250m_cg", "sys_pll2_bypass", anatop_base + 0x104, 17);
+       hws[IMX8MP_SYS_PLL2_333M_CG] = imx_clk_hw_gate("sys_pll2_333m_cg", "sys_pll2_bypass", anatop_base + 0x104, 15);
+       hws[IMX8MP_SYS_PLL2_500M_CG] = imx_clk_hw_gate("sys_pll2_500m_cg", "sys_pll2_bypass", anatop_base + 0x104, 13);
+       hws[IMX8MP_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2_bypass", anatop_base + 0x104, 11);
+
+       hws[IMX8MP_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20);
+       hws[IMX8MP_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10);
+       hws[IMX8MP_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8);
+       hws[IMX8MP_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6);
+       hws[IMX8MP_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5);
+       hws[IMX8MP_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4);
+       hws[IMX8MP_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3);
+       hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2);
        hws[IMX8MP_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
 
-       hws[IMX8MP_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", ccm_base + 0x8000, 24, 3, imx8mp_a53_sels, ARRAY_SIZE(imx8mp_a53_sels));
-       hws[IMX8MP_CLK_M7_SRC] = imx_clk_hw_mux2("arm_m7_src", ccm_base + 0x8080, 24, 3, imx8mp_m7_sels, ARRAY_SIZE(imx8mp_m7_sels));
-       hws[IMX8MP_CLK_ML_SRC] = imx_clk_hw_mux2("ml_src", ccm_base + 0x8100, 24, 3, imx8mp_ml_sels, ARRAY_SIZE(imx8mp_ml_sels));
-       hws[IMX8MP_CLK_GPU3D_CORE_SRC] = imx_clk_hw_mux2("gpu3d_core_src", ccm_base + 0x8180, 24, 3,  imx8mp_gpu3d_core_sels, ARRAY_SIZE(imx8mp_gpu3d_core_sels));
-       hws[IMX8MP_CLK_GPU3D_SHADER_SRC] = imx_clk_hw_mux2("gpu3d_shader_src", ccm_base + 0x8200, 24, 3, imx8mp_gpu3d_shader_sels, ARRAY_SIZE(imx8mp_gpu3d_shader_sels));
-       hws[IMX8MP_CLK_GPU2D_SRC] = imx_clk_hw_mux2("gpu2d_src", ccm_base + 0x8280, 24, 3, imx8mp_gpu2d_sels, ARRAY_SIZE(imx8mp_gpu2d_sels));
-       hws[IMX8MP_CLK_AUDIO_AXI_SRC] = imx_clk_hw_mux2("audio_axi_src", ccm_base + 0x8300, 24, 3, imx8mp_audio_axi_sels, ARRAY_SIZE(imx8mp_audio_axi_sels));
-       hws[IMX8MP_CLK_HSIO_AXI_SRC] = imx_clk_hw_mux2("hsio_axi_src", ccm_base + 0x8380, 24, 3, imx8mp_hsio_axi_sels, ARRAY_SIZE(imx8mp_hsio_axi_sels));
-       hws[IMX8MP_CLK_MEDIA_ISP_SRC] = imx_clk_hw_mux2("media_isp_src", ccm_base + 0x8400, 24, 3, imx8mp_media_isp_sels, ARRAY_SIZE(imx8mp_media_isp_sels));
-       hws[IMX8MP_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", ccm_base + 0x8000, 28);
-       hws[IMX8MP_CLK_M4_CG] = imx_clk_hw_gate3("arm_m7_cg", "arm_m7_src", ccm_base + 0x8080, 28);
-       hws[IMX8MP_CLK_ML_CG] = imx_clk_hw_gate3("ml_cg", "ml_src", ccm_base + 0x8100, 28);
-       hws[IMX8MP_CLK_GPU3D_CORE_CG] = imx_clk_hw_gate3("gpu3d_core_cg", "gpu3d_core_src", ccm_base + 0x8180, 28);
-       hws[IMX8MP_CLK_GPU3D_SHADER_CG] = imx_clk_hw_gate3("gpu3d_shader_cg", "gpu3d_shader_src", ccm_base + 0x8200, 28);
-       hws[IMX8MP_CLK_GPU2D_CG] = imx_clk_hw_gate3("gpu2d_cg", "gpu2d_src", ccm_base + 0x8280, 28);
-       hws[IMX8MP_CLK_AUDIO_AXI_CG] = imx_clk_hw_gate3("audio_axi_cg", "audio_axi_src", ccm_base + 0x8300, 28);
-       hws[IMX8MP_CLK_HSIO_AXI_CG] = imx_clk_hw_gate3("hsio_axi_cg", "hsio_axi_src", ccm_base + 0x8380, 28);
-       hws[IMX8MP_CLK_MEDIA_ISP_CG] = imx_clk_hw_gate3("media_isp_cg", "media_isp_src", ccm_base + 0x8400, 28);
-       hws[IMX8MP_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", ccm_base + 0x8000, 0, 3);
-       hws[IMX8MP_CLK_M7_DIV] = imx_clk_hw_divider2("arm_m7_div", "arm_m7_cg", ccm_base + 0x8080, 0, 3);
-       hws[IMX8MP_CLK_ML_DIV] = imx_clk_hw_divider2("ml_div", "ml_cg", ccm_base + 0x8100, 0, 3);
-       hws[IMX8MP_CLK_GPU3D_CORE_DIV] = imx_clk_hw_divider2("gpu3d_core_div", "gpu3d_core_cg", ccm_base + 0x8180, 0, 3);
-       hws[IMX8MP_CLK_GPU3D_SHADER_DIV] = imx_clk_hw_divider2("gpu3d_shader_div", "gpu3d_shader_cg", ccm_base + 0x8200, 0, 3);
-       hws[IMX8MP_CLK_GPU2D_DIV] = imx_clk_hw_divider2("gpu2d_div", "gpu2d_cg", ccm_base + 0x8280, 0, 3);
-       hws[IMX8MP_CLK_AUDIO_AXI_DIV] = imx_clk_hw_divider2("audio_axi_div", "audio_axi_cg", ccm_base + 0x8300, 0, 3);
-       hws[IMX8MP_CLK_HSIO_AXI_DIV] = imx_clk_hw_divider2("hsio_axi_div", "hsio_axi_cg", ccm_base + 0x8380, 0, 3);
-       hws[IMX8MP_CLK_MEDIA_ISP_DIV] = imx_clk_hw_divider2("media_isp_div", "media_isp_cg", ccm_base + 0x8400, 0, 3);
+       hws[IMX8MP_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mp_a53_sels, ccm_base + 0x8000);
+       hws[IMX8MP_CLK_A53_SRC] = hws[IMX8MP_CLK_A53_DIV];
+       hws[IMX8MP_CLK_A53_CG] = hws[IMX8MP_CLK_A53_DIV];
+       hws[IMX8MP_CLK_M7_CORE] = imx8m_clk_hw_composite_core("m7_core", imx8mp_m7_sels, ccm_base + 0x8080);
+       hws[IMX8MP_CLK_ML_CORE] = imx8m_clk_hw_composite_core("ml_core", imx8mp_ml_sels, ccm_base + 0x8100);
+       hws[IMX8MP_CLK_GPU3D_CORE] = imx8m_clk_hw_composite_core("gpu3d_core", imx8mp_gpu3d_core_sels, ccm_base + 0x8180);
+       hws[IMX8MP_CLK_GPU3D_SHADER_CORE] = imx8m_clk_hw_composite("gpu3d_shader_core", imx8mp_gpu3d_shader_sels, ccm_base + 0x8200);
+       hws[IMX8MP_CLK_GPU2D_CORE] = imx8m_clk_hw_composite("gpu2d_core", imx8mp_gpu2d_sels, ccm_base + 0x8280);
+       hws[IMX8MP_CLK_AUDIO_AXI] = imx8m_clk_hw_composite("audio_axi", imx8mp_audio_axi_sels, ccm_base + 0x8300);
+       hws[IMX8MP_CLK_AUDIO_AXI_SRC] = hws[IMX8MP_CLK_AUDIO_AXI];
+       hws[IMX8MP_CLK_HSIO_AXI] = imx8m_clk_hw_composite("hsio_axi", imx8mp_hsio_axi_sels, ccm_base + 0x8380);
+       hws[IMX8MP_CLK_MEDIA_ISP] = imx8m_clk_hw_composite("media_isp", imx8mp_media_isp_sels, ccm_base + 0x8400);
 
        /* CORE SEL */
        hws[IMX8MP_CLK_A53_CORE] = imx_clk_hw_mux2("arm_a53_core", ccm_base + 0x9880, 24, 1, imx8mp_a53_core_sels, ARRAY_SIZE(imx8mp_a53_core_sels));
 
        hws[IMX8MP_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mp_main_axi_sels, ccm_base + 0x8800);
-       hws[IMX8MP_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mp_enet_axi_sels, ccm_base + 0x8880);
+       hws[IMX8MP_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mp_enet_axi_sels, ccm_base + 0x8880);
        hws[IMX8MP_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_critical("nand_usdhc_bus", imx8mp_nand_usdhc_sels, ccm_base + 0x8900);
-       hws[IMX8MP_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mp_vpu_bus_sels, ccm_base + 0x8980);
-       hws[IMX8MP_CLK_MEDIA_AXI] = imx8m_clk_hw_composite("media_axi", imx8mp_media_axi_sels, ccm_base + 0x8a00);
-       hws[IMX8MP_CLK_MEDIA_APB] = imx8m_clk_hw_composite("media_apb", imx8mp_media_apb_sels, ccm_base + 0x8a80);
-       hws[IMX8MP_CLK_HDMI_APB] = imx8m_clk_hw_composite("hdmi_apb", imx8mp_media_apb_sels, ccm_base + 0x8b00);
-       hws[IMX8MP_CLK_HDMI_AXI] = imx8m_clk_hw_composite("hdmi_axi", imx8mp_media_axi_sels, ccm_base + 0x8b80);
-       hws[IMX8MP_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mp_gpu_axi_sels, ccm_base + 0x8c00);
-       hws[IMX8MP_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mp_gpu_ahb_sels, ccm_base + 0x8c80);
+       hws[IMX8MP_CLK_VPU_BUS] = imx8m_clk_hw_composite_bus("vpu_bus", imx8mp_vpu_bus_sels, ccm_base + 0x8980);
+       hws[IMX8MP_CLK_MEDIA_AXI] = imx8m_clk_hw_composite_bus("media_axi", imx8mp_media_axi_sels, ccm_base + 0x8a00);
+       hws[IMX8MP_CLK_MEDIA_APB] = imx8m_clk_hw_composite_bus("media_apb", imx8mp_media_apb_sels, ccm_base + 0x8a80);
+       hws[IMX8MP_CLK_HDMI_APB] = imx8m_clk_hw_composite_bus("hdmi_apb", imx8mp_media_apb_sels, ccm_base + 0x8b00);
+       hws[IMX8MP_CLK_HDMI_AXI] = imx8m_clk_hw_composite_bus("hdmi_axi", imx8mp_media_axi_sels, ccm_base + 0x8b80);
+       hws[IMX8MP_CLK_GPU_AXI] = imx8m_clk_hw_composite_bus("gpu_axi", imx8mp_gpu_axi_sels, ccm_base + 0x8c00);
+       hws[IMX8MP_CLK_GPU_AHB] = imx8m_clk_hw_composite_bus("gpu_ahb", imx8mp_gpu_ahb_sels, ccm_base + 0x8c80);
        hws[IMX8MP_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mp_noc_sels, ccm_base + 0x8d00);
        hws[IMX8MP_CLK_NOC_IO] = imx8m_clk_hw_composite_critical("noc_io", imx8mp_noc_io_sels, ccm_base + 0x8d80);
-       hws[IMX8MP_CLK_ML_AXI] = imx8m_clk_hw_composite("ml_axi", imx8mp_ml_axi_sels, ccm_base + 0x8e00);
-       hws[IMX8MP_CLK_ML_AHB] = imx8m_clk_hw_composite("ml_ahb", imx8mp_ml_ahb_sels, ccm_base + 0x8e80);
+       hws[IMX8MP_CLK_ML_AXI] = imx8m_clk_hw_composite_bus("ml_axi", imx8mp_ml_axi_sels, ccm_base + 0x8e00);
+       hws[IMX8MP_CLK_ML_AHB] = imx8m_clk_hw_composite_bus("ml_ahb", imx8mp_ml_ahb_sels, ccm_base + 0x8e80);
 
        hws[IMX8MP_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb_root", imx8mp_ahb_sels, ccm_base + 0x9000);
-       hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100);
-       hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200);
+       hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100);
+       hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite_bus("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200);
 
        hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1);
        hws[IMX8MP_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", ccm_base + 0x9180, 0, 1);
@@ -695,8 +698,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
        hws[IMX8MP_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_root_clk", "ipg_root", ccm_base + 0x43a0, 0);
        hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "sim_enet_root_clk", ccm_base + 0x43b0, 0);
        hws[IMX8MP_CLK_SIM_ENET_ROOT] = imx_clk_hw_gate4("sim_enet_root_clk", "enet_axi", ccm_base + 0x4400, 0);
-       hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_div", ccm_base + 0x4450, 0);
-       hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core_div", ccm_base + 0x4460, 0);
+       hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_core", ccm_base + 0x4450, 0);
+       hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core", ccm_base + 0x4460, 0);
        hws[IMX8MP_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", ccm_base + 0x4470, 0);
        hws[IMX8MP_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", ccm_base + 0x4490, 0);
        hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0);
@@ -713,7 +716,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
        hws[IMX8MP_CLK_GPU_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_axi", ccm_base + 0x4570, 0);
        hws[IMX8MP_CLK_VPU_VC8KE_ROOT] = imx_clk_hw_gate4("vpu_vc8ke_root_clk", "vpu_vc8000e", ccm_base + 0x4590, 0);
        hws[IMX8MP_CLK_VPU_G2_ROOT] = imx_clk_hw_gate4("vpu_g2_root_clk", "vpu_g2", ccm_base + 0x45a0, 0);
-       hws[IMX8MP_CLK_NPU_ROOT] = imx_clk_hw_gate4("npu_root_clk", "ml_div", ccm_base + 0x45b0, 0);
+       hws[IMX8MP_CLK_NPU_ROOT] = imx_clk_hw_gate4("npu_root_clk", "ml_core", ccm_base + 0x45b0, 0);
        hws[IMX8MP_CLK_HSIO_ROOT] = imx_clk_hw_gate4("hsio_root_clk", "ipg_root", ccm_base + 0x45c0, 0);
        hws[IMX8MP_CLK_MEDIA_APB_ROOT] = imx_clk_hw_gate2_shared2("media_apb_root_clk", "media_apb", ccm_base + 0x45d0, 0, &share_count_media);
        hws[IMX8MP_CLK_MEDIA_AXI_ROOT] = imx_clk_hw_gate2_shared2("media_axi_root_clk", "media_axi", ccm_base + 0x45d0, 0, &share_count_media);
@@ -721,7 +724,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
        hws[IMX8MP_CLK_MEDIA_CAM2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam2_pix_root_clk", "media_cam2_pix", ccm_base + 0x45d0, 0, &share_count_media);
        hws[IMX8MP_CLK_MEDIA_DISP1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp1_pix_root_clk", "media_disp1_pix", ccm_base + 0x45d0, 0, &share_count_media);
        hws[IMX8MP_CLK_MEDIA_DISP2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp2_pix_root_clk", "media_disp2_pix", ccm_base + 0x45d0, 0, &share_count_media);
-       hws[IMX8MP_CLK_MEDIA_ISP_ROOT] = imx_clk_hw_gate2_shared2("media_isp_root_clk", "media_isp_div", ccm_base + 0x45d0, 0, &share_count_media);
+       hws[IMX8MP_CLK_MEDIA_ISP_ROOT] = imx_clk_hw_gate2_shared2("media_isp_root_clk", "media_isp", ccm_base + 0x45d0, 0, &share_count_media);
 
        hws[IMX8MP_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", ccm_base + 0x45e0, 0);
        hws[IMX8MP_CLK_HDMI_ROOT] = imx_clk_hw_gate4("hdmi_root_clk", "hdmi_axi", ccm_base + 0x45f0, 0);
@@ -735,9 +738,6 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
                                             hws[IMX8MP_ARM_PLL_OUT]->clk,
                                             hws[IMX8MP_CLK_A53_DIV]->clk);
 
-       clk_hw_set_parent(hws[IMX8MP_CLK_A53_SRC], hws[IMX8MP_SYS_PLL1_800M]);
-       clk_hw_set_parent(hws[IMX8MP_CLK_A53_CORE], hws[IMX8MP_ARM_PLL_OUT]);
-
        imx_check_clk_hws(hws, IMX8MP_CLK_END);
 
        of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
index fdc68db..a64aace 100644 (file)
@@ -405,9 +405,9 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
                return PTR_ERR(base);
 
        /* CORE */
-       hws[IMX8MQ_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels));
-       hws[IMX8MQ_CLK_A53_CG] = imx_clk_hw_gate3_flags("arm_a53_cg", "arm_a53_src", base + 0x8000, 28, CLK_IS_CRITICAL);
-       hws[IMX8MQ_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
+       hws[IMX8MQ_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mq_a53_sels, base + 0x8000);
+       hws[IMX8MQ_CLK_A53_CG] = hws[IMX8MQ_CLK_A53_DIV];
+       hws[IMX8MQ_CLK_A53_SRC] = hws[IMX8MQ_CLK_A53_DIV];
 
        hws[IMX8MQ_CLK_M4_CORE] = imx8m_clk_hw_composite_core("arm_m4_core", imx8mq_arm_m4_sels, base + 0x8080);
        hws[IMX8MQ_CLK_VPU_CORE] = imx8m_clk_hw_composite_core("vpu_core", imx8mq_vpu_sels, base + 0x8100);
@@ -432,22 +432,22 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
 
        /* BUS */
        hws[IMX8MQ_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mq_main_axi_sels, base + 0x8800);
-       hws[IMX8MQ_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mq_enet_axi_sels, base + 0x8880);
-       hws[IMX8MQ_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite("nand_usdhc_bus", imx8mq_nand_usdhc_sels, base + 0x8900);
-       hws[IMX8MQ_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mq_vpu_bus_sels, base + 0x8980);
-       hws[IMX8MQ_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mq_disp_axi_sels, base + 0x8a00);
-       hws[IMX8MQ_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mq_disp_apb_sels, base + 0x8a80);
-       hws[IMX8MQ_CLK_DISP_RTRM] = imx8m_clk_hw_composite("disp_rtrm", imx8mq_disp_rtrm_sels, base + 0x8b00);
-       hws[IMX8MQ_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80);
-       hws[IMX8MQ_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mq_gpu_axi_sels, base + 0x8c00);
-       hws[IMX8MQ_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mq_gpu_ahb_sels, base + 0x8c80);
+       hws[IMX8MQ_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mq_enet_axi_sels, base + 0x8880);
+       hws[IMX8MQ_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_bus("nand_usdhc_bus", imx8mq_nand_usdhc_sels, base + 0x8900);
+       hws[IMX8MQ_CLK_VPU_BUS] = imx8m_clk_hw_composite_bus("vpu_bus", imx8mq_vpu_bus_sels, base + 0x8980);
+       hws[IMX8MQ_CLK_DISP_AXI] = imx8m_clk_hw_composite_bus("disp_axi", imx8mq_disp_axi_sels, base + 0x8a00);
+       hws[IMX8MQ_CLK_DISP_APB] = imx8m_clk_hw_composite_bus("disp_apb", imx8mq_disp_apb_sels, base + 0x8a80);
+       hws[IMX8MQ_CLK_DISP_RTRM] = imx8m_clk_hw_composite_bus("disp_rtrm", imx8mq_disp_rtrm_sels, base + 0x8b00);
+       hws[IMX8MQ_CLK_USB_BUS] = imx8m_clk_hw_composite_bus("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80);
+       hws[IMX8MQ_CLK_GPU_AXI] = imx8m_clk_hw_composite_bus("gpu_axi", imx8mq_gpu_axi_sels, base + 0x8c00);
+       hws[IMX8MQ_CLK_GPU_AHB] = imx8m_clk_hw_composite_bus("gpu_ahb", imx8mq_gpu_ahb_sels, base + 0x8c80);
        hws[IMX8MQ_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mq_noc_sels, base + 0x8d00);
        hws[IMX8MQ_CLK_NOC_APB] = imx8m_clk_hw_composite_critical("noc_apb", imx8mq_noc_apb_sels, base + 0x8d80);
 
        /* AHB */
        /* AHB clock is used by the AHB bus therefore marked as critical */
        hws[IMX8MQ_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mq_ahb_sels, base + 0x9000);
-       hws[IMX8MQ_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mq_audio_ahb_sels, base + 0x9100);
+       hws[IMX8MQ_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mq_audio_ahb_sels, base + 0x9100);
 
        /* IPG */
        hws[IMX8MQ_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
@@ -599,9 +599,6 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
                                           hws[IMX8MQ_ARM_PLL_OUT]->clk,
                                           hws[IMX8MQ_CLK_A53_DIV]->clk);
 
-       clk_hw_set_parent(hws[IMX8MQ_CLK_A53_SRC], hws[IMX8MQ_SYS1_PLL_800M]);
-       clk_hw_set_parent(hws[IMX8MQ_CLK_A53_CORE], hws[IMX8MQ_ARM_PLL_OUT]);
-
        imx_check_clk_hws(hws, IMX8MQ_CLK_END);
 
        err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
index a83bbbe..f9eb189 100644 (file)
@@ -378,9 +378,9 @@ static const struct clk_ops clk_pll1443x_ops = {
        .set_rate       = clk_pll1443x_set_rate,
 };
 
-struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
-                                 void __iomem *base,
-                                 const struct imx_pll14xx_clk *pll_clk)
+struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name,
+                               const char *parent_name, void __iomem *base,
+                               const struct imx_pll14xx_clk *pll_clk)
 {
        struct clk_pll14xx *pll;
        struct clk_hw *hw;
@@ -426,7 +426,7 @@ struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
 
        hw = &pll->hw;
 
-       ret = clk_hw_register(NULL, hw);
+       ret = clk_hw_register(dev, hw);
        if (ret) {
                pr_err("%s: failed to register pll %s %d\n",
                        __func__, name, ret);
index df91a82..a7db930 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/clk-provider.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/slab.h>
 #include <linux/jiffies.h>
 #include <linux/err.h>
@@ -25,6 +26,8 @@
 #define IMX7_ENET_PLL_POWER    (0x1 << 5)
 #define IMX7_DDR_PLL_POWER     (0x1 << 20)
 
+#define PLL_LOCK_TIMEOUT       10000
+
 /**
  * struct clk_pllv3 - IMX PLL clock version 3
  * @clk_hw:     clock source
@@ -53,23 +56,14 @@ struct clk_pllv3 {
 
 static int clk_pllv3_wait_lock(struct clk_pllv3 *pll)
 {
-       unsigned long timeout = jiffies + msecs_to_jiffies(10);
        u32 val = readl_relaxed(pll->base) & pll->power_bit;
 
        /* No need to wait for lock when pll is not powered up */
        if ((pll->powerup_set && !val) || (!pll->powerup_set && val))
                return 0;
 
-       /* Wait for PLL to lock */
-       do {
-               if (readl_relaxed(pll->base) & BM_PLL_LOCK)
-                       break;
-               if (time_after(jiffies, timeout))
-                       break;
-               usleep_range(50, 500);
-       } while (1);
-
-       return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT;
+       return readl_relaxed_poll_timeout(pll->base, val, val & BM_PLL_LOCK,
+                                         500, PLL_LOCK_TIMEOUT);
 }
 
 static int clk_pllv3_prepare(struct clk_hw *hw)
index d4a2be1..773d8a5 100644 (file)
@@ -72,7 +72,6 @@ struct clk_sscg_pll_setup {
        int divr2, divf2;
        int divq;
        int bypass;
-
        uint64_t vco1;
        uint64_t vco2;
        uint64_t fout;
@@ -86,11 +85,8 @@ struct clk_sscg_pll_setup {
 struct clk_sscg_pll {
        struct clk_hw   hw;
        const struct clk_ops  ops;
-
        void __iomem *base;
-
        struct clk_sscg_pll_setup setup;
-
        u8 parent;
        u8 bypass1;
        u8 bypass2;
@@ -194,7 +190,6 @@ static int clk_sscg_pll2_find_setup(struct clk_sscg_pll_setup *setup,
                                        struct clk_sscg_pll_setup *temp_setup,
                                        uint64_t ref)
 {
-
        int ret;
 
        if (ref < PLL_STAGE1_MIN_FREQ || ref > PLL_STAGE1_MAX_FREQ)
@@ -253,7 +248,6 @@ static int clk_sscg_pll1_find_setup(struct clk_sscg_pll_setup *setup,
                                        struct clk_sscg_pll_setup *temp_setup,
                                        uint64_t ref)
 {
-
        int ret;
 
        if (ref < PLL_REF_MIN_FREQ || ref > PLL_REF_MAX_FREQ)
@@ -280,7 +274,6 @@ static int clk_sscg_pll_find_setup(struct clk_sscg_pll_setup *setup,
        temp_setup.fout_request = rate;
 
        switch (try_bypass) {
-
        case PLL_BYPASS2:
                if (prate == rate) {
                        setup->bypass = PLL_BYPASS2;
@@ -288,11 +281,9 @@ static int clk_sscg_pll_find_setup(struct clk_sscg_pll_setup *setup,
                        ret = 0;
                }
                break;
-
        case PLL_BYPASS1:
                ret = clk_sscg_pll2_find_setup(setup, &temp_setup, prate);
                break;
-
        case PLL_BYPASS_NONE:
                ret = clk_sscg_pll1_find_setup(setup, &temp_setup, prate);
                break;
@@ -301,7 +292,6 @@ static int clk_sscg_pll_find_setup(struct clk_sscg_pll_setup *setup,
        return ret;
 }
 
-
 static int clk_sscg_pll_is_prepared(struct clk_hw *hw)
 {
        struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
index f074dd8..16adbc3 100644 (file)
@@ -5,6 +5,8 @@
 #include <linux/spinlock.h>
 #include <linux/clk-provider.h>
 
+#define IMX_CLK_GATE2_SINGLE_BIT       1
+
 extern spinlock_t imx_ccm_lock;
 
 void imx_check_clocks(struct clk *clks[], unsigned int count);
@@ -131,9 +133,9 @@ struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
 #define imx_clk_pll14xx(name, parent_name, base, pll_clk) \
        to_clk(imx_clk_hw_pll14xx(name, parent_name, base, pll_clk))
 
-struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
-                                 void __iomem *base,
-                                 const struct imx_pll14xx_clk *pll_clk);
+struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name,
+                               const char *parent_name, void __iomem *base,
+                               const struct imx_pll14xx_clk *pll_clk);
 
 struct clk_hw *imx_clk_hw_pllv1(enum imx_pllv1_type type, const char *name,
                const char *parent, void __iomem *base);
@@ -240,6 +242,13 @@ static inline struct clk *to_clk(struct clk_hw *hw)
        return hw->clk;
 }
 
+static inline struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
+                                 void __iomem *base,
+                                 const struct imx_pll14xx_clk *pll_clk)
+{
+       return imx_dev_clk_hw_pll14xx(NULL, name, parent_name, base, pll_clk);
+}
+
 static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)
 {
        return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
@@ -310,6 +319,13 @@ static inline struct clk_hw *imx_clk_hw_gate(const char *name, const char *paren
                                    shift, 0, &imx_ccm_lock);
 }
 
+static inline struct clk_hw *imx_dev_clk_hw_gate(struct device *dev, const char *name,
+                                               const char *parent, void __iomem *reg, u8 shift)
+{
+       return clk_hw_register_gate(dev, name, parent, CLK_SET_RATE_PARENT, reg,
+                                   shift, 0, &imx_ccm_lock);
+}
+
 static inline struct clk_hw *imx_clk_hw_gate_dis(const char *name, const char *parent,
                void __iomem *reg, u8 shift)
 {
@@ -355,6 +371,17 @@ static inline struct clk_hw *imx_clk_hw_gate2_shared2(const char *name,
                                  &imx_ccm_lock, share_count);
 }
 
+static inline struct clk_hw *imx_dev_clk_hw_gate_shared(struct device *dev,
+                               const char *name, const char *parent,
+                               void __iomem *reg, u8 shift,
+                               unsigned int *share_count)
+{
+       return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
+                                       CLK_OPS_PARENT_ENABLE, reg, shift, 0x3,
+                                       IMX_CLK_GATE2_SINGLE_BIT,
+                                       &imx_ccm_lock, share_count);
+}
+
 static inline struct clk *imx_clk_gate2_cgr(const char *name,
                const char *parent, void __iomem *reg, u8 shift, u8 cgr_val)
 {
@@ -411,6 +438,15 @@ static inline struct clk_hw *imx_clk_hw_mux(const char *name, void __iomem *reg,
                        width, 0, &imx_ccm_lock);
 }
 
+static inline struct clk_hw *imx_dev_clk_hw_mux(struct device *dev,
+                       const char *name, void __iomem *reg, u8 shift,
+                       u8 width, const char * const *parents, int num_parents)
+{
+       return clk_hw_register_mux(dev, name, parents, num_parents,
+                       CLK_SET_RATE_NO_REPARENT | CLK_SET_PARENT_GATE,
+                       reg, shift, width, 0, &imx_ccm_lock);
+}
+
 static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
                        u8 shift, u8 width, const char * const *parents,
                        int num_parents)
@@ -473,11 +509,25 @@ static inline struct clk_hw *imx_clk_hw_mux_flags(const char *name,
                                   reg, shift, width, 0, &imx_ccm_lock);
 }
 
+static inline struct clk_hw *imx_dev_clk_hw_mux_flags(struct device *dev,
+                                                 const char *name,
+                                                 void __iomem *reg, u8 shift,
+                                                 u8 width,
+                                                 const char * const *parents,
+                                                 int num_parents,
+                                                 unsigned long flags)
+{
+       return clk_hw_register_mux(dev, name, parents, num_parents,
+                                  flags | CLK_SET_RATE_NO_REPARENT,
+                                  reg, shift, width, 0, &imx_ccm_lock);
+}
+
 struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
                struct clk *div, struct clk *mux, struct clk *pll,
                struct clk *step);
 
 #define IMX_COMPOSITE_CORE     BIT(0)
+#define IMX_COMPOSITE_BUS      BIT(1)
 
 struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
                                            const char * const *parent_names,
@@ -486,6 +536,12 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
                                            u32 composite_flags,
                                            unsigned long flags);
 
+#define imx8m_clk_hw_composite_bus(name, parent_names, reg)    \
+       imx8m_clk_hw_composite_flags(name, parent_names, \
+                       ARRAY_SIZE(parent_names), reg, \
+                       IMX_COMPOSITE_BUS, \
+                       CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
+
 #define imx8m_clk_hw_composite_core(name, parent_names, reg)   \
        imx8m_clk_hw_composite_flags(name, parent_names, \
                        ARRAY_SIZE(parent_names), reg, \
index fad616c..30c1576 100644 (file)
@@ -3702,7 +3702,9 @@ static struct clk_regmap g12a_hdmi = {
 
 /*
  * The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
- * muxed by a glitch-free switch.
+ * muxed by a glitch-free switch. The CCF can manage this glitch-free
+ * mux because it does top-to-bottom updates the each clock tree and
+ * switches to the "inactive" one when CLK_SET_RATE_GATE is set.
  */
 static const struct clk_parent_data g12a_mali_0_1_parent_data[] = {
        { .fw_name = "xtal", },
@@ -3726,7 +3728,13 @@ static struct clk_regmap g12a_mali_0_sel = {
                .ops = &clk_regmap_mux_ops,
                .parent_data = g12a_mali_0_1_parent_data,
                .num_parents = 8,
-               .flags = CLK_SET_RATE_NO_REPARENT,
+               /*
+                * Don't request the parent to change the rate because
+                * all GPU frequencies can be derived from the fclk_*
+                * clocks and one special GP0_PLL setting. This is
+                * important because we need the MPLL clocks for audio.
+                */
+               .flags = 0,
        },
 };
 
@@ -3743,7 +3751,7 @@ static struct clk_regmap g12a_mali_0_div = {
                        &g12a_mali_0_sel.hw
                },
                .num_parents = 1,
-               .flags = CLK_SET_RATE_NO_REPARENT,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -3759,7 +3767,7 @@ static struct clk_regmap g12a_mali_0 = {
                        &g12a_mali_0_div.hw
                },
                .num_parents = 1,
-               .flags = CLK_SET_RATE_PARENT,
+               .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
        },
 };
 
@@ -3774,7 +3782,13 @@ static struct clk_regmap g12a_mali_1_sel = {
                .ops = &clk_regmap_mux_ops,
                .parent_data = g12a_mali_0_1_parent_data,
                .num_parents = 8,
-               .flags = CLK_SET_RATE_NO_REPARENT,
+               /*
+                * Don't request the parent to change the rate because
+                * all GPU frequencies can be derived from the fclk_*
+                * clocks and one special GP0_PLL setting. This is
+                * important because we need the MPLL clocks for audio.
+                */
+               .flags = 0,
        },
 };
 
@@ -3791,7 +3805,7 @@ static struct clk_regmap g12a_mali_1_div = {
                        &g12a_mali_1_sel.hw
                },
                .num_parents = 1,
-               .flags = CLK_SET_RATE_NO_REPARENT,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -3807,7 +3821,7 @@ static struct clk_regmap g12a_mali_1 = {
                        &g12a_mali_1_div.hw
                },
                .num_parents = 1,
-               .flags = CLK_SET_RATE_PARENT,
+               .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
        },
 };
 
@@ -3827,7 +3841,7 @@ static struct clk_regmap g12a_mali = {
                .ops = &clk_regmap_mux_ops,
                .parent_hws = g12a_mali_parent_hws,
                .num_parents = 2,
-               .flags = CLK_SET_RATE_NO_REPARENT,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
index 5fd6a57..0a68af6 100644 (file)
@@ -957,7 +957,9 @@ static struct clk_regmap gxbb_sar_adc_clk = {
 
 /*
  * The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
- * muxed by a glitch-free switch.
+ * muxed by a glitch-free switch. The CCF can manage this glitch-free
+ * mux because it does top-to-bottom updates the each clock tree and
+ * switches to the "inactive" one when CLK_SET_RATE_GATE is set.
  */
 
 static const struct clk_parent_data gxbb_mali_0_1_parent_data[] = {
@@ -980,14 +982,15 @@ static struct clk_regmap gxbb_mali_0_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0_sel",
                .ops = &clk_regmap_mux_ops,
-               /*
-                * bits 10:9 selects from 8 possible parents:
-                * xtal, gp0_pll, mpll2, mpll1, fclk_div7,
-                * fclk_div4, fclk_div3, fclk_div5
-                */
                .parent_data = gxbb_mali_0_1_parent_data,
                .num_parents = 8,
-               .flags = CLK_SET_RATE_NO_REPARENT,
+               /*
+                * Don't request the parent to change the rate because
+                * all GPU frequencies can be derived from the fclk_*
+                * clocks and one special GP0_PLL setting. This is
+                * important because we need the MPLL clocks for audio.
+                */
+               .flags = 0,
        },
 };
 
@@ -1004,7 +1007,7 @@ static struct clk_regmap gxbb_mali_0_div = {
                        &gxbb_mali_0_sel.hw
                },
                .num_parents = 1,
-               .flags = CLK_SET_RATE_NO_REPARENT,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -1020,7 +1023,7 @@ static struct clk_regmap gxbb_mali_0 = {
                        &gxbb_mali_0_div.hw
                },
                .num_parents = 1,
-               .flags = CLK_SET_RATE_PARENT,
+               .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
        },
 };
 
@@ -1033,14 +1036,15 @@ static struct clk_regmap gxbb_mali_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1_sel",
                .ops = &clk_regmap_mux_ops,
-               /*
-                * bits 10:9 selects from 8 possible parents:
-                * xtal, gp0_pll, mpll2, mpll1, fclk_div7,
-                * fclk_div4, fclk_div3, fclk_div5
-                */
                .parent_data = gxbb_mali_0_1_parent_data,
                .num_parents = 8,
-               .flags = CLK_SET_RATE_NO_REPARENT,
+               /*
+                * Don't request the parent to change the rate because
+                * all GPU frequencies can be derived from the fclk_*
+                * clocks and one special GP0_PLL setting. This is
+                * important because we need the MPLL clocks for audio.
+                */
+               .flags = 0,
        },
 };
 
@@ -1057,7 +1061,7 @@ static struct clk_regmap gxbb_mali_1_div = {
                        &gxbb_mali_1_sel.hw
                },
                .num_parents = 1,
-               .flags = CLK_SET_RATE_NO_REPARENT,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -1073,7 +1077,7 @@ static struct clk_regmap gxbb_mali_1 = {
                        &gxbb_mali_1_div.hw
                },
                .num_parents = 1,
-               .flags = CLK_SET_RATE_PARENT,
+               .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
        },
 };
 
@@ -1093,7 +1097,7 @@ static struct clk_regmap gxbb_mali = {
                .ops = &clk_regmap_mux_ops,
                .parent_hws = gxbb_mali_parent_hws,
                .num_parents = 2,
-               .flags = CLK_SET_RATE_NO_REPARENT,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
index 34a70c4..edc09d0 100644 (file)
@@ -1077,7 +1077,7 @@ static struct clk_regmap meson8b_vid_pll_in_sel = {
                 * Meson8m2: vid2_pll
                 */
                .parent_hws = (const struct clk_hw *[]) {
-                       &meson8b_hdmi_pll_dco.hw
+                       &meson8b_hdmi_pll_lvds_out.hw
                },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
@@ -1213,7 +1213,7 @@ static struct clk_regmap meson8b_vclk_in_en = {
 
 static struct clk_regmap meson8b_vclk_div1_gate = {
        .data = &(struct clk_regmap_gate_data){
-               .offset = HHI_VID_CLK_DIV,
+               .offset = HHI_VID_CLK_CNTL,
                .bit_idx = 0,
        },
        .hw.init = &(struct clk_init_data){
@@ -1243,7 +1243,7 @@ static struct clk_fixed_factor meson8b_vclk_div2_div = {
 
 static struct clk_regmap meson8b_vclk_div2_div_gate = {
        .data = &(struct clk_regmap_gate_data){
-               .offset = HHI_VID_CLK_DIV,
+               .offset = HHI_VID_CLK_CNTL,
                .bit_idx = 1,
        },
        .hw.init = &(struct clk_init_data){
@@ -1273,7 +1273,7 @@ static struct clk_fixed_factor meson8b_vclk_div4_div = {
 
 static struct clk_regmap meson8b_vclk_div4_div_gate = {
        .data = &(struct clk_regmap_gate_data){
-               .offset = HHI_VID_CLK_DIV,
+               .offset = HHI_VID_CLK_CNTL,
                .bit_idx = 2,
        },
        .hw.init = &(struct clk_init_data){
@@ -1303,7 +1303,7 @@ static struct clk_fixed_factor meson8b_vclk_div6_div = {
 
 static struct clk_regmap meson8b_vclk_div6_div_gate = {
        .data = &(struct clk_regmap_gate_data){
-               .offset = HHI_VID_CLK_DIV,
+               .offset = HHI_VID_CLK_CNTL,
                .bit_idx = 3,
        },
        .hw.init = &(struct clk_init_data){
@@ -1333,7 +1333,7 @@ static struct clk_fixed_factor meson8b_vclk_div12_div = {
 
 static struct clk_regmap meson8b_vclk_div12_div_gate = {
        .data = &(struct clk_regmap_gate_data){
-               .offset = HHI_VID_CLK_DIV,
+               .offset = HHI_VID_CLK_CNTL,
                .bit_idx = 4,
        },
        .hw.init = &(struct clk_init_data){
@@ -1725,7 +1725,7 @@ static struct clk_regmap meson8b_hdmi_sys_sel = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_sys_sel",
-               .ops = &clk_regmap_mux_ro_ops,
+               .ops = &clk_regmap_mux_ops,
                /* FIXME: all other parents are unknown */
                .parent_data = &(const struct clk_parent_data) {
                        .fw_name = "xtal",
@@ -1745,7 +1745,7 @@ static struct clk_regmap meson8b_hdmi_sys_div = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_sys_div",
-               .ops = &clk_regmap_divider_ro_ops,
+               .ops = &clk_regmap_divider_ops,
                .parent_hws = (const struct clk_hw *[]) {
                        &meson8b_hdmi_sys_sel.hw
                },
@@ -1761,7 +1761,7 @@ static struct clk_regmap meson8b_hdmi_sys = {
        },
        .hw.init = &(struct clk_init_data) {
                .name = "hdmi_sys",
-               .ops = &clk_regmap_gate_ro_ops,
+               .ops = &clk_regmap_gate_ops,
                .parent_hws = (const struct clk_hw *[]) {
                        &meson8b_hdmi_sys_div.hw
                },
@@ -1918,6 +1918,13 @@ static struct clk_regmap meson8b_mali = {
        },
 };
 
+static const struct reg_sequence meson8m2_gp_pll_init_regs[] = {
+       { .reg = HHI_GP_PLL_CNTL2,      .def = 0x59c88000 },
+       { .reg = HHI_GP_PLL_CNTL3,      .def = 0xca463823 },
+       { .reg = HHI_GP_PLL_CNTL4,      .def = 0x0286a027 },
+       { .reg = HHI_GP_PLL_CNTL5,      .def = 0x00003000 },
+};
+
 static const struct pll_params_table meson8m2_gp_pll_params_table[] = {
        PLL_PARAMS(182, 3),
        { /* sentinel */ },
@@ -1951,6 +1958,8 @@ static struct clk_regmap meson8m2_gp_pll_dco = {
                        .width   = 1,
                },
                .table = meson8m2_gp_pll_params_table,
+               .init_regs = meson8m2_gp_pll_init_regs,
+               .init_count = ARRAY_SIZE(meson8m2_gp_pll_init_regs),
        },
        .hw.init = &(struct clk_init_data){
                .name = "gp_pll_dco",
@@ -2063,7 +2072,7 @@ static struct clk_regmap meson8b_vpu_0 = {
                        &meson8b_vpu_0_div.hw
                },
                .num_parents = 1,
-               .flags = CLK_SET_RATE_PARENT,
+               .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
        },
 };
 
@@ -2134,10 +2143,18 @@ static struct clk_regmap meson8b_vpu_1 = {
                        &meson8b_vpu_1_div.hw
                },
                .num_parents = 1,
-               .flags = CLK_SET_RATE_PARENT,
+               .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
        },
 };
 
+/*
+ * The VPU clock has two two identical clock trees (vpu_0 and vpu_1)
+ * muxed by a glitch-free switch on Meson8b and Meson8m2. The CCF can
+ * actually manage this glitch-free mux because it does top-to-bottom
+ * updates the each clock tree and switches to the "inactive" one when
+ * CLK_SET_RATE_GATE is set.
+ * Meson8 only has vpu_0 and no glitch-free mux.
+ */
 static struct clk_regmap meson8b_vpu = {
        .data = &(struct clk_regmap_mux_data){
                .offset = HHI_VPU_CLK_CNTL,
@@ -2152,7 +2169,7 @@ static struct clk_regmap meson8b_vpu = {
                        &meson8b_vpu_1.hw,
                },
                .num_parents = 2,
-               .flags = CLK_SET_RATE_NO_REPARENT,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -3506,54 +3523,87 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = {
 static const struct meson8b_clk_reset_line {
        u32 reg;
        u8 bit_idx;
+       bool active_low;
 } meson8b_clk_reset_bits[] = {
        [CLKC_RESET_L2_CACHE_SOFT_RESET] = {
-               .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 30
+               .reg = HHI_SYS_CPU_CLK_CNTL0,
+               .bit_idx = 30,
+               .active_low = false,
        },
        [CLKC_RESET_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET] = {
-               .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 29
+               .reg = HHI_SYS_CPU_CLK_CNTL0,
+               .bit_idx = 29,
+               .active_low = false,
        },
        [CLKC_RESET_SCU_SOFT_RESET] = {
-               .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 28
+               .reg = HHI_SYS_CPU_CLK_CNTL0,
+               .bit_idx = 28,
+               .active_low = false,
        },
        [CLKC_RESET_CPU3_SOFT_RESET] = {
-               .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 27
+               .reg = HHI_SYS_CPU_CLK_CNTL0,
+               .bit_idx = 27,
+               .active_low = false,
        },
        [CLKC_RESET_CPU2_SOFT_RESET] = {
-               .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 26
+               .reg = HHI_SYS_CPU_CLK_CNTL0,
+               .bit_idx = 26,
+               .active_low = false,
        },
        [CLKC_RESET_CPU1_SOFT_RESET] = {
-               .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 25
+               .reg = HHI_SYS_CPU_CLK_CNTL0,
+               .bit_idx = 25,
+               .active_low = false,
        },
        [CLKC_RESET_CPU0_SOFT_RESET] = {
-               .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 24
+               .reg = HHI_SYS_CPU_CLK_CNTL0,
+               .bit_idx = 24,
+               .active_low = false,
        },
        [CLKC_RESET_A5_GLOBAL_RESET] = {
-               .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 18
+               .reg = HHI_SYS_CPU_CLK_CNTL0,
+               .bit_idx = 18,
+               .active_low = false,
        },
        [CLKC_RESET_A5_AXI_SOFT_RESET] = {
-               .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 17
+               .reg = HHI_SYS_CPU_CLK_CNTL0,
+               .bit_idx = 17,
+               .active_low = false,
        },
        [CLKC_RESET_A5_ABP_SOFT_RESET] = {
-               .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 16
+               .reg = HHI_SYS_CPU_CLK_CNTL0,
+               .bit_idx = 16,
+               .active_low = false,
        },
        [CLKC_RESET_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET] = {
-               .reg = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 30
+               .reg = HHI_SYS_CPU_CLK_CNTL1,
+               .bit_idx = 30,
+               .active_low = false,
        },
        [CLKC_RESET_VID_CLK_CNTL_SOFT_RESET] = {
-               .reg = HHI_VID_CLK_CNTL, .bit_idx = 15
+               .reg = HHI_VID_CLK_CNTL,
+               .bit_idx = 15,
+               .active_low = false,
        },
        [CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST] = {
-               .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 7
+               .reg = HHI_VID_DIVIDER_CNTL,
+               .bit_idx = 7,
+               .active_low = false,
        },
        [CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE] = {
-               .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 3
+               .reg = HHI_VID_DIVIDER_CNTL,
+               .bit_idx = 3,
+               .active_low = false,
        },
        [CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST] = {
-               .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 1
+               .reg = HHI_VID_DIVIDER_CNTL,
+               .bit_idx = 1,
+               .active_low = true,
        },
        [CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE] = {
-               .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 0
+               .reg = HHI_VID_DIVIDER_CNTL,
+               .bit_idx = 0,
+               .active_low = true,
        },
 };
 
@@ -3562,22 +3612,22 @@ static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev,
 {
        struct meson8b_clk_reset *meson8b_clk_reset =
                container_of(rcdev, struct meson8b_clk_reset, reset);
-       unsigned long flags;
        const struct meson8b_clk_reset_line *reset;
+       unsigned int value = 0;
+       unsigned long flags;
 
        if (id >= ARRAY_SIZE(meson8b_clk_reset_bits))
                return -EINVAL;
 
        reset = &meson8b_clk_reset_bits[id];
 
+       if (assert != reset->active_low)
+               value = BIT(reset->bit_idx);
+
        spin_lock_irqsave(&meson_clk_lock, flags);
 
-       if (assert)
-               regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
-                                  BIT(reset->bit_idx), BIT(reset->bit_idx));
-       else
-               regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
-                                  BIT(reset->bit_idx), 0);
+       regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
+                          BIT(reset->bit_idx), value);
 
        spin_unlock_irqrestore(&meson_clk_lock, flags);
 
index c889fbe..cd38ae2 100644 (file)
  * [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
  */
 #define HHI_GP_PLL_CNTL                        0x40  /* 0x10 offset in data sheet */
+#define HHI_GP_PLL_CNTL2               0x44  /* 0x11 offset in data sheet */
+#define HHI_GP_PLL_CNTL3               0x48  /* 0x12 offset in data sheet */
+#define HHI_GP_PLL_CNTL4               0x4C  /* 0x13 offset in data sheet */
+#define HHI_GP_PLL_CNTL5               0x50  /* 0x14 offset in data sheet */
 #define HHI_VIID_CLK_DIV               0x128 /* 0x4a offset in data sheet */
 #define HHI_VIID_CLK_CNTL              0x12c /* 0x4b offset in data sheet */
 #define HHI_GCLK_MPEG0                 0x140 /* 0x50 offset in data sheet */
 #define CLKID_CTS_VDAC0                171
 #define CLKID_HDMI_SYS_SEL     172
 #define CLKID_HDMI_SYS_DIV     173
-#define CLKID_HDMI_SYS         174
 #define CLKID_MALI_0_SEL       175
 #define CLKID_MALI_0_DIV       176
 #define CLKID_MALI_0           177
index ac2dd92..9eb79bf 100644 (file)
@@ -8,6 +8,7 @@ config CLK_RENESAS
        select CLK_R7S9210 if ARCH_R7S9210
        select CLK_R8A73A4 if ARCH_R8A73A4
        select CLK_R8A7740 if ARCH_R8A7740
+       select CLK_R8A7742 if ARCH_R8A7742
        select CLK_R8A7743 if ARCH_R8A7743 || ARCH_R8A7744
        select CLK_R8A7745 if ARCH_R8A7745
        select CLK_R8A77470 if ARCH_R8A77470
@@ -55,6 +56,10 @@ config CLK_R8A7740
        select CLK_RENESAS_CPG_MSTP
        select CLK_RENESAS_DIV6
 
+config CLK_R8A7742
+       bool "RZ/G1H clock support" if COMPILE_TEST
+       select CLK_RCAR_GEN2_CPG
+
 config CLK_R8A7743
        bool "RZ/G1M clock support" if COMPILE_TEST
        select CLK_RCAR_GEN2_CPG
@@ -90,12 +95,10 @@ config CLK_R8A7779
 config CLK_R8A7790
        bool "R-Car H2 clock support" if COMPILE_TEST
        select CLK_RCAR_GEN2_CPG
-       select CLK_RENESAS_DIV6
 
 config CLK_R8A7791
        bool "R-Car M2-W/N clock support" if COMPILE_TEST
        select CLK_RCAR_GEN2_CPG
-       select CLK_RENESAS_DIV6
 
 config CLK_R8A7792
        bool "R-Car V2H clock support" if COMPILE_TEST
@@ -104,7 +107,6 @@ config CLK_R8A7792
 config CLK_R8A7794
        bool "R-Car E2 clock support" if COMPILE_TEST
        select CLK_RCAR_GEN2_CPG
-       select CLK_RENESAS_DIV6
 
 config CLK_R8A7795
        bool "R-Car H3 clock support" if COMPILE_TEST
index 4a722bc..a4066f9 100644 (file)
@@ -5,6 +5,7 @@ obj-$(CONFIG_CLK_RZA1)                  += clk-rz.o
 obj-$(CONFIG_CLK_R7S9210)              += r7s9210-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A73A4)              += clk-r8a73a4.o
 obj-$(CONFIG_CLK_R8A7740)              += clk-r8a7740.o
+obj-$(CONFIG_CLK_R8A7742)              += r8a7742-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A7743)              += r8a7743-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A7745)              += r8a7745-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A77470)             += r8a77470-cpg-mssr.o
diff --git a/drivers/clk/renesas/r8a7742-cpg-mssr.c b/drivers/clk/renesas/r8a7742-cpg-mssr.c
new file mode 100644 (file)
index 0000000..e919828
--- /dev/null
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * r8a7742 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/soc/renesas/rcar-rst.h>
+
+#include <dt-bindings/clock/r8a7742-cpg-mssr.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen2-cpg.h"
+
+enum clk_ids {
+       /* Core Clock Outputs exported to DT */
+       LAST_DT_CORE_CLK = R8A7742_CLK_OSC,
+
+       /* External Input Clocks */
+       CLK_EXTAL,
+       CLK_USB_EXTAL,
+
+       /* Internal Core Clocks */
+       CLK_MAIN,
+       CLK_PLL0,
+       CLK_PLL1,
+       CLK_PLL3,
+       CLK_PLL1_DIV2,
+
+       /* Module Clocks */
+       MOD_CLK_BASE
+};
+
+static const struct cpg_core_clk r8a7742_core_clks[] __initconst = {
+       /* External Clock Inputs */
+       DEF_INPUT("extal",      CLK_EXTAL),
+       DEF_INPUT("usb_extal",  CLK_USB_EXTAL),
+
+       /* Internal Core Clocks */
+       DEF_BASE(".main",       CLK_MAIN, CLK_TYPE_GEN2_MAIN, CLK_EXTAL),
+       DEF_BASE(".pll0",       CLK_PLL0, CLK_TYPE_GEN2_PLL0, CLK_MAIN),
+       DEF_BASE(".pll1",       CLK_PLL1, CLK_TYPE_GEN2_PLL1, CLK_MAIN),
+       DEF_BASE(".pll3",       CLK_PLL3, CLK_TYPE_GEN2_PLL3, CLK_MAIN),
+
+       DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
+
+       /* Core Clock Outputs */
+       DEF_BASE("z",    R8A7742_CLK_Z,    CLK_TYPE_GEN2_Z,     CLK_PLL0),
+       DEF_BASE("lb",   R8A7742_CLK_LB,   CLK_TYPE_GEN2_LB,    CLK_PLL1),
+       DEF_BASE("sdh",  R8A7742_CLK_SDH,  CLK_TYPE_GEN2_SDH,   CLK_PLL1),
+       DEF_BASE("sd0",  R8A7742_CLK_SD0,  CLK_TYPE_GEN2_SD0,   CLK_PLL1),
+       DEF_BASE("sd1",  R8A7742_CLK_SD1,  CLK_TYPE_GEN2_SD1,   CLK_PLL1),
+       DEF_BASE("qspi", R8A7742_CLK_QSPI, CLK_TYPE_GEN2_QSPI,  CLK_PLL1_DIV2),
+       DEF_BASE("rcan", R8A7742_CLK_RCAN, CLK_TYPE_GEN2_RCAN,  CLK_USB_EXTAL),
+
+       DEF_FIXED("z2",    R8A7742_CLK_Z2,      CLK_PLL1,           2, 1),
+       DEF_FIXED("zg",    R8A7742_CLK_ZG,      CLK_PLL1,           3, 1),
+       DEF_FIXED("zx",    R8A7742_CLK_ZX,      CLK_PLL1,           3, 1),
+       DEF_FIXED("zs",    R8A7742_CLK_ZS,      CLK_PLL1,           6, 1),
+       DEF_FIXED("hp",    R8A7742_CLK_HP,      CLK_PLL1,          12, 1),
+       DEF_FIXED("b",     R8A7742_CLK_B,       CLK_PLL1,          12, 1),
+       DEF_FIXED("p",     R8A7742_CLK_P,       CLK_PLL1,          24, 1),
+       DEF_FIXED("cl",    R8A7742_CLK_CL,      CLK_PLL1,          48, 1),
+       DEF_FIXED("m2",    R8A7742_CLK_M2,      CLK_PLL1,           8, 1),
+       DEF_FIXED("zb3",   R8A7742_CLK_ZB3,     CLK_PLL3,           4, 1),
+       DEF_FIXED("zb3d2", R8A7742_CLK_ZB3D2,   CLK_PLL3,           8, 1),
+       DEF_FIXED("ddr",   R8A7742_CLK_DDR,     CLK_PLL3,           8, 1),
+       DEF_FIXED("mp",    R8A7742_CLK_MP,      CLK_PLL1_DIV2,     15, 1),
+       DEF_FIXED("cp",    R8A7742_CLK_CP,      CLK_EXTAL,          2, 1),
+       DEF_FIXED("r",     R8A7742_CLK_R,       CLK_PLL1,       49152, 1),
+       DEF_FIXED("osc",   R8A7742_CLK_OSC,     CLK_PLL1,       12288, 1),
+
+       DEF_DIV6P1("sd2",  R8A7742_CLK_SD2,     CLK_PLL1_DIV2,  0x078),
+       DEF_DIV6P1("sd3",  R8A7742_CLK_SD3,     CLK_PLL1_DIV2,  0x26c),
+       DEF_DIV6P1("mmc0", R8A7742_CLK_MMC0,    CLK_PLL1_DIV2,  0x240),
+       DEF_DIV6P1("mmc1", R8A7742_CLK_MMC1,    CLK_PLL1_DIV2,  0x244),
+};
+
+static const struct mssr_mod_clk r8a7742_mod_clks[] __initconst = {
+       DEF_MOD("msiof0",                  0,   R8A7742_CLK_MP),
+       DEF_MOD("vcp1",                  100,   R8A7742_CLK_ZS),
+       DEF_MOD("vcp0",                  101,   R8A7742_CLK_ZS),
+       DEF_MOD("vpc1",                  102,   R8A7742_CLK_ZS),
+       DEF_MOD("vpc0",                  103,   R8A7742_CLK_ZS),
+       DEF_MOD("tmu1",                  111,   R8A7742_CLK_P),
+       DEF_MOD("3dg",                   112,   R8A7742_CLK_ZG),
+       DEF_MOD("2d-dmac",               115,   R8A7742_CLK_ZS),
+       DEF_MOD("fdp1-2",                117,   R8A7742_CLK_ZS),
+       DEF_MOD("fdp1-1",                118,   R8A7742_CLK_ZS),
+       DEF_MOD("fdp1-0",                119,   R8A7742_CLK_ZS),
+       DEF_MOD("tmu3",                  121,   R8A7742_CLK_P),
+       DEF_MOD("tmu2",                  122,   R8A7742_CLK_P),
+       DEF_MOD("cmt0",                  124,   R8A7742_CLK_R),
+       DEF_MOD("tmu0",                  125,   R8A7742_CLK_CP),
+       DEF_MOD("vsp1du1",               127,   R8A7742_CLK_ZS),
+       DEF_MOD("vsp1du0",               128,   R8A7742_CLK_ZS),
+       DEF_MOD("vsp1-sy",               131,   R8A7742_CLK_ZS),
+       DEF_MOD("scifa2",                202,   R8A7742_CLK_MP),
+       DEF_MOD("scifa1",                203,   R8A7742_CLK_MP),
+       DEF_MOD("scifa0",                204,   R8A7742_CLK_MP),
+       DEF_MOD("msiof2",                205,   R8A7742_CLK_MP),
+       DEF_MOD("scifb0",                206,   R8A7742_CLK_MP),
+       DEF_MOD("scifb1",                207,   R8A7742_CLK_MP),
+       DEF_MOD("msiof1",                208,   R8A7742_CLK_MP),
+       DEF_MOD("msiof3",                215,   R8A7742_CLK_MP),
+       DEF_MOD("scifb2",                216,   R8A7742_CLK_MP),
+       DEF_MOD("sys-dmac1",             218,   R8A7742_CLK_ZS),
+       DEF_MOD("sys-dmac0",             219,   R8A7742_CLK_ZS),
+       DEF_MOD("iic2",                  300,   R8A7742_CLK_HP),
+       DEF_MOD("tpu0",                  304,   R8A7742_CLK_CP),
+       DEF_MOD("mmcif1",                305,   R8A7742_CLK_MMC1),
+       DEF_MOD("scif2",                 310,   R8A7742_CLK_P),
+       DEF_MOD("sdhi3",                 311,   R8A7742_CLK_SD3),
+       DEF_MOD("sdhi2",                 312,   R8A7742_CLK_SD2),
+       DEF_MOD("sdhi1",                 313,   R8A7742_CLK_SD1),
+       DEF_MOD("sdhi0",                 314,   R8A7742_CLK_SD0),
+       DEF_MOD("mmcif0",                315,   R8A7742_CLK_MMC0),
+       DEF_MOD("iic0",                  318,   R8A7742_CLK_HP),
+       DEF_MOD("pciec",                 319,   R8A7742_CLK_MP),
+       DEF_MOD("iic1",                  323,   R8A7742_CLK_HP),
+       DEF_MOD("usb3.0",                328,   R8A7742_CLK_MP),
+       DEF_MOD("cmt1",                  329,   R8A7742_CLK_R),
+       DEF_MOD("usbhs-dmac0",           330,   R8A7742_CLK_HP),
+       DEF_MOD("usbhs-dmac1",           331,   R8A7742_CLK_HP),
+       DEF_MOD("rwdt",                  402,   R8A7742_CLK_R),
+       DEF_MOD("irqc",                  407,   R8A7742_CLK_CP),
+       DEF_MOD("intc-sys",              408,   R8A7742_CLK_ZS),
+       DEF_MOD("audio-dmac1",           501,   R8A7742_CLK_HP),
+       DEF_MOD("audio-dmac0",           502,   R8A7742_CLK_HP),
+       DEF_MOD("thermal",               522,   CLK_EXTAL),
+       DEF_MOD("pwm",                   523,   R8A7742_CLK_P),
+       DEF_MOD("usb-ehci",              703,   R8A7742_CLK_MP),
+       DEF_MOD("usbhs",                 704,   R8A7742_CLK_HP),
+       DEF_MOD("hscif1",                716,   R8A7742_CLK_ZS),
+       DEF_MOD("hscif0",                717,   R8A7742_CLK_ZS),
+       DEF_MOD("scif1",                 720,   R8A7742_CLK_P),
+       DEF_MOD("scif0",                 721,   R8A7742_CLK_P),
+       DEF_MOD("du2",                   722,   R8A7742_CLK_ZX),
+       DEF_MOD("du1",                   723,   R8A7742_CLK_ZX),
+       DEF_MOD("du0",                   724,   R8A7742_CLK_ZX),
+       DEF_MOD("lvds1",                 725,   R8A7742_CLK_ZX),
+       DEF_MOD("lvds0",                 726,   R8A7742_CLK_ZX),
+       DEF_MOD("r-gp2d",                807,   R8A7742_CLK_ZX),
+       DEF_MOD("vin3",                  808,   R8A7742_CLK_ZG),
+       DEF_MOD("vin2",                  809,   R8A7742_CLK_ZG),
+       DEF_MOD("vin1",                  810,   R8A7742_CLK_ZG),
+       DEF_MOD("vin0",                  811,   R8A7742_CLK_ZG),
+       DEF_MOD("etheravb",              812,   R8A7742_CLK_HP),
+       DEF_MOD("ether",                 813,   R8A7742_CLK_P),
+       DEF_MOD("sata1",                 814,   R8A7742_CLK_ZS),
+       DEF_MOD("sata0",                 815,   R8A7742_CLK_ZS),
+       DEF_MOD("imr-x2-1",              820,   R8A7742_CLK_ZG),
+       DEF_MOD("imr-x2-0",              821,   R8A7742_CLK_HP),
+       DEF_MOD("imr-lsx2-1",            822,   R8A7742_CLK_P),
+       DEF_MOD("imr-lsx2-0",            823,   R8A7742_CLK_ZS),
+       DEF_MOD("gpio5",                 907,   R8A7742_CLK_CP),
+       DEF_MOD("gpio4",                 908,   R8A7742_CLK_CP),
+       DEF_MOD("gpio3",                 909,   R8A7742_CLK_CP),
+       DEF_MOD("gpio2",                 910,   R8A7742_CLK_CP),
+       DEF_MOD("gpio1",                 911,   R8A7742_CLK_CP),
+       DEF_MOD("gpio0",                 912,   R8A7742_CLK_CP),
+       DEF_MOD("can1",                  915,   R8A7742_CLK_P),
+       DEF_MOD("can0",                  916,   R8A7742_CLK_P),
+       DEF_MOD("qspi_mod",              917,   R8A7742_CLK_QSPI),
+       DEF_MOD("iicdvfs",               926,   R8A7742_CLK_CP),
+       DEF_MOD("i2c3",                  928,   R8A7742_CLK_HP),
+       DEF_MOD("i2c2",                  929,   R8A7742_CLK_HP),
+       DEF_MOD("i2c1",                  930,   R8A7742_CLK_HP),
+       DEF_MOD("i2c0",                  931,   R8A7742_CLK_HP),
+       DEF_MOD("ssi-all",              1005,   R8A7742_CLK_P),
+       DEF_MOD("ssi9",                 1006,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi8",                 1007,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi7",                 1008,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi6",                 1009,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi5",                 1010,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi4",                 1011,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi3",                 1012,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi2",                 1013,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi1",                 1014,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi0",                 1015,   MOD_CLK_ID(1005)),
+       DEF_MOD("scu-all",              1017,   R8A7742_CLK_P),
+       DEF_MOD("scu-dvc1",             1018,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-dvc0",             1019,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-ctu1-mix1",        1020,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-ctu0-mix0",        1021,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src9",             1022,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src8",             1023,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src7",             1024,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src6",             1025,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src5",             1026,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src4",             1027,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src3",             1028,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src2",             1029,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src1",             1030,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src0",             1031,   MOD_CLK_ID(1017)),
+};
+
+static const unsigned int r8a7742_crit_mod_clks[] __initconst = {
+       MOD_CLK_ID(402),        /* RWDT */
+       MOD_CLK_ID(408),        /* INTC-SYS (GIC) */
+};
+
+/*
+ * CPG Clock Data
+ */
+
+/*
+ *    MD       EXTAL           PLL0    PLL1    PLL3
+ * 14 13 19    (MHz)           *1      *1
+ *---------------------------------------------------
+ * 0  0  0     15              x172/2  x208/2  x106
+ * 0  0  1     15              x172/2  x208/2  x88
+ * 0  1  0     20              x130/2  x156/2  x80
+ * 0  1  1     20              x130/2  x156/2  x66
+ * 1  0  0     26 / 2          x200/2  x240/2  x122
+ * 1  0  1     26 / 2          x200/2  x240/2  x102
+ * 1  1  0     30 / 2          x172/2  x208/2  x106
+ * 1  1  1     30 / 2          x172/2  x208/2  x88
+ *
+ * *1 :        Table 7.5a indicates VCO output (PLLx = VCO/2)
+ */
+#define CPG_PLL_CONFIG_INDEX(md)       ((((md) & BIT(14)) >> 12) | \
+                                        (((md) & BIT(13)) >> 12) | \
+                                        (((md) & BIT(19)) >> 19))
+
+static const struct rcar_gen2_cpg_pll_config cpg_pll_configs[8] __initconst = {
+       /* EXTAL div    PLL1 mult       PLL3 mult */
+       { 1,            208,            106,    },
+       { 1,            208,            88,     },
+       { 1,            156,            80,     },
+       { 1,            156,            66,     },
+       { 2,            240,            122,    },
+       { 2,            240,            102,    },
+       { 2,            208,            106,    },
+       { 2,            208,            88,     },
+};
+
+static int __init r8a7742_cpg_mssr_init(struct device *dev)
+{
+       const struct rcar_gen2_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)];
+
+       return rcar_gen2_cpg_init(cpg_pll_config, 2, cpg_mode);
+}
+
+const struct cpg_mssr_info r8a7742_cpg_mssr_info __initconst = {
+       /* Core Clocks */
+       .core_clks = r8a7742_core_clks,
+       .num_core_clks = ARRAY_SIZE(r8a7742_core_clks),
+       .last_dt_core_clk = LAST_DT_CORE_CLK,
+       .num_total_core_clks = MOD_CLK_BASE,
+
+       /* Module Clocks */
+       .mod_clks = r8a7742_mod_clks,
+       .num_mod_clks = ARRAY_SIZE(r8a7742_mod_clks),
+       .num_hw_mod_clks = 12 * 32,
+
+       /* Critical Module Clocks */
+       .crit_mod_clks = r8a7742_crit_mod_clks,
+       .num_crit_mod_clks = ARRAY_SIZE(r8a7742_crit_mod_clks),
+
+       /* Callbacks */
+       .init = r8a7742_cpg_mssr_init,
+       .cpg_clk_register = rcar_gen2_cpg_clk_register,
+};
index 1907ee1..d900f6b 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * R9A09G032 clock driver
+ * R9A06G032 clock driver
  *
  * Copyright (C) 2018 Renesas Electronics Europe Limited
  *
@@ -338,8 +338,8 @@ clk_rdesc_get(struct r9a06g032_priv *clocks,
 }
 
 /*
- * This implements the R9A09G032 clock gate 'driver'. We cannot use the system's
- * clock gate framework as the gates on the R9A09G032 have a special enabling
+ * This implements the R9A06G032 clock gate 'driver'. We cannot use the system's
+ * clock gate framework as the gates on the R9A06G032 have a special enabling
  * sequence, therefore we use this little proxy.
  */
 struct r9a06g032_clk_gate {
index a2663fb..dcb6e27 100644 (file)
@@ -673,6 +673,12 @@ static const struct of_device_id cpg_mssr_match[] = {
                .data = &r7s9210_cpg_mssr_info,
        },
 #endif
+#ifdef CONFIG_CLK_R8A7742
+       {
+               .compatible = "renesas,r8a7742-cpg-mssr",
+               .data = &r8a7742_cpg_mssr_info,
+       },
+#endif
 #ifdef CONFIG_CLK_R8A7743
        {
                .compatible = "renesas,r8a7743-cpg-mssr",
@@ -812,7 +818,8 @@ static int cpg_mssr_suspend_noirq(struct device *dev)
        /* Save module registers with bits under our control */
        for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) {
                if (priv->smstpcr_saved[reg].mask)
-                       priv->smstpcr_saved[reg].val =
+                       priv->smstpcr_saved[reg].val = priv->stbyctrl ?
+                               readb(priv->base + STBCR(reg)) :
                                readl(priv->base + SMSTPCR(reg));
        }
 
@@ -872,8 +879,9 @@ static int cpg_mssr_resume_noirq(struct device *dev)
                }
 
                if (!i)
-                       dev_warn(dev, "Failed to enable SMSTP %p[0x%x]\n",
-                                priv->base + SMSTPCR(reg), oldval & mask);
+                       dev_warn(dev, "Failed to enable %s%u[0x%x]\n",
+                                priv->stbyctrl ? "STB" : "SMSTP", reg,
+                                oldval & mask);
        }
 
        return 0;
index 3b852ba..55a18ef 100644 (file)
@@ -155,6 +155,7 @@ struct cpg_mssr_info {
 };
 
 extern const struct cpg_mssr_info r7s9210_cpg_mssr_info;
+extern const struct cpg_mssr_info r8a7742_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a7743_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a7745_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a77470_cpg_mssr_info;
index c9e5a1f..fea3339 100644 (file)
@@ -540,7 +540,7 @@ static const struct samsung_div_clock exynos5800_div_clks[] __initconst = {
 
 static const struct samsung_gate_clock exynos5800_gate_clks[] __initconst = {
        GATE(CLK_ACLK550_CAM, "aclk550_cam", "mout_user_aclk550_cam",
-                               GATE_BUS_TOP, 24, 0, 0),
+                               GATE_BUS_TOP, 24, CLK_IS_CRITICAL, 0),
        GATE(CLK_ACLK432_SCALER, "aclk432_scaler", "mout_user_aclk432_scaler",
                                GATE_BUS_TOP, 27, CLK_IS_CRITICAL, 0),
 };
@@ -943,25 +943,25 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
        GATE(0, "aclk300_jpeg", "mout_user_aclk300_jpeg",
                        GATE_BUS_TOP, 4, CLK_IGNORE_UNUSED, 0),
        GATE(0, "aclk333_432_isp0", "mout_user_aclk333_432_isp0",
-                       GATE_BUS_TOP, 5, 0, 0),
+                       GATE_BUS_TOP, 5, CLK_IS_CRITICAL, 0),
        GATE(0, "aclk300_gscl", "mout_user_aclk300_gscl",
                        GATE_BUS_TOP, 6, CLK_IS_CRITICAL, 0),
        GATE(0, "aclk333_432_gscl", "mout_user_aclk333_432_gscl",
                        GATE_BUS_TOP, 7, CLK_IGNORE_UNUSED, 0),
        GATE(0, "aclk333_432_isp", "mout_user_aclk333_432_isp",
-                       GATE_BUS_TOP, 8, 0, 0),
+                       GATE_BUS_TOP, 8, CLK_IS_CRITICAL, 0),
        GATE(CLK_PCLK66_GPIO, "pclk66_gpio", "mout_user_pclk66_gpio",
                        GATE_BUS_TOP, 9, CLK_IGNORE_UNUSED, 0),
        GATE(0, "aclk66_psgen", "mout_user_aclk66_psgen",
                        GATE_BUS_TOP, 10, CLK_IGNORE_UNUSED, 0),
        GATE(0, "aclk266_isp", "mout_user_aclk266_isp",
-                       GATE_BUS_TOP, 13, 0, 0),
+                       GATE_BUS_TOP, 13, CLK_IS_CRITICAL, 0),
        GATE(0, "aclk166", "mout_user_aclk166",
                        GATE_BUS_TOP, 14, CLK_IGNORE_UNUSED, 0),
        GATE(CLK_ACLK333, "aclk333", "mout_user_aclk333",
                        GATE_BUS_TOP, 15, CLK_IS_CRITICAL, 0),
        GATE(0, "aclk400_isp", "mout_user_aclk400_isp",
-                       GATE_BUS_TOP, 16, 0, 0),
+                       GATE_BUS_TOP, 16, CLK_IS_CRITICAL, 0),
        GATE(0, "aclk400_mscl", "mout_user_aclk400_mscl",
                        GATE_BUS_TOP, 17, CLK_IS_CRITICAL, 0),
        GATE(0, "aclk200_disp1", "mout_user_aclk200_disp1",
@@ -1161,9 +1161,11 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
                        GATE_IP_GSCL1, 3, 0, 0),
        GATE(CLK_SMMU_FIMCL1, "smmu_fimcl1", "dout_gscl_blk_333",
                        GATE_IP_GSCL1, 4, 0, 0),
-       GATE(CLK_GSCL_WA, "gscl_wa", "sclk_gscl_wa", GATE_IP_GSCL1, 12, 0, 0),
-       GATE(CLK_GSCL_WB, "gscl_wb", "sclk_gscl_wb", GATE_IP_GSCL1, 13, 0, 0),
-       GATE(CLK_SMMU_FIMCL3, "smmu_fimcl3,", "dout_gscl_blk_333",
+       GATE(CLK_GSCL_WA, "gscl_wa", "sclk_gscl_wa", GATE_IP_GSCL1, 12,
+                       CLK_IS_CRITICAL, 0),
+       GATE(CLK_GSCL_WB, "gscl_wb", "sclk_gscl_wb", GATE_IP_GSCL1, 13,
+                       CLK_IS_CRITICAL, 0),
+       GATE(CLK_SMMU_FIMCL3, "smmu_fimcl3", "dout_gscl_blk_333",
                        GATE_IP_GSCL1, 16, 0, 0),
        GATE(CLK_FIMC_LITE3, "fimc_lite3", "aclk333_432_gscl",
                        GATE_IP_GSCL1, 17, 0, 0),
index 4b1aa93..6f29ecd 100644 (file)
@@ -1706,7 +1706,8 @@ static const struct samsung_gate_clock peric_gate_clks[] __initconst = {
        GATE(CLK_SCLK_PCM1, "sclk_pcm1", "sclk_pcm1_peric",
                        ENABLE_SCLK_PERIC, 7, CLK_SET_RATE_PARENT, 0),
        GATE(CLK_SCLK_I2S1, "sclk_i2s1", "sclk_i2s1_peric",
-                       ENABLE_SCLK_PERIC, 6, CLK_SET_RATE_PARENT, 0),
+                       ENABLE_SCLK_PERIC, 6,
+                       CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0),
        GATE(CLK_SCLK_SPI2, "sclk_spi2", "sclk_spi2_peric", ENABLE_SCLK_PERIC,
                        5, CLK_SET_RATE_PARENT, 0),
        GATE(CLK_SCLK_SPI1, "sclk_spi1", "sclk_spi1_peric", ENABLE_SCLK_PERIC,
index 5f30fe7..c7aba1e 100644 (file)
@@ -387,7 +387,7 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
                                ARRAY_SIZE(s3c2450_gates));
                samsung_clk_register_alias(ctx, s3c2450_aliases,
                                ARRAY_SIZE(s3c2450_aliases));
-               /* fall through - as s3c2450 extends the s3c2416 clocks */
+               fallthrough;    /* as s3c2450 extends the s3c2416 clocks */
        case S3C2416:
                samsung_clk_register_div(ctx, s3c2416_dividers,
                                ARRAY_SIZE(s3c2416_dividers));
index ce5aa78..bf736f8 100644 (file)
@@ -3,3 +3,5 @@ obj-$(CONFIG_ARCH_SOCFPGA) += clk.o clk-gate.o clk-pll.o clk-periph.o
 obj-$(CONFIG_ARCH_SOCFPGA) += clk-pll-a10.o clk-periph-a10.o clk-gate-a10.o
 obj-$(CONFIG_ARCH_STRATIX10) += clk-s10.o
 obj-$(CONFIG_ARCH_STRATIX10) += clk-pll-s10.o clk-periph-s10.o clk-gate-s10.o
+obj-$(CONFIG_ARCH_AGILEX) += clk-agilex.o
+obj-$(CONFIG_ARCH_AGILEX) += clk-pll-s10.o clk-periph-s10.o clk-gate-s10.o
diff --git a/drivers/clk/socfpga/clk-agilex.c b/drivers/clk/socfpga/clk-agilex.c
new file mode 100644 (file)
index 0000000..699527f
--- /dev/null
@@ -0,0 +1,454 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019, Intel Corporation
+ */
+#include <linux/slab.h>
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/agilex-clock.h>
+
+#include "stratix10-clk.h"
+
+static const struct clk_parent_data pll_mux[] = {
+       { .fw_name = "osc1",
+         .name = "osc1", },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk", },
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data cntr_mux[] = {
+       { .fw_name = "main_pll",
+         .name = "main_pll", },
+       { .fw_name = "periph_pll",
+         .name = "periph_pll", },
+       { .fw_name = "osc1",
+         .name = "osc1", },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk", },
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data boot_mux[] = {
+       { .fw_name = "osc1",
+         .name = "osc1", },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk", },
+};
+
+static const struct clk_parent_data mpu_free_mux[] = {
+       { .fw_name = "main_pll_c0",
+         .name = "main_pll_c0", },
+       { .fw_name = "peri_pll_c0",
+         .name = "peri_pll_c0", },
+       { .fw_name = "osc1",
+         .name = "osc1", },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk", },
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data noc_free_mux[] = {
+       { .fw_name = "main_pll_c1",
+         .name = "main_pll_c1", },
+       { .fw_name = "peri_pll_c1",
+         .name = "peri_pll_c1", },
+       { .fw_name = "osc1",
+         .name = "osc1", },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk", },
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data emaca_free_mux[] = {
+       { .fw_name = "main_pll_c2",
+         .name = "main_pll_c2", },
+       { .fw_name = "peri_pll_c2",
+         .name = "peri_pll_c2", },
+       { .fw_name = "osc1",
+         .name = "osc1", },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk", },
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data emacb_free_mux[] = {
+       { .fw_name = "main_pll_c3",
+         .name = "main_pll_c3", },
+       { .fw_name = "peri_pll_c3",
+         .name = "peri_pll_c3", },
+       { .fw_name = "osc1",
+         .name = "osc1", },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk", },
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data emac_ptp_free_mux[] = {
+       { .fw_name = "main_pll_c3",
+         .name = "main_pll_c3", },
+       { .fw_name = "peri_pll_c3",
+         .name = "peri_pll_c3", },
+       { .fw_name = "osc1",
+         .name = "osc1", },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk", },
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data gpio_db_free_mux[] = {
+       { .fw_name = "main_pll_c3",
+         .name = "main_pll_c3", },
+       { .fw_name = "peri_pll_c3",
+         .name = "peri_pll_c3", },
+       { .fw_name = "osc1",
+         .name = "osc1", },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk", },
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data psi_ref_free_mux[] = {
+       { .fw_name = "main_pll_c3",
+         .name = "main_pll_c3", },
+       { .fw_name = "peri_pll_c3",
+         .name = "peri_pll_c3", },
+       { .fw_name = "osc1",
+         .name = "osc1", },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk", },
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data sdmmc_free_mux[] = {
+       { .fw_name = "main_pll_c3",
+         .name = "main_pll_c3", },
+       { .fw_name = "peri_pll_c3",
+         .name = "peri_pll_c3", },
+       { .fw_name = "osc1",
+         .name = "osc1", },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk", },
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data s2f_usr0_free_mux[] = {
+       { .fw_name = "main_pll_c2",
+         .name = "main_pll_c2", },
+       { .fw_name = "peri_pll_c2",
+         .name = "peri_pll_c2", },
+       { .fw_name = "osc1",
+         .name = "osc1", },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk", },
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data s2f_usr1_free_mux[] = {
+       { .fw_name = "main_pll_c2",
+         .name = "main_pll_c2", },
+       { .fw_name = "peri_pll_c2",
+         .name = "peri_pll_c2", },
+       { .fw_name = "osc1",
+         .name = "osc1", },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk", },
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data mpu_mux[] = {
+       { .fw_name = "mpu_free_clk",
+         .name = "mpu_free_clk", },
+       { .fw_name = "boot_clk",
+         .name = "boot_clk", },
+};
+
+static const struct clk_parent_data s2f_usr0_mux[] = {
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+       { .fw_name = "boot_clk",
+         .name = "boot_clk", },
+};
+
+static const struct clk_parent_data emac_mux[] = {
+       { .fw_name = "emaca_free_clk",
+         .name = "emaca_free_clk", },
+       { .fw_name = "emacb_free_clk",
+         .name = "emacb_free_clk", },
+};
+
+static const struct clk_parent_data noc_mux[] = {
+       { .fw_name = "noc_free_clk",
+         .name = "noc_free_clk", },
+       { .fw_name = "boot_clk",
+         .name = "boot_clk", },
+};
+
+/* clocks in AO (always on) controller */
+static const struct stratix10_pll_clock agilex_pll_clks[] = {
+       { AGILEX_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0,
+         0x0},
+       { AGILEX_MAIN_PLL_CLK, "main_pll", pll_mux, ARRAY_SIZE(pll_mux),
+         0, 0x48},
+       { AGILEX_PERIPH_PLL_CLK, "periph_pll", pll_mux, ARRAY_SIZE(pll_mux),
+         0, 0x9c},
+};
+
+static const struct stratix10_perip_c_clock agilex_main_perip_c_clks[] = {
+       { AGILEX_MAIN_PLL_C0_CLK, "main_pll_c0", "main_pll", NULL, 1, 0, 0x58},
+       { AGILEX_MAIN_PLL_C1_CLK, "main_pll_c1", "main_pll", NULL, 1, 0, 0x5C},
+       { AGILEX_MAIN_PLL_C2_CLK, "main_pll_c2", "main_pll", NULL, 1, 0, 0x64},
+       { AGILEX_MAIN_PLL_C3_CLK, "main_pll_c3", "main_pll", NULL, 1, 0, 0x68},
+       { AGILEX_PERIPH_PLL_C0_CLK, "peri_pll_c0", "periph_pll", NULL, 1, 0, 0xAC},
+       { AGILEX_PERIPH_PLL_C1_CLK, "peri_pll_c1", "periph_pll", NULL, 1, 0, 0xB0},
+       { AGILEX_PERIPH_PLL_C2_CLK, "peri_pll_c2", "periph_pll", NULL, 1, 0, 0xB8},
+       { AGILEX_PERIPH_PLL_C3_CLK, "peri_pll_c3", "periph_pll", NULL, 1, 0, 0xBC},
+};
+
+static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = {
+       { AGILEX_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux),
+          0, 0x3C, 0, 0, 0},
+       { AGILEX_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux),
+         0, 0x40, 0, 0, 1},
+       { AGILEX_L4_SYS_FREE_CLK, "l4_sys_free_clk", "noc_free_clk", NULL, 1, 0,
+         0, 4, 0, 0},
+       { AGILEX_NOC_CLK, "noc_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux),
+         0, 0, 0, 0x30, 1},
+       { AGILEX_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux),
+         0, 0xD4, 0, 0x88, 0},
+       { AGILEX_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux),
+         0, 0xD8, 0, 0x88, 1},
+       { AGILEX_EMAC_PTP_FREE_CLK, "emac_ptp_free_clk", NULL, emac_ptp_free_mux,
+         ARRAY_SIZE(emac_ptp_free_mux), 0, 0xDC, 0, 0x88, 2},
+       { AGILEX_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux,
+         ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3},
+       { AGILEX_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux,
+         ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0x88, 4},
+       { AGILEX_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", NULL, s2f_usr0_free_mux,
+         ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0, 0},
+       { AGILEX_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL, s2f_usr1_free_mux,
+         ARRAY_SIZE(s2f_usr1_free_mux), 0, 0xEC, 0, 0x88, 5},
+       { AGILEX_PSI_REF_FREE_CLK, "psi_ref_free_clk", NULL, psi_ref_free_mux,
+         ARRAY_SIZE(psi_ref_free_mux), 0, 0xF0, 0, 0x88, 6},
+};
+
+static const struct stratix10_gate_clock agilex_gate_clks[] = {
+       { AGILEX_MPU_CLK, "mpu_clk", NULL, mpu_mux, ARRAY_SIZE(mpu_mux), 0, 0x24,
+         0, 0, 0, 0, 0x30, 0, 0},
+       { AGILEX_MPU_PERIPH_CLK, "mpu_periph_clk", "mpu_clk", NULL, 1, 0, 0x24,
+         0, 0, 0, 0, 0, 0, 4},
+       { AGILEX_MPU_L2RAM_CLK, "mpu_l2ram_clk", "mpu_clk", NULL, 1, 0, 0x24,
+         0, 0, 0, 0, 0, 0, 2},
+       { AGILEX_L4_MAIN_CLK, "l4_main_clk", "noc_clk", NULL, 1, 0, 0x24,
+         1, 0x44, 0, 2, 0, 0, 0},
+       { AGILEX_L4_MP_CLK, "l4_mp_clk", "noc_clk", NULL, 1, 0, 0x24,
+         2, 0x44, 8, 2, 0, 0, 0},
+       /*
+        * The l4_sp_clk feeds a 100 MHz clock to various peripherals, one of them
+        * being the SP timers, thus cannot get gated.
+        */
+       { AGILEX_L4_SP_CLK, "l4_sp_clk", "noc_clk", NULL, 1, CLK_IS_CRITICAL, 0x24,
+         3, 0x44, 16, 2, 0, 0, 0},
+       { AGILEX_CS_AT_CLK, "cs_at_clk", "noc_clk", NULL, 1, 0, 0x24,
+         4, 0x44, 24, 2, 0, 0, 0},
+       { AGILEX_CS_TRACE_CLK, "cs_trace_clk", "noc_clk", NULL, 1, 0, 0x24,
+         4, 0x44, 26, 2, 0, 0, 0},
+       { AGILEX_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x24,
+         4, 0x44, 28, 1, 0, 0, 0},
+       { AGILEX_CS_TIMER_CLK, "cs_timer_clk", "noc_clk", NULL, 1, 0, 0x24,
+         5, 0, 0, 0, 0, 0, 0},
+       { AGILEX_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_usr0_mux, ARRAY_SIZE(s2f_usr0_mux), 0, 0x24,
+         6, 0, 0, 0, 0, 0, 0},
+       { AGILEX_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
+         0, 0, 0, 0, 0x94, 26, 0},
+       { AGILEX_EMAC1_CLK, "emac1_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
+         1, 0, 0, 0, 0x94, 27, 0},
+       { AGILEX_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
+         2, 0, 0, 0, 0x94, 28, 0},
+       { AGILEX_EMAC_PTP_CLK, "emac_ptp_clk", "emac_ptp_free_clk", NULL, 1, 0, 0x7C,
+         3, 0, 0, 0, 0, 0, 0},
+       { AGILEX_GPIO_DB_CLK, "gpio_db_clk", "gpio_db_free_clk", NULL, 1, 0, 0x7C,
+         4, 0x98, 0, 16, 0, 0, 0},
+       { AGILEX_SDMMC_CLK, "sdmmc_clk", "sdmmc_free_clk", NULL, 1, 0, 0x7C,
+         5, 0, 0, 0, 0, 0, 4},
+       { AGILEX_S2F_USER1_CLK, "s2f_user1_clk", "s2f_user1_free_clk", NULL, 1, 0, 0x7C,
+         6, 0, 0, 0, 0, 0, 0},
+       { AGILEX_PSI_REF_CLK, "psi_ref_clk", "psi_ref_free_clk", NULL, 1, 0, 0x7C,
+         7, 0, 0, 0, 0, 0, 0},
+       { AGILEX_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
+         8, 0, 0, 0, 0, 0, 0},
+       { AGILEX_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
+         9, 0, 0, 0, 0, 0, 0},
+       { AGILEX_NAND_CLK, "nand_clk", "l4_main_clk", NULL, 1, 0, 0x7C,
+         10, 0, 0, 0, 0, 0, 0},
+};
+
+static int agilex_clk_register_c_perip(const struct stratix10_perip_c_clock *clks,
+                                      int nums, struct stratix10_clock_data *data)
+{
+       struct clk *clk;
+       void __iomem *base = data->base;
+       int i;
+
+       for (i = 0; i < nums; i++) {
+               clk = s10_register_periph(&clks[i], base);
+               if (IS_ERR(clk)) {
+                       pr_err("%s: failed to register clock %s\n",
+                              __func__, clks[i].name);
+                       continue;
+               }
+               data->clk_data.clks[clks[i].id] = clk;
+       }
+       return 0;
+}
+
+static int agilex_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock *clks,
+                                        int nums, struct stratix10_clock_data *data)
+{
+       struct clk *clk;
+       void __iomem *base = data->base;
+       int i;
+
+       for (i = 0; i < nums; i++) {
+               clk = s10_register_cnt_periph(&clks[i], base);
+               if (IS_ERR(clk)) {
+                       pr_err("%s: failed to register clock %s\n",
+                              __func__, clks[i].name);
+                       continue;
+               }
+               data->clk_data.clks[clks[i].id] = clk;
+       }
+
+       return 0;
+}
+
+static int agilex_clk_register_gate(const struct stratix10_gate_clock *clks,                                       int nums, struct stratix10_clock_data *data)
+{
+       struct clk *clk;
+       void __iomem *base = data->base;
+       int i;
+
+       for (i = 0; i < nums; i++) {
+               clk = s10_register_gate(&clks[i], base);
+               if (IS_ERR(clk)) {
+                       pr_err("%s: failed to register clock %s\n",
+                              __func__, clks[i].name);
+                       continue;
+               }
+               data->clk_data.clks[clks[i].id] = clk;
+       }
+
+       return 0;
+}
+
+static int agilex_clk_register_pll(const struct stratix10_pll_clock *clks,
+                                int nums, struct stratix10_clock_data *data)
+{
+       struct clk *clk;
+       void __iomem *base = data->base;
+       int i;
+
+       for (i = 0; i < nums; i++) {
+               clk = agilex_register_pll(&clks[i], base);
+               if (IS_ERR(clk)) {
+                       pr_err("%s: failed to register clock %s\n",
+                              __func__, clks[i].name);
+                       continue;
+               }
+               data->clk_data.clks[clks[i].id] = clk;
+       }
+
+       return 0;
+}
+
+static struct stratix10_clock_data *__socfpga_agilex_clk_init(struct platform_device *pdev,
+                                                   int nr_clks)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct device *dev = &pdev->dev;
+       struct stratix10_clock_data *clk_data;
+       struct clk **clk_table;
+       struct resource *res;
+       void __iomem *base;
+       int ret;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(base))
+               return ERR_CAST(base);
+
+       clk_data = devm_kzalloc(dev, sizeof(*clk_data), GFP_KERNEL);
+       if (!clk_data)
+               return ERR_PTR(-ENOMEM);
+
+       clk_data->base = base;
+       clk_table = devm_kcalloc(dev, nr_clks, sizeof(*clk_table), GFP_KERNEL);
+       if (!clk_table)
+               return ERR_PTR(-ENOMEM);
+
+       clk_data->clk_data.clks = clk_table;
+       clk_data->clk_data.clk_num = nr_clks;
+       ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data);
+       if (ret)
+               return ERR_PTR(ret);
+
+       return clk_data;
+}
+
+static int agilex_clkmgr_probe(struct platform_device *pdev)
+{
+       struct stratix10_clock_data *clk_data;
+
+       clk_data = __socfpga_agilex_clk_init(pdev, AGILEX_NUM_CLKS);
+       if (IS_ERR(clk_data))
+               return PTR_ERR(clk_data);
+
+       agilex_clk_register_pll(agilex_pll_clks, ARRAY_SIZE(agilex_pll_clks), clk_data);
+
+       agilex_clk_register_c_perip(agilex_main_perip_c_clks,
+                                ARRAY_SIZE(agilex_main_perip_c_clks), clk_data);
+
+       agilex_clk_register_cnt_perip(agilex_main_perip_cnt_clks,
+                                  ARRAY_SIZE(agilex_main_perip_cnt_clks),
+                                  clk_data);
+
+       agilex_clk_register_gate(agilex_gate_clks, ARRAY_SIZE(agilex_gate_clks),
+                             clk_data);
+       return 0;
+}
+
+static const struct of_device_id agilex_clkmgr_match_table[] = {
+       { .compatible = "intel,agilex-clkmgr",
+         .data = agilex_clkmgr_probe },
+       { }
+};
+
+static struct platform_driver agilex_clkmgr_driver = {
+       .probe          = agilex_clkmgr_probe,
+       .driver         = {
+               .name   = "agilex-clkmgr",
+               .suppress_bind_attrs = true,
+               .of_match_table = agilex_clkmgr_match_table,
+       },
+};
+
+static int __init agilex_clk_init(void)
+{
+       return platform_driver_register(&agilex_clkmgr_driver);
+}
+core_initcall(agilex_clk_init);
index 8be4722..083b2ec 100644 (file)
@@ -70,7 +70,6 @@ struct clk *s10_register_gate(const struct stratix10_gate_clock *clks, void __io
        struct clk *clk;
        struct socfpga_gate_clk *socfpga_clk;
        struct clk_init_data init;
-       const char * const *parent_names = clks->parent_names;
        const char *parent_name = clks->parent_name;
 
        socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
@@ -108,7 +107,9 @@ struct clk *s10_register_gate(const struct stratix10_gate_clock *clks, void __io
        init.flags = clks->flags;
 
        init.num_parents = clks->num_parents;
-       init.parent_names = parent_names ? parent_names : &parent_name;
+       init.parent_names = parent_name ? &parent_name : NULL;
+       if (init.parent_names == NULL)
+               init.parent_data = clks->parent_data;
        socfpga_clk->hw.hw.init = &init;
 
        clk = clk_register(NULL, &socfpga_clk->hw.hw);
index dd6d405..397b77b 100644 (file)
@@ -81,7 +81,6 @@ struct clk *s10_register_periph(const struct stratix10_perip_c_clock *clks,
        struct clk_init_data init;
        const char *name = clks->name;
        const char *parent_name = clks->parent_name;
-       const char * const *parent_names = clks->parent_names;
 
        periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
        if (WARN_ON(!periph_clk))
@@ -94,7 +93,9 @@ struct clk *s10_register_periph(const struct stratix10_perip_c_clock *clks,
        init.flags = clks->flags;
 
        init.num_parents = clks->num_parents;
-       init.parent_names = parent_names ? parent_names : &parent_name;
+       init.parent_names = parent_name ? &parent_name : NULL;
+       if (init.parent_names == NULL)
+               init.parent_data = clks->parent_data;
 
        periph_clk->hw.hw.init = &init;
 
@@ -114,7 +115,6 @@ struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *clks
        struct clk_init_data init;
        const char *name = clks->name;
        const char *parent_name = clks->parent_name;
-       const char * const *parent_names = clks->parent_names;
 
        periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
        if (WARN_ON(!periph_clk))
@@ -137,7 +137,9 @@ struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *clks
        init.flags = clks->flags;
 
        init.num_parents = clks->num_parents;
-       init.parent_names = parent_names ? parent_names : &parent_name;
+       init.parent_names = parent_name ? &parent_name : NULL;
+       if (init.parent_names == NULL)
+               init.parent_data = clks->parent_data;
 
        periph_clk->hw.hw.init = &init;
 
index 3816fc0..db54f7d 100644 (file)
@@ -58,7 +58,7 @@ static u8 clk_pll_get_parent(struct clk_hw *hwclk)
                CLK_MGR_PLL_CLK_SRC_MASK;
 }
 
-static struct clk_ops clk_pll_ops = {
+static const struct clk_ops clk_pll_ops = {
        .recalc_rate = clk_pll_recalc_rate,
        .get_parent = clk_pll_get_parent,
 };
@@ -102,8 +102,6 @@ static struct clk * __init __socfpga_pll_init(struct device_node *node,
        pll_clk->hw.hw.init = &init;
 
        pll_clk->hw.bit_idx = SOCFPGA_PLL_EXT_ENA;
-       clk_pll_ops.enable = clk_gate_ops.enable;
-       clk_pll_ops.disable = clk_gate_ops.disable;
 
        clk = clk_register(NULL, &pll_clk->hw.hw);
        if (WARN_ON(IS_ERR(clk))) {
index a301bb2..4e26895 100644 (file)
 #define SOCFPGA_PLL_RESET_MASK         0x2
 #define SOCFPGA_PLL_REFDIV_MASK                0x00003F00
 #define SOCFPGA_PLL_REFDIV_SHIFT       8
+#define SOCFPGA_PLL_AREFDIV_MASK       0x00000F00
+#define SOCFPGA_PLL_DREFDIV_MASK       0x00003000
+#define SOCFPGA_PLL_DREFDIV_SHIFT      12
 #define SOCFPGA_PLL_MDIV_MASK          0xFF000000
 #define SOCFPGA_PLL_MDIV_SHIFT         24
+#define SOCFPGA_AGILEX_PLL_MDIV_MASK   0x000003FF
 #define SWCTRLBTCLKSEL_MASK            0x200
 #define SWCTRLBTCLKSEL_SHIFT           9
 
 
 #define to_socfpga_clk(p) container_of(p, struct socfpga_pll, hw.hw)
 
+static unsigned long agilex_clk_pll_recalc_rate(struct clk_hw *hwclk,
+                                               unsigned long parent_rate)
+{
+       struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
+       unsigned long arefdiv, reg, mdiv;
+       unsigned long long vco_freq;
+
+       /* read VCO1 reg for numerator and denominator */
+       reg = readl(socfpgaclk->hw.reg);
+       arefdiv = (reg & SOCFPGA_PLL_AREFDIV_MASK) >> SOCFPGA_PLL_REFDIV_SHIFT;
+
+       vco_freq = (unsigned long long)parent_rate / arefdiv;
+
+       /* Read mdiv and fdiv from the fdbck register */
+       reg = readl(socfpgaclk->hw.reg + 0x24);
+       mdiv = reg & SOCFPGA_AGILEX_PLL_MDIV_MASK;
+
+       vco_freq = (unsigned long long)vco_freq * mdiv;
+       return (unsigned long)vco_freq;
+}
+
 static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk,
                                         unsigned long parent_rate)
 {
@@ -98,13 +123,19 @@ static int clk_pll_prepare(struct clk_hw *hwclk)
        return 0;
 }
 
-static struct clk_ops clk_pll_ops = {
+static const struct clk_ops agilex_clk_pll_ops = {
+       .recalc_rate = agilex_clk_pll_recalc_rate,
+       .get_parent = clk_pll_get_parent,
+       .prepare = clk_pll_prepare,
+};
+
+static const struct clk_ops clk_pll_ops = {
        .recalc_rate = clk_pll_recalc_rate,
        .get_parent = clk_pll_get_parent,
        .prepare = clk_pll_prepare,
 };
 
-static struct clk_ops clk_boot_ops = {
+static const struct clk_ops clk_boot_ops = {
        .recalc_rate = clk_boot_clk_recalc_rate,
        .get_parent = clk_boot_get_parent,
        .prepare = clk_pll_prepare,
@@ -117,7 +148,6 @@ struct clk *s10_register_pll(const struct stratix10_pll_clock *clks,
        struct socfpga_pll *pll_clk;
        struct clk_init_data init;
        const char *name = clks->name;
-       const char * const *parent_names = clks->parent_names;
 
        pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
        if (WARN_ON(!pll_clk))
@@ -134,12 +164,48 @@ struct clk *s10_register_pll(const struct stratix10_pll_clock *clks,
        init.flags = clks->flags;
 
        init.num_parents = clks->num_parents;
-       init.parent_names = parent_names;
+       init.parent_names = NULL;
+       init.parent_data = clks->parent_data;
+       pll_clk->hw.hw.init = &init;
+
+       pll_clk->hw.bit_idx = SOCFPGA_PLL_POWER;
+
+       clk = clk_register(NULL, &pll_clk->hw.hw);
+       if (WARN_ON(IS_ERR(clk))) {
+               kfree(pll_clk);
+               return NULL;
+       }
+       return clk;
+}
+
+struct clk *agilex_register_pll(const struct stratix10_pll_clock *clks,
+                               void __iomem *reg)
+{
+       struct clk *clk;
+       struct socfpga_pll *pll_clk;
+       struct clk_init_data init;
+       const char *name = clks->name;
+
+       pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
+       if (WARN_ON(!pll_clk))
+               return NULL;
+
+       pll_clk->hw.reg = reg + clks->offset;
+
+       if (streq(name, SOCFPGA_BOOT_CLK))
+               init.ops = &clk_boot_ops;
+       else
+               init.ops = &agilex_clk_pll_ops;
+
+       init.name = name;
+       init.flags = clks->flags;
+
+       init.num_parents = clks->num_parents;
+       init.parent_names = NULL;
+       init.parent_data = clks->parent_data;
        pll_clk->hw.hw.init = &init;
 
        pll_clk->hw.bit_idx = SOCFPGA_PLL_POWER;
-       clk_pll_ops.enable = clk_gate_ops.enable;
-       clk_pll_ops.disable = clk_gate_ops.disable;
 
        clk = clk_register(NULL, &pll_clk->hw.hw);
        if (WARN_ON(IS_ERR(clk))) {
index dc65cc0..e5fb786 100644 (file)
@@ -65,7 +65,7 @@ static u8 clk_pll_get_parent(struct clk_hw *hwclk)
                        CLK_MGR_PLL_CLK_SRC_MASK;
 }
 
-static struct clk_ops clk_pll_ops = {
+static const struct clk_ops clk_pll_ops = {
        .recalc_rate = clk_pll_recalc_rate,
        .get_parent = clk_pll_get_parent,
 };
@@ -105,8 +105,6 @@ static __init struct clk *__socfpga_pll_init(struct device_node *node,
        pll_clk->hw.hw.init = &init;
 
        pll_clk->hw.bit_idx = SOCFPGA_PLL_EXT_ENA;
-       clk_pll_ops.enable = clk_gate_ops.enable;
-       clk_pll_ops.disable = clk_gate_ops.disable;
 
        clk = clk_register(NULL, &pll_clk->hw.hw);
        if (WARN_ON(IS_ERR(clk))) {
index dea7c6c..c1dfc9b 100644 (file)
 
 #include "stratix10-clk.h"
 
-static const char * const pll_mux[] = { "osc1", "cb-intosc-hs-div2-clk",
-                                       "f2s-free-clk",};
-static const char * const cntr_mux[] = { "main_pll", "periph_pll",
-                                        "osc1", "cb-intosc-hs-div2-clk",
-                                        "f2s-free-clk"};
-static const char * const boot_mux[] = { "osc1", "cb-intosc-hs-div2-clk",};
-
-static const char * const noc_free_mux[] = {"main_noc_base_clk",
-                                           "peri_noc_base_clk",
-                                           "osc1", "cb-intosc-hs-div2-clk",
-                                           "f2s-free-clk"};
-
-static const char * const emaca_free_mux[] = {"peri_emaca_clk", "boot_clk"};
-static const char * const emacb_free_mux[] = {"peri_emacb_clk", "boot_clk"};
-static const char * const emac_ptp_free_mux[] = {"peri_emac_ptp_clk", "boot_clk"};
-static const char * const gpio_db_free_mux[] = {"peri_gpio_db_clk", "boot_clk"};
-static const char * const sdmmc_free_mux[] = {"main_sdmmc_clk", "boot_clk"};
-static const char * const s2f_usr1_free_mux[] = {"peri_s2f_usr1_clk", "boot_clk"};
-static const char * const psi_ref_free_mux[] = {"peri_psi_ref_clk", "boot_clk"};
-static const char * const mpu_mux[] = { "mpu_free_clk", "boot_clk",};
-
-static const char * const s2f_usr0_mux[] = {"f2s-free-clk", "boot_clk"};
-static const char * const emac_mux[] = {"emaca_free_clk", "emacb_free_clk"};
-static const char * const noc_mux[] = {"noc_free_clk", "boot_clk"};
-
-static const char * const mpu_free_mux[] = {"main_mpu_base_clk",
-                                           "peri_mpu_base_clk",
-                                           "osc1", "cb-intosc-hs-div2-clk",
-                                           "f2s-free-clk"};
+static const struct clk_parent_data pll_mux[] = {
+       { .fw_name = "osc1",
+         .name = "osc1" },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk" },
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk" },
+};
+
+static const struct clk_parent_data cntr_mux[] = {
+       { .fw_name =  "main_pll",
+         .name = "main_pll", },
+       { .fw_name = "periph_pll",
+         .name = "periph_pll", },
+       { .fw_name = "osc1",
+         .name = "osc1", },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk", },
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data boot_mux[] = {
+       { .fw_name = "osc1",
+         .name = "osc1" },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk" },
+};
+
+static const struct clk_parent_data noc_free_mux[] = {
+       { .fw_name = "main_noc_base_clk",
+         .name = "main_noc_base_clk", },
+       { .fw_name = "peri_noc_base_clk",
+         .name = "peri_noc_base_clk", },
+       { .fw_name = "osc1",
+         .name = "osc1", },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk", },
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+};
+
+static const struct clk_parent_data emaca_free_mux[] = {
+       { .fw_name = "peri_emaca_clk",
+         .name = "peri_emaca_clk", },
+       { .fw_name = "boot_clk",
+         .name = "boot_clk", },
+};
+
+static const struct clk_parent_data emacb_free_mux[] = {
+       { .fw_name = "peri_emacb_clk",
+         .name = "peri_emacb_clk", },
+       { .fw_name = "boot_clk",
+         .name = "boot_clk", },
+};
+
+static const struct clk_parent_data emac_ptp_free_mux[] = {
+       { .fw_name = "peri_emac_ptp_clk",
+         .name = "peri_emac_ptp_clk", },
+       { .fw_name = "boot_clk",
+         .name = "boot_clk", },
+};
+
+static const struct clk_parent_data gpio_db_free_mux[] = {
+       { .fw_name = "peri_gpio_db_clk",
+         .name = "peri_gpio_db_clk", },
+       { .fw_name = "boot_clk",
+         .name = "boot_clk", },
+};
+
+static const struct clk_parent_data sdmmc_free_mux[] = {
+       { .fw_name = "main_sdmmc_clk",
+         .name = "main_sdmmc_clk", },
+       { .fw_name = "boot_clk",
+         .name = "boot_clk", },
+};
+
+static const struct clk_parent_data s2f_usr1_free_mux[] = {
+       { .fw_name = "peri_s2f_usr1_clk",
+         .name = "peri_s2f_usr1_clk", },
+       { .fw_name = "boot_clk",
+         .name = "boot_clk", },
+};
+
+static const struct clk_parent_data psi_ref_free_mux[] = {
+       { .fw_name = "peri_psi_ref_clk",
+         .name = "peri_psi_ref_clk", },
+       { .fw_name = "boot_clk",
+         .name = "boot_clk", },
+};
+
+static const struct clk_parent_data mpu_mux[] = {
+       { .fw_name = "mpu_free_clk",
+         .name = "mpu_free_clk", },
+       { .fw_name = "boot_clk",
+         .name = "boot_clk", },
+};
+
+static const struct clk_parent_data s2f_usr0_mux[] = {
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+       { .fw_name = "boot_clk",
+         .name = "boot_clk", },
+};
+
+static const struct clk_parent_data emac_mux[] = {
+       { .fw_name = "emaca_free_clk",
+         .name = "emaca_free_clk", },
+       { .fw_name = "emacb_free_clk",
+         .name = "emacb_free_clk", },
+};
+
+static const struct clk_parent_data noc_mux[] = {
+       { .fw_name = "noc_free_clk",
+         .name = "noc_free_clk", },
+       { .fw_name = "boot_clk",
+         .name = "boot_clk", },
+};
+
+static const struct clk_parent_data mpu_free_mux[] = {
+       { .fw_name = "main_mpu_base_clk",
+         .name = "main_mpu_base_clk", },
+       { .fw_name = "peri_mpu_base_clk",
+         .name = "peri_mpu_base_clk", },
+       { .fw_name = "osc1",
+         .name = "osc1", },
+       { .fw_name = "cb-intosc-hs-div2-clk",
+         .name = "cb-intosc-hs-div2-clk", },
+       { .fw_name = "f2s-free-clk",
+         .name = "f2s-free-clk", },
+};
 
 /* clocks in AO (always on) controller */
 static const struct stratix10_pll_clock s10_pll_clks[] = {
index fcabef4..f9d5d72 100644 (file)
@@ -14,7 +14,7 @@ struct stratix10_clock_data {
 struct stratix10_pll_clock {
        unsigned int            id;
        const char              *name;
-       const char              *const *parent_names;
+       const struct clk_parent_data    *parent_data;
        u8                      num_parents;
        unsigned long           flags;
        unsigned long           offset;
@@ -24,7 +24,7 @@ struct stratix10_perip_c_clock {
        unsigned int            id;
        const char              *name;
        const char              *parent_name;
-       const char              *const *parent_names;
+       const struct clk_parent_data    *parent_data;
        u8                      num_parents;
        unsigned long           flags;
        unsigned long           offset;
@@ -34,7 +34,7 @@ struct stratix10_perip_cnt_clock {
        unsigned int            id;
        const char              *name;
        const char              *parent_name;
-       const char              *const *parent_names;
+       const struct clk_parent_data    *parent_data;
        u8                      num_parents;
        unsigned long           flags;
        unsigned long           offset;
@@ -47,7 +47,7 @@ struct stratix10_gate_clock {
        unsigned int            id;
        const char              *name;
        const char              *parent_name;
-       const char              *const *parent_names;
+       const struct clk_parent_data    *parent_data;
        u8                      num_parents;
        unsigned long           flags;
        unsigned long           gate_reg;
@@ -62,6 +62,8 @@ struct stratix10_gate_clock {
 
 struct clk *s10_register_pll(const struct stratix10_pll_clock *,
                             void __iomem *);
+struct clk *agilex_register_pll(const struct stratix10_pll_clock *,
+                               void __iomem *);
 struct clk *s10_register_periph(const struct stratix10_perip_c_clock *,
                                void __iomem *);
 struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *,
index 27201fd..e1aa1fb 100644 (file)
@@ -90,7 +90,7 @@ static void sun6i_a31_get_pll1_factors(struct factors_request *req)
         * Round down the frequency to the closest multiple of either
         * 6 or 16
         */
-       u32 round_freq_6 = round_down(freq_mhz, 6);
+       u32 round_freq_6 = rounddown(freq_mhz, 6);
        u32 round_freq_16 = round_down(freq_mhz, 16);
 
        if (round_freq_6 > round_freq_16)
index 4d99a87..deaa460 100644 (file)
@@ -1,8 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
-config TEGRA_CLK_EMC
-       def_bool y
-       depends on TEGRA124_EMC
-
 config CLK_TEGRA_BPMP
        def_bool y
        depends on TEGRA_BPMP
index 1f7c30f..eec2313 100644 (file)
@@ -13,8 +13,8 @@ obj-y                                 += clk-super.o
 obj-y                                  += clk-tegra-audio.o
 obj-y                                  += clk-tegra-periph.o
 obj-y                                  += clk-tegra-fixed.o
+obj-y                                  += clk-tegra-super-cclk.o
 obj-y                                  += clk-tegra-super-gen4.o
-obj-$(CONFIG_TEGRA_CLK_EMC)            += clk-emc.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += clk-tegra20.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += clk-tegra20-emc.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += clk-tegra30.o
@@ -22,8 +22,10 @@ obj-$(CONFIG_ARCH_TEGRA_3x_SOC)              += clk-tegra20-emc.o
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)       += clk-tegra114.o
 obj-$(CONFIG_ARCH_TEGRA_124_SOC)       += clk-tegra124.o
 obj-$(CONFIG_TEGRA_CLK_DFLL)           += clk-tegra124-dfll-fcpu.o
+obj-$(CONFIG_TEGRA124_EMC)             += clk-tegra124-emc.o
 obj-$(CONFIG_ARCH_TEGRA_132_SOC)       += clk-tegra124.o
 obj-y                                  += cvb.o
 obj-$(CONFIG_ARCH_TEGRA_210_SOC)       += clk-tegra210.o
+obj-$(CONFIG_ARCH_TEGRA_210_SOC)       += clk-tegra210-emc.o
 obj-$(CONFIG_CLK_TEGRA_BPMP)           += clk-bpmp.o
 obj-y                                  += clk-utils.o
index 531c2b3..0b212cf 100644 (file)
@@ -744,13 +744,19 @@ static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
 
        state = clk_pll_is_enabled(hw);
 
+       if (state && pll->params->pre_rate_change) {
+               ret = pll->params->pre_rate_change();
+               if (WARN_ON(ret))
+                       return ret;
+       }
+
        _get_pll_mnp(pll, &old_cfg);
 
        if (state && pll->params->defaults_set && pll->params->dyn_ramp &&
                        (cfg->m == old_cfg.m) && (cfg->p == old_cfg.p)) {
                ret = pll->params->dyn_ramp(pll, cfg);
                if (!ret)
-                       return 0;
+                       goto done;
        }
 
        if (state) {
@@ -772,6 +778,10 @@ static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
                pll_clk_start_ss(pll);
        }
 
+done:
+       if (state && pll->params->post_rate_change)
+               pll->params->post_rate_change();
+
        return ret;
 }
 
diff --git a/drivers/clk/tegra/clk-tegra-super-cclk.c b/drivers/clk/tegra/clk-tegra-super-cclk.c
new file mode 100644 (file)
index 0000000..a03119c
--- /dev/null
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Based on clk-super.c
+ * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * Based on older tegra20-cpufreq driver by Colin Cross <ccross@google.com>
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author: Dmitry Osipenko <digetx@gmail.com>
+ * Copyright (C) 2019 GRATE-DRIVER project
+ */
+
+#include <linux/bits.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "clk.h"
+
+#define PLLP_INDEX             4
+#define PLLX_INDEX             8
+
+#define SUPER_CDIV_ENB         BIT(31)
+
+static struct tegra_clk_super_mux *cclk_super;
+static bool cclk_on_pllx;
+
+static u8 cclk_super_get_parent(struct clk_hw *hw)
+{
+       return tegra_clk_super_ops.get_parent(hw);
+}
+
+static int cclk_super_set_parent(struct clk_hw *hw, u8 index)
+{
+       return tegra_clk_super_ops.set_parent(hw, index);
+}
+
+static int cclk_super_set_rate(struct clk_hw *hw, unsigned long rate,
+                              unsigned long parent_rate)
+{
+       return tegra_clk_super_ops.set_rate(hw, rate, parent_rate);
+}
+
+static unsigned long cclk_super_recalc_rate(struct clk_hw *hw,
+                                           unsigned long parent_rate)
+{
+       if (cclk_super_get_parent(hw) == PLLX_INDEX)
+               return parent_rate;
+
+       return tegra_clk_super_ops.recalc_rate(hw, parent_rate);
+}
+
+static int cclk_super_determine_rate(struct clk_hw *hw,
+                                    struct clk_rate_request *req)
+{
+       struct clk_hw *pllp_hw = clk_hw_get_parent_by_index(hw, PLLP_INDEX);
+       struct clk_hw *pllx_hw = clk_hw_get_parent_by_index(hw, PLLX_INDEX);
+       struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
+       unsigned long pllp_rate;
+       long rate = req->rate;
+
+       if (WARN_ON_ONCE(!pllp_hw || !pllx_hw))
+               return -EINVAL;
+
+       /*
+        * Switch parent to PLLP for all CCLK rates that are suitable for PLLP.
+        * PLLX will be disabled in this case, saving some power.
+        */
+       pllp_rate = clk_hw_get_rate(pllp_hw);
+
+       if (rate <= pllp_rate) {
+               if (super->flags & TEGRA20_SUPER_CLK)
+                       rate = pllp_rate;
+               else
+                       rate = tegra_clk_super_ops.round_rate(hw, rate,
+                                                             &pllp_rate);
+
+               req->best_parent_rate = pllp_rate;
+               req->best_parent_hw = pllp_hw;
+               req->rate = rate;
+       } else {
+               rate = clk_hw_round_rate(pllx_hw, rate);
+               req->best_parent_rate = rate;
+               req->best_parent_hw = pllx_hw;
+               req->rate = rate;
+       }
+
+       if (WARN_ON_ONCE(rate <= 0))
+               return -EINVAL;
+
+       return 0;
+}
+
+static const struct clk_ops tegra_cclk_super_ops = {
+       .get_parent = cclk_super_get_parent,
+       .set_parent = cclk_super_set_parent,
+       .set_rate = cclk_super_set_rate,
+       .recalc_rate = cclk_super_recalc_rate,
+       .determine_rate = cclk_super_determine_rate,
+};
+
+static const struct clk_ops tegra_cclk_super_mux_ops = {
+       .get_parent = cclk_super_get_parent,
+       .set_parent = cclk_super_set_parent,
+       .determine_rate = cclk_super_determine_rate,
+};
+
+struct clk *tegra_clk_register_super_cclk(const char *name,
+               const char * const *parent_names, u8 num_parents,
+               unsigned long flags, void __iomem *reg, u8 clk_super_flags,
+               spinlock_t *lock)
+{
+       struct tegra_clk_super_mux *super;
+       struct clk *clk;
+       struct clk_init_data init;
+       u32 val;
+
+       if (WARN_ON(cclk_super))
+               return ERR_PTR(-EBUSY);
+
+       super = kzalloc(sizeof(*super), GFP_KERNEL);
+       if (!super)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.flags = flags;
+       init.parent_names = parent_names;
+       init.num_parents = num_parents;
+
+       super->reg = reg;
+       super->lock = lock;
+       super->width = 4;
+       super->flags = clk_super_flags;
+       super->hw.init = &init;
+
+       if (super->flags & TEGRA20_SUPER_CLK) {
+               init.ops = &tegra_cclk_super_mux_ops;
+       } else {
+               init.ops = &tegra_cclk_super_ops;
+
+               super->frac_div.reg = reg + 4;
+               super->frac_div.shift = 16;
+               super->frac_div.width = 8;
+               super->frac_div.frac_width = 1;
+               super->frac_div.lock = lock;
+               super->div_ops = &tegra_clk_frac_div_ops;
+       }
+
+       /*
+        * Tegra30+ has the following CPUG clock topology:
+        *
+        *        +---+  +-------+  +-+            +-+                +-+
+        * PLLP+->+   +->+DIVIDER+->+0|  +-------->+0|  ------------->+0|
+        *        |   |  +-------+  | |  |  +---+  | |  |             | |
+        * PLLC+->+MUX|             | +->+  | S |  | +->+             | +->+CPU
+        *  ...   |   |             | |  |  | K |  | |  |  +-------+  | |
+        * PLLX+->+-->+------------>+1|  +->+ I +->+1|  +->+ DIV2  +->+1|
+        *        +---+             +++     | P |  +++     |SKIPPER|  +++
+        *                           ^      | P |   ^      +-------+   ^
+        *                           |      | E |   |                  |
+        *                PLLX_SEL+--+      | R |   |       OVERHEAT+--+
+        *                                  +---+   |
+        *                                          |
+        *                         SUPER_CDIV_ENB+--+
+        *
+        * Tegra20 is similar, but simpler. It doesn't have the divider and
+        * thermal DIV2 skipper.
+        *
+        * At least for now we're not going to use clock-skipper, hence let's
+        * ensure that it is disabled.
+        */
+       val = readl_relaxed(reg + 4);
+       val &= ~SUPER_CDIV_ENB;
+       writel_relaxed(val, reg + 4);
+
+       clk = clk_register(NULL, &super->hw);
+       if (IS_ERR(clk))
+               kfree(super);
+       else
+               cclk_super = super;
+
+       return clk;
+}
+
+int tegra_cclk_pre_pllx_rate_change(void)
+{
+       if (IS_ERR_OR_NULL(cclk_super))
+               return -EINVAL;
+
+       if (cclk_super_get_parent(&cclk_super->hw) == PLLX_INDEX)
+               cclk_on_pllx = true;
+       else
+               cclk_on_pllx = false;
+
+       /*
+        * CPU needs to be temporarily re-parented away from PLLX if PLLX
+        * changes its rate. PLLP is a safe parent for CPU on all Tegra SoCs.
+        */
+       if (cclk_on_pllx)
+               cclk_super_set_parent(&cclk_super->hw, PLLP_INDEX);
+
+       return 0;
+}
+
+void tegra_cclk_post_pllx_rate_change(void)
+{
+       if (cclk_on_pllx)
+               cclk_super_set_parent(&cclk_super->hw, PLLX_INDEX);
+}
index 085feb0..3efc651 100644 (file)
@@ -391,6 +391,8 @@ static struct tegra_clk_pll_params pll_x_params = {
        .lock_delay = 300,
        .freq_table = pll_x_freq_table,
        .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_HAS_LOCK_ENABLE,
+       .pre_rate_change = tegra_cclk_pre_pllx_rate_change,
+       .post_rate_change = tegra_cclk_post_pllx_rate_change,
 };
 
 static struct tegra_clk_pll_params pll_e_params = {
@@ -702,9 +704,10 @@ static void tegra20_super_clk_init(void)
        struct clk *clk;
 
        /* CCLK */
-       clk = tegra_clk_register_super_mux("cclk", cclk_parents,
+       clk = tegra_clk_register_super_cclk("cclk", cclk_parents,
                              ARRAY_SIZE(cclk_parents), CLK_SET_RATE_PARENT,
-                             clk_base + CCLK_BURST_POLICY, 0, 4, 0, 0, NULL);
+                             clk_base + CCLK_BURST_POLICY, TEGRA20_SUPER_CLK,
+                             NULL);
        clks[TEGRA20_CLK_CCLK] = clk;
 
        /* SCLK */
diff --git a/drivers/clk/tegra/clk-tegra210-emc.c b/drivers/clk/tegra/clk-tegra210-emc.c
new file mode 100644 (file)
index 0000000..352a2c3
--- /dev/null
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2015-2020, NVIDIA CORPORATION.  All rights reserved.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/tegra.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#define CLK_SOURCE_EMC 0x19c
+#define  CLK_SOURCE_EMC_2X_CLK_SRC GENMASK(31, 29)
+#define  CLK_SOURCE_EMC_MC_EMC_SAME_FREQ BIT(16)
+#define  CLK_SOURCE_EMC_2X_CLK_DIVISOR GENMASK(7, 0)
+
+#define CLK_SRC_PLLM 0
+#define CLK_SRC_PLLC 1
+#define CLK_SRC_PLLP 2
+#define CLK_SRC_CLK_M 3
+#define CLK_SRC_PLLM_UD 4
+#define CLK_SRC_PLLMB_UD 5
+#define CLK_SRC_PLLMB 6
+#define CLK_SRC_PLLP_UD 7
+
+struct tegra210_clk_emc {
+       struct clk_hw hw;
+       void __iomem *regs;
+
+       struct tegra210_clk_emc_provider *provider;
+
+       struct clk *parents[8];
+};
+
+static inline struct tegra210_clk_emc *
+to_tegra210_clk_emc(struct clk_hw *hw)
+{
+       return container_of(hw, struct tegra210_clk_emc, hw);
+}
+
+static const char *tegra210_clk_emc_parents[] = {
+       "pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_mb_ud",
+       "pll_mb", "pll_p_ud",
+};
+
+static u8 tegra210_clk_emc_get_parent(struct clk_hw *hw)
+{
+       struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
+       u32 value;
+       u8 src;
+
+       value = readl_relaxed(emc->regs + CLK_SOURCE_EMC);
+       src = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_SRC, value);
+
+       return src;
+}
+
+static unsigned long tegra210_clk_emc_recalc_rate(struct clk_hw *hw,
+                                                 unsigned long parent_rate)
+{
+       struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
+       u32 value, div;
+
+       /*
+        * CCF assumes that neither the parent nor its rate will change during
+        * ->set_rate(), so the parent rate passed in here was cached from the
+        * parent before the ->set_rate() call.
+        *
+        * This can lead to wrong results being reported for the EMC clock if
+        * the parent and/or parent rate have changed as part of the EMC rate
+        * change sequence. Fix this by overriding the parent clock with what
+        * we know to be the correct value after the rate change.
+        */
+       parent_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
+
+       value = readl_relaxed(emc->regs + CLK_SOURCE_EMC);
+
+       div = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_DIVISOR, value);
+       div += 2;
+
+       return DIV_ROUND_UP(parent_rate * 2, div);
+}
+
+static long tegra210_clk_emc_round_rate(struct clk_hw *hw, unsigned long rate,
+                                       unsigned long *prate)
+{
+       struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
+       struct tegra210_clk_emc_provider *provider = emc->provider;
+       unsigned int i;
+
+       if (!provider || !provider->configs || provider->num_configs == 0)
+               return clk_hw_get_rate(hw);
+
+       for (i = 0; i < provider->num_configs; i++) {
+               if (provider->configs[i].rate >= rate)
+                       return provider->configs[i].rate;
+       }
+
+       return provider->configs[i - 1].rate;
+}
+
+static struct clk *tegra210_clk_emc_find_parent(struct tegra210_clk_emc *emc,
+                                               u8 index)
+{
+       struct clk_hw *parent = clk_hw_get_parent_by_index(&emc->hw, index);
+       const char *name = clk_hw_get_name(parent);
+
+       /* XXX implement cache? */
+
+       return __clk_lookup(name);
+}
+
+static int tegra210_clk_emc_set_rate(struct clk_hw *hw, unsigned long rate,
+                                    unsigned long parent_rate)
+{
+       struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
+       struct tegra210_clk_emc_provider *provider = emc->provider;
+       struct tegra210_clk_emc_config *config;
+       struct device *dev = provider->dev;
+       struct clk_hw *old, *new, *parent;
+       u8 old_idx, new_idx, index;
+       struct clk *clk;
+       unsigned int i;
+       int err;
+
+       if (!provider || !provider->configs || provider->num_configs == 0)
+               return -EINVAL;
+
+       for (i = 0; i < provider->num_configs; i++) {
+               if (provider->configs[i].rate >= rate) {
+                       config = &provider->configs[i];
+                       break;
+               }
+       }
+
+       if (i == provider->num_configs)
+               config = &provider->configs[i - 1];
+
+       old_idx = tegra210_clk_emc_get_parent(hw);
+       new_idx = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_SRC, config->value);
+
+       old = clk_hw_get_parent_by_index(hw, old_idx);
+       new = clk_hw_get_parent_by_index(hw, new_idx);
+
+       /* if the rate has changed... */
+       if (config->parent_rate != clk_hw_get_rate(old)) {
+               /* ... but the clock source remains the same ... */
+               if (new_idx == old_idx) {
+                       /* ... switch to the alternative clock source. */
+                       switch (new_idx) {
+                       case CLK_SRC_PLLM:
+                               new_idx = CLK_SRC_PLLMB;
+                               break;
+
+                       case CLK_SRC_PLLM_UD:
+                               new_idx = CLK_SRC_PLLMB_UD;
+                               break;
+
+                       case CLK_SRC_PLLMB_UD:
+                               new_idx = CLK_SRC_PLLM_UD;
+                               break;
+
+                       case CLK_SRC_PLLMB:
+                               new_idx = CLK_SRC_PLLM;
+                               break;
+                       }
+
+                       /*
+                        * This should never happen because we can't deal with
+                        * it.
+                        */
+                       if (WARN_ON(new_idx == old_idx))
+                               return -EINVAL;
+
+                       new = clk_hw_get_parent_by_index(hw, new_idx);
+               }
+
+               index = new_idx;
+               parent = new;
+       } else {
+               index = old_idx;
+               parent = old;
+       }
+
+       clk = tegra210_clk_emc_find_parent(emc, index);
+       if (IS_ERR(clk)) {
+               err = PTR_ERR(clk);
+               dev_err(dev, "failed to get parent clock for index %u: %d\n",
+                       index, err);
+               return err;
+       }
+
+       /* set the new parent clock to the required rate */
+       if (clk_get_rate(clk) != config->parent_rate) {
+               err = clk_set_rate(clk, config->parent_rate);
+               if (err < 0) {
+                       dev_err(dev, "failed to set rate %lu Hz for %pC: %d\n",
+                               config->parent_rate, clk, err);
+                       return err;
+               }
+       }
+
+       /* enable the new parent clock */
+       if (parent != old) {
+               err = clk_prepare_enable(clk);
+               if (err < 0) {
+                       dev_err(dev, "failed to enable parent clock %pC: %d\n",
+                               clk, err);
+                       return err;
+               }
+       }
+
+       /* update the EMC source configuration to reflect the new parent */
+       config->value &= ~CLK_SOURCE_EMC_2X_CLK_SRC;
+       config->value |= FIELD_PREP(CLK_SOURCE_EMC_2X_CLK_SRC, index);
+
+       /*
+        * Finally, switch the EMC programming with both old and new parent
+        * clocks enabled.
+        */
+       err = provider->set_rate(dev, config);
+       if (err < 0) {
+               dev_err(dev, "failed to set EMC rate to %lu Hz: %d\n", rate,
+                       err);
+
+               /*
+                * If we're unable to switch to the new EMC frequency, we no
+                * longer need the new parent to be enabled.
+                */
+               if (parent != old)
+                       clk_disable_unprepare(clk);
+
+               return err;
+       }
+
+       /* reparent to new parent clock and disable the old parent clock */
+       if (parent != old) {
+               clk = tegra210_clk_emc_find_parent(emc, old_idx);
+               if (IS_ERR(clk)) {
+                       err = PTR_ERR(clk);
+                       dev_err(dev,
+                               "failed to get parent clock for index %u: %d\n",
+                               old_idx, err);
+                       return err;
+               }
+
+               clk_hw_reparent(hw, parent);
+               clk_disable_unprepare(clk);
+       }
+
+       return err;
+}
+
+static const struct clk_ops tegra210_clk_emc_ops = {
+       .get_parent = tegra210_clk_emc_get_parent,
+       .recalc_rate = tegra210_clk_emc_recalc_rate,
+       .round_rate = tegra210_clk_emc_round_rate,
+       .set_rate = tegra210_clk_emc_set_rate,
+};
+
+struct clk *tegra210_clk_register_emc(struct device_node *np,
+                                     void __iomem *regs)
+{
+       struct tegra210_clk_emc *emc;
+       struct clk_init_data init;
+       struct clk *clk;
+
+       emc = kzalloc(sizeof(*emc), GFP_KERNEL);
+       if (!emc)
+               return ERR_PTR(-ENOMEM);
+
+       emc->regs = regs;
+
+       init.name = "emc";
+       init.ops = &tegra210_clk_emc_ops;
+       init.flags = CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE;
+       init.parent_names = tegra210_clk_emc_parents;
+       init.num_parents = ARRAY_SIZE(tegra210_clk_emc_parents);
+       emc->hw.init = &init;
+
+       clk = clk_register(NULL, &emc->hw);
+       if (IS_ERR(clk)) {
+               kfree(emc);
+               return clk;
+       }
+
+       return clk;
+}
+
+int tegra210_clk_emc_attach(struct clk *clk,
+                           struct tegra210_clk_emc_provider *provider)
+{
+       struct clk_hw *hw = __clk_get_hw(clk);
+       struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
+       struct device *dev = provider->dev;
+       unsigned int i;
+       int err;
+
+       if (!try_module_get(provider->owner))
+               return -ENODEV;
+
+       for (i = 0; i < provider->num_configs; i++) {
+               struct tegra210_clk_emc_config *config = &provider->configs[i];
+               struct clk_hw *parent;
+               bool same_freq;
+               u8 div, src;
+
+               div = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_DIVISOR, config->value);
+               src = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_SRC, config->value);
+
+               /* do basic sanity checking on the EMC timings */
+               if (div & 0x1) {
+                       dev_err(dev, "invalid odd divider %u for rate %lu Hz\n",
+                               div, config->rate);
+                       err = -EINVAL;
+                       goto put;
+               }
+
+               same_freq = config->value & CLK_SOURCE_EMC_MC_EMC_SAME_FREQ;
+
+               if (same_freq != config->same_freq) {
+                       dev_err(dev,
+                               "ambiguous EMC to MC ratio for rate %lu Hz\n",
+                               config->rate);
+                       err = -EINVAL;
+                       goto put;
+               }
+
+               parent = clk_hw_get_parent_by_index(hw, src);
+               config->parent = src;
+
+               if (src == CLK_SRC_PLLM || src == CLK_SRC_PLLM_UD) {
+                       config->parent_rate = config->rate * (1 + div / 2);
+               } else {
+                       unsigned long rate = config->rate * (1 + div / 2);
+
+                       config->parent_rate = clk_hw_get_rate(parent);
+
+                       if (config->parent_rate != rate) {
+                               dev_err(dev,
+                                       "rate %lu Hz does not match input\n",
+                                       config->rate);
+                               err = -EINVAL;
+                               goto put;
+                       }
+               }
+       }
+
+       emc->provider = provider;
+
+       return 0;
+
+put:
+       module_put(provider->owner);
+       return err;
+}
+EXPORT_SYMBOL_GPL(tegra210_clk_emc_attach);
+
+void tegra210_clk_emc_detach(struct clk *clk)
+{
+       struct tegra210_clk_emc *emc = to_tegra210_clk_emc(__clk_get_hw(clk));
+
+       module_put(emc->provider->owner);
+       emc->provider = NULL;
+}
+EXPORT_SYMBOL_GPL(tegra210_clk_emc_detach);
index defe3b7..68cbb98 100644 (file)
@@ -37,6 +37,7 @@
 #define CLK_SOURCE_LA 0x1f8
 #define CLK_SOURCE_SDMMC2 0x154
 #define CLK_SOURCE_SDMMC4 0x164
+#define CLK_SOURCE_EMC_DLL 0x664
 
 #define PLLC_BASE 0x80
 #define PLLC_OUT 0x84
 #define RST_DFLL_DVCO 0x2f4
 #define DVFS_DFLL_RESET_SHIFT 0
 
+#define CLK_RST_CONTROLLER_CLK_OUT_ENB_X_SET   0x284
+#define CLK_RST_CONTROLLER_CLK_OUT_ENB_X_CLR   0x288
+#define CLK_OUT_ENB_X_CLK_ENB_EMC_DLL          BIT(14)
+
 #define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8
 #define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac
 #define CPU_SOFTRST_CTRL 0x380
@@ -314,12 +319,6 @@ static unsigned long tegra210_input_freq[] = {
        [8] = 12000000,
 };
 
-static const char *mux_pllmcp_clkm[] = {
-       "pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_mb", "pll_mb",
-       "pll_p",
-};
-#define mux_pllmcp_clkm_idx NULL
-
 #define PLL_ENABLE                     (1 << 30)
 
 #define PLLCX_MISC1_IDDQ               (1 << 27)
@@ -555,6 +554,27 @@ void tegra210_set_sata_pll_seq_sw(bool state)
 }
 EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw);
 
+void tegra210_clk_emc_dll_enable(bool flag)
+{
+       u32 offset = flag ? CLK_RST_CONTROLLER_CLK_OUT_ENB_X_SET :
+                    CLK_RST_CONTROLLER_CLK_OUT_ENB_X_CLR;
+
+       writel_relaxed(CLK_OUT_ENB_X_CLK_ENB_EMC_DLL, clk_base + offset);
+}
+EXPORT_SYMBOL_GPL(tegra210_clk_emc_dll_enable);
+
+void tegra210_clk_emc_dll_update_setting(u32 emc_dll_src_value)
+{
+       writel_relaxed(emc_dll_src_value, clk_base + CLK_SOURCE_EMC_DLL);
+}
+EXPORT_SYMBOL_GPL(tegra210_clk_emc_dll_update_setting);
+
+void tegra210_clk_emc_update_setting(u32 emc_src_value)
+{
+       writel_relaxed(emc_src_value, clk_base + CLK_SOURCE_EMC);
+}
+EXPORT_SYMBOL_GPL(tegra210_clk_emc_update_setting);
+
 static void tegra210_generic_mbist_war(struct tegra210_domain_mbist_war *mbist)
 {
        u32 val;
@@ -2310,7 +2330,6 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = {
        [tegra_clk_i2c2] = { .dt_id = TEGRA210_CLK_I2C2, .present = true },
        [tegra_clk_uartc_8] = { .dt_id = TEGRA210_CLK_UARTC, .present = true },
        [tegra_clk_mipi_cal] = { .dt_id = TEGRA210_CLK_MIPI_CAL, .present = true },
-       [tegra_clk_emc] = { .dt_id = TEGRA210_CLK_EMC, .present = true },
        [tegra_clk_usb2] = { .dt_id = TEGRA210_CLK_USB2, .present = true },
        [tegra_clk_bsev] = { .dt_id = TEGRA210_CLK_BSEV, .present = true },
        [tegra_clk_uartd_8] = { .dt_id = TEGRA210_CLK_UARTD, .present = true },
@@ -2953,6 +2972,27 @@ static const char * const sor1_parents[] = {
 
 static u32 sor1_parents_idx[] = { 0, 2, 5, 6 };
 
+static const struct clk_div_table mc_div_table_tegra210[] = {
+       { .val = 0, .div = 2 },
+       { .val = 1, .div = 4 },
+       { .val = 2, .div = 1 },
+       { .val = 3, .div = 2 },
+       { .val = 0, .div = 0 },
+};
+
+static void tegra210_clk_register_mc(const char *name,
+                                    const char *parent_name)
+{
+       struct clk *clk;
+
+       clk = clk_register_divider_table(NULL, name, parent_name,
+                                        CLK_IS_CRITICAL,
+                                        clk_base + CLK_SOURCE_EMC,
+                                        15, 2, CLK_DIVIDER_READ_ONLY,
+                                        mc_div_table_tegra210, &emc_lock);
+       clks[TEGRA210_CLK_MC] = clk;
+}
+
 static const char * const sor1_out_parents[] = {
        /*
         * Bit 0 of the mux selects sor1_pad_clkout, irrespective of bit 1, so
@@ -2995,7 +3035,8 @@ static const char * const la_parents[] = {
 static struct tegra_clk_periph tegra210_la =
        TEGRA_CLK_PERIPH(29, 7, 9, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, 76, 0, NULL, NULL);
 
-static __init void tegra210_periph_clk_init(void __iomem *clk_base,
+static __init void tegra210_periph_clk_init(struct device_node *np,
+                                           void __iomem *clk_base,
                                            void __iomem *pmc_base)
 {
        struct clk *clk;
@@ -3035,22 +3076,19 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base,
                                             periph_clk_enb_refcnt);
        clks[TEGRA210_CLK_DSIB] = clk;
 
+       /* csi_tpg */
+       clk = clk_register_gate(NULL, "csi_tpg", "pll_d",
+                               CLK_SET_RATE_PARENT, clk_base + PLLD_BASE,
+                               23, 0, &pll_d_lock);
+       clk_register_clkdev(clk, "csi_tpg", NULL);
+       clks[TEGRA210_CLK_CSI_TPG] = clk;
+
        /* la */
        clk = tegra_clk_register_periph("la", la_parents,
                        ARRAY_SIZE(la_parents), &tegra210_la, clk_base,
                        CLK_SOURCE_LA, 0);
        clks[TEGRA210_CLK_LA] = clk;
 
-       /* emc mux */
-       clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
-                              ARRAY_SIZE(mux_pllmcp_clkm), 0,
-                              clk_base + CLK_SOURCE_EMC,
-                              29, 3, 0, &emc_lock);
-
-       clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC,
-                                   &emc_lock);
-       clks[TEGRA210_CLK_MC] = clk;
-
        /* cml0 */
        clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX,
                                0, 0, &pll_e_lock);
@@ -3093,6 +3131,13 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base,
        }
 
        tegra_periph_clk_init(clk_base, pmc_base, tegra210_clks, &pll_p_params);
+
+       /* emc */
+       clk = tegra210_clk_register_emc(np, clk_base);
+       clks[TEGRA210_CLK_EMC] = clk;
+
+       /* mc */
+       tegra210_clk_register_mc("mc", "emc");
 }
 
 static void __init tegra210_pll_init(void __iomem *clk_base,
@@ -3153,6 +3198,17 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
        clk_register_clkdev(clk, "pll_m_ud", NULL);
        clks[TEGRA210_CLK_PLL_M_UD] = clk;
 
+       /* PLLMB_UD */
+       clk = clk_register_fixed_factor(NULL, "pll_mb_ud", "pll_mb",
+                                       CLK_SET_RATE_PARENT, 1, 1);
+       clk_register_clkdev(clk, "pll_mb_ud", NULL);
+       clks[TEGRA210_CLK_PLL_MB_UD] = clk;
+
+       /* PLLP_UD */
+       clk = clk_register_fixed_factor(NULL, "pll_p_ud", "pll_p",
+                                       0, 1, 1);
+       clks[TEGRA210_CLK_PLL_P_UD] = clk;
+
        /* PLLU_VCO */
        if (!tegra210_init_pllu()) {
                clk = clk_register_fixed_rate(NULL, "pll_u_vco", "pll_ref", 0,
@@ -3680,7 +3736,7 @@ static void __init tegra210_clock_init(struct device_node *np)
 
        tegra_fixed_clk_init(tegra210_clks);
        tegra210_pll_init(clk_base, pmc_base);
-       tegra210_periph_clk_init(clk_base, pmc_base);
+       tegra210_periph_clk_init(np, clk_base, pmc_base);
        tegra_audio_clk_init(clk_base, pmc_base, tegra210_clks,
                             tegra210_audio_plls,
                             ARRAY_SIZE(tegra210_audio_plls), 24576000);
index 3255f82..37244a7 100644 (file)
@@ -499,6 +499,8 @@ static struct tegra_clk_pll_params pll_x_params __ro_after_init = {
        .freq_table = pll_x_freq_table,
        .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_DCCON |
                 TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
+       .pre_rate_change = tegra_cclk_pre_pllx_rate_change,
+       .post_rate_change = tegra_cclk_post_pllx_rate_change,
 };
 
 static struct tegra_clk_pll_params pll_e_params __ro_after_init = {
@@ -926,11 +928,11 @@ static void __init tegra30_super_clk_init(void)
        clk_register_clkdev(clk, "pll_p_out4_cclkg", NULL);
 
        /* CCLKG */
-       clk = tegra_clk_register_super_mux("cclk_g", cclk_g_parents,
+       clk = tegra_clk_register_super_cclk("cclk_g", cclk_g_parents,
                                  ARRAY_SIZE(cclk_g_parents),
                                  CLK_SET_RATE_PARENT,
                                  clk_base + CCLKG_BURST_POLICY,
-                                 0, 4, 0, 0, NULL);
+                                 0, NULL);
        clks[TEGRA30_CLK_CCLK_G] = clk;
 
        /*
index 2c9a683..6b565f6 100644 (file)
@@ -266,6 +266,10 @@ struct tegra_clk_pll;
  *                             disabled.
  * @dyn_ramp:                  Callback which can be used to define a custom
  *                             dynamic ramp function for a given PLL.
+ * @pre_rate_change:           Callback which is invoked just before changing
+ *                             PLL's rate.
+ * @post_rate_change:          Callback which is invoked right after changing
+ *                             PLL's rate.
  *
  * Flags:
  * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for
@@ -342,6 +346,8 @@ struct tegra_clk_pll_params {
        void    (*set_defaults)(struct tegra_clk_pll *pll);
        int     (*dyn_ramp)(struct tegra_clk_pll *pll,
                        struct tegra_clk_pll_freq_table *cfg);
+       int     (*pre_rate_change)(void);
+       void    (*post_rate_change)(void);
 };
 
 #define TEGRA_PLL_USE_LOCK BIT(0)
@@ -729,8 +735,10 @@ struct clk *tegra_clk_register_periph_data(void __iomem *clk_base,
  * TEGRA_DIVIDER_2 - LP cluster has additional divider. This flag indicates
  *     that this is LP cluster clock.
  * TEGRA210_CPU_CLK - This flag is used to identify CPU cluster for gen5
- * super mux parent using PLLP branches. To use PLLP branches to CPU, need
- * to configure additional bit PLLP_OUT_CPU in the clock registers.
+ *     super mux parent using PLLP branches. To use PLLP branches to CPU, need
+ *     to configure additional bit PLLP_OUT_CPU in the clock registers.
+ * TEGRA20_SUPER_CLK - Tegra20 doesn't have a dedicated divider for Super
+ *     clocks, it only has a clock-skipper.
  */
 struct tegra_clk_super_mux {
        struct clk_hw   hw;
@@ -748,6 +756,7 @@ struct tegra_clk_super_mux {
 
 #define TEGRA_DIVIDER_2 BIT(0)
 #define TEGRA210_CPU_CLK BIT(1)
+#define TEGRA20_SUPER_CLK BIT(2)
 
 extern const struct clk_ops tegra_clk_super_ops;
 struct clk *tegra_clk_register_super_mux(const char *name,
@@ -758,6 +767,12 @@ struct clk *tegra_clk_register_super_clk(const char *name,
                const char * const *parent_names, u8 num_parents,
                unsigned long flags, void __iomem *reg, u8 clk_super_flags,
                spinlock_t *lock);
+struct clk *tegra_clk_register_super_cclk(const char *name,
+               const char * const *parent_names, u8 num_parents,
+               unsigned long flags, void __iomem *reg, u8 clk_super_flags,
+               spinlock_t *lock);
+int tegra_cclk_pre_pllx_rate_change(void);
+void tegra_cclk_post_pllx_rate_change(void);
 
 /**
  * struct tegra_sdmmc_mux - switch divider with Low Jitter inputs for SDMMC
@@ -866,7 +881,7 @@ void tegra_super_clk_gen5_init(void __iomem *clk_base,
                        void __iomem *pmc_base, struct tegra_clk *tegra_clks,
                        struct tegra_clk_pll_params *pll_params);
 
-#ifdef CONFIG_TEGRA_CLK_EMC
+#ifdef CONFIG_TEGRA124_EMC
 struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
                                   spinlock_t *lock);
 #else
@@ -907,4 +922,7 @@ void tegra_clk_periph_resume(void);
 bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw);
 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);
+
 #endif /* TEGRA_CLK_H */
index 312a20f..a38c921 100644 (file)
@@ -606,13 +606,13 @@ static const struct omap_clkctrl_reg_data omap4_l4_per_clkctrl_regs[] __initcons
 
 static const struct
 omap_clkctrl_reg_data omap4_l4_secure_clkctrl_regs[] __initconst = {
-       { OMAP4_AES1_CLKCTRL, NULL, CLKF_SW_SUP, "" },
-       { OMAP4_AES2_CLKCTRL, NULL, CLKF_SW_SUP, "" },
-       { OMAP4_DES3DES_CLKCTRL, NULL, CLKF_SW_SUP, "" },
-       { OMAP4_PKA_CLKCTRL, NULL, CLKF_SW_SUP, "" },
-       { OMAP4_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
-       { OMAP4_SHA2MD5_CLKCTRL, NULL, CLKF_SW_SUP, "" },
-       { OMAP4_CRYPTODMA_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
+       { OMAP4_AES1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_div_ck" },
+       { OMAP4_AES2_CLKCTRL, NULL, CLKF_SW_SUP, "l3_div_ck" },
+       { OMAP4_DES3DES_CLKCTRL, NULL, CLKF_SW_SUP, "l4_div_ck" },
+       { OMAP4_PKA_CLKCTRL, NULL, CLKF_SW_SUP, "l4_div_ck" },
+       { OMAP4_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l4_div_ck" },
+       { OMAP4_SHA2MD5_CLKCTRL, NULL, CLKF_SW_SUP, "l3_div_ck" },
+       { OMAP4_CRYPTODMA_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l3_div_ck" },
        { 0 },
 };
 
index 92bf2dd..8694bc9 100644 (file)
@@ -303,13 +303,13 @@ static const struct omap_clkctrl_reg_data omap5_l4per_clkctrl_regs[] __initconst
 
 static const struct
 omap_clkctrl_reg_data omap5_l4_secure_clkctrl_regs[] __initconst = {
-       { OMAP5_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "" },
-       { OMAP5_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "" },
-       { OMAP5_DES3DES_CLKCTRL, NULL, CLKF_HW_SUP, "" },
-       { OMAP5_FPKA_CLKCTRL, NULL, CLKF_SW_SUP, "" },
-       { OMAP5_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
-       { OMAP5_SHA2MD5_CLKCTRL, NULL, CLKF_HW_SUP, "" },
-       { OMAP5_DMA_CRYPTO_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
+       { OMAP5_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { OMAP5_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { OMAP5_DES3DES_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" },
+       { OMAP5_FPKA_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div" },
+       { OMAP5_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l4_root_clk_div" },
+       { OMAP5_SHA2MD5_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { OMAP5_DMA_CRYPTO_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l3_iclk_div" },
        { 0 },
 };
 
index 14b6450..b4cf578 100644 (file)
@@ -312,15 +312,6 @@ static const char * const dra7_gpu_hyd_mux_parents[] __initconst = {
        NULL,
 };
 
-static const char * const dra7_gpu_sys_clk_parents[] __initconst = {
-       "sys_clkin",
-       NULL,
-};
-
-static const struct omap_clkctrl_div_data dra7_gpu_sys_clk_data __initconst = {
-       .max_div = 2,
-};
-
 static const struct omap_clkctrl_bit_data dra7_gpu_core_bit_data[] __initconst = {
        { 24, TI_CLK_MUX, dra7_gpu_core_mux_parents, NULL, },
        { 26, TI_CLK_MUX, dra7_gpu_hyd_mux_parents, NULL, },
@@ -328,7 +319,7 @@ static const struct omap_clkctrl_bit_data dra7_gpu_core_bit_data[] __initconst =
 };
 
 static const struct omap_clkctrl_reg_data dra7_gpu_clkctrl_regs[] __initconst = {
-       { DRA7_GPU_CLKCTRL, dra7_gpu_core_bit_data, CLKF_SW_SUP, "gpu_cm:clk:0000:24", },
+       { DRA7_GPU_CLKCTRL, dra7_gpu_core_bit_data, CLKF_SW_SUP, "gpu-clkctrl:0000:24", },
        { 0 },
 };
 
@@ -644,7 +635,7 @@ static const struct omap_clkctrl_reg_data dra7_l4sec_clkctrl_regs[] __initconst
        { DRA7_L4SEC_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
        { DRA7_L4SEC_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
        { DRA7_L4SEC_DES_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
-       { DRA7_L4SEC_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
+       { DRA7_L4SEC_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l4_root_clk_div" },
        { DRA7_L4SEC_SHAM_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
        { 0 },
 };
@@ -815,7 +806,7 @@ static const struct omap_clkctrl_reg_data dra7_wkupaon_clkctrl_regs[] __initcons
        { DRA7_WKUPAON_COUNTER_32K_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" },
        { DRA7_WKUPAON_UART10_CLKCTRL, dra7_uart10_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0060:24" },
        { DRA7_WKUPAON_DCAN1_CLKCTRL, dra7_dcan1_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0068:24" },
-       { DRA7_WKUPAON_ADC_CLKCTRL, NULL, CLKF_SW_SUP, "mcan_clk" },
+       { DRA7_WKUPAON_ADC_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SOC_DRA76, "mcan_clk" },
        { 0 },
 };
 
index 6a89936..eaa4357 100644 (file)
@@ -196,6 +196,7 @@ cleanup:
                if (!cclk->comp_clks[i])
                        continue;
                list_del(&cclk->comp_clks[i]->link);
+               kfree(cclk->comp_clks[i]->parent_names);
                kfree(cclk->comp_clks[i]);
        }
 
index 5a5638e..5798698 100644 (file)
@@ -435,8 +435,7 @@ static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
                 * fall through to the write state, as we will need to
                 * send a byte as well
                 */
-               /* Fall through */
-
+               fallthrough;
        case STATE_WRITE:
                /*
                 * we are writing data to the device... check for the
index 462b535..a53ecb6 100644 (file)
@@ -409,7 +409,7 @@ config MMC_MESON_MX_SDIO
        tristate "Amlogic Meson6/Meson8/Meson8b SD/MMC Host Controller support"
        depends on ARCH_MESON || COMPILE_TEST
        depends on COMMON_CLK
-       depends on OF
+       depends on OF_ADDRESS
        help
          This selects support for the SD/MMC Host Controller on
          Amlogic Meson6, Meson8 and Meson8b SoCs.
diff --git a/include/dt-bindings/clock/agilex-clock.h b/include/dt-bindings/clock/agilex-clock.h
new file mode 100644 (file)
index 0000000..f19cf8c
--- /dev/null
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2019, Intel Corporation
+ */
+
+#ifndef __AGILEX_CLOCK_H
+#define __AGILEX_CLOCK_H
+
+/* fixed rate clocks */
+#define AGILEX_OSC1                    0
+#define AGILEX_CB_INTOSC_HS_DIV2_CLK   1
+#define AGILEX_CB_INTOSC_LS_CLK                2
+#define AGILEX_L4_SYS_FREE_CLK         3
+#define AGILEX_F2S_FREE_CLK            4
+
+/* PLL clocks */
+#define AGILEX_MAIN_PLL_CLK            5
+#define AGILEX_MAIN_PLL_C0_CLK         6
+#define AGILEX_MAIN_PLL_C1_CLK         7
+#define AGILEX_MAIN_PLL_C2_CLK         8
+#define AGILEX_MAIN_PLL_C3_CLK         9
+#define AGILEX_PERIPH_PLL_CLK          10
+#define AGILEX_PERIPH_PLL_C0_CLK       11
+#define AGILEX_PERIPH_PLL_C1_CLK       12
+#define AGILEX_PERIPH_PLL_C2_CLK       13
+#define AGILEX_PERIPH_PLL_C3_CLK       14
+#define AGILEX_MPU_FREE_CLK            15
+#define AGILEX_MPU_CCU_CLK             16
+#define AGILEX_BOOT_CLK                        17
+
+/* fixed factor clocks */
+#define AGILEX_L3_MAIN_FREE_CLK                18
+#define AGILEX_NOC_FREE_CLK            19
+#define AGILEX_S2F_USR0_CLK            20
+#define AGILEX_NOC_CLK                 21
+#define AGILEX_EMAC_A_FREE_CLK         22
+#define AGILEX_EMAC_B_FREE_CLK         23
+#define AGILEX_EMAC_PTP_FREE_CLK       24
+#define AGILEX_GPIO_DB_FREE_CLK                25
+#define AGILEX_SDMMC_FREE_CLK          26
+#define AGILEX_S2F_USER0_FREE_CLK      27
+#define AGILEX_S2F_USER1_FREE_CLK      28
+#define AGILEX_PSI_REF_FREE_CLK                29
+
+/* Gate clocks */
+#define AGILEX_MPU_CLK                 30
+#define AGILEX_MPU_L2RAM_CLK           31
+#define AGILEX_MPU_PERIPH_CLK          32
+#define AGILEX_L4_MAIN_CLK             33
+#define AGILEX_L4_MP_CLK               34
+#define AGILEX_L4_SP_CLK               35
+#define AGILEX_CS_AT_CLK               36
+#define AGILEX_CS_TRACE_CLK            37
+#define AGILEX_CS_PDBG_CLK             38
+#define AGILEX_CS_TIMER_CLK            39
+#define AGILEX_S2F_USER0_CLK           40
+#define AGILEX_EMAC0_CLK               41
+#define AGILEX_EMAC1_CLK               43
+#define AGILEX_EMAC2_CLK               44
+#define AGILEX_EMAC_PTP_CLK            45
+#define AGILEX_GPIO_DB_CLK             46
+#define AGILEX_NAND_CLK                        47
+#define AGILEX_PSI_REF_CLK             48
+#define AGILEX_S2F_USER1_CLK           49
+#define AGILEX_SDMMC_CLK               50
+#define AGILEX_SPI_M_CLK               51
+#define AGILEX_USB_CLK                 52
+#define AGILEX_NUM_CLKS                        53
+
+#endif /* __AGILEX_CLOCK_H */
index 38b5554..eba1710 100644 (file)
@@ -12,6 +12,7 @@
 #define PMC_TYPE_SYSTEM                1
 #define PMC_TYPE_PERIPHERAL    2
 #define PMC_TYPE_GCK           3
+#define PMC_TYPE_PROGRAMMABLE  4
 
 #define PMC_SLOW               0
 #define PMC_MCK                        1
@@ -20,6 +21,9 @@
 #define PMC_MCK2               4
 #define PMC_I2S0_MUX           5
 #define PMC_I2S1_MUX           6
+#define PMC_PLLACK             7
+#define PMC_PLLBCK             8
+#define PMC_AUDIOPLLCK         9
 
 #ifndef AT91_PMC_MOSCS
 #define AT91_PMC_MOSCS         0               /* MOSCS Flag */
index 38145bd..b58370d 100644 (file)
 #define IMX7ULP_CLK_HSRUN_SYS_SEL      44
 #define IMX7ULP_CLK_HSRUN_CORE_DIV     45
 
-#define IMX7ULP_CLK_SCG1_END           46
+#define IMX7ULP_CLK_CORE               46
+#define IMX7ULP_CLK_HSRUN_CORE         47
+
+#define IMX7ULP_CLK_SCG1_END           48
 
 /* PCC2 */
 #define IMX7ULP_CLK_DMA1               0
index 47ab082..7a23f28 100644 (file)
 #define IMX8MP_CLK_ARM                         287
 #define IMX8MP_CLK_A53_CORE                    288
 
-#define IMX8MP_CLK_END                         289
+#define IMX8MP_SYS_PLL1_40M_CG                 289
+#define IMX8MP_SYS_PLL1_80M_CG                 290
+#define IMX8MP_SYS_PLL1_100M_CG                        291
+#define IMX8MP_SYS_PLL1_133M_CG                        292
+#define IMX8MP_SYS_PLL1_160M_CG                        293
+#define IMX8MP_SYS_PLL1_200M_CG                        294
+#define IMX8MP_SYS_PLL1_266M_CG                        295
+#define IMX8MP_SYS_PLL1_400M_CG                        296
+#define IMX8MP_SYS_PLL2_50M_CG                 297
+#define IMX8MP_SYS_PLL2_100M_CG                        298
+#define IMX8MP_SYS_PLL2_125M_CG                        299
+#define IMX8MP_SYS_PLL2_166M_CG                        300
+#define IMX8MP_SYS_PLL2_200M_CG                        301
+#define IMX8MP_SYS_PLL2_250M_CG                        302
+#define IMX8MP_SYS_PLL2_333M_CG                        303
+#define IMX8MP_SYS_PLL2_500M_CG                        304
+
+#define IMX8MP_CLK_M7_CORE                     305
+#define IMX8MP_CLK_ML_CORE                     306
+#define IMX8MP_CLK_GPU3D_CORE                  307
+#define IMX8MP_CLK_GPU3D_SHADER_CORE           308
+#define IMX8MP_CLK_GPU2D_CORE                  309
+#define IMX8MP_CLK_AUDIO_AXI                   310
+#define IMX8MP_CLK_HSIO_AXI                    311
+#define IMX8MP_CLK_MEDIA_ISP                   312
+
+#define IMX8MP_CLK_END                         313
+
+#define IMX8MP_CLK_AUDIOMIX_SAI1_IPG           0
+#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1         1
+#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK2         2
+#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK3         3
+#define IMX8MP_CLK_AUDIOMIX_SAI2_IPG           4
+#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1         5
+#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK2         6
+#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK3         7
+#define IMX8MP_CLK_AUDIOMIX_SAI3_IPG           8
+#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1         9
+#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK2         10
+#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK3         11
+#define IMX8MP_CLK_AUDIOMIX_SAI5_IPG           12
+#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK1         13
+#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK2         14
+#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK3         15
+#define IMX8MP_CLK_AUDIOMIX_SAI6_IPG           16
+#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK1         17
+#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK2         18
+#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK3         19
+#define IMX8MP_CLK_AUDIOMIX_SAI7_IPG           20
+#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK1         21
+#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK2         22
+#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK3         23
+#define IMX8MP_CLK_AUDIOMIX_ASRC_IPG           24
+#define IMX8MP_CLK_AUDIOMIX_PDM_IPG            25
+#define IMX8MP_CLK_AUDIOMIX_SDMA2_ROOT         26
+#define IMX8MP_CLK_AUDIOMIX_SDMA3_ROOT         27
+#define IMX8MP_CLK_AUDIOMIX_SPBA2_ROOT         28
+#define IMX8MP_CLK_AUDIOMIX_DSP_ROOT           29
+#define IMX8MP_CLK_AUDIOMIX_DSPDBG_ROOT                30
+#define IMX8MP_CLK_AUDIOMIX_EARC_IPG           31
+#define IMX8MP_CLK_AUDIOMIX_OCRAMA_IPG         32
+#define IMX8MP_CLK_AUDIOMIX_AUD2HTX_IPG                33
+#define IMX8MP_CLK_AUDIOMIX_EDMA_ROOT          34
+#define IMX8MP_CLK_AUDIOMIX_AUDPLL_ROOT                35
+#define IMX8MP_CLK_AUDIOMIX_MU2_ROOT           36
+#define IMX8MP_CLK_AUDIOMIX_MU3_ROOT           37
+#define IMX8MP_CLK_AUDIOMIX_EARC_PHY           38
+#define IMX8MP_CLK_AUDIOMIX_PDM_ROOT           39
+#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1_SEL     40
+#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK2_SEL     41
+#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1_SEL     42
+#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK2_SEL     43
+#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1_SEL     44
+#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK2_SEL     45
+#define IMX8MP_CLK_AUDIOMIX_SAI4_MCLK1_SEL     46
+#define IMX8MP_CLK_AUDIOMIX_SAI4_MCLK2_SEL     47
+#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK1_SEL     48
+#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK2_SEL     49
+#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK1_SEL     50
+#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK2_SEL     51
+#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK1_SEL     52
+#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK2_SEL     53
+#define IMX8MP_CLK_AUDIOMIX_PDM_SEL            54
+#define IMX8MP_CLK_AUDIOMIX_SAI_PLL_REF_SEL    55
+#define IMX8MP_CLK_AUDIOMIX_SAI_PLL            56
+#define IMX8MP_CLK_AUDIOMIX_SAI_PLL_BYPASS     57
+#define IMX8MP_CLK_AUDIOMIX_SAI_PLL_OUT                58
+
+#define IMX8MP_CLK_AUDIOMIX_END                        59
 
 #endif
index 68862aa..4c5965a 100644 (file)
 #define CLKID_PERIPH           126
 #define CLKID_AXI              128
 #define CLKID_L2_DRAM          130
+#define CLKID_HDMI_SYS         174
 #define CLKID_VPU              190
 #define CLKID_VDEC_1           196
 #define CLKID_VDEC_HCODEC      199
diff --git a/include/dt-bindings/clock/r8a7742-cpg-mssr.h b/include/dt-bindings/clock/r8a7742-cpg-mssr.h
new file mode 100644 (file)
index 0000000..e68191c
--- /dev/null
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0+
+ *
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_CLOCK_R8A7742_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R8A7742_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* r8a7742 CPG Core Clocks */
+#define R8A7742_CLK_Z          0
+#define R8A7742_CLK_Z2         1
+#define R8A7742_CLK_ZG         2
+#define R8A7742_CLK_ZTR                3
+#define R8A7742_CLK_ZTRD2      4
+#define R8A7742_CLK_ZT         5
+#define R8A7742_CLK_ZX         6
+#define R8A7742_CLK_ZS         7
+#define R8A7742_CLK_HP         8
+#define R8A7742_CLK_B          9
+#define R8A7742_CLK_LB         10
+#define R8A7742_CLK_P          11
+#define R8A7742_CLK_CL         12
+#define R8A7742_CLK_M2         13
+#define R8A7742_CLK_ZB3                14
+#define R8A7742_CLK_ZB3D2      15
+#define R8A7742_CLK_DDR                16
+#define R8A7742_CLK_SDH                17
+#define R8A7742_CLK_SD0                18
+#define R8A7742_CLK_SD1                19
+#define R8A7742_CLK_SD2                20
+#define R8A7742_CLK_SD3                21
+#define R8A7742_CLK_MMC0       22
+#define R8A7742_CLK_MMC1       23
+#define R8A7742_CLK_MP         24
+#define R8A7742_CLK_QSPI       25
+#define R8A7742_CLK_CP         26
+#define R8A7742_CLK_RCAN       27
+#define R8A7742_CLK_R          28
+#define R8A7742_CLK_OSC                29
+
+#endif /* __DT_BINDINGS_CLOCK_R8A7742_CPG_MSSR_H__ */
index 7a8f10b..54441fc 100644 (file)
 #define TEGRA210_CLK_PLL_P_OUT_XUSB 317
 #define TEGRA210_CLK_XUSB_SSP_SRC 318
 #define TEGRA210_CLK_PLL_RE_OUT1 319
-/* 320 */
-/* 321 */
+#define TEGRA210_CLK_PLL_MB_UD 320
+#define TEGRA210_CLK_PLL_P_UD 321
 #define TEGRA210_CLK_ISP 322
 #define TEGRA210_CLK_PLL_A_OUT_ADSP 323
 #define TEGRA210_CLK_PLL_A_OUT0_OUT_ADSP 324
 /* 325 */
 #define TEGRA210_CLK_OSC 326
-/* 327 */
+#define TEGRA210_CLK_CSI_TPG 327
 /* 328 */
 /* 329 */
 /* 330 */
diff --git a/include/dt-bindings/power/r8a7742-sysc.h b/include/dt-bindings/power/r8a7742-sysc.h
new file mode 100644 (file)
index 0000000..1b1bd3c
--- /dev/null
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_POWER_R8A7742_SYSC_H__
+#define __DT_BINDINGS_POWER_R8A7742_SYSC_H__
+
+/*
+ * These power domain indices match the numbers of the interrupt bits
+ * representing the power areas in the various Interrupt Registers
+ * (e.g. SYSCISR, Interrupt Status Register)
+ */
+
+#define R8A7742_PD_CA15_CPU0            0
+#define R8A7742_PD_CA15_CPU1            1
+#define R8A7742_PD_CA15_CPU2            2
+#define R8A7742_PD_CA15_CPU3            3
+#define R8A7742_PD_CA7_CPU0             5
+#define R8A7742_PD_CA7_CPU1             6
+#define R8A7742_PD_CA7_CPU2             7
+#define R8A7742_PD_CA7_CPU3             8
+#define R8A7742_PD_CA15_SCU            12
+#define R8A7742_PD_RGX                 20
+#define R8A7742_PD_CA7_SCU             21
+
+/* Always-on power area */
+#define R8A7742_PD_ALWAYS_ON           32
+
+#endif /* __DT_BINDINGS_POWER_R8A7742_SYSC_H__ */
index 2b1b352..3f01d43 100644 (file)
@@ -131,6 +131,9 @@ extern void tegra210_set_sata_pll_seq_sw(bool state);
 extern void tegra210_put_utmipll_in_iddq(void);
 extern void tegra210_put_utmipll_out_iddq(void);
 extern int tegra210_clk_handle_mbist_war(unsigned int id);
+extern void tegra210_clk_emc_dll_enable(bool flag);
+extern void tegra210_clk_emc_dll_update_setting(u32 emc_dll_src_value);
+extern void tegra210_clk_emc_update_setting(u32 emc_src_value);
 
 struct clk;
 
@@ -143,4 +146,28 @@ void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb,
                                        void *cb_arg);
 int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same);
 
+struct tegra210_clk_emc_config {
+       unsigned long rate;
+       bool same_freq;
+       u32 value;
+
+       unsigned long parent_rate;
+       u8 parent;
+};
+
+struct tegra210_clk_emc_provider {
+       struct module *owner;
+       struct device *dev;
+
+       struct tegra210_clk_emc_config *configs;
+       unsigned int num_configs;
+
+       int (*set_rate)(struct device *dev,
+                       const struct tegra210_clk_emc_config *config);
+};
+
+int tegra210_clk_emc_attach(struct clk *clk,
+                           struct tegra210_clk_emc_provider *provider);
+void tegra210_clk_emc_detach(struct clk *clk);
+
 #endif /* __LINUX_CLK_TEGRA_H_ */