Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 18 Nov 2017 04:04:24 +0000 (20:04 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 18 Nov 2017 04:04:24 +0000 (20:04 -0800)
Pull clk updates from Stephen Boyd:
 "We have two changes to the core framework this time around.

  The first being a large change that introduces runtime PM support to
  the clk framework. Now we properly call runtime PM operations on the
  device providing a clk when the clk is in use. This helps on SoCs
  where the clks provided by a device need something to be powered on
  before using the clks, like power domains or regulators. It also helps
  power those things down when clks aren't in use.

  The other core change is a devm API addition for clk providers so we
  can get rid of a bunch of clk driver remove functions that are just
  doing of_clk_del_provider().

  Outside of the core, we have the usual addition of clk drivers and
  smattering of non-critical fixes to existing drivers. The biggest diff
  is support for Mediatek MT2712 and MT7622 SoCs, but those patches
  really just add a bunch of data.

  By the way, we're trying something new here where we build the tree up
  with topic branches. We plan to work this into our workflow so that we
  don't step on each other's toes, and so the fixes branch can be merged
  on an as-needed basis.

  Summary:

  Core:
   - runtime PM support for clk providers
   - devm API for of_clk_add_hw_provider()

  New Drivers:
   - Mediatek MT2712 and MT7622
   - Renesas R-Car V3M SoC

  Updates:
   - runtime PM support for Samsung exynos5433/exynos4412 providers
   - removal of clkdev aliases on Samsung SoCs
   - convert clk-gpio to use gpio descriptors
   - various driver cleanups to match kernel coding style
   - Amlogic Video Processing Unit VPU and VAPB clks
   - sigma-delta modulation for Allwinner audio PLLs
   - Allwinner A83t Display clks
   - support for the second display unit clock on Renesas RZ/G1E
   - suspend/resume support for Renesas R-Car Gen3 CPG/MSSR
   - new clock ids for Rockchip rk3188 and rk3368 SoCs
   - various 'const' markings on clk_ops structures
   - RPM clk support on Qualcomm MSM8996/MSM8660 SoCs"

* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (137 commits)
  clk: stm32h7: fix test of clock config
  clk: pxa: fix building on older compilers
  clk: sunxi-ng: a83t: Fix i2c buses bits
  clk: ti: dra7-atl-clock: fix child-node lookups
  clk: qcom: common: fix legacy board-clock registration
  clk: uniphier: fix DAPLL2 clock rate of Pro5
  clk: uniphier: fix parent of miodmac clock data
  clk: hi3798cv200: correct parent mux clock for 'clk_sdio0_ciu'
  clk: hisilicon: Delete an error message for a failed memory allocation in hisi_register_clkgate_sep()
  clk: hi3660: fix incorrect uart3 clock freqency
  clk: kona-setup: Delete error messages for failed memory allocations
  ARC: clk: fix spelling mistake: "configurarion" -> "configuration"
  clk: cdce925: remove redundant check for non-null parent_name
  clk: versatile: Improve sizeof() usage
  clk: versatile: Delete error messages for failed memory allocations
  clk: ux500: Improve sizeof() usage
  clk: ux500: Delete error messages for failed memory allocations
  clk: spear: Delete error messages for failed memory allocations
  clk: ti: Delete error messages for failed memory allocations
  clk: mmp: Adjust checks for NULL pointers
  ...

185 files changed:
Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,jpgdecsys.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mediatek/mediatek,mcucfg.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
Documentation/devicetree/bindings/clock/exynos4-clock.txt
Documentation/devicetree/bindings/clock/exynos5433-clock.txt
Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt
Documentation/driver-model/devres.txt
MAINTAINERS
drivers/clk/at91/clk-utmi.c
drivers/clk/bcm/clk-kona-setup.c
drivers/clk/clk-cdce925.c
drivers/clk/clk-gpio.c
drivers/clk/clk-hsdk-pll.c
drivers/clk/clk-mux.c
drivers/clk/clk-stm32h7.c
drivers/clk/clk-twl6040.c
drivers/clk/clk-u300.c
drivers/clk/clk-wm831x.c
drivers/clk/clk-xgene.c
drivers/clk/clk.c
drivers/clk/hisilicon/clk-hi3620.c
drivers/clk/hisilicon/clk-hi3660.c
drivers/clk/hisilicon/clk-hi6220.c
drivers/clk/hisilicon/clk-hix5hd2.c
drivers/clk/hisilicon/clkgate-separated.c
drivers/clk/hisilicon/crg-hi3798cv200.c
drivers/clk/imx/clk-busy.c
drivers/clk/imx/clk-gate2.c
drivers/clk/imx/clk-imx6q.c
drivers/clk/imx/clk-imx6ul.c
drivers/clk/imx/clk-imx7d.c
drivers/clk/imx/clk-pllv1.c
drivers/clk/imx/clk-pllv2.c
drivers/clk/mediatek/Kconfig
drivers/clk/mediatek/Makefile
drivers/clk/mediatek/clk-mt2701.c
drivers/clk/mediatek/clk-mt2712-bdp.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt2712-img.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt2712-jpgdec.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt2712-mfg.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt2712-mm.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt2712-vdec.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt2712-venc.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt2712.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt7622-aud.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt7622-eth.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt7622-hif.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt7622.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mtk.h
drivers/clk/mediatek/clk-pll.c
drivers/clk/meson/gxbb.c
drivers/clk/meson/gxbb.h
drivers/clk/mmp/clk-apbc.c
drivers/clk/mmp/clk-apmu.c
drivers/clk/mmp/clk-frac.c
drivers/clk/mmp/clk-gate.c
drivers/clk/mmp/clk-mix.c
drivers/clk/mmp/clk-mmp2.c
drivers/clk/mmp/clk-pxa168.c
drivers/clk/mmp/clk-pxa910.c
drivers/clk/mxs/clk-div.c
drivers/clk/mxs/clk-frac.c
drivers/clk/pxa/clk-pxa.c
drivers/clk/qcom/clk-rcg.h
drivers/clk/qcom/clk-rcg2.c
drivers/clk/qcom/clk-rpm.c
drivers/clk/qcom/clk-smd-rpm.c
drivers/clk/qcom/common.c
drivers/clk/renesas/Kconfig
drivers/clk/renesas/Makefile
drivers/clk/renesas/clk-div6.c
drivers/clk/renesas/clk-div6.h
drivers/clk/renesas/clk-mstp.c
drivers/clk/renesas/clk-rcar-gen2.c
drivers/clk/renesas/clk-rz.c
drivers/clk/renesas/r8a7745-cpg-mssr.c
drivers/clk/renesas/r8a7795-cpg-mssr.c
drivers/clk/renesas/r8a7796-cpg-mssr.c
drivers/clk/renesas/r8a77970-cpg-mssr.c [new file with mode: 0644]
drivers/clk/renesas/r8a77995-cpg-mssr.c
drivers/clk/renesas/rcar-gen2-cpg.c
drivers/clk/renesas/rcar-gen2-cpg.h
drivers/clk/renesas/rcar-gen3-cpg.c
drivers/clk/renesas/rcar-gen3-cpg.h
drivers/clk/renesas/renesas-cpg-mssr.c
drivers/clk/renesas/renesas-cpg-mssr.h
drivers/clk/rockchip/clk-cpu.c
drivers/clk/rockchip/clk-rk3188.c
drivers/clk/rockchip/clk-rk3368.c
drivers/clk/samsung/Makefile
drivers/clk/samsung/clk-cpu.c
drivers/clk/samsung/clk-exynos-audss.c
drivers/clk/samsung/clk-exynos-clkout.c
drivers/clk/samsung/clk-exynos4.c
drivers/clk/samsung/clk-exynos4412-isp.c [new file with mode: 0644]
drivers/clk/samsung/clk-exynos5250.c
drivers/clk/samsung/clk-exynos5420.c
drivers/clk/samsung/clk-exynos5433.c
drivers/clk/samsung/clk-exynos5440.c
drivers/clk/samsung/clk-pll.c
drivers/clk/samsung/clk-s3c2443.c
drivers/clk/samsung/clk.c
drivers/clk/samsung/clk.h
drivers/clk/sirf/clk-atlas6.c
drivers/clk/sirf/clk-atlas7.c
drivers/clk/sirf/clk-common.c
drivers/clk/sirf/clk-prima2.c
drivers/clk/spear/clk-aux-synth.c
drivers/clk/spear/clk-frac-synth.c
drivers/clk/spear/clk-gpt-synth.c
drivers/clk/spear/clk-vco-pll.c
drivers/clk/spear/clk.h
drivers/clk/spear/spear1310_clock.c
drivers/clk/spear/spear1340_clock.c
drivers/clk/sunxi-ng/Makefile
drivers/clk/sunxi-ng/ccu-sun4i-a10.c
drivers/clk/sunxi-ng/ccu-sun4i-a10.h
drivers/clk/sunxi-ng/ccu-sun5i.c
drivers/clk/sunxi-ng/ccu-sun6i-a31.c
drivers/clk/sunxi-ng/ccu-sun6i-a31.h
drivers/clk/sunxi-ng/ccu-sun8i-a23.c
drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
drivers/clk/sunxi-ng/ccu-sun8i-de2.c
drivers/clk/sunxi-ng/ccu-sun8i-h3.c
drivers/clk/sunxi-ng/ccu_common.h
drivers/clk/sunxi-ng/ccu_nm.c
drivers/clk/sunxi-ng/ccu_nm.h
drivers/clk/sunxi-ng/ccu_reset.c
drivers/clk/sunxi-ng/ccu_sdm.c [new file with mode: 0644]
drivers/clk/sunxi-ng/ccu_sdm.h [new file with mode: 0644]
drivers/clk/sunxi/clk-factors.c
drivers/clk/sunxi/clk-sun9i-mmc.c
drivers/clk/tegra/clk-bpmp.c
drivers/clk/tegra/clk-dfll.c
drivers/clk/tegra/clk-dfll.h
drivers/clk/tegra/clk-id.h
drivers/clk/tegra/clk-periph.c
drivers/clk/tegra/clk-tegra-periph.c
drivers/clk/tegra/clk-tegra-super-gen4.c
drivers/clk/tegra/clk-tegra114.c
drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
drivers/clk/tegra/clk-tegra20.c
drivers/clk/tegra/clk-tegra210.c
drivers/clk/tegra/clk-tegra30.c
drivers/clk/tegra/clk.h
drivers/clk/ti/clk-dra7-atl.c
drivers/clk/ti/divider.c
drivers/clk/ti/mux.c
drivers/clk/uniphier/clk-uniphier-mio.c
drivers/clk/uniphier/clk-uniphier-sys.c
drivers/clk/ux500/clk-prcc.c
drivers/clk/ux500/clk-prcmu.c
drivers/clk/ux500/clk-sysctrl.c
drivers/clk/versatile/clk-icst.c
include/dt-bindings/clock/exynos4.h
include/dt-bindings/clock/gxbb-clkc.h
include/dt-bindings/clock/imx7d-clock.h
include/dt-bindings/clock/mt2712-clk.h [new file with mode: 0644]
include/dt-bindings/clock/mt7622-clk.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,rpmcc.h
include/dt-bindings/clock/r8a77970-cpg-mssr.h [new file with mode: 0644]
include/dt-bindings/clock/s3c2443.h
include/dt-bindings/clock/sun4i-a10-ccu.h
include/dt-bindings/clock/sun6i-a31-ccu.h
include/linux/clk-provider.h
include/linux/soc/qcom/smd-rpm.h
include/soc/at91/atmel-sfr.h

index cd977db7630c50a6e118e60edd96256efa138ac9..b404d592ce58a6f129b6d652482b85c2ebbab21f 100644 (file)
@@ -7,7 +7,9 @@ Required Properties:
 
 - compatible: Should be one of:
        - "mediatek,mt2701-apmixedsys"
+       - "mediatek,mt2712-apmixedsys", "syscon"
        - "mediatek,mt6797-apmixedsys"
+       - "mediatek,mt7622-apmixedsys"
        - "mediatek,mt8135-apmixedsys"
        - "mediatek,mt8173-apmixedsys"
 - #clock-cells: Must be 1
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
new file mode 100644 (file)
index 0000000..9b8f578
--- /dev/null
@@ -0,0 +1,22 @@
+MediaTek AUDSYS controller
+============================
+
+The MediaTek AUDSYS controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be one of:
+       - "mediatek,mt7622-audsys", "syscon"
+- #clock-cells: Must be 1
+
+The AUDSYS controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+audsys: audsys@11220000 {
+       compatible = "mediatek,mt7622-audsys", "syscon";
+       reg = <0 0x11220000 0 0x1000>;
+       #clock-cells = <1>;
+};
index 4137196dd686fc0648d3a785c2b3462ac47c11cd..4010e37c53a0218554edfb5885262a168ba73108 100644 (file)
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: Should be:
        - "mediatek,mt2701-bdpsys", "syscon"
+       - "mediatek,mt2712-bdpsys", "syscon"
 - #clock-cells: Must be 1
 
 The bdpsys controller uses the common clk binding from
index 768f3a5bc05521a6bd3bc34e1b7311f2366e794f..7aa3fa167668f424464f8f9fe12078ea08f0bc0b 100644 (file)
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: Should be:
        - "mediatek,mt2701-ethsys", "syscon"
+       - "mediatek,mt7622-ethsys", "syscon"
 - #clock-cells: Must be 1
 
 The ethsys controller uses the common clk binding from
index beed7b594ceaab959185f97acfa6feff7a7e2e55..f5629d64cef2d2dfa218dabb7646abd50b135a08 100644 (file)
@@ -8,6 +8,7 @@ Required Properties:
 
 - compatible: Should be:
        - "mediatek,mt2701-hifsys", "syscon"
+       - "mediatek,mt7622-hifsys", "syscon"
 - #clock-cells: Must be 1
 
 The hifsys controller uses the common clk binding from
index 047b11ae5f45c0a7e020a231a4e87ce656b3842e..868bd51a98befcb5d901bf67995525e9dceb8173 100644 (file)
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: Should be one of:
        - "mediatek,mt2701-imgsys", "syscon"
+       - "mediatek,mt2712-imgsys", "syscon"
        - "mediatek,mt6797-imgsys", "syscon"
        - "mediatek,mt8173-imgsys", "syscon"
 - #clock-cells: Must be 1
index 58d58e2006b83324502d3d39739ab6537552649b..566f153f9f83b29ef7677ea7cd8412486e4154d4 100644 (file)
@@ -8,7 +8,9 @@ Required Properties:
 
 - compatible: Should be one of:
        - "mediatek,mt2701-infracfg", "syscon"
+       - "mediatek,mt2712-infracfg", "syscon"
        - "mediatek,mt6797-infracfg", "syscon"
+       - "mediatek,mt7622-infracfg", "syscon"
        - "mediatek,mt8135-infracfg", "syscon"
        - "mediatek,mt8173-infracfg", "syscon"
 - #clock-cells: Must be 1
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,jpgdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,jpgdecsys.txt
new file mode 100644 (file)
index 0000000..2df799c
--- /dev/null
@@ -0,0 +1,22 @@
+Mediatek jpgdecsys controller
+============================
+
+The Mediatek jpgdecsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+       - "mediatek,mt2712-jpgdecsys", "syscon"
+- #clock-cells: Must be 1
+
+The jpgdecsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+jpgdecsys: syscon@19000000 {
+       compatible = "mediatek,mt2712-jpgdecsys", "syscon";
+       reg = <0 0x19000000 0 0x1000>;
+       #clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mcucfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mcucfg.txt
new file mode 100644 (file)
index 0000000..b8fb03f
--- /dev/null
@@ -0,0 +1,22 @@
+Mediatek mcucfg controller
+============================
+
+The Mediatek mcucfg controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be one of:
+       - "mediatek,mt2712-mcucfg", "syscon"
+- #clock-cells: Must be 1
+
+The mcucfg controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+mcucfg: syscon@10220000 {
+       compatible = "mediatek,mt2712-mcucfg", "syscon";
+       reg = <0 0x10220000 0 0x1000>;
+       #clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt
new file mode 100644 (file)
index 0000000..859e67b
--- /dev/null
@@ -0,0 +1,22 @@
+Mediatek mfgcfg controller
+============================
+
+The Mediatek mfgcfg controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be one of:
+       - "mediatek,mt2712-mfgcfg", "syscon"
+- #clock-cells: Must be 1
+
+The mfgcfg controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+mfgcfg: syscon@13000000 {
+       compatible = "mediatek,mt2712-mfgcfg", "syscon";
+       reg = <0 0x13000000 0 0x1000>;
+       #clock-cells = <1>;
+};
index 70529e0b58e9a15927a552ada8106434c1627100..4eb8bbe15c01cd4828a75a9acb1d8913e231e515 100644 (file)
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: Should be one of:
        - "mediatek,mt2701-mmsys", "syscon"
+       - "mediatek,mt2712-mmsys", "syscon"
        - "mediatek,mt6797-mmsys", "syscon"
        - "mediatek,mt8173-mmsys", "syscon"
 - #clock-cells: Must be 1
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
new file mode 100644 (file)
index 0000000..d5d5f12
--- /dev/null
@@ -0,0 +1,22 @@
+MediaTek PCIESYS controller
+============================
+
+The MediaTek PCIESYS controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+       - "mediatek,mt7622-pciesys", "syscon"
+- #clock-cells: Must be 1
+
+The PCIESYS controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+pciesys: pciesys@1a100800 {
+       compatible = "mediatek,mt7622-pciesys", "syscon";
+       reg = <0 0x1a100800 0 0x1000>;
+       #clock-cells = <1>;
+};
index e494366782aaf79e1a092be3dd701dd2c22b5a37..fb58ca8c2770b5924baf3b624fb6828260553a0d 100644 (file)
@@ -8,6 +8,8 @@ Required Properties:
 
 - compatible: Should be one of:
        - "mediatek,mt2701-pericfg", "syscon"
+       - "mediatek,mt2712-pericfg", "syscon"
+       - "mediatek,mt7622-pericfg", "syscon"
        - "mediatek,mt8135-pericfg", "syscon"
        - "mediatek,mt8173-pericfg", "syscon"
 - #clock-cells: Must be 1
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
new file mode 100644 (file)
index 0000000..d113b8e
--- /dev/null
@@ -0,0 +1,22 @@
+MediaTek SGMIISYS controller
+============================
+
+The MediaTek SGMIISYS controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+       - "mediatek,mt7622-sgmiisys", "syscon"
+- #clock-cells: Must be 1
+
+The SGMIISYS controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+sgmiisys: sgmiisys@1b128000 {
+       compatible = "mediatek,mt7622-sgmiisys", "syscon";
+       reg = <0 0x1b128000 0 0x1000>;
+       #clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
new file mode 100644 (file)
index 0000000..0076001
--- /dev/null
@@ -0,0 +1,22 @@
+MediaTek SSUSBSYS controller
+============================
+
+The MediaTek SSUSBSYS controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+       - "mediatek,mt7622-ssusbsys", "syscon"
+- #clock-cells: Must be 1
+
+The SSUSBSYS controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+ssusbsys: ssusbsys@1a000000 {
+       compatible = "mediatek,mt7622-ssusbsys", "syscon";
+       reg = <0 0x1a000000 0 0x1000>;
+       #clock-cells = <1>;
+};
index ec93ecbb9f3c2fb72bf461d8d57275d8c57ac79a..24014a7e2332370202fcbf2ffc31ede87df571f8 100644 (file)
@@ -7,7 +7,9 @@ Required Properties:
 
 - compatible: Should be one of:
        - "mediatek,mt2701-topckgen"
+       - "mediatek,mt2712-topckgen", "syscon"
        - "mediatek,mt6797-topckgen"
+       - "mediatek,mt7622-topckgen"
        - "mediatek,mt8135-topckgen"
        - "mediatek,mt8173-topckgen"
 - #clock-cells: Must be 1
index d150104f928a4f7c023a724a3e646eb11b49d83a..ea40d05089f8306b2b15e2b0cd304ef61b8f8602 100644 (file)
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: Should be one of:
        - "mediatek,mt2701-vdecsys", "syscon"
+       - "mediatek,mt2712-vdecsys", "syscon"
        - "mediatek,mt6797-vdecsys", "syscon"
        - "mediatek,mt8173-vdecsys", "syscon"
 - #clock-cells: Must be 1
index 8a93be643647d429c39ba3c978e6e1a02f94d1c4..851545357e94af7f3ec4a96ac882cded0d166d7e 100644 (file)
@@ -6,6 +6,7 @@ The Mediatek vencsys controller provides various clocks to the system.
 Required Properties:
 
 - compatible: Should be one of:
+       - "mediatek,mt2712-vencsys", "syscon"
        - "mediatek,mt6797-vencsys", "syscon"
        - "mediatek,mt8173-vencsys", "syscon"
 - #clock-cells: Must be 1
index 2cba012f5af07690f9019ebc4e8097d60d5a69c6..6030afb10b5c15558dfd27ed40f55d4f12171ec6 100644 (file)
@@ -33,6 +33,12 @@ Required Properties:
 - clock-names: Aliases for the above clocks. They should be "pll_ref",
   "pll_in", "cdclk", "sclk_audio", and "sclk_pcm_in" respectively.
 
+Optional Properties:
+
+  - power-domains: a phandle to respective power domain node as described by
+    generic PM domain bindings (see power/power_domain.txt for more
+    information).
+
 The following is the list of clocks generated by the controller. Each clock is
 assigned an identifier and client nodes use this identifier to specify the
 clock which they consume. Some of the clocks are available only on a particular
index f5a5b19ed3b23bfd11631b9c14641e2ba3c484e3..bc61c952cb0b7221ccd47c099199d06598daf91e 100644 (file)
@@ -41,3 +41,46 @@ Example 2: UART controller node that consumes the clock generated by the clock
                clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
                clock-names = "uart", "clk_uart_baud0";
        };
+
+Exynos4412 SoC contains some additional clocks for FIMC-ISP (Camera ISP)
+subsystem. Registers for those clocks are located in the ISP power domain.
+Because those registers are also located in a different memory region than
+the main clock controller, a separate clock controller has to be defined for
+handling them.
+
+Required Properties:
+
+- compatible: should be "samsung,exynos4412-isp-clock".
+
+- reg: physical base address of the ISP clock controller and length of memory
+  mapped region.
+
+- #clock-cells: should be 1.
+
+- clocks: list of the clock controller input clock identifiers,
+  from common clock bindings, should point to CLK_ACLK200 and
+  CLK_ACLK400_MCUISP clocks from the main clock controller.
+
+- clock-names: list of the clock controller input clock names,
+  as described in clock-bindings.txt, should be "aclk200" and
+  "aclk400_mcuisp".
+
+- power-domains: a phandle to ISP power domain node as described by
+  generic PM domain bindings.
+
+Example 3: The clock controllers bindings for Exynos4412 SoCs.
+
+       clock: clock-controller@10030000 {
+               compatible = "samsung,exynos4412-clock";
+               reg = <0x10030000 0x18000>;
+               #clock-cells = <1>;
+       };
+
+       isp_clock: clock-controller@10048000 {
+               compatible = "samsung,exynos4412-isp-clock";
+               reg = <0x10048000 0x1000>;
+               #clock-cells = <1>;
+               power-domains = <&pd_isp>;
+               clocks = <&clock CLK_ACLK200>, <&clock CLK_ACLK400_MCUISP>;
+               clock-names = "aclk200", "aclk400_mcuisp";
+       };
index fe885abc9cb44874b2e7b7d42d6118a7a0828533..c473dd38dd550ccc03d9fc219095dc9257007376 100644 (file)
@@ -168,6 +168,11 @@ Required Properties:
                - aclk_cam1_400
                - aclk_cam1_552
 
+Optional properties:
+  - power-domains: a phandle to respective power domain node as described by
+       generic PM domain bindings (see power/power_domain.txt for more
+       information).
+
 Each clock is assigned an identifier and client nodes can use this identifier
 to specify the clock which they consume.
 
@@ -270,6 +275,7 @@ Example 2: Examples of clock controller nodes are listed below.
                clocks = <&xxti>,
                       <&cmu_top CLK_ACLK_G2D_266>,
                       <&cmu_top CLK_ACLK_G2D_400>;
+               power-domains = <&pd_g2d>;
        };
 
        cmu_disp: clock-controller@13b90000 {
@@ -295,6 +301,7 @@ Example 2: Examples of clock controller nodes are listed below.
                       <&cmu_mif CLK_SCLK_DECON_ECLK_DISP>,
                       <&cmu_mif CLK_SCLK_DECON_TV_VCLK_DISP>,
                       <&cmu_mif CLK_ACLK_DISP_333>;
+               power-domains = <&pd_disp>;
        };
 
        cmu_aud: clock-controller@114c0000 {
@@ -304,6 +311,7 @@ Example 2: Examples of clock controller nodes are listed below.
 
                clock-names = "oscclk", "fout_aud_pll";
                clocks = <&xxti>, <&cmu_top CLK_FOUT_AUD_PLL>;
+               power-domains = <&pd_aud>;
        };
 
        cmu_bus0: clock-controller@13600000 {
@@ -340,6 +348,7 @@ Example 2: Examples of clock controller nodes are listed below.
 
                clock-names = "oscclk", "aclk_g3d_400";
                clocks = <&xxti>, <&cmu_top CLK_ACLK_G3D_400>;
+               power-domains = <&pd_g3d>;
        };
 
        cmu_gscl: clock-controller@13cf0000 {
@@ -353,6 +362,7 @@ Example 2: Examples of clock controller nodes are listed below.
                clocks = <&xxti>,
                        <&cmu_top CLK_ACLK_GSCL_111>,
                        <&cmu_top CLK_ACLK_GSCL_333>;
+               power-domains = <&pd_gscl>;
        };
 
        cmu_apollo: clock-controller@11900000 {
@@ -384,6 +394,7 @@ Example 2: Examples of clock controller nodes are listed below.
                clocks = <&xxti>,
                       <&cmu_top CLK_SCLK_JPEG_MSCL>,
                       <&cmu_top CLK_ACLK_MSCL_400>;
+               power-domains = <&pd_mscl>;
        };
 
        cmu_mfc: clock-controller@15280000 {
@@ -393,6 +404,7 @@ Example 2: Examples of clock controller nodes are listed below.
 
                clock-names = "oscclk", "aclk_mfc_400";
                clocks = <&xxti>, <&cmu_top CLK_ACLK_MFC_400>;
+               power-domains = <&pd_mfc>;
        };
 
        cmu_hevc: clock-controller@14f80000 {
@@ -402,6 +414,7 @@ Example 2: Examples of clock controller nodes are listed below.
 
                clock-names = "oscclk", "aclk_hevc_400";
                clocks = <&xxti>, <&cmu_top CLK_ACLK_HEVC_400>;
+               power-domains = <&pd_hevc>;
        };
 
        cmu_isp: clock-controller@146d0000 {
@@ -415,6 +428,7 @@ Example 2: Examples of clock controller nodes are listed below.
                clocks = <&xxti>,
                       <&cmu_top CLK_ACLK_ISP_DIS_400>,
                       <&cmu_top CLK_ACLK_ISP_400>;
+               power-domains = <&pd_isp>;
        };
 
        cmu_cam0: clock-controller@120d0000 {
@@ -430,6 +444,7 @@ Example 2: Examples of clock controller nodes are listed below.
                       <&cmu_top CLK_ACLK_CAM0_333>,
                       <&cmu_top CLK_ACLK_CAM0_400>,
                       <&cmu_top CLK_ACLK_CAM0_552>;
+               power-domains = <&pd_cam0>;
        };
 
        cmu_cam1: clock-controller@145d0000 {
@@ -451,6 +466,7 @@ Example 2: Examples of clock controller nodes are listed below.
                       <&cmu_top CLK_ACLK_CAM1_333>,
                       <&cmu_top CLK_ACLK_CAM1_400>,
                       <&cmu_top CLK_ACLK_CAM1_552>;
+               power-domains = <&pd_cam1>;
        };
 
 Example 3: UART controller node that consumes the clock generated by the clock
index a7235e9e1c97d38fdc9ff95a036c403dfb583b28..4491d1c104aacd3b41e73856338c81afc9722f36 100644 (file)
@@ -10,12 +10,23 @@ Required properties :
 - compatible : shall contain only one of the following. The generic
                compatible "qcom,rpmcc" should be also included.
 
+                       "qcom,rpmcc-msm8660", "qcom,rpmcc"
+                       "qcom,rpmcc-apq8060", "qcom,rpmcc"
                        "qcom,rpmcc-msm8916", "qcom,rpmcc"
                        "qcom,rpmcc-msm8974", "qcom,rpmcc"
                        "qcom,rpmcc-apq8064", "qcom,rpmcc"
+                       "qcom,rpmcc-msm8996", "qcom,rpmcc"
 
 - #clock-cells : shall contain 1
 
+The clock enumerators are defined in <dt-bindings/clock/qcom,rpmcc.h>
+and come in pairs: FOO_CLK followed by FOO_A_CLK. The latter clock
+is an "active" clock, which means that the consumer only care that the
+clock is available when the apps CPU subsystem is active, i.e. not
+suspended or in deep idle. If it is important that the clock keeps running
+during system suspend, you need to specify the non-active clock, the one
+not containing *_A_* in the enumerator name.
+
 Example:
        smd {
                compatible = "qcom,smd";
index 316e136865688b7c4fe0c6f1d7b23934d66634d1..f1890d0777a6cc25462d308311b5722a19c21c4d 100644 (file)
@@ -22,6 +22,7 @@ Required Properties:
       - "renesas,r8a7794-cpg-mssr" for the r8a7794 SoC (R-Car E2)
       - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3)
       - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W)
+      - "renesas,r8a77970-cpg-mssr" for the r8a77970 SoC (R-Car V3M)
       - "renesas,r8a77995-cpg-mssr" for the r8a77995 SoC (R-Car D3)
 
   - reg: Base address and length of the memory resource used by the CPG/MSSR
@@ -31,8 +32,8 @@ Required Properties:
     clock-names
   - clock-names: List of external parent clock names. Valid names are:
       - "extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794,
-                r8a7795, r8a7796, r8a77995)
-      - "extalr" (r8a7795, r8a7796)
+                r8a7795, r8a7796, r8a77970, r8a77995)
+      - "extalr" (r8a7795, r8a7796, r8a77970)
       - "usb_extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7793, r8a7794)
 
   - #clock-cells: Must be 2
index bb5d942075fbf0bf18fb9d924f34e3508fcf4298..8ff3e2774ed8d1d0fd46cbf5895346f62252c5b0 100644 (file)
@@ -1,6 +1,6 @@
-* Renesas RZ Clock Pulse Generator (CPG)
+* Renesas RZ/A1 Clock Pulse Generator (CPG)
 
-The CPG generates core clocks for the RZ SoCs. It includes the PLL, variable
+The CPG generates core clocks for the RZ/A1 SoCs. It includes the PLL, variable
 CPU and GPU clocks, and several fixed ratio dividers.
 The CPG also provides a Clock Domain for SoC devices, in combination with the
 CPG Module Stop (MSTP) Clocks.
index 69f08c0f23a8eb8706a35f43d338061cdaa61868..c180045eb43b190beccc1072a7285f6f5de5bf34 100644 (file)
@@ -237,6 +237,7 @@ CLOCK
   devm_clk_get()
   devm_clk_put()
   devm_clk_hw_register()
+  devm_of_clk_add_hw_provider()
 
 DMA
   dmam_alloc_coherent()
index bcab816b25f49ae0a6d721da76453606bbe585d3..16137acd7f2fdb856951e0873273c180580cd2b0 100644 (file)
@@ -11543,6 +11543,7 @@ F:      include/linux/rpmsg/
 RENESAS CLOCK DRIVERS
 M:     Geert Uytterhoeven <geert+renesas@glider.be>
 L:     linux-renesas-soc@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git clk-renesas
 S:     Supported
 F:     drivers/clk/renesas/
 
index aadabd9d1e2b68d69d9cd491a5fab7037747515b..cd8d689138ff9917822aec3416a101bd0eb665c6 100644 (file)
 #include <linux/of.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
+#include <soc/at91/atmel-sfr.h>
 
 #include "pmc.h"
 
-#define UTMI_FIXED_MUL         40
+/*
+ * The purpose of this clock is to generate a 480 MHz signal. A different
+ * rate can't be configured.
+ */
+#define UTMI_RATE      480000000
 
 struct clk_utmi {
        struct clk_hw hw;
-       struct regmap *regmap;
+       struct regmap *regmap_pmc;
+       struct regmap *regmap_sfr;
 };
 
 #define to_clk_utmi(hw) container_of(hw, struct clk_utmi, hw)
@@ -37,13 +43,54 @@ static inline bool clk_utmi_ready(struct regmap *regmap)
 
 static int clk_utmi_prepare(struct clk_hw *hw)
 {
+       struct clk_hw *hw_parent;
        struct clk_utmi *utmi = to_clk_utmi(hw);
        unsigned int uckr = AT91_PMC_UPLLEN | AT91_PMC_UPLLCOUNT |
                            AT91_PMC_BIASEN;
+       unsigned int utmi_ref_clk_freq;
+       unsigned long parent_rate;
+
+       /*
+        * If mainck rate is different from 12 MHz, we have to configure the
+        * FREQ field of the SFR_UTMICKTRIM register to generate properly
+        * the utmi clock.
+        */
+       hw_parent = clk_hw_get_parent(hw);
+       parent_rate = clk_hw_get_rate(hw_parent);
+
+       switch (parent_rate) {
+       case 12000000:
+               utmi_ref_clk_freq = 0;
+               break;
+       case 16000000:
+               utmi_ref_clk_freq = 1;
+               break;
+       case 24000000:
+               utmi_ref_clk_freq = 2;
+               break;
+       /*
+        * Not supported on SAMA5D2 but it's not an issue since MAINCK
+        * maximum value is 24 MHz.
+        */
+       case 48000000:
+               utmi_ref_clk_freq = 3;
+               break;
+       default:
+               pr_err("UTMICK: unsupported mainck rate\n");
+               return -EINVAL;
+       }
 
-       regmap_update_bits(utmi->regmap, AT91_CKGR_UCKR, uckr, uckr);
+       if (utmi->regmap_sfr) {
+               regmap_update_bits(utmi->regmap_sfr, AT91_SFR_UTMICKTRIM,
+                                  AT91_UTMICKTRIM_FREQ, utmi_ref_clk_freq);
+       } else if (utmi_ref_clk_freq) {
+               pr_err("UTMICK: sfr node required\n");
+               return -EINVAL;
+       }
 
-       while (!clk_utmi_ready(utmi->regmap))
+       regmap_update_bits(utmi->regmap_pmc, AT91_CKGR_UCKR, uckr, uckr);
+
+       while (!clk_utmi_ready(utmi->regmap_pmc))
                cpu_relax();
 
        return 0;
@@ -53,21 +100,22 @@ static int clk_utmi_is_prepared(struct clk_hw *hw)
 {
        struct clk_utmi *utmi = to_clk_utmi(hw);
 
-       return clk_utmi_ready(utmi->regmap);
+       return clk_utmi_ready(utmi->regmap_pmc);
 }
 
 static void clk_utmi_unprepare(struct clk_hw *hw)
 {
        struct clk_utmi *utmi = to_clk_utmi(hw);
 
-       regmap_update_bits(utmi->regmap, AT91_CKGR_UCKR, AT91_PMC_UPLLEN, 0);
+       regmap_update_bits(utmi->regmap_pmc, AT91_CKGR_UCKR,
+                          AT91_PMC_UPLLEN, 0);
 }
 
 static unsigned long clk_utmi_recalc_rate(struct clk_hw *hw,
                                          unsigned long parent_rate)
 {
-       /* UTMI clk is a fixed clk multiplier */
-       return parent_rate * UTMI_FIXED_MUL;
+       /* UTMI clk rate is fixed. */
+       return UTMI_RATE;
 }
 
 static const struct clk_ops utmi_ops = {
@@ -78,7 +126,7 @@ static const struct clk_ops utmi_ops = {
 };
 
 static struct clk_hw * __init
-at91_clk_register_utmi(struct regmap *regmap,
+at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
                       const char *name, const char *parent_name)
 {
        struct clk_utmi *utmi;
@@ -97,7 +145,8 @@ at91_clk_register_utmi(struct regmap *regmap,
        init.flags = CLK_SET_RATE_GATE;
 
        utmi->hw.init = &init;
-       utmi->regmap = regmap;
+       utmi->regmap_pmc = regmap_pmc;
+       utmi->regmap_sfr = regmap_sfr;
 
        hw = &utmi->hw;
        ret = clk_hw_register(NULL, &utmi->hw);
@@ -114,17 +163,35 @@ static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
        struct clk_hw *hw;
        const char *parent_name;
        const char *name = np->name;
-       struct regmap *regmap;
+       struct regmap *regmap_pmc, *regmap_sfr;
 
        parent_name = of_clk_get_parent_name(np, 0);
 
        of_property_read_string(np, "clock-output-names", &name);
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
+       regmap_pmc = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap_pmc))
                return;
 
-       hw = at91_clk_register_utmi(regmap, name, parent_name);
+       /*
+        * If the device supports different mainck rates, this value has to be
+        * set in the UTMI Clock Trimming register.
+        * - 9x5: mainck supports several rates but it is indicated that a
+        *   12 MHz is needed in case of USB.
+        * - sama5d3 and sama5d2: mainck supports several rates. Configuring
+        *   the FREQ field of the UTMI Clock Trimming register is mandatory.
+        * - sama5d4: mainck is at 12 MHz.
+        *
+        * We only need to retrieve sama5d3 or sama5d2 sfr regmap.
+        */
+       regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d3-sfr");
+       if (IS_ERR(regmap_sfr)) {
+               regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
+               if (IS_ERR(regmap_sfr))
+                       regmap_sfr = NULL;
+       }
+
+       hw = at91_clk_register_utmi(regmap_pmc, regmap_sfr, name, parent_name);
        if (IS_ERR(hw))
                return;
 
index c37a7f0e83aafc881e54f32a82f868ae346f6eb1..281f4322355c135eded2fc5533a54498a0f0f49f 100644 (file)
@@ -579,18 +579,13 @@ static u32 *parent_process(const char *clocks[],
         */
        parent_names = kmalloc_array(parent_count, sizeof(*parent_names),
                               GFP_KERNEL);
-       if (!parent_names) {
-               pr_err("%s: error allocating %u parent names\n", __func__,
-                               parent_count);
+       if (!parent_names)
                return ERR_PTR(-ENOMEM);
-       }
 
        /* There is at least one parent, so allocate a selector array */
        parent_sel = kmalloc_array(parent_count, sizeof(*parent_sel),
                                   GFP_KERNEL);
        if (!parent_sel) {
-               pr_err("%s: error allocating %u parent selectors\n", __func__,
-                               parent_count);
                kfree(parent_names);
 
                return ERR_PTR(-ENOMEM);
index c933be01c7db66f999331b9d187c1125682b127e..0a7e7d5a750605c5be12d953ac912f3fb9105962 100644 (file)
@@ -665,7 +665,7 @@ static int cdce925_probe(struct i2c_client *client,
        init.ops = &cdce925_pll_ops;
        init.flags = 0;
        init.parent_names = &parent_name;
-       init.num_parents = parent_name ? 1 : 0;
+       init.num_parents = 1;
 
        /* Register PLL clocks */
        for (i = 0; i < data->chip_info->num_plls; ++i) {
index 86b245746a6bad5895b267101268124e5050c4b9..151513c655c3c24becbded77921ff3b290630671 100644 (file)
@@ -15,9 +15,7 @@
 #include <linux/clk-provider.h>
 #include <linux/export.h>
 #include <linux/slab.h>
-#include <linux/gpio.h>
 #include <linux/gpio/consumer.h>
-#include <linux/of_gpio.h>
 #include <linux/err.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
@@ -95,14 +93,12 @@ const struct clk_ops clk_gpio_mux_ops = {
 EXPORT_SYMBOL_GPL(clk_gpio_mux_ops);
 
 static struct clk_hw *clk_register_gpio(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents, unsigned gpio,
-               bool active_low, unsigned long flags,
-               const struct clk_ops *clk_gpio_ops)
+               const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
+               unsigned long flags, const struct clk_ops *clk_gpio_ops)
 {
        struct clk_gpio *clk_gpio;
        struct clk_hw *hw;
        struct clk_init_data init = {};
-       unsigned long gpio_flags;
        int err;
 
        if (dev)
@@ -113,32 +109,13 @@ static struct clk_hw *clk_register_gpio(struct device *dev, const char *name,
        if (!clk_gpio)
                return ERR_PTR(-ENOMEM);
 
-       if (active_low)
-               gpio_flags = GPIOF_ACTIVE_LOW | GPIOF_OUT_INIT_HIGH;
-       else
-               gpio_flags = GPIOF_OUT_INIT_LOW;
-
-       if (dev)
-               err = devm_gpio_request_one(dev, gpio, gpio_flags, name);
-       else
-               err = gpio_request_one(gpio, gpio_flags, name);
-       if (err) {
-               if (err != -EPROBE_DEFER)
-                       pr_err("%s: %s: Error requesting clock control gpio %u\n",
-                                       __func__, name, gpio);
-               if (!dev)
-                       kfree(clk_gpio);
-
-               return ERR_PTR(err);
-       }
-
        init.name = name;
        init.ops = clk_gpio_ops;
        init.flags = flags | CLK_IS_BASIC;
        init.parent_names = parent_names;
        init.num_parents = num_parents;
 
-       clk_gpio->gpiod = gpio_to_desc(gpio);
+       clk_gpio->gpiod = gpiod;
        clk_gpio->hw.init = &init;
 
        hw = &clk_gpio->hw;
@@ -151,7 +128,6 @@ static struct clk_hw *clk_register_gpio(struct device *dev, const char *name,
                return hw;
 
        if (!dev) {
-               gpiod_put(clk_gpio->gpiod);
                kfree(clk_gpio);
        }
 
@@ -164,29 +140,27 @@ static struct clk_hw *clk_register_gpio(struct device *dev, const char *name,
  * @dev: device that is registering this clock
  * @name: name of this clock
  * @parent_name: name of this clock's parent
- * @gpio: gpio number to gate this clock
- * @active_low: true if gpio should be set to 0 to enable clock
+ * @gpiod: gpio descriptor to gate this clock
  * @flags: clock flags
  */
 struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
-               const char *parent_name, unsigned gpio, bool active_low,
+               const char *parent_name, struct gpio_desc *gpiod,
                unsigned long flags)
 {
        return clk_register_gpio(dev, name,
                        (parent_name ? &parent_name : NULL),
-                       (parent_name ? 1 : 0), gpio, active_low, flags,
+                       (parent_name ? 1 : 0), gpiod, flags,
                        &clk_gpio_gate_ops);
 }
 EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate);
 
 struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
-               const char *parent_name, unsigned gpio, bool active_low,
+               const char *parent_name, struct gpio_desc *gpiod,
                unsigned long flags)
 {
        struct clk_hw *hw;
 
-       hw = clk_hw_register_gpio_gate(dev, name, parent_name, gpio, active_low,
-                                      flags);
+       hw = clk_hw_register_gpio_gate(dev, name, parent_name, gpiod, flags);
        if (IS_ERR(hw))
                return ERR_CAST(hw);
        return hw->clk;
@@ -199,13 +173,12 @@ EXPORT_SYMBOL_GPL(clk_register_gpio_gate);
  * @name: name of this clock
  * @parent_names: names of this clock's parents
  * @num_parents: number of parents listed in @parent_names
- * @gpio: gpio number to gate this clock
- * @active_low: true if gpio should be set to 0 to enable clock
+ * @gpiod: gpio descriptor to gate this clock
  * @flags: clock flags
  */
 struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents, unsigned gpio,
-               bool active_low, unsigned long flags)
+               const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
+               unsigned long flags)
 {
        if (num_parents != 2) {
                pr_err("mux-clock %s must have 2 parents\n", name);
@@ -213,18 +186,18 @@ struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
        }
 
        return clk_register_gpio(dev, name, parent_names, num_parents,
-                       gpio, active_low, flags, &clk_gpio_mux_ops);
+                       gpiod, flags, &clk_gpio_mux_ops);
 }
 EXPORT_SYMBOL_GPL(clk_hw_register_gpio_mux);
 
 struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents, unsigned gpio,
-               bool active_low, unsigned long flags)
+               const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
+               unsigned long flags)
 {
        struct clk_hw *hw;
 
        hw = clk_hw_register_gpio_mux(dev, name, parent_names, num_parents,
-                       gpio, active_low, flags);
+                       gpiod, flags);
        if (IS_ERR(hw))
                return ERR_CAST(hw);
        return hw->clk;
@@ -236,10 +209,10 @@ static int gpio_clk_driver_probe(struct platform_device *pdev)
        struct device_node *node = pdev->dev.of_node;
        const char **parent_names, *gpio_name;
        unsigned int num_parents;
-       int gpio;
-       enum of_gpio_flags of_flags;
+       struct gpio_desc *gpiod;
        struct clk *clk;
-       bool active_low, is_mux;
+       bool is_mux;
+       int ret;
 
        num_parents = of_clk_get_parent_count(node);
        if (num_parents) {
@@ -255,28 +228,27 @@ static int gpio_clk_driver_probe(struct platform_device *pdev)
 
        is_mux = of_device_is_compatible(node, "gpio-mux-clock");
 
-       gpio_name = is_mux ? "select-gpios" : "enable-gpios";
-       gpio = of_get_named_gpio_flags(node, gpio_name, 0, &of_flags);
-       if (gpio < 0) {
-               if (gpio == -EPROBE_DEFER)
+       gpio_name = is_mux ? "select" : "enable";
+       gpiod = devm_gpiod_get(&pdev->dev, gpio_name, GPIOD_OUT_LOW);
+       if (IS_ERR(gpiod)) {
+               ret = PTR_ERR(gpiod);
+               if (ret == -EPROBE_DEFER)
                        pr_debug("%s: %s: GPIOs not yet available, retry later\n",
                                        node->name, __func__);
                else
-                       pr_err("%s: %s: Can't get '%s' DT property\n",
+                       pr_err("%s: %s: Can't get '%s' named GPIO property\n",
                                        node->name, __func__,
                                        gpio_name);
-               return gpio;
+               return ret;
        }
 
-       active_low = of_flags & OF_GPIO_ACTIVE_LOW;
-
        if (is_mux)
                clk = clk_register_gpio_mux(&pdev->dev, node->name,
-                               parent_names, num_parents, gpio, active_low, 0);
+                               parent_names, num_parents, gpiod, 0);
        else
                clk = clk_register_gpio_gate(&pdev->dev, node->name,
-                               parent_names ?  parent_names[0] : NULL, gpio,
-                               active_low, 0);
+                               parent_names ?  parent_names[0] : NULL, gpiod,
+                               0);
        if (IS_ERR(clk))
                return PTR_ERR(clk);
 
index bbf237173b37bff255b3d00cfc60016c1a9e93f3..c4ee280f454d9213b2bd1a82ac576e7fd790fb42 100644 (file)
@@ -139,7 +139,7 @@ static inline void hsdk_pll_set_cfg(struct hsdk_pll_clk *clk,
        val |= cfg->odiv << CGU_PLL_CTRL_ODIV_SHIFT;
        val |= cfg->band << CGU_PLL_CTRL_BAND_SHIFT;
 
-       dev_dbg(clk->dev, "write configurarion: %#x\n", val);
+       dev_dbg(clk->dev, "write configuration: %#x\n", val);
 
        hsdk_pll_write(clk, CGU_PLL_CTRL, val);
 }
@@ -169,7 +169,7 @@ static unsigned long hsdk_pll_recalc_rate(struct clk_hw *hw,
 
        val = hsdk_pll_read(clk, CGU_PLL_CTRL);
 
-       dev_dbg(clk->dev, "current configurarion: %#x\n", val);
+       dev_dbg(clk->dev, "current configuration: %#x\n", val);
 
        /* Check if PLL is disabled */
        if (val & CGU_PLL_CTRL_PD)
index 16a3d5717f4edc371da411168276371f0a656cac..39cabe157163b9b0dd3498c65a242fe1614253ee 100644 (file)
@@ -134,11 +134,9 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
        }
 
        /* allocate the mux */
-       mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
-       if (!mux) {
-               pr_err("%s: could not allocate mux clk\n", __func__);
+       mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+       if (!mux)
                return ERR_PTR(-ENOMEM);
-       }
 
        init.name = name;
        if (clk_mux_flags & CLK_MUX_READ_ONLY)
index a94c3f56c590967743fade8e4912ab8f8a4cd2b2..61c3e40507d31846db8ea23dd745cd47a3e01872 100644 (file)
@@ -384,7 +384,7 @@ static void get_cfg_composite_div(const struct composite_clk_gcfg *gcfg,
        mux_ops = div_ops = gate_ops = NULL;
        mux_hw = div_hw = gate_hw = NULL;
 
-       if (gcfg->mux && gcfg->mux) {
+       if (gcfg->mux && cfg->mux) {
                mux = _get_cmux(base + cfg->mux->offset,
                                cfg->mux->shift,
                                cfg->mux->width,
@@ -410,7 +410,7 @@ static void get_cfg_composite_div(const struct composite_clk_gcfg *gcfg,
                }
        }
 
-       if (gcfg->gate && gcfg->gate) {
+       if (gcfg->gate && cfg->gate) {
                gate = _get_cgate(base + cfg->gate->offset,
                                cfg->gate->bit_idx,
                                gcfg->gate->flags, lock);
index 7b222a5db9319b46efe373e6fb859b412457a510..25dfe050ae9f8d3dae9cb393a94590dfad52c7dd 100644 (file)
@@ -82,7 +82,7 @@ static const struct clk_ops twl6040_pdmclk_ops = {
        .recalc_rate = twl6040_pdmclk_recalc_rate,
 };
 
-static struct clk_init_data twl6040_pdmclk_init = {
+static const struct clk_init_data twl6040_pdmclk_init = {
        .name = "pdmclk",
        .ops = &twl6040_pdmclk_ops,
        .flags = CLK_GET_RATE_NOCACHE,
index ec8aafda6e243216b523f6630cf1a148f254c49a..7b3e1921771fa236d19401094eccbc4b63d0f231 100644 (file)
 #define U300_SYSCON_S0CCR_CLOCK_FREQ_MASK                      (0x01E0)
 #define U300_SYSCON_S0CCR_CLOCK_SELECT_MASK                    (0x001E)
 #define U300_SYSCON_S0CCR_CLOCK_ENABLE                         (0x0001)
-#define U300_SYSCON_S0CCR_SEL_MCLK                             (0x8<<1)
-#define U300_SYSCON_S0CCR_SEL_ACC_FSM_CLK                      (0xA<<1)
-#define U300_SYSCON_S0CCR_SEL_PLL60_48_CLK                     (0xC<<1)
-#define U300_SYSCON_S0CCR_SEL_PLL60_60_CLK                     (0xD<<1)
-#define U300_SYSCON_S0CCR_SEL_ACC_PLL208_CLK                   (0xE<<1)
-#define U300_SYSCON_S0CCR_SEL_APP_PLL13_CLK                    (0x0<<1)
-#define U300_SYSCON_S0CCR_SEL_APP_FSM_CLK                      (0x2<<1)
-#define U300_SYSCON_S0CCR_SEL_RTC_CLK                          (0x4<<1)
-#define U300_SYSCON_S0CCR_SEL_APP_PLL208_CLK                   (0x6<<1)
+#define U300_SYSCON_S0CCR_SEL_MCLK                             (0x8 << 1)
+#define U300_SYSCON_S0CCR_SEL_ACC_FSM_CLK                      (0xA << 1)
+#define U300_SYSCON_S0CCR_SEL_PLL60_48_CLK                     (0xC << 1)
+#define U300_SYSCON_S0CCR_SEL_PLL60_60_CLK                     (0xD << 1)
+#define U300_SYSCON_S0CCR_SEL_ACC_PLL208_CLK                   (0xE << 1)
+#define U300_SYSCON_S0CCR_SEL_APP_PLL13_CLK                    (0x0 << 1)
+#define U300_SYSCON_S0CCR_SEL_APP_FSM_CLK                      (0x2 << 1)
+#define U300_SYSCON_S0CCR_SEL_RTC_CLK                          (0x4 << 1)
+#define U300_SYSCON_S0CCR_SEL_APP_PLL208_CLK                   (0x6 << 1)
 /* SYS_1_CLK_CONTROL second clock control 16 bit (R/W) */
 #define U300_SYSCON_S1CCR                                      (0x124)
 #define U300_SYSCON_S1CCR_FIELD_MASK                           (0x43FF)
 #define U300_SYSCON_S1CCR_CLOCK_FREQ_MASK                      (0x01E0)
 #define U300_SYSCON_S1CCR_CLOCK_SELECT_MASK                    (0x001E)
 #define U300_SYSCON_S1CCR_CLOCK_ENABLE                         (0x0001)
-#define U300_SYSCON_S1CCR_SEL_MCLK                             (0x8<<1)
-#define U300_SYSCON_S1CCR_SEL_ACC_FSM_CLK                      (0xA<<1)
-#define U300_SYSCON_S1CCR_SEL_PLL60_48_CLK                     (0xC<<1)
-#define U300_SYSCON_S1CCR_SEL_PLL60_60_CLK                     (0xD<<1)
-#define U300_SYSCON_S1CCR_SEL_ACC_PLL208_CLK                   (0xE<<1)
-#define U300_SYSCON_S1CCR_SEL_ACC_PLL13_CLK                    (0x0<<1)
-#define U300_SYSCON_S1CCR_SEL_APP_FSM_CLK                      (0x2<<1)
-#define U300_SYSCON_S1CCR_SEL_RTC_CLK                          (0x4<<1)
-#define U300_SYSCON_S1CCR_SEL_APP_PLL208_CLK                   (0x6<<1)
-/* SYS_2_CLK_CONTROL third clock contol 16 bit (R/W) */
+#define U300_SYSCON_S1CCR_SEL_MCLK                             (0x8 << 1)
+#define U300_SYSCON_S1CCR_SEL_ACC_FSM_CLK                      (0xA << 1)
+#define U300_SYSCON_S1CCR_SEL_PLL60_48_CLK                     (0xC << 1)
+#define U300_SYSCON_S1CCR_SEL_PLL60_60_CLK                     (0xD << 1)
+#define U300_SYSCON_S1CCR_SEL_ACC_PLL208_CLK                   (0xE << 1)
+#define U300_SYSCON_S1CCR_SEL_ACC_PLL13_CLK                    (0x0 << 1)
+#define U300_SYSCON_S1CCR_SEL_APP_FSM_CLK                      (0x2 << 1)
+#define U300_SYSCON_S1CCR_SEL_RTC_CLK                          (0x4 << 1)
+#define U300_SYSCON_S1CCR_SEL_APP_PLL208_CLK                   (0x6 << 1)
+/* SYS_2_CLK_CONTROL third clock control 16 bit (R/W) */
 #define U300_SYSCON_S2CCR                                      (0x128)
 #define U300_SYSCON_S2CCR_FIELD_MASK                           (0xC3FF)
 #define U300_SYSCON_S2CCR_CLK_STEAL                            (0x8000)
 #define U300_SYSCON_S2CCR_CLOCK_FREQ_MASK                      (0x01E0)
 #define U300_SYSCON_S2CCR_CLOCK_SELECT_MASK                    (0x001E)
 #define U300_SYSCON_S2CCR_CLOCK_ENABLE                         (0x0001)
-#define U300_SYSCON_S2CCR_SEL_MCLK                             (0x8<<1)
-#define U300_SYSCON_S2CCR_SEL_ACC_FSM_CLK                      (0xA<<1)
-#define U300_SYSCON_S2CCR_SEL_PLL60_48_CLK                     (0xC<<1)
-#define U300_SYSCON_S2CCR_SEL_PLL60_60_CLK                     (0xD<<1)
-#define U300_SYSCON_S2CCR_SEL_ACC_PLL208_CLK                   (0xE<<1)
-#define U300_SYSCON_S2CCR_SEL_ACC_PLL13_CLK                    (0x0<<1)
-#define U300_SYSCON_S2CCR_SEL_APP_FSM_CLK                      (0x2<<1)
-#define U300_SYSCON_S2CCR_SEL_RTC_CLK                          (0x4<<1)
-#define U300_SYSCON_S2CCR_SEL_APP_PLL208_CLK                   (0x6<<1)
+#define U300_SYSCON_S2CCR_SEL_MCLK                             (0x8 << 1)
+#define U300_SYSCON_S2CCR_SEL_ACC_FSM_CLK                      (0xA << 1)
+#define U300_SYSCON_S2CCR_SEL_PLL60_48_CLK                     (0xC << 1)
+#define U300_SYSCON_S2CCR_SEL_PLL60_60_CLK                     (0xD << 1)
+#define U300_SYSCON_S2CCR_SEL_ACC_PLL208_CLK                   (0xE << 1)
+#define U300_SYSCON_S2CCR_SEL_ACC_PLL13_CLK                    (0x0 << 1)
+#define U300_SYSCON_S2CCR_SEL_APP_FSM_CLK                      (0x2 << 1)
+#define U300_SYSCON_S2CCR_SEL_RTC_CLK                          (0x4 << 1)
+#define U300_SYSCON_S2CCR_SEL_APP_PLL208_CLK                   (0x6 << 1)
 /* SC_PLL_IRQ_CONTROL 16bit (R/W) */
 #define U300_SYSCON_PICR                                       (0x0130)
 #define U300_SYSCON_PICR_MASK                                  (0x00FF)
  *  +- ISP Image Signal Processor (U335 only)
  *  +- CDS (U335 only)
  *  +- DMA Direct Memory Access Controller
- *  +- AAIF APP/ACC Inteface (Mobile Scalable Link, MSL)
+ *  +- AAIF APP/ACC Interface (Mobile Scalable Link, MSL)
  *  +- APEX
  *  +- VIDEO_ENC AVE2/3 Video Encoder
  *  +- XGAM Graphics Accelerator Controller
@@ -568,14 +568,14 @@ syscon_clk_recalc_rate(struct clk_hw *hw,
        struct clk_syscon *sclk = to_syscon(hw);
        u16 perf = syscon_get_perf();
 
-       switch(sclk->clk_val) {
+       switch (sclk->clk_val) {
        case U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN:
        case U300_SYSCON_SBCER_I2C0_CLK_EN:
        case U300_SYSCON_SBCER_I2C1_CLK_EN:
        case U300_SYSCON_SBCER_MMC_CLK_EN:
        case U300_SYSCON_SBCER_SPI_CLK_EN:
                /* The FAST clocks have one progression */
-               switch(perf) {
+               switch (perf) {
                case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
                case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
                        return 13000000;
@@ -586,7 +586,7 @@ syscon_clk_recalc_rate(struct clk_hw *hw,
        case U300_SYSCON_SBCER_NANDIF_CLK_EN:
        case U300_SYSCON_SBCER_XGAM_CLK_EN:
                /* AMBA interconnect peripherals */
-               switch(perf) {
+               switch (perf) {
                case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
                case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
                        return 6500000;
@@ -598,7 +598,7 @@ syscon_clk_recalc_rate(struct clk_hw *hw,
        case U300_SYSCON_SBCER_SEMI_CLK_EN:
        case U300_SYSCON_SBCER_EMIF_CLK_EN:
                /* EMIF speeds */
-               switch(perf) {
+               switch (perf) {
                case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
                case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
                        return 13000000;
@@ -609,7 +609,7 @@ syscon_clk_recalc_rate(struct clk_hw *hw,
                }
        case U300_SYSCON_SBCER_CPU_CLK_EN:
                /* And the fast CPU clock */
-               switch(perf) {
+               switch (perf) {
                case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
                case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
                        return 13000000;
@@ -702,12 +702,10 @@ syscon_clk_register(struct device *dev, const char *name,
        struct clk_init_data init;
        int ret;
 
-       sclk = kzalloc(sizeof(struct clk_syscon), GFP_KERNEL);
-       if (!sclk) {
-               pr_err("could not allocate syscon clock %s\n",
-                       name);
+       sclk = kzalloc(sizeof(*sclk), GFP_KERNEL);
+       if (!sclk)
                return ERR_PTR(-ENOMEM);
-       }
+
        init.name = name;
        init.ops = &syscon_clk_ops;
        init.flags = flags;
@@ -1123,12 +1121,10 @@ mclk_clk_register(struct device *dev, const char *name,
        struct clk_init_data init;
        int ret;
 
-       mclk = kzalloc(sizeof(struct clk_mclk), GFP_KERNEL);
-       if (!mclk) {
-               pr_err("could not allocate MMC/SD clock %s\n",
-                      name);
+       mclk = kzalloc(sizeof(*mclk), GFP_KERNEL);
+       if (!mclk)
                return ERR_PTR(-ENOMEM);
-       }
+
        init.name = "mclk";
        init.ops = &mclk_ops;
        init.flags = 0;
index a47960aacfa52c30749787ea3cb1a3d35b0576d0..146769532325cafa3e922ebf4681318d82797736 100644 (file)
@@ -52,7 +52,7 @@ static const struct clk_ops wm831x_xtal_ops = {
        .recalc_rate = wm831x_xtal_recalc_rate,
 };
 
-static struct clk_init_data wm831x_xtal_init = {
+static const struct clk_init_data wm831x_xtal_init = {
        .name = "xtal",
        .ops = &wm831x_xtal_ops,
 };
@@ -225,7 +225,7 @@ static const struct clk_ops wm831x_fll_ops = {
        .get_parent = wm831x_fll_get_parent,
 };
 
-static struct clk_init_data wm831x_fll_init = {
+static const struct clk_init_data wm831x_fll_init = {
        .name = "fll",
        .ops = &wm831x_fll_ops,
        .parent_names = wm831x_fll_parents,
@@ -338,7 +338,7 @@ static const struct clk_ops wm831x_clkout_ops = {
        .set_parent = wm831x_clkout_set_parent,
 };
 
-static struct clk_init_data wm831x_clkout_init = {
+static const struct clk_init_data wm831x_clkout_init = {
        .name = "clkout",
        .ops = &wm831x_clkout_ops,
        .parent_names = wm831x_clkout_parents,
index 4c75821a3933c26cd1c0582ce7ae13b145836f40..531b030d4d4e7392cd827b9c9f40f5293d59b1f2 100644 (file)
@@ -146,10 +146,8 @@ static struct clk *xgene_register_clk_pll(struct device *dev,
 
        /* allocate the APM clock structure */
        apmclk = kzalloc(sizeof(*apmclk), GFP_KERNEL);
-       if (!apmclk) {
-               pr_err("%s: could not allocate APM clk\n", __func__);
+       if (!apmclk)
                return ERR_PTR(-ENOMEM);
-       }
 
        init.name = name;
        init.ops = &xgene_clk_pll_ops;
@@ -191,7 +189,7 @@ static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_ty
        int version = xgene_pllclk_version(np);
 
        reg = of_iomap(np, 0);
-       if (reg == NULL) {
+       if (!reg) {
                pr_err("Unable to map CSR register for %pOF\n", np);
                return;
        }
@@ -467,7 +465,7 @@ static int xgene_clk_enable(struct clk_hw *hw)
        if (pclk->lock)
                spin_lock_irqsave(pclk->lock, flags);
 
-       if (pclk->param.csr_reg != NULL) {
+       if (pclk->param.csr_reg) {
                pr_debug("%s clock enabled\n", clk_hw_get_name(hw));
                /* First enable the clock */
                data = xgene_clk_read(pclk->param.csr_reg +
@@ -507,7 +505,7 @@ static void xgene_clk_disable(struct clk_hw *hw)
        if (pclk->lock)
                spin_lock_irqsave(pclk->lock, flags);
 
-       if (pclk->param.csr_reg != NULL) {
+       if (pclk->param.csr_reg) {
                pr_debug("%s clock disabled\n", clk_hw_get_name(hw));
                /* First put the CSR in reset */
                data = xgene_clk_read(pclk->param.csr_reg +
@@ -533,7 +531,7 @@ static int xgene_clk_is_enabled(struct clk_hw *hw)
        struct xgene_clk *pclk = to_xgene_clk(hw);
        u32 data = 0;
 
-       if (pclk->param.csr_reg != NULL) {
+       if (pclk->param.csr_reg) {
                pr_debug("%s clock checking\n", clk_hw_get_name(hw));
                data = xgene_clk_read(pclk->param.csr_reg +
                                        pclk->param.reg_clk_offset);
@@ -542,7 +540,7 @@ static int xgene_clk_is_enabled(struct clk_hw *hw)
                                                        "disabled");
        }
 
-       if (pclk->param.csr_reg == NULL)
+       if (!pclk->param.csr_reg)
                return 1;
        return data & pclk->param.reg_clk_mask ? 1 : 0;
 }
@@ -650,10 +648,8 @@ static struct clk *xgene_register_clk(struct device *dev,
 
        /* allocate the APM clock structure */
        apmclk = kzalloc(sizeof(*apmclk), GFP_KERNEL);
-       if (!apmclk) {
-               pr_err("%s: could not allocate APM clk\n", __func__);
+       if (!apmclk)
                return ERR_PTR(-ENOMEM);
-       }
 
        init.name = name;
        init.ops = &xgene_clk_ops;
@@ -709,7 +705,7 @@ static void __init xgene_devclk_init(struct device_node *np)
                        break;
                }
                map_res = of_iomap(np, i);
-               if (map_res == NULL) {
+               if (!map_res) {
                        pr_err("Unable to map resource %d for %pOF\n", i, np);
                        goto err;
                }
index c8d83acda0061977218d1fd084bc6faddff4091c..647d056df88c8dd2a7d8288e35fa2eeba9b7705b 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/of.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/pm_runtime.h>
 #include <linux/sched.h>
 #include <linux/clkdev.h>
 
@@ -46,6 +47,7 @@ struct clk_core {
        const struct clk_ops    *ops;
        struct clk_hw           *hw;
        struct module           *owner;
+       struct device           *dev;
        struct clk_core         *parent;
        const char              **parent_names;
        struct clk_core         **parents;
@@ -87,6 +89,26 @@ struct clk {
        struct hlist_node clks_node;
 };
 
+/***           runtime pm          ***/
+static int clk_pm_runtime_get(struct clk_core *core)
+{
+       int ret = 0;
+
+       if (!core->dev)
+               return 0;
+
+       ret = pm_runtime_get_sync(core->dev);
+       return ret < 0 ? ret : 0;
+}
+
+static void clk_pm_runtime_put(struct clk_core *core)
+{
+       if (!core->dev)
+               return;
+
+       pm_runtime_put_sync(core->dev);
+}
+
 /***           locking             ***/
 static void clk_prepare_lock(void)
 {
@@ -150,6 +172,8 @@ static void clk_enable_unlock(unsigned long flags)
 
 static bool clk_core_is_prepared(struct clk_core *core)
 {
+       bool ret = false;
+
        /*
         * .is_prepared is optional for clocks that can prepare
         * fall back to software usage counter if it is missing
@@ -157,11 +181,18 @@ static bool clk_core_is_prepared(struct clk_core *core)
        if (!core->ops->is_prepared)
                return core->prepare_count;
 
-       return core->ops->is_prepared(core->hw);
+       if (!clk_pm_runtime_get(core)) {
+               ret = core->ops->is_prepared(core->hw);
+               clk_pm_runtime_put(core);
+       }
+
+       return ret;
 }
 
 static bool clk_core_is_enabled(struct clk_core *core)
 {
+       bool ret = false;
+
        /*
         * .is_enabled is only mandatory for clocks that gate
         * fall back to software usage counter if .is_enabled is missing
@@ -169,7 +200,29 @@ static bool clk_core_is_enabled(struct clk_core *core)
        if (!core->ops->is_enabled)
                return core->enable_count;
 
-       return core->ops->is_enabled(core->hw);
+       /*
+        * Check if clock controller's device is runtime active before
+        * calling .is_enabled callback. If not, assume that clock is
+        * disabled, because we might be called from atomic context, from
+        * which pm_runtime_get() is not allowed.
+        * This function is called mainly from clk_disable_unused_subtree,
+        * which ensures proper runtime pm activation of controller before
+        * taking enable spinlock, but the below check is needed if one tries
+        * to call it from other places.
+        */
+       if (core->dev) {
+               pm_runtime_get_noresume(core->dev);
+               if (!pm_runtime_active(core->dev)) {
+                       ret = false;
+                       goto done;
+               }
+       }
+
+       ret = core->ops->is_enabled(core->hw);
+done:
+       clk_pm_runtime_put(core);
+
+       return ret;
 }
 
 /***    helper functions   ***/
@@ -489,6 +542,8 @@ static void clk_core_unprepare(struct clk_core *core)
        if (core->ops->unprepare)
                core->ops->unprepare(core->hw);
 
+       clk_pm_runtime_put(core);
+
        trace_clk_unprepare_complete(core);
        clk_core_unprepare(core->parent);
 }
@@ -530,10 +585,14 @@ static int clk_core_prepare(struct clk_core *core)
                return 0;
 
        if (core->prepare_count == 0) {
-               ret = clk_core_prepare(core->parent);
+               ret = clk_pm_runtime_get(core);
                if (ret)
                        return ret;
 
+               ret = clk_core_prepare(core->parent);
+               if (ret)
+                       goto runtime_put;
+
                trace_clk_prepare(core);
 
                if (core->ops->prepare)
@@ -541,15 +600,18 @@ static int clk_core_prepare(struct clk_core *core)
 
                trace_clk_prepare_complete(core);
 
-               if (ret) {
-                       clk_core_unprepare(core->parent);
-                       return ret;
-               }
+               if (ret)
+                       goto unprepare;
        }
 
        core->prepare_count++;
 
        return 0;
+unprepare:
+       clk_core_unprepare(core->parent);
+runtime_put:
+       clk_pm_runtime_put(core);
+       return ret;
 }
 
 static int clk_core_prepare_lock(struct clk_core *core)
@@ -745,6 +807,9 @@ static void clk_unprepare_unused_subtree(struct clk_core *core)
        if (core->flags & CLK_IGNORE_UNUSED)
                return;
 
+       if (clk_pm_runtime_get(core))
+               return;
+
        if (clk_core_is_prepared(core)) {
                trace_clk_unprepare(core);
                if (core->ops->unprepare_unused)
@@ -753,6 +818,8 @@ static void clk_unprepare_unused_subtree(struct clk_core *core)
                        core->ops->unprepare(core->hw);
                trace_clk_unprepare_complete(core);
        }
+
+       clk_pm_runtime_put(core);
 }
 
 static void clk_disable_unused_subtree(struct clk_core *core)
@@ -768,6 +835,9 @@ static void clk_disable_unused_subtree(struct clk_core *core)
        if (core->flags & CLK_OPS_PARENT_ENABLE)
                clk_core_prepare_enable(core->parent);
 
+       if (clk_pm_runtime_get(core))
+               goto unprepare_out;
+
        flags = clk_enable_lock();
 
        if (core->enable_count)
@@ -792,6 +862,8 @@ static void clk_disable_unused_subtree(struct clk_core *core)
 
 unlock_out:
        clk_enable_unlock(flags);
+       clk_pm_runtime_put(core);
+unprepare_out:
        if (core->flags & CLK_OPS_PARENT_ENABLE)
                clk_core_disable_unprepare(core->parent);
 }
@@ -1038,9 +1110,13 @@ EXPORT_SYMBOL_GPL(clk_get_accuracy);
 static unsigned long clk_recalc(struct clk_core *core,
                                unsigned long parent_rate)
 {
-       if (core->ops->recalc_rate)
-               return core->ops->recalc_rate(core->hw, parent_rate);
-       return parent_rate;
+       unsigned long rate = parent_rate;
+
+       if (core->ops->recalc_rate && !clk_pm_runtime_get(core)) {
+               rate = core->ops->recalc_rate(core->hw, parent_rate);
+               clk_pm_runtime_put(core);
+       }
+       return rate;
 }
 
 /**
@@ -1565,6 +1641,7 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
 {
        struct clk_core *top, *fail_clk;
        unsigned long rate = req_rate;
+       int ret = 0;
 
        if (!core)
                return 0;
@@ -1581,21 +1658,28 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
        if (!top)
                return -EINVAL;
 
+       ret = clk_pm_runtime_get(core);
+       if (ret)
+               return ret;
+
        /* notify that we are about to change rates */
        fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE);
        if (fail_clk) {
                pr_debug("%s: failed to set %s rate\n", __func__,
                                fail_clk->name);
                clk_propagate_rate_change(top, ABORT_RATE_CHANGE);
-               return -EBUSY;
+               ret = -EBUSY;
+               goto err;
        }
 
        /* change the rates */
        clk_change_rate(top);
 
        core->req_rate = req_rate;
+err:
+       clk_pm_runtime_put(core);
 
-       return 0;
+       return ret;
 }
 
 /**
@@ -1826,12 +1910,16 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
                p_rate = parent->rate;
        }
 
+       ret = clk_pm_runtime_get(core);
+       if (ret)
+               goto out;
+
        /* propagate PRE_RATE_CHANGE notifications */
        ret = __clk_speculate_rates(core, p_rate);
 
        /* abort if a driver objects */
        if (ret & NOTIFY_STOP_MASK)
-               goto out;
+               goto runtime_put;
 
        /* do the re-parent */
        ret = __clk_set_parent(core, parent, p_index);
@@ -1844,6 +1932,8 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
                __clk_recalc_accuracies(core);
        }
 
+runtime_put:
+       clk_pm_runtime_put(core);
 out:
        clk_prepare_unlock();
 
@@ -2350,7 +2440,7 @@ static inline void clk_debug_unregister(struct clk_core *core)
  */
 static int __clk_core_init(struct clk_core *core)
 {
-       int i, ret = 0;
+       int i, ret;
        struct clk_core *orphan;
        struct hlist_node *tmp2;
        unsigned long rate;
@@ -2360,6 +2450,10 @@ static int __clk_core_init(struct clk_core *core)
 
        clk_prepare_lock();
 
+       ret = clk_pm_runtime_get(core);
+       if (ret)
+               goto unlock;
+
        /* check to see if a clock with this name is already registered */
        if (clk_core_lookup(core->name)) {
                pr_debug("%s: clk %s already initialized\n",
@@ -2512,6 +2606,8 @@ static int __clk_core_init(struct clk_core *core)
 
        kref_init(&core->ref);
 out:
+       clk_pm_runtime_put(core);
+unlock:
        clk_prepare_unlock();
 
        if (!ret)
@@ -2583,6 +2679,8 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
                goto fail_name;
        }
        core->ops = hw->init->ops;
+       if (dev && pm_runtime_enabled(dev))
+               core->dev = dev;
        if (dev && dev->driver)
                core->owner = dev->driver->owner;
        core->hw = hw;
@@ -3177,6 +3275,37 @@ int of_clk_add_hw_provider(struct device_node *np,
 }
 EXPORT_SYMBOL_GPL(of_clk_add_hw_provider);
 
+static void devm_of_clk_release_provider(struct device *dev, void *res)
+{
+       of_clk_del_provider(*(struct device_node **)res);
+}
+
+int devm_of_clk_add_hw_provider(struct device *dev,
+                       struct clk_hw *(*get)(struct of_phandle_args *clkspec,
+                                             void *data),
+                       void *data)
+{
+       struct device_node **ptr, *np;
+       int ret;
+
+       ptr = devres_alloc(devm_of_clk_release_provider, sizeof(*ptr),
+                          GFP_KERNEL);
+       if (!ptr)
+               return -ENOMEM;
+
+       np = dev->of_node;
+       ret = of_clk_add_hw_provider(np, get, data);
+       if (!ret) {
+               *ptr = np;
+               devres_add(dev, ptr);
+       } else {
+               devres_free(ptr);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(devm_of_clk_add_hw_provider);
+
 /**
  * of_clk_del_provider() - Remove a previously registered clock provider
  * @np: Device node pointer associated with clock provider
@@ -3198,6 +3327,27 @@ void of_clk_del_provider(struct device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_clk_del_provider);
 
+static int devm_clk_provider_match(struct device *dev, void *res, void *data)
+{
+       struct device_node **np = res;
+
+       if (WARN_ON(!np || !*np))
+               return 0;
+
+       return *np == data;
+}
+
+void devm_of_clk_del_provider(struct device *dev)
+{
+       int ret;
+
+       ret = devres_release(dev, devm_of_clk_release_provider,
+                            devm_clk_provider_match, dev->of_node);
+
+       WARN_ON(ret);
+}
+EXPORT_SYMBOL(devm_of_clk_del_provider);
+
 static struct clk_hw *
 __of_clk_get_hw_from_provider(struct of_clk_provider *provider,
                              struct of_phandle_args *clkspec)
index fa0fba653898b462e6615549b1bd2e94553fffea..77072c7778b9ca5bae9c01592f4ef781f68b6f35 100644 (file)
@@ -415,7 +415,7 @@ static int mmc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
        return mmc_clk_set_timing(hw, rate);
 }
 
-static struct clk_ops clk_mmc_ops = {
+static const struct clk_ops clk_mmc_ops = {
        .prepare = mmc_clk_prepare,
        .determine_rate = mmc_clk_determine_rate,
        .set_rate = mmc_clk_set_rate,
index a18258eb89cb1b1767a5335b7bf8938e66fafab2..f404199596563e34f7b62eead4fc539f084ca79b 100644 (file)
@@ -34,7 +34,7 @@ static const struct hisi_fixed_rate_clock hi3660_fixed_rate_clks[] = {
 
 /* crgctrl */
 static const struct hisi_fixed_factor_clock hi3660_crg_fixed_factor_clks[] = {
-       { HI3660_FACTOR_UART3, "clk_factor_uart3", "iomcu_peri0", 1, 8, 0, },
+       { HI3660_FACTOR_UART3, "clk_factor_uart3", "iomcu_peri0", 1, 16, 0, },
        { HI3660_CLK_FACTOR_MMC, "clk_factor_mmc", "clkin_sys", 1, 6, 0, },
        { HI3660_CLK_GATE_I2C0, "clk_gate_i2c0", "clk_i2c0_iomcu", 1, 4, 0, },
        { HI3660_CLK_GATE_I2C1, "clk_gate_i2c1", "clk_i2c1_iomcu", 1, 4, 0, },
index e786d717f75dcf51383627988e22f5956fe74d6c..a87809d4bd525aad9ebffc7a9ef0f9c5a33752d8 100644 (file)
@@ -145,7 +145,7 @@ static struct hisi_gate_clock hi6220_separated_gate_clks_sys[] __initdata = {
        { HI6220_BBPPLL_SEL,    "bbppll_sel",    "pll0_bbp_gate",  CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x270, 9,  0, },
        { HI6220_MEDIA_PLL_SRC, "media_pll_src", "pll_media_gate", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x270, 10, 0, },
        { HI6220_MMC2_SEL,      "mmc2_sel",      "mmc2_mux1",      CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x270, 11, 0, },
-       { HI6220_CS_ATB_SYSPLL, "cs_atb_syspll", "syspll",         CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x270, 12, 0, },
+       { HI6220_CS_ATB_SYSPLL, "cs_atb_syspll", "syspll",         CLK_SET_RATE_PARENT|CLK_IS_CRITICAL,   0x270, 12, 0, },
 };
 
 static struct hisi_mux_clock hi6220_mux_clks_sys[] __initdata = {
index 14b05efa3c2ae4fca3b86e2afe270801074d066d..9584f0c32dda985528b65baa83ef646ff9654b81 100644 (file)
@@ -208,7 +208,7 @@ static void clk_ether_unprepare(struct clk_hw *hw)
        writel_relaxed(val, clk->ctrl_reg);
 }
 
-static struct clk_ops clk_ether_ops = {
+static const struct clk_ops clk_ether_ops = {
        .prepare = clk_ether_prepare,
        .unprepare = clk_ether_unprepare,
 };
@@ -247,7 +247,7 @@ static void clk_complex_disable(struct clk_hw *hw)
        writel_relaxed(val, clk->phy_reg);
 }
 
-static struct clk_ops clk_complex_ops = {
+static const struct clk_ops clk_complex_ops = {
        .enable = clk_complex_enable,
        .disable = clk_complex_disable,
 };
index 7908bc3c9ec73c0bbc498197d774bef5075797cf..f36bdef9183178f21f1a33327b4e8b586f611345 100644 (file)
@@ -88,7 +88,7 @@ static int clkgate_separated_is_enabled(struct clk_hw *hw)
        return reg ? 1 : 0;
 }
 
-static struct clk_ops clkgate_separated_ops = {
+static const struct clk_ops clkgate_separated_ops = {
        .enable         = clkgate_separated_enable,
        .disable        = clkgate_separated_disable,
        .is_enabled     = clkgate_separated_is_enabled,
@@ -105,10 +105,8 @@ struct clk *hisi_register_clkgate_sep(struct device *dev, const char *name,
        struct clk_init_data init;
 
        sclk = kzalloc(sizeof(*sclk), GFP_KERNEL);
-       if (!sclk) {
-               pr_err("%s: fail to allocate separated gated clk\n", __func__);
+       if (!sclk)
                return ERR_PTR(-ENOMEM);
-       }
 
        init.name = name;
        init.ops = &clkgate_separated_ops;
index ed8bb5f7507f2c22aa750367721dbfad8ed5355c..8478948e858e396b3797d99d926c0dfe754cd8fa 100644 (file)
@@ -47,6 +47,8 @@
 #define HI3798CV200_FIXED_12M  81
 #define HI3798CV200_FIXED_48M  82
 #define HI3798CV200_FIXED_60M  83
+#define HI3798CV200_FIXED_166P5M       84
+#define HI3798CV200_SDIO0_MUX  85
 
 #define HI3798CV200_CRG_NR_CLKS                128
 
@@ -63,6 +65,7 @@ static const struct hisi_fixed_rate_clock hi3798cv200_fixed_rate_clks[] = {
        { HI3798CV200_FIXED_75M, "75m", NULL, 0, 75000000, },
        { HI3798CV200_FIXED_100M, "100m", NULL, 0, 100000000, },
        { HI3798CV200_FIXED_150M, "150m", NULL, 0, 150000000, },
+       { HI3798CV200_FIXED_166P5M, "166p5m", NULL, 0, 165000000, },
        { HI3798CV200_FIXED_200M, "200m", NULL, 0, 200000000, },
        { HI3798CV200_FIXED_250M, "250m", NULL, 0, 250000000, },
 };
@@ -75,12 +78,19 @@ static const char *const comphy1_mux_p[] = {
                "100m", "25m"};
 static u32 comphy1_mux_table[] = {2, 3};
 
+static const char *const sdio_mux_p[] = {
+               "100m", "50m", "150m", "166p5m" };
+static u32 sdio_mux_table[] = {0, 1, 2, 3};
+
 static struct hisi_mux_clock hi3798cv200_mux_clks[] = {
        { HI3798CV200_MMC_MUX, "mmc_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p),
                CLK_SET_RATE_PARENT, 0xa0, 8, 3, 0, mmc_mux_table, },
        { HI3798CV200_COMBPHY1_MUX, "combphy1_mux",
                comphy1_mux_p, ARRAY_SIZE(comphy1_mux_p),
                CLK_SET_RATE_PARENT, 0x188, 10, 2, 0, comphy1_mux_table, },
+       { HI3798CV200_SDIO0_MUX, "sdio0_mux", sdio_mux_p,
+               ARRAY_SIZE(sdio_mux_p), CLK_SET_RATE_PARENT,
+               0x9c, 8, 2, 0, sdio_mux_table, },
 };
 
 static const struct hisi_gate_clock hi3798cv200_gate_clks[] = {
@@ -104,7 +114,7 @@ static const struct hisi_gate_clock hi3798cv200_gate_clks[] = {
        /* SDIO */
        { HISTB_SDIO0_BIU_CLK, "clk_sdio0_biu", "200m",
                        CLK_SET_RATE_PARENT, 0x9c, 0, 0, },
-       { HISTB_SDIO0_CIU_CLK, "clk_sdio0_ciu", "mmc_mux",
+       { HISTB_SDIO0_CIU_CLK, "clk_sdio0_ciu", "sdio0_mux",
                CLK_SET_RATE_PARENT, 0x9c, 1, 0, },
        /* EMMC */
        { HISTB_MMC_BIU_CLK, "clk_mmc_biu", "200m",
index 5cc99590f9a33a397bc1fc51ffaf821867aeb6e9..6df3389687bc0fe9e4afae264e3c825ea11bb35e 100644 (file)
@@ -72,7 +72,7 @@ static int clk_busy_divider_set_rate(struct clk_hw *hw, unsigned long rate,
        return ret;
 }
 
-static struct clk_ops clk_busy_divider_ops = {
+static const struct clk_ops clk_busy_divider_ops = {
        .recalc_rate = clk_busy_divider_recalc_rate,
        .round_rate = clk_busy_divider_round_rate,
        .set_rate = clk_busy_divider_set_rate,
@@ -147,7 +147,7 @@ static int clk_busy_mux_set_parent(struct clk_hw *hw, u8 index)
        return ret;
 }
 
-static struct clk_ops clk_busy_mux_ops = {
+static const struct clk_ops clk_busy_mux_ops = {
        .get_parent = clk_busy_mux_get_parent,
        .set_parent = clk_busy_mux_set_parent,
 };
index db44a198a0d9999f3e998033a3f8a517035c5e74..60fc9d7a9723959e4b13185d87405a1de8e455d3 100644 (file)
@@ -118,7 +118,7 @@ static void clk_gate2_disable_unused(struct clk_hw *hw)
        spin_unlock_irqrestore(gate->lock, flags);
 }
 
-static struct clk_ops clk_gate2_ops = {
+static const struct clk_ops clk_gate2_ops = {
        .enable = clk_gate2_enable,
        .disable = clk_gate2_disable,
        .disable_unused = clk_gate2_disable_unused,
index c07df719b8a35d16ed88014dcaca37c6d957d158..8d518ad5dc13e5a5c20436950ccf5f45837a5333 100644 (file)
@@ -761,7 +761,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24);
        clk[IMX6QDL_CLK_GPU3D_CORE]   = imx_clk_gate2("gpu3d_core",    "gpu3d_core_podf",   base + 0x6c, 26);
        clk[IMX6QDL_CLK_HDMI_IAHB]    = imx_clk_gate2("hdmi_iahb",     "ahb",               base + 0x70, 0);
-       clk[IMX6QDL_CLK_HDMI_ISFR]    = imx_clk_gate2("hdmi_isfr",     "video_27m",         base + 0x70, 4);
+       clk[IMX6QDL_CLK_HDMI_ISFR]    = imx_clk_gate2("hdmi_isfr",     "mipi_core_cfg",     base + 0x70, 4);
        clk[IMX6QDL_CLK_I2C1]         = imx_clk_gate2("i2c1",          "ipg_per",           base + 0x70, 6);
        clk[IMX6QDL_CLK_I2C2]         = imx_clk_gate2("i2c2",          "ipg_per",           base + 0x70, 8);
        clk[IMX6QDL_CLK_I2C3]         = imx_clk_gate2("i2c3",          "ipg_per",           base + 0x70, 10);
index 5e8c18afce9ad35742dd378cded8042abe80c922..85c1181644697153c7b52ddd417bbe7630c8b5b1 100644 (file)
@@ -267,7 +267,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
                clks[IMX6ULL_CLK_EPDC_SEL]        = imx_clk_mux("epdc_sel",     base + 0x34, 9, 3, epdc_sels, ARRAY_SIZE(epdc_sels));
        }
        clks[IMX6UL_CLK_ECSPI_SEL]        = imx_clk_mux("ecspi_sel",    base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
-       clks[IMX6UL_CLK_LCDIF_PRE_SEL]    = imx_clk_mux("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels));
+       clks[IMX6UL_CLK_LCDIF_PRE_SEL]    = imx_clk_mux_flags("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels), CLK_SET_RATE_PARENT);
        clks[IMX6UL_CLK_LCDIF_SEL]        = imx_clk_mux("lcdif_sel",    base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels));
 
        clks[IMX6UL_CLK_LDB_DI0_DIV_SEL]  = imx_clk_mux("ldb_di0", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels));
index 2305699db46798441c7c32ef8910b5fe3354c64a..80dc211eb74bbebe465c40d7bf30eb336d43af89 100644 (file)
@@ -54,11 +54,6 @@ static const char *arm_m4_sel[] = { "osc", "pll_sys_main_240m_clk",
        "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main_clk",
        "pll_usb_main_clk", };
 
-static const char *arm_m0_sel[] = { "osc", "pll_sys_main_120m_clk",
-       "pll_enet_125m_clk", "pll_sys_pfd2_135m_clk",
-       "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main_clk",
-       "pll_usb_main_clk", };
-
 static const char *axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
        "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd5_clk",
        "pll_audio_post_div", "pll_video_main_clk", "pll_sys_pfd7_clk", };
@@ -510,7 +505,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
 
        clks[IMX7D_ARM_A7_ROOT_SRC] = imx_clk_mux2("arm_a7_src", base + 0x8000, 24, 3, arm_a7_sel, ARRAY_SIZE(arm_a7_sel));
        clks[IMX7D_ARM_M4_ROOT_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, arm_m4_sel, ARRAY_SIZE(arm_m4_sel));
-       clks[IMX7D_ARM_M0_ROOT_SRC] = imx_clk_mux2("arm_m0_src", base + 0x8100, 24, 3, arm_m0_sel, ARRAY_SIZE(arm_m0_sel));
        clks[IMX7D_MAIN_AXI_ROOT_SRC] = imx_clk_mux2("axi_src", base + 0x8800, 24, 3, axi_sel, ARRAY_SIZE(axi_sel));
        clks[IMX7D_DISP_AXI_ROOT_SRC] = imx_clk_mux2("disp_axi_src", base + 0x8880, 24, 3, disp_axi_sel, ARRAY_SIZE(disp_axi_sel));
        clks[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_mux2("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel));
@@ -582,7 +576,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
 
        clks[IMX7D_ARM_A7_ROOT_CG] = imx_clk_gate3("arm_a7_cg", "arm_a7_src", base + 0x8000, 28);
        clks[IMX7D_ARM_M4_ROOT_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
-       clks[IMX7D_ARM_M0_ROOT_CG] = imx_clk_gate3("arm_m0_cg", "arm_m0_src", base + 0x8100, 28);
        clks[IMX7D_MAIN_AXI_ROOT_CG] = imx_clk_gate3("axi_cg", "axi_src", base + 0x8800, 28);
        clks[IMX7D_DISP_AXI_ROOT_CG] = imx_clk_gate3("disp_axi_cg", "disp_axi_src", base + 0x8880, 28);
        clks[IMX7D_ENET_AXI_ROOT_CG] = imx_clk_gate3("enet_axi_cg", "enet_axi_src", base + 0x8900, 28);
@@ -721,7 +714,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
 
        clks[IMX7D_ARM_A7_ROOT_DIV] = imx_clk_divider2("arm_a7_div", "arm_a7_cg", base + 0x8000, 0, 3);
        clks[IMX7D_ARM_M4_ROOT_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
-       clks[IMX7D_ARM_M0_ROOT_DIV] = imx_clk_divider2("arm_m0_div", "arm_m0_cg", base + 0x8100, 0, 3);
        clks[IMX7D_MAIN_AXI_ROOT_DIV] = imx_clk_divider2("axi_post_div", "axi_pre_div", base + 0x8800, 0, 6);
        clks[IMX7D_DISP_AXI_ROOT_DIV] = imx_clk_divider2("disp_axi_post_div", "disp_axi_pre_div", base + 0x8880, 0, 6);
        clks[IMX7D_ENET_AXI_ROOT_DIV] = imx_clk_divider2("enet_axi_post_div", "enet_axi_pre_div", base + 0x8900, 0, 6);
@@ -793,11 +785,10 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
 
        clks[IMX7D_ARM_A7_ROOT_CLK] = imx_clk_gate4("arm_a7_root_clk", "arm_a7_div", base + 0x4000, 0);
        clks[IMX7D_ARM_M4_ROOT_CLK] = imx_clk_gate4("arm_m4_root_clk", "arm_m4_div", base + 0x4010, 0);
-       clks[IMX7D_ARM_M0_ROOT_CLK] = imx_clk_gate4("arm_m0_root_clk", "arm_m0_div", base + 0x4020, 0);
        clks[IMX7D_MAIN_AXI_ROOT_CLK] = imx_clk_gate4("main_axi_root_clk", "axi_post_div", base + 0x4040, 0);
        clks[IMX7D_DISP_AXI_ROOT_CLK] = imx_clk_gate4("disp_axi_root_clk", "disp_axi_post_div", base + 0x4050, 0);
        clks[IMX7D_ENET_AXI_ROOT_CLK] = imx_clk_gate4("enet_axi_root_clk", "enet_axi_post_div", base + 0x4060, 0);
-       clks[IMX7D_OCRAM_CLK] = imx_clk_gate4("ocram_clk", "axi_post_div", base + 0x4110, 0);
+       clks[IMX7D_OCRAM_CLK] = imx_clk_gate4("ocram_clk", "main_axi_root_clk", base + 0x4110, 0);
        clks[IMX7D_OCRAM_S_CLK] = imx_clk_gate4("ocram_s_clk", "ahb_root_clk", base + 0x4120, 0);
        clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate4("dram_root_clk", "dram_post_div", base + 0x4130, 0);
        clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate4("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0);
index e47a1c2fe8bd01d217ad9adb7c380e9bdab9ec5e..4ba9973d4c1878bff6bae24ca680cc85eb463502 100644 (file)
@@ -107,7 +107,7 @@ static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw,
        return ull;
 }
 
-static struct clk_ops clk_pllv1_ops = {
+static const struct clk_ops clk_pllv1_ops = {
        .recalc_rate = clk_pllv1_recalc_rate,
 };
 
index 9842d657e974e71539a690fe0b778a82ad3c16dd..85b5cbe9744caff244e41634db93d619ada1123c 100644 (file)
@@ -227,7 +227,7 @@ static void clk_pllv2_unprepare(struct clk_hw *hw)
        __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
 }
 
-static struct clk_ops clk_pllv2_ops = {
+static const struct clk_ops clk_pllv2_ops = {
        .prepare = clk_pllv2_prepare,
        .unprepare = clk_pllv2_unprepare,
        .recalc_rate = clk_pllv2_recalc_rate,
index 28739a9a6e37da73a084196e94436e4d4bf95ed4..59dc0aad553cf00c7b63da33c18d2a71575771df 100644 (file)
@@ -50,6 +50,56 @@ config COMMON_CLK_MT2701_BDPSYS
        ---help---
          This driver supports Mediatek MT2701 bdpsys clocks.
 
+config COMMON_CLK_MT2712
+       bool "Clock driver for Mediatek MT2712"
+       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK && ARM64
+       ---help---
+         This driver supports Mediatek MT2712 basic clocks.
+
+config COMMON_CLK_MT2712_BDPSYS
+       bool "Clock driver for Mediatek MT2712 bdpsys"
+       depends on COMMON_CLK_MT2712
+       ---help---
+         This driver supports Mediatek MT2712 bdpsys clocks.
+
+config COMMON_CLK_MT2712_IMGSYS
+       bool "Clock driver for Mediatek MT2712 imgsys"
+       depends on COMMON_CLK_MT2712
+       ---help---
+         This driver supports Mediatek MT2712 imgsys clocks.
+
+config COMMON_CLK_MT2712_JPGDECSYS
+       bool "Clock driver for Mediatek MT2712 jpgdecsys"
+       depends on COMMON_CLK_MT2712
+       ---help---
+         This driver supports Mediatek MT2712 jpgdecsys clocks.
+
+config COMMON_CLK_MT2712_MFGCFG
+       bool "Clock driver for Mediatek MT2712 mfgcfg"
+       depends on COMMON_CLK_MT2712
+       ---help---
+         This driver supports Mediatek MT2712 mfgcfg clocks.
+
+config COMMON_CLK_MT2712_MMSYS
+       bool "Clock driver for Mediatek MT2712 mmsys"
+       depends on COMMON_CLK_MT2712
+       ---help---
+         This driver supports Mediatek MT2712 mmsys clocks.
+
+config COMMON_CLK_MT2712_VDECSYS
+       bool "Clock driver for Mediatek MT2712 vdecsys"
+       depends on COMMON_CLK_MT2712
+       ---help---
+         This driver supports Mediatek MT2712 vdecsys clocks.
+
+config COMMON_CLK_MT2712_VENCSYS
+       bool "Clock driver for Mediatek MT2712 vencsys"
+       depends on COMMON_CLK_MT2712
+       ---help---
+         This driver supports Mediatek MT2712 vencsys clocks.
+
 config COMMON_CLK_MT6797
        bool "Clock driver for Mediatek MT6797"
        depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
@@ -82,6 +132,36 @@ config COMMON_CLK_MT6797_VENCSYS
        ---help---
          This driver supports Mediatek MT6797 vencsys clocks.
 
+config COMMON_CLK_MT7622
+       bool "Clock driver for MediaTek MT7622"
+       depends on ARCH_MEDIATEK || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK
+       ---help---
+         This driver supports MediaTek MT7622 basic clocks and clocks
+         required for various periperals found on MediaTek.
+
+config COMMON_CLK_MT7622_ETHSYS
+       bool "Clock driver for MediaTek MT7622 ETHSYS"
+       depends on COMMON_CLK_MT7622
+       ---help---
+         This driver add support for clocks for Ethernet and SGMII
+         required on MediaTek MT7622 SoC.
+
+config COMMON_CLK_MT7622_HIFSYS
+       bool "Clock driver for MediaTek MT7622 HIFSYS"
+       depends on COMMON_CLK_MT7622
+       ---help---
+         This driver supports MediaTek MT7622 HIFSYS clocks providing
+         to PCI-E and USB.
+
+config COMMON_CLK_MT7622_AUDSYS
+       bool "Clock driver for MediaTek MT7622 AUDSYS"
+       depends on COMMON_CLK_MT7622
+       ---help---
+         This driver supports MediaTek MT7622 AUDSYS clocks providing
+         to audio consumers such as I2S and TDM.
+
 config COMMON_CLK_MT8135
        bool "Clock driver for Mediatek MT8135"
        depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
index ba2a070765f09c9ee3bf1936c94fdb387c974c4f..c421ffcd49ffd1218eac72a70c08a3342619649c 100644 (file)
@@ -13,5 +13,17 @@ obj-$(CONFIG_COMMON_CLK_MT2701_HIFSYS) += clk-mt2701-hif.o
 obj-$(CONFIG_COMMON_CLK_MT2701_IMGSYS) += clk-mt2701-img.o
 obj-$(CONFIG_COMMON_CLK_MT2701_MMSYS) += clk-mt2701-mm.o
 obj-$(CONFIG_COMMON_CLK_MT2701_VDECSYS) += clk-mt2701-vdec.o
+obj-$(CONFIG_COMMON_CLK_MT2712) += clk-mt2712.o
+obj-$(CONFIG_COMMON_CLK_MT2712_BDPSYS) += clk-mt2712-bdp.o
+obj-$(CONFIG_COMMON_CLK_MT2712_IMGSYS) += clk-mt2712-img.o
+obj-$(CONFIG_COMMON_CLK_MT2712_JPGDECSYS) += clk-mt2712-jpgdec.o
+obj-$(CONFIG_COMMON_CLK_MT2712_MFGCFG) += clk-mt2712-mfg.o
+obj-$(CONFIG_COMMON_CLK_MT2712_MMSYS) += clk-mt2712-mm.o
+obj-$(CONFIG_COMMON_CLK_MT2712_VDECSYS) += clk-mt2712-vdec.o
+obj-$(CONFIG_COMMON_CLK_MT2712_VENCSYS) += clk-mt2712-venc.o
+obj-$(CONFIG_COMMON_CLK_MT7622) += clk-mt7622.o
+obj-$(CONFIG_COMMON_CLK_MT7622_ETHSYS) += clk-mt7622-eth.o
+obj-$(CONFIG_COMMON_CLK_MT7622_HIFSYS) += clk-mt7622-hif.o
+obj-$(CONFIG_COMMON_CLK_MT7622_AUDSYS) += clk-mt7622-aud.o
 obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
 obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o
index 9598889f972b0dd7b163354861a508e8ad8e3ce0..8e7f16fd87c93b80f586d2f223c95c38a10be967 100644 (file)
@@ -750,7 +750,7 @@ static const struct mtk_fixed_factor infra_fixed_divs[] = {
 
 static struct clk_onecell_data *infra_clk_data;
 
-static void mtk_infrasys_init_early(struct device_node *node)
+static void __init mtk_infrasys_init_early(struct device_node *node)
 {
        int r, i;
 
diff --git a/drivers/clk/mediatek/clk-mt2712-bdp.c b/drivers/clk/mediatek/clk-mt2712-bdp.c
new file mode 100644 (file)
index 0000000..5fe4728
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Weiyi Lu <weiyi.lu@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt2712-clk.h>
+
+static const struct mtk_gate_regs bdp_cg_regs = {
+       .set_ofs = 0x100,
+       .clr_ofs = 0x100,
+       .sta_ofs = 0x100,
+};
+
+#define GATE_BDP(_id, _name, _parent, _shift) {        \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &bdp_cg_regs,                   \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_no_setclr,     \
+       }
+
+static const struct mtk_gate bdp_clks[] = {
+       GATE_BDP(CLK_BDP_BRIDGE_B, "bdp_bridge_b", "mm_sel", 0),
+       GATE_BDP(CLK_BDP_BRIDGE_DRAM, "bdp_bridge_d", "mm_sel", 1),
+       GATE_BDP(CLK_BDP_LARB_DRAM, "bdp_larb_d", "mm_sel", 2),
+       GATE_BDP(CLK_BDP_WR_CHANNEL_VDI_PXL, "bdp_vdi_pxl", "tvd_sel", 3),
+       GATE_BDP(CLK_BDP_WR_CHANNEL_VDI_DRAM, "bdp_vdi_d", "mm_sel", 4),
+       GATE_BDP(CLK_BDP_WR_CHANNEL_VDI_B, "bdp_vdi_b", "mm_sel", 5),
+       GATE_BDP(CLK_BDP_MT_B, "bdp_fmt_b", "mm_sel", 9),
+       GATE_BDP(CLK_BDP_DISPFMT_27M, "bdp_27m", "di_sel", 10),
+       GATE_BDP(CLK_BDP_DISPFMT_27M_VDOUT, "bdp_27m_vdout", "di_sel", 11),
+       GATE_BDP(CLK_BDP_DISPFMT_27_74_74, "bdp_27_74_74", "di_sel", 12),
+       GATE_BDP(CLK_BDP_DISPFMT_2FS, "bdp_2fs", "di_sel", 13),
+       GATE_BDP(CLK_BDP_DISPFMT_2FS_2FS74_148, "bdp_2fs74_148", "di_sel", 14),
+       GATE_BDP(CLK_BDP_DISPFMT_B, "bdp_b", "mm_sel", 15),
+       GATE_BDP(CLK_BDP_VDO_DRAM, "bdp_vdo_d", "mm_sel", 16),
+       GATE_BDP(CLK_BDP_VDO_2FS, "bdp_vdo_2fs", "di_sel", 17),
+       GATE_BDP(CLK_BDP_VDO_B, "bdp_vdo_b", "mm_sel", 18),
+       GATE_BDP(CLK_BDP_WR_CHANNEL_DI_PXL, "bdp_di_pxl", "di_sel", 19),
+       GATE_BDP(CLK_BDP_WR_CHANNEL_DI_DRAM, "bdp_di_d", "mm_sel", 20),
+       GATE_BDP(CLK_BDP_WR_CHANNEL_DI_B, "bdp_di_b", "mm_sel", 21),
+       GATE_BDP(CLK_BDP_NR_AGENT, "bdp_nr_agent", "nr_sel", 22),
+       GATE_BDP(CLK_BDP_NR_DRAM, "bdp_nr_d", "mm_sel", 23),
+       GATE_BDP(CLK_BDP_NR_B, "bdp_nr_b", "mm_sel", 24),
+       GATE_BDP(CLK_BDP_BRIDGE_RT_B, "bdp_bridge_rt_b", "mm_sel", 25),
+       GATE_BDP(CLK_BDP_BRIDGE_RT_DRAM, "bdp_bridge_rt_d", "mm_sel", 26),
+       GATE_BDP(CLK_BDP_LARB_RT_DRAM, "bdp_larb_rt_d", "mm_sel", 27),
+       GATE_BDP(CLK_BDP_TVD_TDC, "bdp_tvd_tdc", "mm_sel", 28),
+       GATE_BDP(CLK_BDP_TVD_54, "bdp_tvd_clk_54", "tvd_sel", 29),
+       GATE_BDP(CLK_BDP_TVD_CBUS, "bdp_tvd_cbus", "mm_sel", 30),
+};
+
+static int clk_mt2712_bdp_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_BDP_NR_CLK);
+
+       mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks),
+                       clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r != 0)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+       return r;
+}
+
+static const struct of_device_id of_match_clk_mt2712_bdp[] = {
+       { .compatible = "mediatek,mt2712-bdpsys", },
+       {}
+};
+
+static struct platform_driver clk_mt2712_bdp_drv = {
+       .probe = clk_mt2712_bdp_probe,
+       .driver = {
+               .name = "clk-mt2712-bdp",
+               .of_match_table = of_match_clk_mt2712_bdp,
+       },
+};
+
+builtin_platform_driver(clk_mt2712_bdp_drv);
diff --git a/drivers/clk/mediatek/clk-mt2712-img.c b/drivers/clk/mediatek/clk-mt2712-img.c
new file mode 100644 (file)
index 0000000..139ff55
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Weiyi Lu <weiyi.lu@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt2712-clk.h>
+
+static const struct mtk_gate_regs img_cg_regs = {
+       .set_ofs = 0x0,
+       .clr_ofs = 0x0,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_IMG(_id, _name, _parent, _shift) {        \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &img_cg_regs,                   \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_no_setclr,     \
+       }
+
+static const struct mtk_gate img_clks[] = {
+       GATE_IMG(CLK_IMG_SMI_LARB2, "img_smi_larb2", "mm_sel", 0),
+       GATE_IMG(CLK_IMG_SENINF_SCAM_EN, "img_scam_en", "csi0", 3),
+       GATE_IMG(CLK_IMG_SENINF_CAM_EN, "img_cam_en", "mm_sel", 8),
+       GATE_IMG(CLK_IMG_CAM_SV_EN, "img_cam_sv_en", "mm_sel", 9),
+       GATE_IMG(CLK_IMG_CAM_SV1_EN, "img_cam_sv1_en", "mm_sel", 10),
+       GATE_IMG(CLK_IMG_CAM_SV2_EN, "img_cam_sv2_en", "mm_sel", 11),
+};
+
+static int clk_mt2712_img_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
+
+       mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
+                       clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r != 0)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+       return r;
+}
+
+static const struct of_device_id of_match_clk_mt2712_img[] = {
+       { .compatible = "mediatek,mt2712-imgsys", },
+       {}
+};
+
+static struct platform_driver clk_mt2712_img_drv = {
+       .probe = clk_mt2712_img_probe,
+       .driver = {
+               .name = "clk-mt2712-img",
+               .of_match_table = of_match_clk_mt2712_img,
+       },
+};
+
+builtin_platform_driver(clk_mt2712_img_drv);
diff --git a/drivers/clk/mediatek/clk-mt2712-jpgdec.c b/drivers/clk/mediatek/clk-mt2712-jpgdec.c
new file mode 100644 (file)
index 0000000..c7d4aad
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Weiyi Lu <weiyi.lu@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt2712-clk.h>
+
+static const struct mtk_gate_regs jpgdec_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_JPGDEC(_id, _name, _parent, _shift) {     \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &jpgdec_cg_regs,                        \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr_inv,    \
+       }
+
+static const struct mtk_gate jpgdec_clks[] = {
+       GATE_JPGDEC(CLK_JPGDEC_JPGDEC1, "jpgdec_jpgdec1", "jpgdec_sel", 0),
+       GATE_JPGDEC(CLK_JPGDEC_JPGDEC, "jpgdec_jpgdec", "jpgdec_sel", 4),
+};
+
+static int clk_mt2712_jpgdec_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_JPGDEC_NR_CLK);
+
+       mtk_clk_register_gates(node, jpgdec_clks, ARRAY_SIZE(jpgdec_clks),
+                       clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r != 0)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+       return r;
+}
+
+static const struct of_device_id of_match_clk_mt2712_jpgdec[] = {
+       { .compatible = "mediatek,mt2712-jpgdecsys", },
+       {}
+};
+
+static struct platform_driver clk_mt2712_jpgdec_drv = {
+       .probe = clk_mt2712_jpgdec_probe,
+       .driver = {
+               .name = "clk-mt2712-jpgdec",
+               .of_match_table = of_match_clk_mt2712_jpgdec,
+       },
+};
+
+builtin_platform_driver(clk_mt2712_jpgdec_drv);
diff --git a/drivers/clk/mediatek/clk-mt2712-mfg.c b/drivers/clk/mediatek/clk-mt2712-mfg.c
new file mode 100644 (file)
index 0000000..570f72d
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Weiyi Lu <weiyi.lu@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt2712-clk.h>
+
+static const struct mtk_gate_regs mfg_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_MFG(_id, _name, _parent, _shift) {        \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &mfg_cg_regs,                   \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+static const struct mtk_gate mfg_clks[] = {
+       GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_sel", 0),
+};
+
+static int clk_mt2712_mfg_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_MFG_NR_CLK);
+
+       mtk_clk_register_gates(node, mfg_clks, ARRAY_SIZE(mfg_clks),
+                       clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r != 0)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+       return r;
+}
+
+static const struct of_device_id of_match_clk_mt2712_mfg[] = {
+       { .compatible = "mediatek,mt2712-mfgcfg", },
+       {}
+};
+
+static struct platform_driver clk_mt2712_mfg_drv = {
+       .probe = clk_mt2712_mfg_probe,
+       .driver = {
+               .name = "clk-mt2712-mfg",
+               .of_match_table = of_match_clk_mt2712_mfg,
+       },
+};
+
+builtin_platform_driver(clk_mt2712_mfg_drv);
diff --git a/drivers/clk/mediatek/clk-mt2712-mm.c b/drivers/clk/mediatek/clk-mt2712-mm.c
new file mode 100644 (file)
index 0000000..a8b4b6d
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Weiyi Lu <weiyi.lu@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt2712-clk.h>
+
+static const struct mtk_gate_regs mm0_cg_regs = {
+       .set_ofs = 0x104,
+       .clr_ofs = 0x108,
+       .sta_ofs = 0x100,
+};
+
+static const struct mtk_gate_regs mm1_cg_regs = {
+       .set_ofs = 0x114,
+       .clr_ofs = 0x118,
+       .sta_ofs = 0x110,
+};
+
+static const struct mtk_gate_regs mm2_cg_regs = {
+       .set_ofs = 0x224,
+       .clr_ofs = 0x228,
+       .sta_ofs = 0x220,
+};
+
+#define GATE_MM0(_id, _name, _parent, _shift) {        \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &mm0_cg_regs,                   \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+#define GATE_MM1(_id, _name, _parent, _shift) {        \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &mm1_cg_regs,                   \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+#define GATE_MM2(_id, _name, _parent, _shift) {        \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &mm2_cg_regs,                   \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+static const struct mtk_gate mm_clks[] = {
+       /* MM0 */
+       GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0),
+       GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
+       GATE_MM0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 2),
+       GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 3),
+       GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 4),
+       GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 5),
+       GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 6),
+       GATE_MM0(CLK_MM_MDP_RSZ2, "mm_mdp_rsz2", "mm_sel", 7),
+       GATE_MM0(CLK_MM_MDP_TDSHP0, "mm_mdp_tdshp0", "mm_sel", 8),
+       GATE_MM0(CLK_MM_MDP_TDSHP1, "mm_mdp_tdshp1", "mm_sel", 9),
+       GATE_MM0(CLK_MM_MDP_CROP, "mm_mdp_crop", "mm_sel", 10),
+       GATE_MM0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11),
+       GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 12),
+       GATE_MM0(CLK_MM_MDP_WROT1, "mm_mdp_wrot1", "mm_sel", 13),
+       GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 14),
+       GATE_MM0(CLK_MM_MUTEX_32K, "mm_mutex_32k", "clk32k", 15),
+       GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 16),
+       GATE_MM0(CLK_MM_DISP_OVL1, "mm_disp_ovl1", "mm_sel", 17),
+       GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 18),
+       GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 19),
+       GATE_MM0(CLK_MM_DISP_RDMA2, "mm_disp_rdma2", "mm_sel", 20),
+       GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 21),
+       GATE_MM0(CLK_MM_DISP_WDMA1, "mm_disp_wdma1", "mm_sel", 22),
+       GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_sel", 23),
+       GATE_MM0(CLK_MM_DISP_COLOR1, "mm_disp_color1", "mm_sel", 24),
+       GATE_MM0(CLK_MM_DISP_AAL, "mm_disp_aal", "mm_sel", 25),
+       GATE_MM0(CLK_MM_DISP_GAMMA, "mm_disp_gamma", "mm_sel", 26),
+       GATE_MM0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 27),
+       GATE_MM0(CLK_MM_DISP_SPLIT0, "mm_disp_split0", "mm_sel", 28),
+       GATE_MM0(CLK_MM_DISP_OD, "mm_disp_od", "mm_sel", 31),
+       /* MM1 */
+       GATE_MM1(CLK_MM_DISP_PWM0_MM, "mm_pwm0_mm", "mm_sel", 0),
+       GATE_MM1(CLK_MM_DISP_PWM0_26M, "mm_pwm0_26m", "pwm_sel", 1),
+       GATE_MM1(CLK_MM_DISP_PWM1_MM, "mm_pwm1_mm", "mm_sel", 2),
+       GATE_MM1(CLK_MM_DISP_PWM1_26M, "mm_pwm1_26m", "pwm_sel", 3),
+       GATE_MM1(CLK_MM_DSI0_ENGINE, "mm_dsi0_engine", "mm_sel", 4),
+       GATE_MM1(CLK_MM_DSI0_DIGITAL, "mm_dsi0_digital", "dsi0_lntc", 5),
+       GATE_MM1(CLK_MM_DSI1_ENGINE, "mm_dsi1_engine", "mm_sel", 6),
+       GATE_MM1(CLK_MM_DSI1_DIGITAL, "mm_dsi1_digital", "dsi1_lntc", 7),
+       GATE_MM1(CLK_MM_DPI_PIXEL, "mm_dpi_pixel", "vpll_dpix", 8),
+       GATE_MM1(CLK_MM_DPI_ENGINE, "mm_dpi_engine", "mm_sel", 9),
+       GATE_MM1(CLK_MM_DPI1_PIXEL, "mm_dpi1_pixel", "vpll3_dpix", 10),
+       GATE_MM1(CLK_MM_DPI1_ENGINE, "mm_dpi1_engine", "mm_sel", 11),
+       GATE_MM1(CLK_MM_LVDS_PIXEL, "mm_lvds_pixel", "vpll_dpix", 16),
+       GATE_MM1(CLK_MM_LVDS_CTS, "mm_lvds_cts", "lvdstx", 17),
+       GATE_MM1(CLK_MM_SMI_LARB4, "mm_smi_larb4", "mm_sel", 18),
+       GATE_MM1(CLK_MM_SMI_COMMON1, "mm_smi_common1", "mm_sel", 21),
+       GATE_MM1(CLK_MM_SMI_LARB5, "mm_smi_larb5", "mm_sel", 22),
+       GATE_MM1(CLK_MM_MDP_RDMA2, "mm_mdp_rdma2", "mm_sel", 23),
+       GATE_MM1(CLK_MM_MDP_TDSHP2, "mm_mdp_tdshp2", "mm_sel", 24),
+       GATE_MM1(CLK_MM_DISP_OVL2, "mm_disp_ovl2", "mm_sel", 25),
+       GATE_MM1(CLK_MM_DISP_WDMA2, "mm_disp_wdma2", "mm_sel", 26),
+       GATE_MM1(CLK_MM_DISP_COLOR2, "mm_disp_color2", "mm_sel", 27),
+       GATE_MM1(CLK_MM_DISP_AAL1, "mm_disp_aal1", "mm_sel", 28),
+       GATE_MM1(CLK_MM_DISP_OD1, "mm_disp_od1", "mm_sel", 29),
+       GATE_MM1(CLK_MM_LVDS1_PIXEL, "mm_lvds1_pixel", "vpll3_dpix", 30),
+       GATE_MM1(CLK_MM_LVDS1_CTS, "mm_lvds1_cts", "lvdstx3", 31),
+       /* MM2 */
+       GATE_MM2(CLK_MM_SMI_LARB7, "mm_smi_larb7", "mm_sel", 0),
+       GATE_MM2(CLK_MM_MDP_RDMA3, "mm_mdp_rdma3", "mm_sel", 1),
+       GATE_MM2(CLK_MM_MDP_WROT2, "mm_mdp_wrot2", "mm_sel", 2),
+       GATE_MM2(CLK_MM_DSI2, "mm_dsi2", "mm_sel", 3),
+       GATE_MM2(CLK_MM_DSI2_DIGITAL, "mm_dsi2_digital", "dsi0_lntc", 4),
+       GATE_MM2(CLK_MM_DSI3, "mm_dsi3", "mm_sel", 5),
+       GATE_MM2(CLK_MM_DSI3_DIGITAL, "mm_dsi3_digital", "dsi1_lntc", 6),
+};
+
+static int clk_mt2712_mm_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
+
+       mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
+                       clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r != 0)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+       return r;
+}
+
+static const struct of_device_id of_match_clk_mt2712_mm[] = {
+       { .compatible = "mediatek,mt2712-mmsys", },
+       {}
+};
+
+static struct platform_driver clk_mt2712_mm_drv = {
+       .probe = clk_mt2712_mm_probe,
+       .driver = {
+               .name = "clk-mt2712-mm",
+               .of_match_table = of_match_clk_mt2712_mm,
+       },
+};
+
+builtin_platform_driver(clk_mt2712_mm_drv);
diff --git a/drivers/clk/mediatek/clk-mt2712-vdec.c b/drivers/clk/mediatek/clk-mt2712-vdec.c
new file mode 100644 (file)
index 0000000..55c64ee
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Weiyi Lu <weiyi.lu@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt2712-clk.h>
+
+static const struct mtk_gate_regs vdec0_cg_regs = {
+       .set_ofs = 0x0,
+       .clr_ofs = 0x4,
+       .sta_ofs = 0x0,
+};
+
+static const struct mtk_gate_regs vdec1_cg_regs = {
+       .set_ofs = 0x8,
+       .clr_ofs = 0xc,
+       .sta_ofs = 0x8,
+};
+
+#define GATE_VDEC0(_id, _name, _parent, _shift) {      \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &vdec0_cg_regs,                 \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr_inv,    \
+       }
+
+#define GATE_VDEC1(_id, _name, _parent, _shift) {      \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &vdec1_cg_regs,                 \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr_inv,    \
+       }
+
+static const struct mtk_gate vdec_clks[] = {
+       /* VDEC0 */
+       GATE_VDEC0(CLK_VDEC_CKEN, "vdec_cken", "vdec_sel", 0),
+       /* VDEC1 */
+       GATE_VDEC1(CLK_VDEC_LARB1_CKEN, "vdec_larb1_cken", "vdec_sel", 0),
+       GATE_VDEC1(CLK_VDEC_IMGRZ_CKEN, "vdec_imgrz_cken", "vdec_sel", 1),
+};
+
+static int clk_mt2712_vdec_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_VDEC_NR_CLK);
+
+       mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
+                       clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r != 0)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+       return r;
+}
+
+static const struct of_device_id of_match_clk_mt2712_vdec[] = {
+       { .compatible = "mediatek,mt2712-vdecsys", },
+       {}
+};
+
+static struct platform_driver clk_mt2712_vdec_drv = {
+       .probe = clk_mt2712_vdec_probe,
+       .driver = {
+               .name = "clk-mt2712-vdec",
+               .of_match_table = of_match_clk_mt2712_vdec,
+       },
+};
+
+builtin_platform_driver(clk_mt2712_vdec_drv);
diff --git a/drivers/clk/mediatek/clk-mt2712-venc.c b/drivers/clk/mediatek/clk-mt2712-venc.c
new file mode 100644 (file)
index 0000000..ccbfe98
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Weiyi Lu <weiyi.lu@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt2712-clk.h>
+
+static const struct mtk_gate_regs venc_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_VENC(_id, _name, _parent, _shift) {       \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &venc_cg_regs,                  \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr_inv,    \
+       }
+
+static const struct mtk_gate venc_clks[] = {
+       GATE_VENC(CLK_VENC_SMI_COMMON_CON, "venc_smi", "mm_sel", 0),
+       GATE_VENC(CLK_VENC_VENC, "venc_venc", "venc_sel", 4),
+       GATE_VENC(CLK_VENC_SMI_LARB6, "venc_smi_larb6", "jpgdec_sel", 12),
+};
+
+static int clk_mt2712_venc_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_VENC_NR_CLK);
+
+       mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
+                       clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r != 0)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+       return r;
+}
+
+static const struct of_device_id of_match_clk_mt2712_venc[] = {
+       { .compatible = "mediatek,mt2712-vencsys", },
+       {}
+};
+
+static struct platform_driver clk_mt2712_venc_drv = {
+       .probe = clk_mt2712_venc_probe,
+       .driver = {
+               .name = "clk-mt2712-venc",
+               .of_match_table = of_match_clk_mt2712_venc,
+       },
+};
+
+builtin_platform_driver(clk_mt2712_venc_drv);
diff --git a/drivers/clk/mediatek/clk-mt2712.c b/drivers/clk/mediatek/clk-mt2712.c
new file mode 100644 (file)
index 0000000..498d137
--- /dev/null
@@ -0,0 +1,1435 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Weiyi Lu <weiyi.lu@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt2712-clk.h>
+
+static DEFINE_SPINLOCK(mt2712_clk_lock);
+
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+       FIXED_CLK(CLK_TOP_VPLL3_DPIX, "vpll3_dpix", NULL, 200000000),
+       FIXED_CLK(CLK_TOP_VPLL_DPIX, "vpll_dpix", NULL, 200000000),
+       FIXED_CLK(CLK_TOP_LTEPLL_FS26M, "ltepll_fs26m", NULL, 26000000),
+       FIXED_CLK(CLK_TOP_DMPLL, "dmpll_ck", NULL, 350000000),
+       FIXED_CLK(CLK_TOP_DSI0_LNTC, "dsi0_lntc", NULL, 143000000),
+       FIXED_CLK(CLK_TOP_DSI1_LNTC, "dsi1_lntc", NULL, 143000000),
+       FIXED_CLK(CLK_TOP_LVDSTX3_CLKDIG_CTS, "lvdstx3", NULL, 140000000),
+       FIXED_CLK(CLK_TOP_LVDSTX_CLKDIG_CTS, "lvdstx", NULL, 140000000),
+       FIXED_CLK(CLK_TOP_CLKRTC_EXT, "clkrtc_ext", NULL, 32768),
+       FIXED_CLK(CLK_TOP_CLKRTC_INT, "clkrtc_int", NULL, 32747),
+       FIXED_CLK(CLK_TOP_CSI0, "csi0", NULL, 26000000),
+       FIXED_CLK(CLK_TOP_CVBSPLL, "cvbspll", NULL, 108000000),
+};
+
+static const struct mtk_fixed_factor top_early_divs[] = {
+       FACTOR(CLK_TOP_SYS_26M, "sys_26m", "clk26m", 1,
+               1),
+       FACTOR(CLK_TOP_CLK26M_D2, "clk26m_d2", "sys_26m", 1,
+               2),
+};
+
+static const struct mtk_fixed_factor top_divs[] = {
+       FACTOR(CLK_TOP_ARMCA35PLL, "armca35pll_ck", "armca35pll", 1,
+               1),
+       FACTOR(CLK_TOP_ARMCA35PLL_600M, "armca35pll_600m", "armca35pll_ck", 1,
+               2),
+       FACTOR(CLK_TOP_ARMCA35PLL_400M, "armca35pll_400m", "armca35pll_ck", 1,
+               3),
+       FACTOR(CLK_TOP_ARMCA72PLL, "armca72pll_ck", "armca72pll", 1,
+               1),
+       FACTOR(CLK_TOP_SYSPLL, "syspll_ck", "mainpll", 1,
+               1),
+       FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "syspll_ck", 1,
+               2),
+       FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "syspll_d2", 1,
+               2),
+       FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "syspll_d2", 1,
+               4),
+       FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "syspll_d2", 1,
+               8),
+       FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "syspll_d2", 1,
+               16),
+       FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "syspll_ck", 1,
+               3),
+       FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "syspll_d3", 1,
+               2),
+       FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "syspll_d3", 1,
+               4),
+       FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "syspll_ck", 1,
+               5),
+       FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "syspll_d5", 1,
+               2),
+       FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "syspll_d5", 1,
+               4),
+       FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "syspll_ck", 1,
+               7),
+       FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "syspll_d7", 1,
+               2),
+       FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "syspll_d7", 1,
+               4),
+       FACTOR(CLK_TOP_UNIVPLL, "univpll_ck", "univpll", 1,
+               1),
+       FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll_ck", 1,
+               7),
+       FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll_ck", 1,
+               26),
+       FACTOR(CLK_TOP_UNIVPLL_D52, "univpll_d52", "univpll_ck", 1,
+               52),
+       FACTOR(CLK_TOP_UNIVPLL_D104, "univpll_d104", "univpll_ck", 1,
+               104),
+       FACTOR(CLK_TOP_UNIVPLL_D208, "univpll_d208", "univpll_ck", 1,
+               208),
+       FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll_ck", 1,
+               2),
+       FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_d2", 1,
+               2),
+       FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_d2", 1,
+               4),
+       FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_d2", 1,
+               8),
+       FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll_ck", 1,
+               3),
+       FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_d3", 1,
+               2),
+       FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_d3", 1,
+               4),
+       FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_d3", 1,
+               8),
+       FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll_ck", 1,
+               5),
+       FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll_d5", 1,
+               2),
+       FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll_d5", 1,
+               4),
+       FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univpll_d5", 1,
+               8),
+       FACTOR(CLK_TOP_F_MP0_PLL1, "f_mp0_pll1_ck", "univpll_d2", 1,
+               1),
+       FACTOR(CLK_TOP_F_MP0_PLL2, "f_mp0_pll2_ck", "univpll1_d2", 1,
+               1),
+       FACTOR(CLK_TOP_F_BIG_PLL1, "f_big_pll1_ck", "univpll_d2", 1,
+               1),
+       FACTOR(CLK_TOP_F_BIG_PLL2, "f_big_pll2_ck", "univpll1_d2", 1,
+               1),
+       FACTOR(CLK_TOP_F_BUS_PLL1, "f_bus_pll1_ck", "univpll_d2", 1,
+               1),
+       FACTOR(CLK_TOP_F_BUS_PLL2, "f_bus_pll2_ck", "univpll1_d2", 1,
+               1),
+       FACTOR(CLK_TOP_APLL1, "apll1_ck", "apll1", 1,
+               1),
+       FACTOR(CLK_TOP_APLL1_D2, "apll1_d2", "apll1_ck", 1,
+               2),
+       FACTOR(CLK_TOP_APLL1_D4, "apll1_d4", "apll1_ck", 1,
+               4),
+       FACTOR(CLK_TOP_APLL1_D8, "apll1_d8", "apll1_ck", 1,
+               8),
+       FACTOR(CLK_TOP_APLL1_D16, "apll1_d16", "apll1_ck", 1,
+               16),
+       FACTOR(CLK_TOP_APLL2, "apll2_ck", "apll2", 1,
+               1),
+       FACTOR(CLK_TOP_APLL2_D2, "apll2_d2", "apll2_ck", 1,
+               2),
+       FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2_ck", 1,
+               4),
+       FACTOR(CLK_TOP_APLL2_D8, "apll2_d8", "apll2_ck", 1,
+               8),
+       FACTOR(CLK_TOP_APLL2_D16, "apll2_d16", "apll2_ck", 1,
+               16),
+       FACTOR(CLK_TOP_LVDSPLL, "lvdspll_ck", "lvdspll", 1,
+               1),
+       FACTOR(CLK_TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll_ck", 1,
+               2),
+       FACTOR(CLK_TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll_ck", 1,
+               4),
+       FACTOR(CLK_TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll_ck", 1,
+               8),
+       FACTOR(CLK_TOP_LVDSPLL2, "lvdspll2_ck", "lvdspll2", 1,
+               1),
+       FACTOR(CLK_TOP_LVDSPLL2_D2, "lvdspll2_d2", "lvdspll2_ck", 1,
+               2),
+       FACTOR(CLK_TOP_LVDSPLL2_D4, "lvdspll2_d4", "lvdspll2_ck", 1,
+               4),
+       FACTOR(CLK_TOP_LVDSPLL2_D8, "lvdspll2_d8", "lvdspll2_ck", 1,
+               8),
+       FACTOR(CLK_TOP_ETHERPLL_125M, "etherpll_125m", "etherpll", 1,
+               1),
+       FACTOR(CLK_TOP_ETHERPLL_50M, "etherpll_50m", "etherpll", 1,
+               1),
+       FACTOR(CLK_TOP_CVBS, "cvbs", "cvbspll", 1,
+               1),
+       FACTOR(CLK_TOP_CVBS_D2, "cvbs_d2", "cvbs", 1,
+               2),
+       FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1,
+               1),
+       FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll_ck", 1,
+               2),
+       FACTOR(CLK_TOP_VENCPLL, "vencpll_ck", "vencpll", 1,
+               1),
+       FACTOR(CLK_TOP_VENCPLL_D2, "vencpll_d2", "vencpll_ck", 1,
+               2),
+       FACTOR(CLK_TOP_VCODECPLL, "vcodecpll_ck", "vcodecpll", 1,
+               1),
+       FACTOR(CLK_TOP_VCODECPLL_D2, "vcodecpll_d2", "vcodecpll_ck", 1,
+               2),
+       FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll", 1,
+               1),
+       FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll_ck", 1,
+               2),
+       FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll_ck", 1,
+               4),
+       FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll_ck", 1,
+               8),
+       FACTOR(CLK_TOP_TVDPLL_429M, "tvdpll_429m", "tvdpll", 1,
+               1),
+       FACTOR(CLK_TOP_TVDPLL_429M_D2, "tvdpll_429m_d2", "tvdpll_429m", 1,
+               2),
+       FACTOR(CLK_TOP_TVDPLL_429M_D4, "tvdpll_429m_d4", "tvdpll_429m", 1,
+               4),
+       FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1,
+               1),
+       FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll_ck", 1,
+               2),
+       FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll_ck", 1,
+               4),
+       FACTOR(CLK_TOP_MSDCPLL2, "msdcpll2_ck", "msdcpll2", 1,
+               1),
+       FACTOR(CLK_TOP_MSDCPLL2_D2, "msdcpll2_d2", "msdcpll2_ck", 1,
+               2),
+       FACTOR(CLK_TOP_MSDCPLL2_D4, "msdcpll2_d4", "msdcpll2_ck", 1,
+               4),
+       FACTOR(CLK_TOP_D2A_ULCLK_6P5M, "d2a_ulclk_6p5m", "clk26m", 1,
+               4),
+};
+
+static const char * const axi_parents[] = {
+       "clk26m",
+       "syspll1_d2",
+       "syspll_d5",
+       "syspll1_d4",
+       "univpll_d5",
+       "univpll2_d2",
+       "msdcpll2_ck"
+};
+
+static const char * const mem_parents[] = {
+       "clk26m",
+       "dmpll_ck"
+};
+
+static const char * const mm_parents[] = {
+       "clk26m",
+       "vencpll_ck",
+       "syspll_d3",
+       "syspll1_d2",
+       "syspll_d5",
+       "syspll1_d4",
+       "univpll1_d2",
+       "univpll2_d2"
+};
+
+static const char * const pwm_parents[] = {
+       "clk26m",
+       "univpll2_d4",
+       "univpll3_d2",
+       "univpll1_d4"
+};
+
+static const char * const vdec_parents[] = {
+       "clk26m",
+       "vcodecpll_ck",
+       "tvdpll_429m",
+       "univpll_d3",
+       "vencpll_ck",
+       "syspll_d3",
+       "univpll1_d2",
+       "mmpll_d2",
+       "syspll3_d2",
+       "tvdpll_ck"
+};
+
+static const char * const venc_parents[] = {
+       "clk26m",
+       "univpll1_d2",
+       "mmpll_d2",
+       "tvdpll_d2",
+       "syspll1_d2",
+       "univpll_d5",
+       "vcodecpll_d2",
+       "univpll2_d2",
+       "syspll3_d2"
+};
+
+static const char * const mfg_parents[] = {
+       "clk26m",
+       "mmpll_ck",
+       "univpll_d3",
+       "clk26m",
+       "clk26m",
+       "clk26m",
+       "clk26m",
+       "clk26m",
+       "clk26m",
+       "syspll_d3",
+       "syspll1_d2",
+       "syspll_d5",
+       "univpll_d3",
+       "univpll1_d2",
+       "univpll_d5",
+       "univpll2_d2"
+};
+
+static const char * const camtg_parents[] = {
+       "clk26m",
+       "univpll_d52",
+       "univpll_d208",
+       "univpll_d104",
+       "clk26m_d2",
+       "univpll_d26",
+       "univpll2_d8",
+       "syspll3_d4",
+       "syspll3_d2",
+       "univpll1_d4",
+       "univpll2_d2"
+};
+
+static const char * const uart_parents[] = {
+       "clk26m",
+       "univpll2_d8"
+};
+
+static const char * const spi_parents[] = {
+       "clk26m",
+       "univpll2_d4",
+       "univpll1_d4",
+       "univpll2_d2",
+       "univpll3_d2",
+       "univpll1_d8"
+};
+
+static const char * const usb20_parents[] = {
+       "clk26m",
+       "univpll1_d8",
+       "univpll3_d4"
+};
+
+static const char * const usb30_parents[] = {
+       "clk26m",
+       "univpll3_d2",
+       "univpll3_d4",
+       "univpll2_d4"
+};
+
+static const char * const msdc50_0_h_parents[] = {
+       "clk26m",
+       "syspll1_d2",
+       "syspll2_d2",
+       "syspll4_d2",
+       "univpll_d5",
+       "univpll1_d4"
+};
+
+static const char * const msdc50_0_parents[] = {
+       "clk26m",
+       "msdcpll_ck",
+       "msdcpll_d2",
+       "univpll1_d4",
+       "syspll2_d2",
+       "msdcpll_d4",
+       "vencpll_d2",
+       "univpll1_d2",
+       "msdcpll2_ck",
+       "msdcpll2_d2",
+       "msdcpll2_d4"
+};
+
+static const char * const msdc30_1_parents[] = {
+       "clk26m",
+       "univpll2_d2",
+       "msdcpll_d2",
+       "univpll1_d4",
+       "syspll2_d2",
+       "univpll_d7",
+       "vencpll_d2"
+};
+
+static const char * const msdc30_3_parents[] = {
+       "clk26m",
+       "msdcpll2_ck",
+       "msdcpll2_d2",
+       "univpll2_d2",
+       "msdcpll2_d4",
+       "univpll1_d4",
+       "syspll2_d2",
+       "syspll_d7",
+       "univpll_d7",
+       "vencpll_d2",
+       "msdcpll_ck",
+       "msdcpll_d2",
+       "msdcpll_d4"
+};
+
+static const char * const audio_parents[] = {
+       "clk26m",
+       "syspll3_d4",
+       "syspll4_d4",
+       "syspll1_d16"
+};
+
+static const char * const aud_intbus_parents[] = {
+       "clk26m",
+       "syspll1_d4",
+       "syspll4_d2",
+       "univpll3_d2",
+       "univpll2_d8",
+       "syspll3_d2",
+       "syspll3_d4"
+};
+
+static const char * const pmicspi_parents[] = {
+       "clk26m",
+       "syspll1_d8",
+       "syspll3_d4",
+       "syspll1_d16",
+       "univpll3_d4",
+       "univpll_d26",
+       "syspll3_d4"
+};
+
+static const char * const dpilvds1_parents[] = {
+       "clk26m",
+       "lvdspll2_ck",
+       "lvdspll2_d2",
+       "lvdspll2_d4",
+       "lvdspll2_d8",
+       "clkfpc"
+};
+
+static const char * const atb_parents[] = {
+       "clk26m",
+       "syspll1_d2",
+       "univpll_d5",
+       "syspll_d5"
+};
+
+static const char * const nr_parents[] = {
+       "clk26m",
+       "univpll1_d4",
+       "syspll2_d2",
+       "syspll1_d4",
+       "univpll1_d8",
+       "univpll3_d2",
+       "univpll2_d2",
+       "syspll_d5"
+};
+
+static const char * const nfi2x_parents[] = {
+       "clk26m",
+       "syspll4_d4",
+       "univpll3_d4",
+       "univpll1_d8",
+       "syspll2_d4",
+       "univpll3_d2",
+       "syspll_d7",
+       "syspll2_d2",
+       "univpll2_d2",
+       "syspll_d5",
+       "syspll1_d2"
+};
+
+static const char * const irda_parents[] = {
+       "clk26m",
+       "univpll2_d4",
+       "syspll2_d4",
+       "univpll2_d8"
+};
+
+static const char * const cci400_parents[] = {
+       "clk26m",
+       "vencpll_ck",
+       "armca35pll_600m",
+       "armca35pll_400m",
+       "univpll_d2",
+       "syspll_d2",
+       "msdcpll_ck",
+       "univpll_d3"
+};
+
+static const char * const aud_1_parents[] = {
+       "clk26m",
+       "apll1_ck",
+       "univpll2_d4",
+       "univpll2_d8"
+};
+
+static const char * const aud_2_parents[] = {
+       "clk26m",
+       "apll2_ck",
+       "univpll2_d4",
+       "univpll2_d8"
+};
+
+static const char * const mem_mfg_parents[] = {
+       "clk26m",
+       "mmpll_ck",
+       "univpll_d3"
+};
+
+static const char * const axi_mfg_parents[] = {
+       "clk26m",
+       "axi_sel",
+       "univpll_d5"
+};
+
+static const char * const scam_parents[] = {
+       "clk26m",
+       "syspll3_d2",
+       "univpll2_d4",
+       "syspll2_d4"
+};
+
+static const char * const nfiecc_parents[] = {
+       "clk26m",
+       "nfi2x_sel",
+       "syspll_d7",
+       "syspll2_d2",
+       "univpll2_d2",
+       "univpll_d5",
+       "syspll1_d2"
+};
+
+static const char * const pe2_mac_p0_parents[] = {
+       "clk26m",
+       "syspll1_d8",
+       "syspll4_d2",
+       "syspll2_d4",
+       "univpll2_d4",
+       "syspll3_d2"
+};
+
+static const char * const dpilvds_parents[] = {
+       "clk26m",
+       "lvdspll_ck",
+       "lvdspll_d2",
+       "lvdspll_d4",
+       "lvdspll_d8",
+       "clkfpc"
+};
+
+static const char * const hdcp_parents[] = {
+       "clk26m",
+       "syspll4_d2",
+       "syspll3_d4",
+       "univpll2_d4"
+};
+
+static const char * const hdcp_24m_parents[] = {
+       "clk26m",
+       "univpll_d26",
+       "univpll_d52",
+       "univpll2_d8"
+};
+
+static const char * const rtc_parents[] = {
+       "clkrtc_int",
+       "clkrtc_ext",
+       "clk26m",
+       "univpll3_d8"
+};
+
+static const char * const spinor_parents[] = {
+       "clk26m",
+       "clk26m_d2",
+       "syspll4_d4",
+       "univpll2_d8",
+       "univpll3_d4",
+       "syspll4_d2",
+       "syspll2_d4",
+       "univpll2_d4",
+       "etherpll_125m",
+       "syspll1_d4"
+};
+
+static const char * const apll_parents[] = {
+       "clk26m",
+       "apll1_ck",
+       "apll1_d2",
+       "apll1_d4",
+       "apll1_d8",
+       "apll1_d16",
+       "apll2_ck",
+       "apll2_d2",
+       "apll2_d4",
+       "apll2_d8",
+       "apll2_d16",
+       "clk26m",
+       "clk26m"
+};
+
+static const char * const a1sys_hp_parents[] = {
+       "clk26m",
+       "apll1_ck",
+       "apll1_d2",
+       "apll1_d4",
+       "apll1_d8"
+};
+
+static const char * const a2sys_hp_parents[] = {
+       "clk26m",
+       "apll2_ck",
+       "apll2_d2",
+       "apll2_d4",
+       "apll2_d8"
+};
+
+static const char * const asm_l_parents[] = {
+       "clk26m",
+       "univpll2_d4",
+       "univpll2_d2",
+       "syspll_d5"
+};
+
+static const char * const i2so1_parents[] = {
+       "clk26m",
+       "apll1_ck",
+       "apll2_ck"
+};
+
+static const char * const ether_125m_parents[] = {
+       "clk26m",
+       "etherpll_125m",
+       "univpll3_d2"
+};
+
+static const char * const ether_50m_parents[] = {
+       "clk26m",
+       "etherpll_50m",
+       "univpll_d26",
+       "univpll3_d4"
+};
+
+static const char * const jpgdec_parents[] = {
+       "clk26m",
+       "univpll_d3",
+       "tvdpll_429m",
+       "vencpll_ck",
+       "syspll_d3",
+       "vcodecpll_ck",
+       "univpll1_d2",
+       "armca35pll_400m",
+       "tvdpll_429m_d2",
+       "tvdpll_429m_d4"
+};
+
+static const char * const spislv_parents[] = {
+       "clk26m",
+       "univpll2_d4",
+       "univpll1_d4",
+       "univpll2_d2",
+       "univpll3_d2",
+       "univpll1_d8",
+       "univpll1_d2",
+       "univpll_d5"
+};
+
+static const char * const ether_parents[] = {
+       "clk26m",
+       "etherpll_50m",
+       "univpll_d26"
+};
+
+static const char * const di_parents[] = {
+       "clk26m",
+       "tvdpll_d2",
+       "tvdpll_d4",
+       "tvdpll_d8",
+       "vencpll_ck",
+       "vencpll_d2",
+       "cvbs",
+       "cvbs_d2"
+};
+
+static const char * const tvd_parents[] = {
+       "clk26m",
+       "cvbs_d2",
+       "univpll2_d8"
+};
+
+static const char * const i2c_parents[] = {
+       "clk26m",
+       "univpll_d26",
+       "univpll2_d4",
+       "univpll3_d2",
+       "univpll1_d4"
+};
+
+static const char * const msdc0p_aes_parents[] = {
+       "clk26m",
+       "msdcpll_ck",
+       "univpll_d3",
+       "vcodecpll_ck"
+};
+
+static const char * const cmsys_parents[] = {
+       "clk26m",
+       "univpll_d3",
+       "syspll_d3",
+       "syspll1_d2",
+       "syspll2_d2"
+};
+
+static const char * const gcpu_parents[] = {
+       "clk26m",
+       "syspll_d3",
+       "syspll1_d2",
+       "univpll1_d2",
+       "univpll_d5",
+       "univpll3_d2",
+       "univpll_d3"
+};
+
+static const char * const aud_apll1_parents[] = {
+       "apll1",
+       "clkaud_ext_i_1"
+};
+
+static const char * const aud_apll2_parents[] = {
+       "apll2",
+       "clkaud_ext_i_2"
+};
+
+static const char * const audull_vtx_parents[] = {
+       "d2a_ulclk_6p5m",
+       "clkaud_ext_i_0"
+};
+
+static struct mtk_composite top_muxes[] = {
+       /* CLK_CFG_0 */
+       MUX_GATE_FLAGS(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, 0x040, 0, 3,
+               7, CLK_IS_CRITICAL),
+       MUX_GATE_FLAGS(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x040, 8, 1,
+               15, CLK_IS_CRITICAL),
+       MUX_GATE(CLK_TOP_MM_SEL, "mm_sel",
+               mm_parents, 0x040, 24, 3, 31),
+       /* CLK_CFG_1 */
+       MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel",
+               pwm_parents, 0x050, 0, 2, 7),
+       MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel",
+               vdec_parents, 0x050, 8, 4, 15),
+       MUX_GATE(CLK_TOP_VENC_SEL, "venc_sel",
+               venc_parents, 0x050, 16, 4, 23),
+       MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel",
+               mfg_parents, 0x050, 24, 4, 31),
+       /* CLK_CFG_2 */
+       MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel",
+               camtg_parents, 0x060, 0, 4, 7),
+       MUX_GATE(CLK_TOP_UART_SEL, "uart_sel",
+               uart_parents, 0x060, 8, 1, 15),
+       MUX_GATE(CLK_TOP_SPI_SEL, "spi_sel",
+               spi_parents, 0x060, 16, 3, 23),
+       MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel",
+               usb20_parents, 0x060, 24, 2, 31),
+       /* CLK_CFG_3 */
+       MUX_GATE(CLK_TOP_USB30_SEL, "usb30_sel",
+               usb30_parents, 0x070, 0, 2, 7),
+       MUX_GATE(CLK_TOP_MSDC50_0_HCLK_SEL, "msdc50_0_h_sel",
+               msdc50_0_h_parents, 0x070, 8, 3, 15),
+       MUX_GATE(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel",
+               msdc50_0_parents, 0x070, 16, 4, 23),
+       MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel",
+               msdc30_1_parents, 0x070, 24, 3, 31),
+       /* CLK_CFG_4 */
+       MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel",
+               msdc30_1_parents, 0x080, 0, 3, 7),
+       MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel",
+               msdc30_3_parents, 0x080, 8, 4, 15),
+       MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel",
+               audio_parents, 0x080, 16, 2, 23),
+       MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel",
+               aud_intbus_parents, 0x080, 24, 3, 31),
+       /* CLK_CFG_5 */
+       MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel",
+               pmicspi_parents, 0x090, 0, 3, 7),
+       MUX_GATE(CLK_TOP_DPILVDS1_SEL, "dpilvds1_sel",
+               dpilvds1_parents, 0x090, 8, 3, 15),
+       MUX_GATE(CLK_TOP_ATB_SEL, "atb_sel",
+               atb_parents, 0x090, 16, 2, 23),
+       MUX_GATE(CLK_TOP_NR_SEL, "nr_sel",
+               nr_parents, 0x090, 24, 3, 31),
+       /* CLK_CFG_6 */
+       MUX_GATE(CLK_TOP_NFI2X_SEL, "nfi2x_sel",
+               nfi2x_parents, 0x0a0, 0, 4, 7),
+       MUX_GATE(CLK_TOP_IRDA_SEL, "irda_sel",
+               irda_parents, 0x0a0, 8, 2, 15),
+       MUX_GATE(CLK_TOP_CCI400_SEL, "cci400_sel",
+               cci400_parents, 0x0a0, 16, 3, 23),
+       MUX_GATE(CLK_TOP_AUD_1_SEL, "aud_1_sel",
+               aud_1_parents, 0x0a0, 24, 2, 31),
+       /* CLK_CFG_7 */
+       MUX_GATE(CLK_TOP_AUD_2_SEL, "aud_2_sel",
+               aud_2_parents, 0x0b0, 0, 2, 7),
+       MUX_GATE(CLK_TOP_MEM_MFG_IN_AS_SEL, "mem_mfg_sel",
+               mem_mfg_parents, 0x0b0, 8, 2, 15),
+       MUX_GATE(CLK_TOP_AXI_MFG_IN_AS_SEL, "axi_mfg_sel",
+               axi_mfg_parents, 0x0b0, 16, 2, 23),
+       MUX_GATE(CLK_TOP_SCAM_SEL, "scam_sel",
+               scam_parents, 0x0b0, 24, 2, 31),
+       /* CLK_CFG_8 */
+       MUX_GATE(CLK_TOP_NFIECC_SEL, "nfiecc_sel",
+               nfiecc_parents, 0x0c0, 0, 3, 7),
+       MUX_GATE(CLK_TOP_PE2_MAC_P0_SEL, "pe2_mac_p0_sel",
+               pe2_mac_p0_parents, 0x0c0, 8, 3, 15),
+       MUX_GATE(CLK_TOP_PE2_MAC_P1_SEL, "pe2_mac_p1_sel",
+               pe2_mac_p0_parents, 0x0c0, 16, 3, 23),
+       MUX_GATE(CLK_TOP_DPILVDS_SEL, "dpilvds_sel",
+               dpilvds_parents, 0x0c0, 24, 3, 31),
+       /* CLK_CFG_9 */
+       MUX_GATE(CLK_TOP_MSDC50_3_HCLK_SEL, "msdc50_3_h_sel",
+               msdc50_0_h_parents, 0x0d0, 0, 3, 7),
+       MUX_GATE(CLK_TOP_HDCP_SEL, "hdcp_sel",
+               hdcp_parents, 0x0d0, 8, 2, 15),
+       MUX_GATE(CLK_TOP_HDCP_24M_SEL, "hdcp_24m_sel",
+               hdcp_24m_parents, 0x0d0, 16, 2, 23),
+       MUX_GATE_FLAGS(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents, 0x0d0, 24, 2,
+               31, CLK_IS_CRITICAL),
+       /* CLK_CFG_10 */
+       MUX_GATE(CLK_TOP_SPINOR_SEL, "spinor_sel",
+               spinor_parents, 0x500, 0, 4, 7),
+       MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel",
+               apll_parents, 0x500, 8, 4, 15),
+       MUX_GATE(CLK_TOP_APLL2_SEL, "apll2_sel",
+               apll_parents, 0x500, 16, 4, 23),
+       MUX_GATE(CLK_TOP_A1SYS_HP_SEL, "a1sys_hp_sel",
+               a1sys_hp_parents, 0x500, 24, 3, 31),
+       /* CLK_CFG_11 */
+       MUX_GATE(CLK_TOP_A2SYS_HP_SEL, "a2sys_hp_sel",
+               a2sys_hp_parents, 0x510, 0, 3, 7),
+       MUX_GATE(CLK_TOP_ASM_L_SEL, "asm_l_sel",
+               asm_l_parents, 0x510, 8, 2, 15),
+       MUX_GATE(CLK_TOP_ASM_M_SEL, "asm_m_sel",
+               asm_l_parents, 0x510, 16, 2, 23),
+       MUX_GATE(CLK_TOP_ASM_H_SEL, "asm_h_sel",
+               asm_l_parents, 0x510, 24, 2, 31),
+       /* CLK_CFG_12 */
+       MUX_GATE(CLK_TOP_I2SO1_SEL, "i2so1_sel",
+               i2so1_parents, 0x520, 0, 2, 7),
+       MUX_GATE(CLK_TOP_I2SO2_SEL, "i2so2_sel",
+               i2so1_parents, 0x520, 8, 2, 15),
+       MUX_GATE(CLK_TOP_I2SO3_SEL, "i2so3_sel",
+               i2so1_parents, 0x520, 16, 2, 23),
+       MUX_GATE(CLK_TOP_TDMO0_SEL, "tdmo0_sel",
+               i2so1_parents, 0x520, 24, 2, 31),
+       /* CLK_CFG_13 */
+       MUX_GATE(CLK_TOP_TDMO1_SEL, "tdmo1_sel",
+               i2so1_parents, 0x530, 0, 2, 7),
+       MUX_GATE(CLK_TOP_I2SI1_SEL, "i2si1_sel",
+               i2so1_parents, 0x530, 8, 2, 15),
+       MUX_GATE(CLK_TOP_I2SI2_SEL, "i2si2_sel",
+               i2so1_parents, 0x530, 16, 2, 23),
+       MUX_GATE(CLK_TOP_I2SI3_SEL, "i2si3_sel",
+               i2so1_parents, 0x530, 24, 2, 31),
+       /* CLK_CFG_14 */
+       MUX_GATE(CLK_TOP_ETHER_125M_SEL, "ether_125m_sel",
+               ether_125m_parents, 0x540, 0, 2, 7),
+       MUX_GATE(CLK_TOP_ETHER_50M_SEL, "ether_50m_sel",
+               ether_50m_parents, 0x540, 8, 2, 15),
+       MUX_GATE(CLK_TOP_JPGDEC_SEL, "jpgdec_sel",
+               jpgdec_parents, 0x540, 16, 4, 23),
+       MUX_GATE(CLK_TOP_SPISLV_SEL, "spislv_sel",
+               spislv_parents, 0x540, 24, 3, 31),
+       /* CLK_CFG_15 */
+       MUX_GATE(CLK_TOP_ETHER_50M_RMII_SEL, "ether_sel",
+               ether_parents, 0x550, 0, 2, 7),
+       MUX_GATE(CLK_TOP_CAM2TG_SEL, "cam2tg_sel",
+               camtg_parents, 0x550, 8, 4, 15),
+       MUX_GATE(CLK_TOP_DI_SEL, "di_sel",
+               di_parents, 0x550, 16, 3, 23),
+       MUX_GATE(CLK_TOP_TVD_SEL, "tvd_sel",
+               tvd_parents, 0x550, 24, 2, 31),
+       /* CLK_CFG_16 */
+       MUX_GATE(CLK_TOP_I2C_SEL, "i2c_sel",
+               i2c_parents, 0x560, 0, 3, 7),
+       MUX_GATE(CLK_TOP_PWM_INFRA_SEL, "pwm_infra_sel",
+               pwm_parents, 0x560, 8, 2, 15),
+       MUX_GATE(CLK_TOP_MSDC0P_AES_SEL, "msdc0p_aes_sel",
+               msdc0p_aes_parents, 0x560, 16, 2, 23),
+       MUX_GATE(CLK_TOP_CMSYS_SEL, "cmsys_sel",
+               cmsys_parents, 0x560, 24, 3, 31),
+       /* CLK_CFG_17 */
+       MUX_GATE(CLK_TOP_GCPU_SEL, "gcpu_sel",
+               gcpu_parents, 0x570, 0, 3, 7),
+       /* CLK_AUDDIV_4 */
+       MUX(CLK_TOP_AUD_APLL1_SEL, "aud_apll1_sel",
+               aud_apll1_parents, 0x134, 0, 1),
+       MUX(CLK_TOP_AUD_APLL2_SEL, "aud_apll2_sel",
+               aud_apll2_parents, 0x134, 1, 1),
+       MUX(CLK_TOP_DA_AUDULL_VTX_6P5M_SEL, "audull_vtx_sel",
+               audull_vtx_parents, 0x134, 31, 1),
+};
+
+static const char * const mcu_mp0_parents[] = {
+       "clk26m",
+       "armca35pll_ck",
+       "f_mp0_pll1_ck",
+       "f_mp0_pll2_ck"
+};
+
+static const char * const mcu_mp2_parents[] = {
+       "clk26m",
+       "armca72pll_ck",
+       "f_big_pll1_ck",
+       "f_big_pll2_ck"
+};
+
+static const char * const mcu_bus_parents[] = {
+       "clk26m",
+       "cci400_sel",
+       "f_bus_pll1_ck",
+       "f_bus_pll2_ck"
+};
+
+static struct mtk_composite mcu_muxes[] = {
+       /* mp0_pll_divider_cfg */
+       MUX_GATE_FLAGS(CLK_MCU_MP0_SEL, "mcu_mp0_sel", mcu_mp0_parents, 0x7A0,
+               9, 2, -1, CLK_IS_CRITICAL),
+       /* mp2_pll_divider_cfg */
+       MUX_GATE_FLAGS(CLK_MCU_MP2_SEL, "mcu_mp2_sel", mcu_mp2_parents, 0x7A8,
+               9, 2, -1, CLK_IS_CRITICAL),
+       /* bus_pll_divider_cfg */
+       MUX_GATE_FLAGS(CLK_MCU_BUS_SEL, "mcu_bus_sel", mcu_bus_parents, 0x7C0,
+               9, 2, -1, CLK_IS_CRITICAL),
+};
+
+static const struct mtk_clk_divider top_adj_divs[] = {
+       DIV_ADJ(CLK_TOP_APLL_DIV0, "apll_div0", "i2so1_sel", 0x124, 0, 8),
+       DIV_ADJ(CLK_TOP_APLL_DIV1, "apll_div1", "i2so2_sel", 0x124, 8, 8),
+       DIV_ADJ(CLK_TOP_APLL_DIV2, "apll_div2", "i2so3_sel", 0x124, 16, 8),
+       DIV_ADJ(CLK_TOP_APLL_DIV3, "apll_div3", "tdmo0_sel", 0x124, 24, 8),
+       DIV_ADJ(CLK_TOP_APLL_DIV4, "apll_div4", "tdmo1_sel", 0x128, 0, 8),
+       DIV_ADJ(CLK_TOP_APLL_DIV5, "apll_div5", "i2si1_sel", 0x128, 8, 8),
+       DIV_ADJ(CLK_TOP_APLL_DIV6, "apll_div6", "i2si2_sel", 0x128, 16, 8),
+       DIV_ADJ(CLK_TOP_APLL_DIV7, "apll_div7", "i2si3_sel", 0x128, 24, 8),
+};
+
+static const struct mtk_gate_regs top_cg_regs = {
+       .set_ofs = 0x120,
+       .clr_ofs = 0x120,
+       .sta_ofs = 0x120,
+};
+
+#define GATE_TOP(_id, _name, _parent, _shift) {        \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &top_cg_regs,                   \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_no_setclr,     \
+       }
+
+static const struct mtk_gate top_clks[] = {
+       GATE_TOP(CLK_TOP_APLL_DIV_PDN0, "apll_div_pdn0", "i2so1_sel", 0),
+       GATE_TOP(CLK_TOP_APLL_DIV_PDN1, "apll_div_pdn1", "i2so2_sel", 1),
+       GATE_TOP(CLK_TOP_APLL_DIV_PDN2, "apll_div_pdn2", "i2so3_sel", 2),
+       GATE_TOP(CLK_TOP_APLL_DIV_PDN3, "apll_div_pdn3", "tdmo0_sel", 3),
+       GATE_TOP(CLK_TOP_APLL_DIV_PDN4, "apll_div_pdn4", "tdmo1_sel", 4),
+       GATE_TOP(CLK_TOP_APLL_DIV_PDN5, "apll_div_pdn5", "i2si1_sel", 5),
+       GATE_TOP(CLK_TOP_APLL_DIV_PDN6, "apll_div_pdn6", "i2si2_sel", 6),
+       GATE_TOP(CLK_TOP_APLL_DIV_PDN7, "apll_div_pdn7", "i2si3_sel", 7),
+};
+
+static const struct mtk_gate_regs infra_cg_regs = {
+       .set_ofs = 0x40,
+       .clr_ofs = 0x44,
+       .sta_ofs = 0x40,
+};
+
+#define GATE_INFRA(_id, _name, _parent, _shift) {      \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &infra_cg_regs,                 \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+static const struct mtk_gate infra_clks[] = {
+       GATE_INFRA(CLK_INFRA_DBGCLK, "infra_dbgclk", "axi_sel", 0),
+       GATE_INFRA(CLK_INFRA_GCE, "infra_gce", "axi_sel", 6),
+       GATE_INFRA(CLK_INFRA_M4U, "infra_m4u", "mem_sel", 8),
+       GATE_INFRA(CLK_INFRA_KP, "infra_kp", "axi_sel", 16),
+       GATE_INFRA(CLK_INFRA_AO_SPI0, "infra_ao_spi0", "spi_sel", 24),
+       GATE_INFRA(CLK_INFRA_AO_SPI1, "infra_ao_spi1", "spislv_sel", 25),
+       GATE_INFRA(CLK_INFRA_AO_UART5, "infra_ao_uart5", "axi_sel", 26),
+};
+
+static const struct mtk_gate_regs peri0_cg_regs = {
+       .set_ofs = 0x8,
+       .clr_ofs = 0x10,
+       .sta_ofs = 0x18,
+};
+
+static const struct mtk_gate_regs peri1_cg_regs = {
+       .set_ofs = 0xc,
+       .clr_ofs = 0x14,
+       .sta_ofs = 0x1c,
+};
+
+static const struct mtk_gate_regs peri2_cg_regs = {
+       .set_ofs = 0x42c,
+       .clr_ofs = 0x42c,
+       .sta_ofs = 0x42c,
+};
+
+#define GATE_PERI0(_id, _name, _parent, _shift) {      \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &peri0_cg_regs,                 \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+#define GATE_PERI1(_id, _name, _parent, _shift) {      \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &peri1_cg_regs,                 \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_setclr,        \
+       }
+
+#define GATE_PERI2(_id, _name, _parent, _shift) {      \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &peri2_cg_regs,                 \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+       }
+
+static const struct mtk_gate peri_clks[] = {
+       /* PERI0 */
+       GATE_PERI0(CLK_PERI_NFI, "per_nfi",
+               "axi_sel", 0),
+       GATE_PERI0(CLK_PERI_THERM, "per_therm",
+               "axi_sel", 1),
+       GATE_PERI0(CLK_PERI_PWM0, "per_pwm0",
+               "pwm_sel", 2),
+       GATE_PERI0(CLK_PERI_PWM1, "per_pwm1",
+               "pwm_sel", 3),
+       GATE_PERI0(CLK_PERI_PWM2, "per_pwm2",
+               "pwm_sel", 4),
+       GATE_PERI0(CLK_PERI_PWM3, "per_pwm3",
+               "pwm_sel", 5),
+       GATE_PERI0(CLK_PERI_PWM4, "per_pwm4",
+               "pwm_sel", 6),
+       GATE_PERI0(CLK_PERI_PWM5, "per_pwm5",
+               "pwm_sel", 7),
+       GATE_PERI0(CLK_PERI_PWM6, "per_pwm6",
+               "pwm_sel", 8),
+       GATE_PERI0(CLK_PERI_PWM7, "per_pwm7",
+               "pwm_sel", 9),
+       GATE_PERI0(CLK_PERI_PWM, "per_pwm",
+               "pwm_sel", 10),
+       GATE_PERI0(CLK_PERI_AP_DMA, "per_ap_dma",
+               "axi_sel", 13),
+       GATE_PERI0(CLK_PERI_MSDC30_0, "per_msdc30_0",
+               "msdc50_0_sel", 14),
+       GATE_PERI0(CLK_PERI_MSDC30_1, "per_msdc30_1",
+               "msdc30_1_sel", 15),
+       GATE_PERI0(CLK_PERI_MSDC30_2, "per_msdc30_2",
+               "msdc30_2_sel", 16),
+       GATE_PERI0(CLK_PERI_MSDC30_3, "per_msdc30_3",
+               "msdc30_3_sel", 17),
+       GATE_PERI0(CLK_PERI_UART0, "per_uart0",
+               "uart_sel", 20),
+       GATE_PERI0(CLK_PERI_UART1, "per_uart1",
+               "uart_sel", 21),
+       GATE_PERI0(CLK_PERI_UART2, "per_uart2",
+               "uart_sel", 22),
+       GATE_PERI0(CLK_PERI_UART3, "per_uart3",
+               "uart_sel", 23),
+       GATE_PERI0(CLK_PERI_I2C0, "per_i2c0",
+               "axi_sel", 24),
+       GATE_PERI0(CLK_PERI_I2C1, "per_i2c1",
+               "axi_sel", 25),
+       GATE_PERI0(CLK_PERI_I2C2, "per_i2c2",
+               "axi_sel", 26),
+       GATE_PERI0(CLK_PERI_I2C3, "per_i2c3",
+               "axi_sel", 27),
+       GATE_PERI0(CLK_PERI_I2C4, "per_i2c4",
+               "axi_sel", 28),
+       GATE_PERI0(CLK_PERI_AUXADC, "per_auxadc",
+               "ltepll_fs26m", 29),
+       GATE_PERI0(CLK_PERI_SPI0, "per_spi0",
+               "spi_sel", 30),
+       /* PERI1 */
+       GATE_PERI1(CLK_PERI_SPI, "per_spi",
+               "spinor_sel", 1),
+       GATE_PERI1(CLK_PERI_I2C5, "per_i2c5",
+               "axi_sel", 3),
+       GATE_PERI1(CLK_PERI_SPI2, "per_spi2",
+               "spi_sel", 5),
+       GATE_PERI1(CLK_PERI_SPI3, "per_spi3",
+               "spi_sel", 6),
+       GATE_PERI1(CLK_PERI_SPI5, "per_spi5",
+               "spi_sel", 8),
+       GATE_PERI1(CLK_PERI_UART4, "per_uart4",
+               "uart_sel", 9),
+       GATE_PERI1(CLK_PERI_SFLASH, "per_sflash",
+               "uart_sel", 11),
+       GATE_PERI1(CLK_PERI_GMAC, "per_gmac",
+               "uart_sel", 12),
+       GATE_PERI1(CLK_PERI_PCIE0, "per_pcie0",
+               "uart_sel", 14),
+       GATE_PERI1(CLK_PERI_PCIE1, "per_pcie1",
+               "uart_sel", 15),
+       GATE_PERI1(CLK_PERI_GMAC_PCLK, "per_gmac_pclk",
+               "uart_sel", 16),
+       /* PERI2 */
+       GATE_PERI2(CLK_PERI_MSDC50_0_EN, "per_msdc50_0_en",
+               "msdc50_0_sel", 0),
+       GATE_PERI2(CLK_PERI_MSDC30_1_EN, "per_msdc30_1_en",
+               "msdc30_1_sel", 1),
+       GATE_PERI2(CLK_PERI_MSDC30_2_EN, "per_msdc30_2_en",
+               "msdc30_2_sel", 2),
+       GATE_PERI2(CLK_PERI_MSDC30_3_EN, "per_msdc30_3_en",
+               "msdc30_3_sel", 3),
+       GATE_PERI2(CLK_PERI_MSDC50_0_HCLK_EN, "per_msdc50_0_h",
+               "msdc50_0_h_sel", 4),
+       GATE_PERI2(CLK_PERI_MSDC50_3_HCLK_EN, "per_msdc50_3_h",
+               "msdc50_3_h_sel", 5),
+};
+
+#define MT2712_PLL_FMAX                (3000UL * MHZ)
+
+#define CON0_MT2712_RST_BAR    BIT(24)
+
+#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,  \
+                       _pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg,  \
+                       _tuner_en_bit, _pcw_reg, _pcw_shift,            \
+                       _div_table) {                                   \
+               .id = _id,                                              \
+               .name = _name,                                          \
+               .reg = _reg,                                            \
+               .pwr_reg = _pwr_reg,                                    \
+               .en_mask = _en_mask,                                    \
+               .flags = _flags,                                        \
+               .rst_bar_mask = CON0_MT2712_RST_BAR,                    \
+               .fmax = MT2712_PLL_FMAX,                                \
+               .pcwbits = _pcwbits,                                    \
+               .pd_reg = _pd_reg,                                      \
+               .pd_shift = _pd_shift,                                  \
+               .tuner_reg = _tuner_reg,                                \
+               .tuner_en_reg = _tuner_en_reg,                          \
+               .tuner_en_bit = _tuner_en_bit,                          \
+               .pcw_reg = _pcw_reg,                                    \
+               .pcw_shift = _pcw_shift,                                \
+               .div_table = _div_table,                                \
+       }
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,    \
+                       _pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg,  \
+                       _tuner_en_bit, _pcw_reg, _pcw_shift)            \
+               PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags,     \
+                       _pcwbits, _pd_reg, _pd_shift, _tuner_reg,       \
+                       _tuner_en_reg, _tuner_en_bit, _pcw_reg,         \
+                       _pcw_shift, NULL)
+
+static const struct mtk_pll_div_table armca35pll_div_table[] = {
+       { .div = 0, .freq = MT2712_PLL_FMAX },
+       { .div = 1, .freq = 1202500000 },
+       { .div = 2, .freq = 500500000 },
+       { .div = 3, .freq = 315250000 },
+       { .div = 4, .freq = 157625000 },
+       { } /* sentinel */
+};
+
+static const struct mtk_pll_div_table armca72pll_div_table[] = {
+       { .div = 0, .freq = MT2712_PLL_FMAX },
+       { .div = 1, .freq = 994500000 },
+       { .div = 2, .freq = 520000000 },
+       { .div = 3, .freq = 315250000 },
+       { .div = 4, .freq = 157625000 },
+       { } /* sentinel */
+};
+
+static const struct mtk_pll_div_table mmpll_div_table[] = {
+       { .div = 0, .freq = MT2712_PLL_FMAX },
+       { .div = 1, .freq = 1001000000 },
+       { .div = 2, .freq = 601250000 },
+       { .div = 3, .freq = 250250000 },
+       { .div = 4, .freq = 125125000 },
+       { } /* sentinel */
+};
+
+static const struct mtk_pll_data plls[] = {
+       PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0230, 0x023C, 0xf0000101,
+               HAVE_RST_BAR, 31, 0x0230, 4, 0, 0, 0, 0x0234, 0),
+       PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x0240, 0x024C, 0xfe000101,
+               HAVE_RST_BAR, 31, 0x0240, 4, 0, 0, 0, 0x0244, 0),
+       PLL(CLK_APMIXED_VCODECPLL, "vcodecpll", 0x0320, 0x032C, 0xc0000101,
+               0, 31, 0x0320, 4, 0, 0, 0, 0x0324, 0),
+       PLL(CLK_APMIXED_VENCPLL, "vencpll", 0x0280, 0x028C, 0x00000101,
+               0, 31, 0x0280, 4, 0, 0, 0, 0x0284, 0),
+       PLL(CLK_APMIXED_APLL1, "apll1", 0x0330, 0x0340, 0x00000101,
+               0, 31, 0x0330, 4, 0x0338, 0x0014, 0, 0x0334, 0),
+       PLL(CLK_APMIXED_APLL2, "apll2", 0x0350, 0x0360, 0x00000101,
+               0, 31, 0x0350, 4, 0x0358, 0x0014, 1, 0x0354, 0),
+       PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x0370, 0x037c, 0x00000101,
+               0, 31, 0x0370, 4, 0, 0, 0, 0x0374, 0),
+       PLL(CLK_APMIXED_LVDSPLL2, "lvdspll2", 0x0390, 0x039C, 0x00000101,
+               0, 31, 0x0390, 4, 0, 0, 0, 0x0394, 0),
+       PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0270, 0x027C, 0x00000101,
+               0, 31, 0x0270, 4, 0, 0, 0, 0x0274, 0),
+       PLL(CLK_APMIXED_MSDCPLL2, "msdcpll2", 0x0410, 0x041C, 0x00000101,
+               0, 31, 0x0410, 4, 0, 0, 0, 0x0414, 0),
+       PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x0290, 0x029C, 0xc0000101,
+               0, 31, 0x0290, 4, 0, 0, 0, 0x0294, 0),
+       PLL_B(CLK_APMIXED_MMPLL, "mmpll", 0x0250, 0x0260, 0x00000101,
+               0, 31, 0x0250, 4, 0, 0, 0, 0x0254, 0,
+               mmpll_div_table),
+       PLL_B(CLK_APMIXED_ARMCA35PLL, "armca35pll", 0x0100, 0x0110, 0xf0000101,
+               HAVE_RST_BAR, 31, 0x0100, 4, 0, 0, 0, 0x0104, 0,
+               armca35pll_div_table),
+       PLL_B(CLK_APMIXED_ARMCA72PLL, "armca72pll", 0x0210, 0x0220, 0x00000101,
+               0, 31, 0x0210, 4, 0, 0, 0, 0x0214, 0,
+               armca72pll_div_table),
+       PLL(CLK_APMIXED_ETHERPLL, "etherpll", 0x0300, 0x030C, 0xc0000101,
+               0, 31, 0x0300, 4, 0, 0, 0, 0x0304, 0),
+};
+
+static int clk_mt2712_apmixed_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
+
+       mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r != 0)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+       return r;
+}
+
+static struct clk_onecell_data *top_clk_data;
+
+static void clk_mt2712_top_init_early(struct device_node *node)
+{
+       int r, i;
+
+       if (!top_clk_data) {
+               top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
+
+               for (i = 0; i < CLK_TOP_NR_CLK; i++)
+                       top_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
+       }
+
+       mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs),
+                       top_clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+}
+
+CLK_OF_DECLARE_DRIVER(mt2712_topckgen, "mediatek,mt2712-topckgen",
+                       clk_mt2712_top_init_early);
+
+static int clk_mt2712_top_probe(struct platform_device *pdev)
+{
+       int r, i;
+       struct device_node *node = pdev->dev.of_node;
+       void __iomem *base;
+       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(base)) {
+               pr_err("%s(): ioremap failed\n", __func__);
+               return PTR_ERR(base);
+       }
+
+       if (!top_clk_data) {
+               top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
+       } else {
+               for (i = 0; i < CLK_TOP_NR_CLK; i++) {
+                       if (top_clk_data->clks[i] == ERR_PTR(-EPROBE_DEFER))
+                               top_clk_data->clks[i] = ERR_PTR(-ENOENT);
+               }
+       }
+
+       mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
+                       top_clk_data);
+       mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs),
+                       top_clk_data);
+       mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
+       mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
+                       &mt2712_clk_lock, top_clk_data);
+       mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
+                       &mt2712_clk_lock, top_clk_data);
+       mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
+                       top_clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
+
+       if (r != 0)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+       return r;
+}
+
+static int clk_mt2712_infra_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
+
+       mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+                       clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r != 0)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+       mtk_register_reset_controller(node, 2, 0x30);
+
+       return r;
+}
+
+static int clk_mt2712_peri_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
+
+       mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
+                       clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r != 0)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+       mtk_register_reset_controller(node, 2, 0);
+
+       return r;
+}
+
+static int clk_mt2712_mcu_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+       struct device_node *node = pdev->dev.of_node;
+       void __iomem *base;
+       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(base)) {
+               pr_err("%s(): ioremap failed\n", __func__);
+               return PTR_ERR(base);
+       }
+
+       clk_data = mtk_alloc_clk_data(CLK_MCU_NR_CLK);
+
+       mtk_clk_register_composites(mcu_muxes, ARRAY_SIZE(mcu_muxes), base,
+                       &mt2712_clk_lock, clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r != 0)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
+       return r;
+}
+
+static const struct of_device_id of_match_clk_mt2712[] = {
+       {
+               .compatible = "mediatek,mt2712-apmixedsys",
+               .data = clk_mt2712_apmixed_probe,
+       }, {
+               .compatible = "mediatek,mt2712-topckgen",
+               .data = clk_mt2712_top_probe,
+       }, {
+               .compatible = "mediatek,mt2712-infracfg",
+               .data = clk_mt2712_infra_probe,
+       }, {
+               .compatible = "mediatek,mt2712-pericfg",
+               .data = clk_mt2712_peri_probe,
+       }, {
+               .compatible = "mediatek,mt2712-mcucfg",
+               .data = clk_mt2712_mcu_probe,
+       }, {
+               /* sentinel */
+       }
+};
+
+static int clk_mt2712_probe(struct platform_device *pdev)
+{
+       int (*clk_probe)(struct platform_device *);
+       int r;
+
+       clk_probe = of_device_get_match_data(&pdev->dev);
+       if (!clk_probe)
+               return -EINVAL;
+
+       r = clk_probe(pdev);
+       if (r != 0)
+               dev_err(&pdev->dev,
+                       "could not register clock provider: %s: %d\n",
+                       pdev->name, r);
+
+       return r;
+}
+
+static struct platform_driver clk_mt2712_drv = {
+       .probe = clk_mt2712_probe,
+       .driver = {
+               .name = "clk-mt2712",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_clk_mt2712,
+       },
+};
+
+static int __init clk_mt2712_init(void)
+{
+       return platform_driver_register(&clk_mt2712_drv);
+}
+
+arch_initcall(clk_mt2712_init);
diff --git a/drivers/clk/mediatek/clk-mt7622-aud.c b/drivers/clk/mediatek/clk-mt7622-aud.c
new file mode 100644 (file)
index 0000000..fad7d9f
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
+ *        Sean Wang <sean.wang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt7622-clk.h>
+
+#define GATE_AUDIO0(_id, _name, _parent, _shift) {     \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &audio0_cg_regs,                        \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_no_setclr,     \
+       }
+
+#define GATE_AUDIO1(_id, _name, _parent, _shift) {     \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &audio1_cg_regs,                        \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_no_setclr,     \
+       }
+
+#define GATE_AUDIO2(_id, _name, _parent, _shift) {     \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &audio2_cg_regs,                        \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_no_setclr,     \
+       }
+
+#define GATE_AUDIO3(_id, _name, _parent, _shift) {     \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &audio3_cg_regs,                        \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_no_setclr,     \
+       }
+
+static const struct mtk_gate_regs audio0_cg_regs = {
+       .set_ofs = 0x0,
+       .clr_ofs = 0x0,
+       .sta_ofs = 0x0,
+};
+
+static const struct mtk_gate_regs audio1_cg_regs = {
+       .set_ofs = 0x10,
+       .clr_ofs = 0x10,
+       .sta_ofs = 0x10,
+};
+
+static const struct mtk_gate_regs audio2_cg_regs = {
+       .set_ofs = 0x14,
+       .clr_ofs = 0x14,
+       .sta_ofs = 0x14,
+};
+
+static const struct mtk_gate_regs audio3_cg_regs = {
+       .set_ofs = 0x634,
+       .clr_ofs = 0x634,
+       .sta_ofs = 0x634,
+};
+
+static const struct mtk_gate audio_clks[] = {
+       /* AUDIO0 */
+       GATE_AUDIO0(CLK_AUDIO_AFE, "audio_afe", "rtc", 2),
+       GATE_AUDIO0(CLK_AUDIO_HDMI, "audio_hdmi", "apll1_ck_sel", 20),
+       GATE_AUDIO0(CLK_AUDIO_SPDF, "audio_spdf", "apll1_ck_sel", 21),
+       GATE_AUDIO0(CLK_AUDIO_APLL, "audio_apll", "apll1_ck_sel", 23),
+       /* AUDIO1 */
+       GATE_AUDIO1(CLK_AUDIO_I2SIN1, "audio_i2sin1", "a1sys_hp_sel", 0),
+       GATE_AUDIO1(CLK_AUDIO_I2SIN2, "audio_i2sin2", "a1sys_hp_sel", 1),
+       GATE_AUDIO1(CLK_AUDIO_I2SIN3, "audio_i2sin3", "a1sys_hp_sel", 2),
+       GATE_AUDIO1(CLK_AUDIO_I2SIN4, "audio_i2sin4", "a1sys_hp_sel", 3),
+       GATE_AUDIO1(CLK_AUDIO_I2SO1, "audio_i2so1", "a1sys_hp_sel", 6),
+       GATE_AUDIO1(CLK_AUDIO_I2SO2, "audio_i2so2", "a1sys_hp_sel", 7),
+       GATE_AUDIO1(CLK_AUDIO_I2SO3, "audio_i2so3", "a1sys_hp_sel", 8),
+       GATE_AUDIO1(CLK_AUDIO_I2SO4, "audio_i2so4", "a1sys_hp_sel", 9),
+       GATE_AUDIO1(CLK_AUDIO_ASRCI1, "audio_asrci1", "asm_h_sel", 12),
+       GATE_AUDIO1(CLK_AUDIO_ASRCI2, "audio_asrci2", "asm_h_sel", 13),
+       GATE_AUDIO1(CLK_AUDIO_ASRCO1, "audio_asrco1", "asm_h_sel", 14),
+       GATE_AUDIO1(CLK_AUDIO_ASRCO2, "audio_asrco2", "asm_h_sel", 15),
+       GATE_AUDIO1(CLK_AUDIO_INTDIR, "audio_intdir", "intdir_sel", 20),
+       GATE_AUDIO1(CLK_AUDIO_A1SYS, "audio_a1sys", "a1sys_hp_sel", 21),
+       GATE_AUDIO1(CLK_AUDIO_A2SYS, "audio_a2sys", "a2sys_hp_sel", 22),
+       /* AUDIO2 */
+       GATE_AUDIO2(CLK_AUDIO_UL1, "audio_ul1", "a1sys_hp_sel", 0),
+       GATE_AUDIO2(CLK_AUDIO_UL2, "audio_ul2", "a1sys_hp_sel", 1),
+       GATE_AUDIO2(CLK_AUDIO_UL3, "audio_ul3", "a1sys_hp_sel", 2),
+       GATE_AUDIO2(CLK_AUDIO_UL4, "audio_ul4", "a1sys_hp_sel", 3),
+       GATE_AUDIO2(CLK_AUDIO_UL5, "audio_ul5", "a1sys_hp_sel", 4),
+       GATE_AUDIO2(CLK_AUDIO_UL6, "audio_ul6", "a1sys_hp_sel", 5),
+       GATE_AUDIO2(CLK_AUDIO_DL1, "audio_dl1", "a1sys_hp_sel", 6),
+       GATE_AUDIO2(CLK_AUDIO_DL2, "audio_dl2", "a1sys_hp_sel", 7),
+       GATE_AUDIO2(CLK_AUDIO_DL3, "audio_dl3", "a1sys_hp_sel", 8),
+       GATE_AUDIO2(CLK_AUDIO_DL4, "audio_dl4", "a1sys_hp_sel", 9),
+       GATE_AUDIO2(CLK_AUDIO_DL5, "audio_dl5", "a1sys_hp_sel", 10),
+       GATE_AUDIO2(CLK_AUDIO_DL6, "audio_dl6", "a1sys_hp_sel", 11),
+       GATE_AUDIO2(CLK_AUDIO_DLMCH, "audio_dlmch", "a1sys_hp_sel", 12),
+       GATE_AUDIO2(CLK_AUDIO_ARB1, "audio_arb1", "a1sys_hp_sel", 13),
+       GATE_AUDIO2(CLK_AUDIO_AWB, "audio_awb", "a1sys_hp_sel", 14),
+       GATE_AUDIO2(CLK_AUDIO_AWB2, "audio_awb2", "a1sys_hp_sel", 15),
+       GATE_AUDIO2(CLK_AUDIO_DAI, "audio_dai", "a1sys_hp_sel", 16),
+       GATE_AUDIO2(CLK_AUDIO_MOD, "audio_mod", "a1sys_hp_sel", 17),
+       /* AUDIO3 */
+       GATE_AUDIO3(CLK_AUDIO_ASRCI3, "audio_asrci3", "asm_h_sel", 2),
+       GATE_AUDIO3(CLK_AUDIO_ASRCI4, "audio_asrci4", "asm_h_sel", 3),
+       GATE_AUDIO3(CLK_AUDIO_ASRCO3, "audio_asrco3", "asm_h_sel", 6),
+       GATE_AUDIO3(CLK_AUDIO_ASRCO4, "audio_asrco4", "asm_h_sel", 7),
+       GATE_AUDIO3(CLK_AUDIO_MEM_ASRC1, "audio_mem_asrc1", "asm_h_sel", 10),
+       GATE_AUDIO3(CLK_AUDIO_MEM_ASRC2, "audio_mem_asrc2", "asm_h_sel", 11),
+       GATE_AUDIO3(CLK_AUDIO_MEM_ASRC3, "audio_mem_asrc3", "asm_h_sel", 12),
+       GATE_AUDIO3(CLK_AUDIO_MEM_ASRC4, "audio_mem_asrc4", "asm_h_sel", 13),
+       GATE_AUDIO3(CLK_AUDIO_MEM_ASRC5, "audio_mem_asrc5", "asm_h_sel", 14),
+};
+
+static int clk_mt7622_audiosys_init(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_AUDIO_NR_CLK);
+
+       mtk_clk_register_gates(node, audio_clks, ARRAY_SIZE(audio_clks),
+                              clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               dev_err(&pdev->dev,
+                       "could not register clock provider: %s: %d\n",
+                       pdev->name, r);
+
+       return r;
+}
+
+static const struct of_device_id of_match_clk_mt7622_aud[] = {
+       {
+               .compatible = "mediatek,mt7622-audsys",
+               .data = clk_mt7622_audiosys_init,
+       }, {
+               /* sentinel */
+       }
+};
+
+static int clk_mt7622_aud_probe(struct platform_device *pdev)
+{
+       int (*clk_init)(struct platform_device *);
+       int r;
+
+       clk_init = of_device_get_match_data(&pdev->dev);
+       if (!clk_init)
+               return -EINVAL;
+
+       r = clk_init(pdev);
+       if (r)
+               dev_err(&pdev->dev,
+                       "could not register clock provider: %s: %d\n",
+                       pdev->name, r);
+
+       return r;
+}
+
+static struct platform_driver clk_mt7622_aud_drv = {
+       .probe = clk_mt7622_aud_probe,
+       .driver = {
+               .name = "clk-mt7622-aud",
+               .of_match_table = of_match_clk_mt7622_aud,
+       },
+};
+
+builtin_platform_driver(clk_mt7622_aud_drv);
diff --git a/drivers/clk/mediatek/clk-mt7622-eth.c b/drivers/clk/mediatek/clk-mt7622-eth.c
new file mode 100644 (file)
index 0000000..6328127
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
+ *        Sean Wang <sean.wang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt7622-clk.h>
+
+#define GATE_ETH(_id, _name, _parent, _shift) {        \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &eth_cg_regs,                   \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+       }
+
+static const struct mtk_gate_regs eth_cg_regs = {
+       .set_ofs = 0x30,
+       .clr_ofs = 0x30,
+       .sta_ofs = 0x30,
+};
+
+static const struct mtk_gate eth_clks[] = {
+       GATE_ETH(CLK_ETH_HSDMA_EN, "eth_hsdma_en", "eth_sel", 5),
+       GATE_ETH(CLK_ETH_ESW_EN, "eth_esw_en", "eth_500m", 6),
+       GATE_ETH(CLK_ETH_GP2_EN, "eth_gp2_en", "txclk_src_pre", 7),
+       GATE_ETH(CLK_ETH_GP1_EN, "eth_gp1_en", "txclk_src_pre", 8),
+       GATE_ETH(CLK_ETH_GP0_EN, "eth_gp0_en", "txclk_src_pre", 9),
+};
+
+static const struct mtk_gate_regs sgmii_cg_regs = {
+       .set_ofs = 0xE4,
+       .clr_ofs = 0xE4,
+       .sta_ofs = 0xE4,
+};
+
+#define GATE_SGMII(_id, _name, _parent, _shift) {      \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &sgmii_cg_regs,                 \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+       }
+
+static const struct mtk_gate sgmii_clks[] = {
+       GATE_SGMII(CLK_SGMII_TX250M_EN, "sgmii_tx250m_en",
+                  "ssusb_tx250m", 2),
+       GATE_SGMII(CLK_SGMII_RX250M_EN, "sgmii_rx250m_en",
+                  "ssusb_eq_rx250m", 3),
+       GATE_SGMII(CLK_SGMII_CDR_REF, "sgmii_cdr_ref",
+                  "ssusb_cdr_ref", 4),
+       GATE_SGMII(CLK_SGMII_CDR_FB, "sgmii_cdr_fb",
+                  "ssusb_cdr_fb", 5),
+};
+
+static int clk_mt7622_ethsys_init(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_ETH_NR_CLK);
+
+       mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks),
+                              clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               dev_err(&pdev->dev,
+                       "could not register clock provider: %s: %d\n",
+                       pdev->name, r);
+
+       mtk_register_reset_controller(node, 1, 0x34);
+
+       return r;
+}
+
+static int clk_mt7622_sgmiisys_init(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_SGMII_NR_CLK);
+
+       mtk_clk_register_gates(node, sgmii_clks, ARRAY_SIZE(sgmii_clks),
+                              clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               dev_err(&pdev->dev,
+                       "could not register clock provider: %s: %d\n",
+                       pdev->name, r);
+
+       return r;
+}
+
+static const struct of_device_id of_match_clk_mt7622_eth[] = {
+       {
+               .compatible = "mediatek,mt7622-ethsys",
+               .data = clk_mt7622_ethsys_init,
+       }, {
+               .compatible = "mediatek,mt7622-sgmiisys",
+               .data = clk_mt7622_sgmiisys_init,
+       }, {
+               /* sentinel */
+       }
+};
+
+static int clk_mt7622_eth_probe(struct platform_device *pdev)
+{
+       int (*clk_init)(struct platform_device *);
+       int r;
+
+       clk_init = of_device_get_match_data(&pdev->dev);
+       if (!clk_init)
+               return -EINVAL;
+
+       r = clk_init(pdev);
+       if (r)
+               dev_err(&pdev->dev,
+                       "could not register clock provider: %s: %d\n",
+                       pdev->name, r);
+
+       return r;
+}
+
+static struct platform_driver clk_mt7622_eth_drv = {
+       .probe = clk_mt7622_eth_probe,
+       .driver = {
+               .name = "clk-mt7622-eth",
+               .of_match_table = of_match_clk_mt7622_eth,
+       },
+};
+
+builtin_platform_driver(clk_mt7622_eth_drv);
diff --git a/drivers/clk/mediatek/clk-mt7622-hif.c b/drivers/clk/mediatek/clk-mt7622-hif.c
new file mode 100644 (file)
index 0000000..a6e8534
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
+ *        Sean Wang <sean.wang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt7622-clk.h>
+
+#define GATE_PCIE(_id, _name, _parent, _shift) {       \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &pcie_cg_regs,                  \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+       }
+
+#define GATE_SSUSB(_id, _name, _parent, _shift) {      \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent_name = _parent,                 \
+               .regs = &ssusb_cg_regs,                 \
+               .shift = _shift,                        \
+               .ops = &mtk_clk_gate_ops_no_setclr_inv, \
+       }
+
+static const struct mtk_gate_regs pcie_cg_regs = {
+       .set_ofs = 0x30,
+       .clr_ofs = 0x30,
+       .sta_ofs = 0x30,
+};
+
+static const struct mtk_gate_regs ssusb_cg_regs = {
+       .set_ofs = 0x30,
+       .clr_ofs = 0x30,
+       .sta_ofs = 0x30,
+};
+
+static const struct mtk_gate ssusb_clks[] = {
+       GATE_SSUSB(CLK_SSUSB_U2_PHY_1P_EN, "ssusb_u2_phy_1p",
+                  "to_u2_phy_1p", 0),
+       GATE_SSUSB(CLK_SSUSB_U2_PHY_EN, "ssusb_u2_phy_en", "to_u2_phy", 1),
+       GATE_SSUSB(CLK_SSUSB_REF_EN, "ssusb_ref_en", "to_usb3_ref", 5),
+       GATE_SSUSB(CLK_SSUSB_SYS_EN, "ssusb_sys_en", "to_usb3_sys", 6),
+       GATE_SSUSB(CLK_SSUSB_MCU_EN, "ssusb_mcu_en", "axi_sel", 7),
+       GATE_SSUSB(CLK_SSUSB_DMA_EN, "ssusb_dma_en", "hif_sel", 8),
+};
+
+static const struct mtk_gate pcie_clks[] = {
+       GATE_PCIE(CLK_PCIE_P1_AUX_EN, "pcie_p1_aux_en", "p1_1mhz", 12),
+       GATE_PCIE(CLK_PCIE_P1_OBFF_EN, "pcie_p1_obff_en", "free_run_4mhz", 13),
+       GATE_PCIE(CLK_PCIE_P1_AHB_EN, "pcie_p1_ahb_en", "axi_sel", 14),
+       GATE_PCIE(CLK_PCIE_P1_AXI_EN, "pcie_p1_axi_en", "hif_sel", 15),
+       GATE_PCIE(CLK_PCIE_P1_MAC_EN, "pcie_p1_mac_en", "pcie1_mac_en", 16),
+       GATE_PCIE(CLK_PCIE_P1_PIPE_EN, "pcie_p1_pipe_en", "pcie1_pipe_en", 17),
+       GATE_PCIE(CLK_PCIE_P0_AUX_EN, "pcie_p0_aux_en", "p0_1mhz", 18),
+       GATE_PCIE(CLK_PCIE_P0_OBFF_EN, "pcie_p0_obff_en", "free_run_4mhz", 19),
+       GATE_PCIE(CLK_PCIE_P0_AHB_EN, "pcie_p0_ahb_en", "axi_sel", 20),
+       GATE_PCIE(CLK_PCIE_P0_AXI_EN, "pcie_p0_axi_en", "hif_sel", 21),
+       GATE_PCIE(CLK_PCIE_P0_MAC_EN, "pcie_p0_mac_en", "pcie0_mac_en", 22),
+       GATE_PCIE(CLK_PCIE_P0_PIPE_EN, "pcie_p0_pipe_en", "pcie0_pipe_en", 23),
+       GATE_PCIE(CLK_SATA_AHB_EN, "sata_ahb_en", "axi_sel", 26),
+       GATE_PCIE(CLK_SATA_AXI_EN, "sata_axi_en", "hif_sel", 27),
+       GATE_PCIE(CLK_SATA_ASIC_EN, "sata_asic_en", "sata_asic", 28),
+       GATE_PCIE(CLK_SATA_RBC_EN, "sata_rbc_en", "sata_rbc", 29),
+       GATE_PCIE(CLK_SATA_PM_EN, "sata_pm_en", "univpll2_d4", 30),
+};
+
+static int clk_mt7622_ssusbsys_init(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_SSUSB_NR_CLK);
+
+       mtk_clk_register_gates(node, ssusb_clks, ARRAY_SIZE(ssusb_clks),
+                              clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               dev_err(&pdev->dev,
+                       "could not register clock provider: %s: %d\n",
+                       pdev->name, r);
+
+       mtk_register_reset_controller(node, 1, 0x34);
+
+       return r;
+}
+
+static int clk_mt7622_pciesys_init(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_PCIE_NR_CLK);
+
+       mtk_clk_register_gates(node, pcie_clks, ARRAY_SIZE(pcie_clks),
+                              clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               dev_err(&pdev->dev,
+                       "could not register clock provider: %s: %d\n",
+                       pdev->name, r);
+
+       mtk_register_reset_controller(node, 1, 0x34);
+
+       return r;
+}
+
+static const struct of_device_id of_match_clk_mt7622_hif[] = {
+       {
+               .compatible = "mediatek,mt7622-pciesys",
+               .data = clk_mt7622_pciesys_init,
+       }, {
+               .compatible = "mediatek,mt7622-ssusbsys",
+               .data = clk_mt7622_ssusbsys_init,
+       }, {
+               /* sentinel */
+       }
+};
+
+static int clk_mt7622_hif_probe(struct platform_device *pdev)
+{
+       int (*clk_init)(struct platform_device *);
+       int r;
+
+       clk_init = of_device_get_match_data(&pdev->dev);
+       if (!clk_init)
+               return -EINVAL;
+
+       r = clk_init(pdev);
+       if (r)
+               dev_err(&pdev->dev,
+                       "could not register clock provider: %s: %d\n",
+                       pdev->name, r);
+
+       return r;
+}
+
+static struct platform_driver clk_mt7622_hif_drv = {
+       .probe = clk_mt7622_hif_probe,
+       .driver = {
+               .name = "clk-mt7622-hif",
+               .of_match_table = of_match_clk_mt7622_hif,
+       },
+};
+
+builtin_platform_driver(clk_mt7622_hif_drv);
diff --git a/drivers/clk/mediatek/clk-mt7622.c b/drivers/clk/mediatek/clk-mt7622.c
new file mode 100644 (file)
index 0000000..92f7e32
--- /dev/null
@@ -0,0 +1,780 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
+ *        Sean Wang <sean.wang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+#include "clk-cpumux.h"
+
+#include <dt-bindings/clock/mt7622-clk.h>
+#include <linux/clk.h> /* for consumer */
+
+#define MT7622_PLL_FMAX                (2500UL * MHZ)
+#define CON0_MT7622_RST_BAR    BIT(27)
+
+#define PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,\
+                       _pd_reg, _pd_shift, _tuner_reg, _pcw_reg,       \
+                       _pcw_shift, _div_table, _parent_name) {         \
+               .id = _id,                                              \
+               .name = _name,                                          \
+               .reg = _reg,                                            \
+               .pwr_reg = _pwr_reg,                                    \
+               .en_mask = _en_mask,                                    \
+               .flags = _flags,                                        \
+               .rst_bar_mask = CON0_MT7622_RST_BAR,                    \
+               .fmax = MT7622_PLL_FMAX,                                \
+               .pcwbits = _pcwbits,                                    \
+               .pd_reg = _pd_reg,                                      \
+               .pd_shift = _pd_shift,                                  \
+               .tuner_reg = _tuner_reg,                                \
+               .pcw_reg = _pcw_reg,                                    \
+               .pcw_shift = _pcw_shift,                                \
+               .div_table = _div_table,                                \
+               .parent_name = _parent_name,                            \
+       }
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,    \
+                       _pd_reg, _pd_shift, _tuner_reg, _pcw_reg,       \
+                       _pcw_shift)                                     \
+       PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,\
+                _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift,  \
+                NULL, "clkxtal")
+
+#define GATE_APMIXED(_id, _name, _parent, _shift) {                    \
+               .id = _id,                                              \
+               .name = _name,                                          \
+               .parent_name = _parent,                                 \
+               .regs = &apmixed_cg_regs,                               \
+               .shift = _shift,                                        \
+               .ops = &mtk_clk_gate_ops_no_setclr_inv,                 \
+       }
+
+#define GATE_INFRA(_id, _name, _parent, _shift) {                      \
+               .id = _id,                                              \
+               .name = _name,                                          \
+               .parent_name = _parent,                                 \
+               .regs = &infra_cg_regs,                                 \
+               .shift = _shift,                                        \
+               .ops = &mtk_clk_gate_ops_setclr,                        \
+       }
+
+#define GATE_TOP0(_id, _name, _parent, _shift) {                       \
+               .id = _id,                                              \
+               .name = _name,                                          \
+               .parent_name = _parent,                                 \
+               .regs = &top0_cg_regs,                                  \
+               .shift = _shift,                                        \
+               .ops = &mtk_clk_gate_ops_no_setclr,                     \
+       }
+
+#define GATE_TOP1(_id, _name, _parent, _shift) {                       \
+               .id = _id,                                              \
+               .name = _name,                                          \
+               .parent_name = _parent,                                 \
+               .regs = &top1_cg_regs,                                  \
+               .shift = _shift,                                        \
+               .ops = &mtk_clk_gate_ops_no_setclr,                     \
+       }
+
+#define GATE_PERI0(_id, _name, _parent, _shift) {                      \
+               .id = _id,                                              \
+               .name = _name,                                          \
+               .parent_name = _parent,                                 \
+               .regs = &peri0_cg_regs,                                 \
+               .shift = _shift,                                        \
+               .ops = &mtk_clk_gate_ops_setclr,                        \
+       }
+
+#define GATE_PERI1(_id, _name, _parent, _shift) {                      \
+               .id = _id,                                              \
+               .name = _name,                                          \
+               .parent_name = _parent,                                 \
+               .regs = &peri1_cg_regs,                                 \
+               .shift = _shift,                                        \
+               .ops = &mtk_clk_gate_ops_setclr,                        \
+       }
+
+static DEFINE_SPINLOCK(mt7622_clk_lock);
+
+static const char * const infra_mux1_parents[] = {
+       "clkxtal",
+       "armpll",
+       "main_core_en",
+       "armpll"
+};
+
+static const char * const axi_parents[] = {
+       "clkxtal",
+       "syspll1_d2",
+       "syspll_d5",
+       "syspll1_d4",
+       "univpll_d5",
+       "univpll2_d2",
+       "univpll_d7"
+};
+
+static const char * const mem_parents[] = {
+       "clkxtal",
+       "dmpll_ck"
+};
+
+static const char * const ddrphycfg_parents[] = {
+       "clkxtal",
+       "syspll1_d8"
+};
+
+static const char * const eth_parents[] = {
+       "clkxtal",
+       "syspll1_d2",
+       "univpll1_d2",
+       "syspll1_d4",
+       "univpll_d5",
+       "clk_null",
+       "univpll_d7"
+};
+
+static const char * const pwm_parents[] = {
+       "clkxtal",
+       "univpll2_d4"
+};
+
+static const char * const f10m_ref_parents[] = {
+       "clkxtal",
+       "syspll4_d16"
+};
+
+static const char * const nfi_infra_parents[] = {
+       "clkxtal",
+       "clkxtal",
+       "clkxtal",
+       "clkxtal",
+       "clkxtal",
+       "clkxtal",
+       "clkxtal",
+       "clkxtal",
+       "univpll2_d8",
+       "syspll1_d8",
+       "univpll1_d8",
+       "syspll4_d2",
+       "univpll2_d4",
+       "univpll3_d2",
+       "syspll1_d4"
+};
+
+static const char * const flash_parents[] = {
+       "clkxtal",
+       "univpll_d80_d4",
+       "syspll2_d8",
+       "syspll3_d4",
+       "univpll3_d4",
+       "univpll1_d8",
+       "syspll2_d4",
+       "univpll2_d4"
+};
+
+static const char * const uart_parents[] = {
+       "clkxtal",
+       "univpll2_d8"
+};
+
+static const char * const spi0_parents[] = {
+       "clkxtal",
+       "syspll3_d2",
+       "clkxtal",
+       "syspll2_d4",
+       "syspll4_d2",
+       "univpll2_d4",
+       "univpll1_d8",
+       "clkxtal"
+};
+
+static const char * const spi1_parents[] = {
+       "clkxtal",
+       "syspll3_d2",
+       "clkxtal",
+       "syspll4_d4",
+       "syspll4_d2",
+       "univpll2_d4",
+       "univpll1_d8",
+       "clkxtal"
+};
+
+static const char * const msdc30_0_parents[] = {
+       "clkxtal",
+       "univpll2_d16",
+       "univ48m"
+};
+
+static const char * const a1sys_hp_parents[] = {
+       "clkxtal",
+       "aud1pll_ck",
+       "aud2pll_ck",
+       "clkxtal"
+};
+
+static const char * const intdir_parents[] = {
+       "clkxtal",
+       "syspll_d2",
+       "univpll_d2",
+       "sgmiipll_ck"
+};
+
+static const char * const aud_intbus_parents[] = {
+       "clkxtal",
+       "syspll1_d4",
+       "syspll4_d2",
+       "syspll3_d2"
+};
+
+static const char * const pmicspi_parents[] = {
+       "clkxtal",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "clk_null",
+       "univpll2_d16"
+};
+
+static const char * const atb_parents[] = {
+       "clkxtal",
+       "syspll1_d2",
+       "syspll_d5"
+};
+
+static const char * const audio_parents[] = {
+       "clkxtal",
+       "syspll3_d4",
+       "syspll4_d4",
+       "univpll1_d16"
+};
+
+static const char * const usb20_parents[] = {
+       "clkxtal",
+       "univpll3_d4",
+       "syspll1_d8",
+       "clkxtal"
+};
+
+static const char * const aud1_parents[] = {
+       "clkxtal",
+       "aud1pll_ck"
+};
+
+static const char * const aud2_parents[] = {
+       "clkxtal",
+       "aud2pll_ck"
+};
+
+static const char * const asm_l_parents[] = {
+       "clkxtal",
+       "syspll_d5",
+       "univpll2_d2",
+       "univpll2_d4"
+};
+
+static const char * const apll1_ck_parents[] = {
+       "aud1_sel",
+       "aud2_sel"
+};
+
+static const char * const peribus_ck_parents[] = {
+       "syspll1_d8",
+       "syspll1_d4"
+};
+
+static const struct mtk_gate_regs apmixed_cg_regs = {
+       .set_ofs = 0x8,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x8,
+};
+
+static const struct mtk_gate_regs infra_cg_regs = {
+       .set_ofs = 0x40,
+       .clr_ofs = 0x44,
+       .sta_ofs = 0x48,
+};
+
+static const struct mtk_gate_regs top0_cg_regs = {
+       .set_ofs = 0x120,
+       .clr_ofs = 0x120,
+       .sta_ofs = 0x120,
+};
+
+static const struct mtk_gate_regs top1_cg_regs = {
+       .set_ofs = 0x128,
+       .clr_ofs = 0x128,
+       .sta_ofs = 0x128,
+};
+
+static const struct mtk_gate_regs peri0_cg_regs = {
+       .set_ofs = 0x8,
+       .clr_ofs = 0x10,
+       .sta_ofs = 0x18,
+};
+
+static const struct mtk_gate_regs peri1_cg_regs = {
+       .set_ofs = 0xC,
+       .clr_ofs = 0x14,
+       .sta_ofs = 0x1C,
+};
+
+static const struct mtk_pll_data plls[] = {
+       PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0200, 0x020C, 0x00000001,
+           PLL_AO, 21, 0x0204, 24, 0, 0x0204, 0),
+       PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0210, 0x021C, 0x00000001,
+           HAVE_RST_BAR, 21, 0x0214, 24, 0, 0x0214, 0),
+       PLL(CLK_APMIXED_UNIV2PLL, "univ2pll", 0x0220, 0x022C, 0x00000001,
+           HAVE_RST_BAR, 7, 0x0224, 24, 0, 0x0224, 14),
+       PLL(CLK_APMIXED_ETH1PLL, "eth1pll", 0x0300, 0x0310, 0x00000001,
+           0, 21, 0x0300, 1, 0, 0x0304, 0),
+       PLL(CLK_APMIXED_ETH2PLL, "eth2pll", 0x0314, 0x0320, 0x00000001,
+           0, 21, 0x0314, 1, 0, 0x0318, 0),
+       PLL(CLK_APMIXED_AUD1PLL, "aud1pll", 0x0324, 0x0330, 0x00000001,
+           0, 31, 0x0324, 1, 0, 0x0328, 0),
+       PLL(CLK_APMIXED_AUD2PLL, "aud2pll", 0x0334, 0x0340, 0x00000001,
+           0, 31, 0x0334, 1, 0, 0x0338, 0),
+       PLL(CLK_APMIXED_TRGPLL, "trgpll", 0x0344, 0x0354, 0x00000001,
+           0, 21, 0x0344, 1, 0, 0x0348, 0),
+       PLL(CLK_APMIXED_SGMIPLL, "sgmipll", 0x0358, 0x0368, 0x00000001,
+           0, 21, 0x0358, 1, 0, 0x035C, 0),
+};
+
+static const struct mtk_gate apmixed_clks[] = {
+       GATE_APMIXED(CLK_APMIXED_MAIN_CORE_EN, "main_core_en", "mainpll", 5),
+};
+
+static const struct mtk_gate infra_clks[] = {
+       GATE_INFRA(CLK_INFRA_DBGCLK_PD, "infra_dbgclk_pd", "axi_sel", 0),
+       GATE_INFRA(CLK_INFRA_TRNG, "trng_ck", "axi_sel", 2),
+       GATE_INFRA(CLK_INFRA_AUDIO_PD, "infra_audio_pd", "aud_intbus_sel", 5),
+       GATE_INFRA(CLK_INFRA_IRRX_PD, "infra_irrx_pd", "irrx_sel", 16),
+       GATE_INFRA(CLK_INFRA_APXGPT_PD, "infra_apxgpt_pd", "f10m_ref_sel", 18),
+       GATE_INFRA(CLK_INFRA_PMIC_PD, "infra_pmic_pd", "pmicspi_sel", 22),
+};
+
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+       FIXED_CLK(CLK_TOP_TO_U2_PHY, "to_u2_phy", "clkxtal",
+                 31250000),
+       FIXED_CLK(CLK_TOP_TO_U2_PHY_1P, "to_u2_phy_1p", "clkxtal",
+                 31250000),
+       FIXED_CLK(CLK_TOP_PCIE0_PIPE_EN, "pcie0_pipe_en", "clkxtal",
+                 125000000),
+       FIXED_CLK(CLK_TOP_PCIE1_PIPE_EN, "pcie1_pipe_en", "clkxtal",
+                 125000000),
+       FIXED_CLK(CLK_TOP_SSUSB_TX250M, "ssusb_tx250m", "clkxtal",
+                 250000000),
+       FIXED_CLK(CLK_TOP_SSUSB_EQ_RX250M, "ssusb_eq_rx250m", "clkxtal",
+                 250000000),
+       FIXED_CLK(CLK_TOP_SSUSB_CDR_REF, "ssusb_cdr_ref", "clkxtal",
+                 33333333),
+       FIXED_CLK(CLK_TOP_SSUSB_CDR_FB, "ssusb_cdr_fb", "clkxtal",
+                 50000000),
+       FIXED_CLK(CLK_TOP_SATA_ASIC, "sata_asic", "clkxtal",
+                 50000000),
+       FIXED_CLK(CLK_TOP_SATA_RBC, "sata_rbc", "clkxtal",
+                 50000000),
+};
+
+static const struct mtk_fixed_factor top_divs[] = {
+       FACTOR(CLK_TOP_TO_USB3_SYS, "to_usb3_sys", "eth1pll", 1, 4),
+       FACTOR(CLK_TOP_P1_1MHZ, "p1_1mhz", "eth1pll", 1, 500),
+       FACTOR(CLK_TOP_4MHZ, "free_run_4mhz", "eth1pll", 1, 125),
+       FACTOR(CLK_TOP_P0_1MHZ, "p0_1mhz", "eth1pll", 1, 500),
+       FACTOR(CLK_TOP_TXCLK_SRC_PRE, "txclk_src_pre", "sgmiipll_d2", 1, 1),
+       FACTOR(CLK_TOP_RTC, "rtc", "clkxtal", 1, 1024),
+       FACTOR(CLK_TOP_MEMPLL, "mempll", "clkxtal", 32, 1),
+       FACTOR(CLK_TOP_DMPLL, "dmpll_ck", "mempll", 1, 1),
+       FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2),
+       FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "mainpll", 1, 4),
+       FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "mainpll", 1, 8),
+       FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "mainpll", 1, 16),
+       FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "mainpll", 1, 12),
+       FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "mainpll", 1, 24),
+       FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5),
+       FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "mainpll", 1, 10),
+       FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "mainpll", 1, 20),
+       FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "mainpll", 1, 14),
+       FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "mainpll", 1, 28),
+       FACTOR(CLK_TOP_SYSPLL4_D16, "syspll4_d16", "mainpll", 1, 112),
+       FACTOR(CLK_TOP_UNIVPLL, "univpll", "univ2pll", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll", 1, 4),
+       FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll", 1, 8),
+       FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll", 1, 16),
+       FACTOR(CLK_TOP_UNIVPLL1_D16, "univpll1_d16", "univpll", 1, 32),
+       FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll", 1, 6),
+       FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll", 1, 12),
+       FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll", 1, 24),
+       FACTOR(CLK_TOP_UNIVPLL2_D16, "univpll2_d16", "univpll", 1, 48),
+       FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
+       FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll", 1, 10),
+       FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll", 1, 20),
+       FACTOR(CLK_TOP_UNIVPLL3_D16, "univpll3_d16", "univpll", 1, 80),
+       FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7),
+       FACTOR(CLK_TOP_UNIVPLL_D80_D4, "univpll_d80_d4", "univpll", 1, 320),
+       FACTOR(CLK_TOP_UNIV48M, "univ48m", "univpll", 1, 25),
+       FACTOR(CLK_TOP_SGMIIPLL, "sgmiipll_ck", "sgmipll", 1, 1),
+       FACTOR(CLK_TOP_SGMIIPLL_D2, "sgmiipll_d2", "sgmipll", 1, 2),
+       FACTOR(CLK_TOP_AUD1PLL, "aud1pll_ck", "aud1pll", 1, 1),
+       FACTOR(CLK_TOP_AUD2PLL, "aud2pll_ck", "aud2pll", 1, 1),
+       FACTOR(CLK_TOP_AUD_I2S2_MCK, "aud_i2s2_mck", "i2s2_mck_sel", 1, 2),
+       FACTOR(CLK_TOP_TO_USB3_REF, "to_usb3_ref", "univpll2_d4", 1, 4),
+       FACTOR(CLK_TOP_PCIE1_MAC_EN, "pcie1_mac_en", "univpll1_d4", 1, 1),
+       FACTOR(CLK_TOP_PCIE0_MAC_EN, "pcie0_mac_en", "univpll1_d4", 1, 1),
+       FACTOR(CLK_TOP_ETH_500M, "eth_500m", "eth1pll", 1, 1),
+};
+
+static const struct mtk_gate top_clks[] = {
+       /* TOP0 */
+       GATE_TOP0(CLK_TOP_APLL1_DIV_PD, "apll1_ck_div_pd", "apll1_ck_div", 0),
+       GATE_TOP0(CLK_TOP_APLL2_DIV_PD, "apll2_ck_div_pd", "apll2_ck_div", 1),
+       GATE_TOP0(CLK_TOP_I2S0_MCK_DIV_PD, "i2s0_mck_div_pd", "i2s0_mck_div",
+                 2),
+       GATE_TOP0(CLK_TOP_I2S1_MCK_DIV_PD, "i2s1_mck_div_pd", "i2s1_mck_div",
+                 3),
+       GATE_TOP0(CLK_TOP_I2S2_MCK_DIV_PD, "i2s2_mck_div_pd", "i2s2_mck_div",
+                 4),
+       GATE_TOP0(CLK_TOP_I2S3_MCK_DIV_PD, "i2s3_mck_div_pd", "i2s3_mck_div",
+                 5),
+
+       /* TOP1 */
+       GATE_TOP1(CLK_TOP_A1SYS_HP_DIV_PD, "a1sys_div_pd", "a1sys_div", 0),
+       GATE_TOP1(CLK_TOP_A2SYS_HP_DIV_PD, "a2sys_div_pd", "a2sys_div", 16),
+};
+
+static const struct mtk_clk_divider top_adj_divs[] = {
+       DIV_ADJ(CLK_TOP_APLL1_DIV, "apll1_ck_div", "apll1_ck_sel",
+               0x120, 24, 3),
+       DIV_ADJ(CLK_TOP_APLL2_DIV, "apll2_ck_div", "apll2_ck_sel",
+               0x120, 28, 3),
+       DIV_ADJ(CLK_TOP_I2S0_MCK_DIV, "i2s0_mck_div", "i2s0_mck_sel",
+               0x124, 0, 7),
+       DIV_ADJ(CLK_TOP_I2S1_MCK_DIV, "i2s1_mck_div", "i2s1_mck_sel",
+               0x124, 8, 7),
+       DIV_ADJ(CLK_TOP_I2S2_MCK_DIV, "i2s2_mck_div", "aud_i2s2_mck",
+               0x124, 16, 7),
+       DIV_ADJ(CLK_TOP_I2S3_MCK_DIV, "i2s3_mck_div", "i2s3_mck_sel",
+               0x124, 24, 7),
+       DIV_ADJ(CLK_TOP_A1SYS_HP_DIV, "a1sys_div", "a1sys_hp_sel",
+               0x128, 8, 7),
+       DIV_ADJ(CLK_TOP_A2SYS_HP_DIV, "a2sys_div", "a2sys_hp_sel",
+               0x128, 24, 7),
+};
+
+static const struct mtk_gate peri_clks[] = {
+       /* PERI0 */
+       GATE_PERI0(CLK_PERI_THERM_PD, "peri_therm_pd", "axi_sel", 1),
+       GATE_PERI0(CLK_PERI_PWM1_PD, "peri_pwm1_pd", "clkxtal", 2),
+       GATE_PERI0(CLK_PERI_PWM2_PD, "peri_pwm2_pd", "clkxtal", 3),
+       GATE_PERI0(CLK_PERI_PWM3_PD, "peri_pwm3_pd", "clkxtal", 4),
+       GATE_PERI0(CLK_PERI_PWM4_PD, "peri_pwm4_pd", "clkxtal", 5),
+       GATE_PERI0(CLK_PERI_PWM5_PD, "peri_pwm5_pd", "clkxtal", 6),
+       GATE_PERI0(CLK_PERI_PWM6_PD, "peri_pwm6_pd", "clkxtal", 7),
+       GATE_PERI0(CLK_PERI_PWM7_PD, "peri_pwm7_pd", "clkxtal", 8),
+       GATE_PERI0(CLK_PERI_PWM_PD, "peri_pwm_pd", "clkxtal", 9),
+       GATE_PERI0(CLK_PERI_AP_DMA_PD, "peri_ap_dma_pd", "axi_sel", 12),
+       GATE_PERI0(CLK_PERI_MSDC30_0_PD, "peri_msdc30_0", "msdc30_0_sel", 13),
+       GATE_PERI0(CLK_PERI_MSDC30_1_PD, "peri_msdc30_1", "msdc30_1_sel", 14),
+       GATE_PERI0(CLK_PERI_UART0_PD, "peri_uart0_pd", "axi_sel", 17),
+       GATE_PERI0(CLK_PERI_UART1_PD, "peri_uart1_pd", "axi_sel", 18),
+       GATE_PERI0(CLK_PERI_UART2_PD, "peri_uart2_pd", "axi_sel", 19),
+       GATE_PERI0(CLK_PERI_UART3_PD, "peri_uart3_pd", "axi_sel", 20),
+       GATE_PERI0(CLK_PERI_UART4_PD, "peri_uart4_pd", "axi_sel", 21),
+       GATE_PERI0(CLK_PERI_BTIF_PD, "peri_btif_pd", "axi_sel", 22),
+       GATE_PERI0(CLK_PERI_I2C0_PD, "peri_i2c0_pd", "axi_sel", 23),
+       GATE_PERI0(CLK_PERI_I2C1_PD, "peri_i2c1_pd", "axi_sel", 24),
+       GATE_PERI0(CLK_PERI_I2C2_PD, "peri_i2c2_pd", "axi_sel", 25),
+       GATE_PERI0(CLK_PERI_SPI1_PD, "peri_spi1_pd", "spi1_sel", 26),
+       GATE_PERI0(CLK_PERI_AUXADC_PD, "peri_auxadc_pd", "clkxtal", 27),
+       GATE_PERI0(CLK_PERI_SPI0_PD, "peri_spi0_pd", "spi0_sel", 28),
+       GATE_PERI0(CLK_PERI_SNFI_PD, "peri_snfi_pd", "nfi_infra_sel", 29),
+       GATE_PERI0(CLK_PERI_NFI_PD, "peri_nfi_pd", "axi_sel", 30),
+       GATE_PERI0(CLK_PERI_NFIECC_PD, "peri_nfiecc_pd", "axi_sel", 31),
+
+       /* PERI1 */
+       GATE_PERI1(CLK_PERI_FLASH_PD, "peri_flash_pd", "flash_sel", 1),
+       GATE_PERI1(CLK_PERI_IRTX_PD, "peri_irtx_pd", "irtx_sel", 2),
+};
+
+static struct mtk_composite infra_muxes[] __initdata = {
+       MUX(CLK_INFRA_MUX1_SEL, "infra_mux1_sel", infra_mux1_parents,
+           0x000, 2, 2),
+};
+
+static struct mtk_composite top_muxes[] = {
+       /* CLK_CFG_0 */
+       MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
+                0x040, 0, 3, 7),
+       MUX_GATE(CLK_TOP_MEM_SEL, "mem_sel", mem_parents,
+                0x040, 8, 1, 15),
+       MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents,
+                0x040, 16, 1, 23),
+       MUX_GATE(CLK_TOP_ETH_SEL, "eth_sel", eth_parents,
+                0x040, 24, 3, 31),
+
+       /* CLK_CFG_1 */
+       MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents,
+                0x050, 0, 2, 7),
+       MUX_GATE(CLK_TOP_F10M_REF_SEL, "f10m_ref_sel", f10m_ref_parents,
+                0x050, 8, 1, 15),
+       MUX_GATE(CLK_TOP_NFI_INFRA_SEL, "nfi_infra_sel", nfi_infra_parents,
+                0x050, 16, 4, 23),
+       MUX_GATE(CLK_TOP_FLASH_SEL, "flash_sel", flash_parents,
+                0x050, 24, 3, 31),
+
+       /* CLK_CFG_2 */
+       MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents,
+                0x060, 0, 1, 7),
+       MUX_GATE(CLK_TOP_SPI0_SEL, "spi0_sel", spi0_parents,
+                0x060, 8, 3, 15),
+       MUX_GATE(CLK_TOP_SPI1_SEL, "spi1_sel", spi1_parents,
+                0x060, 16, 3, 23),
+       MUX_GATE(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel", uart_parents,
+                0x060, 24, 3, 31),
+
+       /* CLK_CFG_3 */
+       MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_0_parents,
+                0x070, 0, 3, 7),
+       MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_0_parents,
+                0x070, 8, 3, 15),
+       MUX_GATE(CLK_TOP_A1SYS_HP_SEL, "a1sys_hp_sel", a1sys_hp_parents,
+                0x070, 16, 2, 23),
+       MUX_GATE(CLK_TOP_A2SYS_HP_SEL, "a2sys_hp_sel", a1sys_hp_parents,
+                0x070, 24, 2, 31),
+
+       /* CLK_CFG_4 */
+       MUX_GATE(CLK_TOP_INTDIR_SEL, "intdir_sel", intdir_parents,
+                0x080, 0, 2, 7),
+       MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents,
+                0x080, 8, 2, 15),
+       MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents,
+                0x080, 16, 3, 23),
+       MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", ddrphycfg_parents,
+                0x080, 24, 2, 31),
+
+       /* CLK_CFG_5 */
+       MUX_GATE(CLK_TOP_ATB_SEL, "atb_sel", atb_parents,
+                0x090, 0, 2, 7),
+       MUX_GATE(CLK_TOP_HIF_SEL, "hif_sel", eth_parents,
+                0x090, 8, 3, 15),
+       MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", audio_parents,
+                0x090, 16, 2, 23),
+       MUX_GATE(CLK_TOP_U2_SEL, "usb20_sel", usb20_parents,
+                0x090, 24, 2, 31),
+
+       /* CLK_CFG_6 */
+       MUX_GATE(CLK_TOP_AUD1_SEL, "aud1_sel", aud1_parents,
+                0x0A0, 0, 1, 7),
+       MUX_GATE(CLK_TOP_AUD2_SEL, "aud2_sel", aud2_parents,
+                0x0A0, 8, 1, 15),
+       MUX_GATE(CLK_TOP_IRRX_SEL, "irrx_sel", f10m_ref_parents,
+                0x0A0, 16, 1, 23),
+       MUX_GATE(CLK_TOP_IRTX_SEL, "irtx_sel", f10m_ref_parents,
+                0x0A0, 24, 1, 31),
+
+       /* CLK_CFG_7 */
+       MUX_GATE(CLK_TOP_ASM_L_SEL, "asm_l_sel", asm_l_parents,
+                0x0B0, 0, 2, 7),
+       MUX_GATE(CLK_TOP_ASM_M_SEL, "asm_m_sel", asm_l_parents,
+                0x0B0, 8, 2, 15),
+       MUX_GATE(CLK_TOP_ASM_H_SEL, "asm_h_sel", asm_l_parents,
+                0x0B0, 16, 2, 23),
+
+       /* CLK_AUDDIV_0 */
+       MUX(CLK_TOP_APLL1_SEL, "apll1_ck_sel", apll1_ck_parents,
+           0x120, 6, 1),
+       MUX(CLK_TOP_APLL2_SEL, "apll2_ck_sel", apll1_ck_parents,
+           0x120, 7, 1),
+       MUX(CLK_TOP_I2S0_MCK_SEL, "i2s0_mck_sel", apll1_ck_parents,
+           0x120, 8, 1),
+       MUX(CLK_TOP_I2S1_MCK_SEL, "i2s1_mck_sel", apll1_ck_parents,
+           0x120, 9, 1),
+       MUX(CLK_TOP_I2S2_MCK_SEL, "i2s2_mck_sel", apll1_ck_parents,
+           0x120, 10, 1),
+       MUX(CLK_TOP_I2S3_MCK_SEL, "i2s3_mck_sel", apll1_ck_parents,
+           0x120, 11, 1),
+};
+
+static struct mtk_composite peri_muxes[] = {
+       /* PERI_GLOBALCON_CKSEL */
+       MUX(CLK_PERIBUS_SEL, "peribus_ck_sel", peribus_ck_parents, 0x05C, 0, 1),
+};
+
+static int mtk_topckgen_init(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       void __iomem *base;
+       struct device_node *node = pdev->dev.of_node;
+       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
+
+       mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
+                                   clk_data);
+
+       mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs),
+                                clk_data);
+
+       mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes),
+                                   base, &mt7622_clk_lock, clk_data);
+
+       mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
+                                 base, &mt7622_clk_lock, clk_data);
+
+       mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
+                              clk_data);
+
+       clk_prepare_enable(clk_data->clks[CLK_TOP_AXI_SEL]);
+       clk_prepare_enable(clk_data->clks[CLK_TOP_MEM_SEL]);
+       clk_prepare_enable(clk_data->clks[CLK_TOP_DDRPHYCFG_SEL]);
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static int __init mtk_infrasys_init(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
+
+       mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+                              clk_data);
+
+       mtk_clk_register_cpumuxes(node, infra_muxes, ARRAY_SIZE(infra_muxes),
+                                 clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get,
+                               clk_data);
+       if (r)
+               return r;
+
+       mtk_register_reset_controller(node, 1, 0x30);
+
+       return 0;
+}
+
+static int mtk_apmixedsys_init(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+
+       clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls),
+                             clk_data);
+
+       mtk_clk_register_gates(node, apmixed_clks,
+                              ARRAY_SIZE(apmixed_clks), clk_data);
+
+       clk_prepare_enable(clk_data->clks[CLK_APMIXED_ARMPLL]);
+       clk_prepare_enable(clk_data->clks[CLK_APMIXED_MAIN_CORE_EN]);
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static int mtk_pericfg_init(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       void __iomem *base;
+       int r;
+       struct device_node *node = pdev->dev.of_node;
+       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
+
+       mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
+                              clk_data);
+
+       mtk_clk_register_composites(peri_muxes, ARRAY_SIZE(peri_muxes), base,
+                                   &mt7622_clk_lock, clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               return r;
+
+       clk_prepare_enable(clk_data->clks[CLK_PERI_UART0_PD]);
+
+       mtk_register_reset_controller(node, 2, 0x0);
+
+       return 0;
+}
+
+static const struct of_device_id of_match_clk_mt7622[] = {
+       {
+               .compatible = "mediatek,mt7622-apmixedsys",
+               .data = mtk_apmixedsys_init,
+       }, {
+               .compatible = "mediatek,mt7622-infracfg",
+               .data = mtk_infrasys_init,
+       }, {
+               .compatible = "mediatek,mt7622-topckgen",
+               .data = mtk_topckgen_init,
+       }, {
+               .compatible = "mediatek,mt7622-pericfg",
+               .data = mtk_pericfg_init,
+       }, {
+               /* sentinel */
+       }
+};
+
+static int clk_mt7622_probe(struct platform_device *pdev)
+{
+       int (*clk_init)(struct platform_device *);
+       int r;
+
+       clk_init = of_device_get_match_data(&pdev->dev);
+       if (!clk_init)
+               return -EINVAL;
+
+       r = clk_init(pdev);
+       if (r)
+               dev_err(&pdev->dev,
+                       "could not register clock provider: %s: %d\n",
+                       pdev->name, r);
+
+       return r;
+}
+
+static struct platform_driver clk_mt7622_drv = {
+       .probe = clk_mt7622_probe,
+       .driver = {
+               .name = "clk-mt7622",
+               .of_match_table = of_match_clk_mt7622,
+       },
+};
+
+static int clk_mt7622_init(void)
+{
+       return platform_driver_register(&clk_mt7622_drv);
+}
+
+arch_initcall(clk_mt7622_init);
index f5d6b70ce189372602f2c6f8aaa1d2694ba8e65e..f10250dcece4ebd44e4216864da1a90f0a802dbd 100644 (file)
@@ -207,6 +207,8 @@ struct mtk_pll_data {
        uint32_t en_mask;
        uint32_t pd_reg;
        uint32_t tuner_reg;
+       uint32_t tuner_en_reg;
+       uint8_t tuner_en_bit;
        int pd_shift;
        unsigned int flags;
        const struct clk_ops *ops;
@@ -216,6 +218,7 @@ struct mtk_pll_data {
        uint32_t pcw_reg;
        int pcw_shift;
        const struct mtk_pll_div_table *div_table;
+       const char *parent_name;
 };
 
 void mtk_clk_register_plls(struct device_node *node,
index a409142e93462dd0eb7fc599f43479a26b2c695c..f54e4015b0b1f3c005e7d82b5fdffa6dc826a8ad 100644 (file)
@@ -47,6 +47,7 @@ struct mtk_clk_pll {
        void __iomem    *pd_addr;
        void __iomem    *pwr_addr;
        void __iomem    *tuner_addr;
+       void __iomem    *tuner_en_addr;
        void __iomem    *pcw_addr;
        const struct mtk_pll_data *data;
 };
@@ -227,7 +228,10 @@ static int mtk_pll_prepare(struct clk_hw *hw)
        r |= pll->data->en_mask;
        writel(r, pll->base_addr + REG_CON0);
 
-       if (pll->tuner_addr) {
+       if (pll->tuner_en_addr) {
+               r = readl(pll->tuner_en_addr) | BIT(pll->data->tuner_en_bit);
+               writel(r, pll->tuner_en_addr);
+       } else if (pll->tuner_addr) {
                r = readl(pll->tuner_addr) | AUDPLL_TUNER_EN;
                writel(r, pll->tuner_addr);
        }
@@ -254,7 +258,10 @@ static void mtk_pll_unprepare(struct clk_hw *hw)
                writel(r, pll->base_addr + REG_CON0);
        }
 
-       if (pll->tuner_addr) {
+       if (pll->tuner_en_addr) {
+               r = readl(pll->tuner_en_addr) & ~BIT(pll->data->tuner_en_bit);
+               writel(r, pll->tuner_en_addr);
+       } else if (pll->tuner_addr) {
                r = readl(pll->tuner_addr) & ~AUDPLL_TUNER_EN;
                writel(r, pll->tuner_addr);
        }
@@ -297,13 +304,18 @@ static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data,
        pll->pcw_addr = base + data->pcw_reg;
        if (data->tuner_reg)
                pll->tuner_addr = base + data->tuner_reg;
+       if (data->tuner_en_reg)
+               pll->tuner_en_addr = base + data->tuner_en_reg;
        pll->hw.init = &init;
        pll->data = data;
 
        init.name = data->name;
        init.flags = (data->flags & PLL_AO) ? CLK_IS_CRITICAL : 0;
        init.ops = &mtk_pll_ops;
-       init.parent_names = &parent_name;
+       if (data->parent_name)
+               init.parent_names = &data->parent_name;
+       else
+               init.parent_names = &parent_name;
        init.num_parents = 1;
 
        clk = clk_register(NULL, &pll->hw);
index b2d1e8ed7152b75f11352f58ff40cad71a1dab57..ae385310e98090de90002b16d1829ecaad6819b3 100644 (file)
@@ -1131,6 +1131,253 @@ static struct clk_gate gxbb_sd_emmc_c_clk0 = {
        },
 };
 
+/* VPU Clock */
+
+static u32 mux_table_vpu[] = {0, 1, 2, 3};
+static const char * const gxbb_vpu_parent_names[] = {
+       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
+};
+
+static struct clk_mux gxbb_vpu_0_sel = {
+       .reg = (void *)HHI_VPU_CLK_CNTL,
+       .mask = 0x3,
+       .shift = 9,
+       .lock = &clk_lock,
+       .table = mux_table_vpu,
+       .hw.init = &(struct clk_init_data){
+               .name = "vpu_0_sel",
+               .ops = &clk_mux_ops,
+               /*
+                * bits 9:10 selects from 4 possible parents:
+                * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
+                */
+               .parent_names = gxbb_vpu_parent_names,
+               .num_parents = ARRAY_SIZE(gxbb_vpu_parent_names),
+               .flags = CLK_SET_RATE_NO_REPARENT,
+       },
+};
+
+static struct clk_divider gxbb_vpu_0_div = {
+       .reg = (void *)HHI_VPU_CLK_CNTL,
+       .shift = 0,
+       .width = 7,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "vpu_0_div",
+               .ops = &clk_divider_ops,
+               .parent_names = (const char *[]){ "vpu_0_sel" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_gate gxbb_vpu_0 = {
+       .reg = (void *)HHI_VPU_CLK_CNTL,
+       .bit_idx = 8,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data) {
+               .name = "vpu_0",
+               .ops = &clk_gate_ops,
+               .parent_names = (const char *[]){ "vpu_0_div" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+       },
+};
+
+static struct clk_mux gxbb_vpu_1_sel = {
+       .reg = (void *)HHI_VPU_CLK_CNTL,
+       .mask = 0x3,
+       .shift = 25,
+       .lock = &clk_lock,
+       .table = mux_table_vpu,
+       .hw.init = &(struct clk_init_data){
+               .name = "vpu_1_sel",
+               .ops = &clk_mux_ops,
+               /*
+                * bits 25:26 selects from 4 possible parents:
+                * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
+                */
+               .parent_names = gxbb_vpu_parent_names,
+               .num_parents = ARRAY_SIZE(gxbb_vpu_parent_names),
+               .flags = CLK_SET_RATE_NO_REPARENT,
+       },
+};
+
+static struct clk_divider gxbb_vpu_1_div = {
+       .reg = (void *)HHI_VPU_CLK_CNTL,
+       .shift = 16,
+       .width = 7,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "vpu_1_div",
+               .ops = &clk_divider_ops,
+               .parent_names = (const char *[]){ "vpu_1_sel" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_gate gxbb_vpu_1 = {
+       .reg = (void *)HHI_VPU_CLK_CNTL,
+       .bit_idx = 24,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data) {
+               .name = "vpu_1",
+               .ops = &clk_gate_ops,
+               .parent_names = (const char *[]){ "vpu_1_div" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+       },
+};
+
+static struct clk_mux gxbb_vpu = {
+       .reg = (void *)HHI_VPU_CLK_CNTL,
+       .mask = 1,
+       .shift = 31,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "vpu",
+               .ops = &clk_mux_ops,
+               /*
+                * bit 31 selects from 2 possible parents:
+                * vpu_0 or vpu_1
+                */
+               .parent_names = (const char *[]){ "vpu_0", "vpu_1" },
+               .num_parents = 2,
+               .flags = CLK_SET_RATE_NO_REPARENT,
+       },
+};
+
+/* VAPB Clock */
+
+static u32 mux_table_vapb[] = {0, 1, 2, 3};
+static const char * const gxbb_vapb_parent_names[] = {
+       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
+};
+
+static struct clk_mux gxbb_vapb_0_sel = {
+       .reg = (void *)HHI_VAPBCLK_CNTL,
+       .mask = 0x3,
+       .shift = 9,
+       .lock = &clk_lock,
+       .table = mux_table_vapb,
+       .hw.init = &(struct clk_init_data){
+               .name = "vapb_0_sel",
+               .ops = &clk_mux_ops,
+               /*
+                * bits 9:10 selects from 4 possible parents:
+                * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
+                */
+               .parent_names = gxbb_vapb_parent_names,
+               .num_parents = ARRAY_SIZE(gxbb_vapb_parent_names),
+               .flags = CLK_SET_RATE_NO_REPARENT,
+       },
+};
+
+static struct clk_divider gxbb_vapb_0_div = {
+       .reg = (void *)HHI_VAPBCLK_CNTL,
+       .shift = 0,
+       .width = 7,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "vapb_0_div",
+               .ops = &clk_divider_ops,
+               .parent_names = (const char *[]){ "vapb_0_sel" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_gate gxbb_vapb_0 = {
+       .reg = (void *)HHI_VAPBCLK_CNTL,
+       .bit_idx = 8,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data) {
+               .name = "vapb_0",
+               .ops = &clk_gate_ops,
+               .parent_names = (const char *[]){ "vapb_0_div" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+       },
+};
+
+static struct clk_mux gxbb_vapb_1_sel = {
+       .reg = (void *)HHI_VAPBCLK_CNTL,
+       .mask = 0x3,
+       .shift = 25,
+       .lock = &clk_lock,
+       .table = mux_table_vapb,
+       .hw.init = &(struct clk_init_data){
+               .name = "vapb_1_sel",
+               .ops = &clk_mux_ops,
+               /*
+                * bits 25:26 selects from 4 possible parents:
+                * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
+                */
+               .parent_names = gxbb_vapb_parent_names,
+               .num_parents = ARRAY_SIZE(gxbb_vapb_parent_names),
+               .flags = CLK_SET_RATE_NO_REPARENT,
+       },
+};
+
+static struct clk_divider gxbb_vapb_1_div = {
+       .reg = (void *)HHI_VAPBCLK_CNTL,
+       .shift = 16,
+       .width = 7,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "vapb_1_div",
+               .ops = &clk_divider_ops,
+               .parent_names = (const char *[]){ "vapb_1_sel" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_gate gxbb_vapb_1 = {
+       .reg = (void *)HHI_VAPBCLK_CNTL,
+       .bit_idx = 24,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data) {
+               .name = "vapb_1",
+               .ops = &clk_gate_ops,
+               .parent_names = (const char *[]){ "vapb_1_div" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+       },
+};
+
+static struct clk_mux gxbb_vapb_sel = {
+       .reg = (void *)HHI_VAPBCLK_CNTL,
+       .mask = 1,
+       .shift = 31,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "vapb_sel",
+               .ops = &clk_mux_ops,
+               /*
+                * bit 31 selects from 2 possible parents:
+                * vapb_0 or vapb_1
+                */
+               .parent_names = (const char *[]){ "vapb_0", "vapb_1" },
+               .num_parents = 2,
+               .flags = CLK_SET_RATE_NO_REPARENT,
+       },
+};
+
+static struct clk_gate gxbb_vapb = {
+       .reg = (void *)HHI_VAPBCLK_CNTL,
+       .bit_idx = 30,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data) {
+               .name = "vapb",
+               .ops = &clk_gate_ops,
+               .parent_names = (const char *[]){ "vapb_sel" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+       },
+};
+
 /* Everything Else (EE) domain gates */
 static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0);
 static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1);
@@ -1349,6 +1596,21 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
                [CLKID_SD_EMMC_C_CLK0_SEL]  = &gxbb_sd_emmc_c_clk0_sel.hw,
                [CLKID_SD_EMMC_C_CLK0_DIV]  = &gxbb_sd_emmc_c_clk0_div.hw,
                [CLKID_SD_EMMC_C_CLK0]      = &gxbb_sd_emmc_c_clk0.hw,
+               [CLKID_VPU_0_SEL]           = &gxbb_vpu_0_sel.hw,
+               [CLKID_VPU_0_DIV]           = &gxbb_vpu_0_div.hw,
+               [CLKID_VPU_0]               = &gxbb_vpu_0.hw,
+               [CLKID_VPU_1_SEL]           = &gxbb_vpu_1_sel.hw,
+               [CLKID_VPU_1_DIV]           = &gxbb_vpu_1_div.hw,
+               [CLKID_VPU_1]               = &gxbb_vpu_1.hw,
+               [CLKID_VPU]                 = &gxbb_vpu.hw,
+               [CLKID_VAPB_0_SEL]          = &gxbb_vapb_0_sel.hw,
+               [CLKID_VAPB_0_DIV]          = &gxbb_vapb_0_div.hw,
+               [CLKID_VAPB_0]              = &gxbb_vapb_0.hw,
+               [CLKID_VAPB_1_SEL]          = &gxbb_vapb_1_sel.hw,
+               [CLKID_VAPB_1_DIV]          = &gxbb_vapb_1_div.hw,
+               [CLKID_VAPB_1]              = &gxbb_vapb_1.hw,
+               [CLKID_VAPB_SEL]            = &gxbb_vapb_sel.hw,
+               [CLKID_VAPB]                = &gxbb_vapb.hw,
                [NR_CLKS]                   = NULL,
        },
        .num = NR_CLKS,
@@ -1481,6 +1743,21 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
                [CLKID_SD_EMMC_C_CLK0_SEL]  = &gxbb_sd_emmc_c_clk0_sel.hw,
                [CLKID_SD_EMMC_C_CLK0_DIV]  = &gxbb_sd_emmc_c_clk0_div.hw,
                [CLKID_SD_EMMC_C_CLK0]      = &gxbb_sd_emmc_c_clk0.hw,
+               [CLKID_VPU_0_SEL]           = &gxbb_vpu_0_sel.hw,
+               [CLKID_VPU_0_DIV]           = &gxbb_vpu_0_div.hw,
+               [CLKID_VPU_0]               = &gxbb_vpu_0.hw,
+               [CLKID_VPU_1_SEL]           = &gxbb_vpu_1_sel.hw,
+               [CLKID_VPU_1_DIV]           = &gxbb_vpu_1_div.hw,
+               [CLKID_VPU_1]               = &gxbb_vpu_1.hw,
+               [CLKID_VPU]                 = &gxbb_vpu.hw,
+               [CLKID_VAPB_0_SEL]          = &gxbb_vapb_0_sel.hw,
+               [CLKID_VAPB_0_DIV]          = &gxbb_vapb_0_div.hw,
+               [CLKID_VAPB_0]              = &gxbb_vapb_0.hw,
+               [CLKID_VAPB_1_SEL]          = &gxbb_vapb_1_sel.hw,
+               [CLKID_VAPB_1_DIV]          = &gxbb_vapb_1_div.hw,
+               [CLKID_VAPB_1]              = &gxbb_vapb_1.hw,
+               [CLKID_VAPB_SEL]            = &gxbb_vapb_sel.hw,
+               [CLKID_VAPB]                = &gxbb_vapb.hw,
                [NR_CLKS]                   = NULL,
        },
        .num = NR_CLKS,
@@ -1600,6 +1877,11 @@ static struct clk_gate *const gxbb_clk_gates[] = {
        &gxbb_sd_emmc_a_clk0,
        &gxbb_sd_emmc_b_clk0,
        &gxbb_sd_emmc_c_clk0,
+       &gxbb_vpu_0,
+       &gxbb_vpu_1,
+       &gxbb_vapb_0,
+       &gxbb_vapb_1,
+       &gxbb_vapb,
 };
 
 static struct clk_mux *const gxbb_clk_muxes[] = {
@@ -1615,6 +1897,12 @@ static struct clk_mux *const gxbb_clk_muxes[] = {
        &gxbb_sd_emmc_a_clk0_sel,
        &gxbb_sd_emmc_b_clk0_sel,
        &gxbb_sd_emmc_c_clk0_sel,
+       &gxbb_vpu_0_sel,
+       &gxbb_vpu_1_sel,
+       &gxbb_vpu,
+       &gxbb_vapb_0_sel,
+       &gxbb_vapb_1_sel,
+       &gxbb_vapb_sel,
 };
 
 static struct clk_divider *const gxbb_clk_dividers[] = {
@@ -1627,6 +1915,10 @@ static struct clk_divider *const gxbb_clk_dividers[] = {
        &gxbb_sd_emmc_a_clk0_div,
        &gxbb_sd_emmc_b_clk0_div,
        &gxbb_sd_emmc_c_clk0_div,
+       &gxbb_vpu_0_div,
+       &gxbb_vpu_1_div,
+       &gxbb_vapb_0_div,
+       &gxbb_vapb_1_div,
 };
 
 static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = {
index 5b1d4b374d1c21dfa9ded8167b5e9d32bad95b77..aee6fbba20043275cd25adce6b2548febcbea2b9 100644 (file)
 #define CLKID_SD_EMMC_B_CLK0_DIV  121
 #define CLKID_SD_EMMC_C_CLK0_SEL  123
 #define CLKID_SD_EMMC_C_CLK0_DIV  124
+#define CLKID_VPU_0_DIV                  127
+#define CLKID_VPU_1_DIV                  130
+#define CLKID_VAPB_0_DIV         134
+#define CLKID_VAPB_1_DIV         137
 
-#define NR_CLKS                          126
+#define NR_CLKS                          141
 
 /* include the CLKIDs that have been made part of the DT binding */
 #include <dt-bindings/clock/gxbb-clkc.h>
index 4c717db05f2deb61a4519c7b112d3c75199371fe..fb294ada0b03d770de27a02b151c9e311b2462cf 100644 (file)
@@ -114,7 +114,7 @@ static void clk_apbc_unprepare(struct clk_hw *hw)
                spin_unlock_irqrestore(apbc->lock, flags);
 }
 
-static struct clk_ops clk_apbc_ops = {
+static const struct clk_ops clk_apbc_ops = {
        .prepare = clk_apbc_prepare,
        .unprepare = clk_apbc_unprepare,
 };
index 47b5542ce50f3ec8c356eeb4bdbf9c580f207bfd..b7ce8f52026e40be24e5683d458dbb3597bb860e 100644 (file)
@@ -60,7 +60,7 @@ static void clk_apmu_disable(struct clk_hw *hw)
                spin_unlock_irqrestore(apmu->lock, flags);
 }
 
-static struct clk_ops clk_apmu_ops = {
+static const struct clk_ops clk_apmu_ops = {
        .enable = clk_apmu_enable,
        .disable = clk_apmu_disable,
 };
index 584a9927993b41f73df73f40ec598f4e7d45ca1d..cb43d54735b054cf971875e02d1ee30caae12652 100644 (file)
@@ -149,7 +149,7 @@ static void clk_factor_init(struct clk_hw *hw)
                spin_unlock_irqrestore(factor->lock, flags);
 }
 
-static struct clk_ops clk_factor_ops = {
+static const struct clk_ops clk_factor_ops = {
        .recalc_rate = clk_factor_recalc_rate,
        .round_rate = clk_factor_round_rate,
        .set_rate = clk_factor_set_rate,
@@ -172,10 +172,8 @@ struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,
        }
 
        factor = kzalloc(sizeof(*factor), GFP_KERNEL);
-       if (!factor) {
-               pr_err("%s: could not allocate factor  clk\n", __func__);
+       if (!factor)
                return ERR_PTR(-ENOMEM);
-       }
 
        /* struct clk_aux assignments */
        factor->base = base;
index d20cd3431ac27547121d8bc6412c460a45b1ff10..7355595c42e21e4249590b40292cc2a814e7002b 100644 (file)
@@ -103,10 +103,8 @@ struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
 
        /* allocate the gate */
        gate = kzalloc(sizeof(*gate), GFP_KERNEL);
-       if (!gate) {
-               pr_err("%s:%s could not allocate gate clk\n", __func__, name);
+       if (!gate)
                return ERR_PTR(-ENOMEM);
-       }
 
        init.name = name;
        init.ops = &mmp_clk_gate_ops;
index c554833cffc509a8d2e120c4af5873b8100e3018..90814b2613c0c2c4e01a1b39b186ee06d1efbcc1 100644 (file)
@@ -229,7 +229,7 @@ static int mmp_clk_mix_determine_rate(struct clk_hw *hw,
                        parent_rate = clk_hw_get_rate(parent);
                        mix_rate = parent_rate / item->divisor;
                        gap = abs(mix_rate - req->rate);
-                       if (parent_best == NULL || gap < gap_best) {
+                       if (!parent_best || gap < gap_best) {
                                parent_best = parent;
                                parent_rate_best = parent_rate;
                                mix_rate_best = mix_rate;
@@ -247,7 +247,7 @@ static int mmp_clk_mix_determine_rate(struct clk_hw *hw,
                                div = _get_div(mix, j);
                                mix_rate = parent_rate / div;
                                gap = abs(mix_rate - req->rate);
-                               if (parent_best == NULL || gap < gap_best) {
+                               if (!parent_best || gap < gap_best) {
                                        parent_best = parent;
                                        parent_rate_best = parent_rate;
                                        mix_rate_best = mix_rate;
@@ -451,11 +451,8 @@ struct clk *mmp_clk_register_mix(struct device *dev,
        size_t table_bytes;
 
        mix = kzalloc(sizeof(*mix), GFP_KERNEL);
-       if (!mix) {
-               pr_err("%s:%s: could not allocate mmp mix clk\n",
-                       __func__, name);
+       if (!mix)
                return ERR_PTR(-ENOMEM);
-       }
 
        init.name = name;
        init.flags = flags | CLK_GET_RATE_NOCACHE;
@@ -467,12 +464,9 @@ struct clk *mmp_clk_register_mix(struct device *dev,
        if (config->table) {
                table_bytes = sizeof(*config->table) * config->table_size;
                mix->table = kmemdup(config->table, table_bytes, GFP_KERNEL);
-               if (!mix->table) {
-                       pr_err("%s:%s: could not allocate mmp mix table\n",
-                               __func__, name);
-                       kfree(mix);
-                       return ERR_PTR(-ENOMEM);
-               }
+               if (!mix->table)
+                       goto free_mix;
+
                mix->table_size = config->table_size;
        }
 
@@ -481,11 +475,8 @@ struct clk *mmp_clk_register_mix(struct device *dev,
                mix->mux_table = kmemdup(config->mux_table, table_bytes,
                                         GFP_KERNEL);
                if (!mix->mux_table) {
-                       pr_err("%s:%s: could not allocate mmp mix mux-table\n",
-                               __func__, name);
                        kfree(mix->table);
-                       kfree(mix);
-                       return ERR_PTR(-ENOMEM);
+                       goto free_mix;
                }
        }
 
@@ -509,4 +500,8 @@ struct clk *mmp_clk_register_mix(struct device *dev,
        }
 
        return clk;
+
+free_mix:
+       kfree(mix);
+       return ERR_PTR(-ENOMEM);
 }
index 038023483b98fe1f4d2cbed08f8a6525e7360d53..7460031714da970569aee9209279b62953cdfa5d 100644 (file)
@@ -83,19 +83,19 @@ void __init mmp2_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
        void __iomem *apbc_base;
 
        mpmu_base = ioremap(mpmu_phys, SZ_4K);
-       if (mpmu_base == NULL) {
+       if (!mpmu_base) {
                pr_err("error to ioremap MPMU base\n");
                return;
        }
 
        apmu_base = ioremap(apmu_phys, SZ_4K);
-       if (apmu_base == NULL) {
+       if (!apmu_base) {
                pr_err("error to ioremap APMU base\n");
                return;
        }
 
        apbc_base = ioremap(apbc_phys, SZ_4K);
-       if (apbc_base == NULL) {
+       if (!apbc_base) {
                pr_err("error to ioremap APBC base\n");
                return;
        }
index a9ef9209532aa66605c1eca9de7b1f74d52ae09c..8e2551ab846251ce4bdd0b4e13fc70e832db4782 100644 (file)
@@ -75,19 +75,19 @@ void __init pxa168_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
        void __iomem *apbc_base;
 
        mpmu_base = ioremap(mpmu_phys, SZ_4K);
-       if (mpmu_base == NULL) {
+       if (!mpmu_base) {
                pr_err("error to ioremap MPMU base\n");
                return;
        }
 
        apmu_base = ioremap(apmu_phys, SZ_4K);
-       if (apmu_base == NULL) {
+       if (!apmu_base) {
                pr_err("error to ioremap APMU base\n");
                return;
        }
 
        apbc_base = ioremap(apbc_phys, SZ_4K);
-       if (apbc_base == NULL) {
+       if (!apbc_base) {
                pr_err("error to ioremap APBC base\n");
                return;
        }
index a520cf7702a11649fe14581a59cdb063c859b461..7a79651419183dfa044bcd8ccfd69d87953ce810 100644 (file)
@@ -74,25 +74,25 @@ void __init pxa910_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
        void __iomem *apbc_base;
 
        mpmu_base = ioremap(mpmu_phys, SZ_4K);
-       if (mpmu_base == NULL) {
+       if (!mpmu_base) {
                pr_err("error to ioremap MPMU base\n");
                return;
        }
 
        apmu_base = ioremap(apmu_phys, SZ_4K);
-       if (apmu_base == NULL) {
+       if (!apmu_base) {
                pr_err("error to ioremap APMU base\n");
                return;
        }
 
        apbcp_base = ioremap(apbcp_phys, SZ_4K);
-       if (apbcp_base == NULL) {
+       if (!apbcp_base) {
                pr_err("error to ioremap APBC extension base\n");
                return;
        }
 
        apbc_base = ioremap(apbc_phys, SZ_4K);
-       if (apbc_base == NULL) {
+       if (!apbc_base) {
                pr_err("error to ioremap APBC base\n");
                return;
        }
index f75e989c578ffca5ce8474262a60b9809e13fd7f..ccebd014fc1ea70350ad1bc4a4a9594055cf9786 100644 (file)
@@ -67,7 +67,7 @@ static int clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
        return ret;
 }
 
-static struct clk_ops clk_div_ops = {
+static const struct clk_ops clk_div_ops = {
        .recalc_rate = clk_div_recalc_rate,
        .round_rate = clk_div_round_rate,
        .set_rate = clk_div_set_rate,
index f8dd10f6df3d47347ea245a5a2b8275ec738f9f4..27b3372adc37e3531aec3dac77f19a0a97ebe486 100644 (file)
@@ -107,7 +107,7 @@ static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate,
        return mxs_clk_wait(frac->reg, frac->busy);
 }
 
-static struct clk_ops clk_frac_ops = {
+static const struct clk_ops clk_frac_ops = {
        .recalc_rate = clk_frac_recalc_rate,
        .round_rate = clk_frac_round_rate,
        .set_rate = clk_frac_set_rate,
index 74f64c3c429098b832840b5082ab3eb15e5ef73f..b80dc9d5855c9a041957cb7f067d072d868466b8 100644 (file)
@@ -147,9 +147,7 @@ void pxa2xx_core_turbo_switch(bool on)
        "       b       3f\n"
        "2:     b       1b\n"
        "3:     nop\n"
-               : "=&r" (unused)
-               : "r" (clkcfg)
-               : );
+               : "=&r" (unused) : "r" (clkcfg));
 
        local_irq_restore(flags);
 }
index 1b3e8d265bdb02c08c96c7cfecfb3ce8e401de60..a2495457e5647f1ca0e11c23191a9486b8f59cd0 100644 (file)
@@ -156,7 +156,6 @@ extern const struct clk_ops clk_dyn_rcg_ops;
  * @hid_width: number of bits in half integer divider
  * @parent_map: map from software's parent index to hardware's src_sel field
  * @freq_tbl: frequency table
- * @current_freq: last cached frequency when using branches with shared RCGs
  * @clkr: regmap clock handle
  *
  */
@@ -166,7 +165,6 @@ struct clk_rcg2 {
        u8                      hid_width;
        const struct parent_map *parent_map;
        const struct freq_tbl   *freq_tbl;
-       unsigned long           current_freq;
        struct clk_regmap       clkr;
 };
 
@@ -174,7 +172,6 @@ struct clk_rcg2 {
 
 extern const struct clk_ops clk_rcg2_ops;
 extern const struct clk_ops clk_rcg2_floor_ops;
-extern const struct clk_ops clk_rcg2_shared_ops;
 extern const struct clk_ops clk_edp_pixel_ops;
 extern const struct clk_ops clk_byte_ops;
 extern const struct clk_ops clk_byte2_ops;
index 1a0985ae20d2e34a2f4588784bfd70ba2f66050f..bbeaf9c09dbb4750cd6479ae16ab416626a19731 100644 (file)
@@ -358,85 +358,6 @@ const struct clk_ops clk_rcg2_floor_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_rcg2_floor_ops);
 
-static int clk_rcg2_shared_force_enable(struct clk_hw *hw, unsigned long rate)
-{
-       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-       const char *name = clk_hw_get_name(hw);
-       int ret, count;
-
-       /* force enable RCG */
-       ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG,
-                                CMD_ROOT_EN, CMD_ROOT_EN);
-       if (ret)
-               return ret;
-
-       /* wait for RCG to turn ON */
-       for (count = 500; count > 0; count--) {
-               ret = clk_rcg2_is_enabled(hw);
-               if (ret)
-                       break;
-               udelay(1);
-       }
-       if (!count)
-               pr_err("%s: RCG did not turn on\n", name);
-
-       /* set clock rate */
-       ret = __clk_rcg2_set_rate(hw, rate, CEIL);
-       if (ret)
-               return ret;
-
-       /* clear force enable RCG */
-       return regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG,
-                                CMD_ROOT_EN, 0);
-}
-
-static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate,
-                                   unsigned long parent_rate)
-{
-       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-
-       /* cache the rate */
-       rcg->current_freq = rate;
-
-       if (!__clk_is_enabled(hw->clk))
-               return 0;
-
-       return clk_rcg2_shared_force_enable(hw, rcg->current_freq);
-}
-
-static unsigned long
-clk_rcg2_shared_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-{
-       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-
-       return rcg->current_freq = clk_rcg2_recalc_rate(hw, parent_rate);
-}
-
-static int clk_rcg2_shared_enable(struct clk_hw *hw)
-{
-       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-
-       return clk_rcg2_shared_force_enable(hw, rcg->current_freq);
-}
-
-static void clk_rcg2_shared_disable(struct clk_hw *hw)
-{
-       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-
-       /* switch to XO, which is the lowest entry in the freq table */
-       clk_rcg2_shared_set_rate(hw, rcg->freq_tbl[0].freq, 0);
-}
-
-const struct clk_ops clk_rcg2_shared_ops = {
-       .enable = clk_rcg2_shared_enable,
-       .disable = clk_rcg2_shared_disable,
-       .get_parent = clk_rcg2_get_parent,
-       .recalc_rate = clk_rcg2_shared_recalc_rate,
-       .determine_rate = clk_rcg2_determine_rate,
-       .set_rate = clk_rcg2_shared_set_rate,
-};
-EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops);
-
 struct frac_entry {
        int num;
        int den;
index df3e5fe8442a555a3f22380bebd6a7a41645013d..c60f61b10c7f9335bc269489b84b4d16d44863a7 100644 (file)
                },                                                            \
        }
 
+#define DEFINE_CLK_RPM_FIXED(_platform, _name, _active, r_id, r)             \
+       static struct clk_rpm _platform##_##_name = {                         \
+               .rpm_clk_id = (r_id),                                         \
+               .rate = (r),                                                  \
+               .hw.init = &(struct clk_init_data){                           \
+                       .ops = &clk_rpm_fixed_ops,                            \
+                       .name = #_name,                                       \
+                       .parent_names = (const char *[]){ "pxo" },            \
+                       .num_parents = 1,                                     \
+               },                                                            \
+       }
+
 #define DEFINE_CLK_RPM_PXO_BRANCH(_platform, _name, _active, r_id, r)        \
        static struct clk_rpm _platform##_##_active;                          \
        static struct clk_rpm _platform##_##_name = {                         \
@@ -143,6 +155,13 @@ static int clk_rpm_handoff(struct clk_rpm *r)
        int ret;
        u32 value = INT_MAX;
 
+       /*
+        * The vendor tree simply reads the status for this
+        * RPM clock.
+        */
+       if (r->rpm_clk_id == QCOM_RPM_PLL_4)
+               return 0;
+
        ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE,
                             r->rpm_clk_id, &value, 1);
        if (ret)
@@ -269,6 +288,32 @@ out:
        mutex_unlock(&rpm_clk_lock);
 }
 
+static int clk_rpm_fixed_prepare(struct clk_hw *hw)
+{
+       struct clk_rpm *r = to_clk_rpm(hw);
+       u32 value = 1;
+       int ret;
+
+       ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE,
+                            r->rpm_clk_id, &value, 1);
+       if (!ret)
+               r->enabled = true;
+
+       return ret;
+}
+
+static void clk_rpm_fixed_unprepare(struct clk_hw *hw)
+{
+       struct clk_rpm *r = to_clk_rpm(hw);
+       u32 value = 0;
+       int ret;
+
+       ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE,
+                            r->rpm_clk_id, &value, 1);
+       if (!ret)
+               r->enabled = false;
+}
+
 static int clk_rpm_set_rate(struct clk_hw *hw,
                            unsigned long rate, unsigned long parent_rate)
 {
@@ -333,6 +378,13 @@ static unsigned long clk_rpm_recalc_rate(struct clk_hw *hw,
        return r->rate;
 }
 
+static const struct clk_ops clk_rpm_fixed_ops = {
+       .prepare        = clk_rpm_fixed_prepare,
+       .unprepare      = clk_rpm_fixed_unprepare,
+       .round_rate     = clk_rpm_round_rate,
+       .recalc_rate    = clk_rpm_recalc_rate,
+};
+
 static const struct clk_ops clk_rpm_ops = {
        .prepare        = clk_rpm_prepare,
        .unprepare      = clk_rpm_unprepare,
@@ -348,6 +400,45 @@ static const struct clk_ops clk_rpm_branch_ops = {
        .recalc_rate    = clk_rpm_recalc_rate,
 };
 
+/* MSM8660/APQ8060 */
+DEFINE_CLK_RPM(msm8660, afab_clk, afab_a_clk, QCOM_RPM_APPS_FABRIC_CLK);
+DEFINE_CLK_RPM(msm8660, sfab_clk, sfab_a_clk, QCOM_RPM_SYS_FABRIC_CLK);
+DEFINE_CLK_RPM(msm8660, mmfab_clk, mmfab_a_clk, QCOM_RPM_MM_FABRIC_CLK);
+DEFINE_CLK_RPM(msm8660, daytona_clk, daytona_a_clk, QCOM_RPM_DAYTONA_FABRIC_CLK);
+DEFINE_CLK_RPM(msm8660, sfpb_clk, sfpb_a_clk, QCOM_RPM_SFPB_CLK);
+DEFINE_CLK_RPM(msm8660, cfpb_clk, cfpb_a_clk, QCOM_RPM_CFPB_CLK);
+DEFINE_CLK_RPM(msm8660, mmfpb_clk, mmfpb_a_clk, QCOM_RPM_MMFPB_CLK);
+DEFINE_CLK_RPM(msm8660, smi_clk, smi_a_clk, QCOM_RPM_SMI_CLK);
+DEFINE_CLK_RPM(msm8660, ebi1_clk, ebi1_a_clk, QCOM_RPM_EBI1_CLK);
+DEFINE_CLK_RPM_FIXED(msm8660, pll4_clk, pll4_a_clk, QCOM_RPM_PLL_4, 540672000);
+
+static struct clk_rpm *msm8660_clks[] = {
+       [RPM_APPS_FABRIC_CLK] = &msm8660_afab_clk,
+       [RPM_APPS_FABRIC_A_CLK] = &msm8660_afab_a_clk,
+       [RPM_SYS_FABRIC_CLK] = &msm8660_sfab_clk,
+       [RPM_SYS_FABRIC_A_CLK] = &msm8660_sfab_a_clk,
+       [RPM_MM_FABRIC_CLK] = &msm8660_mmfab_clk,
+       [RPM_MM_FABRIC_A_CLK] = &msm8660_mmfab_a_clk,
+       [RPM_DAYTONA_FABRIC_CLK] = &msm8660_daytona_clk,
+       [RPM_DAYTONA_FABRIC_A_CLK] = &msm8660_daytona_a_clk,
+       [RPM_SFPB_CLK] = &msm8660_sfpb_clk,
+       [RPM_SFPB_A_CLK] = &msm8660_sfpb_a_clk,
+       [RPM_CFPB_CLK] = &msm8660_cfpb_clk,
+       [RPM_CFPB_A_CLK] = &msm8660_cfpb_a_clk,
+       [RPM_MMFPB_CLK] = &msm8660_mmfpb_clk,
+       [RPM_MMFPB_A_CLK] = &msm8660_mmfpb_a_clk,
+       [RPM_SMI_CLK] = &msm8660_smi_clk,
+       [RPM_SMI_A_CLK] = &msm8660_smi_a_clk,
+       [RPM_EBI1_CLK] = &msm8660_ebi1_clk,
+       [RPM_EBI1_A_CLK] = &msm8660_ebi1_a_clk,
+       [RPM_PLL4_CLK] = &msm8660_pll4_clk,
+};
+
+static const struct rpm_clk_desc rpm_clk_msm8660 = {
+       .clks = msm8660_clks,
+       .num_clks = ARRAY_SIZE(msm8660_clks),
+};
+
 /* apq8064 */
 DEFINE_CLK_RPM(apq8064, afab_clk, afab_a_clk, QCOM_RPM_APPS_FABRIC_CLK);
 DEFINE_CLK_RPM(apq8064, cfpb_clk, cfpb_a_clk, QCOM_RPM_CFPB_CLK);
@@ -386,6 +477,8 @@ static const struct rpm_clk_desc rpm_clk_apq8064 = {
 };
 
 static const struct of_device_id rpm_clk_match_table[] = {
+       { .compatible = "qcom,rpmcc-msm8660", .data = &rpm_clk_msm8660 },
+       { .compatible = "qcom,rpmcc-apq8060", .data = &rpm_clk_msm8660 },
        { .compatible = "qcom,rpmcc-apq8064", .data = &rpm_clk_apq8064 },
        { }
 };
index cc03d5508627b3ee11cf17eb8762b94f21740f16..c26d9007bfc41c5c21053b3bd2ff9d5ba4dc2a29 100644 (file)
@@ -530,9 +530,91 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8974 = {
        .clks = msm8974_clks,
        .num_clks = ARRAY_SIZE(msm8974_clks),
 };
+
+/* msm8996 */
+DEFINE_CLK_SMD_RPM(msm8996, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
+DEFINE_CLK_SMD_RPM(msm8996, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
+DEFINE_CLK_SMD_RPM(msm8996, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2);
+DEFINE_CLK_SMD_RPM(msm8996, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
+DEFINE_CLK_SMD_RPM(msm8996, mmssnoc_axi_rpm_clk, mmssnoc_axi_rpm_a_clk,
+                  QCOM_SMD_RPM_MMAXI_CLK, 0);
+DEFINE_CLK_SMD_RPM(msm8996, ipa_clk, ipa_a_clk, QCOM_SMD_RPM_IPA_CLK, 0);
+DEFINE_CLK_SMD_RPM(msm8996, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0);
+DEFINE_CLK_SMD_RPM_BRANCH(msm8996, aggre1_noc_clk, aggre1_noc_a_clk,
+                         QCOM_SMD_RPM_AGGR_CLK, 1, 1000);
+DEFINE_CLK_SMD_RPM_BRANCH(msm8996, aggre2_noc_clk, aggre2_noc_a_clk,
+                         QCOM_SMD_RPM_AGGR_CLK, 2, 1000);
+DEFINE_CLK_SMD_RPM_QDSS(msm8996, qdss_clk, qdss_a_clk,
+                       QCOM_SMD_RPM_MISC_CLK, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, bb_clk1, bb_clk1_a, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, bb_clk2, bb_clk2_a, 2);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, rf_clk1, rf_clk1_a, 4);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, rf_clk2, rf_clk2_a, 5);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, ln_bb_clk, ln_bb_a_clk, 8);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, div_clk1, div_clk1_a, 0xb);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, div_clk2, div_clk2_a, 0xc);
+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, div_clk3, div_clk3_a, 0xd);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, bb_clk1_pin, bb_clk1_a_pin, 1);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, bb_clk2_pin, bb_clk2_a_pin, 2);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, rf_clk1_pin, rf_clk1_a_pin, 4);
+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, rf_clk2_pin, rf_clk2_a_pin, 5);
+
+static struct clk_smd_rpm *msm8996_clks[] = {
+       [RPM_SMD_PCNOC_CLK] = &msm8996_pcnoc_clk,
+       [RPM_SMD_PCNOC_A_CLK] = &msm8996_pcnoc_a_clk,
+       [RPM_SMD_SNOC_CLK] = &msm8996_snoc_clk,
+       [RPM_SMD_SNOC_A_CLK] = &msm8996_snoc_a_clk,
+       [RPM_SMD_CNOC_CLK] = &msm8996_cnoc_clk,
+       [RPM_SMD_CNOC_A_CLK] = &msm8996_cnoc_a_clk,
+       [RPM_SMD_BIMC_CLK] = &msm8996_bimc_clk,
+       [RPM_SMD_BIMC_A_CLK] = &msm8996_bimc_a_clk,
+       [RPM_SMD_MMAXI_CLK] = &msm8996_mmssnoc_axi_rpm_clk,
+       [RPM_SMD_MMAXI_A_CLK] = &msm8996_mmssnoc_axi_rpm_a_clk,
+       [RPM_SMD_IPA_CLK] = &msm8996_ipa_clk,
+       [RPM_SMD_IPA_A_CLK] = &msm8996_ipa_a_clk,
+       [RPM_SMD_CE1_CLK] = &msm8996_ce1_clk,
+       [RPM_SMD_CE1_A_CLK] = &msm8996_ce1_a_clk,
+       [RPM_SMD_AGGR1_NOC_CLK] = &msm8996_aggre1_noc_clk,
+       [RPM_SMD_AGGR1_NOC_A_CLK] = &msm8996_aggre1_noc_a_clk,
+       [RPM_SMD_AGGR2_NOC_CLK] = &msm8996_aggre2_noc_clk,
+       [RPM_SMD_AGGR2_NOC_A_CLK] = &msm8996_aggre2_noc_a_clk,
+       [RPM_SMD_QDSS_CLK] = &msm8996_qdss_clk,
+       [RPM_SMD_QDSS_A_CLK] = &msm8996_qdss_a_clk,
+       [RPM_SMD_BB_CLK1] = &msm8996_bb_clk1,
+       [RPM_SMD_BB_CLK1_A] = &msm8996_bb_clk1_a,
+       [RPM_SMD_BB_CLK2] = &msm8996_bb_clk2,
+       [RPM_SMD_BB_CLK2_A] = &msm8996_bb_clk2_a,
+       [RPM_SMD_RF_CLK1] = &msm8996_rf_clk1,
+       [RPM_SMD_RF_CLK1_A] = &msm8996_rf_clk1_a,
+       [RPM_SMD_RF_CLK2] = &msm8996_rf_clk2,
+       [RPM_SMD_RF_CLK2_A] = &msm8996_rf_clk2_a,
+       [RPM_SMD_LN_BB_CLK] = &msm8996_ln_bb_clk,
+       [RPM_SMD_LN_BB_A_CLK] = &msm8996_ln_bb_a_clk,
+       [RPM_SMD_DIV_CLK1] = &msm8996_div_clk1,
+       [RPM_SMD_DIV_A_CLK1] = &msm8996_div_clk1_a,
+       [RPM_SMD_DIV_CLK2] = &msm8996_div_clk2,
+       [RPM_SMD_DIV_A_CLK2] = &msm8996_div_clk2_a,
+       [RPM_SMD_DIV_CLK3] = &msm8996_div_clk3,
+       [RPM_SMD_DIV_A_CLK3] = &msm8996_div_clk3_a,
+       [RPM_SMD_BB_CLK1_PIN] = &msm8996_bb_clk1_pin,
+       [RPM_SMD_BB_CLK1_A_PIN] = &msm8996_bb_clk1_a_pin,
+       [RPM_SMD_BB_CLK2_PIN] = &msm8996_bb_clk2_pin,
+       [RPM_SMD_BB_CLK2_A_PIN] = &msm8996_bb_clk2_a_pin,
+       [RPM_SMD_RF_CLK1_PIN] = &msm8996_rf_clk1_pin,
+       [RPM_SMD_RF_CLK1_A_PIN] = &msm8996_rf_clk1_a_pin,
+       [RPM_SMD_RF_CLK2_PIN] = &msm8996_rf_clk2_pin,
+       [RPM_SMD_RF_CLK2_A_PIN] = &msm8996_rf_clk2_a_pin,
+};
+
+static const struct rpm_smd_clk_desc rpm_clk_msm8996 = {
+       .clks = msm8996_clks,
+       .num_clks = ARRAY_SIZE(msm8996_clks),
+};
+
 static const struct of_device_id rpm_smd_clk_match_table[] = {
        { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 },
        { .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 },
+       { .compatible = "qcom,rpmcc-msm8996", .data = &rpm_clk_msm8996 },
        { }
 };
 MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table);
index d523991c945f9d4cbcd047c8a7edbb405d0e85ba..b8064a336d464bbe9aa253c39ebf0c3283c2ee54 100644 (file)
@@ -111,16 +111,6 @@ qcom_pll_set_fsm_mode(struct regmap *map, u32 reg, u8 bias_count, u8 lock_count)
 }
 EXPORT_SYMBOL_GPL(qcom_pll_set_fsm_mode);
 
-static void qcom_cc_del_clk_provider(void *data)
-{
-       of_clk_del_provider(data);
-}
-
-static void qcom_cc_reset_unregister(void *data)
-{
-       reset_controller_unregister(data);
-}
-
 static void qcom_cc_gdsc_unregister(void *data)
 {
        gdsc_unregister(data);
@@ -143,8 +133,10 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path,
        int ret;
 
        clocks_node = of_find_node_by_path("/clocks");
-       if (clocks_node)
-               node = of_find_node_by_name(clocks_node, path);
+       if (clocks_node) {
+               node = of_get_child_by_name(clocks_node, path);
+               of_node_put(clocks_node);
+       }
 
        if (!node) {
                fixed = devm_kzalloc(dev, sizeof(*fixed), GFP_KERNEL);
@@ -248,13 +240,7 @@ int qcom_cc_really_probe(struct platform_device *pdev,
                        return ret;
        }
 
-       ret = of_clk_add_hw_provider(dev->of_node, qcom_cc_clk_hw_get, cc);
-       if (ret)
-               return ret;
-
-       ret = devm_add_action_or_reset(dev, qcom_cc_del_clk_provider,
-                                      pdev->dev.of_node);
-
+       ret = devm_of_clk_add_hw_provider(dev, qcom_cc_clk_hw_get, cc);
        if (ret)
                return ret;
 
@@ -266,13 +252,7 @@ int qcom_cc_really_probe(struct platform_device *pdev,
        reset->regmap = regmap;
        reset->reset_map = desc->resets;
 
-       ret = reset_controller_register(&reset->rcdev);
-       if (ret)
-               return ret;
-
-       ret = devm_add_action_or_reset(dev, qcom_cc_reset_unregister,
-                                      &reset->rcdev);
-
+       ret = devm_reset_controller_register(dev, &reset->rcdev);
        if (ret)
                return ret;
 
index acbb38151ba1c51aa57bdd3663ae31db23d1bab8..43b5a89c4b282db8fc12ce2a7279cc05fece19b4 100644 (file)
@@ -15,6 +15,7 @@ config CLK_RENESAS
        select CLK_R8A7794 if ARCH_R8A7794
        select CLK_R8A7795 if ARCH_R8A7795
        select CLK_R8A7796 if ARCH_R8A7796
+       select CLK_R8A77970 if ARCH_R8A77970
        select CLK_R8A77995 if ARCH_R8A77995
        select CLK_SH73A0 if ARCH_SH73A0
 
@@ -95,6 +96,10 @@ config CLK_R8A7796
        bool "R-Car M3-W clock support" if COMPILE_TEST
        select CLK_RCAR_GEN3_CPG
 
+config CLK_R8A77970
+       bool "R-Car V3M clock support" if COMPILE_TEST
+       select CLK_RCAR_GEN3_CPG
+
 config CLK_R8A77995
        bool "R-Car D3 clock support" if COMPILE_TEST
        select CLK_RCAR_GEN3_CPG
index cbbb081e2145e20ab25480461ff412a4387fdb4b..34c4e0b37afa0c081c8340e577da03506226fee6 100644 (file)
@@ -14,6 +14,7 @@ obj-$(CONFIG_CLK_R8A7792)             += r8a7792-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A7794)              += r8a7794-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A7795)              += r8a7795-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A7796)              += r8a7796-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A77970)             += r8a77970-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A77995)             += r8a77995-cpg-mssr.o
 obj-$(CONFIG_CLK_SH73A0)               += clk-sh73a0.o
 
index 3e0040c0ac87a14bdd0b6a44c6abeee3ef5a1c14..151336d2ba59e689c2b83bb1255000581cd25043 100644 (file)
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/notifier.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/pm.h>
 #include <linux/slab.h>
 
 #include "clk-div6.h"
@@ -32,6 +34,7 @@
  * @src_shift: Shift to access the register bits to select the parent clock
  * @src_width: Number of register bits to select the parent clock (may be 0)
  * @parents: Array to map from valid parent clocks indices to hardware indices
+ * @nb: Notifier block to save/restore clock state for system resume
  */
 struct div6_clock {
        struct clk_hw hw;
@@ -40,6 +43,7 @@ struct div6_clock {
        u32 src_shift;
        u32 src_width;
        u8 *parents;
+       struct notifier_block nb;
 };
 
 #define to_div6_clock(_hw) container_of(_hw, struct div6_clock, hw)
@@ -176,6 +180,29 @@ static const struct clk_ops cpg_div6_clock_ops = {
        .set_rate = cpg_div6_clock_set_rate,
 };
 
+static int cpg_div6_clock_notifier_call(struct notifier_block *nb,
+                                       unsigned long action, void *data)
+{
+       struct div6_clock *clock = container_of(nb, struct div6_clock, nb);
+
+       switch (action) {
+       case PM_EVENT_RESUME:
+               /*
+                * TODO: This does not yet support DIV6 clocks with multiple
+                * parents, as the parent selection bits are not restored.
+                * Fortunately so far such DIV6 clocks are found only on
+                * R/SH-Mobile SoCs, while the resume functionality is only
+                * needed on R-Car Gen3.
+                */
+               if (__clk_get_enable_count(clock->hw.clk))
+                       cpg_div6_clock_enable(&clock->hw);
+               else
+                       cpg_div6_clock_disable(&clock->hw);
+               return NOTIFY_OK;
+       }
+
+       return NOTIFY_DONE;
+}
 
 /**
  * cpg_div6_register - Register a DIV6 clock
@@ -183,11 +210,13 @@ static const struct clk_ops cpg_div6_clock_ops = {
  * @num_parents: Number of parent clocks of the DIV6 clock (1, 4, or 8)
  * @parent_names: Array containing the names of the parent clocks
  * @reg: Mapped register used to control the DIV6 clock
+ * @notifiers: Optional notifier chain to save/restore state for system resume
  */
 struct clk * __init cpg_div6_register(const char *name,
                                      unsigned int num_parents,
                                      const char **parent_names,
-                                     void __iomem *reg)
+                                     void __iomem *reg,
+                                     struct raw_notifier_head *notifiers)
 {
        unsigned int valid_parents;
        struct clk_init_data init;
@@ -258,6 +287,11 @@ struct clk * __init cpg_div6_register(const char *name,
        if (IS_ERR(clk))
                goto free_parents;
 
+       if (notifiers) {
+               clock->nb.notifier_call = cpg_div6_clock_notifier_call;
+               raw_notifier_chain_register(notifiers, &clock->nb);
+       }
+
        return clk;
 
 free_parents:
@@ -301,7 +335,7 @@ static void __init cpg_div6_clock_init(struct device_node *np)
        for (i = 0; i < num_parents; i++)
                parent_names[i] = of_clk_get_parent_name(np, i);
 
-       clk = cpg_div6_register(clk_name, num_parents, parent_names, reg);
+       clk = cpg_div6_register(clk_name, num_parents, parent_names, reg, NULL);
        if (IS_ERR(clk)) {
                pr_err("%s: failed to register %s DIV6 clock (%ld)\n",
                       __func__, np->name, PTR_ERR(clk));
index 065dfb49adf6fb10170422b56298e47809372e78..3af640a0b08dc81e01b53f50ac36a85e16dae4e3 100644 (file)
@@ -3,6 +3,7 @@
 #define __RENESAS_CLK_DIV6_H__
 
 struct clk *cpg_div6_register(const char *name, unsigned int num_parents,
-                             const char **parent_names, void __iomem *reg);
+                             const char **parent_names, void __iomem *reg,
+                             struct raw_notifier_head *notifiers);
 
 #endif
index 500a9e4e03c489579c5e056a0f27cd2100ec3e05..c944cc421e3086434a2fd59233850b55bfd19b7f 100644 (file)
@@ -156,10 +156,8 @@ static struct clk * __init cpg_mstp_clock_register(const char *name,
        struct clk *clk;
 
        clock = kzalloc(sizeof(*clock), GFP_KERNEL);
-       if (!clock) {
-               pr_err("%s: failed to allocate MSTP clock.\n", __func__);
+       if (!clock)
                return ERR_PTR(-ENOMEM);
-       }
 
        init.name = name;
        init.ops = &cpg_mstp_clock_ops;
@@ -196,7 +194,6 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
        if (group == NULL || clks == NULL) {
                kfree(group);
                kfree(clks);
-               pr_err("%s: failed to allocate group\n", __func__);
                return;
        }
 
index 0b2e56d0d94bb04c633cdebc1bef916e67d9d732..d14cbe1ca29ac0098610b1364b8fefb5ae07027d 100644 (file)
@@ -423,7 +423,6 @@ static void __init rcar_gen2_cpg_clocks_init(struct device_node *np)
                /* We're leaking memory on purpose, there's no point in cleaning
                 * up as the system won't boot anyway.
                 */
-               pr_err("%s: failed to allocate cpg\n", __func__);
                return;
        }
 
index 5adb934326d1f5be4725bc645dd13f6e3c494d7d..127c58135c8fec76b812b186b4f0d6d670ca828f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * rz Core CPG Clocks
+ * RZ/A1 Core CPG Clocks
  *
  * Copyright (C) 2013 Ideas On Board SPRL
  * Copyright (C) 2014 Wolfram Sang, Sang Engineering <wsa@sang-engineering.com>
index 9e2360a8e14b860ec4a3a5e9982c370b772be178..2859504cc8668199f69f8bd32c4ae3d9c5bdfe3f 100644 (file)
@@ -129,6 +129,7 @@ static const struct mssr_mod_clk r8a7745_mod_clks[] __initconst = {
        DEF_MOD("scif2",                 719,   R8A7745_CLK_P),
        DEF_MOD("scif1",                 720,   R8A7745_CLK_P),
        DEF_MOD("scif0",                 721,   R8A7745_CLK_P),
+       DEF_MOD("du1",                   723,   R8A7745_CLK_ZX),
        DEF_MOD("du0",                   724,   R8A7745_CLK_ZX),
        DEF_MOD("ipmmu-sgx",             800,   R8A7745_CLK_ZX),
        DEF_MOD("vin1",                  810,   R8A7745_CLK_ZG),
index 762b2f8824f118deb1a41e0f24ab5281b5179712..b1d9f48eae9e6ad492d1bc7b634ef4f32c9fd341 100644 (file)
@@ -149,7 +149,7 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = {
        DEF_MOD("usb-dmac1",             331,   R8A7795_CLK_S3D1),
        DEF_MOD("rwdt",                  402,   R8A7795_CLK_R),
        DEF_MOD("intc-ex",               407,   R8A7795_CLK_CP),
-       DEF_MOD("intc-ap",               408,   R8A7795_CLK_S3D1),
+       DEF_MOD("intc-ap",               408,   R8A7795_CLK_S0D3),
        DEF_MOD("audmac1",               501,   R8A7795_CLK_S0D3),
        DEF_MOD("audmac0",               502,   R8A7795_CLK_S0D3),
        DEF_MOD("drif7",                 508,   R8A7795_CLK_S3D2),
@@ -348,6 +348,7 @@ static const struct mssr_mod_reparent r8a7795es1_mod_reparent[] __initconst = {
        { MOD_CLK_ID(217), R8A7795_CLK_S3D1 },  /* SYS-DMAC2 */
        { MOD_CLK_ID(218), R8A7795_CLK_S3D1 },  /* SYS-DMAC1 */
        { MOD_CLK_ID(219), R8A7795_CLK_S3D1 },  /* SYS-DMAC0 */
+       { MOD_CLK_ID(408), R8A7795_CLK_S3D1 },  /* INTC-AP */
        { MOD_CLK_ID(501), R8A7795_CLK_S3D1 },  /* AUDMAC1 */
        { MOD_CLK_ID(502), R8A7795_CLK_S3D1 },  /* AUDMAC0 */
        { MOD_CLK_ID(523), R8A7795_CLK_S3D4 },  /* PWM */
index e5e7fb212288c3779dfa09ed0f001ee3f77b4408..b3767472088ac0965ef41fe13a6c2c1bde41bf2e 100644 (file)
@@ -143,7 +143,7 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = {
        DEF_MOD("usb-dmac1",             331,   R8A7796_CLK_S3D1),
        DEF_MOD("rwdt",                  402,   R8A7796_CLK_R),
        DEF_MOD("intc-ex",               407,   R8A7796_CLK_CP),
-       DEF_MOD("intc-ap",               408,   R8A7796_CLK_S3D1),
+       DEF_MOD("intc-ap",               408,   R8A7796_CLK_S0D3),
        DEF_MOD("audmac1",               501,   R8A7796_CLK_S0D3),
        DEF_MOD("audmac0",               502,   R8A7796_CLK_S0D3),
        DEF_MOD("drif7",                 508,   R8A7796_CLK_S3D2),
diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c
new file mode 100644 (file)
index 0000000..72f9852
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * r8a77970 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2017 Cogent Embedded Inc.
+ *
+ * Based on r8a7795-cpg-mssr.c
+ *
+ * Copyright (C) 2015 Glider bvba
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/soc/renesas/rcar-rst.h>
+
+#include <dt-bindings/clock/r8a77970-cpg-mssr.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen3-cpg.h"
+
+enum clk_ids {
+       /* Core Clock Outputs exported to DT */
+       LAST_DT_CORE_CLK = R8A77970_CLK_OSC,
+
+       /* External Input Clocks */
+       CLK_EXTAL,
+       CLK_EXTALR,
+
+       /* Internal Core Clocks */
+       CLK_MAIN,
+       CLK_PLL0,
+       CLK_PLL1,
+       CLK_PLL3,
+       CLK_PLL1_DIV2,
+       CLK_PLL1_DIV4,
+
+       /* Module Clocks */
+       MOD_CLK_BASE
+};
+
+static const struct cpg_core_clk r8a77970_core_clks[] __initconst = {
+       /* External Clock Inputs */
+       DEF_INPUT("extal",      CLK_EXTAL),
+       DEF_INPUT("extalr",     CLK_EXTALR),
+
+       /* Internal Core Clocks */
+       DEF_BASE(".main",       CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL),
+       DEF_BASE(".pll0",       CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN),
+       DEF_BASE(".pll1",       CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN),
+       DEF_BASE(".pll3",       CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN),
+
+       DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2,  CLK_PLL1,       2, 1),
+       DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4,  CLK_PLL1_DIV2,  2, 1),
+
+       /* Core Clock Outputs */
+       DEF_FIXED("ztr",        R8A77970_CLK_ZTR,   CLK_PLL1_DIV2,  6, 1),
+       DEF_FIXED("ztrd2",      R8A77970_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
+       DEF_FIXED("zt",         R8A77970_CLK_ZT,    CLK_PLL1_DIV2,  4, 1),
+       DEF_FIXED("zx",         R8A77970_CLK_ZX,    CLK_PLL1_DIV2,  3, 1),
+       DEF_FIXED("s1d1",       R8A77970_CLK_S1D1,  CLK_PLL1_DIV2,  4, 1),
+       DEF_FIXED("s1d2",       R8A77970_CLK_S1D2,  CLK_PLL1_DIV2,  8, 1),
+       DEF_FIXED("s1d4",       R8A77970_CLK_S1D4,  CLK_PLL1_DIV2, 16, 1),
+       DEF_FIXED("s2d1",       R8A77970_CLK_S2D1,  CLK_PLL1_DIV2,  6, 1),
+       DEF_FIXED("s2d2",       R8A77970_CLK_S2D2,  CLK_PLL1_DIV2, 12, 1),
+       DEF_FIXED("s2d4",       R8A77970_CLK_S2D4,  CLK_PLL1_DIV2, 24, 1),
+
+       DEF_FIXED("cl",         R8A77970_CLK_CL,    CLK_PLL1_DIV2, 48, 1),
+       DEF_FIXED("cp",         R8A77970_CLK_CP,    CLK_EXTAL,      2, 1),
+
+       DEF_DIV6P1("canfd",     R8A77970_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
+       DEF_DIV6P1("mso",       R8A77970_CLK_MSO,   CLK_PLL1_DIV4, 0x014),
+       DEF_DIV6P1("csi0",      R8A77970_CLK_CSI0,  CLK_PLL1_DIV4, 0x00c),
+
+       DEF_FIXED("osc",        R8A77970_CLK_OSC,   CLK_PLL1_DIV2, 12*1024, 1),
+       DEF_FIXED("r",          R8A77970_CLK_R,     CLK_EXTALR,    1, 1),
+};
+
+static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = {
+       DEF_MOD("ivcp1e",                127,   R8A77970_CLK_S2D1),
+       DEF_MOD("scif4",                 203,   R8A77970_CLK_S2D4),
+       DEF_MOD("scif3",                 204,   R8A77970_CLK_S2D4),
+       DEF_MOD("scif1",                 206,   R8A77970_CLK_S2D4),
+       DEF_MOD("scif0",                 207,   R8A77970_CLK_S2D4),
+       DEF_MOD("msiof3",                208,   R8A77970_CLK_MSO),
+       DEF_MOD("msiof2",                209,   R8A77970_CLK_MSO),
+       DEF_MOD("msiof1",                210,   R8A77970_CLK_MSO),
+       DEF_MOD("msiof0",                211,   R8A77970_CLK_MSO),
+       DEF_MOD("mfis",                  213,   R8A77970_CLK_S2D2),
+       DEF_MOD("sys-dmac2",             217,   R8A77970_CLK_S2D1),
+       DEF_MOD("sys-dmac1",             218,   R8A77970_CLK_S2D1),
+       DEF_MOD("rwdt",                  402,   R8A77970_CLK_R),
+       DEF_MOD("intc-ex",               407,   R8A77970_CLK_CP),
+       DEF_MOD("intc-ap",               408,   R8A77970_CLK_S2D1),
+       DEF_MOD("hscif3",                517,   R8A77970_CLK_S2D1),
+       DEF_MOD("hscif2",                518,   R8A77970_CLK_S2D1),
+       DEF_MOD("hscif1",                519,   R8A77970_CLK_S2D1),
+       DEF_MOD("hscif0",                520,   R8A77970_CLK_S2D1),
+       DEF_MOD("thermal",               522,   R8A77970_CLK_CP),
+       DEF_MOD("pwm",                   523,   R8A77970_CLK_S2D4),
+       DEF_MOD("fcpvd0",                603,   R8A77970_CLK_S2D1),
+       DEF_MOD("vspd0",                 623,   R8A77970_CLK_S2D1),
+       DEF_MOD("csi40",                 716,   R8A77970_CLK_CSI0),
+       DEF_MOD("du0",                   724,   R8A77970_CLK_S2D1),
+       DEF_MOD("vin3",                  808,   R8A77970_CLK_S2D1),
+       DEF_MOD("vin2",                  809,   R8A77970_CLK_S2D1),
+       DEF_MOD("vin1",                  810,   R8A77970_CLK_S2D1),
+       DEF_MOD("vin0",                  811,   R8A77970_CLK_S2D1),
+       DEF_MOD("etheravb",              812,   R8A77970_CLK_S2D2),
+       DEF_MOD("gpio5",                 907,   R8A77970_CLK_CP),
+       DEF_MOD("gpio4",                 908,   R8A77970_CLK_CP),
+       DEF_MOD("gpio3",                 909,   R8A77970_CLK_CP),
+       DEF_MOD("gpio2",                 910,   R8A77970_CLK_CP),
+       DEF_MOD("gpio1",                 911,   R8A77970_CLK_CP),
+       DEF_MOD("gpio0",                 912,   R8A77970_CLK_CP),
+       DEF_MOD("can-fd",                914,   R8A77970_CLK_S2D2),
+       DEF_MOD("i2c4",                  927,   R8A77970_CLK_S2D2),
+       DEF_MOD("i2c3",                  928,   R8A77970_CLK_S2D2),
+       DEF_MOD("i2c2",                  929,   R8A77970_CLK_S2D2),
+       DEF_MOD("i2c1",                  930,   R8A77970_CLK_S2D2),
+       DEF_MOD("i2c0",                  931,   R8A77970_CLK_S2D2),
+};
+
+static const unsigned int r8a77970_crit_mod_clks[] __initconst = {
+       MOD_CLK_ID(408),        /* INTC-AP (GIC) */
+};
+
+
+/*
+ * CPG Clock Data
+ */
+
+/*
+ *   MD                EXTAL           PLL0    PLL1    PLL3
+ * 14 13 19    (MHz)
+ *-------------------------------------------------
+ * 0  0  0     16.66 x 1       x192    x192    x96
+ * 0  0  1     16.66 x 1       x192    x192    x80
+ * 0  1  0     20    x 1       x160    x160    x80
+ * 0  1  1     20    x 1       x160    x160    x66
+ * 1  0  0     27    / 2       x236    x236    x118
+ * 1  0  1     27    / 2       x236    x236    x98
+ * 1  1  0     33.33 / 2       x192    x192    x96
+ * 1  1  1     33.33 / 2       x192    x192    x80
+ */
+#define CPG_PLL_CONFIG_INDEX(md)       ((((md) & BIT(14)) >> 12) | \
+                                        (((md) & BIT(13)) >> 12) | \
+                                        (((md) & BIT(19)) >> 19))
+
+static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[8] __initconst = {
+       /* EXTAL div    PLL1 mult/div   PLL3 mult/div */
+       { 1,            192,    1,      96,     1,      },
+       { 1,            192,    1,      80,     1,      },
+       { 1,            160,    1,      80,     1,      },
+       { 1,            160,    1,      66,     1,      },
+       { 2,            236,    1,      118,    1,      },
+       { 2,            236,    1,      98,     1,      },
+       { 2,            192,    1,      96,     1,      },
+       { 2,            192,    1,      80,     1,      },
+};
+
+static int __init r8a77970_cpg_mssr_init(struct device *dev)
+{
+       const struct rcar_gen3_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_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode);
+}
+
+const struct cpg_mssr_info r8a77970_cpg_mssr_info __initconst = {
+       /* Core Clocks */
+       .core_clks = r8a77970_core_clks,
+       .num_core_clks = ARRAY_SIZE(r8a77970_core_clks),
+       .last_dt_core_clk = LAST_DT_CORE_CLK,
+       .num_total_core_clks = MOD_CLK_BASE,
+
+       /* Module Clocks */
+       .mod_clks = r8a77970_mod_clks,
+       .num_mod_clks = ARRAY_SIZE(r8a77970_mod_clks),
+       .num_hw_mod_clks = 12 * 32,
+
+       /* Critical Module Clocks */
+       .crit_mod_clks = r8a77970_crit_mod_clks,
+       .num_crit_mod_clks = ARRAY_SIZE(r8a77970_crit_mod_clks),
+
+       /* Callbacks */
+       .init = r8a77970_cpg_mssr_init,
+       .cpg_clk_register = rcar_gen3_cpg_clk_register,
+};
index e594cf8ee63b64e0b297c623ca31551b06d9fe31..ea4cafbe6e851aca89c24f79b4912b1a2278d774 100644 (file)
@@ -127,7 +127,7 @@ static const struct mssr_mod_clk r8a77995_mod_clks[] __initconst = {
        DEF_MOD("usb-dmac1",             331,   R8A77995_CLK_S3D1),
        DEF_MOD("rwdt",                  402,   R8A77995_CLK_R),
        DEF_MOD("intc-ex",               407,   R8A77995_CLK_CP),
-       DEF_MOD("intc-ap",               408,   R8A77995_CLK_S3D1),
+       DEF_MOD("intc-ap",               408,   R8A77995_CLK_S1D2),
        DEF_MOD("audmac0",               502,   R8A77995_CLK_S3D1),
        DEF_MOD("hscif3",                517,   R8A77995_CLK_S3D1C),
        DEF_MOD("hscif0",                520,   R8A77995_CLK_S3D1C),
index 123b1e622179308eb4080a00ae5a46472e318d28..feb14579a71b3bf47f38039315553b179d8716f7 100644 (file)
@@ -262,10 +262,9 @@ static unsigned int cpg_pll0_div __initdata;
 static u32 cpg_mode __initdata;
 
 struct clk * __init rcar_gen2_cpg_clk_register(struct device *dev,
-                                              const struct cpg_core_clk *core,
-                                              const struct cpg_mssr_info *info,
-                                              struct clk **clks,
-                                              void __iomem *base)
+       const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
+       struct clk **clks, void __iomem *base,
+       struct raw_notifier_head *notifiers)
 {
        const struct clk_div_table *table = NULL;
        const struct clk *parent;
index 9eba07ff8b11e20eaac35acd8651b9f615664d85..020a3baad0154231fb397792912fed327f39a0c1 100644 (file)
@@ -34,9 +34,9 @@ struct rcar_gen2_cpg_pll_config {
 };
 
 struct clk *rcar_gen2_cpg_clk_register(struct device *dev,
-                                      const struct cpg_core_clk *core,
-                                      const struct cpg_mssr_info *info,
-                                      struct clk **clks, void __iomem *base);
+       const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
+       struct clk **clks, void __iomem *base,
+       struct raw_notifier_head *notifiers);
 int rcar_gen2_cpg_init(const struct rcar_gen2_cpg_pll_config *config,
                       unsigned int pll0_div, u32 mode);
 
index 9511058165475dd7c8563aaa1409d1dd5ada5cc1..0904886f55015a3bdf309f7bdb38add0fd08a7e3 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/pm.h>
 #include <linux/slab.h>
 #include <linux/sys_soc.h>
 
 #define CPG_PLL2CR             0x002c
 #define CPG_PLL4CR             0x01f4
 
+struct cpg_simple_notifier {
+       struct notifier_block nb;
+       void __iomem *reg;
+       u32 saved;
+};
+
+static int cpg_simple_notifier_call(struct notifier_block *nb,
+                                   unsigned long action, void *data)
+{
+       struct cpg_simple_notifier *csn =
+               container_of(nb, struct cpg_simple_notifier, nb);
+
+       switch (action) {
+       case PM_EVENT_SUSPEND:
+               csn->saved = readl(csn->reg);
+               return NOTIFY_OK;
+
+       case PM_EVENT_RESUME:
+               writel(csn->saved, csn->reg);
+               return NOTIFY_OK;
+       }
+       return NOTIFY_DONE;
+}
+
+static void cpg_simple_notifier_register(struct raw_notifier_head *notifiers,
+                                        struct cpg_simple_notifier *csn)
+{
+       csn->nb.notifier_call = cpg_simple_notifier_call;
+       raw_notifier_chain_register(notifiers, &csn->nb);
+}
 
 /*
  * SDn Clock
@@ -55,8 +86,8 @@ struct sd_div_table {
 
 struct sd_clock {
        struct clk_hw hw;
-       void __iomem *reg;
        const struct sd_div_table *div_table;
+       struct cpg_simple_notifier csn;
        unsigned int div_num;
        unsigned int div_min;
        unsigned int div_max;
@@ -97,12 +128,12 @@ static const struct sd_div_table cpg_sd_div_table[] = {
 static int cpg_sd_clock_enable(struct clk_hw *hw)
 {
        struct sd_clock *clock = to_sd_clock(hw);
-       u32 val = readl(clock->reg);
+       u32 val = readl(clock->csn.reg);
 
        val &= ~(CPG_SD_STP_MASK);
        val |= clock->div_table[clock->cur_div_idx].val & CPG_SD_STP_MASK;
 
-       writel(val, clock->reg);
+       writel(val, clock->csn.reg);
 
        return 0;
 }
@@ -111,14 +142,14 @@ static void cpg_sd_clock_disable(struct clk_hw *hw)
 {
        struct sd_clock *clock = to_sd_clock(hw);
 
-       writel(readl(clock->reg) | CPG_SD_STP_MASK, clock->reg);
+       writel(readl(clock->csn.reg) | CPG_SD_STP_MASK, clock->csn.reg);
 }
 
 static int cpg_sd_clock_is_enabled(struct clk_hw *hw)
 {
        struct sd_clock *clock = to_sd_clock(hw);
 
-       return !(readl(clock->reg) & CPG_SD_STP_MASK);
+       return !(readl(clock->csn.reg) & CPG_SD_STP_MASK);
 }
 
 static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw,
@@ -170,10 +201,10 @@ static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate,
 
        clock->cur_div_idx = i;
 
-       val = readl(clock->reg);
+       val = readl(clock->csn.reg);
        val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK);
        val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK);
-       writel(val, clock->reg);
+       writel(val, clock->csn.reg);
 
        return 0;
 }
@@ -188,8 +219,8 @@ static const struct clk_ops cpg_sd_clock_ops = {
 };
 
 static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core,
-                                              void __iomem *base,
-                                              const char *parent_name)
+       void __iomem *base, const char *parent_name,
+       struct raw_notifier_head *notifiers)
 {
        struct clk_init_data init;
        struct sd_clock *clock;
@@ -207,12 +238,12 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core,
        init.parent_names = &parent_name;
        init.num_parents = 1;
 
-       clock->reg = base + core->offset;
+       clock->csn.reg = base + core->offset;
        clock->hw.init = &init;
        clock->div_table = cpg_sd_div_table;
        clock->div_num = ARRAY_SIZE(cpg_sd_div_table);
 
-       sd_fc = readl(clock->reg) & CPG_SD_FC_MASK;
+       sd_fc = readl(clock->csn.reg) & CPG_SD_FC_MASK;
        for (i = 0; i < clock->div_num; i++)
                if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK))
                        break;
@@ -233,8 +264,13 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core,
 
        clk = clk_register(NULL, &clock->hw);
        if (IS_ERR(clk))
-               kfree(clock);
+               goto free_clock;
 
+       cpg_simple_notifier_register(notifiers, &clock->csn);
+       return clk;
+
+free_clock:
+       kfree(clock);
        return clk;
 }
 
@@ -265,7 +301,8 @@ static const struct soc_device_attribute cpg_quirks_match[] __initconst = {
 
 struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
        const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
-       struct clk **clks, void __iomem *base)
+       struct clk **clks, void __iomem *base,
+       struct raw_notifier_head *notifiers)
 {
        const struct clk *parent;
        unsigned int mult = 1;
@@ -331,22 +368,32 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
                break;
 
        case CLK_TYPE_GEN3_SD:
-               return cpg_sd_clk_register(core, base, __clk_get_name(parent));
+               return cpg_sd_clk_register(core, base, __clk_get_name(parent),
+                                          notifiers);
 
        case CLK_TYPE_GEN3_R:
                if (cpg_quirks & RCKCR_CKSEL) {
+                       struct cpg_simple_notifier *csn;
+
+                       csn = kzalloc(sizeof(*csn), GFP_KERNEL);
+                       if (!csn)
+                               return ERR_PTR(-ENOMEM);
+
+                       csn->reg = base + CPG_RCKCR;
+
                        /*
                         * RINT is default.
                         * Only if EXTALR is populated, we switch to it.
                         */
-                       value = readl(base + CPG_RCKCR) & 0x3f;
+                       value = readl(csn->reg) & 0x3f;
 
                        if (clk_get_rate(clks[cpg_clk_extalr])) {
                                parent = clks[cpg_clk_extalr];
                                value |= BIT(15);
                        }
 
-                       writel(value, base + CPG_RCKCR);
+                       writel(value, csn->reg);
+                       cpg_simple_notifier_register(notifiers, csn);
                        break;
                }
 
index d756ef8b78eb6c02d9fee43dd6670cda36df53bb..2e4284399f530f96cf249238a5beb813408d8d34 100644 (file)
@@ -44,7 +44,8 @@ struct rcar_gen3_cpg_pll_config {
 
 struct clk *rcar_gen3_cpg_clk_register(struct device *dev,
        const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
-       struct clk **clks, void __iomem *base);
+       struct clk **clks, void __iomem *base,
+       struct raw_notifier_head *notifiers);
 int rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config,
                       unsigned int clk_extalr, u32 mode);
 
index e580a5e6346c2533ab34dd12cda0dcabe7369476..e3d03ffea4bc2fd6e17cf9268f797ade839ca750 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_clock.h>
 #include <linux/pm_domain.h>
+#include <linux/psci.h>
 #include <linux/reset-controller.h>
 #include <linux/slab.h>
 
@@ -106,6 +107,9 @@ static const u16 srcr[] = {
  * @num_core_clks: Number of Core Clocks in clks[]
  * @num_mod_clks: Number of Module Clocks in clks[]
  * @last_dt_core_clk: ID of the last Core Clock exported to DT
+ * @notifiers: Notifier chain to save/restore clock state for system resume
+ * @smstpcr_saved[].mask: Mask of SMSTPCR[] bits under our control
+ * @smstpcr_saved[].val: Saved values of SMSTPCR[]
  */
 struct cpg_mssr_priv {
 #ifdef CONFIG_RESET_CONTROLLER
@@ -119,6 +123,12 @@ struct cpg_mssr_priv {
        unsigned int num_core_clks;
        unsigned int num_mod_clks;
        unsigned int last_dt_core_clk;
+
+       struct raw_notifier_head notifiers;
+       struct {
+               u32 mask;
+               u32 val;
+       } smstpcr_saved[ARRAY_SIZE(smstpcr)];
 };
 
 
@@ -293,7 +303,8 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
 
                if (core->type == CLK_TYPE_DIV6P1) {
                        clk = cpg_div6_register(core->name, 1, &parent_name,
-                                               priv->base + core->offset);
+                                               priv->base + core->offset,
+                                               &priv->notifiers);
                } else {
                        clk = clk_register_fixed_factor(NULL, core->name,
                                                        parent_name, 0,
@@ -304,7 +315,8 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
        default:
                if (info->cpg_clk_register)
                        clk = info->cpg_clk_register(dev, core, info,
-                                                    priv->clks, priv->base);
+                                                    priv->clks, priv->base,
+                                                    &priv->notifiers);
                else
                        dev_err(dev, "%s has unsupported core clock type %u\n",
                                core->name, core->type);
@@ -382,6 +394,7 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod,
 
        dev_dbg(dev, "Module clock %pC at %pCr Hz\n", clk, clk);
        priv->clks[id] = clk;
+       priv->smstpcr_saved[clock->index / 32].mask |= BIT(clock->index % 32);
        return;
 
 fail:
@@ -680,6 +693,12 @@ static const struct of_device_id cpg_mssr_match[] = {
                .data = &r8a7796_cpg_mssr_info,
        },
 #endif
+#ifdef CONFIG_CLK_R8A77970
+       {
+               .compatible = "renesas,r8a77970-cpg-mssr",
+               .data = &r8a77970_cpg_mssr_info,
+       },
+#endif
 #ifdef CONFIG_CLK_R8A77995
        {
                .compatible = "renesas,r8a77995-cpg-mssr",
@@ -694,6 +713,85 @@ static void cpg_mssr_del_clk_provider(void *data)
        of_clk_del_provider(data);
 }
 
+#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM_PSCI_FW)
+static int cpg_mssr_suspend_noirq(struct device *dev)
+{
+       struct cpg_mssr_priv *priv = dev_get_drvdata(dev);
+       unsigned int reg;
+
+       /* This is the best we can do to check for the presence of PSCI */
+       if (!psci_ops.cpu_suspend)
+               return 0;
+
+       /* 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 =
+                               readl(priv->base + SMSTPCR(reg));
+       }
+
+       /* Save core clocks */
+       raw_notifier_call_chain(&priv->notifiers, PM_EVENT_SUSPEND, NULL);
+
+       return 0;
+}
+
+static int cpg_mssr_resume_noirq(struct device *dev)
+{
+       struct cpg_mssr_priv *priv = dev_get_drvdata(dev);
+       unsigned int reg, i;
+       u32 mask, oldval, newval;
+
+       /* This is the best we can do to check for the presence of PSCI */
+       if (!psci_ops.cpu_suspend)
+               return 0;
+
+       /* Restore core clocks */
+       raw_notifier_call_chain(&priv->notifiers, PM_EVENT_RESUME, NULL);
+
+       /* Restore module clocks */
+       for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) {
+               mask = priv->smstpcr_saved[reg].mask;
+               if (!mask)
+                       continue;
+
+               oldval = readl(priv->base + SMSTPCR(reg));
+               newval = oldval & ~mask;
+               newval |= priv->smstpcr_saved[reg].val & mask;
+               if (newval == oldval)
+                       continue;
+
+               writel(newval, priv->base + SMSTPCR(reg));
+
+               /* Wait until enabled clocks are really enabled */
+               mask &= ~priv->smstpcr_saved[reg].val;
+               if (!mask)
+                       continue;
+
+               for (i = 1000; i > 0; --i) {
+                       oldval = readl(priv->base + MSTPSR(reg));
+                       if (!(oldval & mask))
+                               break;
+                       cpu_relax();
+               }
+
+               if (!i)
+                       dev_warn(dev, "Failed to enable SMSTP %p[0x%x]\n",
+                                priv->base + SMSTPCR(reg), oldval & mask);
+       }
+
+       return 0;
+}
+
+static const struct dev_pm_ops cpg_mssr_pm = {
+       SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(cpg_mssr_suspend_noirq,
+                                     cpg_mssr_resume_noirq)
+};
+#define DEV_PM_OPS     &cpg_mssr_pm
+#else
+#define DEV_PM_OPS     NULL
+#endif /* CONFIG_PM_SLEEP && CONFIG_ARM_PSCI_FW */
+
 static int __init cpg_mssr_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -729,10 +827,12 @@ static int __init cpg_mssr_probe(struct platform_device *pdev)
        if (!clks)
                return -ENOMEM;
 
+       dev_set_drvdata(dev, priv);
        priv->clks = clks;
        priv->num_core_clks = info->num_total_core_clks;
        priv->num_mod_clks = info->num_hw_mod_clks;
        priv->last_dt_core_clk = info->last_dt_core_clk;
+       RAW_INIT_NOTIFIER_HEAD(&priv->notifiers);
 
        for (i = 0; i < nclks; i++)
                clks[i] = ERR_PTR(-ENOENT);
@@ -769,6 +869,7 @@ static struct platform_driver cpg_mssr_driver = {
        .driver         = {
                .name   = "renesas-cpg-mssr",
                .of_match_table = cpg_mssr_match,
+               .pm = DEV_PM_OPS,
        },
 };
 
index 94b9071d1061ab16dd18268c399bb1576a0041a8..0745b09303082ef9bf65288bca5dac66ae0b00c1 100644 (file)
@@ -127,7 +127,8 @@ struct cpg_mssr_info {
        struct clk *(*cpg_clk_register)(struct device *dev,
                                        const struct cpg_core_clk *core,
                                        const struct cpg_mssr_info *info,
-                                       struct clk **clks, void __iomem *base);
+                                       struct clk **clks, void __iomem *base,
+                                       struct raw_notifier_head *notifiers);
 };
 
 extern const struct cpg_mssr_info r8a7743_cpg_mssr_info;
@@ -138,6 +139,7 @@ extern const struct cpg_mssr_info r8a7792_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a7794_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a7795_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a7796_cpg_mssr_info;
+extern const struct cpg_mssr_info r8a77970_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a77995_cpg_mssr_info;
 
 
index 0e09684d43a5b15cf441f06fa12145abeb0234a2..32c19c0f1e141f95bc364f8695a87d85d90ac6bf 100644 (file)
@@ -322,8 +322,6 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
                                             sizeof(*rates) * nrates,
                                             GFP_KERNEL);
                if (!cpuclk->rate_table) {
-                       pr_err("%s: could not allocate memory for cpuclk rates\n",
-                              __func__);
                        ret = -ENOMEM;
                        goto unregister_notifier;
                }
index 00ad0e5f8d6661ee767be492cb35a407ea83b873..67e73fd71f095c9b1164e26a5422c4d8f5edd6ee 100644 (file)
@@ -290,15 +290,15 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
                        RK2928_CLKSEL_CON(0), 6, 2, DFLAGS | CLK_DIVIDER_READ_ONLY,
                        div_core_peri_t, RK2928_CLKGATE_CON(0), 0, GFLAGS),
 
-       COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_p, 0,
+       COMPOSITE(ACLK_VEPU, "aclk_vepu", mux_pll_src_cpll_gpll_p, 0,
                        RK2928_CLKSEL_CON(32), 7, 1, MFLAGS, 0, 5, DFLAGS,
                        RK2928_CLKGATE_CON(3), 9, GFLAGS),
-       GATE(0, "hclk_vepu", "aclk_vepu", 0,
+       GATE(HCLK_VEPU, "hclk_vepu", "aclk_vepu", 0,
                        RK2928_CLKGATE_CON(3), 10, GFLAGS),
-       COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_p, 0,
+       COMPOSITE(ACLK_VDPU, "aclk_vdpu", mux_pll_src_cpll_gpll_p, 0,
                        RK2928_CLKSEL_CON(32), 15, 1, MFLAGS, 8, 5, DFLAGS,
                        RK2928_CLKGATE_CON(3), 11, GFLAGS),
-       GATE(0, "hclk_vdpu", "aclk_vdpu", 0,
+       GATE(HCLK_VDPU, "hclk_vdpu", "aclk_vdpu", 0,
                        RK2928_CLKGATE_CON(3), 12, GFLAGS),
 
        GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED,
@@ -644,13 +644,13 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
 
        GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS),
        GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
-       GATE(0, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS),
+       GATE(HCLK_CIF1, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS),
        GATE(0, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
 
        GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED,
                        RK2928_CLKGATE_CON(5), 14, GFLAGS),
 
-       GATE(0, "aclk_cif1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 7, GFLAGS),
+       GATE(ACLK_CIF1, "aclk_cif1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 7, GFLAGS),
 
        GATE(PCLK_TIMER1, "pclk_timer1", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 8, GFLAGS),
        GATE(PCLK_TIMER2, "pclk_timer2", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 9, GFLAGS),
index fc56565379dd46123c31982c691bd44dacd5912b..7c4d242f19c1003b55cc6eee69af7ff503bfe820 100644 (file)
@@ -711,7 +711,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = {
        GATE(PCLK_SIM, "pclk_sim", "pclk_bus", 0, RK3368_CLKGATE_CON(13), 8, GFLAGS),
        GATE(PCLK_PWM1, "pclk_pwm1", "pclk_bus", 0, RK3368_CLKGATE_CON(13), 6, GFLAGS),
        GATE(PCLK_UART2, "pclk_uart2", "pclk_bus", 0, RK3368_CLKGATE_CON(13), 5, GFLAGS),
-       GATE(0, "pclk_efuse_256", "pclk_bus", 0, RK3368_CLKGATE_CON(13), 1, GFLAGS),
+       GATE(PCLK_EFUSE256, "pclk_efuse_256", "pclk_bus", 0, RK3368_CLKGATE_CON(13), 1, GFLAGS),
        GATE(0, "pclk_efuse_1024", "pclk_bus", 0, RK3368_CLKGATE_CON(13), 0, GFLAGS),
 
        /*
index 23835001e8bdb5007efc9b1e66cd8c9557fd6de1..ef8900bc077f60c78b2a097c9cd89457973229db 100644 (file)
@@ -6,6 +6,7 @@
 obj-$(CONFIG_COMMON_CLK)       += clk.o clk-pll.o clk-cpu.o
 obj-$(CONFIG_SOC_EXYNOS3250)   += clk-exynos3250.o
 obj-$(CONFIG_ARCH_EXYNOS4)     += clk-exynos4.o
+obj-$(CONFIG_ARCH_EXYNOS4)     += clk-exynos4412-isp.o
 obj-$(CONFIG_SOC_EXYNOS5250)   += clk-exynos5250.o
 obj-$(CONFIG_SOC_EXYNOS5260)   += clk-exynos5260.o
 obj-$(CONFIG_SOC_EXYNOS5410)   += clk-exynos5410.o
index 6686e8ba61f9f768681810b4ceaa3afcb5ff43b6..d2c99d8916b83e48c1b23d6c49dd98f43f81f2db 100644 (file)
@@ -457,8 +457,6 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 
        cpuclk->cfg = kmemdup(cfg, sizeof(*cfg) * num_cfgs, GFP_KERNEL);
        if (!cpuclk->cfg) {
-               pr_err("%s: could not allocate memory for cpuclk data\n",
-                               __func__);
                ret = -ENOMEM;
                goto unregister_clk_nb;
        }
index b117783ed40478b03be6abe4ac1b107df8d7a424..5bfc92ee3129a5fec4df14c58f7024a64ed15058 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/syscore_ops.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 
 #include <dt-bindings/clock/exynos-audss-clk.h>
 
@@ -36,14 +37,13 @@ static struct clk *epll;
 #define ASS_CLK_DIV 0x4
 #define ASS_CLK_GATE 0x8
 
-#ifdef CONFIG_PM_SLEEP
 static unsigned long reg_save[][2] = {
        { ASS_CLK_SRC,  0 },
        { ASS_CLK_DIV,  0 },
        { ASS_CLK_GATE, 0 },
 };
 
-static int exynos_audss_clk_suspend(struct device *dev)
+static int __maybe_unused exynos_audss_clk_suspend(struct device *dev)
 {
        int i;
 
@@ -53,7 +53,7 @@ static int exynos_audss_clk_suspend(struct device *dev)
        return 0;
 }
 
-static int exynos_audss_clk_resume(struct device *dev)
+static int __maybe_unused exynos_audss_clk_resume(struct device *dev)
 {
        int i;
 
@@ -62,7 +62,6 @@ static int exynos_audss_clk_resume(struct device *dev)
 
        return 0;
 }
-#endif /* CONFIG_PM_SLEEP */
 
 struct exynos_audss_clk_drvdata {
        unsigned int has_adma_clk:1;
@@ -135,6 +134,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
        const struct exynos_audss_clk_drvdata *variant;
        struct clk_hw **clk_table;
        struct resource *res;
+       struct device *dev = &pdev->dev;
        int i, ret = 0;
 
        variant = of_device_get_match_data(&pdev->dev);
@@ -142,15 +142,15 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
                return -EINVAL;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       reg_base = devm_ioremap_resource(&pdev->dev, res);
+       reg_base = devm_ioremap_resource(dev, res);
        if (IS_ERR(reg_base)) {
-               dev_err(&pdev->dev, "failed to map audss registers\n");
+               dev_err(dev, "failed to map audss registers\n");
                return PTR_ERR(reg_base);
        }
 
        epll = ERR_PTR(-ENODEV);
 
-       clk_data = devm_kzalloc(&pdev->dev,
+       clk_data = devm_kzalloc(dev,
                                sizeof(*clk_data) +
                                sizeof(*clk_data->hws) * EXYNOS_AUDSS_MAX_CLKS,
                                GFP_KERNEL);
@@ -160,8 +160,8 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
        clk_data->num = variant->num_clks;
        clk_table = clk_data->hws;
 
-       pll_ref = devm_clk_get(&pdev->dev, "pll_ref");
-       pll_in = devm_clk_get(&pdev->dev, "pll_in");
+       pll_ref = devm_clk_get(dev, "pll_ref");
+       pll_in = devm_clk_get(dev, "pll_in");
        if (!IS_ERR(pll_ref))
                mout_audss_p[0] = __clk_get_name(pll_ref);
        if (!IS_ERR(pll_in)) {
@@ -172,88 +172,103 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
 
                        ret = clk_prepare_enable(epll);
                        if (ret) {
-                               dev_err(&pdev->dev,
+                               dev_err(dev,
                                        "failed to prepare the epll clock\n");
                                return ret;
                        }
                }
        }
-       clk_table[EXYNOS_MOUT_AUDSS] = clk_hw_register_mux(NULL, "mout_audss",
+
+       /*
+        * Enable runtime PM here to allow the clock core using runtime PM
+        * for the registered clocks. Additionally, we increase the runtime
+        * PM usage count before registering the clocks, to prevent the
+        * clock core from runtime suspending the device.
+        */
+       pm_runtime_get_noresume(dev);
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
+
+       clk_table[EXYNOS_MOUT_AUDSS] = clk_hw_register_mux(dev, "mout_audss",
                                mout_audss_p, ARRAY_SIZE(mout_audss_p),
                                CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
                                reg_base + ASS_CLK_SRC, 0, 1, 0, &lock);
 
-       cdclk = devm_clk_get(&pdev->dev, "cdclk");
-       sclk_audio = devm_clk_get(&pdev->dev, "sclk_audio");
+       cdclk = devm_clk_get(dev, "cdclk");
+       sclk_audio = devm_clk_get(dev, "sclk_audio");
        if (!IS_ERR(cdclk))
                mout_i2s_p[1] = __clk_get_name(cdclk);
        if (!IS_ERR(sclk_audio))
                mout_i2s_p[2] = __clk_get_name(sclk_audio);
-       clk_table[EXYNOS_MOUT_I2S] = clk_hw_register_mux(NULL, "mout_i2s",
+       clk_table[EXYNOS_MOUT_I2S] = clk_hw_register_mux(dev, "mout_i2s",
                                mout_i2s_p, ARRAY_SIZE(mout_i2s_p),
                                CLK_SET_RATE_NO_REPARENT,
                                reg_base + ASS_CLK_SRC, 2, 2, 0, &lock);
 
-       clk_table[EXYNOS_DOUT_SRP] = clk_hw_register_divider(NULL, "dout_srp",
+       clk_table[EXYNOS_DOUT_SRP] = clk_hw_register_divider(dev, "dout_srp",
                                "mout_audss", CLK_SET_RATE_PARENT,
                                reg_base + ASS_CLK_DIV, 0, 4, 0, &lock);
 
-       clk_table[EXYNOS_DOUT_AUD_BUS] = clk_hw_register_divider(NULL,
+       clk_table[EXYNOS_DOUT_AUD_BUS] = clk_hw_register_divider(dev,
                                "dout_aud_bus", "dout_srp", CLK_SET_RATE_PARENT,
                                reg_base + ASS_CLK_DIV, 4, 4, 0, &lock);
 
-       clk_table[EXYNOS_DOUT_I2S] = clk_hw_register_divider(NULL, "dout_i2s",
+       clk_table[EXYNOS_DOUT_I2S] = clk_hw_register_divider(dev, "dout_i2s",
                                "mout_i2s", 0, reg_base + ASS_CLK_DIV, 8, 4, 0,
                                &lock);
 
-       clk_table[EXYNOS_SRP_CLK] = clk_hw_register_gate(NULL, "srp_clk",
+       clk_table[EXYNOS_SRP_CLK] = clk_hw_register_gate(dev, "srp_clk",
                                "dout_srp", CLK_SET_RATE_PARENT,
                                reg_base + ASS_CLK_GATE, 0, 0, &lock);
 
-       clk_table[EXYNOS_I2S_BUS] = clk_hw_register_gate(NULL, "i2s_bus",
+       clk_table[EXYNOS_I2S_BUS] = clk_hw_register_gate(dev, "i2s_bus",
                                "dout_aud_bus", CLK_SET_RATE_PARENT,
                                reg_base + ASS_CLK_GATE, 2, 0, &lock);
 
-       clk_table[EXYNOS_SCLK_I2S] = clk_hw_register_gate(NULL, "sclk_i2s",
+       clk_table[EXYNOS_SCLK_I2S] = clk_hw_register_gate(dev, "sclk_i2s",
                                "dout_i2s", CLK_SET_RATE_PARENT,
                                reg_base + ASS_CLK_GATE, 3, 0, &lock);
 
-       clk_table[EXYNOS_PCM_BUS] = clk_hw_register_gate(NULL, "pcm_bus",
+       clk_table[EXYNOS_PCM_BUS] = clk_hw_register_gate(dev, "pcm_bus",
                                 "sclk_pcm", CLK_SET_RATE_PARENT,
                                reg_base + ASS_CLK_GATE, 4, 0, &lock);
 
-       sclk_pcm_in = devm_clk_get(&pdev->dev, "sclk_pcm_in");
+       sclk_pcm_in = devm_clk_get(dev, "sclk_pcm_in");
        if (!IS_ERR(sclk_pcm_in))
                sclk_pcm_p = __clk_get_name(sclk_pcm_in);
-       clk_table[EXYNOS_SCLK_PCM] = clk_hw_register_gate(NULL, "sclk_pcm",
+       clk_table[EXYNOS_SCLK_PCM] = clk_hw_register_gate(dev, "sclk_pcm",
                                sclk_pcm_p, CLK_SET_RATE_PARENT,
                                reg_base + ASS_CLK_GATE, 5, 0, &lock);
 
        if (variant->has_adma_clk) {
-               clk_table[EXYNOS_ADMA] = clk_hw_register_gate(NULL, "adma",
+               clk_table[EXYNOS_ADMA] = clk_hw_register_gate(dev, "adma",
                                "dout_srp", CLK_SET_RATE_PARENT,
                                reg_base + ASS_CLK_GATE, 9, 0, &lock);
        }
 
        for (i = 0; i < clk_data->num; i++) {
                if (IS_ERR(clk_table[i])) {
-                       dev_err(&pdev->dev, "failed to register clock %d\n", i);
+                       dev_err(dev, "failed to register clock %d\n", i);
                        ret = PTR_ERR(clk_table[i]);
                        goto unregister;
                }
        }
 
-       ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
+       ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
                                     clk_data);
        if (ret) {
-               dev_err(&pdev->dev, "failed to add clock provider\n");
+               dev_err(dev, "failed to add clock provider\n");
                goto unregister;
        }
 
+       pm_runtime_put_sync(dev);
+
        return 0;
 
 unregister:
        exynos_audss_clk_teardown();
+       pm_runtime_put_sync(dev);
+       pm_runtime_disable(dev);
 
        if (!IS_ERR(epll))
                clk_disable_unprepare(epll);
@@ -266,6 +281,7 @@ static int exynos_audss_clk_remove(struct platform_device *pdev)
        of_clk_del_provider(pdev->dev.of_node);
 
        exynos_audss_clk_teardown();
+       pm_runtime_disable(&pdev->dev);
 
        if (!IS_ERR(epll))
                clk_disable_unprepare(epll);
@@ -274,8 +290,10 @@ static int exynos_audss_clk_remove(struct platform_device *pdev)
 }
 
 static const struct dev_pm_ops exynos_audss_clk_pm_ops = {
-       SET_LATE_SYSTEM_SLEEP_PM_OPS(exynos_audss_clk_suspend,
-                                    exynos_audss_clk_resume)
+       SET_RUNTIME_PM_OPS(exynos_audss_clk_suspend, exynos_audss_clk_resume,
+                          NULL)
+       SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+                                    pm_runtime_force_resume)
 };
 
 static struct platform_driver exynos_audss_clk_driver = {
index a21aea062baed6716bcc937aaf149506cd1f65ad..f29fb582400508efbff99f2daa2a1804de378c86 100644 (file)
@@ -144,8 +144,6 @@ static void __init exynos4_clkout_init(struct device_node *node)
 }
 CLK_OF_DECLARE_DRIVER(exynos4210_clkout, "samsung,exynos4210-pmu",
                exynos4_clkout_init);
-CLK_OF_DECLARE_DRIVER(exynos4212_clkout, "samsung,exynos4212-pmu",
-               exynos4_clkout_init);
 CLK_OF_DECLARE_DRIVER(exynos4412_clkout, "samsung,exynos4412-pmu",
                exynos4_clkout_init);
 CLK_OF_DECLARE_DRIVER(exynos3250_clkout, "samsung,exynos3250-pmu",
index d8d3cb67b4029ac58c905fcae097a2c6957a9f22..134f25f2a913861c2ce2a2f89ce5a5221e14a98c 100644 (file)
@@ -550,9 +550,8 @@ static const struct samsung_fixed_factor_clock exynos4x12_fixed_factor_clks[] __
 
 /* list of mux clocks supported in all exynos4 soc's */
 static const struct samsung_mux_clock exynos4_mux_clks[] __initconst = {
-       MUX_FA(CLK_MOUT_APLL, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
-                       CLK_SET_RATE_PARENT | CLK_RECALC_NEW_RATES, 0,
-                       "mout_apll"),
+       MUX_F(CLK_MOUT_APLL, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
+                       CLK_SET_RATE_PARENT | CLK_RECALC_NEW_RATES, 0),
        MUX(CLK_MOUT_HDMI, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1),
        MUX(0, "mout_mfc1", sclk_evpll_p, SRC_MFC, 4, 1),
        MUX(0, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1),
@@ -737,7 +736,7 @@ static const struct samsung_div_clock exynos4_div_clks[] __initconst = {
        DIV(0, "div_periph", "div_core2", DIV_CPU0, 12, 3),
        DIV(0, "div_atb", "mout_core", DIV_CPU0, 16, 3),
        DIV(0, "div_pclk_dbg", "div_atb", DIV_CPU0, 20, 3),
-       DIV(CLK_ARM_CLK, "div_core2", "div_core", DIV_CPU0, 28, 3),
+       DIV(0, "div_core2", "div_core", DIV_CPU0, 28, 3),
        DIV(0, "div_copy", "mout_hpm", DIV_CPU1, 0, 3),
        DIV(0, "div_hpm", "div_copy", DIV_CPU1, 4, 3),
        DIV(0, "div_clkout_cpu", "mout_clkout_cpu", CLKOUT_CMU_CPU, 8, 6),
@@ -837,6 +836,12 @@ static const struct samsung_div_clock exynos4x12_div_clks[] __initconst = {
        DIV(0, "div_spi1_isp", "mout_spi1_isp", E4X12_DIV_ISP, 16, 4),
        DIV(0, "div_spi1_isp_pre", "div_spi1_isp", E4X12_DIV_ISP, 20, 8),
        DIV(0, "div_uart_isp", "mout_uart_isp", E4X12_DIV_ISP, 28, 4),
+       DIV(CLK_SCLK_FIMG2D, "sclk_fimg2d", "mout_g2d", DIV_DMC1, 0, 4),
+       DIV(CLK_DIV_C2C, "div_c2c", "mout_c2c", DIV_DMC1, 4, 3),
+       DIV(0, "div_c2c_aclk", "div_c2c", DIV_DMC1, 12, 3),
+};
+
+static struct samsung_div_clock exynos4x12_isp_div_clks[] = {
        DIV_F(CLK_DIV_ISP0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3,
                                                CLK_GET_RATE_NOCACHE, 0),
        DIV_F(CLK_DIV_ISP1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3,
@@ -846,18 +851,10 @@ static const struct samsung_div_clock exynos4x12_div_clks[] __initconst = {
                                                4, 3, CLK_GET_RATE_NOCACHE, 0),
        DIV_F(CLK_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1,
                                                8, 3, CLK_GET_RATE_NOCACHE, 0),
-       DIV(CLK_SCLK_FIMG2D, "sclk_fimg2d", "mout_g2d", DIV_DMC1, 0, 4),
-       DIV(CLK_DIV_C2C, "div_c2c", "mout_c2c", DIV_DMC1, 4, 3),
-       DIV(0, "div_c2c_aclk", "div_c2c", DIV_DMC1, 12, 3),
 };
 
 /* list of gate clocks supported in all exynos4 soc's */
 static const struct samsung_gate_clock exynos4_gate_clks[] __initconst = {
-       /*
-        * After all Exynos4 based platforms are migrated to use device tree,
-        * the device name and clock alias names specified below for some
-        * of the clocks can be removed.
-        */
        GATE(CLK_PPMULEFT, "ppmuleft", "aclk200", GATE_IP_LEFTBUS, 1, 0, 0),
        GATE(CLK_PPMURIGHT, "ppmuright", "aclk200", GATE_IP_RIGHTBUS, 1, 0, 0),
        GATE(CLK_SCLK_HDMI, "sclk_hdmi", "mout_hdmi", SRC_MASK_TV, 0, 0, 0),
@@ -1147,6 +1144,13 @@ static const struct samsung_gate_clock exynos4x12_gate_clks[] __initconst = {
                        0, 0),
        GATE(CLK_I2S0, "i2s0", "aclk100", E4X12_GATE_IP_MAUDIO, 3,
                        0, 0),
+       GATE(CLK_G2D, "g2d", "aclk200", GATE_IP_DMC, 23, 0, 0),
+       GATE(CLK_SMMU_G2D, "smmu_g2d", "aclk200", GATE_IP_DMC, 24, 0, 0),
+       GATE(CLK_TMU_APBIF, "tmu_apbif", "aclk100", E4X12_GATE_IP_PERIR, 17, 0,
+               0),
+};
+
+static struct samsung_gate_clock exynos4x12_isp_gate_clks[] = {
        GATE(CLK_FIMC_ISP, "isp", "aclk200", E4X12_GATE_ISP0, 0,
                        CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
        GATE(CLK_FIMC_DRC, "drc", "aclk200", E4X12_GATE_ISP0, 1,
@@ -1199,24 +1203,6 @@ static const struct samsung_gate_clock exynos4x12_gate_clks[] __initconst = {
                        CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
        GATE(CLK_SPI1_ISP, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13,
                        CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_G2D, "g2d", "aclk200", GATE_IP_DMC, 23, 0, 0),
-       GATE(CLK_SMMU_G2D, "smmu_g2d", "aclk200", GATE_IP_DMC, 24, 0, 0),
-       GATE(CLK_TMU_APBIF, "tmu_apbif", "aclk100", E4X12_GATE_IP_PERIR, 17, 0,
-               0),
-};
-
-static const struct samsung_clock_alias exynos4_aliases[] __initconst = {
-       ALIAS(CLK_MOUT_CORE, NULL, "moutcore"),
-       ALIAS(CLK_ARM_CLK, NULL, "armclk"),
-       ALIAS(CLK_SCLK_APLL, NULL, "mout_apll"),
-};
-
-static const struct samsung_clock_alias exynos4210_aliases[] __initconst = {
-       ALIAS(CLK_SCLK_MPLL, NULL, "mout_mpll"),
-};
-
-static const struct samsung_clock_alias exynos4x12_aliases[] __initconst = {
-       ALIAS(CLK_MOUT_MPLL_USER_C, NULL, "mout_mpll"),
 };
 
 /*
@@ -1355,14 +1341,14 @@ static const struct samsung_pll_rate_table exynos4x12_vpll_rates[] __initconst =
 };
 
 static struct samsung_pll_clock exynos4210_plls[nr_plls] __initdata = {
-       [apll] = PLL_A(pll_4508, CLK_FOUT_APLL, "fout_apll", "fin_pll",
-               APLL_LOCK, APLL_CON0, "fout_apll", NULL),
-       [mpll] = PLL_A(pll_4508, CLK_FOUT_MPLL, "fout_mpll", "fin_pll",
-               E4210_MPLL_LOCK, E4210_MPLL_CON0, "fout_mpll", NULL),
-       [epll] = PLL_A(pll_4600, CLK_FOUT_EPLL, "fout_epll", "fin_pll",
-               EPLL_LOCK, EPLL_CON0, "fout_epll", NULL),
-       [vpll] = PLL_A(pll_4650c, CLK_FOUT_VPLL, "fout_vpll", "mout_vpllsrc",
-               VPLL_LOCK, VPLL_CON0, "fout_vpll", NULL),
+       [apll] = PLL(pll_4508, CLK_FOUT_APLL, "fout_apll", "fin_pll",
+               APLL_LOCK, APLL_CON0, NULL),
+       [mpll] = PLL(pll_4508, CLK_FOUT_MPLL, "fout_mpll", "fin_pll",
+               E4210_MPLL_LOCK, E4210_MPLL_CON0, NULL),
+       [epll] = PLL(pll_4600, CLK_FOUT_EPLL, "fout_epll", "fin_pll",
+               EPLL_LOCK, EPLL_CON0, NULL),
+       [vpll] = PLL(pll_4650c, CLK_FOUT_VPLL, "fout_vpll", "mout_vpllsrc",
+               VPLL_LOCK, VPLL_CON0, NULL),
 };
 
 static struct samsung_pll_clock exynos4x12_plls[nr_plls] __initdata = {
@@ -1416,24 +1402,6 @@ static const struct exynos_cpuclk_cfg_data e4210_armclk_d[] __initconst = {
        {  0 },
 };
 
-static const struct exynos_cpuclk_cfg_data e4212_armclk_d[] __initconst = {
-       { 1500000, E4210_CPU_DIV0(2, 1, 6, 0, 7, 3), E4210_CPU_DIV1(2, 6), },
-       { 1400000, E4210_CPU_DIV0(2, 1, 6, 0, 7, 3), E4210_CPU_DIV1(2, 6), },
-       { 1300000, E4210_CPU_DIV0(2, 1, 5, 0, 7, 3), E4210_CPU_DIV1(2, 5), },
-       { 1200000, E4210_CPU_DIV0(2, 1, 5, 0, 7, 3), E4210_CPU_DIV1(2, 5), },
-       { 1100000, E4210_CPU_DIV0(2, 1, 4, 0, 6, 3), E4210_CPU_DIV1(2, 4), },
-       { 1000000, E4210_CPU_DIV0(1, 1, 4, 0, 5, 2), E4210_CPU_DIV1(2, 4), },
-       {  900000, E4210_CPU_DIV0(1, 1, 3, 0, 5, 2), E4210_CPU_DIV1(2, 3), },
-       {  800000, E4210_CPU_DIV0(1, 1, 3, 0, 5, 2), E4210_CPU_DIV1(2, 3), },
-       {  700000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
-       {  600000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
-       {  500000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
-       {  400000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
-       {  300000, E4210_CPU_DIV0(1, 1, 2, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
-       {  200000, E4210_CPU_DIV0(1, 1, 1, 0, 3, 1), E4210_CPU_DIV1(2, 3), },
-       {  0 },
-};
-
 #define E4412_CPU_DIV1(cores, hpm, copy)                               \
                (((cores) << 8) | ((hpm) << 4) | ((copy) << 0))
 
@@ -1527,8 +1495,6 @@ static void __init exynos4_clk_init(struct device_node *np,
                        ARRAY_SIZE(exynos4210_div_clks));
                samsung_clk_register_gate(ctx, exynos4210_gate_clks,
                        ARRAY_SIZE(exynos4210_gate_clks));
-               samsung_clk_register_alias(ctx, exynos4210_aliases,
-                       ARRAY_SIZE(exynos4210_aliases));
                samsung_clk_register_fixed_factor(ctx,
                        exynos4210_fixed_factor_clks,
                        ARRAY_SIZE(exynos4210_fixed_factor_clks));
@@ -1537,32 +1503,31 @@ static void __init exynos4_clk_init(struct device_node *np,
                        e4210_armclk_d, ARRAY_SIZE(e4210_armclk_d),
                        CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
        } else {
+               struct resource res;
+
                samsung_clk_register_mux(ctx, exynos4x12_mux_clks,
                        ARRAY_SIZE(exynos4x12_mux_clks));
                samsung_clk_register_div(ctx, exynos4x12_div_clks,
                        ARRAY_SIZE(exynos4x12_div_clks));
                samsung_clk_register_gate(ctx, exynos4x12_gate_clks,
                        ARRAY_SIZE(exynos4x12_gate_clks));
-               samsung_clk_register_alias(ctx, exynos4x12_aliases,
-                       ARRAY_SIZE(exynos4x12_aliases));
                samsung_clk_register_fixed_factor(ctx,
                        exynos4x12_fixed_factor_clks,
                        ARRAY_SIZE(exynos4x12_fixed_factor_clks));
-               if (of_machine_is_compatible("samsung,exynos4412")) {
-                       exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
-                               mout_core_p4x12[0], mout_core_p4x12[1], 0x14200,
-                               e4412_armclk_d, ARRAY_SIZE(e4412_armclk_d),
-                               CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
-               } else {
-                       exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
-                               mout_core_p4x12[0], mout_core_p4x12[1], 0x14200,
-                               e4212_armclk_d, ARRAY_SIZE(e4212_armclk_d),
-                               CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
+
+               of_address_to_resource(np, 0, &res);
+               if (resource_size(&res) > 0x18000) {
+                       samsung_clk_register_div(ctx, exynos4x12_isp_div_clks,
+                               ARRAY_SIZE(exynos4x12_isp_div_clks));
+                       samsung_clk_register_gate(ctx, exynos4x12_isp_gate_clks,
+                               ARRAY_SIZE(exynos4x12_isp_gate_clks));
                }
-       }
 
-       samsung_clk_register_alias(ctx, exynos4_aliases,
-                       ARRAY_SIZE(exynos4_aliases));
+               exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
+                       mout_core_p4x12[0], mout_core_p4x12[1], 0x14200,
+                       e4412_armclk_d, ARRAY_SIZE(e4412_armclk_d),
+                       CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
+       }
 
        if (soc == EXYNOS4X12)
                exynos4x12_core_down_clock();
diff --git a/drivers/clk/samsung/clk-exynos4412-isp.c b/drivers/clk/samsung/clk-exynos4412-isp.c
new file mode 100644 (file)
index 0000000..d5f1ccb
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Common Clock Framework support for Exynos4412 ISP module.
+*/
+
+#include <dt-bindings/clock/exynos4.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include "clk.h"
+
+/* Exynos4x12 specific registers, which belong to ISP power domain */
+#define E4X12_DIV_ISP0         0x0300
+#define E4X12_DIV_ISP1         0x0304
+#define E4X12_GATE_ISP0                0x0800
+#define E4X12_GATE_ISP1                0x0804
+
+/*
+ * Support for CMU save/restore across system suspends
+ */
+static struct samsung_clk_reg_dump *exynos4x12_save_isp;
+
+static const unsigned long exynos4x12_clk_isp_save[] __initconst = {
+       E4X12_DIV_ISP0,
+       E4X12_DIV_ISP1,
+       E4X12_GATE_ISP0,
+       E4X12_GATE_ISP1,
+};
+
+PNAME(mout_user_aclk400_mcuisp_p4x12) = { "fin_pll", "div_aclk400_mcuisp", };
+
+static struct samsung_div_clock exynos4x12_isp_div_clks[] = {
+       DIV(CLK_ISP_DIV_ISP0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3),
+       DIV(CLK_ISP_DIV_ISP1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3),
+       DIV(CLK_ISP_DIV_MCUISP0, "div_mcuisp0", "aclk400_mcuisp",
+           E4X12_DIV_ISP1, 4, 3),
+       DIV(CLK_ISP_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0",
+           E4X12_DIV_ISP1, 8, 3),
+       DIV(0, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3),
+};
+
+static struct samsung_gate_clock exynos4x12_isp_gate_clks[] = {
+       GATE(CLK_ISP_FIMC_ISP, "isp", "aclk200", E4X12_GATE_ISP0, 0, 0, 0),
+       GATE(CLK_ISP_FIMC_DRC, "drc", "aclk200", E4X12_GATE_ISP0, 1, 0, 0),
+       GATE(CLK_ISP_FIMC_FD, "fd", "aclk200", E4X12_GATE_ISP0, 2, 0, 0),
+       GATE(CLK_ISP_FIMC_LITE0, "lite0", "aclk200", E4X12_GATE_ISP0, 3, 0, 0),
+       GATE(CLK_ISP_FIMC_LITE1, "lite1", "aclk200", E4X12_GATE_ISP0, 4, 0, 0),
+       GATE(CLK_ISP_MCUISP, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5, 0, 0),
+       GATE(CLK_ISP_GICISP, "gicisp", "aclk200", E4X12_GATE_ISP0, 7, 0, 0),
+       GATE(CLK_ISP_SMMU_ISP, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8, 0, 0),
+       GATE(CLK_ISP_SMMU_DRC, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9, 0, 0),
+       GATE(CLK_ISP_SMMU_FD, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10, 0, 0),
+       GATE(CLK_ISP_SMMU_LITE0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11,
+            0, 0),
+       GATE(CLK_ISP_SMMU_LITE1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12,
+            0, 0),
+       GATE(CLK_ISP_PPMUISPMX, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20,
+            0, 0),
+       GATE(CLK_ISP_PPMUISPX, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21,
+            0, 0),
+       GATE(CLK_ISP_MCUCTL_ISP, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23,
+            0, 0),
+       GATE(CLK_ISP_MPWM_ISP, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24,
+            0, 0),
+       GATE(CLK_ISP_I2C0_ISP, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25,
+            0, 0),
+       GATE(CLK_ISP_I2C1_ISP, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26,
+            0, 0),
+       GATE(CLK_ISP_MTCADC_ISP, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27,
+            0, 0),
+       GATE(CLK_ISP_PWM_ISP, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28, 0, 0),
+       GATE(CLK_ISP_WDT_ISP, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30, 0, 0),
+       GATE(CLK_ISP_UART_ISP, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31,
+            0, 0),
+       GATE(CLK_ISP_ASYNCAXIM, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0,
+            0, 0),
+       GATE(CLK_ISP_SMMU_ISPCX, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4,
+            0, 0),
+       GATE(CLK_ISP_SPI0_ISP, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12,
+            0, 0),
+       GATE(CLK_ISP_SPI1_ISP, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13,
+            0, 0),
+};
+
+static int __maybe_unused exynos4x12_isp_clk_suspend(struct device *dev)
+{
+       struct samsung_clk_provider *ctx = dev_get_drvdata(dev);
+
+       samsung_clk_save(ctx->reg_base, exynos4x12_save_isp,
+                        ARRAY_SIZE(exynos4x12_clk_isp_save));
+       return 0;
+}
+
+static int __maybe_unused exynos4x12_isp_clk_resume(struct device *dev)
+{
+       struct samsung_clk_provider *ctx = dev_get_drvdata(dev);
+
+       samsung_clk_restore(ctx->reg_base, exynos4x12_save_isp,
+                           ARRAY_SIZE(exynos4x12_clk_isp_save));
+       return 0;
+}
+
+static int __init exynos4x12_isp_clk_probe(struct platform_device *pdev)
+{
+       struct samsung_clk_provider *ctx;
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       struct resource *res;
+       void __iomem *reg_base;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       reg_base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(reg_base)) {
+               dev_err(dev, "failed to map registers\n");
+               return PTR_ERR(reg_base);
+       }
+
+       exynos4x12_save_isp = samsung_clk_alloc_reg_dump(exynos4x12_clk_isp_save,
+                                       ARRAY_SIZE(exynos4x12_clk_isp_save));
+       if (!exynos4x12_save_isp)
+               return -ENOMEM;
+
+       ctx = samsung_clk_init(np, reg_base, CLK_NR_ISP_CLKS);
+       ctx->dev = dev;
+
+       platform_set_drvdata(pdev, ctx);
+
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
+       pm_runtime_get_sync(dev);
+
+       samsung_clk_register_div(ctx, exynos4x12_isp_div_clks,
+                                ARRAY_SIZE(exynos4x12_isp_div_clks));
+       samsung_clk_register_gate(ctx, exynos4x12_isp_gate_clks,
+                                 ARRAY_SIZE(exynos4x12_isp_gate_clks));
+
+       samsung_clk_of_add_provider(np, ctx);
+       pm_runtime_put(dev);
+
+       return 0;
+}
+
+static const struct of_device_id exynos4x12_isp_clk_of_match[] = {
+       { .compatible = "samsung,exynos4412-isp-clock", },
+       { },
+};
+
+static const struct dev_pm_ops exynos4x12_isp_pm_ops = {
+       SET_RUNTIME_PM_OPS(exynos4x12_isp_clk_suspend,
+                          exynos4x12_isp_clk_resume, NULL)
+       SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+                                    pm_runtime_force_resume)
+};
+
+static struct platform_driver exynos4x12_isp_clk_driver __refdata = {
+       .driver = {
+               .name = "exynos4x12-isp-clk",
+               .of_match_table = exynos4x12_isp_clk_of_match,
+               .suppress_bind_attrs = true,
+               .pm = &exynos4x12_isp_pm_ops,
+       },
+       .probe = exynos4x12_isp_clk_probe,
+};
+
+static int __init exynos4x12_isp_clk_init(void)
+{
+       return platform_driver_register(&exynos4x12_isp_clk_driver);
+}
+core_initcall(exynos4x12_isp_clk_init);
index 27a227d6620c7b32bedf04bf16f2f2a7f71ce49b..9b073c98a8910e02be6420454a6d198275de27fc 100644 (file)
@@ -293,14 +293,14 @@ static const struct samsung_mux_clock exynos5250_mux_clks[] __initconst = {
        /*
         * CMU_CPU
         */
-       MUX_FA(0, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
-                                       CLK_SET_RATE_PARENT, 0, "mout_apll"),
-       MUX_A(0, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1, "mout_cpu"),
+       MUX_F(0, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
+                                       CLK_SET_RATE_PARENT, 0),
+       MUX(0, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1),
 
        /*
         * CMU_CORE
         */
-       MUX_A(0, "mout_mpll", mout_mpll_p, SRC_CORE1, 8, 1, "mout_mpll"),
+       MUX(0, "mout_mpll", mout_mpll_p, SRC_CORE1, 8, 1),
 
        /*
         * CMU_TOP
@@ -391,7 +391,7 @@ static const struct samsung_div_clock exynos5250_div_clks[] __initconst = {
         */
        DIV(0, "div_arm", "mout_cpu", DIV_CPU0, 0, 3),
        DIV(0, "div_apll", "mout_apll", DIV_CPU0, 24, 3),
-       DIV_A(0, "div_arm2", "div_arm", DIV_CPU0, 28, 3, "armclk"),
+       DIV(0, "div_arm2", "div_arm", DIV_CPU0, 28, 3),
 
        /*
         * CMU_TOP
@@ -743,10 +743,10 @@ static const struct samsung_pll_rate_table apll_24mhz_tbl[] __initconst = {
 };
 
 static struct samsung_pll_clock exynos5250_plls[nr_plls] __initdata = {
-       [apll] = PLL_A(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll",
-               APLL_LOCK, APLL_CON0, "fout_apll", NULL),
-       [mpll] = PLL_A(pll_35xx, CLK_FOUT_MPLL, "fout_mpll", "fin_pll",
-               MPLL_LOCK, MPLL_CON0, "fout_mpll", NULL),
+       [apll] = PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK,
+               APLL_CON0, NULL),
+       [mpll] = PLL(pll_35xx, CLK_FOUT_MPLL, "fout_mpll", "fin_pll", MPLL_LOCK,
+               MPLL_CON0, NULL),
        [bpll] = PLL(pll_35xx, CLK_FOUT_BPLL, "fout_bpll", "fin_pll", BPLL_LOCK,
                BPLL_CON0, NULL),
        [gpll] = PLL(pll_35xx, CLK_FOUT_GPLL, "fout_gpll", "fin_pll", GPLL_LOCK,
index 25601967d1cd6da55c733e41f1057670ae7ff87e..45d34f601e9e0abfa5eac115272df833c4c86ce1 100644 (file)
@@ -600,8 +600,7 @@ static const struct samsung_mux_clock exynos5420_mux_clks[] __initconst = {
                                TOP_SPARE2, 4, 1),
 
        MUX(0, "mout_aclk400_isp", mout_group1_p, SRC_TOP0, 0, 2),
-       MUX_A(0, "mout_aclk400_mscl", mout_group1_p,
-                               SRC_TOP0, 4, 2, "aclk400_mscl"),
+       MUX(0, "mout_aclk400_mscl", mout_group1_p, SRC_TOP0, 4, 2),
        MUX(0, "mout_aclk400_wcore", mout_group1_p, SRC_TOP0, 16, 2),
        MUX(0, "mout_aclk100_noc", mout_group1_p, SRC_TOP0, 20, 2),
 
@@ -998,7 +997,7 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
        GATE(0, "aclk400_isp", "mout_user_aclk400_isp",
                        GATE_BUS_TOP, 16, 0, 0),
        GATE(0, "aclk400_mscl", "mout_user_aclk400_mscl",
-                       GATE_BUS_TOP, 17, 0, 0),
+                       GATE_BUS_TOP, 17, CLK_IS_CRITICAL, 0),
        GATE(0, "aclk200_disp1", "mout_user_aclk200_disp1",
                        GATE_BUS_TOP, 18, CLK_IS_CRITICAL, 0),
        GATE(CLK_SCLK_MPHY_IXTAL24, "sclk_mphy_ixtal24", "mphy_refclk_ixtal24",
index 11343a5970933d14c490006727c9fc39a86e1a5e..db270908037abc097d1ec7b43a1a10677cc7eaed 100644 (file)
@@ -9,9 +9,13 @@
  * Common Clock Framework support for Exynos5433 SoC.
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 
 #include <dt-bindings/clock/exynos5433.h>
 
@@ -1991,6 +1995,14 @@ static const unsigned long fsys_clk_regs[] __initconst = {
        ENABLE_IP_FSYS1,
 };
 
+static const struct samsung_clk_reg_dump fsys_suspend_regs[] = {
+       { MUX_SEL_FSYS0, 0 },
+       { MUX_SEL_FSYS1, 0 },
+       { MUX_SEL_FSYS2, 0 },
+       { MUX_SEL_FSYS3, 0 },
+       { MUX_SEL_FSYS4, 0 },
+};
+
 static const struct samsung_fixed_rate_clock fsys_fixed_clks[] __initconst = {
        /* PHY clocks from USBDRD30_PHY */
        FRATE(CLK_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_PHY,
@@ -2296,16 +2308,11 @@ static const struct samsung_cmu_info fsys_cmu_info __initconst = {
        .nr_clk_ids             = FSYS_NR_CLK,
        .clk_regs               = fsys_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(fsys_clk_regs),
+       .suspend_regs           = fsys_suspend_regs,
+       .nr_suspend_regs        = ARRAY_SIZE(fsys_suspend_regs),
+       .clk_name               = "aclk_fsys_200",
 };
 
-static void __init exynos5433_cmu_fsys_init(struct device_node *np)
-{
-       samsung_cmu_register_one(np, &fsys_cmu_info);
-}
-
-CLK_OF_DECLARE(exynos5433_cmu_fsys, "samsung,exynos5433-cmu-fsys",
-               exynos5433_cmu_fsys_init);
-
 /*
  * Register offset definitions for CMU_G2D
  */
@@ -2335,6 +2342,10 @@ static const unsigned long g2d_clk_regs[] __initconst = {
        DIV_ENABLE_IP_G2D_SECURE_SMMU_G2D,
 };
 
+static const struct samsung_clk_reg_dump g2d_suspend_regs[] = {
+       { MUX_SEL_G2D0, 0 },
+};
+
 /* list of all parent clock list */
 PNAME(mout_aclk_g2d_266_user_p)                = { "oscclk", "aclk_g2d_266", };
 PNAME(mout_aclk_g2d_400_user_p)                = { "oscclk", "aclk_g2d_400", };
@@ -2420,16 +2431,11 @@ static const struct samsung_cmu_info g2d_cmu_info __initconst = {
        .nr_clk_ids             = G2D_NR_CLK,
        .clk_regs               = g2d_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(g2d_clk_regs),
+       .suspend_regs           = g2d_suspend_regs,
+       .nr_suspend_regs        = ARRAY_SIZE(g2d_suspend_regs),
+       .clk_name               = "aclk_g2d_400",
 };
 
-static void __init exynos5433_cmu_g2d_init(struct device_node *np)
-{
-       samsung_cmu_register_one(np, &g2d_cmu_info);
-}
-
-CLK_OF_DECLARE(exynos5433_cmu_g2d, "samsung,exynos5433-cmu-g2d",
-               exynos5433_cmu_g2d_init);
-
 /*
  * Register offset definitions for CMU_DISP
  */
@@ -2494,6 +2500,18 @@ static const unsigned long disp_clk_regs[] __initconst = {
        CLKOUT_CMU_DISP_DIV_STAT,
 };
 
+static const struct samsung_clk_reg_dump disp_suspend_regs[] = {
+       /* PLL has to be enabled for suspend */
+       { DISP_PLL_CON0, 0x85f40502 },
+       /* ignore status of external PHY muxes during suspend to avoid hangs */
+       { MUX_IGNORE_DISP2, 0x00111111 },
+       { MUX_SEL_DISP0, 0 },
+       { MUX_SEL_DISP1, 0 },
+       { MUX_SEL_DISP2, 0 },
+       { MUX_SEL_DISP3, 0 },
+       { MUX_SEL_DISP4, 0 },
+};
+
 /* list of all parent clock list */
 PNAME(mout_disp_pll_p)                 = { "oscclk", "fout_disp_pll", };
 PNAME(mout_sclk_dsim1_user_p)          = { "oscclk", "sclk_dsim1_disp", };
@@ -2841,16 +2859,11 @@ static const struct samsung_cmu_info disp_cmu_info __initconst = {
        .nr_clk_ids             = DISP_NR_CLK,
        .clk_regs               = disp_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(disp_clk_regs),
+       .suspend_regs           = disp_suspend_regs,
+       .nr_suspend_regs        = ARRAY_SIZE(disp_suspend_regs),
+       .clk_name               = "aclk_disp_333",
 };
 
-static void __init exynos5433_cmu_disp_init(struct device_node *np)
-{
-       samsung_cmu_register_one(np, &disp_cmu_info);
-}
-
-CLK_OF_DECLARE(exynos5433_cmu_disp, "samsung,exynos5433-cmu-disp",
-               exynos5433_cmu_disp_init);
-
 /*
  * Register offset definitions for CMU_AUD
  */
@@ -2885,6 +2898,11 @@ static const unsigned long aud_clk_regs[] __initconst = {
        ENABLE_IP_AUD1,
 };
 
+static const struct samsung_clk_reg_dump aud_suspend_regs[] = {
+       { MUX_SEL_AUD0, 0 },
+       { MUX_SEL_AUD1, 0 },
+};
+
 /* list of all parent clock list */
 PNAME(mout_aud_pll_user_aud_p) = { "oscclk", "fout_aud_pll", };
 PNAME(mout_sclk_aud_pcm_p)     = { "mout_aud_pll_user", "ioclk_audiocdclk0",};
@@ -3011,16 +3029,11 @@ static const struct samsung_cmu_info aud_cmu_info __initconst = {
        .nr_clk_ids             = AUD_NR_CLK,
        .clk_regs               = aud_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(aud_clk_regs),
+       .suspend_regs           = aud_suspend_regs,
+       .nr_suspend_regs        = ARRAY_SIZE(aud_suspend_regs),
+       .clk_name               = "fout_aud_pll",
 };
 
-static void __init exynos5433_cmu_aud_init(struct device_node *np)
-{
-       samsung_cmu_register_one(np, &aud_cmu_info);
-}
-CLK_OF_DECLARE(exynos5433_cmu_aud, "samsung,exynos5433-cmu-aud",
-               exynos5433_cmu_aud_init);
-
-
 /*
  * Register offset definitions for CMU_BUS{0|1|2}
  */
@@ -3222,6 +3235,10 @@ static const unsigned long g3d_clk_regs[] __initconst = {
        CLK_STOPCTRL,
 };
 
+static const struct samsung_clk_reg_dump g3d_suspend_regs[] = {
+       { MUX_SEL_G3D, 0 },
+};
+
 /* list of all parent clock list */
 PNAME(mout_aclk_g3d_400_p)     = { "mout_g3d_pll", "aclk_g3d_400", };
 PNAME(mout_g3d_pll_p)          = { "oscclk", "fout_g3d_pll", };
@@ -3295,15 +3312,11 @@ static const struct samsung_cmu_info g3d_cmu_info __initconst = {
        .nr_clk_ids             = G3D_NR_CLK,
        .clk_regs               = g3d_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(g3d_clk_regs),
+       .suspend_regs           = g3d_suspend_regs,
+       .nr_suspend_regs        = ARRAY_SIZE(g3d_suspend_regs),
+       .clk_name               = "aclk_g3d_400",
 };
 
-static void __init exynos5433_cmu_g3d_init(struct device_node *np)
-{
-       samsung_cmu_register_one(np, &g3d_cmu_info);
-}
-CLK_OF_DECLARE(exynos5433_cmu_g3d, "samsung,exynos5433-cmu-g3d",
-               exynos5433_cmu_g3d_init);
-
 /*
  * Register offset definitions for CMU_GSCL
  */
@@ -3342,6 +3355,12 @@ static const unsigned long gscl_clk_regs[] __initconst = {
        ENABLE_IP_GSCL_SECURE_SMMU_GSCL2,
 };
 
+static const struct samsung_clk_reg_dump gscl_suspend_regs[] = {
+       { MUX_SEL_GSCL, 0 },
+       { ENABLE_ACLK_GSCL, 0xfff },
+       { ENABLE_PCLK_GSCL, 0xff },
+};
+
 /* list of all parent clock list */
 PNAME(aclk_gscl_111_user_p)    = { "oscclk", "aclk_gscl_111", };
 PNAME(aclk_gscl_333_user_p)    = { "oscclk", "aclk_gscl_333", };
@@ -3436,15 +3455,11 @@ static const struct samsung_cmu_info gscl_cmu_info __initconst = {
        .nr_clk_ids             = GSCL_NR_CLK,
        .clk_regs               = gscl_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(gscl_clk_regs),
+       .suspend_regs           = gscl_suspend_regs,
+       .nr_suspend_regs        = ARRAY_SIZE(gscl_suspend_regs),
+       .clk_name               = "aclk_gscl_111",
 };
 
-static void __init exynos5433_cmu_gscl_init(struct device_node *np)
-{
-       samsung_cmu_register_one(np, &gscl_cmu_info);
-}
-CLK_OF_DECLARE(exynos5433_cmu_gscl, "samsung,exynos5433-cmu-gscl",
-               exynos5433_cmu_gscl_init);
-
 /*
  * Register offset definitions for CMU_APOLLO
  */
@@ -3970,6 +3985,11 @@ static const unsigned long mscl_clk_regs[] __initconst = {
        ENABLE_IP_MSCL_SECURE_SMMU_JPEG,
 };
 
+static const struct samsung_clk_reg_dump mscl_suspend_regs[] = {
+       { MUX_SEL_MSCL0, 0 },
+       { MUX_SEL_MSCL1, 0 },
+};
+
 /* list of all parent clock list */
 PNAME(mout_sclk_jpeg_user_p)           = { "oscclk", "sclk_jpeg_mscl", };
 PNAME(mout_aclk_mscl_400_user_p)       = { "oscclk", "aclk_mscl_400", };
@@ -4082,15 +4102,11 @@ static const struct samsung_cmu_info mscl_cmu_info __initconst = {
        .nr_clk_ids             = MSCL_NR_CLK,
        .clk_regs               = mscl_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(mscl_clk_regs),
+       .suspend_regs           = mscl_suspend_regs,
+       .nr_suspend_regs        = ARRAY_SIZE(mscl_suspend_regs),
+       .clk_name               = "aclk_mscl_400",
 };
 
-static void __init exynos5433_cmu_mscl_init(struct device_node *np)
-{
-       samsung_cmu_register_one(np, &mscl_cmu_info);
-}
-CLK_OF_DECLARE(exynos5433_cmu_mscl, "samsung,exynos5433-cmu-mscl",
-               exynos5433_cmu_mscl_init);
-
 /*
  * Register offset definitions for CMU_MFC
  */
@@ -4120,6 +4136,10 @@ static const unsigned long mfc_clk_regs[] __initconst = {
        ENABLE_IP_MFC_SECURE_SMMU_MFC,
 };
 
+static const struct samsung_clk_reg_dump mfc_suspend_regs[] = {
+       { MUX_SEL_MFC, 0 },
+};
+
 PNAME(mout_aclk_mfc_400_user_p)                = { "oscclk", "aclk_mfc_400", };
 
 static const struct samsung_mux_clock mfc_mux_clks[] __initconst = {
@@ -4190,15 +4210,11 @@ static const struct samsung_cmu_info mfc_cmu_info __initconst = {
        .nr_clk_ids             = MFC_NR_CLK,
        .clk_regs               = mfc_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(mfc_clk_regs),
+       .suspend_regs           = mfc_suspend_regs,
+       .nr_suspend_regs        = ARRAY_SIZE(mfc_suspend_regs),
+       .clk_name               = "aclk_mfc_400",
 };
 
-static void __init exynos5433_cmu_mfc_init(struct device_node *np)
-{
-       samsung_cmu_register_one(np, &mfc_cmu_info);
-}
-CLK_OF_DECLARE(exynos5433_cmu_mfc, "samsung,exynos5433-cmu-mfc",
-               exynos5433_cmu_mfc_init);
-
 /*
  * Register offset definitions for CMU_HEVC
  */
@@ -4228,6 +4244,10 @@ static const unsigned long hevc_clk_regs[] __initconst = {
        ENABLE_IP_HEVC_SECURE_SMMU_HEVC,
 };
 
+static const struct samsung_clk_reg_dump hevc_suspend_regs[] = {
+       { MUX_SEL_HEVC, 0 },
+};
+
 PNAME(mout_aclk_hevc_400_user_p)       = { "oscclk", "aclk_hevc_400", };
 
 static const struct samsung_mux_clock hevc_mux_clks[] __initconst = {
@@ -4300,15 +4320,11 @@ static const struct samsung_cmu_info hevc_cmu_info __initconst = {
        .nr_clk_ids             = HEVC_NR_CLK,
        .clk_regs               = hevc_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(hevc_clk_regs),
+       .suspend_regs           = hevc_suspend_regs,
+       .nr_suspend_regs        = ARRAY_SIZE(hevc_suspend_regs),
+       .clk_name               = "aclk_hevc_400",
 };
 
-static void __init exynos5433_cmu_hevc_init(struct device_node *np)
-{
-       samsung_cmu_register_one(np, &hevc_cmu_info);
-}
-CLK_OF_DECLARE(exynos5433_cmu_hevc, "samsung,exynos5433-cmu-hevc",
-               exynos5433_cmu_hevc_init);
-
 /*
  * Register offset definitions for CMU_ISP
  */
@@ -4342,6 +4358,10 @@ static const unsigned long isp_clk_regs[] __initconst = {
        ENABLE_IP_ISP3,
 };
 
+static const struct samsung_clk_reg_dump isp_suspend_regs[] = {
+       { MUX_SEL_ISP, 0 },
+};
+
 PNAME(mout_aclk_isp_dis_400_user_p)    = { "oscclk", "aclk_isp_dis_400", };
 PNAME(mout_aclk_isp_400_user_p)                = { "oscclk", "aclk_isp_400", };
 
@@ -4553,15 +4573,11 @@ static const struct samsung_cmu_info isp_cmu_info __initconst = {
        .nr_clk_ids             = ISP_NR_CLK,
        .clk_regs               = isp_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(isp_clk_regs),
+       .suspend_regs           = isp_suspend_regs,
+       .nr_suspend_regs        = ARRAY_SIZE(isp_suspend_regs),
+       .clk_name               = "aclk_isp_400",
 };
 
-static void __init exynos5433_cmu_isp_init(struct device_node *np)
-{
-       samsung_cmu_register_one(np, &isp_cmu_info);
-}
-CLK_OF_DECLARE(exynos5433_cmu_isp, "samsung,exynos5433-cmu-isp",
-               exynos5433_cmu_isp_init);
-
 /*
  * Register offset definitions for CMU_CAM0
  */
@@ -4625,6 +4641,15 @@ static const unsigned long cam0_clk_regs[] __initconst = {
        ENABLE_IP_CAM02,
        ENABLE_IP_CAM03,
 };
+
+static const struct samsung_clk_reg_dump cam0_suspend_regs[] = {
+       { MUX_SEL_CAM00, 0 },
+       { MUX_SEL_CAM01, 0 },
+       { MUX_SEL_CAM02, 0 },
+       { MUX_SEL_CAM03, 0 },
+       { MUX_SEL_CAM04, 0 },
+};
+
 PNAME(mout_aclk_cam0_333_user_p)       = { "oscclk", "aclk_cam0_333", };
 PNAME(mout_aclk_cam0_400_user_p)       = { "oscclk", "aclk_cam0_400", };
 PNAME(mout_aclk_cam0_552_user_p)       = { "oscclk", "aclk_cam0_552", };
@@ -5030,15 +5055,11 @@ static const struct samsung_cmu_info cam0_cmu_info __initconst = {
        .nr_clk_ids             = CAM0_NR_CLK,
        .clk_regs               = cam0_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(cam0_clk_regs),
+       .suspend_regs           = cam0_suspend_regs,
+       .nr_suspend_regs        = ARRAY_SIZE(cam0_suspend_regs),
+       .clk_name               = "aclk_cam0_400",
 };
 
-static void __init exynos5433_cmu_cam0_init(struct device_node *np)
-{
-       samsung_cmu_register_one(np, &cam0_cmu_info);
-}
-CLK_OF_DECLARE(exynos5433_cmu_cam0, "samsung,exynos5433-cmu-cam0",
-               exynos5433_cmu_cam0_init);
-
 /*
  * Register offset definitions for CMU_CAM1
  */
@@ -5085,6 +5106,12 @@ static const unsigned long cam1_clk_regs[] __initconst = {
        ENABLE_IP_CAM12,
 };
 
+static const struct samsung_clk_reg_dump cam1_suspend_regs[] = {
+       { MUX_SEL_CAM10, 0 },
+       { MUX_SEL_CAM11, 0 },
+       { MUX_SEL_CAM12, 0 },
+};
+
 PNAME(mout_sclk_isp_uart_user_p)       = { "oscclk", "sclk_isp_uart_cam1", };
 PNAME(mout_sclk_isp_spi1_user_p)       = { "oscclk", "sclk_isp_spi1_cam1", };
 PNAME(mout_sclk_isp_spi0_user_p)       = { "oscclk", "sclk_isp_spi0_cam1", };
@@ -5403,11 +5430,223 @@ static const struct samsung_cmu_info cam1_cmu_info __initconst = {
        .nr_clk_ids             = CAM1_NR_CLK,
        .clk_regs               = cam1_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(cam1_clk_regs),
+       .suspend_regs           = cam1_suspend_regs,
+       .nr_suspend_regs        = ARRAY_SIZE(cam1_suspend_regs),
+       .clk_name               = "aclk_cam1_400",
+};
+
+
+struct exynos5433_cmu_data {
+       struct samsung_clk_reg_dump *clk_save;
+       unsigned int nr_clk_save;
+       const struct samsung_clk_reg_dump *clk_suspend;
+       unsigned int nr_clk_suspend;
+
+       struct clk *clk;
+       struct clk **pclks;
+       int nr_pclks;
+
+       /* must be the last entry */
+       struct samsung_clk_provider ctx;
+};
+
+static int __maybe_unused exynos5433_cmu_suspend(struct device *dev)
+{
+       struct exynos5433_cmu_data *data = dev_get_drvdata(dev);
+       int i;
+
+       samsung_clk_save(data->ctx.reg_base, data->clk_save,
+                        data->nr_clk_save);
+
+       for (i = 0; i < data->nr_pclks; i++)
+               clk_prepare_enable(data->pclks[i]);
+
+       /* for suspend some registers have to be set to certain values */
+       samsung_clk_restore(data->ctx.reg_base, data->clk_suspend,
+                           data->nr_clk_suspend);
+
+       for (i = 0; i < data->nr_pclks; i++)
+               clk_disable_unprepare(data->pclks[i]);
+
+       clk_disable_unprepare(data->clk);
+
+       return 0;
+}
+
+static int __maybe_unused exynos5433_cmu_resume(struct device *dev)
+{
+       struct exynos5433_cmu_data *data = dev_get_drvdata(dev);
+       int i;
+
+       clk_prepare_enable(data->clk);
+
+       for (i = 0; i < data->nr_pclks; i++)
+               clk_prepare_enable(data->pclks[i]);
+
+       samsung_clk_restore(data->ctx.reg_base, data->clk_save,
+                           data->nr_clk_save);
+
+       for (i = 0; i < data->nr_pclks; i++)
+               clk_disable_unprepare(data->pclks[i]);
+
+       return 0;
+}
+
+static int __init exynos5433_cmu_probe(struct platform_device *pdev)
+{
+       const struct samsung_cmu_info *info;
+       struct exynos5433_cmu_data *data;
+       struct samsung_clk_provider *ctx;
+       struct device *dev = &pdev->dev;
+       struct resource *res;
+       void __iomem *reg_base;
+       int i;
+
+       info = of_device_get_match_data(dev);
+
+       data = devm_kzalloc(dev, sizeof(*data) +
+                           sizeof(*data->ctx.clk_data.hws) * info->nr_clk_ids,
+                           GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+       ctx = &data->ctx;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       reg_base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(reg_base)) {
+               dev_err(dev, "failed to map registers\n");
+               return PTR_ERR(reg_base);
+       }
+
+       for (i = 0; i < info->nr_clk_ids; ++i)
+               ctx->clk_data.hws[i] = ERR_PTR(-ENOENT);
+
+       ctx->clk_data.num = info->nr_clk_ids;
+       ctx->reg_base = reg_base;
+       ctx->dev = dev;
+       spin_lock_init(&ctx->lock);
+
+       data->clk_save = samsung_clk_alloc_reg_dump(info->clk_regs,
+                                                   info->nr_clk_regs);
+       data->nr_clk_save = info->nr_clk_regs;
+       data->clk_suspend = info->suspend_regs;
+       data->nr_clk_suspend = info->nr_suspend_regs;
+       data->nr_pclks = of_count_phandle_with_args(dev->of_node, "clocks",
+                                                   "#clock-cells");
+       if (data->nr_pclks > 0) {
+               data->pclks = devm_kcalloc(dev, sizeof(struct clk *),
+                                          data->nr_pclks, GFP_KERNEL);
+
+               for (i = 0; i < data->nr_pclks; i++) {
+                       struct clk *clk = of_clk_get(dev->of_node, i);
+
+                       if (IS_ERR(clk))
+                               return PTR_ERR(clk);
+                       data->pclks[i] = clk;
+               }
+       }
+
+       if (info->clk_name)
+               data->clk = clk_get(dev, info->clk_name);
+       clk_prepare_enable(data->clk);
+
+       platform_set_drvdata(pdev, data);
+
+       /*
+        * Enable runtime PM here to allow the clock core using runtime PM
+        * for the registered clocks. Additionally, we increase the runtime
+        * PM usage count before registering the clocks, to prevent the
+        * clock core from runtime suspending the device.
+        */
+       pm_runtime_get_noresume(dev);
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
+
+       if (info->pll_clks)
+               samsung_clk_register_pll(ctx, info->pll_clks, info->nr_pll_clks,
+                                        reg_base);
+       if (info->mux_clks)
+               samsung_clk_register_mux(ctx, info->mux_clks,
+                                        info->nr_mux_clks);
+       if (info->div_clks)
+               samsung_clk_register_div(ctx, info->div_clks,
+                                        info->nr_div_clks);
+       if (info->gate_clks)
+               samsung_clk_register_gate(ctx, info->gate_clks,
+                                         info->nr_gate_clks);
+       if (info->fixed_clks)
+               samsung_clk_register_fixed_rate(ctx, info->fixed_clks,
+                                               info->nr_fixed_clks);
+       if (info->fixed_factor_clks)
+               samsung_clk_register_fixed_factor(ctx, info->fixed_factor_clks,
+                                                 info->nr_fixed_factor_clks);
+
+       samsung_clk_of_add_provider(dev->of_node, ctx);
+       pm_runtime_put_sync(dev);
+
+       return 0;
+}
+
+static const struct of_device_id exynos5433_cmu_of_match[] = {
+       {
+               .compatible = "samsung,exynos5433-cmu-aud",
+               .data = &aud_cmu_info,
+       }, {
+               .compatible = "samsung,exynos5433-cmu-cam0",
+               .data = &cam0_cmu_info,
+       }, {
+               .compatible = "samsung,exynos5433-cmu-cam1",
+               .data = &cam1_cmu_info,
+       }, {
+               .compatible = "samsung,exynos5433-cmu-disp",
+               .data = &disp_cmu_info,
+       }, {
+               .compatible = "samsung,exynos5433-cmu-g2d",
+               .data = &g2d_cmu_info,
+       }, {
+               .compatible = "samsung,exynos5433-cmu-g3d",
+               .data = &g3d_cmu_info,
+       }, {
+               .compatible = "samsung,exynos5433-cmu-fsys",
+               .data = &fsys_cmu_info,
+       }, {
+               .compatible = "samsung,exynos5433-cmu-gscl",
+               .data = &gscl_cmu_info,
+       }, {
+               .compatible = "samsung,exynos5433-cmu-mfc",
+               .data = &mfc_cmu_info,
+       }, {
+               .compatible = "samsung,exynos5433-cmu-hevc",
+               .data = &hevc_cmu_info,
+       }, {
+               .compatible = "samsung,exynos5433-cmu-isp",
+               .data = &isp_cmu_info,
+       }, {
+               .compatible = "samsung,exynos5433-cmu-mscl",
+               .data = &mscl_cmu_info,
+       }, {
+       },
+};
+
+static const struct dev_pm_ops exynos5433_cmu_pm_ops = {
+       SET_RUNTIME_PM_OPS(exynos5433_cmu_suspend, exynos5433_cmu_resume,
+                          NULL)
+       SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+                                    pm_runtime_force_resume)
+};
+
+static struct platform_driver exynos5433_cmu_driver __refdata = {
+       .driver = {
+               .name = "exynos5433-cmu",
+               .of_match_table = exynos5433_cmu_of_match,
+               .suppress_bind_attrs = true,
+               .pm = &exynos5433_cmu_pm_ops,
+       },
+       .probe = exynos5433_cmu_probe,
 };
 
-static void __init exynos5433_cmu_cam1_init(struct device_node *np)
+static int __init exynos5433_cmu_init(void)
 {
-       samsung_cmu_register_one(np, &cam1_cmu_info);
+       return platform_driver_register(&exynos5433_cmu_driver);
 }
-CLK_OF_DECLARE(exynos5433_cmu_cam1, "samsung,exynos5433-cmu-cam1",
-               exynos5433_cmu_cam1_init);
+core_initcall(exynos5433_cmu_init);
index a80f3ef208018758c5e5774abadc7b700ebf39da..b08bd54c5e766833b5355e69b6acd165731aef61 100644 (file)
@@ -53,8 +53,7 @@ static const struct samsung_fixed_factor_clock exynos5440_fixed_factor_clks[] __
 /* mux clocks */
 static const struct samsung_mux_clock exynos5440_mux_clks[] __initconst = {
        MUX(0, "mout_spi", mout_spi_p, MISC_DOUT1, 5, 1),
-       MUX_A(CLK_ARM_CLK, "arm_clk", mout_armclk_p,
-                       CPU_CLK_STATUS, 0, 1, "armclk"),
+       MUX(CLK_ARM_CLK, "arm_clk", mout_armclk_p, CPU_CLK_STATUS, 0, 1),
 };
 
 /* divider clocks */
@@ -117,6 +116,13 @@ static const struct samsung_pll_clock exynos5440_plls[] __initconst = {
        PLL(pll_2550x, CLK_CPLLB, "cpllb", "xtal", 0, 0x50, NULL),
 };
 
+/*
+ * Clock aliases for legacy clkdev look-up.
+ */
+static const struct samsung_clock_alias exynos5440_aliases[] __initconst = {
+       ALIAS(CLK_ARM_CLK, NULL, "armclk"),
+};
+
 /* register exynos5440 clocks */
 static void __init exynos5440_clk_init(struct device_node *np)
 {
@@ -147,6 +153,8 @@ static void __init exynos5440_clk_init(struct device_node *np)
                        ARRAY_SIZE(exynos5440_div_clks));
        samsung_clk_register_gate(ctx, exynos5440_gate_clks,
                        ARRAY_SIZE(exynos5440_gate_clks));
+       samsung_clk_register_alias(ctx, exynos5440_aliases,
+                                               ARRAY_SIZE(exynos5440_aliases));
 
        samsung_clk_of_add_provider(np, ctx);
 
index 037c6148409872b46f35f9613244742fd52b3a09..1c4c7a3039f1bc53a5ccb1bc558fd304db50c677 100644 (file)
@@ -1388,7 +1388,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
        pll->lock_reg = base + pll_clk->lock_offset;
        pll->con_reg = base + pll_clk->con_offset;
 
-       ret = clk_hw_register(NULL, &pll->hw);
+       ret = clk_hw_register(ctx->dev, &pll->hw);
        if (ret) {
                pr_err("%s: failed to register pll clock %s : %d\n",
                        __func__, pll_clk->name, ret);
@@ -1397,15 +1397,6 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
        }
 
        samsung_clk_add_lookup(ctx, &pll->hw, pll_clk->id);
-
-       if (!pll_clk->alias)
-               return;
-
-       ret = clk_hw_register_clkdev(&pll->hw, pll_clk->alias,
-                                    pll_clk->dev_name);
-       if (ret)
-               pr_err("%s: failed to register lookup for %s : %d",
-                       __func__, pll_clk->name, ret);
 }
 
 void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
index abb935c4291699c957c242c5192512349e31524b..d94b85a4235604bfd8212d80925382acd7a9d9b3 100644 (file)
@@ -117,8 +117,8 @@ struct samsung_mux_clock s3c2443_common_muxes[] __initdata = {
        MUX(0, "epllref", epllref_p, CLKSRC, 7, 2),
        MUX(ESYSCLK, "esysclk", esysclk_p, CLKSRC, 6, 1),
        MUX(0, "mpllref", mpllref_p, CLKSRC, 3, 1),
-       MUX_A(MSYSCLK, "msysclk", msysclk_p, CLKSRC, 4, 1, "msysclk"),
-       MUX_A(ARMCLK, "armclk", armclk_p, CLKDIV0, 13, 1, "armclk"),
+       MUX(MSYSCLK, "msysclk", msysclk_p, CLKSRC, 4, 1),
+       MUX(ARMCLK, "armclk", armclk_p, CLKDIV0, 13, 1),
        MUX(0, "mux_i2s0", i2s0_p, CLKSRC, 14, 2),
 };
 
@@ -189,6 +189,10 @@ struct samsung_gate_clock s3c2443_common_gates[] __initdata = {
 };
 
 struct samsung_clock_alias s3c2443_common_aliases[] __initdata = {
+       ALIAS(MSYSCLK, NULL, "msysclk"),
+       ALIAS(ARMCLK, NULL, "armclk"),
+       ALIAS(MPLL, NULL, "mpll"),
+       ALIAS(EPLL, NULL, "epll"),
        ALIAS(HCLK, NULL, "hclk"),
        ALIAS(HCLK_SSMC, NULL, "nand"),
        ALIAS(PCLK_UART0, "s3c2440-uart.0", "uart"),
@@ -221,9 +225,9 @@ struct samsung_clock_alias s3c2443_common_aliases[] __initdata = {
 /* S3C2416 specific clocks */
 
 static struct samsung_pll_clock s3c2416_pll_clks[] __initdata = {
-       [mpll] = PLL(pll_6552_s3c2416, 0, "mpll", "mpllref",
+       [mpll] = PLL(pll_6552_s3c2416, MPLL, "mpll", "mpllref",
                                                LOCKCON0, MPLLCON, NULL),
-       [epll] = PLL(pll_6553, 0, "epll", "epllref",
+       [epll] = PLL(pll_6553, EPLL, "epll", "epllref",
                                                LOCKCON1, EPLLCON, NULL),
 };
 
@@ -275,9 +279,9 @@ struct samsung_clock_alias s3c2416_aliases[] __initdata = {
 /* S3C2443 specific clocks */
 
 static struct samsung_pll_clock s3c2443_pll_clks[] __initdata = {
-       [mpll] = PLL(pll_3000, 0, "mpll", "mpllref",
+       [mpll] = PLL(pll_3000, MPLL, "mpll", "mpllref",
                                                LOCKCON0, MPLLCON, NULL),
-       [epll] = PLL(pll_2126, 0, "epll", "epllref",
+       [epll] = PLL(pll_2126, EPLL, "epll", "epllref",
                                                LOCKCON1, EPLLCON, NULL),
 };
 
index 7ce0fa86c5ff821b0a2745e589b8f047b66b4e1b..8634884aa11ce421fb9a3485d6f1af2408bd5fd4 100644 (file)
@@ -134,7 +134,7 @@ void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx,
        unsigned int idx, ret;
 
        for (idx = 0; idx < nr_clk; idx++, list++) {
-               clk_hw = clk_hw_register_fixed_rate(NULL, list->name,
+               clk_hw = clk_hw_register_fixed_rate(ctx->dev, list->name,
                        list->parent_name, list->flags, list->fixed_rate);
                if (IS_ERR(clk_hw)) {
                        pr_err("%s: failed to register clock %s\n", __func__,
@@ -163,7 +163,7 @@ void __init samsung_clk_register_fixed_factor(struct samsung_clk_provider *ctx,
        unsigned int idx;
 
        for (idx = 0; idx < nr_clk; idx++, list++) {
-               clk_hw = clk_hw_register_fixed_factor(NULL, list->name,
+               clk_hw = clk_hw_register_fixed_factor(ctx->dev, list->name,
                        list->parent_name, list->flags, list->mult, list->div);
                if (IS_ERR(clk_hw)) {
                        pr_err("%s: failed to register clock %s\n", __func__,
@@ -181,10 +181,10 @@ void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
                                unsigned int nr_clk)
 {
        struct clk_hw *clk_hw;
-       unsigned int idx, ret;
+       unsigned int idx;
 
        for (idx = 0; idx < nr_clk; idx++, list++) {
-               clk_hw = clk_hw_register_mux(NULL, list->name,
+               clk_hw = clk_hw_register_mux(ctx->dev, list->name,
                        list->parent_names, list->num_parents, list->flags,
                        ctx->reg_base + list->offset,
                        list->shift, list->width, list->mux_flags, &ctx->lock);
@@ -195,15 +195,6 @@ void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
                }
 
                samsung_clk_add_lookup(ctx, clk_hw, list->id);
-
-               /* register a clock lookup only if a clock alias is specified */
-               if (list->alias) {
-                       ret = clk_hw_register_clkdev(clk_hw, list->alias,
-                                               list->dev_name);
-                       if (ret)
-                               pr_err("%s: failed to register lookup %s\n",
-                                               __func__, list->alias);
-               }
        }
 }
 
@@ -213,17 +204,17 @@ void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
                                unsigned int nr_clk)
 {
        struct clk_hw *clk_hw;
-       unsigned int idx, ret;
+       unsigned int idx;
 
        for (idx = 0; idx < nr_clk; idx++, list++) {
                if (list->table)
-                       clk_hw = clk_hw_register_divider_table(NULL,
+                       clk_hw = clk_hw_register_divider_table(ctx->dev,
                                list->name, list->parent_name, list->flags,
                                ctx->reg_base + list->offset,
                                list->shift, list->width, list->div_flags,
                                list->table, &ctx->lock);
                else
-                       clk_hw = clk_hw_register_divider(NULL, list->name,
+                       clk_hw = clk_hw_register_divider(ctx->dev, list->name,
                                list->parent_name, list->flags,
                                ctx->reg_base + list->offset, list->shift,
                                list->width, list->div_flags, &ctx->lock);
@@ -234,15 +225,6 @@ void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
                }
 
                samsung_clk_add_lookup(ctx, clk_hw, list->id);
-
-               /* register a clock lookup only if a clock alias is specified */
-               if (list->alias) {
-                       ret = clk_hw_register_clkdev(clk_hw, list->alias,
-                                               list->dev_name);
-                       if (ret)
-                               pr_err("%s: failed to register lookup %s\n",
-                                               __func__, list->alias);
-               }
        }
 }
 
@@ -252,10 +234,10 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
                                unsigned int nr_clk)
 {
        struct clk_hw *clk_hw;
-       unsigned int idx, ret;
+       unsigned int idx;
 
        for (idx = 0; idx < nr_clk; idx++, list++) {
-               clk_hw = clk_hw_register_gate(NULL, list->name, list->parent_name,
+               clk_hw = clk_hw_register_gate(ctx->dev, list->name, list->parent_name,
                                list->flags, ctx->reg_base + list->offset,
                                list->bit_idx, list->gate_flags, &ctx->lock);
                if (IS_ERR(clk_hw)) {
@@ -264,15 +246,6 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
                        continue;
                }
 
-               /* register a clock lookup only if a clock alias is specified */
-               if (list->alias) {
-                       ret = clk_hw_register_clkdev(clk_hw, list->alias,
-                                                       list->dev_name);
-                       if (ret)
-                               pr_err("%s: failed to register lookup %s\n",
-                                       __func__, list->alias);
-               }
-
                samsung_clk_add_lookup(ctx, clk_hw, list->id);
        }
 }
index b8ca0dd3a38b771f2b2af998ad19cfff5e216fde..3880d2f9d5829df357f0c4b9f9639bbfd171599d 100644 (file)
@@ -24,6 +24,7 @@
  */
 struct samsung_clk_provider {
        void __iomem *reg_base;
+       struct device *dev;
        spinlock_t lock;
        /* clk_data must be the last entry due to variable lenght 'hws' array */
        struct clk_hw_onecell_data clk_data;
@@ -106,7 +107,6 @@ struct samsung_fixed_factor_clock {
 /**
  * struct samsung_mux_clock: information about mux clock
  * @id: platform specific id of the clock.
- * @dev_name: name of the device to which this clock belongs.
  * @name: name of this mux clock.
  * @parent_names: array of pointer to parent clock names.
  * @num_parents: number of parents listed in @parent_names.
@@ -115,11 +115,9 @@ struct samsung_fixed_factor_clock {
  * @shift: starting bit location of the mux control bit-field in @reg.
  * @width: width of the mux control bit-field in @reg.
  * @mux_flags: flags for mux-type clock.
- * @alias: optional clock alias name to be assigned to this clock.
  */
 struct samsung_mux_clock {
        unsigned int            id;
-       const char              *dev_name;
        const char              *name;
        const char              *const *parent_names;
        u8                      num_parents;
@@ -128,13 +126,11 @@ struct samsung_mux_clock {
        u8                      shift;
        u8                      width;
        u8                      mux_flags;
-       const char              *alias;
 };
 
-#define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a)    \
+#define __MUX(_id, cname, pnames, o, s, w, f, mf)              \
        {                                                       \
                .id             = _id,                          \
-               .dev_name       = dname,                        \
                .name           = cname,                        \
                .parent_names   = pnames,                       \
                .num_parents    = ARRAY_SIZE(pnames),           \
@@ -143,36 +139,26 @@ struct samsung_mux_clock {
                .shift          = s,                            \
                .width          = w,                            \
                .mux_flags      = mf,                           \
-               .alias          = a,                            \
        }
 
 #define MUX(_id, cname, pnames, o, s, w)                       \
-       __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL)
-
-#define MUX_A(_id, cname, pnames, o, s, w, a)                  \
-       __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a)
+       __MUX(_id, cname, pnames, o, s, w, 0, 0)
 
 #define MUX_F(_id, cname, pnames, o, s, w, f, mf)              \
-       __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL)
-
-#define MUX_FA(_id, cname, pnames, o, s, w, f, mf, a)          \
-       __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, a)
+       __MUX(_id, cname, pnames, o, s, w, f, mf)
 
 /**
  * @id: platform specific id of the clock.
  * struct samsung_div_clock: information about div clock
- * @dev_name: name of the device to which this clock belongs.
  * @name: name of this div clock.
  * @parent_name: name of the parent clock.
  * @flags: optional flags for basic clock.
  * @offset: offset of the register for configuring the div.
  * @shift: starting bit location of the div control bit-field in @reg.
  * @div_flags: flags for div-type clock.
- * @alias: optional clock alias name to be assigned to this clock.
  */
 struct samsung_div_clock {
        unsigned int            id;
-       const char              *dev_name;
        const char              *name;
        const char              *parent_name;
        unsigned long           flags;
@@ -180,14 +166,12 @@ struct samsung_div_clock {
        u8                      shift;
        u8                      width;
        u8                      div_flags;
-       const char              *alias;
        struct clk_div_table    *table;
 };
 
-#define __DIV(_id, dname, cname, pname, o, s, w, f, df, a, t)  \
+#define __DIV(_id, cname, pname, o, s, w, f, df, t)    \
        {                                                       \
                .id             = _id,                          \
-               .dev_name       = dname,                        \
                .name           = cname,                        \
                .parent_name    = pname,                        \
                .flags          = f,                            \
@@ -195,70 +179,51 @@ struct samsung_div_clock {
                .shift          = s,                            \
                .width          = w,                            \
                .div_flags      = df,                           \
-               .alias          = a,                            \
                .table          = t,                            \
        }
 
 #define DIV(_id, cname, pname, o, s, w)                                \
-       __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, NULL)
-
-#define DIV_A(_id, cname, pname, o, s, w, a)                   \
-       __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a, NULL)
+       __DIV(_id, cname, pname, o, s, w, 0, 0, NULL)
 
 #define DIV_F(_id, cname, pname, o, s, w, f, df)               \
-       __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL, NULL)
+       __DIV(_id, cname, pname, o, s, w, f, df, NULL)
 
 #define DIV_T(_id, cname, pname, o, s, w, t)                   \
-       __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, t)
+       __DIV(_id, cname, pname, o, s, w, 0, 0, t)
 
 /**
  * struct samsung_gate_clock: information about gate clock
  * @id: platform specific id of the clock.
- * @dev_name: name of the device to which this clock belongs.
  * @name: name of this gate clock.
  * @parent_name: name of the parent clock.
  * @flags: optional flags for basic clock.
  * @offset: offset of the register for configuring the gate.
  * @bit_idx: bit index of the gate control bit-field in @reg.
  * @gate_flags: flags for gate-type clock.
- * @alias: optional clock alias name to be assigned to this clock.
  */
 struct samsung_gate_clock {
        unsigned int            id;
-       const char              *dev_name;
        const char              *name;
        const char              *parent_name;
        unsigned long           flags;
        unsigned long           offset;
        u8                      bit_idx;
        u8                      gate_flags;
-       const char              *alias;
 };
 
-#define __GATE(_id, dname, cname, pname, o, b, f, gf, a)       \
+#define __GATE(_id, cname, pname, o, b, f, gf)                 \
        {                                                       \
                .id             = _id,                          \
-               .dev_name       = dname,                        \
                .name           = cname,                        \
                .parent_name    = pname,                        \
                .flags          = f,                            \
                .offset         = o,                            \
                .bit_idx        = b,                            \
                .gate_flags     = gf,                           \
-               .alias          = a,                            \
        }
 
 #define GATE(_id, cname, pname, o, b, f, gf)                   \
-       __GATE(_id, NULL, cname, pname, o, b, f, gf, NULL)
-
-#define GATE_A(_id, cname, pname, o, b, f, gf, a)              \
-       __GATE(_id, NULL, cname, pname, o, b, f, gf, a)
-
-#define GATE_D(_id, dname, cname, pname, o, b, f, gf)          \
-       __GATE(_id, dname, cname, pname, o, b, f, gf, NULL)
-
-#define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a)      \
-       __GATE(_id, dname, cname, pname, o, b, f, gf, a)
+       __GATE(_id, cname, pname, o, b, f, gf)
 
 #define PNAME(x) static const char * const x[] __initconst
 
@@ -275,18 +240,15 @@ struct samsung_clk_reg_dump {
 /**
  * struct samsung_pll_clock: information about pll clock
  * @id: platform specific id of the clock.
- * @dev_name: name of the device to which this clock belongs.
  * @name: name of this pll clock.
  * @parent_name: name of the parent clock.
  * @flags: optional flags for basic clock.
  * @con_offset: offset of the register for configuring the PLL.
  * @lock_offset: offset of the register for locking the PLL.
  * @type: Type of PLL to be registered.
- * @alias: optional clock alias name to be assigned to this clock.
  */
 struct samsung_pll_clock {
        unsigned int            id;
-       const char              *dev_name;
        const char              *name;
        const char              *parent_name;
        unsigned long           flags;
@@ -294,31 +256,23 @@ struct samsung_pll_clock {
        int                     lock_offset;
        enum samsung_pll_type   type;
        const struct samsung_pll_rate_table *rate_table;
-       const char              *alias;
 };
 
-#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con,   \
-               _rtable, _alias)                                        \
+#define __PLL(_typ, _id, _name, _pname, _flags, _lock, _con, _rtable)  \
        {                                                               \
                .id             = _id,                                  \
                .type           = _typ,                                 \
-               .dev_name       = _dname,                               \
                .name           = _name,                                \
                .parent_name    = _pname,                               \
-               .flags          = CLK_GET_RATE_NOCACHE,                 \
+               .flags          = _flags,                               \
                .con_offset     = _con,                                 \
                .lock_offset    = _lock,                                \
                .rate_table     = _rtable,                              \
-               .alias          = _alias,                               \
        }
 
 #define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable)    \
-       __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,     \
-               _lock, _con, _rtable, _name)
-
-#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias, _rtable) \
-       __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,     \
-               _lock, _con, _rtable, _alias)
+       __PLL(_typ, _id, _name, _pname, CLK_GET_RATE_NOCACHE, _lock,    \
+             _con, _rtable)
 
 struct samsung_clock_reg_cache {
        struct list_head node;
@@ -352,6 +306,12 @@ struct samsung_cmu_info {
        /* list and number of clocks registers */
        const unsigned long *clk_regs;
        unsigned int nr_clk_regs;
+
+       /* list and number of clocks registers to set before suspend */
+       const struct samsung_clk_reg_dump *suspend_regs;
+       unsigned int nr_suspend_regs;
+       /* name of the parent clock needed for CMU register access */
+       const char *clk_name;
 };
 
 extern struct samsung_clk_provider *__init samsung_clk_init(
index 665fa681b2e1e9a2ccb2f2f857d76e98c3e3da64..0cd11e6893afa282c0d9c32bb386fcae5e21e065 100644 (file)
@@ -42,7 +42,7 @@ static struct clk_dmn clk_mmc45 = {
        },
 };
 
-static struct clk_init_data clk_nand_init = {
+static const struct clk_init_data clk_nand_init = {
        .name = "nand",
        .ops = &dmn_ops,
        .parent_names = dmn_clk_parents,
index d0c6c9a2d06ae7d87cc5fe6b1d5866e33508e314..be012b4bab46263f92f0e547f673f43945060f6e 100644 (file)
@@ -392,7 +392,7 @@ static const char * const pll_clk_parents[] = {
        "xin",
 };
 
-static struct clk_init_data clk_cpupll_init = {
+static const struct clk_init_data clk_cpupll_init = {
        .name = "cpupll_vco",
        .ops = &ab_pll_ops,
        .parent_names = pll_clk_parents,
@@ -406,7 +406,7 @@ static struct clk_pll clk_cpupll = {
        },
 };
 
-static struct clk_init_data clk_mempll_init = {
+static const struct clk_init_data clk_mempll_init = {
        .name = "mempll_vco",
        .ops = &ab_pll_ops,
        .parent_names = pll_clk_parents,
@@ -420,7 +420,7 @@ static struct clk_pll clk_mempll = {
        },
 };
 
-static struct clk_init_data clk_sys0pll_init = {
+static const struct clk_init_data clk_sys0pll_init = {
        .name = "sys0pll_vco",
        .ops = &ab_pll_ops,
        .parent_names = pll_clk_parents,
@@ -434,7 +434,7 @@ static struct clk_pll clk_sys0pll = {
        },
 };
 
-static struct clk_init_data clk_sys1pll_init = {
+static const struct clk_init_data clk_sys1pll_init = {
        .name = "sys1pll_vco",
        .ops = &ab_pll_ops,
        .parent_names = pll_clk_parents,
@@ -448,7 +448,7 @@ static struct clk_pll clk_sys1pll = {
        },
 };
 
-static struct clk_init_data clk_sys2pll_init = {
+static const struct clk_init_data clk_sys2pll_init = {
        .name = "sys2pll_vco",
        .ops = &ab_pll_ops,
        .parent_names = pll_clk_parents,
@@ -462,7 +462,7 @@ static struct clk_pll clk_sys2pll = {
        },
 };
 
-static struct clk_init_data clk_sys3pll_init = {
+static const struct clk_init_data clk_sys3pll_init = {
        .name = "sys3pll_vco",
        .ops = &ab_pll_ops,
        .parent_names = pll_clk_parents,
@@ -596,7 +596,7 @@ static const char * const audiodto_clk_parents[] = {
        "sys3pll_clk1",
 };
 
-static struct clk_init_data clk_audiodto_init = {
+static const struct clk_init_data clk_audiodto_init = {
        .name = "audio_dto",
        .ops = &dto_ops,
        .parent_names = audiodto_clk_parents,
@@ -617,7 +617,7 @@ static const char * const disp0dto_clk_parents[] = {
        "sys3pll_clk1",
 };
 
-static struct clk_init_data clk_disp0dto_init = {
+static const struct clk_init_data clk_disp0dto_init = {
        .name = "disp0_dto",
        .ops = &dto_ops,
        .parent_names = disp0dto_clk_parents,
@@ -638,7 +638,7 @@ static const char * const disp1dto_clk_parents[] = {
        "sys3pll_clk1",
 };
 
-static struct clk_init_data clk_disp1dto_init = {
+static const struct clk_init_data clk_disp1dto_init = {
        .name = "disp1_dto",
        .ops = &dto_ops,
        .parent_names = disp1dto_clk_parents,
index 77e1e2491689b9c37e943c43e8fabf5778a561aa..d8f9efa5129adf4d7e9731ba1dd7967f71d9c946 100644 (file)
@@ -184,7 +184,7 @@ static unsigned long cpu_clk_recalc_rate(struct clk_hw *hw,
        return clk_hw_get_rate(parent_clk);
 }
 
-static struct clk_ops std_pll_ops = {
+static const struct clk_ops std_pll_ops = {
        .recalc_rate = pll_clk_recalc_rate,
        .round_rate = pll_clk_round_rate,
        .set_rate = pll_clk_set_rate,
@@ -194,21 +194,21 @@ static const char * const pll_clk_parents[] = {
        "osc",
 };
 
-static struct clk_init_data clk_pll1_init = {
+static const struct clk_init_data clk_pll1_init = {
        .name = "pll1",
        .ops = &std_pll_ops,
        .parent_names = pll_clk_parents,
        .num_parents = ARRAY_SIZE(pll_clk_parents),
 };
 
-static struct clk_init_data clk_pll2_init = {
+static const struct clk_init_data clk_pll2_init = {
        .name = "pll2",
        .ops = &std_pll_ops,
        .parent_names = pll_clk_parents,
        .num_parents = ARRAY_SIZE(pll_clk_parents),
 };
 
-static struct clk_init_data clk_pll3_init = {
+static const struct clk_init_data clk_pll3_init = {
        .name = "pll3",
        .ops = &std_pll_ops,
        .parent_names = pll_clk_parents,
@@ -265,13 +265,13 @@ static unsigned long usb_pll_clk_recalc_rate(struct clk_hw *hw, unsigned long pa
        return (reg & SIRFSOC_USBPHY_PLL_BYPASS) ? parent_rate : 48*MHZ;
 }
 
-static struct clk_ops usb_pll_ops = {
+static const struct clk_ops usb_pll_ops = {
        .enable = usb_pll_clk_enable,
        .disable = usb_pll_clk_disable,
        .recalc_rate = usb_pll_clk_recalc_rate,
 };
 
-static struct clk_init_data clk_usb_pll_init = {
+static const struct clk_init_data clk_usb_pll_init = {
        .name = "usb_pll",
        .ops = &usb_pll_ops,
        .parent_names = pll_clk_parents,
@@ -437,7 +437,7 @@ static int cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate,
        return ret2 ? ret2 : ret1;
 }
 
-static struct clk_ops msi_ops = {
+static const struct clk_ops msi_ops = {
        .set_rate = dmn_clk_set_rate,
        .round_rate = dmn_clk_round_rate,
        .recalc_rate = dmn_clk_recalc_rate,
@@ -445,7 +445,7 @@ static struct clk_ops msi_ops = {
        .get_parent = dmn_clk_get_parent,
 };
 
-static struct clk_init_data clk_mem_init = {
+static const struct clk_init_data clk_mem_init = {
        .name = "mem",
        .ops = &msi_ops,
        .parent_names = dmn_clk_parents,
@@ -459,7 +459,7 @@ static struct clk_dmn clk_mem = {
        },
 };
 
-static struct clk_init_data clk_sys_init = {
+static const struct clk_init_data clk_sys_init = {
        .name = "sys",
        .ops = &msi_ops,
        .parent_names = dmn_clk_parents,
@@ -474,7 +474,7 @@ static struct clk_dmn clk_sys = {
        },
 };
 
-static struct clk_init_data clk_io_init = {
+static const struct clk_init_data clk_io_init = {
        .name = "io",
        .ops = &msi_ops,
        .parent_names = dmn_clk_parents,
@@ -488,7 +488,7 @@ static struct clk_dmn clk_io = {
        },
 };
 
-static struct clk_ops cpu_ops = {
+static const struct clk_ops cpu_ops = {
        .set_parent = dmn_clk_set_parent,
        .get_parent = dmn_clk_get_parent,
        .set_rate = cpu_clk_set_rate,
@@ -496,7 +496,7 @@ static struct clk_ops cpu_ops = {
        .recalc_rate = cpu_clk_recalc_rate,
 };
 
-static struct clk_init_data clk_cpu_init = {
+static const struct clk_init_data clk_cpu_init = {
        .name = "cpu",
        .ops = &cpu_ops,
        .parent_names = dmn_clk_parents,
@@ -511,7 +511,7 @@ static struct clk_dmn clk_cpu = {
        },
 };
 
-static struct clk_ops dmn_ops = {
+static const struct clk_ops dmn_ops = {
        .is_enabled = std_clk_is_enabled,
        .enable = std_clk_enable,
        .disable = std_clk_disable,
@@ -524,7 +524,7 @@ static struct clk_ops dmn_ops = {
 
 /* dsp, gfx, mm, lcd and vpp domain */
 
-static struct clk_init_data clk_dsp_init = {
+static const struct clk_init_data clk_dsp_init = {
        .name = "dsp",
        .ops = &dmn_ops,
        .parent_names = dmn_clk_parents,
@@ -539,7 +539,7 @@ static struct clk_dmn clk_dsp = {
        },
 };
 
-static struct clk_init_data clk_gfx_init = {
+static const struct clk_init_data clk_gfx_init = {
        .name = "gfx",
        .ops = &dmn_ops,
        .parent_names = dmn_clk_parents,
@@ -554,7 +554,7 @@ static struct clk_dmn clk_gfx = {
        },
 };
 
-static struct clk_init_data clk_mm_init = {
+static const struct clk_init_data clk_mm_init = {
        .name = "mm",
        .ops = &dmn_ops,
        .parent_names = dmn_clk_parents,
@@ -574,7 +574,7 @@ static struct clk_dmn clk_mm = {
  */
 #define clk_gfx2d clk_mm
 
-static struct clk_init_data clk_lcd_init = {
+static const struct clk_init_data clk_lcd_init = {
        .name = "lcd",
        .ops = &dmn_ops,
        .parent_names = dmn_clk_parents,
@@ -589,7 +589,7 @@ static struct clk_dmn clk_lcd = {
        },
 };
 
-static struct clk_init_data clk_vpp_init = {
+static const struct clk_init_data clk_vpp_init = {
        .name = "vpp",
        .ops = &dmn_ops,
        .parent_names = dmn_clk_parents,
@@ -604,21 +604,21 @@ static struct clk_dmn clk_vpp = {
        },
 };
 
-static struct clk_init_data clk_mmc01_init = {
+static const struct clk_init_data clk_mmc01_init = {
        .name = "mmc01",
        .ops = &dmn_ops,
        .parent_names = dmn_clk_parents,
        .num_parents = ARRAY_SIZE(dmn_clk_parents),
 };
 
-static struct clk_init_data clk_mmc23_init = {
+static const struct clk_init_data clk_mmc23_init = {
        .name = "mmc23",
        .ops = &dmn_ops,
        .parent_names = dmn_clk_parents,
        .num_parents = ARRAY_SIZE(dmn_clk_parents),
 };
 
-static struct clk_init_data clk_mmc45_init = {
+static const struct clk_init_data clk_mmc45_init = {
        .name = "mmc45",
        .ops = &dmn_ops,
        .parent_names = dmn_clk_parents,
@@ -679,13 +679,13 @@ static const char * const std_clk_io_parents[] = {
        "io",
 };
 
-static struct clk_ops ios_ops = {
+static const struct clk_ops ios_ops = {
        .is_enabled = std_clk_is_enabled,
        .enable = std_clk_enable,
        .disable = std_clk_disable,
 };
 
-static struct clk_init_data clk_cphif_init = {
+static const struct clk_init_data clk_cphif_init = {
        .name = "cphif",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -699,7 +699,7 @@ static struct clk_std clk_cphif = {
        },
 };
 
-static struct clk_init_data clk_dmac0_init = {
+static const struct clk_init_data clk_dmac0_init = {
        .name = "dmac0",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -713,7 +713,7 @@ static struct clk_std clk_dmac0 = {
        },
 };
 
-static struct clk_init_data clk_dmac1_init = {
+static const struct clk_init_data clk_dmac1_init = {
        .name = "dmac1",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -727,7 +727,7 @@ static struct clk_std clk_dmac1 = {
        },
 };
 
-static struct clk_init_data clk_audio_init = {
+static const struct clk_init_data clk_audio_init = {
        .name = "audio",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -741,7 +741,7 @@ static struct clk_std clk_audio = {
        },
 };
 
-static struct clk_init_data clk_uart0_init = {
+static const struct clk_init_data clk_uart0_init = {
        .name = "uart0",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -755,7 +755,7 @@ static struct clk_std clk_uart0 = {
        },
 };
 
-static struct clk_init_data clk_uart1_init = {
+static const struct clk_init_data clk_uart1_init = {
        .name = "uart1",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -769,7 +769,7 @@ static struct clk_std clk_uart1 = {
        },
 };
 
-static struct clk_init_data clk_uart2_init = {
+static const struct clk_init_data clk_uart2_init = {
        .name = "uart2",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -783,7 +783,7 @@ static struct clk_std clk_uart2 = {
        },
 };
 
-static struct clk_init_data clk_usp0_init = {
+static const struct clk_init_data clk_usp0_init = {
        .name = "usp0",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -797,7 +797,7 @@ static struct clk_std clk_usp0 = {
        },
 };
 
-static struct clk_init_data clk_usp1_init = {
+static const struct clk_init_data clk_usp1_init = {
        .name = "usp1",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -811,7 +811,7 @@ static struct clk_std clk_usp1 = {
        },
 };
 
-static struct clk_init_data clk_usp2_init = {
+static const struct clk_init_data clk_usp2_init = {
        .name = "usp2",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -825,7 +825,7 @@ static struct clk_std clk_usp2 = {
        },
 };
 
-static struct clk_init_data clk_vip_init = {
+static const struct clk_init_data clk_vip_init = {
        .name = "vip",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -839,7 +839,7 @@ static struct clk_std clk_vip = {
        },
 };
 
-static struct clk_init_data clk_spi0_init = {
+static const struct clk_init_data clk_spi0_init = {
        .name = "spi0",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -853,7 +853,7 @@ static struct clk_std clk_spi0 = {
        },
 };
 
-static struct clk_init_data clk_spi1_init = {
+static const struct clk_init_data clk_spi1_init = {
        .name = "spi1",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -867,7 +867,7 @@ static struct clk_std clk_spi1 = {
        },
 };
 
-static struct clk_init_data clk_tsc_init = {
+static const struct clk_init_data clk_tsc_init = {
        .name = "tsc",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -881,7 +881,7 @@ static struct clk_std clk_tsc = {
        },
 };
 
-static struct clk_init_data clk_i2c0_init = {
+static const struct clk_init_data clk_i2c0_init = {
        .name = "i2c0",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -895,7 +895,7 @@ static struct clk_std clk_i2c0 = {
        },
 };
 
-static struct clk_init_data clk_i2c1_init = {
+static const struct clk_init_data clk_i2c1_init = {
        .name = "i2c1",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -909,7 +909,7 @@ static struct clk_std clk_i2c1 = {
        },
 };
 
-static struct clk_init_data clk_pwmc_init = {
+static const struct clk_init_data clk_pwmc_init = {
        .name = "pwmc",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -923,7 +923,7 @@ static struct clk_std clk_pwmc = {
        },
 };
 
-static struct clk_init_data clk_efuse_init = {
+static const struct clk_init_data clk_efuse_init = {
        .name = "efuse",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -937,7 +937,7 @@ static struct clk_std clk_efuse = {
        },
 };
 
-static struct clk_init_data clk_pulse_init = {
+static const struct clk_init_data clk_pulse_init = {
        .name = "pulse",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -955,7 +955,7 @@ static const char * const std_clk_dsp_parents[] = {
        "dsp",
 };
 
-static struct clk_init_data clk_gps_init = {
+static const struct clk_init_data clk_gps_init = {
        .name = "gps",
        .ops = &ios_ops,
        .parent_names = std_clk_dsp_parents,
@@ -969,7 +969,7 @@ static struct clk_std clk_gps = {
        },
 };
 
-static struct clk_init_data clk_mf_init = {
+static const struct clk_init_data clk_mf_init = {
        .name = "mf",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
@@ -987,7 +987,7 @@ static const char * const std_clk_sys_parents[] = {
        "sys",
 };
 
-static struct clk_init_data clk_security_init = {
+static const struct clk_init_data clk_security_init = {
        .name = "security",
        .ops = &ios_ops,
        .parent_names = std_clk_sys_parents,
@@ -1005,7 +1005,7 @@ static const char * const std_clk_usb_parents[] = {
        "usb_pll",
 };
 
-static struct clk_init_data clk_usb0_init = {
+static const struct clk_init_data clk_usb0_init = {
        .name = "usb0",
        .ops = &ios_ops,
        .parent_names = std_clk_usb_parents,
@@ -1019,7 +1019,7 @@ static struct clk_std clk_usb0 = {
        },
 };
 
-static struct clk_init_data clk_usb1_init = {
+static const struct clk_init_data clk_usb1_init = {
        .name = "usb1",
        .ops = &ios_ops,
        .parent_names = std_clk_usb_parents,
index aac1c8ec151a9aff5a962e447aeb46bf680f269b..2f824320c3180c869d5584edace0ab029d36bba5 100644 (file)
@@ -42,7 +42,7 @@ static struct clk_dmn clk_mmc45 = {
        },
 };
 
-static struct clk_init_data clk_nand_init = {
+static const struct clk_init_data clk_nand_init = {
        .name = "nand",
        .ops = &ios_ops,
        .parent_names = std_clk_io_parents,
index f271c350ef9404838fcaa6502db28cd1db5a744c..906410413bc149d7e33e361fbb9874ed473d1bdc 100644 (file)
@@ -29,7 +29,7 @@
 
 #define to_clk_aux(_hw) container_of(_hw, struct clk_aux, hw)
 
-static struct aux_clk_masks default_aux_masks = {
+static const  struct aux_clk_masks default_aux_masks = {
        .eq_sel_mask = AUX_EQ_SEL_MASK,
        .eq_sel_shift = AUX_EQ_SEL_SHIFT,
        .eq1_mask = AUX_EQ1_SEL,
@@ -128,7 +128,7 @@ static int clk_aux_set_rate(struct clk_hw *hw, unsigned long drate,
        return 0;
 }
 
-static struct clk_ops clk_aux_ops = {
+static const struct clk_ops clk_aux_ops = {
        .recalc_rate = clk_aux_recalc_rate,
        .round_rate = clk_aux_round_rate,
        .set_rate = clk_aux_set_rate,
@@ -136,7 +136,7 @@ static struct clk_ops clk_aux_ops = {
 
 struct clk *clk_register_aux(const char *aux_name, const char *gate_name,
                const char *parent_name, unsigned long flags, void __iomem *reg,
-               struct aux_clk_masks *masks, struct aux_rate_tbl *rtbl,
+               const struct aux_clk_masks *masks, struct aux_rate_tbl *rtbl,
                u8 rtbl_cnt, spinlock_t *lock, struct clk **gate_clk)
 {
        struct clk_aux *aux;
@@ -149,10 +149,8 @@ struct clk *clk_register_aux(const char *aux_name, const char *gate_name,
        }
 
        aux = kzalloc(sizeof(*aux), GFP_KERNEL);
-       if (!aux) {
-               pr_err("could not allocate aux clk\n");
+       if (!aux)
                return ERR_PTR(-ENOMEM);
-       }
 
        /* struct clk_aux assignments */
        if (!masks)
index 58d678b5b40a76c6e426b41ed957e044197b2ae8..229c96daece62d311f03cc86b91f75ffa391b6ca 100644 (file)
@@ -116,7 +116,7 @@ static int clk_frac_set_rate(struct clk_hw *hw, unsigned long drate,
        return 0;
 }
 
-static struct clk_ops clk_frac_ops = {
+static const struct clk_ops clk_frac_ops = {
        .recalc_rate = clk_frac_recalc_rate,
        .round_rate = clk_frac_round_rate,
        .set_rate = clk_frac_set_rate,
@@ -136,10 +136,8 @@ struct clk *clk_register_frac(const char *name, const char *parent_name,
        }
 
        frac = kzalloc(sizeof(*frac), GFP_KERNEL);
-       if (!frac) {
-               pr_err("could not allocate frac clk\n");
+       if (!frac)
                return ERR_PTR(-ENOMEM);
-       }
 
        /* struct clk_frac assignments */
        frac->reg = reg;
index 1a722e99e76e949352ab03120440ec3e312c365d..28262f4225628742db10ec13de492b87cc0171bf 100644 (file)
@@ -105,7 +105,7 @@ static int clk_gpt_set_rate(struct clk_hw *hw, unsigned long drate,
        return 0;
 }
 
-static struct clk_ops clk_gpt_ops = {
+static const struct clk_ops clk_gpt_ops = {
        .recalc_rate = clk_gpt_recalc_rate,
        .round_rate = clk_gpt_round_rate,
        .set_rate = clk_gpt_set_rate,
@@ -125,10 +125,8 @@ struct clk *clk_register_gpt(const char *name, const char *parent_name, unsigned
        }
 
        gpt = kzalloc(sizeof(*gpt), GFP_KERNEL);
-       if (!gpt) {
-               pr_err("could not allocate gpt clk\n");
+       if (!gpt)
                return ERR_PTR(-ENOMEM);
-       }
 
        /* struct clk_gpt assignments */
        gpt->reg = reg;
index dc21ca4601aab28ce2eba866e2d00e0e33f9dbe1..c08dec30bfa629dd5599822f74f0054be114b0e4 100644 (file)
@@ -165,7 +165,7 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long drate,
        return 0;
 }
 
-static struct clk_ops clk_pll_ops = {
+static const struct clk_ops clk_pll_ops = {
        .recalc_rate = clk_pll_recalc_rate,
        .round_rate = clk_pll_round_rate,
        .set_rate = clk_pll_set_rate,
@@ -266,7 +266,7 @@ static int clk_vco_set_rate(struct clk_hw *hw, unsigned long drate,
        return 0;
 }
 
-static struct clk_ops clk_vco_ops = {
+static const struct clk_ops clk_vco_ops = {
        .recalc_rate = clk_vco_recalc_rate,
        .round_rate = clk_vco_round_rate,
        .set_rate = clk_vco_set_rate,
@@ -292,16 +292,12 @@ struct clk *clk_register_vco_pll(const char *vco_name, const char *pll_name,
        }
 
        vco = kzalloc(sizeof(*vco), GFP_KERNEL);
-       if (!vco) {
-               pr_err("could not allocate vco clk\n");
+       if (!vco)
                return ERR_PTR(-ENOMEM);
-       }
 
        pll = kzalloc(sizeof(*pll), GFP_KERNEL);
-       if (!pll) {
-               pr_err("could not allocate pll clk\n");
+       if (!pll)
                goto free_vco;
-       }
 
        /* struct clk_vco assignments */
        vco->mode_reg = mode_reg;
index 9834944f08b1dafff2a24835a5b1e57b010e3e4a..af0e25f496c1a112ac3dc89d9f3b8e14aea3fd32 100644 (file)
@@ -49,7 +49,7 @@ struct aux_rate_tbl {
 struct clk_aux {
        struct                  clk_hw hw;
        void __iomem            *reg;
-       struct aux_clk_masks    *masks;
+       const struct aux_clk_masks *masks;
        struct aux_rate_tbl     *rtbl;
        u8                      rtbl_cnt;
        spinlock_t              *lock;
@@ -112,7 +112,7 @@ typedef unsigned long (*clk_calc_rate)(struct clk_hw *hw, unsigned long prate,
 /* clk register routines */
 struct clk *clk_register_aux(const char *aux_name, const char *gate_name,
                const char *parent_name, unsigned long flags, void __iomem *reg,
-               struct aux_clk_masks *masks, struct aux_rate_tbl *rtbl,
+               const struct aux_clk_masks *masks, struct aux_rate_tbl *rtbl,
                u8 rtbl_cnt, spinlock_t *lock, struct clk **gate_clk);
 struct clk *clk_register_frac(const char *name, const char *parent_name,
                unsigned long flags, void __iomem *reg,
index 2f86e3f94efa6f2fe306fbbecd581bd70e4b392e..591248c9a88e797295a712abcb9b26b6d00a95e9 100644 (file)
@@ -284,7 +284,7 @@ static struct frac_rate_tbl clcd_rtbl[] = {
 };
 
 /* i2s prescaler1 masks */
-static struct aux_clk_masks i2s_prs1_masks = {
+static const struct aux_clk_masks i2s_prs1_masks = {
        .eq_sel_mask = AUX_EQ_SEL_MASK,
        .eq_sel_shift = SPEAR1310_I2S_PRS1_EQ_SEL_SHIFT,
        .eq1_mask = AUX_EQ1_SEL,
index cbb19a90f2d614569f48ad7ffec1c287714e5810..e5bc8c828cf0d84a420fd087ae726d961f5f05c2 100644 (file)
@@ -323,7 +323,7 @@ static struct frac_rate_tbl clcd_rtbl[] = {
 };
 
 /* i2s prescaler1 masks */
-static struct aux_clk_masks i2s_prs1_masks = {
+static const struct aux_clk_masks i2s_prs1_masks = {
        .eq_sel_mask = AUX_EQ_SEL_MASK,
        .eq_sel_shift = SPEAR1340_I2S_PRS1_EQ_SEL_SHIFT,
        .eq1_mask = AUX_EQ1_SEL,
index d1c2fa93ddd9bcf782829245545c35db05cfd06d..4141c3fe08ae1eaccb3ca77d4d1989649c3ac718 100644 (file)
@@ -11,6 +11,7 @@ lib-$(CONFIG_SUNXI_CCU)               += ccu_gate.o
 lib-$(CONFIG_SUNXI_CCU)                += ccu_mux.o
 lib-$(CONFIG_SUNXI_CCU)                += ccu_mult.o
 lib-$(CONFIG_SUNXI_CCU)                += ccu_phase.o
+lib-$(CONFIG_SUNXI_CCU)                += ccu_sdm.o
 
 # Multi-factor clocks
 lib-$(CONFIG_SUNXI_CCU)                += ccu_nk.o
index 286b0049b7b604e461c8c2d1c85b13addf161686..ffa5dac221e471f95cf4c16dd4c6cb759eb6872a 100644 (file)
@@ -28,6 +28,7 @@
 #include "ccu_nkmp.h"
 #include "ccu_nm.h"
 #include "ccu_phase.h"
+#include "ccu_sdm.h"
 
 #include "ccu-sun4i-a10.h"
 
@@ -51,16 +52,29 @@ static struct ccu_nkmp pll_core_clk = {
  * the base (2x, 4x and 8x), and one variable divider (the one true
  * pll audio).
  *
- * We don't have any need for the variable divider for now, so we just
- * hardcode it to match with the clock names.
+ * With sigma-delta modulation for fractional-N on the audio PLL,
+ * we have to use specific dividers. This means the variable divider
+ * can no longer be used, as the audio codec requests the exact clock
+ * rates we support through this mechanism. So we now hard code the
+ * variable divider to 1. This means the clock rates will no longer
+ * match the clock names.
  */
 #define SUN4I_PLL_AUDIO_REG    0x008
+
+static struct ccu_sdm_setting pll_audio_sdm_table[] = {
+       { .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
+       { .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
+};
+
 static struct ccu_nm pll_audio_base_clk = {
        .enable         = BIT(31),
        .n              = _SUNXI_CCU_MULT_OFFSET(8, 7, 0),
        .m              = _SUNXI_CCU_DIV_OFFSET(0, 5, 0),
+       .sdm            = _SUNXI_CCU_SDM(pll_audio_sdm_table, 0,
+                                        0x00c, BIT(31)),
        .common         = {
                .reg            = 0x008,
+               .features       = CCU_FEATURE_SIGMA_DELTA_MOD,
                .hw.init        = CLK_HW_INIT("pll-audio-base",
                                              "hosc",
                                              &ccu_nm_ops,
@@ -223,7 +237,7 @@ static struct ccu_mux cpu_clk = {
                .hw.init        = CLK_HW_INIT_PARENTS("cpu",
                                                      cpu_parents,
                                                      &ccu_mux_ops,
-                                                     CLK_IS_CRITICAL),
+                                                     CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
        }
 };
 
@@ -1021,9 +1035,9 @@ static struct ccu_common *sun4i_sun7i_ccu_clks[] = {
        &out_b_clk.common
 };
 
-/* Post-divider for pll-audio is hardcoded to 4 */
+/* Post-divider for pll-audio is hardcoded to 1 */
 static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
-                       "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
+                       "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
 static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
                        "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
 static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
@@ -1420,10 +1434,10 @@ static void __init sun4i_ccu_init(struct device_node *node,
                return;
        }
 
-       /* Force the PLL-Audio-1x divider to 4 */
+       /* Force the PLL-Audio-1x divider to 1 */
        val = readl(reg + SUN4I_PLL_AUDIO_REG);
        val &= ~GENMASK(29, 26);
-       writel(val | (4 << 26), reg + SUN4I_PLL_AUDIO_REG);
+       writel(val | (1 << 26), reg + SUN4I_PLL_AUDIO_REG);
 
        /*
         * Use the peripheral PLL6 as the AHB parent, instead of CPU /
index c5947c7c050e79bd7123769b6aa75840aaabbaf2..23c908ad509fd80029bc8fe722e4f808a810c77d 100644 (file)
@@ -29,7 +29,7 @@
 #define CLK_PLL_AUDIO_4X       6
 #define CLK_PLL_AUDIO_8X       7
 #define CLK_PLL_VIDEO0         8
-#define CLK_PLL_VIDEO0_2X      9
+/* The PLL_VIDEO0_2X clock is exported */
 #define CLK_PLL_VE             10
 #define CLK_PLL_DDR_BASE       11
 #define CLK_PLL_DDR            12
@@ -38,7 +38,7 @@
 #define CLK_PLL_PERIPH         15
 #define CLK_PLL_PERIPH_SATA    16
 #define CLK_PLL_VIDEO1         17
-#define CLK_PLL_VIDEO1_2X      18
+/* The PLL_VIDEO1_2X clock is exported */
 #define CLK_PLL_GPU            19
 
 /* The CPU clock is exported */
index ab9e850b370783259cde6b5aa7fa0b9cb05c6daa..fa2c2dd771021b05ff7782bd514d108b23078d1d 100644 (file)
@@ -26,6 +26,7 @@
 #include "ccu_nkmp.h"
 #include "ccu_nm.h"
 #include "ccu_phase.h"
+#include "ccu_sdm.h"
 
 #include "ccu-sun5i.h"
 
@@ -49,11 +50,20 @@ static struct ccu_nkmp pll_core_clk = {
  * the base (2x, 4x and 8x), and one variable divider (the one true
  * pll audio).
  *
- * We don't have any need for the variable divider for now, so we just
- * hardcode it to match with the clock names
+ * With sigma-delta modulation for fractional-N on the audio PLL,
+ * we have to use specific dividers. This means the variable divider
+ * can no longer be used, as the audio codec requests the exact clock
+ * rates we support through this mechanism. So we now hard code the
+ * variable divider to 1. This means the clock rates will no longer
+ * match the clock names.
  */
 #define SUN5I_PLL_AUDIO_REG    0x008
 
+static struct ccu_sdm_setting pll_audio_sdm_table[] = {
+       { .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
+       { .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
+};
+
 static struct ccu_nm pll_audio_base_clk = {
        .enable         = BIT(31),
        .n              = _SUNXI_CCU_MULT_OFFSET(8, 7, 0),
@@ -63,8 +73,11 @@ static struct ccu_nm pll_audio_base_clk = {
         * offset
         */
        .m              = _SUNXI_CCU_DIV_OFFSET(0, 5, 0),
+       .sdm            = _SUNXI_CCU_SDM(pll_audio_sdm_table, 0,
+                                        0x00c, BIT(31)),
        .common         = {
                .reg            = 0x008,
+               .features       = CCU_FEATURE_SIGMA_DELTA_MOD,
                .hw.init        = CLK_HW_INIT("pll-audio-base",
                                              "hosc",
                                              &ccu_nm_ops,
@@ -597,9 +610,9 @@ static struct ccu_common *sun5i_a10s_ccu_clks[] = {
        &iep_clk.common,
 };
 
-/* We hardcode the divider to 4 for now */
+/* We hardcode the divider to 1 for now */
 static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
-                       "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
+                       "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
 static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
                        "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
 static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
@@ -980,10 +993,10 @@ static void __init sun5i_ccu_init(struct device_node *node,
                return;
        }
 
-       /* Force the PLL-Audio-1x divider to 4 */
+       /* Force the PLL-Audio-1x divider to 1 */
        val = readl(reg + SUN5I_PLL_AUDIO_REG);
-       val &= ~GENMASK(19, 16);
-       writel(val | (3 << 16), reg + SUN5I_PLL_AUDIO_REG);
+       val &= ~GENMASK(29, 26);
+       writel(val | (0 << 26), reg + SUN5I_PLL_AUDIO_REG);
 
        /*
         * Use the peripheral PLL as the AHB parent, instead of CPU /
index 8af434815fba9f284154c92aa7dc55e26ec96981..72b16ed1012b1e78e272b0ca06fee32a8a49aed0 100644 (file)
@@ -31,6 +31,7 @@
 #include "ccu_nkmp.h"
 #include "ccu_nm.h"
 #include "ccu_phase.h"
+#include "ccu_sdm.h"
 
 #include "ccu-sun6i-a31.h"
 
@@ -48,18 +49,29 @@ static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_cpu_clk, "pll-cpu",
  * the base (2x, 4x and 8x), and one variable divider (the one true
  * pll audio).
  *
- * We don't have any need for the variable divider for now, so we just
- * hardcode it to match with the clock names
+ * With sigma-delta modulation for fractional-N on the audio PLL,
+ * we have to use specific dividers. This means the variable divider
+ * can no longer be used, as the audio codec requests the exact clock
+ * rates we support through this mechanism. So we now hard code the
+ * variable divider to 1. This means the clock rates will no longer
+ * match the clock names.
  */
 #define SUN6I_A31_PLL_AUDIO_REG        0x008
 
-static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
-                                  "osc24M", 0x008,
-                                  8, 7,        /* N */
-                                  0, 5,        /* M */
-                                  BIT(31),     /* gate */
-                                  BIT(28),     /* lock */
-                                  CLK_SET_RATE_UNGATE);
+static struct ccu_sdm_setting pll_audio_sdm_table[] = {
+       { .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
+       { .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
+};
+
+static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
+                                      "osc24M", 0x008,
+                                      8, 7,    /* N */
+                                      0, 5,    /* M */
+                                      pll_audio_sdm_table, BIT(24),
+                                      0x284, BIT(31),
+                                      BIT(31), /* gate */
+                                      BIT(28), /* lock */
+                                      CLK_SET_RATE_UNGATE);
 
 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0",
                                        "osc24M", 0x010,
@@ -608,7 +620,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", lcd_ch1_parents,
                                 0x150, 0, 4, 24, 2, BIT(31),
                                 CLK_SET_RATE_PARENT);
 
-static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x150, BIT(30), 0);
+static SUNXI_CCU_GATE(hdmi_ddc_clk, "ddc", "osc24M", 0x150, BIT(30), 0);
 
 static SUNXI_CCU_GATE(ps_clk, "ps", "lcd1-ch1", 0x140, BIT(31), 0);
 
@@ -950,9 +962,9 @@ static struct ccu_common *sun6i_a31_ccu_clks[] = {
        &out_c_clk.common,
 };
 
-/* We hardcode the divider to 4 for now */
+/* We hardcode the divider to 1 for now */
 static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
-                       "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
+                       "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
 static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
                        "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
 static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
@@ -1221,10 +1233,10 @@ static void __init sun6i_a31_ccu_setup(struct device_node *node)
                return;
        }
 
-       /* Force the PLL-Audio-1x divider to 4 */
+       /* Force the PLL-Audio-1x divider to 1 */
        val = readl(reg + SUN6I_A31_PLL_AUDIO_REG);
        val &= ~GENMASK(19, 16);
-       writel(val | (3 << 16), reg + SUN6I_A31_PLL_AUDIO_REG);
+       writel(val | (0 << 16), reg + SUN6I_A31_PLL_AUDIO_REG);
 
        /* Force PLL-MIPI to MIPI mode */
        val = readl(reg + SUN6I_A31_PLL_MIPI_REG);
index 4e434011e9e795e390641b38be3a262151ae1ebf..27e6ad4133ab462df78ee1c5d36c41a1d536b753 100644 (file)
@@ -27,7 +27,9 @@
 #define CLK_PLL_AUDIO_4X       4
 #define CLK_PLL_AUDIO_8X       5
 #define CLK_PLL_VIDEO0         6
-#define CLK_PLL_VIDEO0_2X      7
+
+/* The PLL_VIDEO0_2X clock is exported */
+
 #define CLK_PLL_VE             8
 #define CLK_PLL_DDR            9
 
@@ -35,7 +37,9 @@
 
 #define CLK_PLL_PERIPH_2X      11
 #define CLK_PLL_VIDEO1         12
-#define CLK_PLL_VIDEO1_2X      13
+
+/* The PLL_VIDEO1_2X clock is exported */
+
 #define CLK_PLL_GPU            14
 #define CLK_PLL_MIPI           15
 #define CLK_PLL9               16
index d93b452f0df9752aa348323821a5de0e20cd51c3..a4fa2945f2302e8f3a41632b456db28018e0069b 100644 (file)
@@ -26,6 +26,7 @@
 #include "ccu_nkmp.h"
 #include "ccu_nm.h"
 #include "ccu_phase.h"
+#include "ccu_sdm.h"
 
 #include "ccu-sun8i-a23-a33.h"
 
@@ -52,18 +53,29 @@ static struct ccu_nkmp pll_cpux_clk = {
  * the base (2x, 4x and 8x), and one variable divider (the one true
  * pll audio).
  *
- * We don't have any need for the variable divider for now, so we just
- * hardcode it to match with the clock names
+ * With sigma-delta modulation for fractional-N on the audio PLL,
+ * we have to use specific dividers. This means the variable divider
+ * can no longer be used, as the audio codec requests the exact clock
+ * rates we support through this mechanism. So we now hard code the
+ * variable divider to 1. This means the clock rates will no longer
+ * match the clock names.
  */
 #define SUN8I_A23_PLL_AUDIO_REG        0x008
 
-static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
-                                  "osc24M", 0x008,
-                                  8, 7,                /* N */
-                                  0, 5,                /* M */
-                                  BIT(31),             /* gate */
-                                  BIT(28),             /* lock */
-                                  CLK_SET_RATE_UNGATE);
+static struct ccu_sdm_setting pll_audio_sdm_table[] = {
+       { .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
+       { .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
+};
+
+static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
+                                      "osc24M", 0x008,
+                                      8, 7,    /* N */
+                                      0, 5,    /* M */
+                                      pll_audio_sdm_table, BIT(24),
+                                      0x284, BIT(31),
+                                      BIT(31), /* gate */
+                                      BIT(28), /* lock */
+                                      CLK_SET_RATE_UNGATE);
 
 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
                                        "osc24M", 0x010,
@@ -538,9 +550,9 @@ static struct ccu_common *sun8i_a23_ccu_clks[] = {
        &ats_clk.common,
 };
 
-/* We hardcode the divider to 4 for now */
+/* We hardcode the divider to 1 for now */
 static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
-                       "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
+                       "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
 static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
                        "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
 static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
@@ -720,10 +732,10 @@ static void __init sun8i_a23_ccu_setup(struct device_node *node)
                return;
        }
 
-       /* Force the PLL-Audio-1x divider to 4 */
+       /* Force the PLL-Audio-1x divider to 1 */
        val = readl(reg + SUN8I_A23_PLL_AUDIO_REG);
        val &= ~GENMASK(19, 16);
-       writel(val | (3 << 16), reg + SUN8I_A23_PLL_AUDIO_REG);
+       writel(val | (0 << 16), reg + SUN8I_A23_PLL_AUDIO_REG);
 
        /* Force PLL-MIPI to MIPI mode */
        val = readl(reg + SUN8I_A23_PLL_MIPI_REG);
index e43acebdfbcdbe98d67009e4a98ae0619181018a..5cedcd0d8be8d49874a17500fda495a393dabda5 100644 (file)
@@ -354,9 +354,9 @@ static SUNXI_CCU_GATE(bus_tdm_clk,  "bus-tdm",      "apb1",
 static SUNXI_CCU_GATE(bus_i2c0_clk,    "bus-i2c0",     "apb2",
                      0x06c, BIT(0), 0);
 static SUNXI_CCU_GATE(bus_i2c1_clk,    "bus-i2c1",     "apb2",
-                     0x06c, BIT(0), 0);
+                     0x06c, BIT(1), 0);
 static SUNXI_CCU_GATE(bus_i2c2_clk,    "bus-i2c2",     "apb2",
-                     0x06c, BIT(0), 0);
+                     0x06c, BIT(2), 0);
 static SUNXI_CCU_GATE(bus_uart0_clk,   "bus-uart0",    "apb2",
                      0x06c, BIT(16), 0);
 static SUNXI_CCU_GATE(bus_uart1_clk,   "bus-uart1",    "apb2",
@@ -506,7 +506,7 @@ static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk",
                                       csi_mclk_parents, csi_mclk_table,
                                       0x134,
                                       0, 5,    /* M */
-                                      10, 3,   /* mux */
+                                      8, 3,    /* mux */
                                       BIT(15), /* gate */
                                       0);
 
index 5cdaf52669e443de01829f699bd72231db6bbf05..5cc9d9952121308767c2eea7b1365efcd3a27f1d 100644 (file)
@@ -41,11 +41,16 @@ static SUNXI_CCU_GATE(wb_clk,               "wb",           "wb-div",
 
 static SUNXI_CCU_M(mixer0_div_clk, "mixer0-div", "de", 0x0c, 0, 4,
                   CLK_SET_RATE_PARENT);
-static SUNXI_CCU_M(mixer1_div_clk, "mixer1-div", "de", 0x0c, 4, 4,
-                  CLK_SET_RATE_PARENT);
 static SUNXI_CCU_M(wb_div_clk, "wb-div", "de", 0x0c, 8, 4,
                   CLK_SET_RATE_PARENT);
 
+static SUNXI_CCU_M(mixer0_div_a83_clk, "mixer0-div", "pll-de", 0x0c, 0, 4,
+                  CLK_SET_RATE_PARENT);
+static SUNXI_CCU_M(mixer1_div_a83_clk, "mixer1-div", "pll-de", 0x0c, 4, 4,
+                  CLK_SET_RATE_PARENT);
+static SUNXI_CCU_M(wb_div_a83_clk, "wb-div", "pll-de", 0x0c, 8, 4,
+                  CLK_SET_RATE_PARENT);
+
 static struct ccu_common *sun8i_a83t_de2_clks[] = {
        &mixer0_clk.common,
        &mixer1_clk.common,
@@ -55,9 +60,9 @@ static struct ccu_common *sun8i_a83t_de2_clks[] = {
        &bus_mixer1_clk.common,
        &bus_wb_clk.common,
 
-       &mixer0_div_clk.common,
-       &mixer1_div_clk.common,
-       &wb_div_clk.common,
+       &mixer0_div_a83_clk.common,
+       &mixer1_div_a83_clk.common,
+       &wb_div_a83_clk.common,
 };
 
 static struct ccu_common *sun8i_v3s_de2_clks[] = {
@@ -81,9 +86,9 @@ static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = {
                [CLK_BUS_MIXER1]        = &bus_mixer1_clk.common.hw,
                [CLK_BUS_WB]            = &bus_wb_clk.common.hw,
 
-               [CLK_MIXER0_DIV]        = &mixer0_div_clk.common.hw,
-               [CLK_MIXER1_DIV]        = &mixer1_div_clk.common.hw,
-               [CLK_WB_DIV]            = &wb_div_clk.common.hw,
+               [CLK_MIXER0_DIV]        = &mixer0_div_a83_clk.common.hw,
+               [CLK_MIXER1_DIV]        = &mixer1_div_a83_clk.common.hw,
+               [CLK_WB_DIV]            = &wb_div_a83_clk.common.hw,
        },
        .num    = CLK_NUMBER,
 };
index 1729ff6a5aaed90fdd9749b2030c92b4d5616619..29bc0566b776e7444f8a07c9a8660073a1ddadb8 100644 (file)
@@ -26,6 +26,7 @@
 #include "ccu_nkmp.h"
 #include "ccu_nm.h"
 #include "ccu_phase.h"
+#include "ccu_sdm.h"
 
 #include "ccu-sun8i-h3.h"
 
@@ -37,25 +38,36 @@ static SUNXI_CCU_NKMP_WITH_GATE_LOCK(pll_cpux_clk, "pll-cpux",
                                     16, 2,     /* P */
                                     BIT(31),   /* gate */
                                     BIT(28),   /* lock */
-                                    0);
+                                    CLK_SET_RATE_UNGATE);
 
 /*
  * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
  * the base (2x, 4x and 8x), and one variable divider (the one true
  * pll audio).
  *
- * We don't have any need for the variable divider for now, so we just
- * hardcode it to match with the clock names
+ * With sigma-delta modulation for fractional-N on the audio PLL,
+ * we have to use specific dividers. This means the variable divider
+ * can no longer be used, as the audio codec requests the exact clock
+ * rates we support through this mechanism. So we now hard code the
+ * variable divider to 1. This means the clock rates will no longer
+ * match the clock names.
  */
 #define SUN8I_H3_PLL_AUDIO_REG 0x008
 
-static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
-                                  "osc24M", 0x008,
-                                  8, 7,        /* N */
-                                  0, 5,        /* M */
-                                  BIT(31),     /* gate */
-                                  BIT(28),     /* lock */
-                                  0);
+static struct ccu_sdm_setting pll_audio_sdm_table[] = {
+       { .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
+       { .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
+};
+
+static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
+                                      "osc24M", 0x008,
+                                      8, 7,    /* N */
+                                      0, 5,    /* M */
+                                      pll_audio_sdm_table, BIT(24),
+                                      0x284, BIT(31),
+                                      BIT(31), /* gate */
+                                      BIT(28), /* lock */
+                                      CLK_SET_RATE_UNGATE);
 
 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
                                        "osc24M", 0x0010,
@@ -67,7 +79,7 @@ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
                                        297000000,      /* frac rate 1 */
                                        BIT(31),        /* gate */
                                        BIT(28),        /* lock */
-                                       0);
+                                       CLK_SET_RATE_UNGATE);
 
 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
                                        "osc24M", 0x0018,
@@ -79,7 +91,7 @@ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
                                        297000000,      /* frac rate 1 */
                                        BIT(31),        /* gate */
                                        BIT(28),        /* lock */
-                                       0);
+                                       CLK_SET_RATE_UNGATE);
 
 static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr",
                                    "osc24M", 0x020,
@@ -88,7 +100,7 @@ static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr",
                                    0, 2,       /* M */
                                    BIT(31),    /* gate */
                                    BIT(28),    /* lock */
-                                   0);
+                                   CLK_SET_RATE_UNGATE);
 
 static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph0_clk, "pll-periph0",
                                           "osc24M", 0x028,
@@ -97,7 +109,7 @@ static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph0_clk, "pll-periph0",
                                           BIT(31),     /* gate */
                                           BIT(28),     /* lock */
                                           2,           /* post-div */
-                                          0);
+                                          CLK_SET_RATE_UNGATE);
 
 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
                                        "osc24M", 0x0038,
@@ -109,7 +121,7 @@ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
                                        297000000,      /* frac rate 1 */
                                        BIT(31),        /* gate */
                                        BIT(28),        /* lock */
-                                       0);
+                                       CLK_SET_RATE_UNGATE);
 
 static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph1_clk, "pll-periph1",
                                           "osc24M", 0x044,
@@ -118,7 +130,7 @@ static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph1_clk, "pll-periph1",
                                           BIT(31),     /* gate */
                                           BIT(28),     /* lock */
                                           2,           /* post-div */
-                                          0);
+                                          CLK_SET_RATE_UNGATE);
 
 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de",
                                        "osc24M", 0x0048,
@@ -130,7 +142,7 @@ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de",
                                        297000000,      /* frac rate 1 */
                                        BIT(31),        /* gate */
                                        BIT(28),        /* lock */
-                                       0);
+                                       CLK_SET_RATE_UNGATE);
 
 static const char * const cpux_parents[] = { "osc32k", "osc24M",
                                             "pll-cpux" , "pll-cpux" };
@@ -484,7 +496,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
                                 0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL);
 
 static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu",
-                            0x1a0, 0, 3, BIT(31), 0);
+                            0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT);
 
 static struct ccu_common *sun8i_h3_ccu_clks[] = {
        &pll_cpux_clk.common,
@@ -707,9 +719,9 @@ static struct ccu_common *sun50i_h5_ccu_clks[] = {
        &gpu_clk.common,
 };
 
-/* We hardcode the divider to 4 for now */
+/* We hardcode the divider to 1 for now */
 static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
-                       "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
+                       "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
 static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
                        "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
 static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
@@ -1129,10 +1141,10 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node,
                return;
        }
 
-       /* Force the PLL-Audio-1x divider to 4 */
+       /* Force the PLL-Audio-1x divider to 1 */
        val = readl(reg + SUN8I_H3_PLL_AUDIO_REG);
        val &= ~GENMASK(19, 16);
-       writel(val | (3 << 16), reg + SUN8I_H3_PLL_AUDIO_REG);
+       writel(val | (0 << 16), reg + SUN8I_H3_PLL_AUDIO_REG);
 
        sunxi_ccu_probe(node, reg, desc);
 
index cadd1a9f93b624c8633c946a7d35cecee0b6fd8d..5d684ce77c548e24be2a0fa8f005269dc2f273ad 100644 (file)
@@ -24,6 +24,7 @@
 #define CCU_FEATURE_ALL_PREDIV         BIT(4)
 #define CCU_FEATURE_LOCK_REG           BIT(5)
 #define CCU_FEATURE_MMC_TIMING_SWITCH  BIT(6)
+#define CCU_FEATURE_SIGMA_DELTA_MOD    BIT(7)
 
 /* MMC timing mode switch bit */
 #define CCU_MMC_NEW_TIMING_MODE                BIT(30)
index a32158e8f2e35a4fa89d5d21111e11e17a518ee8..7620aa973a6e49f5af0371508eacfadc864f5508 100644 (file)
@@ -90,6 +90,14 @@ static unsigned long ccu_nm_recalc_rate(struct clk_hw *hw,
        if (!m)
                m++;
 
+       if (ccu_sdm_helper_is_enabled(&nm->common, &nm->sdm)) {
+               unsigned long rate =
+                       ccu_sdm_helper_read_rate(&nm->common, &nm->sdm,
+                                                m, n);
+               if (rate)
+                       return rate;
+       }
+
        return parent_rate * n / m;
 }
 
@@ -99,6 +107,12 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
        struct ccu_nm *nm = hw_to_ccu_nm(hw);
        struct _ccu_nm _nm;
 
+       if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate))
+               return rate;
+
+       if (ccu_sdm_helper_has_rate(&nm->common, &nm->sdm, rate))
+               return rate;
+
        _nm.min_n = nm->n.min ?: 1;
        _nm.max_n = nm->n.max ?: 1 << nm->n.width;
        _nm.min_m = 1;
@@ -140,7 +154,16 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
        _nm.min_m = 1;
        _nm.max_m = nm->m.max ?: 1 << nm->m.width;
 
-       ccu_nm_find_best(parent_rate, rate, &_nm);
+       if (ccu_sdm_helper_has_rate(&nm->common, &nm->sdm, rate)) {
+               ccu_sdm_helper_enable(&nm->common, &nm->sdm, rate);
+
+               /* Sigma delta modulation requires specific N and M factors */
+               ccu_sdm_helper_get_factors(&nm->common, &nm->sdm, rate,
+                                          &_nm.m, &_nm.n);
+       } else {
+               ccu_sdm_helper_disable(&nm->common, &nm->sdm);
+               ccu_nm_find_best(parent_rate, rate, &_nm);
+       }
 
        spin_lock_irqsave(nm->common.lock, flags);
 
index e87fd186da7830cf4d79bfb5c8b621154735487c..c623b0c7a23c3f7229445aa0b40051245f95b028 100644 (file)
@@ -20,6 +20,7 @@
 #include "ccu_div.h"
 #include "ccu_frac.h"
 #include "ccu_mult.h"
+#include "ccu_sdm.h"
 
 /*
  * struct ccu_nm - Definition of an N-M clock
@@ -33,10 +34,34 @@ struct ccu_nm {
        struct ccu_mult_internal        n;
        struct ccu_div_internal         m;
        struct ccu_frac_internal        frac;
+       struct ccu_sdm_internal         sdm;
 
        struct ccu_common       common;
 };
 
+#define SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(_struct, _name, _parent, _reg, \
+                                       _nshift, _nwidth,               \
+                                       _mshift, _mwidth,               \
+                                       _sdm_table, _sdm_en,            \
+                                       _sdm_reg, _sdm_reg_en,          \
+                                       _gate, _lock, _flags)           \
+       struct ccu_nm _struct = {                                       \
+               .enable         = _gate,                                \
+               .lock           = _lock,                                \
+               .n              = _SUNXI_CCU_MULT(_nshift, _nwidth),    \
+               .m              = _SUNXI_CCU_DIV(_mshift, _mwidth),     \
+               .sdm            = _SUNXI_CCU_SDM(_sdm_table, _sdm_en,   \
+                                                _sdm_reg, _sdm_reg_en),\
+               .common         = {                                     \
+                       .reg            = _reg,                         \
+                       .features       = CCU_FEATURE_SIGMA_DELTA_MOD,  \
+                       .hw.init        = CLK_HW_INIT(_name,            \
+                                                     _parent,          \
+                                                     &ccu_nm_ops,      \
+                                                     _flags),          \
+               },                                                      \
+       }
+
 #define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(_struct, _name, _parent, _reg,        \
                                         _nshift, _nwidth,              \
                                         _mshift, _mwidth,              \
index 1dc4e98ea8023d592a700b11896d3b0dbcbccd40..b67149143554e45247fd55450a4134367a773fe9 100644 (file)
@@ -60,8 +60,22 @@ static int ccu_reset_reset(struct reset_controller_dev *rcdev,
        return 0;
 }
 
+static int ccu_reset_status(struct reset_controller_dev *rcdev,
+                           unsigned long id)
+{
+       struct ccu_reset *ccu = rcdev_to_ccu_reset(rcdev);
+       const struct ccu_reset_map *map = &ccu->reset_map[id];
+
+       /*
+        * The reset control API expects 0 if reset is not asserted,
+        * which is the opposite of what our hardware uses.
+        */
+       return !(map->bit & readl(ccu->base + map->reg));
+}
+
 const struct reset_control_ops ccu_reset_ops = {
        .assert         = ccu_reset_assert,
        .deassert       = ccu_reset_deassert,
        .reset          = ccu_reset_reset,
+       .status         = ccu_reset_status,
 };
diff --git a/drivers/clk/sunxi-ng/ccu_sdm.c b/drivers/clk/sunxi-ng/ccu_sdm.c
new file mode 100644 (file)
index 0000000..3b3dc9b
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2017 Chen-Yu Tsai <wens@csie.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
+
+#include "ccu_sdm.h"
+
+bool ccu_sdm_helper_is_enabled(struct ccu_common *common,
+                              struct ccu_sdm_internal *sdm)
+{
+       if (!(common->features & CCU_FEATURE_SIGMA_DELTA_MOD))
+               return false;
+
+       if (sdm->enable && !(readl(common->base + common->reg) & sdm->enable))
+               return false;
+
+       return !!(readl(common->base + sdm->tuning_reg) & sdm->tuning_enable);
+}
+
+void ccu_sdm_helper_enable(struct ccu_common *common,
+                          struct ccu_sdm_internal *sdm,
+                          unsigned long rate)
+{
+       unsigned long flags;
+       unsigned int i;
+       u32 reg;
+
+       if (!(common->features & CCU_FEATURE_SIGMA_DELTA_MOD))
+               return;
+
+       /* Set the pattern */
+       for (i = 0; i < sdm->table_size; i++)
+               if (sdm->table[i].rate == rate)
+                       writel(sdm->table[i].pattern,
+                              common->base + sdm->tuning_reg);
+
+       /* Make sure SDM is enabled */
+       spin_lock_irqsave(common->lock, flags);
+       reg = readl(common->base + sdm->tuning_reg);
+       writel(reg | sdm->tuning_enable, common->base + sdm->tuning_reg);
+       spin_unlock_irqrestore(common->lock, flags);
+
+       spin_lock_irqsave(common->lock, flags);
+       reg = readl(common->base + common->reg);
+       writel(reg | sdm->enable, common->base + common->reg);
+       spin_unlock_irqrestore(common->lock, flags);
+}
+
+void ccu_sdm_helper_disable(struct ccu_common *common,
+                           struct ccu_sdm_internal *sdm)
+{
+       unsigned long flags;
+       u32 reg;
+
+       if (!(common->features & CCU_FEATURE_SIGMA_DELTA_MOD))
+               return;
+
+       spin_lock_irqsave(common->lock, flags);
+       reg = readl(common->base + common->reg);
+       writel(reg & ~sdm->enable, common->base + common->reg);
+       spin_unlock_irqrestore(common->lock, flags);
+
+       spin_lock_irqsave(common->lock, flags);
+       reg = readl(common->base + sdm->tuning_reg);
+       writel(reg & ~sdm->tuning_enable, common->base + sdm->tuning_reg);
+       spin_unlock_irqrestore(common->lock, flags);
+}
+
+/*
+ * Sigma delta modulation provides a way to do fractional-N frequency
+ * synthesis, in essence allowing the PLL to output any frequency
+ * within its operational range. On earlier SoCs such as the A10/A20,
+ * some PLLs support this. On later SoCs, all PLLs support this.
+ *
+ * The datasheets do not explain what the "wave top" and "wave bottom"
+ * parameters mean or do, nor how to calculate the effective output
+ * frequency. The only examples (and real world usage) are for the audio
+ * PLL to generate 24.576 and 22.5792 MHz clock rates used by the audio
+ * peripherals. The author lacks the underlying domain knowledge to
+ * pursue this.
+ *
+ * The goal and function of the following code is to support the two
+ * clock rates used by the audio subsystem, allowing for proper audio
+ * playback and capture without any pitch or speed changes.
+ */
+bool ccu_sdm_helper_has_rate(struct ccu_common *common,
+                            struct ccu_sdm_internal *sdm,
+                            unsigned long rate)
+{
+       unsigned int i;
+
+       if (!(common->features & CCU_FEATURE_SIGMA_DELTA_MOD))
+               return false;
+
+       for (i = 0; i < sdm->table_size; i++)
+               if (sdm->table[i].rate == rate)
+                       return true;
+
+       return false;
+}
+
+unsigned long ccu_sdm_helper_read_rate(struct ccu_common *common,
+                                      struct ccu_sdm_internal *sdm,
+                                      u32 m, u32 n)
+{
+       unsigned int i;
+       u32 reg;
+
+       pr_debug("%s: Read sigma-delta modulation setting\n",
+                clk_hw_get_name(&common->hw));
+
+       if (!(common->features & CCU_FEATURE_SIGMA_DELTA_MOD))
+               return 0;
+
+       pr_debug("%s: clock is sigma-delta modulated\n",
+                clk_hw_get_name(&common->hw));
+
+       reg = readl(common->base + sdm->tuning_reg);
+
+       pr_debug("%s: pattern reg is 0x%x",
+                clk_hw_get_name(&common->hw), reg);
+
+       for (i = 0; i < sdm->table_size; i++)
+               if (sdm->table[i].pattern == reg &&
+                   sdm->table[i].m == m && sdm->table[i].n == n)
+                       return sdm->table[i].rate;
+
+       /* We can't calculate the effective clock rate, so just fail. */
+       return 0;
+}
+
+int ccu_sdm_helper_get_factors(struct ccu_common *common,
+                              struct ccu_sdm_internal *sdm,
+                              unsigned long rate,
+                              unsigned long *m, unsigned long *n)
+{
+       unsigned int i;
+
+       if (!(common->features & CCU_FEATURE_SIGMA_DELTA_MOD))
+               return -EINVAL;
+
+       for (i = 0; i < sdm->table_size; i++)
+               if (sdm->table[i].rate == rate) {
+                       *m = sdm->table[i].m;
+                       *n = sdm->table[i].n;
+                       return 0;
+               }
+
+       /* nothing found */
+       return -EINVAL;
+}
diff --git a/drivers/clk/sunxi-ng/ccu_sdm.h b/drivers/clk/sunxi-ng/ccu_sdm.h
new file mode 100644 (file)
index 0000000..2a9b4a2
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017 Chen-Yu Tsai. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CCU_SDM_H
+#define _CCU_SDM_H
+
+#include <linux/clk-provider.h>
+
+#include "ccu_common.h"
+
+struct ccu_sdm_setting {
+       unsigned long   rate;
+
+       /*
+        * XXX We don't know what the step and bottom register fields
+        * mean. Just copy the whole register value from the vendor
+        * kernel for now.
+        */
+       u32             pattern;
+
+       /*
+        * M and N factors here should be the values used in
+        * calculation, not the raw values written to registers
+        */
+       u32             m;
+       u32             n;
+};
+
+struct ccu_sdm_internal {
+       struct ccu_sdm_setting  *table;
+       u32             table_size;
+       /* early SoCs don't have the SDM enable bit in the PLL register */
+       u32             enable;
+       /* second enable bit in tuning register */
+       u32             tuning_enable;
+       u16             tuning_reg;
+};
+
+#define _SUNXI_CCU_SDM(_table, _enable,                        \
+                      _reg, _reg_enable)               \
+       {                                               \
+               .table          = _table,               \
+               .table_size     = ARRAY_SIZE(_table),   \
+               .enable         = _enable,              \
+               .tuning_enable  = _reg_enable,          \
+               .tuning_reg     = _reg,                 \
+       }
+
+bool ccu_sdm_helper_is_enabled(struct ccu_common *common,
+                              struct ccu_sdm_internal *sdm);
+void ccu_sdm_helper_enable(struct ccu_common *common,
+                          struct ccu_sdm_internal *sdm,
+                          unsigned long rate);
+void ccu_sdm_helper_disable(struct ccu_common *common,
+                           struct ccu_sdm_internal *sdm);
+
+bool ccu_sdm_helper_has_rate(struct ccu_common *common,
+                            struct ccu_sdm_internal *sdm,
+                            unsigned long rate);
+
+unsigned long ccu_sdm_helper_read_rate(struct ccu_common *common,
+                                      struct ccu_sdm_internal *sdm,
+                                      u32 m, u32 n);
+
+int ccu_sdm_helper_get_factors(struct ccu_common *common,
+                              struct ccu_sdm_internal *sdm,
+                              unsigned long rate,
+                              unsigned long *m, unsigned long *n);
+
+#endif
index dfe5e3e32d28f050388f05cb0247f101eb69dc74..856fef65433b4b013b8e0c27a2f919b7690f2325 100644 (file)
@@ -276,13 +276,11 @@ void sunxi_factors_unregister(struct device_node *node, struct clk *clk)
 {
        struct clk_hw *hw = __clk_get_hw(clk);
        struct clk_factors *factors;
-       const char *name;
 
        if (!hw)
                return;
 
        factors = to_clk_factors(hw);
-       name = clk_hw_get_name(hw);
 
        of_clk_del_provider(node);
        /* TODO: The composite clock stuff will leak a bit here. */
index 6041bdba2e971ecb93c3047c14854e676750bf5e..a1a634253d6f2299bfad888b2fa193c98b4ac019 100644 (file)
@@ -124,7 +124,7 @@ static int sun9i_a80_mmc_config_clk_probe(struct platform_device *pdev)
                return PTR_ERR(data->clk);
        }
 
-       data->reset = devm_reset_control_get(&pdev->dev, NULL);
+       data->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
        if (IS_ERR(data->reset)) {
                dev_err(&pdev->dev, "Could not get reset control\n");
                return PTR_ERR(data->reset);
index 638ace64033b92a54b930c4bdf1be65550241099..a896692b74ec8eb70c75d9539914928672984e0d 100644 (file)
@@ -55,6 +55,7 @@ struct tegra_bpmp_clk_message {
        struct {
                void *data;
                size_t size;
+               int ret;
        } rx;
 };
 
@@ -64,6 +65,7 @@ static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
        struct mrq_clk_request request;
        struct tegra_bpmp_message msg;
        void *req = &request;
+       int err;
 
        memset(&request, 0, sizeof(request));
        request.cmd_and_id = (clk->cmd << 24) | clk->id;
@@ -84,7 +86,13 @@ static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
        msg.rx.data = clk->rx.data;
        msg.rx.size = clk->rx.size;
 
-       return tegra_bpmp_transfer(bpmp, &msg);
+       err = tegra_bpmp_transfer(bpmp, &msg);
+       if (err < 0)
+               return err;
+       else if (msg.rx.ret < 0)
+               return -EINVAL;
+
+       return 0;
 }
 
 static int tegra_bpmp_clk_prepare(struct clk_hw *hw)
@@ -414,11 +422,8 @@ static int tegra_bpmp_probe_clocks(struct tegra_bpmp *bpmp,
                struct tegra_bpmp_clk_info *info = &clocks[count];
 
                err = tegra_bpmp_clk_get_info(bpmp, id, info);
-               if (err < 0) {
-                       dev_err(bpmp->dev, "failed to query clock %u: %d\n",
-                               id, err);
+               if (err < 0)
                        continue;
-               }
 
                if (info->num_parents >= U8_MAX) {
                        dev_err(bpmp->dev,
index 2c44aeb0b97c7b437fa79b2cdf82f8ee9df577b0..0a7deee74eea5846d5c76788828dc73d8f844c7d 100644 (file)
@@ -1728,10 +1728,10 @@ EXPORT_SYMBOL(tegra_dfll_register);
  * @pdev: DFLL platform_device *
  *
  * Unbind this driver from the DFLL hardware device represented by
- * @pdev. The DFLL must be disabled for this to succeed. Returns 0
- * upon success or -EBUSY if the DFLL is still active.
+ * @pdev. The DFLL must be disabled for this to succeed. Returns a
+ * soc pointer upon success or -EBUSY if the DFLL is still active.
  */
-int tegra_dfll_unregister(struct platform_device *pdev)
+struct tegra_dfll_soc_data *tegra_dfll_unregister(struct platform_device *pdev)
 {
        struct tegra_dfll *td = platform_get_drvdata(pdev);
 
@@ -1739,7 +1739,7 @@ int tegra_dfll_unregister(struct platform_device *pdev)
        if (td->mode != DFLL_DISABLED) {
                dev_err(&pdev->dev,
                        "must disable DFLL before removing driver\n");
-               return -EBUSY;
+               return ERR_PTR(-EBUSY);
        }
 
        debugfs_remove_recursive(td->debugfs_dir);
@@ -1753,6 +1753,6 @@ int tegra_dfll_unregister(struct platform_device *pdev)
 
        reset_control_assert(td->dvco_rst);
 
-       return 0;
+       return td->soc;
 }
 EXPORT_SYMBOL(tegra_dfll_unregister);
index ed2ad888268f39bd27d7ead71eb3875137f1d937..83352c8078f27a9644d7d5bb165432d1bcddef37 100644 (file)
@@ -43,7 +43,7 @@ struct tegra_dfll_soc_data {
 
 int tegra_dfll_register(struct platform_device *pdev,
                        struct tegra_dfll_soc_data *soc);
-int tegra_dfll_unregister(struct platform_device *pdev);
+struct tegra_dfll_soc_data *tegra_dfll_unregister(struct platform_device *pdev);
 int tegra_dfll_runtime_suspend(struct device *dev);
 int tegra_dfll_runtime_resume(struct device *dev);
 
index 11ee5f9ce99e134a73851d0a5709114d0e0aa1a9..b616e33c525574fa7752362c6f8fe2297923d97b 100644 (file)
@@ -13,6 +13,7 @@ enum clk_id {
        tegra_clk_amx,
        tegra_clk_amx1,
        tegra_clk_apb2ape,
+       tegra_clk_ahbdma,
        tegra_clk_apbdma,
        tegra_clk_apbif,
        tegra_clk_ape,
index cf80831de79d63260eb94b1208b76c216c5a20b8..9475c00b7cf9b7dd645cec8df1a5d5e6b1adbb80 100644 (file)
@@ -203,3 +203,11 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name,
        return _tegra_clk_register_periph(name, parent_names, num_parents,
                        periph, clk_base, offset, CLK_SET_RATE_PARENT);
 }
+
+struct clk *tegra_clk_register_periph_data(void __iomem *clk_base,
+                                          struct tegra_periph_init_data *init)
+{
+       return _tegra_clk_register_periph(init->name, init->p.parent_names,
+                                         init->num_parents, &init->periph,
+                                         clk_base, init->offset, init->flags);
+}
index 848255cc0209911ec5781ceb2d09107244bcf659..c02711927d7912cac57e74194df6781adfa1764c 100644 (file)
 #define CLK_SOURCE_NVDEC 0x698
 #define CLK_SOURCE_NVJPG 0x69c
 #define CLK_SOURCE_APE 0x6c0
-#define CLK_SOURCE_SOR1 0x410
 #define CLK_SOURCE_SDMMC_LEGACY 0x694
 #define CLK_SOURCE_QSPI 0x6c4
 #define CLK_SOURCE_VI_I2C 0x6c8
@@ -278,7 +277,6 @@ static DEFINE_SPINLOCK(PLLP_OUTA_lock);
 static DEFINE_SPINLOCK(PLLP_OUTB_lock);
 static DEFINE_SPINLOCK(PLLP_OUTC_lock);
 static DEFINE_SPINLOCK(sor0_lock);
-static DEFINE_SPINLOCK(sor1_lock);
 
 #define MUX_I2S_SPDIF(_id)                                             \
 static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = { "pll_a_out0", \
@@ -604,18 +602,6 @@ static u32 mux_pllp_plld_plld2_clkm_idx[] = {
        [0] = 0, [1] = 2, [2] = 5, [3] = 6
 };
 
-static const char *mux_sor_safe_sor1_brick_sor1_src[] = {
-       /*
-        * Bit 0 of the mux selects sor1_brick, irrespective of bit 1, so the
-        * sor1_brick parent appears twice in the list below. This is merely
-        * to support clk_get_parent() if firmware happened to set these bits
-        * to 0b11. While not an invalid setting, code should always set the
-        * bits to 0b01 to select sor1_brick.
-        */
-       "sor_safe", "sor1_brick", "sor1_src", "sor1_brick"
-};
-#define mux_sor_safe_sor1_brick_sor1_src_idx NULL
-
 static const char *mux_pllp_pllre_clkm[] = {
        "pll_p", "pll_re_out1", "clk_m"
 };
@@ -804,8 +790,6 @@ static struct tegra_periph_init_data periph_clks[] = {
        MUX8("nvdec", mux_pllc2_c_c3_pllp_plla1_clkm, CLK_SOURCE_NVDEC, 194, 0, tegra_clk_nvdec),
        MUX8("nvjpg", mux_pllc2_c_c3_pllp_plla1_clkm, CLK_SOURCE_NVJPG, 195, 0, tegra_clk_nvjpg),
        MUX8("ape", mux_plla_pllc4_out0_pllc_pllc4_out1_pllp_pllc4_out2_clkm, CLK_SOURCE_APE, 198, TEGRA_PERIPH_ON_APB, tegra_clk_ape),
-       MUX8_NOGATE_LOCK("sor1_src", mux_pllp_plld_plld2_clkm, CLK_SOURCE_SOR1, tegra_clk_sor1_src, &sor1_lock),
-       NODIV("sor1", mux_sor_safe_sor1_brick_sor1_src, CLK_SOURCE_SOR1, 14, MASK(2), 183, 0, tegra_clk_sor1, &sor1_lock),
        MUX8("sdmmc_legacy", mux_pllp_out3_clkm_pllp_pllc4, CLK_SOURCE_SDMMC_LEGACY, 193, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_sdmmc_legacy),
        MUX8("qspi", mux_pllp_pllc_pllc_out1_pllc4_out2_pllc4_out1_clkm_pllc4_out0, CLK_SOURCE_QSPI, 211, TEGRA_PERIPH_ON_APB, tegra_clk_qspi),
        I2C("vii2c", mux_pllp_pllc_clkm, CLK_SOURCE_VI_I2C, 208, tegra_clk_vi_i2c),
@@ -823,7 +807,8 @@ static struct tegra_periph_init_data gate_clks[] = {
        GATE("timer", "clk_m", 5, 0, tegra_clk_timer, CLK_IS_CRITICAL),
        GATE("isp", "clk_m", 23, 0, tegra_clk_isp, 0),
        GATE("vcp", "clk_m", 29, 0, tegra_clk_vcp, 0),
-       GATE("apbdma", "clk_m", 34, 0, tegra_clk_apbdma, 0),
+       GATE("ahbdma", "hclk", 33, 0, tegra_clk_ahbdma, 0),
+       GATE("apbdma", "pclk", 34, 0, tegra_clk_apbdma, 0),
        GATE("kbc", "clk_32k", 36, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_kbc, 0),
        GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, 0),
        GATE("fuse_burn", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse_burn, 0),
@@ -927,10 +912,7 @@ static void __init periph_clk_init(void __iomem *clk_base,
                        continue;
 
                data->periph.gate.regs = bank;
-               clk = tegra_clk_register_periph(data->name,
-                       data->p.parent_names, data->num_parents,
-                       &data->periph, clk_base, data->offset,
-                       data->flags);
+               clk = tegra_clk_register_periph_data(clk_base, data);
                *dt_clk = clk;
        }
 }
index 4f6fd307cb706d2d38003203417a2a9adf70a92e..10047107c1dc39720275537b5dddb86db4438e6a 100644 (file)
@@ -166,7 +166,7 @@ static void __init tegra_sclk_init(void __iomem *clk_base,
                                   clk_base + SYSTEM_CLK_RATE, 0, 2, 0,
                                   &sysrate_lock);
        clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT |
-                               CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE,
+                               CLK_IS_CRITICAL, clk_base + SYSTEM_CLK_RATE,
                                3, CLK_GATE_SET_TO_DISABLE, &sysrate_lock);
        *dt_clk = clk;
 }
index fd1a99c05c2dc20214d575313fcf2a3964ac945f..63087d17c3e2c31f0e4e29127a7885c8a510f924 100644 (file)
@@ -1092,9 +1092,7 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base,
 
        for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) {
                data = &tegra_periph_clk_list[i];
-               clk = tegra_clk_register_periph(data->name,
-                       data->p.parent_names, data->num_parents,
-                       &data->periph, clk_base, data->offset, data->flags);
+               clk = tegra_clk_register_periph_data(clk_base, data);
                clks[data->clk_id] = clk;
        }
 
index ad1c1cc829cba46591ba458e3b637441b20f3638..269d3595758bebabf0f72d6448ba6633e9cd3c8f 100644 (file)
@@ -125,19 +125,17 @@ static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
                return err;
        }
 
-       platform_set_drvdata(pdev, soc);
-
        return 0;
 }
 
 static int tegra124_dfll_fcpu_remove(struct platform_device *pdev)
 {
-       struct tegra_dfll_soc_data *soc = platform_get_drvdata(pdev);
-       int err;
+       struct tegra_dfll_soc_data *soc;
 
-       err = tegra_dfll_unregister(pdev);
-       if (err < 0)
-               dev_err(&pdev->dev, "failed to unregister DFLL: %d\n", err);
+       soc = tegra_dfll_unregister(pdev);
+       if (IS_ERR(soc))
+               dev_err(&pdev->dev, "failed to unregister DFLL: %ld\n",
+                       PTR_ERR(soc));
 
        tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq);
 
index 837e5cbd60e9ce842c97e87151b9782779ed81be..cbd5a2e5c569bc2b3471eb4154aa42ee6e083f97 100644 (file)
@@ -522,6 +522,8 @@ static struct tegra_devclk devclks[] __initdata = {
 };
 
 static struct tegra_clk tegra20_clks[tegra_clk_max] __initdata = {
+       [tegra_clk_ahbdma] = { .dt_id = TEGRA20_CLK_AHBDMA, .present = true },
+       [tegra_clk_apbdma] = { .dt_id = TEGRA20_CLK_APBDMA, .present = true },
        [tegra_clk_spdif_out] = { .dt_id = TEGRA20_CLK_SPDIF_OUT, .present = true },
        [tegra_clk_spdif_in] = { .dt_id = TEGRA20_CLK_SPDIF_IN, .present = true },
        [tegra_clk_sdmmc1] = { .dt_id = TEGRA20_CLK_SDMMC1, .present = true },
@@ -806,11 +808,6 @@ static void __init tegra20_periph_clk_init(void)
                                    clk_base, 0, 3, periph_clk_enb_refcnt);
        clks[TEGRA20_CLK_AC97] = clk;
 
-       /* apbdma */
-       clk = tegra_clk_register_periph_gate("apbdma", "pclk", 0, clk_base,
-                                   0, 34, periph_clk_enb_refcnt);
-       clks[TEGRA20_CLK_APBDMA] = clk;
-
        /* emc */
        clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
                               ARRAY_SIZE(mux_pllmcp_clkm),
@@ -850,9 +847,7 @@ static void __init tegra20_periph_clk_init(void)
 
        for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) {
                data = &tegra_periph_clk_list[i];
-               clk = tegra_clk_register_periph(data->name, data->p.parent_names,
-                               data->num_parents, &data->periph,
-                               clk_base, data->offset, data->flags);
+               clk = tegra_clk_register_periph_data(clk_base, data);
                clks[data->clk_id] = clk;
        }
 
@@ -1025,7 +1020,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
        { TEGRA20_CLK_PLL_P_OUT3, TEGRA20_CLK_CLK_MAX, 72000000, 1 },
        { TEGRA20_CLK_PLL_P_OUT4, TEGRA20_CLK_CLK_MAX, 24000000, 1 },
        { TEGRA20_CLK_PLL_C, TEGRA20_CLK_CLK_MAX, 600000000, 1 },
-       { TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 120000000, 1 },
+       { TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 216000000, 1 },
        { TEGRA20_CLK_SCLK, TEGRA20_CLK_PLL_C_OUT1, 0, 1 },
        { TEGRA20_CLK_HCLK, TEGRA20_CLK_CLK_MAX, 0, 1 },
        { TEGRA20_CLK_PCLK, TEGRA20_CLK_CLK_MAX, 60000000, 1 },
index 6d7a613f2656a4f8af55e0905a0c8c0daec6c0dc..9e6260869eb94bee9e9b3c5f17dd7aedbc6c0a79 100644 (file)
@@ -40,6 +40,7 @@
 
 #define CLK_SOURCE_CSITE 0x1d4
 #define CLK_SOURCE_EMC 0x19c
+#define CLK_SOURCE_SOR1 0x410
 
 #define PLLC_BASE 0x80
 #define PLLC_OUT 0x84
@@ -264,6 +265,7 @@ static DEFINE_SPINLOCK(pll_d_lock);
 static DEFINE_SPINLOCK(pll_e_lock);
 static DEFINE_SPINLOCK(pll_re_lock);
 static DEFINE_SPINLOCK(pll_u_lock);
+static DEFINE_SPINLOCK(sor1_lock);
 static DEFINE_SPINLOCK(emc_lock);
 
 /* possible OSC frequencies in Hz */
@@ -2566,8 +2568,8 @@ static int tegra210_enable_pllu(void)
        reg |= PLL_ENABLE;
        writel(reg, clk_base + PLLU_BASE);
 
-       readl_relaxed_poll_timeout(clk_base + PLLU_BASE, reg,
-                                  reg & PLL_BASE_LOCK, 2, 1000);
+       readl_relaxed_poll_timeout_atomic(clk_base + PLLU_BASE, reg,
+                                         reg & PLL_BASE_LOCK, 2, 1000);
        if (!(reg & PLL_BASE_LOCK)) {
                pr_err("Timed out waiting for PLL_U to lock\n");
                return -ETIMEDOUT;
@@ -2628,10 +2630,35 @@ static int tegra210_init_pllu(void)
        return 0;
 }
 
+static const char * const sor1_out_parents[] = {
+       /*
+        * Bit 0 of the mux selects sor1_pad_clkout, irrespective of bit 1, so
+        * the sor1_pad_clkout parent appears twice in the list below. This is
+        * merely to support clk_get_parent() if firmware happened to set
+        * these bits to 0b11. While not an invalid setting, code should
+        * always set the bits to 0b01 to select sor1_pad_clkout.
+        */
+       "sor_safe", "sor1_pad_clkout", "sor1", "sor1_pad_clkout",
+};
+
+static const char * const sor1_parents[] = {
+       "pll_p", "pll_d_out0", "pll_d2_out0", "clk_m",
+};
+
+static u32 sor1_parents_idx[] = { 0, 2, 5, 6 };
+
+static struct tegra_periph_init_data tegra210_periph[] = {
+       TEGRA_INIT_DATA_TABLE("sor1", NULL, NULL, sor1_parents,
+                             CLK_SOURCE_SOR1, 29, 0x7, 0, 0, 8, 1,
+                             TEGRA_DIVIDER_ROUND_UP, 183, 0, tegra_clk_sor1,
+                             sor1_parents_idx, 0, &sor1_lock),
+};
+
 static __init void tegra210_periph_clk_init(void __iomem *clk_base,
                                            void __iomem *pmc_base)
 {
        struct clk *clk;
+       unsigned int i;
 
        /* xusb_ss_div2 */
        clk = clk_register_fixed_factor(NULL, "xusb_ss_div2", "xusb_ss_src", 0,
@@ -2650,6 +2677,12 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base,
                                              1, 17, 207);
        clks[TEGRA210_CLK_DPAUX1] = clk;
 
+       clk = clk_register_mux_table(NULL, "sor1_out", sor1_out_parents,
+                                    ARRAY_SIZE(sor1_out_parents), 0,
+                                    clk_base + CLK_SOURCE_SOR1, 14, 0x3,
+                                    0, NULL, &sor1_lock);
+       clks[TEGRA210_CLK_SOR1_OUT] = clk;
+
        /* pll_d_dsi_out */
        clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0,
                                clk_base + PLLD_MISC0, 21, 0, &pll_d_lock);
@@ -2694,6 +2727,20 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base,
                                0, NULL);
        clks[TEGRA210_CLK_ACLK] = clk;
 
+       for (i = 0; i < ARRAY_SIZE(tegra210_periph); i++) {
+               struct tegra_periph_init_data *init = &tegra210_periph[i];
+               struct clk **clkp;
+
+               clkp = tegra_lookup_dt_id(init->clk_id, tegra210_clks);
+               if (!clkp) {
+                       pr_warn("clock %u not found\n", init->clk_id);
+                       continue;
+               }
+
+               clk = tegra_clk_register_periph_data(clk_base, init);
+               *clkp = clk;
+       }
+
        tegra_periph_clk_init(clk_base, pmc_base, tegra210_clks, &pll_p_params);
 }
 
index a2d163f759b4502df2ad4f1f4e5d738904da67a7..bee84c554932ce1f54f5f32eff0078f7b7f19868 100644 (file)
@@ -359,7 +359,7 @@ static struct tegra_clk_pll_freq_table pll_e_freq_table[] = {
 };
 
 /* PLL parameters */
-static struct tegra_clk_pll_params pll_c_params = {
+static struct tegra_clk_pll_params pll_c_params __ro_after_init = {
        .input_min = 2000000,
        .input_max = 31000000,
        .cf_min = 1000000,
@@ -388,7 +388,7 @@ static struct div_nmp pllm_nmp = {
        .override_divp_shift = 15,
 };
 
-static struct tegra_clk_pll_params pll_m_params = {
+static struct tegra_clk_pll_params pll_m_params __ro_after_init = {
        .input_min = 2000000,
        .input_max = 31000000,
        .cf_min = 1000000,
@@ -409,7 +409,7 @@ static struct tegra_clk_pll_params pll_m_params = {
                 TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_FIXED,
 };
 
-static struct tegra_clk_pll_params pll_p_params = {
+static struct tegra_clk_pll_params pll_p_params __ro_after_init = {
        .input_min = 2000000,
        .input_max = 31000000,
        .cf_min = 1000000,
@@ -444,7 +444,7 @@ static struct tegra_clk_pll_params pll_a_params = {
                 TEGRA_PLL_HAS_LOCK_ENABLE,
 };
 
-static struct tegra_clk_pll_params pll_d_params = {
+static struct tegra_clk_pll_params pll_d_params __ro_after_init = {
        .input_min = 2000000,
        .input_max = 40000000,
        .cf_min = 1000000,
@@ -461,7 +461,7 @@ static struct tegra_clk_pll_params pll_d_params = {
                 TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
 };
 
-static struct tegra_clk_pll_params pll_d2_params = {
+static struct tegra_clk_pll_params pll_d2_params __ro_after_init = {
        .input_min = 2000000,
        .input_max = 40000000,
        .cf_min = 1000000,
@@ -478,7 +478,7 @@ static struct tegra_clk_pll_params pll_d2_params = {
                 TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
 };
 
-static struct tegra_clk_pll_params pll_u_params = {
+static struct tegra_clk_pll_params pll_u_params __ro_after_init = {
        .input_min = 2000000,
        .input_max = 40000000,
        .cf_min = 1000000,
@@ -496,7 +496,7 @@ static struct tegra_clk_pll_params pll_u_params = {
                 TEGRA_PLL_HAS_LOCK_ENABLE,
 };
 
-static struct tegra_clk_pll_params pll_x_params = {
+static struct tegra_clk_pll_params pll_x_params __ro_after_init = {
        .input_min = 2000000,
        .input_max = 31000000,
        .cf_min = 1000000,
@@ -513,7 +513,7 @@ static struct tegra_clk_pll_params pll_x_params = {
                 TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
 };
 
-static struct tegra_clk_pll_params pll_e_params = {
+static struct tegra_clk_pll_params pll_e_params __ro_after_init = {
        .input_min = 12000000,
        .input_max = 216000000,
        .cf_min = 12000000,
@@ -788,6 +788,7 @@ static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = {
        [tegra_clk_extern3] = { .dt_id = TEGRA30_CLK_EXTERN3, .present = true },
        [tegra_clk_disp1] = { .dt_id = TEGRA30_CLK_DISP1, .present = true },
        [tegra_clk_disp2] = { .dt_id = TEGRA30_CLK_DISP2, .present = true },
+       [tegra_clk_ahbdma] = { .dt_id = TEGRA30_CLK_AHBDMA, .present = true },
        [tegra_clk_apbdma] = { .dt_id = TEGRA30_CLK_APBDMA, .present = true },
        [tegra_clk_rtc] = { .dt_id = TEGRA30_CLK_RTC, .present = true },
        [tegra_clk_timer] = { .dt_id = TEGRA30_CLK_TIMER, .present = true },
@@ -964,7 +965,7 @@ static void __init tegra30_super_clk_init(void)
         * U71 divider of cclk_lp.
         */
        clk = tegra_clk_register_divider("pll_p_out3_cclklp", "pll_p_out3",
-                               clk_base + SUPER_CCLKG_DIVIDER, 0,
+                               clk_base + SUPER_CCLKLP_DIVIDER, 0,
                                TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
        clk_register_clkdev(clk, "pll_p_out3_cclklp", NULL);
 
@@ -1079,9 +1080,7 @@ static void __init tegra30_periph_clk_init(void)
 
        for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) {
                data = &tegra_periph_clk_list[i];
-               clk = tegra_clk_register_periph(data->name, data->p.parent_names,
-                               data->num_parents, &data->periph,
-                               clk_base, data->offset, data->flags);
+               clk = tegra_clk_register_periph_data(clk_base, data);
                clks[data->clk_id] = clk;
        }
 
index 872f1189ad7fbc71d3635d7abf28a16092bf6646..3b2763df51c2e0f7c5a5113f8df68dbbc4cb9b21 100644 (file)
@@ -662,6 +662,9 @@ struct tegra_periph_init_data {
                        _clk_num, _gate_flags, _clk_id,\
                        NULL, 0, NULL)
 
+struct clk *tegra_clk_register_periph_data(void __iomem *clk_base,
+                                          struct tegra_periph_init_data *init);
+
 /**
  * struct clk_super_mux - super clock
  *
index 13eb04f72389bbf68e26a12f71b74188910e8ab8..14881547043130d1e686055387a6276e49fd11f9 100644 (file)
@@ -274,8 +274,7 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
 
                /* Get configuration for the ATL instances */
                snprintf(prop, sizeof(prop), "atl%u", i);
-               of_node_get(node);
-               cfg_node = of_find_node_by_name(node, prop);
+               cfg_node = of_get_child_by_name(node, prop);
                if (cfg_node) {
                        ret = of_property_read_u32(cfg_node, "bws",
                                                   &cdesc->bws);
index 88f04a4cb890be4f68025d04d4bfaec4597dfda7..77f93f6d2806a19662b3f2c94128ee491cfc4fe2 100644 (file)
@@ -292,10 +292,8 @@ static struct clk *_register_divider(struct device *dev, const char *name,
 
        /* allocate the divider */
        div = kzalloc(sizeof(*div), GFP_KERNEL);
-       if (!div) {
-               pr_err("%s: could not allocate divider clk\n", __func__);
+       if (!div)
                return ERR_PTR(-ENOMEM);
-       }
 
        init.name = name;
        init.ops = &ti_clk_divider_ops;
index 18c267b38461dc96ff1d5dd26f518136a342ffb3..d4705803f3d3c7f72cfdc9f969bde508c4a1197a 100644 (file)
@@ -108,10 +108,8 @@ static struct clk *_register_mux(struct device *dev, const char *name,
 
        /* allocate the mux */
        mux = kzalloc(sizeof(*mux), GFP_KERNEL);
-       if (!mux) {
-               pr_err("%s: could not allocate mux clk\n", __func__);
+       if (!mux)
                return ERR_PTR(-ENOMEM);
-       }
 
        init.name = name;
        init.ops = &ti_clk_mux_ops;
index 16e4d303f53593f78124d2c2dee9c771613dc7eb..badc478a86c6781e332163c03b87d37b97c71dec 100644 (file)
@@ -13,6 +13,8 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/stddef.h>
+
 #include "clk-uniphier.h"
 
 #define UNIPHIER_MIO_CLK_SD_FIXED                                      \
 #define UNIPHIER_MIO_CLK_USB2_PHY(idx, ch)                             \
        UNIPHIER_CLK_GATE("usb2" #ch "-phy", (idx), "usb2", 0x20 + 0x200 * (ch), 29)
 
-#define UNIPHIER_MIO_CLK_DMAC(idx)                                     \
-       UNIPHIER_CLK_GATE("miodmac", (idx), "stdmac", 0x20, 25)
-
 const struct uniphier_clk_data uniphier_ld4_mio_clk_data[] = {
        UNIPHIER_MIO_CLK_SD_FIXED,
        UNIPHIER_MIO_CLK_SD(0, 0),
        UNIPHIER_MIO_CLK_SD(1, 1),
        UNIPHIER_MIO_CLK_SD(2, 2),
-       UNIPHIER_MIO_CLK_DMAC(7),
+       UNIPHIER_CLK_GATE("miodmac", 7, NULL, 0x20, 25),
        UNIPHIER_MIO_CLK_USB2(8, 0),
        UNIPHIER_MIO_CLK_USB2(9, 1),
        UNIPHIER_MIO_CLK_USB2(10, 2),
index 07f3b91a7daf36f3f15873626312c68707709484..d244e724e19858dfb8b8c5297e9852a61ba0ce50 100644 (file)
@@ -123,7 +123,7 @@ const struct uniphier_clk_data uniphier_sld8_sys_clk_data[] = {
 const struct uniphier_clk_data uniphier_pro5_sys_clk_data[] = {
        UNIPHIER_CLK_FACTOR("spll", -1, "ref", 120, 1),         /* 2400 MHz */
        UNIPHIER_CLK_FACTOR("dapll1", -1, "ref", 128, 1),       /* 2560 MHz */
-       UNIPHIER_CLK_FACTOR("dapll2", -1, "ref", 144, 125),     /* 2949.12 MHz */
+       UNIPHIER_CLK_FACTOR("dapll2", -1, "dapll1", 144, 125),  /* 2949.12 MHz */
        UNIPHIER_CLK_FACTOR("uart", 0, "dapll2", 1, 40),
        UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48),
        UNIPHIER_PRO5_SYS_CLK_NAND(2),
index f50592775c9d792cf21ced429ff10012ade2a937..7cfb59c9136d4169f4fc149a87d64e47f2a19389 100644 (file)
@@ -107,11 +107,9 @@ static struct clk *clk_reg_prcc(const char *name,
                return ERR_PTR(-EINVAL);
        }
 
-       clk = kzalloc(sizeof(struct clk_prcc), GFP_KERNEL);
-       if (!clk) {
-               pr_err("clk_prcc: %s could not allocate clk\n", __func__);
+       clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+       if (!clk)
                return ERR_PTR(-ENOMEM);
-       }
 
        clk->base = ioremap(phy_base, SZ_4K);
        if (!clk->base)
index 6e3e16b2e5caa947543855538cdf064f85293578..9d1f2d4550ad92cfbd2058a1bb53b5ddd81662c0 100644 (file)
@@ -258,11 +258,9 @@ static struct clk *clk_reg_prcmu(const char *name,
                return ERR_PTR(-EINVAL);
        }
 
-       clk = kzalloc(sizeof(struct clk_prcmu), GFP_KERNEL);
-       if (!clk) {
-               pr_err("clk_prcmu: %s could not allocate clk\n", __func__);
+       clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+       if (!clk)
                return ERR_PTR(-ENOMEM);
-       }
 
        clk->cg_sel = cg_sel;
        clk->is_prepared = 1;
index 8a4e93ce1e42cad595e8d8fa439e77f1ad67a2e0..7c0403b733ae4c5b236b58f3ea440cf0a2204a1c 100644 (file)
@@ -139,11 +139,9 @@ static struct clk *clk_reg_sysctrl(struct device *dev,
                return ERR_PTR(-EINVAL);
        }
 
-       clk = devm_kzalloc(dev, sizeof(struct clk_sysctrl), GFP_KERNEL);
-       if (!clk) {
-               dev_err(dev, "clk_sysctrl: could not allocate clk\n");
+       clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
+       if (!clk)
                return ERR_PTR(-ENOMEM);
-       }
 
        /* set main clock registers */
        clk->reg_sel[0] = reg_sel[0];
index 09fbe66f1f11cb41507f104a7458ed38d83e75cd..dafe7a45875d9ef7e27bde705396e6c0d3cbe045 100644 (file)
@@ -359,16 +359,13 @@ static struct clk *icst_clk_setup(struct device *dev,
        struct clk_init_data init;
        struct icst_params *pclone;
 
-       icst = kzalloc(sizeof(struct clk_icst), GFP_KERNEL);
-       if (!icst) {
-               pr_err("could not allocate ICST clock!\n");
+       icst = kzalloc(sizeof(*icst), GFP_KERNEL);
+       if (!icst)
                return ERR_PTR(-ENOMEM);
-       }
 
        pclone = kmemdup(desc->params, sizeof(*pclone), GFP_KERNEL);
        if (!pclone) {
                kfree(icst);
-               pr_err("could not clone ICST params\n");
                return ERR_PTR(-ENOMEM);
        }
 
index c40111f36d5e282ae9e1d9edb002fede6e346ec0..e9f9d400c322f10f04417d69456de75a4d3be17e 100644 (file)
 /* must be greater than maximal clock id */
 #define CLK_NR_CLKS            461
 
+/* Exynos4x12 ISP clocks */
+#define CLK_ISP_FIMC_ISP                1
+#define CLK_ISP_FIMC_DRC                2
+#define CLK_ISP_FIMC_FD                         3
+#define CLK_ISP_FIMC_LITE0              4
+#define CLK_ISP_FIMC_LITE1              5
+#define CLK_ISP_MCUISP                  6
+#define CLK_ISP_GICISP                  7
+#define CLK_ISP_SMMU_ISP                8
+#define CLK_ISP_SMMU_DRC                9
+#define CLK_ISP_SMMU_FD                        10
+#define CLK_ISP_SMMU_LITE0             11
+#define CLK_ISP_SMMU_LITE1             12
+#define CLK_ISP_PPMUISPMX              13
+#define CLK_ISP_PPMUISPX               14
+#define CLK_ISP_MCUCTL_ISP             15
+#define CLK_ISP_MPWM_ISP               16
+#define CLK_ISP_I2C0_ISP               17
+#define CLK_ISP_I2C1_ISP               18
+#define CLK_ISP_MTCADC_ISP             19
+#define CLK_ISP_PWM_ISP                        20
+#define CLK_ISP_WDT_ISP                        21
+#define CLK_ISP_UART_ISP               22
+#define CLK_ISP_ASYNCAXIM              23
+#define CLK_ISP_SMMU_ISPCX             24
+#define CLK_ISP_SPI0_ISP               25
+#define CLK_ISP_SPI1_ISP               26
+
+#define CLK_ISP_DIV_ISP0               27
+#define CLK_ISP_DIV_ISP1               28
+#define CLK_ISP_DIV_MCUISP0            29
+#define CLK_ISP_DIV_MCUISP1            30
+
+#define CLK_NR_ISP_CLKS                        31
+
 #endif /* _DT_BINDINGS_CLOCK_EXYNOS_4_H */
index 8c92528aa48ad1cd94494d6d0f09074ccff32c3f..8ba99a5e3fd34a64f8581ca51cedd47f11e803c5 100644 (file)
 #define CLKID_SD_EMMC_A_CLK0   119
 #define CLKID_SD_EMMC_B_CLK0   122
 #define CLKID_SD_EMMC_C_CLK0   125
+#define CLKID_VPU_0_SEL                126
+#define CLKID_VPU_0            128
+#define CLKID_VPU_1_SEL                129
+#define CLKID_VPU_1            131
+#define CLKID_VPU              132
+#define CLKID_VAPB_0_SEL       133
+#define CLKID_VAPB_0           135
+#define CLKID_VAPB_1_SEL       136
+#define CLKID_VAPB_1           138
+#define CLKID_VAPB_SEL         139
+#define CLKID_VAPB             140
 
 #endif /* __GXBB_CLKC_H */
index de62a83b6c802661b5f7cecae28a7fbabcd34076..e2f99ae72d5c56c07d0b66c167c1131b510d90c6 100644 (file)
 #define IMX7D_ARM_M4_ROOT_SRC          67
 #define IMX7D_ARM_M4_ROOT_CG           68
 #define IMX7D_ARM_M4_ROOT_DIV          69
-#define IMX7D_ARM_M0_ROOT_CLK          70
-#define IMX7D_ARM_M0_ROOT_SRC          71
-#define IMX7D_ARM_M0_ROOT_CG           72
-#define IMX7D_ARM_M0_ROOT_DIV          73
+#define IMX7D_ARM_M0_ROOT_CLK          70      /* unused */
+#define IMX7D_ARM_M0_ROOT_SRC          71      /* unused */
+#define IMX7D_ARM_M0_ROOT_CG           72      /* unused */
+#define IMX7D_ARM_M0_ROOT_DIV          73      /* unused */
 #define IMX7D_MAIN_AXI_ROOT_CLK                74
 #define IMX7D_MAIN_AXI_ROOT_SRC                75
 #define IMX7D_MAIN_AXI_ROOT_CG         76
diff --git a/include/dt-bindings/clock/mt2712-clk.h b/include/dt-bindings/clock/mt2712-clk.h
new file mode 100644 (file)
index 0000000..48a8e79
--- /dev/null
@@ -0,0 +1,427 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Weiyi Lu <weiyi.lu@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT2712_H
+#define _DT_BINDINGS_CLK_MT2712_H
+
+/* APMIXEDSYS */
+
+#define CLK_APMIXED_MAINPLL            0
+#define CLK_APMIXED_UNIVPLL            1
+#define CLK_APMIXED_VCODECPLL          2
+#define CLK_APMIXED_VENCPLL            3
+#define CLK_APMIXED_APLL1              4
+#define CLK_APMIXED_APLL2              5
+#define CLK_APMIXED_LVDSPLL            6
+#define CLK_APMIXED_LVDSPLL2           7
+#define CLK_APMIXED_MSDCPLL            8
+#define CLK_APMIXED_MSDCPLL2           9
+#define CLK_APMIXED_TVDPLL             10
+#define CLK_APMIXED_MMPLL              11
+#define CLK_APMIXED_ARMCA35PLL         12
+#define CLK_APMIXED_ARMCA72PLL         13
+#define CLK_APMIXED_ETHERPLL           14
+#define CLK_APMIXED_NR_CLK             15
+
+/* TOPCKGEN */
+
+#define CLK_TOP_ARMCA35PLL             0
+#define CLK_TOP_ARMCA35PLL_600M                1
+#define CLK_TOP_ARMCA35PLL_400M                2
+#define CLK_TOP_ARMCA72PLL             3
+#define CLK_TOP_SYSPLL                 4
+#define CLK_TOP_SYSPLL_D2              5
+#define CLK_TOP_SYSPLL1_D2             6
+#define CLK_TOP_SYSPLL1_D4             7
+#define CLK_TOP_SYSPLL1_D8             8
+#define CLK_TOP_SYSPLL1_D16            9
+#define CLK_TOP_SYSPLL_D3              10
+#define CLK_TOP_SYSPLL2_D2             11
+#define CLK_TOP_SYSPLL2_D4             12
+#define CLK_TOP_SYSPLL_D5              13
+#define CLK_TOP_SYSPLL3_D2             14
+#define CLK_TOP_SYSPLL3_D4             15
+#define CLK_TOP_SYSPLL_D7              16
+#define CLK_TOP_SYSPLL4_D2             17
+#define CLK_TOP_SYSPLL4_D4             18
+#define CLK_TOP_UNIVPLL                        19
+#define CLK_TOP_UNIVPLL_D7             20
+#define CLK_TOP_UNIVPLL_D26            21
+#define CLK_TOP_UNIVPLL_D52            22
+#define CLK_TOP_UNIVPLL_D104           23
+#define CLK_TOP_UNIVPLL_D208           24
+#define CLK_TOP_UNIVPLL_D2             25
+#define CLK_TOP_UNIVPLL1_D2            26
+#define CLK_TOP_UNIVPLL1_D4            27
+#define CLK_TOP_UNIVPLL1_D8            28
+#define CLK_TOP_UNIVPLL_D3             29
+#define CLK_TOP_UNIVPLL2_D2            30
+#define CLK_TOP_UNIVPLL2_D4            31
+#define CLK_TOP_UNIVPLL2_D8            32
+#define CLK_TOP_UNIVPLL_D5             33
+#define CLK_TOP_UNIVPLL3_D2            34
+#define CLK_TOP_UNIVPLL3_D4            35
+#define CLK_TOP_UNIVPLL3_D8            36
+#define CLK_TOP_F_MP0_PLL1             37
+#define CLK_TOP_F_MP0_PLL2             38
+#define CLK_TOP_F_BIG_PLL1             39
+#define CLK_TOP_F_BIG_PLL2             40
+#define CLK_TOP_F_BUS_PLL1             41
+#define CLK_TOP_F_BUS_PLL2             42
+#define CLK_TOP_APLL1                  43
+#define CLK_TOP_APLL1_D2               44
+#define CLK_TOP_APLL1_D4               45
+#define CLK_TOP_APLL1_D8               46
+#define CLK_TOP_APLL1_D16              47
+#define CLK_TOP_APLL2                  48
+#define CLK_TOP_APLL2_D2               49
+#define CLK_TOP_APLL2_D4               50
+#define CLK_TOP_APLL2_D8               51
+#define CLK_TOP_APLL2_D16              52
+#define CLK_TOP_LVDSPLL                        53
+#define CLK_TOP_LVDSPLL_D2             54
+#define CLK_TOP_LVDSPLL_D4             55
+#define CLK_TOP_LVDSPLL_D8             56
+#define CLK_TOP_LVDSPLL2               57
+#define CLK_TOP_LVDSPLL2_D2            58
+#define CLK_TOP_LVDSPLL2_D4            59
+#define CLK_TOP_LVDSPLL2_D8            60
+#define CLK_TOP_ETHERPLL_125M          61
+#define CLK_TOP_ETHERPLL_50M           62
+#define CLK_TOP_CVBS                   63
+#define CLK_TOP_CVBS_D2                        64
+#define CLK_TOP_SYS_26M                        65
+#define CLK_TOP_MMPLL                  66
+#define CLK_TOP_MMPLL_D2               67
+#define CLK_TOP_VENCPLL                        68
+#define CLK_TOP_VENCPLL_D2             69
+#define CLK_TOP_VCODECPLL              70
+#define CLK_TOP_VCODECPLL_D2           71
+#define CLK_TOP_TVDPLL                 72
+#define CLK_TOP_TVDPLL_D2              73
+#define CLK_TOP_TVDPLL_D4              74
+#define CLK_TOP_TVDPLL_D8              75
+#define CLK_TOP_TVDPLL_429M            76
+#define CLK_TOP_TVDPLL_429M_D2         77
+#define CLK_TOP_TVDPLL_429M_D4         78
+#define CLK_TOP_MSDCPLL                        79
+#define CLK_TOP_MSDCPLL_D2             80
+#define CLK_TOP_MSDCPLL_D4             81
+#define CLK_TOP_MSDCPLL2               82
+#define CLK_TOP_MSDCPLL2_D2            83
+#define CLK_TOP_MSDCPLL2_D4            84
+#define CLK_TOP_CLK26M_D2              85
+#define CLK_TOP_D2A_ULCLK_6P5M         86
+#define CLK_TOP_VPLL3_DPIX             87
+#define CLK_TOP_VPLL_DPIX              88
+#define CLK_TOP_LTEPLL_FS26M           89
+#define CLK_TOP_DMPLL                  90
+#define CLK_TOP_DSI0_LNTC              91
+#define CLK_TOP_DSI1_LNTC              92
+#define CLK_TOP_LVDSTX3_CLKDIG_CTS     93
+#define CLK_TOP_LVDSTX_CLKDIG_CTS      94
+#define CLK_TOP_CLKRTC_EXT             95
+#define CLK_TOP_CLKRTC_INT             96
+#define CLK_TOP_CSI0                   97
+#define CLK_TOP_CVBSPLL                        98
+#define CLK_TOP_AXI_SEL                        99
+#define CLK_TOP_MEM_SEL                        100
+#define CLK_TOP_MM_SEL                 101
+#define CLK_TOP_PWM_SEL                        102
+#define CLK_TOP_VDEC_SEL               103
+#define CLK_TOP_VENC_SEL               104
+#define CLK_TOP_MFG_SEL                        105
+#define CLK_TOP_CAMTG_SEL              106
+#define CLK_TOP_UART_SEL               107
+#define CLK_TOP_SPI_SEL                        108
+#define CLK_TOP_USB20_SEL              109
+#define CLK_TOP_USB30_SEL              110
+#define CLK_TOP_MSDC50_0_HCLK_SEL      111
+#define CLK_TOP_MSDC50_0_SEL           112
+#define CLK_TOP_MSDC30_1_SEL           113
+#define CLK_TOP_MSDC30_2_SEL           114
+#define CLK_TOP_MSDC30_3_SEL           115
+#define CLK_TOP_AUDIO_SEL              116
+#define CLK_TOP_AUD_INTBUS_SEL         117
+#define CLK_TOP_PMICSPI_SEL            118
+#define CLK_TOP_DPILVDS1_SEL           119
+#define CLK_TOP_ATB_SEL                        120
+#define CLK_TOP_NR_SEL                 121
+#define CLK_TOP_NFI2X_SEL              122
+#define CLK_TOP_IRDA_SEL               123
+#define CLK_TOP_CCI400_SEL             124
+#define CLK_TOP_AUD_1_SEL              125
+#define CLK_TOP_AUD_2_SEL              126
+#define CLK_TOP_MEM_MFG_IN_AS_SEL      127
+#define CLK_TOP_AXI_MFG_IN_AS_SEL      128
+#define CLK_TOP_SCAM_SEL               129
+#define CLK_TOP_NFIECC_SEL             130
+#define CLK_TOP_PE2_MAC_P0_SEL         131
+#define CLK_TOP_PE2_MAC_P1_SEL         132
+#define CLK_TOP_DPILVDS_SEL            133
+#define CLK_TOP_MSDC50_3_HCLK_SEL      134
+#define CLK_TOP_HDCP_SEL               135
+#define CLK_TOP_HDCP_24M_SEL           136
+#define CLK_TOP_RTC_SEL                        137
+#define CLK_TOP_SPINOR_SEL             138
+#define CLK_TOP_APLL_SEL               139
+#define CLK_TOP_APLL2_SEL              140
+#define CLK_TOP_A1SYS_HP_SEL           141
+#define CLK_TOP_A2SYS_HP_SEL           142
+#define CLK_TOP_ASM_L_SEL              143
+#define CLK_TOP_ASM_M_SEL              144
+#define CLK_TOP_ASM_H_SEL              145
+#define CLK_TOP_I2SO1_SEL              146
+#define CLK_TOP_I2SO2_SEL              147
+#define CLK_TOP_I2SO3_SEL              148
+#define CLK_TOP_TDMO0_SEL              149
+#define CLK_TOP_TDMO1_SEL              150
+#define CLK_TOP_I2SI1_SEL              151
+#define CLK_TOP_I2SI2_SEL              152
+#define CLK_TOP_I2SI3_SEL              153
+#define CLK_TOP_ETHER_125M_SEL         154
+#define CLK_TOP_ETHER_50M_SEL          155
+#define CLK_TOP_JPGDEC_SEL             156
+#define CLK_TOP_SPISLV_SEL             157
+#define CLK_TOP_ETHER_50M_RMII_SEL     158
+#define CLK_TOP_CAM2TG_SEL             159
+#define CLK_TOP_DI_SEL                 160
+#define CLK_TOP_TVD_SEL                        161
+#define CLK_TOP_I2C_SEL                        162
+#define CLK_TOP_PWM_INFRA_SEL          163
+#define CLK_TOP_MSDC0P_AES_SEL         164
+#define CLK_TOP_CMSYS_SEL              165
+#define CLK_TOP_GCPU_SEL               166
+#define CLK_TOP_AUD_APLL1_SEL          167
+#define CLK_TOP_AUD_APLL2_SEL          168
+#define CLK_TOP_DA_AUDULL_VTX_6P5M_SEL 169
+#define CLK_TOP_APLL_DIV0              170
+#define CLK_TOP_APLL_DIV1              171
+#define CLK_TOP_APLL_DIV2              172
+#define CLK_TOP_APLL_DIV3              173
+#define CLK_TOP_APLL_DIV4              174
+#define CLK_TOP_APLL_DIV5              175
+#define CLK_TOP_APLL_DIV6              176
+#define CLK_TOP_APLL_DIV7              177
+#define CLK_TOP_APLL_DIV_PDN0          178
+#define CLK_TOP_APLL_DIV_PDN1          179
+#define CLK_TOP_APLL_DIV_PDN2          180
+#define CLK_TOP_APLL_DIV_PDN3          181
+#define CLK_TOP_APLL_DIV_PDN4          182
+#define CLK_TOP_APLL_DIV_PDN5          183
+#define CLK_TOP_APLL_DIV_PDN6          184
+#define CLK_TOP_APLL_DIV_PDN7          185
+#define CLK_TOP_NR_CLK                 186
+
+/* INFRACFG */
+
+#define CLK_INFRA_DBGCLK               0
+#define CLK_INFRA_GCE                  1
+#define CLK_INFRA_M4U                  2
+#define CLK_INFRA_KP                   3
+#define CLK_INFRA_AO_SPI0              4
+#define CLK_INFRA_AO_SPI1              5
+#define CLK_INFRA_AO_UART5             6
+#define CLK_INFRA_NR_CLK               7
+
+/* PERICFG */
+
+#define CLK_PERI_NFI                   0
+#define CLK_PERI_THERM                 1
+#define CLK_PERI_PWM0                  2
+#define CLK_PERI_PWM1                  3
+#define CLK_PERI_PWM2                  4
+#define CLK_PERI_PWM3                  5
+#define CLK_PERI_PWM4                  6
+#define CLK_PERI_PWM5                  7
+#define CLK_PERI_PWM6                  8
+#define CLK_PERI_PWM7                  9
+#define CLK_PERI_PWM                   10
+#define CLK_PERI_AP_DMA                        11
+#define CLK_PERI_MSDC30_0              12
+#define CLK_PERI_MSDC30_1              13
+#define CLK_PERI_MSDC30_2              14
+#define CLK_PERI_MSDC30_3              15
+#define CLK_PERI_UART0                 16
+#define CLK_PERI_UART1                 17
+#define CLK_PERI_UART2                 18
+#define CLK_PERI_UART3                 19
+#define CLK_PERI_I2C0                  20
+#define CLK_PERI_I2C1                  21
+#define CLK_PERI_I2C2                  22
+#define CLK_PERI_I2C3                  23
+#define CLK_PERI_I2C4                  24
+#define CLK_PERI_AUXADC                        25
+#define CLK_PERI_SPI0                  26
+#define CLK_PERI_SPI                   27
+#define CLK_PERI_I2C5                  28
+#define CLK_PERI_SPI2                  29
+#define CLK_PERI_SPI3                  30
+#define CLK_PERI_SPI5                  31
+#define CLK_PERI_UART4                 32
+#define CLK_PERI_SFLASH                        33
+#define CLK_PERI_GMAC                  34
+#define CLK_PERI_PCIE0                 35
+#define CLK_PERI_PCIE1                 36
+#define CLK_PERI_GMAC_PCLK             37
+#define CLK_PERI_MSDC50_0_EN           38
+#define CLK_PERI_MSDC30_1_EN           39
+#define CLK_PERI_MSDC30_2_EN           40
+#define CLK_PERI_MSDC30_3_EN           41
+#define CLK_PERI_MSDC50_0_HCLK_EN      42
+#define CLK_PERI_MSDC50_3_HCLK_EN      43
+#define CLK_PERI_NR_CLK                        44
+
+/* MCUCFG */
+
+#define CLK_MCU_MP0_SEL                        0
+#define CLK_MCU_MP2_SEL                        1
+#define CLK_MCU_BUS_SEL                        2
+#define CLK_MCU_NR_CLK                 3
+
+/* MFGCFG */
+
+#define CLK_MFG_BG3D                   0
+#define CLK_MFG_NR_CLK                 1
+
+/* MMSYS */
+
+#define CLK_MM_SMI_COMMON              0
+#define CLK_MM_SMI_LARB0               1
+#define CLK_MM_CAM_MDP                 2
+#define CLK_MM_MDP_RDMA0               3
+#define CLK_MM_MDP_RDMA1               4
+#define CLK_MM_MDP_RSZ0                        5
+#define CLK_MM_MDP_RSZ1                        6
+#define CLK_MM_MDP_RSZ2                        7
+#define CLK_MM_MDP_TDSHP0              8
+#define CLK_MM_MDP_TDSHP1              9
+#define CLK_MM_MDP_CROP                        10
+#define CLK_MM_MDP_WDMA                        11
+#define CLK_MM_MDP_WROT0               12
+#define CLK_MM_MDP_WROT1               13
+#define CLK_MM_FAKE_ENG                        14
+#define CLK_MM_MUTEX_32K               15
+#define CLK_MM_DISP_OVL0               16
+#define CLK_MM_DISP_OVL1               17
+#define CLK_MM_DISP_RDMA0              18
+#define CLK_MM_DISP_RDMA1              19
+#define CLK_MM_DISP_RDMA2              20
+#define CLK_MM_DISP_WDMA0              21
+#define CLK_MM_DISP_WDMA1              22
+#define CLK_MM_DISP_COLOR0             23
+#define CLK_MM_DISP_COLOR1             24
+#define CLK_MM_DISP_AAL                        25
+#define CLK_MM_DISP_GAMMA              26
+#define CLK_MM_DISP_UFOE               27
+#define CLK_MM_DISP_SPLIT0             28
+#define CLK_MM_DISP_OD                 29
+#define CLK_MM_DISP_PWM0_MM            30
+#define CLK_MM_DISP_PWM0_26M           31
+#define CLK_MM_DISP_PWM1_MM            32
+#define CLK_MM_DISP_PWM1_26M           33
+#define CLK_MM_DSI0_ENGINE             34
+#define CLK_MM_DSI0_DIGITAL            35
+#define CLK_MM_DSI1_ENGINE             36
+#define CLK_MM_DSI1_DIGITAL            37
+#define CLK_MM_DPI_PIXEL               38
+#define CLK_MM_DPI_ENGINE              39
+#define CLK_MM_DPI1_PIXEL              40
+#define CLK_MM_DPI1_ENGINE             41
+#define CLK_MM_LVDS_PIXEL              42
+#define CLK_MM_LVDS_CTS                        43
+#define CLK_MM_SMI_LARB4               44
+#define CLK_MM_SMI_COMMON1             45
+#define CLK_MM_SMI_LARB5               46
+#define CLK_MM_MDP_RDMA2               47
+#define CLK_MM_MDP_TDSHP2              48
+#define CLK_MM_DISP_OVL2               49
+#define CLK_MM_DISP_WDMA2              50
+#define CLK_MM_DISP_COLOR2             51
+#define CLK_MM_DISP_AAL1               52
+#define CLK_MM_DISP_OD1                        53
+#define CLK_MM_LVDS1_PIXEL             54
+#define CLK_MM_LVDS1_CTS               55
+#define CLK_MM_SMI_LARB7               56
+#define CLK_MM_MDP_RDMA3               57
+#define CLK_MM_MDP_WROT2               58
+#define CLK_MM_DSI2                    59
+#define CLK_MM_DSI2_DIGITAL            60
+#define CLK_MM_DSI3                    61
+#define CLK_MM_DSI3_DIGITAL            62
+#define CLK_MM_NR_CLK                  63
+
+/* IMGSYS */
+
+#define CLK_IMG_SMI_LARB2              0
+#define CLK_IMG_SENINF_SCAM_EN         1
+#define CLK_IMG_SENINF_CAM_EN          2
+#define CLK_IMG_CAM_SV_EN              3
+#define CLK_IMG_CAM_SV1_EN             4
+#define CLK_IMG_CAM_SV2_EN             5
+#define CLK_IMG_NR_CLK                 6
+
+/* BDPSYS */
+
+#define CLK_BDP_BRIDGE_B               0
+#define CLK_BDP_BRIDGE_DRAM            1
+#define CLK_BDP_LARB_DRAM              2
+#define CLK_BDP_WR_CHANNEL_VDI_PXL     3
+#define CLK_BDP_WR_CHANNEL_VDI_DRAM    4
+#define CLK_BDP_WR_CHANNEL_VDI_B       5
+#define CLK_BDP_MT_B                   6
+#define CLK_BDP_DISPFMT_27M            7
+#define CLK_BDP_DISPFMT_27M_VDOUT      8
+#define CLK_BDP_DISPFMT_27_74_74       9
+#define CLK_BDP_DISPFMT_2FS            10
+#define CLK_BDP_DISPFMT_2FS_2FS74_148  11
+#define CLK_BDP_DISPFMT_B              12
+#define CLK_BDP_VDO_DRAM               13
+#define CLK_BDP_VDO_2FS                        14
+#define CLK_BDP_VDO_B                  15
+#define CLK_BDP_WR_CHANNEL_DI_PXL      16
+#define CLK_BDP_WR_CHANNEL_DI_DRAM     17
+#define CLK_BDP_WR_CHANNEL_DI_B                18
+#define CLK_BDP_NR_AGENT               19
+#define CLK_BDP_NR_DRAM                        20
+#define CLK_BDP_NR_B                   21
+#define CLK_BDP_BRIDGE_RT_B            22
+#define CLK_BDP_BRIDGE_RT_DRAM         23
+#define CLK_BDP_LARB_RT_DRAM           24
+#define CLK_BDP_TVD_TDC                        25
+#define CLK_BDP_TVD_54                 26
+#define CLK_BDP_TVD_CBUS               27
+#define CLK_BDP_NR_CLK                 28
+
+/* VDECSYS */
+
+#define CLK_VDEC_CKEN                  0
+#define CLK_VDEC_LARB1_CKEN            1
+#define CLK_VDEC_IMGRZ_CKEN            2
+#define CLK_VDEC_NR_CLK                        3
+
+/* VENCSYS */
+
+#define CLK_VENC_SMI_COMMON_CON                0
+#define CLK_VENC_VENC                  1
+#define CLK_VENC_SMI_LARB6             2
+#define CLK_VENC_NR_CLK                        3
+
+/* JPGDECSYS */
+
+#define CLK_JPGDEC_JPGDEC1             0
+#define CLK_JPGDEC_JPGDEC              1
+#define CLK_JPGDEC_NR_CLK              2
+
+#endif /* _DT_BINDINGS_CLK_MT2712_H */
diff --git a/include/dt-bindings/clock/mt7622-clk.h b/include/dt-bindings/clock/mt7622-clk.h
new file mode 100644 (file)
index 0000000..3e514ed
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT7622_H
+#define _DT_BINDINGS_CLK_MT7622_H
+
+/* TOPCKGEN */
+
+#define CLK_TOP_TO_U2_PHY              0
+#define CLK_TOP_TO_U2_PHY_1P           1
+#define CLK_TOP_PCIE0_PIPE_EN          2
+#define CLK_TOP_PCIE1_PIPE_EN          3
+#define CLK_TOP_SSUSB_TX250M           4
+#define CLK_TOP_SSUSB_EQ_RX250M                5
+#define CLK_TOP_SSUSB_CDR_REF          6
+#define CLK_TOP_SSUSB_CDR_FB           7
+#define CLK_TOP_SATA_ASIC              8
+#define CLK_TOP_SATA_RBC               9
+#define CLK_TOP_TO_USB3_SYS            10
+#define CLK_TOP_P1_1MHZ                        11
+#define CLK_TOP_4MHZ                   12
+#define CLK_TOP_P0_1MHZ                        13
+#define CLK_TOP_TXCLK_SRC_PRE          14
+#define CLK_TOP_RTC                    15
+#define CLK_TOP_MEMPLL                 16
+#define CLK_TOP_DMPLL                  17
+#define CLK_TOP_SYSPLL_D2              18
+#define CLK_TOP_SYSPLL1_D2             19
+#define CLK_TOP_SYSPLL1_D4             20
+#define CLK_TOP_SYSPLL1_D8             21
+#define CLK_TOP_SYSPLL2_D4             22
+#define CLK_TOP_SYSPLL2_D8             23
+#define CLK_TOP_SYSPLL_D5              24
+#define CLK_TOP_SYSPLL3_D2             25
+#define CLK_TOP_SYSPLL3_D4             26
+#define CLK_TOP_SYSPLL4_D2             27
+#define CLK_TOP_SYSPLL4_D4             28
+#define CLK_TOP_SYSPLL4_D16            29
+#define CLK_TOP_UNIVPLL                        30
+#define CLK_TOP_UNIVPLL_D2             31
+#define CLK_TOP_UNIVPLL1_D2            32
+#define CLK_TOP_UNIVPLL1_D4            33
+#define CLK_TOP_UNIVPLL1_D8            34
+#define CLK_TOP_UNIVPLL1_D16           35
+#define CLK_TOP_UNIVPLL2_D2            36
+#define CLK_TOP_UNIVPLL2_D4            37
+#define CLK_TOP_UNIVPLL2_D8            38
+#define CLK_TOP_UNIVPLL2_D16           39
+#define CLK_TOP_UNIVPLL_D5             40
+#define CLK_TOP_UNIVPLL3_D2            41
+#define CLK_TOP_UNIVPLL3_D4            42
+#define CLK_TOP_UNIVPLL3_D16           43
+#define CLK_TOP_UNIVPLL_D7             44
+#define CLK_TOP_UNIVPLL_D80_D4         45
+#define CLK_TOP_UNIV48M                        46
+#define CLK_TOP_SGMIIPLL               47
+#define CLK_TOP_SGMIIPLL_D2            48
+#define CLK_TOP_AUD1PLL                        49
+#define CLK_TOP_AUD2PLL                        50
+#define CLK_TOP_AUD_I2S2_MCK           51
+#define CLK_TOP_TO_USB3_REF            52
+#define CLK_TOP_PCIE1_MAC_EN           53
+#define CLK_TOP_PCIE0_MAC_EN           54
+#define CLK_TOP_ETH_500M               55
+#define CLK_TOP_AXI_SEL                        56
+#define CLK_TOP_MEM_SEL                        57
+#define CLK_TOP_DDRPHYCFG_SEL          58
+#define CLK_TOP_ETH_SEL                        59
+#define CLK_TOP_PWM_SEL                        60
+#define CLK_TOP_F10M_REF_SEL           61
+#define CLK_TOP_NFI_INFRA_SEL          62
+#define CLK_TOP_FLASH_SEL              63
+#define CLK_TOP_UART_SEL               64
+#define CLK_TOP_SPI0_SEL               65
+#define CLK_TOP_SPI1_SEL               66
+#define CLK_TOP_MSDC50_0_SEL           67
+#define CLK_TOP_MSDC30_0_SEL           68
+#define CLK_TOP_MSDC30_1_SEL           69
+#define CLK_TOP_A1SYS_HP_SEL           70
+#define CLK_TOP_A2SYS_HP_SEL           71
+#define CLK_TOP_INTDIR_SEL             72
+#define CLK_TOP_AUD_INTBUS_SEL         73
+#define CLK_TOP_PMICSPI_SEL            74
+#define CLK_TOP_SCP_SEL                        75
+#define CLK_TOP_ATB_SEL                        76
+#define CLK_TOP_HIF_SEL                        77
+#define CLK_TOP_AUDIO_SEL              78
+#define CLK_TOP_U2_SEL                 79
+#define CLK_TOP_AUD1_SEL               80
+#define CLK_TOP_AUD2_SEL               81
+#define CLK_TOP_IRRX_SEL               82
+#define CLK_TOP_IRTX_SEL               83
+#define CLK_TOP_ASM_L_SEL              84
+#define CLK_TOP_ASM_M_SEL              85
+#define CLK_TOP_ASM_H_SEL              86
+#define CLK_TOP_APLL1_SEL              87
+#define CLK_TOP_APLL2_SEL              88
+#define CLK_TOP_I2S0_MCK_SEL           89
+#define CLK_TOP_I2S1_MCK_SEL           90
+#define CLK_TOP_I2S2_MCK_SEL           91
+#define CLK_TOP_I2S3_MCK_SEL           92
+#define CLK_TOP_APLL1_DIV              93
+#define CLK_TOP_APLL2_DIV              94
+#define CLK_TOP_I2S0_MCK_DIV           95
+#define CLK_TOP_I2S1_MCK_DIV           96
+#define CLK_TOP_I2S2_MCK_DIV           97
+#define CLK_TOP_I2S3_MCK_DIV           98
+#define CLK_TOP_A1SYS_HP_DIV           99
+#define CLK_TOP_A2SYS_HP_DIV           100
+#define CLK_TOP_APLL1_DIV_PD           101
+#define CLK_TOP_APLL2_DIV_PD           102
+#define CLK_TOP_I2S0_MCK_DIV_PD                103
+#define CLK_TOP_I2S1_MCK_DIV_PD                104
+#define CLK_TOP_I2S2_MCK_DIV_PD                105
+#define CLK_TOP_I2S3_MCK_DIV_PD                106
+#define CLK_TOP_A1SYS_HP_DIV_PD                107
+#define CLK_TOP_A2SYS_HP_DIV_PD                108
+#define CLK_TOP_NR_CLK                 109
+
+/* INFRACFG */
+
+#define CLK_INFRA_MUX1_SEL             0
+#define CLK_INFRA_DBGCLK_PD            1
+#define CLK_INFRA_AUDIO_PD             2
+#define CLK_INFRA_IRRX_PD              3
+#define CLK_INFRA_APXGPT_PD            4
+#define CLK_INFRA_PMIC_PD              5
+#define CLK_INFRA_TRNG                 6
+#define CLK_INFRA_NR_CLK               7
+
+/* PERICFG */
+
+#define CLK_PERIBUS_SEL                        0
+#define CLK_PERI_THERM_PD              1
+#define CLK_PERI_PWM1_PD               2
+#define CLK_PERI_PWM2_PD               3
+#define CLK_PERI_PWM3_PD               4
+#define CLK_PERI_PWM4_PD               5
+#define CLK_PERI_PWM5_PD               6
+#define CLK_PERI_PWM6_PD               7
+#define CLK_PERI_PWM7_PD               8
+#define CLK_PERI_PWM_PD                        9
+#define CLK_PERI_AP_DMA_PD             10
+#define CLK_PERI_MSDC30_0_PD           11
+#define CLK_PERI_MSDC30_1_PD           12
+#define CLK_PERI_UART0_PD              13
+#define CLK_PERI_UART1_PD              14
+#define CLK_PERI_UART2_PD              15
+#define CLK_PERI_UART3_PD              16
+#define CLK_PERI_UART4_PD              17
+#define CLK_PERI_BTIF_PD               18
+#define CLK_PERI_I2C0_PD               19
+#define CLK_PERI_I2C1_PD               20
+#define CLK_PERI_I2C2_PD               21
+#define CLK_PERI_SPI1_PD               22
+#define CLK_PERI_AUXADC_PD             23
+#define CLK_PERI_SPI0_PD               24
+#define CLK_PERI_SNFI_PD               25
+#define CLK_PERI_NFI_PD                        26
+#define CLK_PERI_NFIECC_PD             27
+#define CLK_PERI_FLASH_PD              28
+#define CLK_PERI_IRTX_PD               29
+#define CLK_PERI_NR_CLK                        30
+
+/* APMIXEDSYS */
+
+#define CLK_APMIXED_ARMPLL             0
+#define CLK_APMIXED_MAINPLL            1
+#define CLK_APMIXED_UNIV2PLL           2
+#define CLK_APMIXED_ETH1PLL            3
+#define CLK_APMIXED_ETH2PLL            4
+#define CLK_APMIXED_AUD1PLL            5
+#define CLK_APMIXED_AUD2PLL            6
+#define CLK_APMIXED_TRGPLL             7
+#define CLK_APMIXED_SGMIPLL            8
+#define CLK_APMIXED_MAIN_CORE_EN       9
+#define CLK_APMIXED_NR_CLK             10
+
+/* AUDIOSYS */
+
+#define CLK_AUDIO_AFE                  0
+#define CLK_AUDIO_HDMI                 1
+#define CLK_AUDIO_SPDF                 2
+#define CLK_AUDIO_APLL                 3
+#define CLK_AUDIO_I2SIN1               4
+#define CLK_AUDIO_I2SIN2               5
+#define CLK_AUDIO_I2SIN3               6
+#define CLK_AUDIO_I2SIN4               7
+#define CLK_AUDIO_I2SO1                        8
+#define CLK_AUDIO_I2SO2                        9
+#define CLK_AUDIO_I2SO3                        10
+#define CLK_AUDIO_I2SO4                        11
+#define CLK_AUDIO_ASRCI1               12
+#define CLK_AUDIO_ASRCI2               13
+#define CLK_AUDIO_ASRCO1               14
+#define CLK_AUDIO_ASRCO2               15
+#define CLK_AUDIO_INTDIR               16
+#define CLK_AUDIO_A1SYS                        17
+#define CLK_AUDIO_A2SYS                        18
+#define CLK_AUDIO_UL1                  19
+#define CLK_AUDIO_UL2                  20
+#define CLK_AUDIO_UL3                  21
+#define CLK_AUDIO_UL4                  22
+#define CLK_AUDIO_UL5                  23
+#define CLK_AUDIO_UL6                  24
+#define CLK_AUDIO_DL1                  25
+#define CLK_AUDIO_DL2                  26
+#define CLK_AUDIO_DL3                  27
+#define CLK_AUDIO_DL4                  28
+#define CLK_AUDIO_DL5                  29
+#define CLK_AUDIO_DL6                  30
+#define CLK_AUDIO_DLMCH                        31
+#define CLK_AUDIO_ARB1                 32
+#define CLK_AUDIO_AWB                  33
+#define CLK_AUDIO_AWB2                 34
+#define CLK_AUDIO_DAI                  35
+#define CLK_AUDIO_MOD                  36
+#define CLK_AUDIO_ASRCI3               37
+#define CLK_AUDIO_ASRCI4               38
+#define CLK_AUDIO_ASRCO3               39
+#define CLK_AUDIO_ASRCO4               40
+#define CLK_AUDIO_MEM_ASRC1            41
+#define CLK_AUDIO_MEM_ASRC2            42
+#define CLK_AUDIO_MEM_ASRC3            43
+#define CLK_AUDIO_MEM_ASRC4            44
+#define CLK_AUDIO_MEM_ASRC5            45
+#define CLK_AUDIO_NR_CLK               46
+
+/* SSUSBSYS */
+
+#define CLK_SSUSB_U2_PHY_1P_EN         0
+#define CLK_SSUSB_U2_PHY_EN            1
+#define CLK_SSUSB_REF_EN               2
+#define CLK_SSUSB_SYS_EN               3
+#define CLK_SSUSB_MCU_EN               4
+#define CLK_SSUSB_DMA_EN               5
+#define CLK_SSUSB_NR_CLK               6
+
+/* PCIESYS */
+
+#define CLK_PCIE_P1_AUX_EN             0
+#define CLK_PCIE_P1_OBFF_EN            1
+#define CLK_PCIE_P1_AHB_EN             2
+#define CLK_PCIE_P1_AXI_EN             3
+#define CLK_PCIE_P1_MAC_EN             4
+#define CLK_PCIE_P1_PIPE_EN            5
+#define CLK_PCIE_P0_AUX_EN             6
+#define CLK_PCIE_P0_OBFF_EN            7
+#define CLK_PCIE_P0_AHB_EN             8
+#define CLK_PCIE_P0_AXI_EN             9
+#define CLK_PCIE_P0_MAC_EN             10
+#define CLK_PCIE_P0_PIPE_EN            11
+#define CLK_SATA_AHB_EN                        12
+#define CLK_SATA_AXI_EN                        13
+#define CLK_SATA_ASIC_EN               14
+#define CLK_SATA_RBC_EN                        15
+#define CLK_SATA_PM_EN                 16
+#define CLK_PCIE_NR_CLK                        17
+
+/* ETHSYS */
+
+#define CLK_ETH_HSDMA_EN               0
+#define CLK_ETH_ESW_EN                 1
+#define CLK_ETH_GP2_EN                 2
+#define CLK_ETH_GP1_EN                 3
+#define CLK_ETH_GP0_EN                 4
+#define CLK_ETH_NR_CLK                 5
+
+/* SGMIISYS */
+
+#define CLK_SGMII_TX250M_EN            0
+#define CLK_SGMII_RX250M_EN            1
+#define CLK_SGMII_CDR_REF              2
+#define CLK_SGMII_CDR_FB               3
+#define CLK_SGMII_NR_CLK               4
+
+#endif /* _DT_BINDINGS_CLK_MT7622_H */
+
index 96b63c00249eeb201fef1f994905d586b5608c72..b8337a5fa34775330e28fb1a6c42aae20b520489 100644 (file)
@@ -37,6 +37,9 @@
 #define RPM_SYS_FABRIC_A_CLK                   19
 #define RPM_SFPB_CLK                           20
 #define RPM_SFPB_A_CLK                         21
+#define RPM_SMI_CLK                            22
+#define RPM_SMI_A_CLK                          23
+#define RPM_PLL4_CLK                           24
 
 /* SMD RPM clocks */
 #define RPM_SMD_XO_CLK_SRC                             0
 #define RPM_SMD_CXO_A1_A_PIN                   59
 #define RPM_SMD_CXO_A2_PIN                     60
 #define RPM_SMD_CXO_A2_A_PIN                   61
+#define RPM_SMD_AGGR1_NOC_CLK                  62
+#define RPM_SMD_AGGR1_NOC_A_CLK                        63
+#define RPM_SMD_AGGR2_NOC_CLK                  64
+#define RPM_SMD_AGGR2_NOC_A_CLK                        65
+#define RPM_SMD_MMAXI_CLK                      66
+#define RPM_SMD_MMAXI_A_CLK                    67
+#define RPM_SMD_IPA_CLK                                68
+#define RPM_SMD_IPA_A_CLK                      69
+#define RPM_SMD_CE1_CLK                                70
+#define RPM_SMD_CE1_A_CLK                      71
+#define RPM_SMD_DIV_CLK3                       72
+#define RPM_SMD_DIV_A_CLK3                     73
+#define RPM_SMD_LN_BB_CLK                      74
+#define RPM_SMD_LN_BB_A_CLK                    75
 
 #endif
diff --git a/include/dt-bindings/clock/r8a77970-cpg-mssr.h b/include/dt-bindings/clock/r8a77970-cpg-mssr.h
new file mode 100644 (file)
index 0000000..4146395
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 Renesas Electronics Corp.
+ * Copyright (C) 2017 Cogent Embedded, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __DT_BINDINGS_CLOCK_R8A77970_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R8A77970_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* r8a77970 CPG Core Clocks */
+#define R8A77970_CLK_Z2                        0
+#define R8A77970_CLK_ZR                        1
+#define R8A77970_CLK_ZTR               2
+#define R8A77970_CLK_ZTRD2             3
+#define R8A77970_CLK_ZT                        4
+#define R8A77970_CLK_ZX                        5
+#define R8A77970_CLK_S1D1              6
+#define R8A77970_CLK_S1D2              7
+#define R8A77970_CLK_S1D4              8
+#define R8A77970_CLK_S2D1              9
+#define R8A77970_CLK_S2D2              10
+#define R8A77970_CLK_S2D4              11
+#define R8A77970_CLK_LB                        12
+#define R8A77970_CLK_CL                        13
+#define R8A77970_CLK_ZB3               14
+#define R8A77970_CLK_ZB3D2             15
+#define R8A77970_CLK_DDR               16
+#define R8A77970_CLK_CR                        17
+#define R8A77970_CLK_CRD2              18
+#define R8A77970_CLK_SD0H              19
+#define R8A77970_CLK_SD0               20
+#define R8A77970_CLK_RPC               21
+#define R8A77970_CLK_RPCD2             22
+#define R8A77970_CLK_MSO               23
+#define R8A77970_CLK_CANFD             24
+#define R8A77970_CLK_CSI0              25
+#define R8A77970_CLK_FRAY              26
+#define R8A77970_CLK_CP                        27
+#define R8A77970_CLK_CPEX              28
+#define R8A77970_CLK_R                 29
+#define R8A77970_CLK_OSC               30
+
+#endif /* __DT_BINDINGS_CLOCK_R8A77970_CPG_MSSR_H__ */
index 37e66b054d64a1bfb96a5fed7ebbb3aa55219db3..f3ba68a25ecb2a82dbb92169928165a11fb642e5 100644 (file)
@@ -26,6 +26,8 @@
 #define ARMCLK                 4
 #define HCLK                   5
 #define PCLK                   6
+#define MPLL                   7
+#define EPLL                   8
 
 /* Special clocks */
 #define SCLK_HSSPI0            16
index c5a53f38d654048e2c9c8bc2bd3f2f850316bb7c..e4fa61be5c759087c3629441258c38200f400286 100644 (file)
@@ -43,6 +43,8 @@
 #define _DT_BINDINGS_CLK_SUN4I_A10_H_
 
 #define CLK_HOSC               1
+#define CLK_PLL_VIDEO0_2X      9
+#define CLK_PLL_VIDEO1_2X      18
 #define CLK_CPU                        20
 
 /* AHB Gates */
index 4482530fb6f5e005ea2e2a2425a91bb61ed85f61..c5d13340184aada0817376a662f7ae247648aeb5 100644 (file)
 #ifndef _DT_BINDINGS_CLK_SUN6I_A31_H_
 #define _DT_BINDINGS_CLK_SUN6I_A31_H_
 
+#define CLK_PLL_VIDEO0_2X      7
+
 #define CLK_PLL_PERIPH         10
 
+#define CLK_PLL_VIDEO1_2X      13
+
 #define CLK_CPU                        18
 
 #define CLK_AHB1_MIPIDSI       23
index 5100ec1b5d559f93b93a12b320feefe148f23b30..7c925e6211f12eb91b1236d091eed57180899138 100644 (file)
@@ -682,10 +682,10 @@ struct clk_gpio {
 
 extern const struct clk_ops clk_gpio_gate_ops;
 struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
-               const char *parent_name, unsigned gpio, bool active_low,
+               const char *parent_name, struct gpio_desc *gpiod,
                unsigned long flags);
 struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
-               const char *parent_name, unsigned gpio, bool active_low,
+               const char *parent_name, struct gpio_desc *gpiod,
                unsigned long flags);
 void clk_hw_unregister_gpio_gate(struct clk_hw *hw);
 
@@ -701,11 +701,11 @@ void clk_hw_unregister_gpio_gate(struct clk_hw *hw);
 
 extern const struct clk_ops clk_gpio_mux_ops;
 struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents, unsigned gpio,
-               bool active_low, unsigned long flags);
+               const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
+               unsigned long flags);
 struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents, unsigned gpio,
-               bool active_low, unsigned long flags);
+               const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
+               unsigned long flags);
 void clk_hw_unregister_gpio_mux(struct clk_hw *hw);
 
 /**
@@ -815,7 +815,12 @@ int of_clk_add_hw_provider(struct device_node *np,
                           struct clk_hw *(*get)(struct of_phandle_args *clkspec,
                                                 void *data),
                           void *data);
+int devm_of_clk_add_hw_provider(struct device *dev,
+                          struct clk_hw *(*get)(struct of_phandle_args *clkspec,
+                                                void *data),
+                          void *data);
 void of_clk_del_provider(struct device_node *np);
+void devm_of_clk_del_provider(struct device *dev);
 struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
                                  void *data);
 struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec,
@@ -847,7 +852,15 @@ static inline int of_clk_add_hw_provider(struct device_node *np,
 {
        return 0;
 }
+static inline int devm_of_clk_add_hw_provider(struct device *dev,
+                          struct clk_hw *(*get)(struct of_phandle_args *clkspec,
+                                                void *data),
+                          void *data)
+{
+       return 0;
+}
 static inline void of_clk_del_provider(struct device_node *np) {}
+static inline void devm_of_clk_del_provider(struct device *dev) {}
 static inline struct clk *of_clk_src_simple_get(
        struct of_phandle_args *clkspec, void *data)
 {
index 4eff6e68600d979ed5bdbc31bebf875c95ba2332..9f5c6e53f3a5347cac592c6a16ce607b08149144 100644 (file)
@@ -27,6 +27,10 @@ struct qcom_smd_rpm;
 #define QCOM_SMD_RPM_SMPB      0x62706d73
 #define QCOM_SMD_RPM_SPDM      0x63707362
 #define QCOM_SMD_RPM_VSA       0x00617376
+#define QCOM_SMD_RPM_MMAXI_CLK 0x69786d6d
+#define QCOM_SMD_RPM_IPA_CLK   0x617069
+#define QCOM_SMD_RPM_CE_CLK    0x6563
+#define QCOM_SMD_RPM_AGGR_CLK  0x72676761
 
 int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
                       int state,
index 506ea8ffda1995436750b05bde1ebe37605de2a7..482337af06b8d5a1c226b4b18bce2956b37768d1 100644 (file)
@@ -17,6 +17,7 @@
 /* 0x08 ~ 0x0c: Reserved */
 #define AT91_SFR_OHCIICR       0x10    /* OHCI INT Configuration Register */
 #define AT91_SFR_OHCIISR       0x14    /* OHCI INT Status Register */
+#define AT91_SFR_UTMICKTRIM    0x30    /* UTMI Clock Trimming Register */
 #define AT91_SFR_I2SCLKSEL     0x90    /* I2SC Register */
 
 /* Field definitions */
@@ -28,5 +29,6 @@
                                         AT91_OHCIICR_SUSPEND_B | \
                                         AT91_OHCIICR_SUSPEND_C)
 
+#define AT91_UTMICKTRIM_FREQ   GENMASK(1, 0)
 
 #endif /* _LINUX_MFD_SYSCON_ATMEL_SFR_H */