aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-04 14:04:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-04 14:04:57 -0400
commit5617c122e6015e2371c0bd6b5ad2e070844df24a (patch)
tree53082aa1d585d8a9453d1f121b91bc86da1587bc
parent77b0a4aa0732f1856aef85b8db085864e5971a14 (diff)
parentb4626a7f489238a59f08f0b216e883bac07260d7 (diff)
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk framework updates from Stephen Boyd: "The core clk framework changes are small again. They're mostly minor fixes that weren't causing enough problems (or any problems when we're just clarifying things) to warrant sending outside the merge window. The majority of changes are in drivers for various SoCs. Full details are in the logs, but here's the summary. Core: - Better support for DeviceTree overlays with the addition of the CLK_OF_DECLARE_DRIVER macro. Now we won't probe a clk driver for a device node that matched during of_clk_init(), unless the driver uses CLK_OF_DECLARE_DRIVER instead of CLK_OF_DECLARE. This allows overlays to work cleanly for drivers that must probe before the device model is ready, and also after it's ready when an overlay is loaded. - Clarification in the code around how clk_hw pointers are returned from of clk providers - Proper migration of prepare/enable counts to parents when the clk tree is constructed New Drivers: - Socionext's UniPhier SoCs - Loongson1C - ZTE ZX296718 - Qualcomm MDM9615 - Amlogic GXBB AO clocks and resets - Broadcom BCM53573 ILP - Maxim MAX77620 Updates: - Four Allwinner SoCs are migrated to the new style clk driver (A31, A31s, A23 and A33) - Exynos 5xxx audio and DRAM clks - Loongson1B AC97, DMA and NAND clks - Rockchip DDR clks and rk3399 driver tweaks - Renesas R-Car M3-W (r8a7796) SoC SDHI interface and Watchdog timer clks - Renasas R-Car H3 and M3-W CMT clks and RAVB+Thermal clks for M3-W - Amlogic GXBB MMC gate clks - at91 sama5d4 sckc - Removal of STiH415 and STiH416 clk support as the SoC is being removed - Rework of STiH4xx clk support for new style bindings - Continuation of driver migration to clk_hw based registration APIs - xgene PMD support - bcm2835 critical clk markings - ARM versatile ICST" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (199 commits) CLK: Add Loongson1C clock support clk: Loongson1: Make use of GENMASK clk: Loongson1: Update clocks of Loongson1B clk: Loongson1: Refactor Loongson1 clock clk: change the type of clk_hw_onecell_data.num to unsigned int clk: zx296718: register driver earlier with core_initcall clk: mvebu: dynamically allocate resources in Armada CP110 system controller clk: mvebu: fix setting unwanted flags in CP110 gate clock clk: nxp: clk-lpc32xx: Unmap region obtained by of_iomap clk: mediatek: clk-mt8173: Unmap region obtained by of_iomap clk: sunxi-ng: Fix reset offset for the A23 and A33 clk: at91: sckc: optimize boot time clk: at91: Add sama5d4 sckc support clk: at91: move slow clock controller clocks to sckc.c clk: imx6: initialize GPU clocks clk: imx6: fix i.MX6DL clock tree to reflect reality clk: imx53: Add clocks configuration clk: uniphier: add clock data for UniPhier SoCs clk: uniphier: add core support code for UniPhier clock driver clk: bcm: Add driver for BCM53573 ILP clock ...
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt3
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt22
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt22
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt24
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt3
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt3
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt3
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt3
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt3
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt3
-rw-r--r--Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt45
-rw-r--r--Documentation/devicetree/bindings/clock/arm-syscon-icst.txt34
-rw-r--r--Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt70
-rw-r--r--Documentation/devicetree/bindings/clock/armada3700-tbg-clock.txt27
-rw-r--r--Documentation/devicetree/bindings/clock/armada3700-xtal-clock.txt28
-rw-r--r--Documentation/devicetree/bindings/clock/at91-clock.txt3
-rw-r--r--Documentation/devicetree/bindings/clock/brcm,bcm53573-ilp.txt36
-rw-r--r--Documentation/devicetree/bindings/clock/clk-exynos-audss.txt4
-rw-r--r--Documentation/devicetree/bindings/clock/exynos5410-clock.txt21
-rw-r--r--Documentation/devicetree/bindings/clock/maxim,max77686.txt118
-rw-r--r--Documentation/devicetree/bindings/clock/maxim,max77802.txt44
-rw-r--r--Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/qcom,gcc.txt1
-rw-r--r--Documentation/devicetree/bindings/clock/qcom,lcc.txt1
-rw-r--r--Documentation/devicetree/bindings/clock/st/st,clkgen-divmux.txt49
-rw-r--r--Documentation/devicetree/bindings/clock/st/st,clkgen-mux.txt20
-rw-r--r--Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt35
-rw-r--r--Documentation/devicetree/bindings/clock/st/st,clkgen-prediv.txt36
-rw-r--r--Documentation/devicetree/bindings/clock/st/st,clkgen-vcc.txt61
-rw-r--r--Documentation/devicetree/bindings/clock/st/st,clkgen.txt54
-rw-r--r--Documentation/devicetree/bindings/clock/st/st,flexgen.txt4
-rw-r--r--Documentation/devicetree/bindings/clock/st/st,quadfs.txt31
-rw-r--r--Documentation/devicetree/bindings/clock/sunxi-ccu.txt5
-rw-r--r--Documentation/devicetree/bindings/clock/uniphier-clock.txt134
-rw-r--r--Documentation/devicetree/bindings/clock/xgene.txt18
-rw-r--r--Documentation/devicetree/bindings/clock/zx296718-clk.txt35
-rw-r--r--MAINTAINERS11
-rw-r--r--arch/arm/mach-bcm/Kconfig1
-rw-r--r--drivers/clk/Kconfig20
-rw-r--r--drivers/clk/Makefile5
-rw-r--r--drivers/clk/at91/clk-generated.c30
-rw-r--r--drivers/clk/at91/clk-h32mx.c8
-rw-r--r--drivers/clk/at91/clk-main.c88
-rw-r--r--drivers/clk/at91/clk-master.c21
-rw-r--r--drivers/clk/at91/clk-peripheral.c39
-rw-r--r--drivers/clk/at91/clk-pll.c21
-rw-r--r--drivers/clk/at91/clk-plldiv.c24
-rw-r--r--drivers/clk/at91/clk-programmable.c22
-rw-r--r--drivers/clk/at91/clk-slow.c375
-rw-r--r--drivers/clk/at91/clk-smd.c22
-rw-r--r--drivers/clk/at91/clk-system.c22
-rw-r--r--drivers/clk/at91/clk-usb.c69
-rw-r--r--drivers/clk/at91/clk-utmi.c22
-rw-r--r--drivers/clk/at91/sckc.c464
-rw-r--r--drivers/clk/at91/sckc.h22
-rw-r--r--drivers/clk/axis/clk-artpec6.c4
-rw-r--r--drivers/clk/bcm/Kconfig30
-rw-r--r--drivers/clk/bcm/Makefile8
-rw-r--r--drivers/clk/bcm/clk-bcm2835-aux.c28
-rw-r--r--drivers/clk/bcm/clk-bcm2835.c146
-rw-r--r--drivers/clk/bcm/clk-bcm53573-ilp.c148
-rw-r--r--drivers/clk/bcm/clk-kona-setup.c80
-rw-r--r--drivers/clk/bcm/clk-kona.c9
-rw-r--r--drivers/clk/bcm/clk-kona.h7
-rw-r--r--drivers/clk/berlin/berlin2-avpll.c12
-rw-r--r--drivers/clk/berlin/berlin2-avpll.h8
-rw-r--r--drivers/clk/berlin/berlin2-div.c4
-rw-r--r--drivers/clk/berlin/berlin2-div.h4
-rw-r--r--drivers/clk/berlin/berlin2-pll.c6
-rw-r--r--drivers/clk/berlin/berlin2-pll.h9
-rw-r--r--drivers/clk/berlin/bg2.c98
-rw-r--r--drivers/clk/berlin/bg2q.c39
-rw-r--r--drivers/clk/clk-asm9260.c31
-rw-r--r--drivers/clk/clk-axi-clkgen.c12
-rw-r--r--drivers/clk/clk-axm5516.c39
-rw-r--r--drivers/clk/clk-cdce706.c40
-rw-r--r--drivers/clk/clk-cdce925.c42
-rw-r--r--drivers/clk/clk-clps711x.c78
-rw-r--r--drivers/clk/clk-cs2000-cp.c16
-rw-r--r--drivers/clk/clk-divider.c2
-rw-r--r--drivers/clk/clk-efm32gg.c63
-rw-r--r--drivers/clk/clk-fixed-factor.c74
-rw-r--r--drivers/clk/clk-fixed-rate.c72
-rw-r--r--drivers/clk/clk-ls1x.c161
-rw-r--r--drivers/clk/clk-max-gen.c194
-rw-r--r--drivers/clk/clk-max-gen.h32
-rw-r--r--drivers/clk/clk-max77686.c262
-rw-r--r--drivers/clk/clk-max77802.c96
-rw-r--r--drivers/clk/clk-mb86s7x.c16
-rw-r--r--drivers/clk/clk-moxart.c22
-rw-r--r--drivers/clk/clk-nspire.c19
-rw-r--r--drivers/clk/clk-palmas.c12
-rw-r--r--drivers/clk/clk-pwm.c9
-rw-r--r--drivers/clk/clk-qoriq.c6
-rw-r--r--drivers/clk/clk-rk808.c44
-rw-r--r--drivers/clk/clk-scpi.c33
-rw-r--r--drivers/clk/clk-si514.c11
-rw-r--r--drivers/clk/clk-si5351.c71
-rw-r--r--drivers/clk/clk-si570.c13
-rw-r--r--drivers/clk/clk-twl6040.c87
-rw-r--r--drivers/clk/clk-vt8500.c22
-rw-r--r--drivers/clk/clk-wm831x.c21
-rw-r--r--drivers/clk/clk-xgene.c221
-rw-r--r--drivers/clk/clk.c49
-rw-r--r--drivers/clk/h8300/clk-div.c10
-rw-r--r--drivers/clk/h8300/clk-h8s2678.c12
-rw-r--r--drivers/clk/imx/clk-imx35.c32
-rw-r--r--drivers/clk/imx/clk-imx51-imx53.c20
-rw-r--r--drivers/clk/imx/clk-imx6q.c46
-rw-r--r--drivers/clk/imx/clk-imx7d.c117
-rw-r--r--drivers/clk/imx/clk.h9
-rw-r--r--drivers/clk/loongson1/Makefile3
-rw-r--r--drivers/clk/loongson1/clk-loongson1b.c122
-rw-r--r--drivers/clk/loongson1/clk-loongson1c.c97
-rw-r--r--drivers/clk/loongson1/clk.c43
-rw-r--r--drivers/clk/loongson1/clk.h19
-rw-r--r--drivers/clk/mediatek/Kconfig21
-rw-r--r--drivers/clk/mediatek/Makefile6
-rw-r--r--drivers/clk/mediatek/clk-gate.c2
-rw-r--r--drivers/clk/mediatek/clk-mt8173.c4
-rw-r--r--drivers/clk/mediatek/clk-mtk.c12
-rw-r--r--drivers/clk/mediatek/clk-pll.c2
-rw-r--r--drivers/clk/meson/Makefile4
-rw-r--r--drivers/clk/meson/clkc.h2
-rw-r--r--drivers/clk/meson/gxbb-aoclk.c191
-rw-r--r--drivers/clk/meson/gxbb.c177
-rw-r--r--drivers/clk/meson/gxbb.h13
-rw-r--r--drivers/clk/meson/meson8b.c (renamed from drivers/clk/meson/meson8b-clkc.c)299
-rw-r--r--drivers/clk/meson/meson8b.h151
-rw-r--r--drivers/clk/microchip/clk-core.c6
-rw-r--r--drivers/clk/microchip/clk-pic32mzda.c1
-rw-r--r--drivers/clk/mmp/clk-mmp2.c1
-rw-r--r--drivers/clk/mvebu/Kconfig3
-rw-r--r--drivers/clk/mvebu/Makefile3
-rw-r--r--drivers/clk/mvebu/armada-37xx-periph.c447
-rw-r--r--drivers/clk/mvebu/armada-37xx-tbg.c158
-rw-r--r--drivers/clk/mvebu/armada-37xx-xtal.c91
-rw-r--r--drivers/clk/mvebu/armada-39x.c2
-rw-r--r--drivers/clk/mvebu/cp110-system-controller.c31
-rw-r--r--drivers/clk/nxp/clk-lpc18xx-creg.c3
-rw-r--r--drivers/clk/nxp/clk-lpc32xx.c1
-rw-r--r--drivers/clk/qcom/Kconfig19
-rw-r--r--drivers/clk/qcom/Makefile5
-rw-r--r--drivers/clk/qcom/clk-regmap.c5
-rw-r--r--drivers/clk/qcom/clk-regmap.h3
-rw-r--r--drivers/clk/qcom/common.c58
-rw-r--r--drivers/clk/qcom/gcc-ipq4019.c1
-rw-r--r--drivers/clk/qcom/gcc-mdm9615.c1727
-rw-r--r--drivers/clk/qcom/gcc-msm8996.c17
-rw-r--r--drivers/clk/qcom/lcc-mdm9615.c580
-rw-r--r--drivers/clk/qcom/mmcc-msm8996.c18
-rw-r--r--drivers/clk/renesas/clk-mstp.c2
-rw-r--r--drivers/clk/renesas/clk-rz.c24
-rw-r--r--drivers/clk/renesas/r8a7795-cpg-mssr.c4
-rw-r--r--drivers/clk/renesas/r8a7796-cpg-mssr.c31
-rw-r--r--drivers/clk/rockchip/Makefile1
-rw-r--r--drivers/clk/rockchip/clk-ddr.c154
-rw-r--r--drivers/clk/rockchip/clk-pll.c4
-rw-r--r--drivers/clk/rockchip/clk-rk3399.c56
-rw-r--r--drivers/clk/rockchip/clk-rockchip.c7
-rw-r--r--drivers/clk/rockchip/clk.c11
-rw-r--r--drivers/clk/rockchip/clk.h35
-rw-r--r--drivers/clk/samsung/clk-exynos-audss.c84
-rw-r--r--drivers/clk/samsung/clk-exynos5260.c350
-rw-r--r--drivers/clk/samsung/clk-exynos5410.c61
-rw-r--r--drivers/clk/samsung/clk-exynos5420.c37
-rw-r--r--drivers/clk/samsung/clk-exynos5440.c9
-rw-r--r--drivers/clk/samsung/clk-pll.c154
-rw-r--r--drivers/clk/samsung/clk-pll.h2
-rw-r--r--drivers/clk/st/clk-flexgen.c63
-rw-r--r--drivers/clk/st/clkgen-fsyn.c481
-rw-r--r--drivers/clk/st/clkgen-mux.c748
-rw-r--r--drivers/clk/st/clkgen-pll.c472
-rw-r--r--drivers/clk/sunxi-ng/Kconfig39
-rw-r--r--drivers/clk/sunxi-ng/Makefile4
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun6i-a31.c1239
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun6i-a31.h72
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h63
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-a23.c737
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-a33.c780
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-h3.c10
-rw-r--r--drivers/clk/sunxi-ng/ccu_div.h66
-rw-r--r--drivers/clk/sunxi-ng/ccu_mp.c23
-rw-r--r--drivers/clk/sunxi-ng/ccu_mp.h2
-rw-r--r--drivers/clk/sunxi-ng/ccu_mult.c133
-rw-r--r--drivers/clk/sunxi-ng/ccu_mult.h35
-rw-r--r--drivers/clk/sunxi-ng/ccu_mux.c56
-rw-r--r--drivers/clk/sunxi-ng/ccu_mux.h68
-rw-r--r--drivers/clk/sunxi-ng/ccu_nkm.c44
-rw-r--r--drivers/clk/sunxi-ng/ccu_nkm.h23
-rw-r--r--drivers/clk/sunxi-ng/ccu_nkmp.c21
-rw-r--r--drivers/clk/sunxi-ng/ccu_nm.c16
-rw-r--r--drivers/clk/sunxi/clk-mod0.c3
-rw-r--r--drivers/clk/sunxi/clk-sun8i-apb0.c4
-rw-r--r--drivers/clk/uniphier/Kconfig9
-rw-r--r--drivers/clk/uniphier/Makefile8
-rw-r--r--drivers/clk/uniphier/clk-uniphier-core.c214
-rw-r--r--drivers/clk/uniphier/clk-uniphier-fixed-factor.c48
-rw-r--r--drivers/clk/uniphier/clk-uniphier-fixed-rate.c47
-rw-r--r--drivers/clk/uniphier/clk-uniphier-gate.c97
-rw-r--r--drivers/clk/uniphier/clk-uniphier-mio.c101
-rw-r--r--drivers/clk/uniphier/clk-uniphier-mux.c95
-rw-r--r--drivers/clk/uniphier/clk-uniphier-peri.c57
-rw-r--r--drivers/clk/uniphier/clk-uniphier-sys.c151
-rw-r--r--drivers/clk/uniphier/clk-uniphier.h122
-rw-r--r--drivers/clk/versatile/clk-icst.c310
-rw-r--r--drivers/clk/zte/Makefile1
-rw-r--r--drivers/clk/zte/clk-zx296718.c924
-rw-r--r--drivers/clk/zte/clk.c21
-rw-r--r--drivers/clk/zte/clk.h129
-rw-r--r--include/dt-bindings/clock/exynos5410.h3
-rw-r--r--include/dt-bindings/clock/exynos5420.h11
-rw-r--r--include/dt-bindings/clock/exynos5440.h2
-rw-r--r--include/dt-bindings/clock/gxbb-aoclkc.h66
-rw-r--r--include/dt-bindings/clock/gxbb-clkc.h7
-rw-r--r--include/dt-bindings/clock/imx5-clock.h15
-rw-r--r--include/dt-bindings/clock/imx6qdl-clock.h4
-rw-r--r--include/dt-bindings/clock/maxim,max77620.h21
-rw-r--r--include/dt-bindings/clock/meson8b-clkc.h2
-rw-r--r--include/dt-bindings/clock/mt2701-clk.h486
-rw-r--r--include/dt-bindings/clock/qcom,gcc-mdm9615.h327
-rw-r--r--include/dt-bindings/clock/qcom,gcc-msm8996.h5
-rw-r--r--include/dt-bindings/clock/qcom,lcc-mdm9615.h52
-rw-r--r--include/dt-bindings/clock/qcom,mmcc-msm8996.h1
-rw-r--r--include/dt-bindings/clock/rk3399-cru.h3
-rw-r--r--include/dt-bindings/clock/sun6i-a31-ccu.h187
-rw-r--r--include/dt-bindings/clock/sun8i-a23-a33-ccu.h127
-rw-r--r--include/dt-bindings/clock/zx296718-clock.h163
-rw-r--r--include/dt-bindings/reset/gxbb-aoclkc.h66
-rw-r--r--include/dt-bindings/reset/mt2701-resets.h83
-rw-r--r--include/dt-bindings/reset/qcom,gcc-mdm9615.h136
-rw-r--r--include/dt-bindings/reset/sun6i-a31-ccu.h106
-rw-r--r--include/dt-bindings/reset/sun8i-a23-a33-ccu.h87
-rw-r--r--include/linux/clk-provider.h16
-rw-r--r--include/soc/rockchip/rockchip_sip.h27
235 files changed, 15747 insertions, 4213 deletions
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
index 936166fbee09..cb0054ac7121 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
@@ -5,7 +5,8 @@ The Mediatek apmixedsys controller provides the PLLs to the system.
5 5
6Required Properties: 6Required Properties:
7 7
8- compatible: Should be: 8- compatible: Should be one of:
9 - "mediatek,mt2701-apmixedsys"
9 - "mediatek,mt8135-apmixedsys" 10 - "mediatek,mt8135-apmixedsys"
10 - "mediatek,mt8173-apmixedsys" 11 - "mediatek,mt8173-apmixedsys"
11- #clock-cells: Must be 1 12- #clock-cells: Must be 1
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt
new file mode 100644
index 000000000000..4137196dd686
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt
@@ -0,0 +1,22 @@
1Mediatek bdpsys controller
2============================
3
4The Mediatek bdpsys controller provides various clocks to the system.
5
6Required Properties:
7
8- compatible: Should be:
9 - "mediatek,mt2701-bdpsys", "syscon"
10- #clock-cells: Must be 1
11
12The bdpsys controller uses the common clk binding from
13Documentation/devicetree/bindings/clock/clock-bindings.txt
14The available clocks are defined in dt-bindings/clock/mt*-clk.h.
15
16Example:
17
18bdpsys: clock-controller@1c000000 {
19 compatible = "mediatek,mt2701-bdpsys", "syscon";
20 reg = <0 0x1c000000 0 0x1000>;
21 #clock-cells = <1>;
22};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
new file mode 100644
index 000000000000..768f3a5bc055
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
@@ -0,0 +1,22 @@
1Mediatek ethsys controller
2============================
3
4The Mediatek ethsys controller provides various clocks to the system.
5
6Required Properties:
7
8- compatible: Should be:
9 - "mediatek,mt2701-ethsys", "syscon"
10- #clock-cells: Must be 1
11
12The ethsys controller uses the common clk binding from
13Documentation/devicetree/bindings/clock/clock-bindings.txt
14The available clocks are defined in dt-bindings/clock/mt*-clk.h.
15
16Example:
17
18ethsys: clock-controller@1b000000 {
19 compatible = "mediatek,mt2701-ethsys", "syscon";
20 reg = <0 0x1b000000 0 0x1000>;
21 #clock-cells = <1>;
22};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
new file mode 100644
index 000000000000..beed7b594cea
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
@@ -0,0 +1,24 @@
1Mediatek hifsys controller
2============================
3
4The Mediatek hifsys controller provides various clocks and reset
5outputs to the system.
6
7Required Properties:
8
9- compatible: Should be:
10 - "mediatek,mt2701-hifsys", "syscon"
11- #clock-cells: Must be 1
12
13The hifsys controller uses the common clk binding from
14Documentation/devicetree/bindings/clock/clock-bindings.txt
15The available clocks are defined in dt-bindings/clock/mt*-clk.h.
16
17Example:
18
19hifsys: clock-controller@1a000000 {
20 compatible = "mediatek,mt2701-hifsys", "syscon";
21 reg = <0 0x1a000000 0 0x1000>;
22 #clock-cells = <1>;
23 #reset-cells = <1>;
24};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
index b1f2ce17dff8..f6a916686f4c 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
@@ -5,7 +5,8 @@ The Mediatek imgsys controller provides various clocks to the system.
5 5
6Required Properties: 6Required Properties:
7 7
8- compatible: Should be: 8- compatible: Should be one of:
9 - "mediatek,mt2701-imgsys", "syscon"
9 - "mediatek,mt8173-imgsys", "syscon" 10 - "mediatek,mt8173-imgsys", "syscon"
10- #clock-cells: Must be 1 11- #clock-cells: Must be 1
11 12
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
index aaf8d1460c4d..1620ec2a5a3f 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
@@ -6,7 +6,8 @@ outputs to the system.
6 6
7Required Properties: 7Required Properties:
8 8
9- compatible: Should be: 9- compatible: Should be one of:
10 - "mediatek,mt2701-infracfg", "syscon"
10 - "mediatek,mt8135-infracfg", "syscon" 11 - "mediatek,mt8135-infracfg", "syscon"
11 - "mediatek,mt8173-infracfg", "syscon" 12 - "mediatek,mt8173-infracfg", "syscon"
12- #clock-cells: Must be 1 13- #clock-cells: Must be 1
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
index 4385946eadef..67dd2e473d25 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
@@ -5,7 +5,8 @@ The Mediatek mmsys controller provides various clocks to the system.
5 5
6Required Properties: 6Required Properties:
7 7
8- compatible: Should be: 8- compatible: Should be one of:
9 - "mediatek,mt2701-mmsys", "syscon"
9 - "mediatek,mt8173-mmsys", "syscon" 10 - "mediatek,mt8173-mmsys", "syscon"
10- #clock-cells: Must be 1 11- #clock-cells: Must be 1
11 12
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
index 2f6ff86df49f..e494366782aa 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
@@ -6,7 +6,8 @@ outputs to the system.
6 6
7Required Properties: 7Required Properties:
8 8
9- compatible: Should be: 9- compatible: Should be one of:
10 - "mediatek,mt2701-pericfg", "syscon"
10 - "mediatek,mt8135-pericfg", "syscon" 11 - "mediatek,mt8135-pericfg", "syscon"
11 - "mediatek,mt8173-pericfg", "syscon" 12 - "mediatek,mt8173-pericfg", "syscon"
12- #clock-cells: Must be 1 13- #clock-cells: Must be 1
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
index f9e917994ced..9f2fe7860114 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
@@ -5,7 +5,8 @@ The Mediatek topckgen controller provides various clocks to the system.
5 5
6Required Properties: 6Required Properties:
7 7
8- compatible: Should be: 8- compatible: Should be one of:
9 - "mediatek,mt2701-topckgen"
9 - "mediatek,mt8135-topckgen" 10 - "mediatek,mt8135-topckgen"
10 - "mediatek,mt8173-topckgen" 11 - "mediatek,mt8173-topckgen"
11- #clock-cells: Must be 1 12- #clock-cells: Must be 1
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
index 1faacf1c1b25..2440f73450c3 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
@@ -5,7 +5,8 @@ The Mediatek vdecsys controller provides various clocks to the system.
5 5
6Required Properties: 6Required Properties:
7 7
8- compatible: Should be: 8- compatible: Should be one of:
9 - "mediatek,mt2701-vdecsys", "syscon"
9 - "mediatek,mt8173-vdecsys", "syscon" 10 - "mediatek,mt8173-vdecsys", "syscon"
10- #clock-cells: Must be 1 11- #clock-cells: Must be 1
11 12
diff --git a/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt
new file mode 100644
index 000000000000..a55d31b48d6e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt
@@ -0,0 +1,45 @@
1* Amlogic GXBB AO Clock and Reset Unit
2
3The Amlogic GXBB AO clock controller generates and supplies clock to various
4controllers within the Always-On part of the SoC.
5
6Required Properties:
7
8- compatible: should be "amlogic,gxbb-aoclkc"
9- reg: physical base address of the clock controller and length of memory
10 mapped region.
11
12- #clock-cells: should be 1.
13
14Each clock is assigned an identifier and client nodes can use this identifier
15to specify the clock which they consume. All available clocks are defined as
16preprocessor macros in the dt-bindings/clock/gxbb-aoclkc.h header and can be
17used in device tree sources.
18
19- #reset-cells: should be 1.
20
21Each reset is assigned an identifier and client nodes can use this identifier
22to specify the reset which they consume. All available resets are defined as
23preprocessor macros in the dt-bindings/reset/gxbb-aoclkc.h header and can be
24used in device tree sources.
25
26Example: AO Clock controller node:
27
28 clkc_AO: clock-controller@040 {
29 compatible = "amlogic,gxbb-aoclkc";
30 reg = <0x0 0x040 0x0 0x4>;
31 #clock-cells = <1>;
32 #reset-cells = <1>;
33 };
34
35Example: UART controller node that consumes the clock and reset generated
36 by the clock controller:
37
38 uart_AO: serial@4c0 {
39 compatible = "amlogic,meson-uart";
40 reg = <0x4c0 0x14>;
41 interrupts = <0 90 1>;
42 clocks = <&clkc_AO CLKID_AO_UART1>;
43 resets = <&clkc_AO RESET_AO_UART1>;
44 status = "disabled";
45 };
diff --git a/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt b/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt
index 8b7177cecb36..27468119fd94 100644
--- a/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt
+++ b/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt
@@ -5,20 +5,50 @@ Technology (IDT). ARM integrated these oscillators deeply into their
5reference designs by adding special control registers that manage such 5reference designs by adding special control registers that manage such
6oscillators to their system controllers. 6oscillators to their system controllers.
7 7
8The ARM system controller contains logic to serialize and initialize 8The various ARM system controllers contain logic to serialize and initialize
9an ICST clock request after a write to the 32 bit register at an offset 9an ICST clock request after a write to the 32 bit register at an offset
10into the system controller. Furthermore, to even be able to alter one of 10into the system controller. Furthermore, to even be able to alter one of
11these frequencies, the system controller must first be unlocked by 11these frequencies, the system controller must first be unlocked by
12writing a special token to another offset in the system controller. 12writing a special token to another offset in the system controller.
13 13
14Some ARM hardware contain special versions of the serial interface that only
15connects the low 8 bits of the VDW (missing one bit), hardwires RDW to
16different values and sometimes also hardwire the output divider. They
17therefore have special compatible strings as per this table (the OD value is
18the value on the pins, not the resulting output divider):
19
20Hardware variant: RDW OD VDW
21
22Integrator/AP 22 1 Bit 8 0, rest variable
23integratorap-cm
24
25Integrator/AP 46 3 Bit 8 0, rest variable
26integratorap-sys
27
28Integrator/AP 22 or 1 17 or (33 or 25 MHz)
29integratorap-pci 14 1 14
30
31Integrator/CP 22 variable Bit 8 0, rest variable
32integratorcp-cm-core
33
34Integrator/CP 22 variable Bit 8 0, rest variable
35integratorcp-cm-mem
36
14The ICST oscillator must be provided inside a system controller node. 37The ICST oscillator must be provided inside a system controller node.
15 38
16Required properties: 39Required properties:
40- compatible: must be one of
41 "arm,syscon-icst525"
42 "arm,syscon-icst307"
43 "arm,syscon-icst525-integratorap-cm"
44 "arm,syscon-icst525-integratorap-sys"
45 "arm,syscon-icst525-integratorap-pci"
46 "arm,syscon-icst525-integratorcp-cm-core"
47 "arm,syscon-icst525-integratorcp-cm-mem"
17- lock-offset: the offset address into the system controller where the 48- lock-offset: the offset address into the system controller where the
18 unlocking register is located 49 unlocking register is located
19- vco-offset: the offset address into the system controller where the 50- vco-offset: the offset address into the system controller where the
20 ICST control register is located (even 32 bit address) 51 ICST control register is located (even 32 bit address)
21- compatible: must be one of "arm,syscon-icst525" or "arm,syscon-icst307"
22- #clock-cells: must be <0> 52- #clock-cells: must be <0>
23- clocks: parent clock, since the ICST needs a parent clock to derive its 53- clocks: parent clock, since the ICST needs a parent clock to derive its
24 frequency from, this attribute is compulsory. 54 frequency from, this attribute is compulsory.
diff --git a/Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt b/Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt
new file mode 100644
index 000000000000..1e3370ba189f
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt
@@ -0,0 +1,70 @@
1* Peripheral Clock bindings for Marvell Armada 37xx SoCs
2
3Marvell Armada 37xx SoCs provide peripheral clocks which are
4used as clock source for the peripheral of the SoC.
5
6There are two different blocks associated to north bridge and south
7bridge.
8
9The peripheral clock consumer should specify the desired clock by
10having the clock ID in its "clocks" phandle cell.
11
12The following is a list of provided IDs for Armada 370 North bridge clocks:
13ID Clock name Description
14-----------------------------------
150 mmc MMC controller
161 sata_host Sata Host
172 sec_at Security AT
183 sac_dap Security DAP
194 tsecm Security Engine
205 setm_tmx Serial Embedded Trace Module
216 avs Adaptive Voltage Scaling
227 sqf SPI
238 pwm PWM
249 i2c_2 I2C 2
2510 i2c_1 I2C 1
2611 ddr_phy DDR PHY
2712 ddr_fclk DDR F clock
2813 trace Trace
2914 counter Counter
3015 eip97 EIP 97
3116 cpu CPU
32
33The following is a list of provided IDs for Armada 370 South bridge clocks:
34ID Clock name Description
35-----------------------------------
360 gbe-50 50 MHz parent clock for Gigabit Ethernet
371 gbe-core parent clock for Gigabit Ethernet core
382 gbe-125 125 MHz parent clock for Gigabit Ethernet
393 gbe1-50 50 MHz clock for Gigabit Ethernet port 1
404 gbe0-50 50 MHz clock for Gigabit Ethernet port 0
415 gbe1-125 125 MHz clock for Gigabit Ethernet port 1
426 gbe0-125 125 MHz clock for Gigabit Ethernet port 0
437 gbe1-core Gigabit Ethernet core port 1
448 gbe0-core Gigabit Ethernet core port 0
459 gbe-bm Gigabit Ethernet Buffer Manager
4610 sdio SDIO
4711 usb32-sub2-sys USB 2 clock
4812 usb32-ss-sys USB 3 clock
49
50Required properties:
51
52- compatible : shall be "marvell,armada-3700-periph-clock-nb" for the
53 north bridge block, or
54 "marvell,armada-3700-periph-clock-sb" for the south bridge block
55- reg : must be the register address of North/South Bridge Clock register
56- #clock-cells : from common clock binding; shall be set to 1
57
58- clocks : list of the parent clock phandle in the following order:
59 TBG-A P, TBG-B P, TBG-A S, TBG-B S and finally the xtal clock.
60
61
62Example:
63
64nb_perih_clk: nb-periph-clk@13000{
65 compatible = "marvell,armada-3700-periph-clock-nb";
66 reg = <0x13000 0x1000>;
67 clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>,
68 <&tbg 3>, <&xtalclk>;
69 #clock-cells = <1>;
70};
diff --git a/Documentation/devicetree/bindings/clock/armada3700-tbg-clock.txt b/Documentation/devicetree/bindings/clock/armada3700-tbg-clock.txt
new file mode 100644
index 000000000000..0ba1d83ff363
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/armada3700-tbg-clock.txt
@@ -0,0 +1,27 @@
1* Time Base Generator Clock bindings for Marvell Armada 37xx SoCs
2
3Marvell Armada 37xx SoCs provde Time Base Generator clocks which are
4used as parent clocks for the peripheral clocks.
5
6The TBG clock consumer should specify the desired clock by having the
7clock ID in its "clocks" phandle cell.
8
9The following is a list of provided IDs and clock names on Armada 3700:
10 0 = TBG A P
11 1 = TBG B P
12 2 = TBG A S
13 3 = TBG B S
14
15Required properties:
16- compatible : shall be "marvell,armada-3700-tbg-clock"
17- reg : must be the register address of North Bridge PLL register
18- #clock-cells : from common clock binding; shall be set to 1
19
20Example:
21
22tbg: tbg@13200 {
23 compatible = "marvell,armada-3700-tbg-clock";
24 reg = <0x13200 0x1000>;
25 clocks = <&xtalclk>;
26 #clock-cells = <1>;
27};
diff --git a/Documentation/devicetree/bindings/clock/armada3700-xtal-clock.txt b/Documentation/devicetree/bindings/clock/armada3700-xtal-clock.txt
new file mode 100644
index 000000000000..a88f1f05fbd6
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/armada3700-xtal-clock.txt
@@ -0,0 +1,28 @@
1* Xtal Clock bindings for Marvell Armada 37xx SoCs
2
3Marvell Armada 37xx SoCs allow to determine the xtal clock frequencies by
4reading the gpio latch register.
5
6This node must be a subnode of the node exposing the register address
7of the GPIO block where the gpio latch is located.
8
9Required properties:
10- compatible : shall be one of the following:
11 "marvell,armada-3700-xtal-clock"
12- #clock-cells : from common clock binding; shall be set to 0
13
14Optional properties:
15- clock-output-names : from common clock binding; allows overwrite default clock
16 output names ("xtal")
17
18Example:
19gpio1: gpio@13800 {
20 compatible = "marvell,armada-3700-gpio", "syscon", "simple-mfd";
21 reg = <0x13800 0x1000>;
22
23 xtalclk: xtal-clk {
24 compatible = "marvell,armada-3700-xtal-clock";
25 clock-output-names = "xtal";
26 #clock-cells = <0>;
27 };
28};
diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt
index 181bc8ac4e3a..5f3ad65daf69 100644
--- a/Documentation/devicetree/bindings/clock/at91-clock.txt
+++ b/Documentation/devicetree/bindings/clock/at91-clock.txt
@@ -6,7 +6,8 @@ This binding uses the common clock binding[1].
6 6
7Required properties: 7Required properties:
8- compatible : shall be one of the following: 8- compatible : shall be one of the following:
9 "atmel,at91sam9x5-sckc": 9 "atmel,at91sam9x5-sckc" or
10 "atmel,sama5d4-sckc":
10 at91 SCKC (Slow Clock Controller) 11 at91 SCKC (Slow Clock Controller)
11 This node contains the slow clock definitions. 12 This node contains the slow clock definitions.
12 13
diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm53573-ilp.txt b/Documentation/devicetree/bindings/clock/brcm,bcm53573-ilp.txt
new file mode 100644
index 000000000000..2ebb107331dd
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/brcm,bcm53573-ilp.txt
@@ -0,0 +1,36 @@
1Broadcom BCM53573 ILP clock
2===========================
3
4This binding uses the common clock binding:
5 Documentation/devicetree/bindings/clock/clock-bindings.txt
6
7This binding is used for ILP clock (sometimes referred as "slow clock")
8on Broadcom BCM53573 devices using Cortex-A7 CPU.
9
10ILP's rate has to be calculated on runtime and it depends on ALP clock
11which has to be referenced.
12
13This clock is part of PMU (Power Management Unit), a Broadcom's device
14handing power-related aspects. Its node must be sub-node of the PMU
15device.
16
17Required properties:
18- compatible: "brcm,bcm53573-ilp"
19- clocks: has to reference an ALP clock
20- #clock-cells: should be <0>
21- clock-output-names: from common clock bindings, should contain clock
22 name
23
24Example:
25
26pmu@18012000 {
27 compatible = "simple-mfd", "syscon";
28 reg = <0x18012000 0x00001000>;
29
30 ilp {
31 compatible = "brcm,bcm53573-ilp";
32 clocks = <&alp>;
33 #clock-cells = <0>;
34 clock-output-names = "ilp";
35 };
36};
diff --git a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt b/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
index 180e8835569e..0c3d6015868d 100644
--- a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
+++ b/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
@@ -10,6 +10,8 @@ Required Properties:
10 - "samsung,exynos4210-audss-clock" - controller compatible with all Exynos4 SoCs. 10 - "samsung,exynos4210-audss-clock" - controller compatible with all Exynos4 SoCs.
11 - "samsung,exynos5250-audss-clock" - controller compatible with Exynos5250 11 - "samsung,exynos5250-audss-clock" - controller compatible with Exynos5250
12 SoCs. 12 SoCs.
13 - "samsung,exynos5410-audss-clock" - controller compatible with Exynos5410
14 SoCs.
13 - "samsung,exynos5420-audss-clock" - controller compatible with Exynos5420 15 - "samsung,exynos5420-audss-clock" - controller compatible with Exynos5420
14 SoCs. 16 SoCs.
15- reg: physical base address and length of the controller's register set. 17- reg: physical base address and length of the controller's register set.
@@ -91,5 +93,5 @@ i2s0: i2s@03830000 {
91 <&clock_audss EXYNOS_MOUT_AUDSS>, 93 <&clock_audss EXYNOS_MOUT_AUDSS>,
92 <&clock_audss EXYNOS_MOUT_I2S>; 94 <&clock_audss EXYNOS_MOUT_I2S>;
93 clock-names = "iis", "i2s_opclk0", "i2s_opclk1", 95 clock-names = "iis", "i2s_opclk0", "i2s_opclk1",
94 "mout_audss", "mout_i2s"; 96 "mout_audss", "mout_i2s";
95}; 97};
diff --git a/Documentation/devicetree/bindings/clock/exynos5410-clock.txt b/Documentation/devicetree/bindings/clock/exynos5410-clock.txt
index aeab635b07b5..4527de3ea205 100644
--- a/Documentation/devicetree/bindings/clock/exynos5410-clock.txt
+++ b/Documentation/devicetree/bindings/clock/exynos5410-clock.txt
@@ -12,24 +12,29 @@ Required Properties:
12 12
13- #clock-cells: should be 1. 13- #clock-cells: should be 1.
14 14
15- clocks: should contain an entry specifying the root clock from external
16 oscillator supplied through XXTI or XusbXTI pin. This clock should be
17 defined using standard clock bindings with "fin_pll" clock-output-name.
18 That clock is being passed internally to the 9 PLLs.
19
15All available clocks are defined as preprocessor macros in 20All available clocks are defined as preprocessor macros in
16dt-bindings/clock/exynos5410.h header and can be used in device 21dt-bindings/clock/exynos5410.h header and can be used in device
17tree sources. 22tree sources.
18 23
19External clock:
20
21There is clock that is generated outside the SoC. It
22is expected that it is defined using standard clock bindings
23with following clock-output-name:
24
25 - "fin_pll" - PLL input clock from XXTI
26
27Example 1: An example of a clock controller node is listed below. 24Example 1: An example of a clock controller node is listed below.
28 25
26 fin_pll: xxti {
27 compatible = "fixed-clock";
28 clock-frequency = <24000000>;
29 clock-output-names = "fin_pll";
30 #clock-cells = <0>;
31 };
32
29 clock: clock-controller@0x10010000 { 33 clock: clock-controller@0x10010000 {
30 compatible = "samsung,exynos5410-clock"; 34 compatible = "samsung,exynos5410-clock";
31 reg = <0x10010000 0x30000>; 35 reg = <0x10010000 0x30000>;
32 #clock-cells = <1>; 36 #clock-cells = <1>;
37 clocks = <&fin_pll>;
33 }; 38 };
34 39
35Example 2: UART controller node that consumes the clock generated by the clock 40Example 2: UART controller node that consumes the clock generated by the clock
diff --git a/Documentation/devicetree/bindings/clock/maxim,max77686.txt b/Documentation/devicetree/bindings/clock/maxim,max77686.txt
index 9c40739a661a..8398a3a5e106 100644
--- a/Documentation/devicetree/bindings/clock/maxim,max77686.txt
+++ b/Documentation/devicetree/bindings/clock/maxim,max77686.txt
@@ -1,10 +1,24 @@
1Binding for Maxim MAX77686 32k clock generator block 1Binding for Maxim MAX77686/MAX77802/MAX77620 32k clock generator block
2 2
3This is a part of device tree bindings of MAX77686 multi-function device. 3This is a part of device tree bindings of MAX77686/MAX77802/MAX77620
4More information can be found in bindings/mfd/max77686.txt file. 4multi-function device. More information can be found in MFD DT binding
5doc as follows:
6 bindings/mfd/max77686.txt for MAX77686 and
7 bindings/mfd/max77802.txt for MAX77802 and
8 bindings/mfd/max77620.txt for MAX77620.
5 9
6The MAX77686 contains three 32.768khz clock outputs that can be controlled 10The MAX77686 contains three 32.768khz clock outputs that can be controlled
7(gated/ungated) over I2C. 11(gated/ungated) over I2C. Clocks are defined as preprocessor macros in
12dt-bindings/clock/maxim,max77686.h.
13
14
15The MAX77802 contains two 32.768khz clock outputs that can be controlled
16(gated/ungated) over I2C. Clocks are defined as preprocessor macros in
17dt-bindings/clock/maxim,max77802.h.
18
19The MAX77686 contains one 32.768khz clock outputs that can be controlled
20(gated/ungated) over I2C. Clocks are defined as preprocessor macros in
21dt-bindings/clock/maxim,max77620.h.
8 22
9Following properties should be presend in main device node of the MFD chip. 23Following properties should be presend in main device node of the MFD chip.
10 24
@@ -17,30 +31,84 @@ Optional properties:
17 31
18Each clock is assigned an identifier and client nodes can use this identifier 32Each clock is assigned an identifier and client nodes can use this identifier
19to specify the clock which they consume. Following indices are allowed: 33to specify the clock which they consume. Following indices are allowed:
20 - 0: 32khz_ap clock, 34 - 0: 32khz_ap clock (max77686, max77802), 32khz_out0 (max77620)
21 - 1: 32khz_cp clock, 35 - 1: 32khz_cp clock (max77686, max77802),
22 - 2: 32khz_pmic clock. 36 - 2: 32khz_pmic clock (max77686).
37
38Clocks are defined as preprocessor macros in above dt-binding header for
39respective chips.
40
41Example:
42
431. With MAX77686:
44
45#include <dt-bindings/clock/maxim,max77686.h>
46/* ... */
47
48 Node of the MFD chip
49 max77686: max77686@09 {
50 compatible = "maxim,max77686";
51 interrupt-parent = <&wakeup_eint>;
52 interrupts = <26 0>;
53 reg = <0x09>;
54 #clock-cells = <1>;
55
56 /* ... */
57 };
58
59 Clock consumer node
60
61 foo@0 {
62 compatible = "bar,foo";
63 /* ... */
64 clock-names = "my-clock";
65 clocks = <&max77686 MAX77686_CLK_PMIC>;
66 };
67
682. With MAX77802:
69
70#include <dt-bindings/clock/maxim,max77802.h>
71/* ... */
72
73 Node of the MFD chip
74 max77802: max77802@09 {
75 compatible = "maxim,max77802";
76 interrupt-parent = <&wakeup_eint>;
77 interrupts = <26 0>;
78 reg = <0x09>;
79 #clock-cells = <1>;
80
81 /* ... */
82 };
83
84 Clock consumer node
85
86 foo@0 {
87 compatible = "bar,foo";
88 /* ... */
89 clock-names = "my-clock";
90 clocks = <&max77802 MAX77802_CLK_32K_AP>;
91 };
23 92
24Clocks are defined as preprocessor macros in dt-bindings/clock/maxim,max77686.h
25header and can be used in device tree sources.
26 93
27Example: Node of the MFD chip 943. With MAX77620:
28 95
29 max77686: max77686@09 { 96#include <dt-bindings/clock/maxim,max77620.h>
30 compatible = "maxim,max77686"; 97/* ... */
31 interrupt-parent = <&wakeup_eint>;
32 interrupts = <26 0>;
33 reg = <0x09>;
34 #clock-cells = <1>;
35 98
36 /* ... */ 99 Node of the MFD chip
37 }; 100 max77620: max77620@3c {
101 compatible = "maxim,max77620";
102 reg = <0x3c>;
103 #clock-cells = <1>;
104 /* ... */
105 };
38 106
39Example: Clock consumer node 107 Clock consumer node
40 108
41 foo@0 { 109 foo@0 {
42 compatible = "bar,foo"; 110 compatible = "bar,foo";
43 /* ... */ 111 /* ... */
44 clock-names = "my-clock"; 112 clock-names = "my-clock";
45 clocks = <&max77686 MAX77686_CLK_PMIC>; 113 clocks = <&max77620 MAX77620_CLK_32K_OUT0>;
46 }; 114 };
diff --git a/Documentation/devicetree/bindings/clock/maxim,max77802.txt b/Documentation/devicetree/bindings/clock/maxim,max77802.txt
deleted file mode 100644
index c6dc7835f06c..000000000000
--- a/Documentation/devicetree/bindings/clock/maxim,max77802.txt
+++ /dev/null
@@ -1,44 +0,0 @@
1Binding for Maxim MAX77802 32k clock generator block
2
3This is a part of device tree bindings of MAX77802 multi-function device.
4More information can be found in bindings/mfd/max77802.txt file.
5
6The MAX77802 contains two 32.768khz clock outputs that can be controlled
7(gated/ungated) over I2C.
8
9Following properties should be present in main device node of the MFD chip.
10
11Required properties:
12- #clock-cells: From common clock binding; shall be set to 1.
13
14Optional properties:
15- clock-output-names: From common clock binding.
16
17Each clock is assigned an identifier and client nodes can use this identifier
18to specify the clock which they consume. Following indices are allowed:
19 - 0: 32khz_ap clock,
20 - 1: 32khz_cp clock.
21
22Clocks are defined as preprocessor macros in dt-bindings/clock/maxim,max77802.h
23header and can be used in device tree sources.
24
25Example: Node of the MFD chip
26
27 max77802: max77802@09 {
28 compatible = "maxim,max77802";
29 interrupt-parent = <&wakeup_eint>;
30 interrupts = <26 0>;
31 reg = <0x09>;
32 #clock-cells = <1>;
33
34 /* ... */
35 };
36
37Example: Clock consumer node
38
39 foo@0 {
40 compatible = "bar,foo";
41 /* ... */
42 clock-names = "my-clock";
43 clocks = <&max77802 MAX77802_CLK_32K_AP>;
44 };
diff --git a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
index 660e64912cce..cb8542d910b3 100644
--- a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
+++ b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
@@ -86,6 +86,8 @@ ID Clock Peripheral
867 pex3 PCIe 3 867 pex3 PCIe 3
878 pex0 PCIe 0 878 pex0 PCIe 0
889 usb3h0 USB3 Host 0 889 usb3h0 USB3 Host 0
8910 usb3h1 USB3 Host 1
9015 sata0 SATA 0
8917 sdio SDIO 9117 sdio SDIO
9022 xor0 XOR 0 9222 xor0 XOR 0
9128 xor1 XOR 1 9328 xor1 XOR 1
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
index 9a60fde32b02..869a2f0e2ff6 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
@@ -15,6 +15,7 @@ Required properties :
15 "qcom,gcc-msm8974pro" 15 "qcom,gcc-msm8974pro"
16 "qcom,gcc-msm8974pro-ac" 16 "qcom,gcc-msm8974pro-ac"
17 "qcom,gcc-msm8996" 17 "qcom,gcc-msm8996"
18 "qcom,gcc-mdm9615"
18 19
19- reg : shall contain base register location and length 20- reg : shall contain base register location and length
20- #clock-cells : shall contain 1 21- #clock-cells : shall contain 1
diff --git a/Documentation/devicetree/bindings/clock/qcom,lcc.txt b/Documentation/devicetree/bindings/clock/qcom,lcc.txt
index dd755be63a01..a3c78aa88038 100644
--- a/Documentation/devicetree/bindings/clock/qcom,lcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,lcc.txt
@@ -7,6 +7,7 @@ Required properties :
7 "qcom,lcc-msm8960" 7 "qcom,lcc-msm8960"
8 "qcom,lcc-apq8064" 8 "qcom,lcc-apq8064"
9 "qcom,lcc-ipq8064" 9 "qcom,lcc-ipq8064"
10 "qcom,lcc-mdm9615"
10 11
11- reg : shall contain base register location and length 12- reg : shall contain base register location and length
12- #clock-cells : shall contain 1 13- #clock-cells : shall contain 1
diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-divmux.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-divmux.txt
deleted file mode 100644
index 6247652044a0..000000000000
--- a/Documentation/devicetree/bindings/clock/st/st,clkgen-divmux.txt
+++ /dev/null
@@ -1,49 +0,0 @@
1Binding for a ST divider and multiplexer clock driver.
2
3This binding uses the common clock binding[1].
4Base address is located to the parent node. See clock binding[2]
5
6[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
7[2] Documentation/devicetree/bindings/clock/st/st,clkgen.txt
8
9Required properties:
10
11- compatible : shall be:
12 "st,clkgena-divmux-c65-hs", "st,clkgena-divmux"
13 "st,clkgena-divmux-c65-ls", "st,clkgena-divmux"
14 "st,clkgena-divmux-c32-odf0", "st,clkgena-divmux"
15 "st,clkgena-divmux-c32-odf1", "st,clkgena-divmux"
16 "st,clkgena-divmux-c32-odf2", "st,clkgena-divmux"
17 "st,clkgena-divmux-c32-odf3", "st,clkgena-divmux"
18
19- #clock-cells : From common clock binding; shall be set to 1.
20
21- clocks : From common clock binding
22
23- clock-output-names : From common clock binding.
24
25Example:
26
27 clockgen-a@fd345000 {
28 reg = <0xfd345000 0xb50>;
29
30 clk_m_a1_div1: clk-m-a1-div1 {
31 #clock-cells = <1>;
32 compatible = "st,clkgena-divmux-c32-odf1",
33 "st,clkgena-divmux";
34
35 clocks = <&clk_m_a1_osc_prediv>,
36 <&clk_m_a1_pll0 1>, /* PLL0 PHI1 */
37 <&clk_m_a1_pll1 1>; /* PLL1 PHI1 */
38
39 clock-output-names = "clk-m-rx-icn-ts",
40 "clk-m-rx-icn-vdp-0",
41 "", /* unused */
42 "clk-m-prv-t1-bus",
43 "clk-m-icn-reg-12",
44 "clk-m-icn-reg-10",
45 "", /* unused */
46 "clk-m-icn-st231";
47 };
48 };
49
diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-mux.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-mux.txt
index f1fa91c68768..9a46cb1d7a04 100644
--- a/Documentation/devicetree/bindings/clock/st/st,clkgen-mux.txt
+++ b/Documentation/devicetree/bindings/clock/st/st,clkgen-mux.txt
@@ -10,14 +10,7 @@ This binding uses the common clock binding[1].
10Required properties: 10Required properties:
11 11
12- compatible : shall be: 12- compatible : shall be:
13 "st,stih416-clkgenc-vcc-hd", "st,clkgen-mux" 13 "st,stih407-clkgen-a9-mux"
14 "st,stih416-clkgenf-vcc-fvdp", "st,clkgen-mux"
15 "st,stih416-clkgenf-vcc-hva", "st,clkgen-mux"
16 "st,stih416-clkgenf-vcc-hd", "st,clkgen-mux"
17 "st,stih416-clkgenf-vcc-sd", "st,clkgen-mux"
18 "st,stih415-clkgen-a9-mux", "st,clkgen-mux"
19 "st,stih416-clkgen-a9-mux", "st,clkgen-mux"
20 "st,stih407-clkgen-a9-mux", "st,clkgen-mux"
21 14
22- #clock-cells : from common clock binding; shall be set to 0. 15- #clock-cells : from common clock binding; shall be set to 0.
23 16
@@ -27,10 +20,13 @@ Required properties:
27 20
28Example: 21Example:
29 22
30 clk_m_hva: clk-m-hva@fd690868 { 23 clk_m_a9: clk-m-a9@92b0000 {
31 #clock-cells = <0>; 24 #clock-cells = <0>;
32 compatible = "st,stih416-clkgenf-vcc-hva", "st,clkgen-mux"; 25 compatible = "st,stih407-clkgen-a9-mux";
33 reg = <0xfd690868 4>; 26 reg = <0x92b0000 0x10000>;
34 27
35 clocks = <&clockgen_f 1>, <&clk_m_a1_div0 3>; 28 clocks = <&clockgen_a9_pll 0>,
29 <&clockgen_a9_pll 0>,
30 <&clk_s_c0_flexgen 13>,
31 <&clk_m_a9_ext2f_div2>;
36 }; 32 };
diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt
index 844b3a0976bf..f207053e0550 100644
--- a/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt
+++ b/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt
@@ -9,24 +9,10 @@ Base address is located to the parent node. See clock binding[2]
9Required properties: 9Required properties:
10 10
11- compatible : shall be: 11- compatible : shall be:
12 "st,clkgena-prediv-c65", "st,clkgena-prediv" 12 "st,clkgen-pll0"
13 "st,clkgena-prediv-c32", "st,clkgena-prediv" 13 "st,clkgen-pll1"
14 14 "st,stih407-clkgen-plla9"
15 "st,clkgena-plls-c65" 15 "st,stih418-clkgen-plla9"
16 "st,plls-c32-a1x-0", "st,clkgen-plls-c32"
17 "st,plls-c32-a1x-1", "st,clkgen-plls-c32"
18 "st,stih415-plls-c32-a9", "st,clkgen-plls-c32"
19 "st,stih415-plls-c32-ddr", "st,clkgen-plls-c32"
20 "st,stih416-plls-c32-a9", "st,clkgen-plls-c32"
21 "st,stih416-plls-c32-ddr", "st,clkgen-plls-c32"
22 "st,stih407-plls-c32-a0", "st,clkgen-plls-c32"
23 "st,stih407-plls-c32-a9", "st,clkgen-plls-c32"
24 "sst,plls-c32-cx_0", "st,clkgen-plls-c32"
25 "sst,plls-c32-cx_1", "st,clkgen-plls-c32"
26 "st,stih418-plls-c28-a9", "st,clkgen-plls-c32"
27
28 "st,stih415-gpu-pll-c32", "st,clkgengpu-pll-c32"
29 "st,stih416-gpu-pll-c32", "st,clkgengpu-pll-c32"
30 16
31- #clock-cells : From common clock binding; shall be set to 1. 17- #clock-cells : From common clock binding; shall be set to 1.
32 18
@@ -36,17 +22,16 @@ Required properties:
36 22
37Example: 23Example:
38 24
39 clockgen-a@fee62000 { 25 clockgen-a9@92b0000 {
40 reg = <0xfee62000 0xb48>; 26 compatible = "st,clkgen-c32";
27 reg = <0x92b0000 0xffff>;
41 28
42 clk_s_a0_pll: clk-s-a0-pll { 29 clockgen_a9_pll: clockgen-a9-pll {
43 #clock-cells = <1>; 30 #clock-cells = <1>;
44 compatible = "st,clkgena-plls-c65"; 31 compatible = "st,stih407-clkgen-plla9";
45 32
46 clocks = <&clk_sysin>; 33 clocks = <&clk_sysin>;
47 34
48 clock-output-names = "clk-s-a0-pll0-hs", 35 clock-output-names = "clockgen-a9-pll-odf";
49 "clk-s-a0-pll0-ls",
50 "clk-s-a0-pll1";
51 }; 36 };
52 }; 37 };
diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-prediv.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-prediv.txt
deleted file mode 100644
index 604766c2619e..000000000000
--- a/Documentation/devicetree/bindings/clock/st/st,clkgen-prediv.txt
+++ /dev/null
@@ -1,36 +0,0 @@
1Binding for a ST pre-divider clock driver.
2
3This binding uses the common clock binding[1].
4Base address is located to the parent node. See clock binding[2]
5
6[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
7[2] Documentation/devicetree/bindings/clock/st/st,clkgen.txt
8
9Required properties:
10
11- compatible : shall be:
12 "st,clkgena-prediv-c65", "st,clkgena-prediv"
13 "st,clkgena-prediv-c32", "st,clkgena-prediv"
14
15- #clock-cells : From common clock binding; shall be set to 0.
16
17- clocks : From common clock binding
18
19- clock-output-names : From common clock binding.
20
21Example:
22
23 clockgen-a@fd345000 {
24 reg = <0xfd345000 0xb50>;
25
26 clk_m_a2_osc_prediv: clk-m-a2-osc-prediv {
27 #clock-cells = <0>;
28 compatible = "st,clkgena-prediv-c32",
29 "st,clkgena-prediv";
30
31 clocks = <&clk_sysin>;
32
33 clock-output-names = "clk-m-a2-osc-prediv";
34 };
35 };
36
diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-vcc.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-vcc.txt
deleted file mode 100644
index 109b3eddcb17..000000000000
--- a/Documentation/devicetree/bindings/clock/st/st,clkgen-vcc.txt
+++ /dev/null
@@ -1,61 +0,0 @@
1Binding for a type of STMicroelectronics clock crossbar (VCC).
2
3The crossbar can take up to 4 input clocks and control up to 16
4output clocks. Not all inputs or outputs have to be in use in a
5particular instantiation. Each output can be individually enabled,
6select any of the input clocks and apply a divide (by 1,2,4 or 8) to
7that selected clock.
8
9This binding uses the common clock binding[1].
10
11[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
12
13Required properties:
14
15- compatible : shall be:
16 "st,stih416-clkgenc", "st,vcc"
17 "st,stih416-clkgenf", "st,vcc"
18
19- #clock-cells : from common clock binding; shall be set to 1.
20
21- reg : A Base address and length of the register set.
22
23- clocks : from common clock binding
24
25- clock-output-names : From common clock binding. The block has 16
26 clock outputs but not all of them in a specific instance
27 have to be used in the SoC. If a clock name is left as
28 an empty string then no clock will be created for the
29 output associated with that string index. If fewer than
30 16 strings are provided then no clocks will be created
31 for the remaining outputs.
32
33Example:
34
35 clockgen_c_vcc: clockgen-c-vcc@0xfe8308ac {
36 #clock-cells = <1>;
37 compatible = "st,stih416-clkgenc", "st,clkgen-vcc";
38 reg = <0xfe8308ac 12>;
39
40 clocks = <&clk_s_vcc_hd>,
41 <&clockgen_c 1>,
42 <&clk_s_tmds_fromphy>,
43 <&clockgen_c 2>;
44
45 clock-output-names = "clk-s-pix-hdmi",
46 "clk-s-pix-dvo",
47 "clk-s-out-dvo",
48 "clk-s-pix-hd",
49 "clk-s-hddac",
50 "clk-s-denc",
51 "clk-s-sddac",
52 "clk-s-pix-main",
53 "clk-s-pix-aux",
54 "clk-s-stfe-frc-0",
55 "clk-s-ref-mcru",
56 "clk-s-slave-mcru",
57 "clk-s-tmds-hdmi",
58 "clk-s-hdmi-reject-pll",
59 "clk-s-thsens";
60 };
61
diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen.txt
index b18bf86f926f..c35390f60545 100644
--- a/Documentation/devicetree/bindings/clock/st/st,clkgen.txt
+++ b/Documentation/devicetree/bindings/clock/st/st,clkgen.txt
@@ -13,14 +13,6 @@ address is common of all subnode.
13 ... 13 ...
14 }; 14 };
15 15
16 prediv_node {
17 ...
18 };
19
20 divmux_node {
21 ...
22 };
23
24 quadfs_node { 16 quadfs_node {
25 ... 17 ...
26 }; 18 };
@@ -29,10 +21,6 @@ address is common of all subnode.
29 ... 21 ...
30 }; 22 };
31 23
32 vcc_node {
33 ...
34 };
35
36 flexgen_node { 24 flexgen_node {
37 ... 25 ...
38 }; 26 };
@@ -43,11 +31,8 @@ This binding uses the common clock binding[1].
43Each subnode should use the binding described in [2]..[7] 31Each subnode should use the binding described in [2]..[7]
44 32
45[1] Documentation/devicetree/bindings/clock/clock-bindings.txt 33[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
46[2] Documentation/devicetree/bindings/clock/st,clkgen-divmux.txt
47[3] Documentation/devicetree/bindings/clock/st,clkgen-mux.txt 34[3] Documentation/devicetree/bindings/clock/st,clkgen-mux.txt
48[4] Documentation/devicetree/bindings/clock/st,clkgen-pll.txt 35[4] Documentation/devicetree/bindings/clock/st,clkgen-pll.txt
49[5] Documentation/devicetree/bindings/clock/st,clkgen-prediv.txt
50[6] Documentation/devicetree/bindings/clock/st,vcc.txt
51[7] Documentation/devicetree/bindings/clock/st,quadfs.txt 36[7] Documentation/devicetree/bindings/clock/st,quadfs.txt
52[8] Documentation/devicetree/bindings/clock/st,flexgen.txt 37[8] Documentation/devicetree/bindings/clock/st,flexgen.txt
53 38
@@ -57,44 +42,27 @@ Required properties:
57 42
58Example: 43Example:
59 44
60 clockgen-a@fee62000 { 45 clockgen-a@090ff000 {
61 46 compatible = "st,clkgen-c32";
62 reg = <0xfee62000 0xb48>; 47 reg = <0x90ff000 0x1000>;
63 48
64 clk_s_a0_pll: clk-s-a0-pll { 49 clk_s_a0_pll: clk-s-a0-pll {
65 #clock-cells = <1>; 50 #clock-cells = <1>;
66 compatible = "st,clkgena-plls-c65"; 51 compatible = "st,clkgen-pll0";
67
68 clocks = <&clk-sysin>;
69
70 clock-output-names = "clk-s-a0-pll0-hs",
71 "clk-s-a0-pll0-ls",
72 "clk-s-a0-pll1";
73 };
74
75 clk_s_a0_osc_prediv: clk-s-a0-osc-prediv {
76 #clock-cells = <0>;
77 compatible = "st,clkgena-prediv-c65",
78 "st,clkgena-prediv";
79 52
80 clocks = <&clk_sysin>; 53 clocks = <&clk_sysin>;
81 54
82 clock-output-names = "clk-s-a0-osc-prediv"; 55 clock-output-names = "clk-s-a0-pll-ofd-0";
83 }; 56 };
84 57
85 clk_s_a0_hs: clk-s-a0-hs { 58 clk_s_a0_flexgen: clk-s-a0-flexgen {
59 compatible = "st,flexgen";
60
86 #clock-cells = <1>; 61 #clock-cells = <1>;
87 compatible = "st,clkgena-divmux-c65-hs",
88 "st,clkgena-divmux";
89 62
90 clocks = <&clk-s_a0_osc_prediv>, 63 clocks = <&clk_s_a0_pll 0>,
91 <&clk-s_a0_pll 0>, /* pll0 hs */ 64 <&clk_sysin>;
92 <&clk-s_a0_pll 2>; /* pll1 */
93 65
94 clock-output-names = "clk-s-fdma-0", 66 clock-output-names = "clk-ic-lmi0";
95 "clk-s-fdma-1",
96 ""; /* clk-s-jit-sense */
97 /* fourth output unused */
98 }; 67 };
99 }; 68 };
100
diff --git a/Documentation/devicetree/bindings/clock/st/st,flexgen.txt b/Documentation/devicetree/bindings/clock/st/st,flexgen.txt
index b7ee5c7e0f75..7ff77fc57dff 100644
--- a/Documentation/devicetree/bindings/clock/st/st,flexgen.txt
+++ b/Documentation/devicetree/bindings/clock/st/st,flexgen.txt
@@ -60,6 +60,10 @@ This binding uses the common clock binding[2].
60Required properties: 60Required properties:
61- compatible : shall be: 61- compatible : shall be:
62 "st,flexgen" 62 "st,flexgen"
63 "st,flexgen-audio", "st,flexgen" (enable clock propagation on parent for
64 audio use case)
65 "st,flexgen-video", "st,flexgen" (enable clock propagation on parent
66 and activate synchronous mode)
63 67
64- #clock-cells : from common clock binding; shall be set to 1 (multiple clock 68- #clock-cells : from common clock binding; shall be set to 1 (multiple clock
65 outputs). 69 outputs).
diff --git a/Documentation/devicetree/bindings/clock/st/st,quadfs.txt b/Documentation/devicetree/bindings/clock/st/st,quadfs.txt
index cedeb9cc8208..d93d49342e60 100644
--- a/Documentation/devicetree/bindings/clock/st/st,quadfs.txt
+++ b/Documentation/devicetree/bindings/clock/st/st,quadfs.txt
@@ -11,12 +11,8 @@ This binding uses the common clock binding[1].
11 11
12Required properties: 12Required properties:
13- compatible : shall be: 13- compatible : shall be:
14 "st,stih416-quadfs216", "st,quadfs" 14 "st,quadfs"
15 "st,stih416-quadfs432", "st,quadfs" 15 "st,quadfs-pll"
16 "st,stih416-quadfs660-E", "st,quadfs"
17 "st,stih416-quadfs660-F", "st,quadfs"
18 "st,stih407-quadfs660-C", "st,quadfs"
19 "st,stih407-quadfs660-D", "st,quadfs"
20 16
21 17
22- #clock-cells : from common clock binding; shall be set to 1. 18- #clock-cells : from common clock binding; shall be set to 1.
@@ -35,14 +31,15 @@ Required properties:
35 31
36Example: 32Example:
37 33
38 clockgen_e: clockgen-e@fd3208bc { 34 clk_s_c0_quadfs: clk-s-c0-quadfs@9103000 {
39 #clock-cells = <1>; 35 #clock-cells = <1>;
40 compatible = "st,stih416-quadfs660-E", "st,quadfs"; 36 compatible = "st,quadfs-pll";
41 reg = <0xfd3208bc 0xB0>; 37 reg = <0x9103000 0x1000>;
42 38
43 clocks = <&clk_sysin>; 39 clocks = <&clk_sysin>;
44 clock-output-names = "clk-m-pix-mdtp-0", 40
45 "clk-m-pix-mdtp-1", 41 clock-output-names = "clk-s-c0-fs0-ch0",
46 "clk-m-pix-mdtp-2", 42 "clk-s-c0-fs0-ch1",
47 "clk-m-mpelpc"; 43 "clk-s-c0-fs0-ch2",
48 }; 44 "clk-s-c0-fs0-ch3";
45 };
diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
index cb91507ffb1e..3868458a5feb 100644
--- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
@@ -2,7 +2,10 @@ Allwinner Clock Control Unit Binding
2------------------------------------ 2------------------------------------
3 3
4Required properties : 4Required properties :
5- compatible: must contain one of the following compatible: 5- compatible: must contain one of the following compatibles:
6 - "allwinner,sun6i-a31-ccu"
7 - "allwinner,sun8i-a23-ccu"
8 - "allwinner,sun8i-a33-ccu"
6 - "allwinner,sun8i-h3-ccu" 9 - "allwinner,sun8i-h3-ccu"
7 10
8- reg: Must contain the registers base address and length 11- reg: Must contain the registers base address and length
diff --git a/Documentation/devicetree/bindings/clock/uniphier-clock.txt b/Documentation/devicetree/bindings/clock/uniphier-clock.txt
new file mode 100644
index 000000000000..c7179d3b5c33
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/uniphier-clock.txt
@@ -0,0 +1,134 @@
1UniPhier clock controller
2
3
4System clock
5------------
6
7Required properties:
8- compatible: should be one of the following:
9 "socionext,uniphier-sld3-clock" - for sLD3 SoC.
10 "socionext,uniphier-ld4-clock" - for LD4 SoC.
11 "socionext,uniphier-pro4-clock" - for Pro4 SoC.
12 "socionext,uniphier-sld8-clock" - for sLD8 SoC.
13 "socionext,uniphier-pro5-clock" - for Pro5 SoC.
14 "socionext,uniphier-pxs2-clock" - for PXs2/LD6b SoC.
15 "socionext,uniphier-ld11-clock" - for LD11 SoC.
16 "socionext,uniphier-ld20-clock" - for LD20 SoC.
17- #clock-cells: should be 1.
18
19Example:
20
21 sysctrl@61840000 {
22 compatible = "socionext,uniphier-sysctrl",
23 "simple-mfd", "syscon";
24 reg = <0x61840000 0x4000>;
25
26 clock {
27 compatible = "socionext,uniphier-ld20-clock";
28 #clock-cells = <1>;
29 };
30
31 other nodes ...
32 };
33
34Provided clocks:
35
36 8: ST DMAC
3712: GIO (Giga bit stream I/O)
3814: USB3 ch0 host
3915: USB3 ch1 host
4016: USB3 ch0 PHY0
4117: USB3 ch0 PHY1
4220: USB3 ch1 PHY0
4321: USB3 ch1 PHY1
44
45
46Media I/O (MIO) clock
47---------------------
48
49Required properties:
50- compatible: should be one of the following:
51 "socionext,uniphier-sld3-mio-clock" - for sLD3 SoC.
52 "socionext,uniphier-ld4-mio-clock" - for LD4 SoC.
53 "socionext,uniphier-pro4-mio-clock" - for Pro4 SoC.
54 "socionext,uniphier-sld8-mio-clock" - for sLD8 SoC.
55 "socionext,uniphier-pro5-mio-clock" - for Pro5 SoC.
56 "socionext,uniphier-pxs2-mio-clock" - for PXs2/LD6b SoC.
57 "socionext,uniphier-ld11-mio-clock" - for LD11 SoC.
58 "socionext,uniphier-ld20-mio-clock" - for LD20 SoC.
59- #clock-cells: should be 1.
60
61Example:
62
63 mioctrl@59810000 {
64 compatible = "socionext,uniphier-mioctrl",
65 "simple-mfd", "syscon";
66 reg = <0x59810000 0x800>;
67
68 clock {
69 compatible = "socionext,uniphier-ld20-mio-clock";
70 #clock-cells = <1>;
71 };
72
73 other nodes ...
74 };
75
76Provided clocks:
77
78 0: SD ch0 host
79 1: eMMC host
80 2: SD ch1 host
81 7: MIO DMAC
82 8: USB2 ch0 host
83 9: USB2 ch1 host
8410: USB2 ch2 host
8511: USB2 ch3 host
8612: USB2 ch0 PHY
8713: USB2 ch1 PHY
8814: USB2 ch2 PHY
8915: USB2 ch3 PHY
90
91
92Peripheral clock
93----------------
94
95Required properties:
96- compatible: should be one of the following:
97 "socionext,uniphier-sld3-peri-clock" - for sLD3 SoC.
98 "socionext,uniphier-ld4-peri-clock" - for LD4 SoC.
99 "socionext,uniphier-pro4-peri-clock" - for Pro4 SoC.
100 "socionext,uniphier-sld8-peri-clock" - for sLD8 SoC.
101 "socionext,uniphier-pro5-peri-clock" - for Pro5 SoC.
102 "socionext,uniphier-pxs2-peri-clock" - for PXs2/LD6b SoC.
103 "socionext,uniphier-ld11-peri-clock" - for LD11 SoC.
104 "socionext,uniphier-ld20-peri-clock" - for LD20 SoC.
105- #clock-cells: should be 1.
106
107Example:
108
109 perictrl@59820000 {
110 compatible = "socionext,uniphier-perictrl",
111 "simple-mfd", "syscon";
112 reg = <0x59820000 0x200>;
113
114 clock {
115 compatible = "socionext,uniphier-ld20-peri-clock";
116 #clock-cells = <1>;
117 };
118
119 other nodes ...
120 };
121
122Provided clocks:
123
124 0: UART ch0
125 1: UART ch1
126 2: UART ch2
127 3: UART ch3
128 4: I2C ch0
129 5: I2C ch1
130 6: I2C ch2
131 7: I2C ch3
132 8: I2C ch4
133 9: I2C ch5
13410: I2C ch6
diff --git a/Documentation/devicetree/bindings/clock/xgene.txt b/Documentation/devicetree/bindings/clock/xgene.txt
index 82f9638121db..8233e771711b 100644
--- a/Documentation/devicetree/bindings/clock/xgene.txt
+++ b/Documentation/devicetree/bindings/clock/xgene.txt
@@ -8,6 +8,7 @@ Required properties:
8- compatible : shall be one of the following: 8- compatible : shall be one of the following:
9 "apm,xgene-socpll-clock" - for a X-Gene SoC PLL clock 9 "apm,xgene-socpll-clock" - for a X-Gene SoC PLL clock
10 "apm,xgene-pcppll-clock" - for a X-Gene PCP PLL clock 10 "apm,xgene-pcppll-clock" - for a X-Gene PCP PLL clock
11 "apm,xgene-pmd-clock" - for a X-Gene PMD clock
11 "apm,xgene-device-clock" - for a X-Gene device clock 12 "apm,xgene-device-clock" - for a X-Gene device clock
12 "apm,xgene-socpll-v2-clock" - for a X-Gene SoC PLL v2 clock 13 "apm,xgene-socpll-v2-clock" - for a X-Gene SoC PLL v2 clock
13 "apm,xgene-pcppll-v2-clock" - for a X-Gene PCP PLL v2 clock 14 "apm,xgene-pcppll-v2-clock" - for a X-Gene PCP PLL v2 clock
@@ -22,6 +23,15 @@ Required properties for SoC or PCP PLL clocks:
22Optional properties for PLL clocks: 23Optional properties for PLL clocks:
23- clock-names : shall be the name of the PLL. If missing, use the device name. 24- clock-names : shall be the name of the PLL. If missing, use the device name.
24 25
26Required properties for PMD clocks:
27- reg : shall be the physical register address for the pmd clock.
28- clocks : shall be the input parent clock phandle for the clock.
29- #clock-cells : shall be set to 1.
30- clock-output-names : shall be the name of the clock referenced by derive
31 clock.
32Optional properties for PLL clocks:
33- clock-names : shall be the name of the clock. If missing, use the device name.
34
25Required properties for device clocks: 35Required properties for device clocks:
26- reg : shall be a list of address and length pairs describing the CSR 36- reg : shall be a list of address and length pairs describing the CSR
27 reset and/or the divider. Either may be omitted, but at least 37 reset and/or the divider. Either may be omitted, but at least
@@ -59,6 +69,14 @@ For example:
59 type = <0>; 69 type = <0>;
60 }; 70 };
61 71
72 pmd0clk: pmd0clk@7e200200 {
73 compatible = "apm,xgene-pmd-clock";
74 #clock-cells = <1>;
75 clocks = <&pmdpll 0>;
76 reg = <0x0 0x7e200200 0x0 0x10>;
77 clock-output-names = "pmd0clk";
78 };
79
62 socpll: socpll@17000120 { 80 socpll: socpll@17000120 {
63 compatible = "apm,xgene-socpll-clock"; 81 compatible = "apm,xgene-socpll-clock";
64 #clock-cells = <1>; 82 #clock-cells = <1>;
diff --git a/Documentation/devicetree/bindings/clock/zx296718-clk.txt b/Documentation/devicetree/bindings/clock/zx296718-clk.txt
new file mode 100644
index 000000000000..8c18b7b237bf
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/zx296718-clk.txt
@@ -0,0 +1,35 @@
1Device Tree Clock bindings for ZTE zx296718
2
3This binding uses the common clock binding[1].
4
5[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
6
7Required properties:
8- compatible : shall be one of the following:
9 "zte,zx296718-topcrm":
10 zx296718 top clock selection, divider and gating
11
12 "zte,zx296718-lsp0crm" and
13 "zte,zx296718-lsp1crm":
14 zx296718 device level clock selection and gating
15
16- reg: Address and length of the register set
17
18The clock consumer should specify the desired clock by having the clock
19ID in its "clocks" phandle cell. See include/dt-bindings/clock/zx296718-clock.h
20for the full list of zx296718 clock IDs.
21
22
23topclk: topcrm@1461000 {
24 compatible = "zte,zx296718-topcrm-clk";
25 reg = <0x01461000 0x1000>;
26 #clock-cells = <1>;
27};
28
29usbphy0:usb-phy0 {
30 compatible = "zte,zx296718-usb-phy";
31 #phy-cells = <0>;
32 clocks = <&topclk USB20_PHY_CLK>;
33 clock-names = "phyclk";
34 status = "okay";
35};
diff --git a/MAINTAINERS b/MAINTAINERS
index ac8f3cec03f9..8dfb2b45b403 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1847,6 +1847,7 @@ F: arch/arm/mach-uniphier/
1847F: arch/arm/mm/cache-uniphier.c 1847F: arch/arm/mm/cache-uniphier.c
1848F: arch/arm64/boot/dts/socionext/ 1848F: arch/arm64/boot/dts/socionext/
1849F: drivers/bus/uniphier-system-bus.c 1849F: drivers/bus/uniphier-system-bus.c
1850F: drivers/clk/uniphier/
1850F: drivers/i2c/busses/i2c-uniphier* 1851F: drivers/i2c/busses/i2c-uniphier*
1851F: drivers/pinctrl/uniphier/ 1852F: drivers/pinctrl/uniphier/
1852F: drivers/tty/serial/8250/8250_uniphier.c 1853F: drivers/tty/serial/8250/8250_uniphier.c
@@ -3164,6 +3165,7 @@ COMMON CLK FRAMEWORK
3164M: Michael Turquette <mturquette@baylibre.com> 3165M: Michael Turquette <mturquette@baylibre.com>
3165M: Stephen Boyd <sboyd@codeaurora.org> 3166M: Stephen Boyd <sboyd@codeaurora.org>
3166L: linux-clk@vger.kernel.org 3167L: linux-clk@vger.kernel.org
3168Q: http://patchwork.kernel.org/project/linux-clk/list/
3167T: git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git 3169T: git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git
3168S: Maintained 3170S: Maintained
3169F: Documentation/devicetree/bindings/clock/ 3171F: Documentation/devicetree/bindings/clock/
@@ -9950,6 +9952,12 @@ F: drivers/rpmsg/
9950F: Documentation/rpmsg.txt 9952F: Documentation/rpmsg.txt
9951F: include/linux/rpmsg.h 9953F: include/linux/rpmsg.h
9952 9954
9955RENESAS CLOCK DRIVERS
9956M: Geert Uytterhoeven <geert+renesas@glider.be>
9957L: linux-renesas-soc@vger.kernel.org
9958S: Supported
9959F: drivers/clk/renesas/
9960
9953RENESAS ETHERNET DRIVERS 9961RENESAS ETHERNET DRIVERS
9954R: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> 9962R: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
9955L: netdev@vger.kernel.org 9963L: netdev@vger.kernel.org
@@ -10293,9 +10301,12 @@ F: drivers/nfc/s3fwrn5
10293SAMSUNG SOC CLOCK DRIVERS 10301SAMSUNG SOC CLOCK DRIVERS
10294M: Sylwester Nawrocki <s.nawrocki@samsung.com> 10302M: Sylwester Nawrocki <s.nawrocki@samsung.com>
10295M: Tomasz Figa <tomasz.figa@gmail.com> 10303M: Tomasz Figa <tomasz.figa@gmail.com>
10304M: Chanwoo Choi <cw00.choi@samsung.com>
10296S: Supported 10305S: Supported
10297L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) 10306L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
10298F: drivers/clk/samsung/ 10307F: drivers/clk/samsung/
10308F: include/dt-bindings/clock/exynos*.h
10309F: Documentation/devicetree/bindings/clock/exynos*.txt
10299 10310
10300SAMSUNG SPI DRIVERS 10311SAMSUNG SPI DRIVERS
10301M: Kukjin Kim <kgene@kernel.org> 10312M: Kukjin Kim <kgene@kernel.org>
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 34f0fca0b847..7bf3ae76f782 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -15,7 +15,6 @@ config ARCH_BCM_IPROC
15 select HAVE_ARM_SCU if SMP 15 select HAVE_ARM_SCU if SMP
16 select HAVE_ARM_TWD if SMP 16 select HAVE_ARM_TWD if SMP
17 select ARM_GLOBAL_TIMER 17 select ARM_GLOBAL_TIMER
18 select COMMON_CLK_IPROC
19 select CLKSRC_MMIO 18 select CLKSRC_MMIO
20 select GPIOLIB 19 select GPIOLIB
21 select ARM_AMBA 20 select ARM_AMBA
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index e2d9bd760c84..6a8ac04bedeb 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -31,22 +31,12 @@ config COMMON_CLK_WM831X
31 31
32source "drivers/clk/versatile/Kconfig" 32source "drivers/clk/versatile/Kconfig"
33 33
34config COMMON_CLK_MAX_GEN
35 bool
36
37config COMMON_CLK_MAX77686 34config COMMON_CLK_MAX77686
38 tristate "Clock driver for Maxim 77686 MFD" 35 tristate "Clock driver for Maxim 77620/77686/77802 MFD"
39 depends on MFD_MAX77686 36 depends on MFD_MAX77686 || MFD_MAX77620
40 select COMMON_CLK_MAX_GEN
41 ---help---
42 This driver supports Maxim 77686 crystal oscillator clock.
43
44config COMMON_CLK_MAX77802
45 tristate "Clock driver for Maxim 77802 PMIC"
46 depends on MFD_MAX77686
47 select COMMON_CLK_MAX_GEN
48 ---help--- 37 ---help---
49 This driver supports Maxim 77802 crystal oscillator clock. 38 This driver supports Maxim 77620/77686/77802 crystal oscillator
39 clock.
50 40
51config COMMON_CLK_RK808 41config COMMON_CLK_RK808
52 tristate "Clock driver for RK808/RK818" 42 tristate "Clock driver for RK808/RK818"
@@ -210,6 +200,7 @@ config COMMON_CLK_OXNAS
210 200
211source "drivers/clk/bcm/Kconfig" 201source "drivers/clk/bcm/Kconfig"
212source "drivers/clk/hisilicon/Kconfig" 202source "drivers/clk/hisilicon/Kconfig"
203source "drivers/clk/mediatek/Kconfig"
213source "drivers/clk/meson/Kconfig" 204source "drivers/clk/meson/Kconfig"
214source "drivers/clk/mvebu/Kconfig" 205source "drivers/clk/mvebu/Kconfig"
215source "drivers/clk/qcom/Kconfig" 206source "drivers/clk/qcom/Kconfig"
@@ -218,5 +209,6 @@ source "drivers/clk/samsung/Kconfig"
218source "drivers/clk/sunxi-ng/Kconfig" 209source "drivers/clk/sunxi-ng/Kconfig"
219source "drivers/clk/tegra/Kconfig" 210source "drivers/clk/tegra/Kconfig"
220source "drivers/clk/ti/Kconfig" 211source "drivers/clk/ti/Kconfig"
212source "drivers/clk/uniphier/Kconfig"
221 213
222endmenu 214endmenu
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 3b6f9cf3464a..925081ec14c0 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -26,10 +26,7 @@ obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
26obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o 26obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o
27obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o 27obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
28obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o 28obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
29obj-$(CONFIG_MACH_LOONGSON32) += clk-ls1x.o
30obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o
31obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o 29obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
32obj-$(CONFIG_COMMON_CLK_MAX77802) += clk-max77802.o
33obj-$(CONFIG_ARCH_MB86S7X) += clk-mb86s7x.o 30obj-$(CONFIG_ARCH_MB86S7X) += clk-mb86s7x.o
34obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o 31obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
35obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o 32obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
@@ -63,6 +60,7 @@ obj-$(CONFIG_ARCH_HISI) += hisilicon/
63obj-$(CONFIG_ARCH_MXC) += imx/ 60obj-$(CONFIG_ARCH_MXC) += imx/
64obj-$(CONFIG_MACH_INGENIC) += ingenic/ 61obj-$(CONFIG_MACH_INGENIC) += ingenic/
65obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/ 62obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/
63obj-$(CONFIG_MACH_LOONGSON32) += loongson1/
66obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ 64obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
67obj-$(CONFIG_COMMON_CLK_AMLOGIC) += meson/ 65obj-$(CONFIG_COMMON_CLK_AMLOGIC) += meson/
68obj-$(CONFIG_MACH_PIC32) += microchip/ 66obj-$(CONFIG_MACH_PIC32) += microchip/
@@ -86,6 +84,7 @@ obj-$(CONFIG_ARCH_SUNXI) += sunxi/
86obj-$(CONFIG_ARCH_SUNXI) += sunxi-ng/ 84obj-$(CONFIG_ARCH_SUNXI) += sunxi-ng/
87obj-$(CONFIG_ARCH_TEGRA) += tegra/ 85obj-$(CONFIG_ARCH_TEGRA) += tegra/
88obj-y += ti/ 86obj-y += ti/
87obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
89obj-$(CONFIG_ARCH_U8500) += ux500/ 88obj-$(CONFIG_ARCH_U8500) += ux500/
90obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ 89obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
91obj-$(CONFIG_X86) += x86/ 90obj-$(CONFIG_X86) += x86/
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
index 7f6bec8837ea..4e1cd5aa69d8 100644
--- a/drivers/clk/at91/clk-generated.c
+++ b/drivers/clk/at91/clk-generated.c
@@ -233,14 +233,16 @@ static void clk_generated_startup(struct clk_generated *gck)
233 >> AT91_PMC_PCR_GCKDIV_OFFSET; 233 >> AT91_PMC_PCR_GCKDIV_OFFSET;
234} 234}
235 235
236static struct clk * __init 236static struct clk_hw * __init
237at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, const char 237at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
238 *name, const char **parent_names, u8 num_parents, 238 const char *name, const char **parent_names,
239 u8 id, const struct clk_range *range) 239 u8 num_parents, u8 id,
240 const struct clk_range *range)
240{ 241{
241 struct clk_generated *gck; 242 struct clk_generated *gck;
242 struct clk *clk = NULL;
243 struct clk_init_data init; 243 struct clk_init_data init;
244 struct clk_hw *hw;
245 int ret;
244 246
245 gck = kzalloc(sizeof(*gck), GFP_KERNEL); 247 gck = kzalloc(sizeof(*gck), GFP_KERNEL);
246 if (!gck) 248 if (!gck)
@@ -258,13 +260,15 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, const char
258 gck->lock = lock; 260 gck->lock = lock;
259 gck->range = *range; 261 gck->range = *range;
260 262
261 clk = clk_register(NULL, &gck->hw); 263 hw = &gck->hw;
262 if (IS_ERR(clk)) 264 ret = clk_hw_register(NULL, &gck->hw);
265 if (ret) {
263 kfree(gck); 266 kfree(gck);
264 else 267 hw = ERR_PTR(ret);
268 } else
265 clk_generated_startup(gck); 269 clk_generated_startup(gck);
266 270
267 return clk; 271 return hw;
268} 272}
269 273
270static void __init of_sama5d2_clk_generated_setup(struct device_node *np) 274static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
@@ -272,7 +276,7 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
272 int num; 276 int num;
273 u32 id; 277 u32 id;
274 const char *name; 278 const char *name;
275 struct clk *clk; 279 struct clk_hw *hw;
276 unsigned int num_parents; 280 unsigned int num_parents;
277 const char *parent_names[GENERATED_SOURCE_MAX]; 281 const char *parent_names[GENERATED_SOURCE_MAX];
278 struct device_node *gcknp; 282 struct device_node *gcknp;
@@ -306,13 +310,13 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
306 of_at91_get_clk_range(gcknp, "atmel,clk-output-range", 310 of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
307 &range); 311 &range);
308 312
309 clk = at91_clk_register_generated(regmap, &pmc_pcr_lock, name, 313 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name,
310 parent_names, num_parents, 314 parent_names, num_parents,
311 id, &range); 315 id, &range);
312 if (IS_ERR(clk)) 316 if (IS_ERR(hw))
313 continue; 317 continue;
314 318
315 of_clk_add_provider(gcknp, of_clk_src_simple_get, clk); 319 of_clk_add_hw_provider(gcknp, of_clk_hw_simple_get, hw);
316 } 320 }
317} 321}
318CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated", 322CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated",
diff --git a/drivers/clk/at91/clk-h32mx.c b/drivers/clk/at91/clk-h32mx.c
index 8e20c8a76db7..e0daa4a31f88 100644
--- a/drivers/clk/at91/clk-h32mx.c
+++ b/drivers/clk/at91/clk-h32mx.c
@@ -92,7 +92,7 @@ static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
92 struct clk_init_data init; 92 struct clk_init_data init;
93 const char *parent_name; 93 const char *parent_name;
94 struct regmap *regmap; 94 struct regmap *regmap;
95 struct clk *clk; 95 int ret;
96 96
97 regmap = syscon_node_to_regmap(of_get_parent(np)); 97 regmap = syscon_node_to_regmap(of_get_parent(np));
98 if (IS_ERR(regmap)) 98 if (IS_ERR(regmap))
@@ -113,13 +113,13 @@ static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
113 h32mxclk->hw.init = &init; 113 h32mxclk->hw.init = &init;
114 h32mxclk->regmap = regmap; 114 h32mxclk->regmap = regmap;
115 115
116 clk = clk_register(NULL, &h32mxclk->hw); 116 ret = clk_hw_register(NULL, &h32mxclk->hw);
117 if (IS_ERR(clk)) { 117 if (ret) {
118 kfree(h32mxclk); 118 kfree(h32mxclk);
119 return; 119 return;
120 } 120 }
121 121
122 of_clk_add_provider(np, of_clk_src_simple_get, clk); 122 of_clk_add_hw_provider(np, of_clk_hw_simple_get, &h32mxclk->hw);
123} 123}
124CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx", 124CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx",
125 of_sama5d4_clk_h32mx_setup); 125 of_sama5d4_clk_h32mx_setup);
diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c
index 58b5baca670c..c813c27f2e58 100644
--- a/drivers/clk/at91/clk-main.c
+++ b/drivers/clk/at91/clk-main.c
@@ -128,15 +128,16 @@ static const struct clk_ops main_osc_ops = {
128 .is_prepared = clk_main_osc_is_prepared, 128 .is_prepared = clk_main_osc_is_prepared,
129}; 129};
130 130
131static struct clk * __init 131static struct clk_hw * __init
132at91_clk_register_main_osc(struct regmap *regmap, 132at91_clk_register_main_osc(struct regmap *regmap,
133 const char *name, 133 const char *name,
134 const char *parent_name, 134 const char *parent_name,
135 bool bypass) 135 bool bypass)
136{ 136{
137 struct clk_main_osc *osc; 137 struct clk_main_osc *osc;
138 struct clk *clk = NULL;
139 struct clk_init_data init; 138 struct clk_init_data init;
139 struct clk_hw *hw;
140 int ret;
140 141
141 if (!name || !parent_name) 142 if (!name || !parent_name)
142 return ERR_PTR(-EINVAL); 143 return ERR_PTR(-EINVAL);
@@ -160,16 +161,19 @@ at91_clk_register_main_osc(struct regmap *regmap,
160 AT91_PMC_MOSCEN, 161 AT91_PMC_MOSCEN,
161 AT91_PMC_OSCBYPASS | AT91_PMC_KEY); 162 AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
162 163
163 clk = clk_register(NULL, &osc->hw); 164 hw = &osc->hw;
164 if (IS_ERR(clk)) 165 ret = clk_hw_register(NULL, &osc->hw);
166 if (ret) {
165 kfree(osc); 167 kfree(osc);
168 hw = ERR_PTR(ret);
169 }
166 170
167 return clk; 171 return hw;
168} 172}
169 173
170static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np) 174static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
171{ 175{
172 struct clk *clk; 176 struct clk_hw *hw;
173 const char *name = np->name; 177 const char *name = np->name;
174 const char *parent_name; 178 const char *parent_name;
175 struct regmap *regmap; 179 struct regmap *regmap;
@@ -183,11 +187,11 @@ static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
183 if (IS_ERR(regmap)) 187 if (IS_ERR(regmap))
184 return; 188 return;
185 189
186 clk = at91_clk_register_main_osc(regmap, name, parent_name, bypass); 190 hw = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
187 if (IS_ERR(clk)) 191 if (IS_ERR(hw))
188 return; 192 return;
189 193
190 of_clk_add_provider(np, of_clk_src_simple_get, clk); 194 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
191} 195}
192CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc", 196CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
193 of_at91rm9200_clk_main_osc_setup); 197 of_at91rm9200_clk_main_osc_setup);
@@ -271,14 +275,15 @@ static const struct clk_ops main_rc_osc_ops = {
271 .recalc_accuracy = clk_main_rc_osc_recalc_accuracy, 275 .recalc_accuracy = clk_main_rc_osc_recalc_accuracy,
272}; 276};
273 277
274static struct clk * __init 278static struct clk_hw * __init
275at91_clk_register_main_rc_osc(struct regmap *regmap, 279at91_clk_register_main_rc_osc(struct regmap *regmap,
276 const char *name, 280 const char *name,
277 u32 frequency, u32 accuracy) 281 u32 frequency, u32 accuracy)
278{ 282{
279 struct clk_main_rc_osc *osc; 283 struct clk_main_rc_osc *osc;
280 struct clk *clk = NULL;
281 struct clk_init_data init; 284 struct clk_init_data init;
285 struct clk_hw *hw;
286 int ret;
282 287
283 if (!name || !frequency) 288 if (!name || !frequency)
284 return ERR_PTR(-EINVAL); 289 return ERR_PTR(-EINVAL);
@@ -298,16 +303,19 @@ at91_clk_register_main_rc_osc(struct regmap *regmap,
298 osc->frequency = frequency; 303 osc->frequency = frequency;
299 osc->accuracy = accuracy; 304 osc->accuracy = accuracy;
300 305
301 clk = clk_register(NULL, &osc->hw); 306 hw = &osc->hw;
302 if (IS_ERR(clk)) 307 ret = clk_hw_register(NULL, hw);
308 if (ret) {
303 kfree(osc); 309 kfree(osc);
310 hw = ERR_PTR(ret);
311 }
304 312
305 return clk; 313 return hw;
306} 314}
307 315
308static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np) 316static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
309{ 317{
310 struct clk *clk; 318 struct clk_hw *hw;
311 u32 frequency = 0; 319 u32 frequency = 0;
312 u32 accuracy = 0; 320 u32 accuracy = 0;
313 const char *name = np->name; 321 const char *name = np->name;
@@ -321,11 +329,11 @@ static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
321 if (IS_ERR(regmap)) 329 if (IS_ERR(regmap))
322 return; 330 return;
323 331
324 clk = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy); 332 hw = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy);
325 if (IS_ERR(clk)) 333 if (IS_ERR(hw))
326 return; 334 return;
327 335
328 of_clk_add_provider(np, of_clk_src_simple_get, clk); 336 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
329} 337}
330CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc", 338CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
331 of_at91sam9x5_clk_main_rc_osc_setup); 339 of_at91sam9x5_clk_main_rc_osc_setup);
@@ -395,14 +403,15 @@ static const struct clk_ops rm9200_main_ops = {
395 .recalc_rate = clk_rm9200_main_recalc_rate, 403 .recalc_rate = clk_rm9200_main_recalc_rate,
396}; 404};
397 405
398static struct clk * __init 406static struct clk_hw * __init
399at91_clk_register_rm9200_main(struct regmap *regmap, 407at91_clk_register_rm9200_main(struct regmap *regmap,
400 const char *name, 408 const char *name,
401 const char *parent_name) 409 const char *parent_name)
402{ 410{
403 struct clk_rm9200_main *clkmain; 411 struct clk_rm9200_main *clkmain;
404 struct clk *clk = NULL;
405 struct clk_init_data init; 412 struct clk_init_data init;
413 struct clk_hw *hw;
414 int ret;
406 415
407 if (!name) 416 if (!name)
408 return ERR_PTR(-EINVAL); 417 return ERR_PTR(-EINVAL);
@@ -423,16 +432,19 @@ at91_clk_register_rm9200_main(struct regmap *regmap,
423 clkmain->hw.init = &init; 432 clkmain->hw.init = &init;
424 clkmain->regmap = regmap; 433 clkmain->regmap = regmap;
425 434
426 clk = clk_register(NULL, &clkmain->hw); 435 hw = &clkmain->hw;
427 if (IS_ERR(clk)) 436 ret = clk_hw_register(NULL, &clkmain->hw);
437 if (ret) {
428 kfree(clkmain); 438 kfree(clkmain);
439 hw = ERR_PTR(ret);
440 }
429 441
430 return clk; 442 return hw;
431} 443}
432 444
433static void __init of_at91rm9200_clk_main_setup(struct device_node *np) 445static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
434{ 446{
435 struct clk *clk; 447 struct clk_hw *hw;
436 const char *parent_name; 448 const char *parent_name;
437 const char *name = np->name; 449 const char *name = np->name;
438 struct regmap *regmap; 450 struct regmap *regmap;
@@ -444,11 +456,11 @@ static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
444 if (IS_ERR(regmap)) 456 if (IS_ERR(regmap))
445 return; 457 return;
446 458
447 clk = at91_clk_register_rm9200_main(regmap, name, parent_name); 459 hw = at91_clk_register_rm9200_main(regmap, name, parent_name);
448 if (IS_ERR(clk)) 460 if (IS_ERR(hw))
449 return; 461 return;
450 462
451 of_clk_add_provider(np, of_clk_src_simple_get, clk); 463 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
452} 464}
453CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main", 465CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
454 of_at91rm9200_clk_main_setup); 466 of_at91rm9200_clk_main_setup);
@@ -529,16 +541,17 @@ static const struct clk_ops sam9x5_main_ops = {
529 .get_parent = clk_sam9x5_main_get_parent, 541 .get_parent = clk_sam9x5_main_get_parent,
530}; 542};
531 543
532static struct clk * __init 544static struct clk_hw * __init
533at91_clk_register_sam9x5_main(struct regmap *regmap, 545at91_clk_register_sam9x5_main(struct regmap *regmap,
534 const char *name, 546 const char *name,
535 const char **parent_names, 547 const char **parent_names,
536 int num_parents) 548 int num_parents)
537{ 549{
538 struct clk_sam9x5_main *clkmain; 550 struct clk_sam9x5_main *clkmain;
539 struct clk *clk = NULL;
540 struct clk_init_data init; 551 struct clk_init_data init;
541 unsigned int status; 552 unsigned int status;
553 struct clk_hw *hw;
554 int ret;
542 555
543 if (!name) 556 if (!name)
544 return ERR_PTR(-EINVAL); 557 return ERR_PTR(-EINVAL);
@@ -561,16 +574,19 @@ at91_clk_register_sam9x5_main(struct regmap *regmap,
561 regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status); 574 regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
562 clkmain->parent = status & AT91_PMC_MOSCEN ? 1 : 0; 575 clkmain->parent = status & AT91_PMC_MOSCEN ? 1 : 0;
563 576
564 clk = clk_register(NULL, &clkmain->hw); 577 hw = &clkmain->hw;
565 if (IS_ERR(clk)) 578 ret = clk_hw_register(NULL, &clkmain->hw);
579 if (ret) {
566 kfree(clkmain); 580 kfree(clkmain);
581 hw = ERR_PTR(ret);
582 }
567 583
568 return clk; 584 return hw;
569} 585}
570 586
571static void __init of_at91sam9x5_clk_main_setup(struct device_node *np) 587static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
572{ 588{
573 struct clk *clk; 589 struct clk_hw *hw;
574 const char *parent_names[2]; 590 const char *parent_names[2];
575 unsigned int num_parents; 591 unsigned int num_parents;
576 const char *name = np->name; 592 const char *name = np->name;
@@ -587,12 +603,12 @@ static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
587 603
588 of_property_read_string(np, "clock-output-names", &name); 604 of_property_read_string(np, "clock-output-names", &name);
589 605
590 clk = at91_clk_register_sam9x5_main(regmap, name, parent_names, 606 hw = at91_clk_register_sam9x5_main(regmap, name, parent_names,
591 num_parents); 607 num_parents);
592 if (IS_ERR(clk)) 608 if (IS_ERR(hw))
593 return; 609 return;
594 610
595 of_clk_add_provider(np, of_clk_src_simple_get, clk); 611 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
596} 612}
597CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main", 613CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
598 of_at91sam9x5_clk_main_setup); 614 of_at91sam9x5_clk_main_setup);
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
index d1021e106191..e9cba9fc26d7 100644
--- a/drivers/clk/at91/clk-master.c
+++ b/drivers/clk/at91/clk-master.c
@@ -120,7 +120,7 @@ static const struct clk_ops master_ops = {
120 .get_parent = clk_master_get_parent, 120 .get_parent = clk_master_get_parent,
121}; 121};
122 122
123static struct clk * __init 123static struct clk_hw * __init
124at91_clk_register_master(struct regmap *regmap, 124at91_clk_register_master(struct regmap *regmap,
125 const char *name, int num_parents, 125 const char *name, int num_parents,
126 const char **parent_names, 126 const char **parent_names,
@@ -128,8 +128,9 @@ at91_clk_register_master(struct regmap *regmap,
128 const struct clk_master_characteristics *characteristics) 128 const struct clk_master_characteristics *characteristics)
129{ 129{
130 struct clk_master *master; 130 struct clk_master *master;
131 struct clk *clk = NULL;
132 struct clk_init_data init; 131 struct clk_init_data init;
132 struct clk_hw *hw;
133 int ret;
133 134
134 if (!name || !num_parents || !parent_names) 135 if (!name || !num_parents || !parent_names)
135 return ERR_PTR(-EINVAL); 136 return ERR_PTR(-EINVAL);
@@ -149,12 +150,14 @@ at91_clk_register_master(struct regmap *regmap,
149 master->characteristics = characteristics; 150 master->characteristics = characteristics;
150 master->regmap = regmap; 151 master->regmap = regmap;
151 152
152 clk = clk_register(NULL, &master->hw); 153 hw = &master->hw;
153 if (IS_ERR(clk)) { 154 ret = clk_hw_register(NULL, &master->hw);
155 if (ret) {
154 kfree(master); 156 kfree(master);
157 hw = ERR_PTR(ret);
155 } 158 }
156 159
157 return clk; 160 return hw;
158} 161}
159 162
160 163
@@ -198,7 +201,7 @@ static void __init
198of_at91_clk_master_setup(struct device_node *np, 201of_at91_clk_master_setup(struct device_node *np,
199 const struct clk_master_layout *layout) 202 const struct clk_master_layout *layout)
200{ 203{
201 struct clk *clk; 204 struct clk_hw *hw;
202 unsigned int num_parents; 205 unsigned int num_parents;
203 const char *parent_names[MASTER_SOURCE_MAX]; 206 const char *parent_names[MASTER_SOURCE_MAX];
204 const char *name = np->name; 207 const char *name = np->name;
@@ -221,13 +224,13 @@ of_at91_clk_master_setup(struct device_node *np,
221 if (IS_ERR(regmap)) 224 if (IS_ERR(regmap))
222 return; 225 return;
223 226
224 clk = at91_clk_register_master(regmap, name, num_parents, 227 hw = at91_clk_register_master(regmap, name, num_parents,
225 parent_names, layout, 228 parent_names, layout,
226 characteristics); 229 characteristics);
227 if (IS_ERR(clk)) 230 if (IS_ERR(hw))
228 goto out_free_characteristics; 231 goto out_free_characteristics;
229 232
230 of_clk_add_provider(np, of_clk_src_simple_get, clk); 233 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
231 return; 234 return;
232 235
233out_free_characteristics: 236out_free_characteristics:
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c
index fd160728e990..dc29fd979d3f 100644
--- a/drivers/clk/at91/clk-peripheral.c
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -104,13 +104,14 @@ static const struct clk_ops peripheral_ops = {
104 .is_enabled = clk_peripheral_is_enabled, 104 .is_enabled = clk_peripheral_is_enabled,
105}; 105};
106 106
107static struct clk * __init 107static struct clk_hw * __init
108at91_clk_register_peripheral(struct regmap *regmap, const char *name, 108at91_clk_register_peripheral(struct regmap *regmap, const char *name,
109 const char *parent_name, u32 id) 109 const char *parent_name, u32 id)
110{ 110{
111 struct clk_peripheral *periph; 111 struct clk_peripheral *periph;
112 struct clk *clk = NULL;
113 struct clk_init_data init; 112 struct clk_init_data init;
113 struct clk_hw *hw;
114 int ret;
114 115
115 if (!name || !parent_name || id > PERIPHERAL_ID_MAX) 116 if (!name || !parent_name || id > PERIPHERAL_ID_MAX)
116 return ERR_PTR(-EINVAL); 117 return ERR_PTR(-EINVAL);
@@ -129,11 +130,14 @@ at91_clk_register_peripheral(struct regmap *regmap, const char *name,
129 periph->hw.init = &init; 130 periph->hw.init = &init;
130 periph->regmap = regmap; 131 periph->regmap = regmap;
131 132
132 clk = clk_register(NULL, &periph->hw); 133 hw = &periph->hw;
133 if (IS_ERR(clk)) 134 ret = clk_hw_register(NULL, &periph->hw);
135 if (ret) {
134 kfree(periph); 136 kfree(periph);
137 hw = ERR_PTR(ret);
138 }
135 139
136 return clk; 140 return hw;
137} 141}
138 142
139static void clk_sam9x5_peripheral_autodiv(struct clk_sam9x5_peripheral *periph) 143static void clk_sam9x5_peripheral_autodiv(struct clk_sam9x5_peripheral *periph)
@@ -327,14 +331,15 @@ static const struct clk_ops sam9x5_peripheral_ops = {
327 .set_rate = clk_sam9x5_peripheral_set_rate, 331 .set_rate = clk_sam9x5_peripheral_set_rate,
328}; 332};
329 333
330static struct clk * __init 334static struct clk_hw * __init
331at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, 335at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
332 const char *name, const char *parent_name, 336 const char *name, const char *parent_name,
333 u32 id, const struct clk_range *range) 337 u32 id, const struct clk_range *range)
334{ 338{
335 struct clk_sam9x5_peripheral *periph; 339 struct clk_sam9x5_peripheral *periph;
336 struct clk *clk = NULL;
337 struct clk_init_data init; 340 struct clk_init_data init;
341 struct clk_hw *hw;
342 int ret;
338 343
339 if (!name || !parent_name) 344 if (!name || !parent_name)
340 return ERR_PTR(-EINVAL); 345 return ERR_PTR(-EINVAL);
@@ -357,13 +362,15 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
357 periph->auto_div = true; 362 periph->auto_div = true;
358 periph->range = *range; 363 periph->range = *range;
359 364
360 clk = clk_register(NULL, &periph->hw); 365 hw = &periph->hw;
361 if (IS_ERR(clk)) 366 ret = clk_hw_register(NULL, &periph->hw);
367 if (ret) {
362 kfree(periph); 368 kfree(periph);
363 else 369 hw = ERR_PTR(ret);
370 } else
364 clk_sam9x5_peripheral_autodiv(periph); 371 clk_sam9x5_peripheral_autodiv(periph);
365 372
366 return clk; 373 return hw;
367} 374}
368 375
369static void __init 376static void __init
@@ -371,7 +378,7 @@ of_at91_clk_periph_setup(struct device_node *np, u8 type)
371{ 378{
372 int num; 379 int num;
373 u32 id; 380 u32 id;
374 struct clk *clk; 381 struct clk_hw *hw;
375 const char *parent_name; 382 const char *parent_name;
376 const char *name; 383 const char *name;
377 struct device_node *periphclknp; 384 struct device_node *periphclknp;
@@ -400,7 +407,7 @@ of_at91_clk_periph_setup(struct device_node *np, u8 type)
400 name = periphclknp->name; 407 name = periphclknp->name;
401 408
402 if (type == PERIPHERAL_AT91RM9200) { 409 if (type == PERIPHERAL_AT91RM9200) {
403 clk = at91_clk_register_peripheral(regmap, name, 410 hw = at91_clk_register_peripheral(regmap, name,
404 parent_name, id); 411 parent_name, id);
405 } else { 412 } else {
406 struct clk_range range = CLK_RANGE(0, 0); 413 struct clk_range range = CLK_RANGE(0, 0);
@@ -409,17 +416,17 @@ of_at91_clk_periph_setup(struct device_node *np, u8 type)
409 "atmel,clk-output-range", 416 "atmel,clk-output-range",
410 &range); 417 &range);
411 418
412 clk = at91_clk_register_sam9x5_peripheral(regmap, 419 hw = at91_clk_register_sam9x5_peripheral(regmap,
413 &pmc_pcr_lock, 420 &pmc_pcr_lock,
414 name, 421 name,
415 parent_name, 422 parent_name,
416 id, &range); 423 id, &range);
417 } 424 }
418 425
419 if (IS_ERR(clk)) 426 if (IS_ERR(hw))
420 continue; 427 continue;
421 428
422 of_clk_add_provider(periphclknp, of_clk_src_simple_get, clk); 429 of_clk_add_hw_provider(periphclknp, of_clk_hw_simple_get, hw);
423 } 430 }
424} 431}
425 432
diff --git a/drivers/clk/at91/clk-pll.c b/drivers/clk/at91/clk-pll.c
index fb2e0b56d4b7..45ad168e1496 100644
--- a/drivers/clk/at91/clk-pll.c
+++ b/drivers/clk/at91/clk-pll.c
@@ -296,17 +296,18 @@ static const struct clk_ops pll_ops = {
296 .set_rate = clk_pll_set_rate, 296 .set_rate = clk_pll_set_rate,
297}; 297};
298 298
299static struct clk * __init 299static struct clk_hw * __init
300at91_clk_register_pll(struct regmap *regmap, const char *name, 300at91_clk_register_pll(struct regmap *regmap, const char *name,
301 const char *parent_name, u8 id, 301 const char *parent_name, u8 id,
302 const struct clk_pll_layout *layout, 302 const struct clk_pll_layout *layout,
303 const struct clk_pll_characteristics *characteristics) 303 const struct clk_pll_characteristics *characteristics)
304{ 304{
305 struct clk_pll *pll; 305 struct clk_pll *pll;
306 struct clk *clk = NULL; 306 struct clk_hw *hw;
307 struct clk_init_data init; 307 struct clk_init_data init;
308 int offset = PLL_REG(id); 308 int offset = PLL_REG(id);
309 unsigned int pllr; 309 unsigned int pllr;
310 int ret;
310 311
311 if (id > PLL_MAX_ID) 312 if (id > PLL_MAX_ID)
312 return ERR_PTR(-EINVAL); 313 return ERR_PTR(-EINVAL);
@@ -330,12 +331,14 @@ at91_clk_register_pll(struct regmap *regmap, const char *name,
330 pll->div = PLL_DIV(pllr); 331 pll->div = PLL_DIV(pllr);
331 pll->mul = PLL_MUL(pllr, layout); 332 pll->mul = PLL_MUL(pllr, layout);
332 333
333 clk = clk_register(NULL, &pll->hw); 334 hw = &pll->hw;
334 if (IS_ERR(clk)) { 335 ret = clk_hw_register(NULL, &pll->hw);
336 if (ret) {
335 kfree(pll); 337 kfree(pll);
338 hw = ERR_PTR(ret);
336 } 339 }
337 340
338 return clk; 341 return hw;
339} 342}
340 343
341 344
@@ -465,7 +468,7 @@ of_at91_clk_pll_setup(struct device_node *np,
465 const struct clk_pll_layout *layout) 468 const struct clk_pll_layout *layout)
466{ 469{
467 u32 id; 470 u32 id;
468 struct clk *clk; 471 struct clk_hw *hw;
469 struct regmap *regmap; 472 struct regmap *regmap;
470 const char *parent_name; 473 const char *parent_name;
471 const char *name = np->name; 474 const char *name = np->name;
@@ -486,12 +489,12 @@ of_at91_clk_pll_setup(struct device_node *np,
486 if (!characteristics) 489 if (!characteristics)
487 return; 490 return;
488 491
489 clk = at91_clk_register_pll(regmap, name, parent_name, id, layout, 492 hw = at91_clk_register_pll(regmap, name, parent_name, id, layout,
490 characteristics); 493 characteristics);
491 if (IS_ERR(clk)) 494 if (IS_ERR(hw))
492 goto out_free_characteristics; 495 goto out_free_characteristics;
493 496
494 of_clk_add_provider(np, of_clk_src_simple_get, clk); 497 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
495 return; 498 return;
496 499
497out_free_characteristics: 500out_free_characteristics:
diff --git a/drivers/clk/at91/clk-plldiv.c b/drivers/clk/at91/clk-plldiv.c
index 2bed26481027..b4afaf22f3fd 100644
--- a/drivers/clk/at91/clk-plldiv.c
+++ b/drivers/clk/at91/clk-plldiv.c
@@ -75,13 +75,14 @@ static const struct clk_ops plldiv_ops = {
75 .set_rate = clk_plldiv_set_rate, 75 .set_rate = clk_plldiv_set_rate,
76}; 76};
77 77
78static struct clk * __init 78static struct clk_hw * __init
79at91_clk_register_plldiv(struct regmap *regmap, const char *name, 79at91_clk_register_plldiv(struct regmap *regmap, const char *name,
80 const char *parent_name) 80 const char *parent_name)
81{ 81{
82 struct clk_plldiv *plldiv; 82 struct clk_plldiv *plldiv;
83 struct clk *clk = NULL; 83 struct clk_hw *hw;
84 struct clk_init_data init; 84 struct clk_init_data init;
85 int ret;
85 86
86 plldiv = kzalloc(sizeof(*plldiv), GFP_KERNEL); 87 plldiv = kzalloc(sizeof(*plldiv), GFP_KERNEL);
87 if (!plldiv) 88 if (!plldiv)
@@ -96,18 +97,20 @@ at91_clk_register_plldiv(struct regmap *regmap, const char *name,
96 plldiv->hw.init = &init; 97 plldiv->hw.init = &init;
97 plldiv->regmap = regmap; 98 plldiv->regmap = regmap;
98 99
99 clk = clk_register(NULL, &plldiv->hw); 100 hw = &plldiv->hw;
100 101 ret = clk_hw_register(NULL, &plldiv->hw);
101 if (IS_ERR(clk)) 102 if (ret) {
102 kfree(plldiv); 103 kfree(plldiv);
104 hw = ERR_PTR(ret);
105 }
103 106
104 return clk; 107 return hw;
105} 108}
106 109
107static void __init 110static void __init
108of_at91sam9x5_clk_plldiv_setup(struct device_node *np) 111of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
109{ 112{
110 struct clk *clk; 113 struct clk_hw *hw;
111 const char *parent_name; 114 const char *parent_name;
112 const char *name = np->name; 115 const char *name = np->name;
113 struct regmap *regmap; 116 struct regmap *regmap;
@@ -120,12 +123,11 @@ of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
120 if (IS_ERR(regmap)) 123 if (IS_ERR(regmap))
121 return; 124 return;
122 125
123 clk = at91_clk_register_plldiv(regmap, name, parent_name); 126 hw = at91_clk_register_plldiv(regmap, name, parent_name);
124 if (IS_ERR(clk)) 127 if (IS_ERR(hw))
125 return; 128 return;
126 129
127 of_clk_add_provider(np, of_clk_src_simple_get, clk); 130 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
128 return;
129} 131}
130CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv", 132CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv",
131 of_at91sam9x5_clk_plldiv_setup); 133 of_at91sam9x5_clk_plldiv_setup);
diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c
index 25d5906640c3..190122e64a3a 100644
--- a/drivers/clk/at91/clk-programmable.c
+++ b/drivers/clk/at91/clk-programmable.c
@@ -170,15 +170,16 @@ static const struct clk_ops programmable_ops = {
170 .set_rate = clk_programmable_set_rate, 170 .set_rate = clk_programmable_set_rate,
171}; 171};
172 172
173static struct clk * __init 173static struct clk_hw * __init
174at91_clk_register_programmable(struct regmap *regmap, 174at91_clk_register_programmable(struct regmap *regmap,
175 const char *name, const char **parent_names, 175 const char *name, const char **parent_names,
176 u8 num_parents, u8 id, 176 u8 num_parents, u8 id,
177 const struct clk_programmable_layout *layout) 177 const struct clk_programmable_layout *layout)
178{ 178{
179 struct clk_programmable *prog; 179 struct clk_programmable *prog;
180 struct clk *clk = NULL; 180 struct clk_hw *hw;
181 struct clk_init_data init; 181 struct clk_init_data init;
182 int ret;
182 183
183 if (id > PROG_ID_MAX) 184 if (id > PROG_ID_MAX)
184 return ERR_PTR(-EINVAL); 185 return ERR_PTR(-EINVAL);
@@ -198,11 +199,14 @@ at91_clk_register_programmable(struct regmap *regmap,
198 prog->hw.init = &init; 199 prog->hw.init = &init;
199 prog->regmap = regmap; 200 prog->regmap = regmap;
200 201
201 clk = clk_register(NULL, &prog->hw); 202 hw = &prog->hw;
202 if (IS_ERR(clk)) 203 ret = clk_hw_register(NULL, &prog->hw);
204 if (ret) {
203 kfree(prog); 205 kfree(prog);
206 hw = &prog->hw;
207 }
204 208
205 return clk; 209 return hw;
206} 210}
207 211
208static const struct clk_programmable_layout at91rm9200_programmable_layout = { 212static const struct clk_programmable_layout at91rm9200_programmable_layout = {
@@ -229,7 +233,7 @@ of_at91_clk_prog_setup(struct device_node *np,
229{ 233{
230 int num; 234 int num;
231 u32 id; 235 u32 id;
232 struct clk *clk; 236 struct clk_hw *hw;
233 unsigned int num_parents; 237 unsigned int num_parents;
234 const char *parent_names[PROG_SOURCE_MAX]; 238 const char *parent_names[PROG_SOURCE_MAX];
235 const char *name; 239 const char *name;
@@ -257,13 +261,13 @@ of_at91_clk_prog_setup(struct device_node *np,
257 if (of_property_read_string(np, "clock-output-names", &name)) 261 if (of_property_read_string(np, "clock-output-names", &name))
258 name = progclknp->name; 262 name = progclknp->name;
259 263
260 clk = at91_clk_register_programmable(regmap, name, 264 hw = at91_clk_register_programmable(regmap, name,
261 parent_names, num_parents, 265 parent_names, num_parents,
262 id, layout); 266 id, layout);
263 if (IS_ERR(clk)) 267 if (IS_ERR(hw))
264 continue; 268 continue;
265 269
266 of_clk_add_provider(progclknp, of_clk_src_simple_get, clk); 270 of_clk_add_hw_provider(progclknp, of_clk_hw_simple_get, hw);
267 } 271 }
268} 272}
269 273
diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c
index 61090b1146cf..560a8b9abf93 100644
--- a/drivers/clk/at91/clk-slow.c
+++ b/drivers/clk/at91/clk-slow.c
@@ -13,42 +13,11 @@
13#include <linux/clk-provider.h> 13#include <linux/clk-provider.h>
14#include <linux/clkdev.h> 14#include <linux/clkdev.h>
15#include <linux/clk/at91_pmc.h> 15#include <linux/clk/at91_pmc.h>
16#include <linux/delay.h>
17#include <linux/of.h> 16#include <linux/of.h>
18#include <linux/mfd/syscon.h> 17#include <linux/mfd/syscon.h>
19#include <linux/regmap.h> 18#include <linux/regmap.h>
20 19
21#include "pmc.h" 20#include "pmc.h"
22#include "sckc.h"
23
24#define SLOW_CLOCK_FREQ 32768
25#define SLOWCK_SW_CYCLES 5
26#define SLOWCK_SW_TIME_USEC ((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \
27 SLOW_CLOCK_FREQ)
28
29#define AT91_SCKC_CR 0x00
30#define AT91_SCKC_RCEN (1 << 0)
31#define AT91_SCKC_OSC32EN (1 << 1)
32#define AT91_SCKC_OSC32BYP (1 << 2)
33#define AT91_SCKC_OSCSEL (1 << 3)
34
35struct clk_slow_osc {
36 struct clk_hw hw;
37 void __iomem *sckcr;
38 unsigned long startup_usec;
39};
40
41#define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw)
42
43struct clk_slow_rc_osc {
44 struct clk_hw hw;
45 void __iomem *sckcr;
46 unsigned long frequency;
47 unsigned long accuracy;
48 unsigned long startup_usec;
49};
50
51#define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw)
52 21
53struct clk_sam9260_slow { 22struct clk_sam9260_slow {
54 struct clk_hw hw; 23 struct clk_hw hw;
@@ -57,328 +26,6 @@ struct clk_sam9260_slow {
57 26
58#define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw) 27#define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw)
59 28
60struct clk_sam9x5_slow {
61 struct clk_hw hw;
62 void __iomem *sckcr;
63 u8 parent;
64};
65
66#define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)
67
68static int clk_slow_osc_prepare(struct clk_hw *hw)
69{
70 struct clk_slow_osc *osc = to_clk_slow_osc(hw);
71 void __iomem *sckcr = osc->sckcr;
72 u32 tmp = readl(sckcr);
73
74 if (tmp & AT91_SCKC_OSC32BYP)
75 return 0;
76
77 writel(tmp | AT91_SCKC_OSC32EN, sckcr);
78
79 usleep_range(osc->startup_usec, osc->startup_usec + 1);
80
81 return 0;
82}
83
84static void clk_slow_osc_unprepare(struct clk_hw *hw)
85{
86 struct clk_slow_osc *osc = to_clk_slow_osc(hw);
87 void __iomem *sckcr = osc->sckcr;
88 u32 tmp = readl(sckcr);
89
90 if (tmp & AT91_SCKC_OSC32BYP)
91 return;
92
93 writel(tmp & ~AT91_SCKC_OSC32EN, sckcr);
94}
95
96static int clk_slow_osc_is_prepared(struct clk_hw *hw)
97{
98 struct clk_slow_osc *osc = to_clk_slow_osc(hw);
99 void __iomem *sckcr = osc->sckcr;
100 u32 tmp = readl(sckcr);
101
102 if (tmp & AT91_SCKC_OSC32BYP)
103 return 1;
104
105 return !!(tmp & AT91_SCKC_OSC32EN);
106}
107
108static const struct clk_ops slow_osc_ops = {
109 .prepare = clk_slow_osc_prepare,
110 .unprepare = clk_slow_osc_unprepare,
111 .is_prepared = clk_slow_osc_is_prepared,
112};
113
114static struct clk * __init
115at91_clk_register_slow_osc(void __iomem *sckcr,
116 const char *name,
117 const char *parent_name,
118 unsigned long startup,
119 bool bypass)
120{
121 struct clk_slow_osc *osc;
122 struct clk *clk = NULL;
123 struct clk_init_data init;
124
125 if (!sckcr || !name || !parent_name)
126 return ERR_PTR(-EINVAL);
127
128 osc = kzalloc(sizeof(*osc), GFP_KERNEL);
129 if (!osc)
130 return ERR_PTR(-ENOMEM);
131
132 init.name = name;
133 init.ops = &slow_osc_ops;
134 init.parent_names = &parent_name;
135 init.num_parents = 1;
136 init.flags = CLK_IGNORE_UNUSED;
137
138 osc->hw.init = &init;
139 osc->sckcr = sckcr;
140 osc->startup_usec = startup;
141
142 if (bypass)
143 writel((readl(sckcr) & ~AT91_SCKC_OSC32EN) | AT91_SCKC_OSC32BYP,
144 sckcr);
145
146 clk = clk_register(NULL, &osc->hw);
147 if (IS_ERR(clk))
148 kfree(osc);
149
150 return clk;
151}
152
153void __init of_at91sam9x5_clk_slow_osc_setup(struct device_node *np,
154 void __iomem *sckcr)
155{
156 struct clk *clk;
157 const char *parent_name;
158 const char *name = np->name;
159 u32 startup;
160 bool bypass;
161
162 parent_name = of_clk_get_parent_name(np, 0);
163 of_property_read_string(np, "clock-output-names", &name);
164 of_property_read_u32(np, "atmel,startup-time-usec", &startup);
165 bypass = of_property_read_bool(np, "atmel,osc-bypass");
166
167 clk = at91_clk_register_slow_osc(sckcr, name, parent_name, startup,
168 bypass);
169 if (IS_ERR(clk))
170 return;
171
172 of_clk_add_provider(np, of_clk_src_simple_get, clk);
173}
174
175static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw,
176 unsigned long parent_rate)
177{
178 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
179
180 return osc->frequency;
181}
182
183static unsigned long clk_slow_rc_osc_recalc_accuracy(struct clk_hw *hw,
184 unsigned long parent_acc)
185{
186 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
187
188 return osc->accuracy;
189}
190
191static int clk_slow_rc_osc_prepare(struct clk_hw *hw)
192{
193 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
194 void __iomem *sckcr = osc->sckcr;
195
196 writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr);
197
198 usleep_range(osc->startup_usec, osc->startup_usec + 1);
199
200 return 0;
201}
202
203static void clk_slow_rc_osc_unprepare(struct clk_hw *hw)
204{
205 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
206 void __iomem *sckcr = osc->sckcr;
207
208 writel(readl(sckcr) & ~AT91_SCKC_RCEN, sckcr);
209}
210
211static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw)
212{
213 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
214
215 return !!(readl(osc->sckcr) & AT91_SCKC_RCEN);
216}
217
218static const struct clk_ops slow_rc_osc_ops = {
219 .prepare = clk_slow_rc_osc_prepare,
220 .unprepare = clk_slow_rc_osc_unprepare,
221 .is_prepared = clk_slow_rc_osc_is_prepared,
222 .recalc_rate = clk_slow_rc_osc_recalc_rate,
223 .recalc_accuracy = clk_slow_rc_osc_recalc_accuracy,
224};
225
226static struct clk * __init
227at91_clk_register_slow_rc_osc(void __iomem *sckcr,
228 const char *name,
229 unsigned long frequency,
230 unsigned long accuracy,
231 unsigned long startup)
232{
233 struct clk_slow_rc_osc *osc;
234 struct clk *clk = NULL;
235 struct clk_init_data init;
236
237 if (!sckcr || !name)
238 return ERR_PTR(-EINVAL);
239
240 osc = kzalloc(sizeof(*osc), GFP_KERNEL);
241 if (!osc)
242 return ERR_PTR(-ENOMEM);
243
244 init.name = name;
245 init.ops = &slow_rc_osc_ops;
246 init.parent_names = NULL;
247 init.num_parents = 0;
248 init.flags = CLK_IGNORE_UNUSED;
249
250 osc->hw.init = &init;
251 osc->sckcr = sckcr;
252 osc->frequency = frequency;
253 osc->accuracy = accuracy;
254 osc->startup_usec = startup;
255
256 clk = clk_register(NULL, &osc->hw);
257 if (IS_ERR(clk))
258 kfree(osc);
259
260 return clk;
261}
262
263void __init of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np,
264 void __iomem *sckcr)
265{
266 struct clk *clk;
267 u32 frequency = 0;
268 u32 accuracy = 0;
269 u32 startup = 0;
270 const char *name = np->name;
271
272 of_property_read_string(np, "clock-output-names", &name);
273 of_property_read_u32(np, "clock-frequency", &frequency);
274 of_property_read_u32(np, "clock-accuracy", &accuracy);
275 of_property_read_u32(np, "atmel,startup-time-usec", &startup);
276
277 clk = at91_clk_register_slow_rc_osc(sckcr, name, frequency, accuracy,
278 startup);
279 if (IS_ERR(clk))
280 return;
281
282 of_clk_add_provider(np, of_clk_src_simple_get, clk);
283}
284
285static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
286{
287 struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
288 void __iomem *sckcr = slowck->sckcr;
289 u32 tmp;
290
291 if (index > 1)
292 return -EINVAL;
293
294 tmp = readl(sckcr);
295
296 if ((!index && !(tmp & AT91_SCKC_OSCSEL)) ||
297 (index && (tmp & AT91_SCKC_OSCSEL)))
298 return 0;
299
300 if (index)
301 tmp |= AT91_SCKC_OSCSEL;
302 else
303 tmp &= ~AT91_SCKC_OSCSEL;
304
305 writel(tmp, sckcr);
306
307 usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1);
308
309 return 0;
310}
311
312static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw)
313{
314 struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
315
316 return !!(readl(slowck->sckcr) & AT91_SCKC_OSCSEL);
317}
318
319static const struct clk_ops sam9x5_slow_ops = {
320 .set_parent = clk_sam9x5_slow_set_parent,
321 .get_parent = clk_sam9x5_slow_get_parent,
322};
323
324static struct clk * __init
325at91_clk_register_sam9x5_slow(void __iomem *sckcr,
326 const char *name,
327 const char **parent_names,
328 int num_parents)
329{
330 struct clk_sam9x5_slow *slowck;
331 struct clk *clk = NULL;
332 struct clk_init_data init;
333
334 if (!sckcr || !name || !parent_names || !num_parents)
335 return ERR_PTR(-EINVAL);
336
337 slowck = kzalloc(sizeof(*slowck), GFP_KERNEL);
338 if (!slowck)
339 return ERR_PTR(-ENOMEM);
340
341 init.name = name;
342 init.ops = &sam9x5_slow_ops;
343 init.parent_names = parent_names;
344 init.num_parents = num_parents;
345 init.flags = 0;
346
347 slowck->hw.init = &init;
348 slowck->sckcr = sckcr;
349 slowck->parent = !!(readl(sckcr) & AT91_SCKC_OSCSEL);
350
351 clk = clk_register(NULL, &slowck->hw);
352 if (IS_ERR(clk))
353 kfree(slowck);
354
355 return clk;
356}
357
358void __init of_at91sam9x5_clk_slow_setup(struct device_node *np,
359 void __iomem *sckcr)
360{
361 struct clk *clk;
362 const char *parent_names[2];
363 unsigned int num_parents;
364 const char *name = np->name;
365
366 num_parents = of_clk_get_parent_count(np);
367 if (num_parents == 0 || num_parents > 2)
368 return;
369
370 of_clk_parent_fill(np, parent_names, num_parents);
371
372 of_property_read_string(np, "clock-output-names", &name);
373
374 clk = at91_clk_register_sam9x5_slow(sckcr, name, parent_names,
375 num_parents);
376 if (IS_ERR(clk))
377 return;
378
379 of_clk_add_provider(np, of_clk_src_simple_get, clk);
380}
381
382static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw) 29static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw)
383{ 30{
384 struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(hw); 31 struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(hw);
@@ -393,15 +40,16 @@ static const struct clk_ops sam9260_slow_ops = {
393 .get_parent = clk_sam9260_slow_get_parent, 40 .get_parent = clk_sam9260_slow_get_parent,
394}; 41};
395 42
396static struct clk * __init 43static struct clk_hw * __init
397at91_clk_register_sam9260_slow(struct regmap *regmap, 44at91_clk_register_sam9260_slow(struct regmap *regmap,
398 const char *name, 45 const char *name,
399 const char **parent_names, 46 const char **parent_names,
400 int num_parents) 47 int num_parents)
401{ 48{
402 struct clk_sam9260_slow *slowck; 49 struct clk_sam9260_slow *slowck;
403 struct clk *clk = NULL; 50 struct clk_hw *hw;
404 struct clk_init_data init; 51 struct clk_init_data init;
52 int ret;
405 53
406 if (!name) 54 if (!name)
407 return ERR_PTR(-EINVAL); 55 return ERR_PTR(-EINVAL);
@@ -422,16 +70,19 @@ at91_clk_register_sam9260_slow(struct regmap *regmap,
422 slowck->hw.init = &init; 70 slowck->hw.init = &init;
423 slowck->regmap = regmap; 71 slowck->regmap = regmap;
424 72
425 clk = clk_register(NULL, &slowck->hw); 73 hw = &slowck->hw;
426 if (IS_ERR(clk)) 74 ret = clk_hw_register(NULL, &slowck->hw);
75 if (ret) {
427 kfree(slowck); 76 kfree(slowck);
77 hw = ERR_PTR(ret);
78 }
428 79
429 return clk; 80 return hw;
430} 81}
431 82
432static void __init of_at91sam9260_clk_slow_setup(struct device_node *np) 83static void __init of_at91sam9260_clk_slow_setup(struct device_node *np)
433{ 84{
434 struct clk *clk; 85 struct clk_hw *hw;
435 const char *parent_names[2]; 86 const char *parent_names[2];
436 unsigned int num_parents; 87 unsigned int num_parents;
437 const char *name = np->name; 88 const char *name = np->name;
@@ -448,12 +99,12 @@ static void __init of_at91sam9260_clk_slow_setup(struct device_node *np)
448 99
449 of_property_read_string(np, "clock-output-names", &name); 100 of_property_read_string(np, "clock-output-names", &name);
450 101
451 clk = at91_clk_register_sam9260_slow(regmap, name, parent_names, 102 hw = at91_clk_register_sam9260_slow(regmap, name, parent_names,
452 num_parents); 103 num_parents);
453 if (IS_ERR(clk)) 104 if (IS_ERR(hw))
454 return; 105 return;
455 106
456 of_clk_add_provider(np, of_clk_src_simple_get, clk); 107 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
457} 108}
458 109
459CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow", 110CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow",
diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c
index 3c04b069d5b8..965c662b90a5 100644
--- a/drivers/clk/at91/clk-smd.c
+++ b/drivers/clk/at91/clk-smd.c
@@ -111,13 +111,14 @@ static const struct clk_ops at91sam9x5_smd_ops = {
111 .set_rate = at91sam9x5_clk_smd_set_rate, 111 .set_rate = at91sam9x5_clk_smd_set_rate,
112}; 112};
113 113
114static struct clk * __init 114static struct clk_hw * __init
115at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name, 115at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
116 const char **parent_names, u8 num_parents) 116 const char **parent_names, u8 num_parents)
117{ 117{
118 struct at91sam9x5_clk_smd *smd; 118 struct at91sam9x5_clk_smd *smd;
119 struct clk *clk = NULL; 119 struct clk_hw *hw;
120 struct clk_init_data init; 120 struct clk_init_data init;
121 int ret;
121 122
122 smd = kzalloc(sizeof(*smd), GFP_KERNEL); 123 smd = kzalloc(sizeof(*smd), GFP_KERNEL);
123 if (!smd) 124 if (!smd)
@@ -132,16 +133,19 @@ at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
132 smd->hw.init = &init; 133 smd->hw.init = &init;
133 smd->regmap = regmap; 134 smd->regmap = regmap;
134 135
135 clk = clk_register(NULL, &smd->hw); 136 hw = &smd->hw;
136 if (IS_ERR(clk)) 137 ret = clk_hw_register(NULL, &smd->hw);
138 if (ret) {
137 kfree(smd); 139 kfree(smd);
140 hw = ERR_PTR(ret);
141 }
138 142
139 return clk; 143 return hw;
140} 144}
141 145
142static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np) 146static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
143{ 147{
144 struct clk *clk; 148 struct clk_hw *hw;
145 unsigned int num_parents; 149 unsigned int num_parents;
146 const char *parent_names[SMD_SOURCE_MAX]; 150 const char *parent_names[SMD_SOURCE_MAX];
147 const char *name = np->name; 151 const char *name = np->name;
@@ -159,12 +163,12 @@ static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
159 if (IS_ERR(regmap)) 163 if (IS_ERR(regmap))
160 return; 164 return;
161 165
162 clk = at91sam9x5_clk_register_smd(regmap, name, parent_names, 166 hw = at91sam9x5_clk_register_smd(regmap, name, parent_names,
163 num_parents); 167 num_parents);
164 if (IS_ERR(clk)) 168 if (IS_ERR(hw))
165 return; 169 return;
166 170
167 of_clk_add_provider(np, of_clk_src_simple_get, clk); 171 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
168} 172}
169CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd", 173CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd",
170 of_at91sam9x5_clk_smd_setup); 174 of_at91sam9x5_clk_smd_setup);
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c
index 8f35d8172909..86a36809765d 100644
--- a/drivers/clk/at91/clk-system.c
+++ b/drivers/clk/at91/clk-system.c
@@ -88,13 +88,14 @@ static const struct clk_ops system_ops = {
88 .is_prepared = clk_system_is_prepared, 88 .is_prepared = clk_system_is_prepared,
89}; 89};
90 90
91static struct clk * __init 91static struct clk_hw * __init
92at91_clk_register_system(struct regmap *regmap, const char *name, 92at91_clk_register_system(struct regmap *regmap, const char *name,
93 const char *parent_name, u8 id) 93 const char *parent_name, u8 id)
94{ 94{
95 struct clk_system *sys; 95 struct clk_system *sys;
96 struct clk *clk = NULL; 96 struct clk_hw *hw;
97 struct clk_init_data init; 97 struct clk_init_data init;
98 int ret;
98 99
99 if (!parent_name || id > SYSTEM_MAX_ID) 100 if (!parent_name || id > SYSTEM_MAX_ID)
100 return ERR_PTR(-EINVAL); 101 return ERR_PTR(-EINVAL);
@@ -113,18 +114,21 @@ at91_clk_register_system(struct regmap *regmap, const char *name,
113 sys->hw.init = &init; 114 sys->hw.init = &init;
114 sys->regmap = regmap; 115 sys->regmap = regmap;
115 116
116 clk = clk_register(NULL, &sys->hw); 117 hw = &sys->hw;
117 if (IS_ERR(clk)) 118 ret = clk_hw_register(NULL, &sys->hw);
119 if (ret) {
118 kfree(sys); 120 kfree(sys);
121 hw = ERR_PTR(ret);
122 }
119 123
120 return clk; 124 return hw;
121} 125}
122 126
123static void __init of_at91rm9200_clk_sys_setup(struct device_node *np) 127static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
124{ 128{
125 int num; 129 int num;
126 u32 id; 130 u32 id;
127 struct clk *clk; 131 struct clk_hw *hw;
128 const char *name; 132 const char *name;
129 struct device_node *sysclknp; 133 struct device_node *sysclknp;
130 const char *parent_name; 134 const char *parent_name;
@@ -147,11 +151,11 @@ static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
147 151
148 parent_name = of_clk_get_parent_name(sysclknp, 0); 152 parent_name = of_clk_get_parent_name(sysclknp, 0);
149 153
150 clk = at91_clk_register_system(regmap, name, parent_name, id); 154 hw = at91_clk_register_system(regmap, name, parent_name, id);
151 if (IS_ERR(clk)) 155 if (IS_ERR(hw))
152 continue; 156 continue;
153 157
154 of_clk_add_provider(sysclknp, of_clk_src_simple_get, clk); 158 of_clk_add_hw_provider(sysclknp, of_clk_hw_simple_get, hw);
155 } 159 }
156} 160}
157CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system", 161CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system",
diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c
index d80bdb0a8b02..791770a563fc 100644
--- a/drivers/clk/at91/clk-usb.c
+++ b/drivers/clk/at91/clk-usb.c
@@ -192,13 +192,14 @@ static const struct clk_ops at91sam9n12_usb_ops = {
192 .set_rate = at91sam9x5_clk_usb_set_rate, 192 .set_rate = at91sam9x5_clk_usb_set_rate,
193}; 193};
194 194
195static struct clk * __init 195static struct clk_hw * __init
196at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, 196at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
197 const char **parent_names, u8 num_parents) 197 const char **parent_names, u8 num_parents)
198{ 198{
199 struct at91sam9x5_clk_usb *usb; 199 struct at91sam9x5_clk_usb *usb;
200 struct clk *clk = NULL; 200 struct clk_hw *hw;
201 struct clk_init_data init; 201 struct clk_init_data init;
202 int ret;
202 203
203 usb = kzalloc(sizeof(*usb), GFP_KERNEL); 204 usb = kzalloc(sizeof(*usb), GFP_KERNEL);
204 if (!usb) 205 if (!usb)
@@ -214,20 +215,24 @@ at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
214 usb->hw.init = &init; 215 usb->hw.init = &init;
215 usb->regmap = regmap; 216 usb->regmap = regmap;
216 217
217 clk = clk_register(NULL, &usb->hw); 218 hw = &usb->hw;
218 if (IS_ERR(clk)) 219 ret = clk_hw_register(NULL, &usb->hw);
220 if (ret) {
219 kfree(usb); 221 kfree(usb);
222 hw = ERR_PTR(ret);
223 }
220 224
221 return clk; 225 return hw;
222} 226}
223 227
224static struct clk * __init 228static struct clk_hw * __init
225at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name, 229at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
226 const char *parent_name) 230 const char *parent_name)
227{ 231{
228 struct at91sam9x5_clk_usb *usb; 232 struct at91sam9x5_clk_usb *usb;
229 struct clk *clk = NULL; 233 struct clk_hw *hw;
230 struct clk_init_data init; 234 struct clk_init_data init;
235 int ret;
231 236
232 usb = kzalloc(sizeof(*usb), GFP_KERNEL); 237 usb = kzalloc(sizeof(*usb), GFP_KERNEL);
233 if (!usb) 238 if (!usb)
@@ -242,11 +247,14 @@ at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
242 usb->hw.init = &init; 247 usb->hw.init = &init;
243 usb->regmap = regmap; 248 usb->regmap = regmap;
244 249
245 clk = clk_register(NULL, &usb->hw); 250 hw = &usb->hw;
246 if (IS_ERR(clk)) 251 ret = clk_hw_register(NULL, &usb->hw);
252 if (ret) {
247 kfree(usb); 253 kfree(usb);
254 hw = ERR_PTR(ret);
255 }
248 256
249 return clk; 257 return hw;
250} 258}
251 259
252static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw *hw, 260static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw *hw,
@@ -334,13 +342,14 @@ static const struct clk_ops at91rm9200_usb_ops = {
334 .set_rate = at91rm9200_clk_usb_set_rate, 342 .set_rate = at91rm9200_clk_usb_set_rate,
335}; 343};
336 344
337static struct clk * __init 345static struct clk_hw * __init
338at91rm9200_clk_register_usb(struct regmap *regmap, const char *name, 346at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
339 const char *parent_name, const u32 *divisors) 347 const char *parent_name, const u32 *divisors)
340{ 348{
341 struct at91rm9200_clk_usb *usb; 349 struct at91rm9200_clk_usb *usb;
342 struct clk *clk = NULL; 350 struct clk_hw *hw;
343 struct clk_init_data init; 351 struct clk_init_data init;
352 int ret;
344 353
345 usb = kzalloc(sizeof(*usb), GFP_KERNEL); 354 usb = kzalloc(sizeof(*usb), GFP_KERNEL);
346 if (!usb) 355 if (!usb)
@@ -356,16 +365,19 @@ at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
356 usb->regmap = regmap; 365 usb->regmap = regmap;
357 memcpy(usb->divisors, divisors, sizeof(usb->divisors)); 366 memcpy(usb->divisors, divisors, sizeof(usb->divisors));
358 367
359 clk = clk_register(NULL, &usb->hw); 368 hw = &usb->hw;
360 if (IS_ERR(clk)) 369 ret = clk_hw_register(NULL, &usb->hw);
370 if (ret) {
361 kfree(usb); 371 kfree(usb);
372 hw = ERR_PTR(ret);
373 }
362 374
363 return clk; 375 return hw;
364} 376}
365 377
366static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np) 378static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
367{ 379{
368 struct clk *clk; 380 struct clk_hw *hw;
369 unsigned int num_parents; 381 unsigned int num_parents;
370 const char *parent_names[USB_SOURCE_MAX]; 382 const char *parent_names[USB_SOURCE_MAX];
371 const char *name = np->name; 383 const char *name = np->name;
@@ -383,19 +395,19 @@ static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
383 if (IS_ERR(regmap)) 395 if (IS_ERR(regmap))
384 return; 396 return;
385 397
386 clk = at91sam9x5_clk_register_usb(regmap, name, parent_names, 398 hw = at91sam9x5_clk_register_usb(regmap, name, parent_names,
387 num_parents); 399 num_parents);
388 if (IS_ERR(clk)) 400 if (IS_ERR(hw))
389 return; 401 return;
390 402
391 of_clk_add_provider(np, of_clk_src_simple_get, clk); 403 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
392} 404}
393CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb", 405CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb",
394 of_at91sam9x5_clk_usb_setup); 406 of_at91sam9x5_clk_usb_setup);
395 407
396static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np) 408static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np)
397{ 409{
398 struct clk *clk; 410 struct clk_hw *hw;
399 const char *parent_name; 411 const char *parent_name;
400 const char *name = np->name; 412 const char *name = np->name;
401 struct regmap *regmap; 413 struct regmap *regmap;
@@ -410,18 +422,18 @@ static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np)
410 if (IS_ERR(regmap)) 422 if (IS_ERR(regmap))
411 return; 423 return;
412 424
413 clk = at91sam9n12_clk_register_usb(regmap, name, parent_name); 425 hw = at91sam9n12_clk_register_usb(regmap, name, parent_name);
414 if (IS_ERR(clk)) 426 if (IS_ERR(hw))
415 return; 427 return;
416 428
417 of_clk_add_provider(np, of_clk_src_simple_get, clk); 429 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
418} 430}
419CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb", 431CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb",
420 of_at91sam9n12_clk_usb_setup); 432 of_at91sam9n12_clk_usb_setup);
421 433
422static void __init of_at91rm9200_clk_usb_setup(struct device_node *np) 434static void __init of_at91rm9200_clk_usb_setup(struct device_node *np)
423{ 435{
424 struct clk *clk; 436 struct clk_hw *hw;
425 const char *parent_name; 437 const char *parent_name;
426 const char *name = np->name; 438 const char *name = np->name;
427 u32 divisors[4] = {0, 0, 0, 0}; 439 u32 divisors[4] = {0, 0, 0, 0};
@@ -440,12 +452,11 @@ static void __init of_at91rm9200_clk_usb_setup(struct device_node *np)
440 regmap = syscon_node_to_regmap(of_get_parent(np)); 452 regmap = syscon_node_to_regmap(of_get_parent(np));
441 if (IS_ERR(regmap)) 453 if (IS_ERR(regmap))
442 return; 454 return;
443 455 hw = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
444 clk = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors); 456 if (IS_ERR(hw))
445 if (IS_ERR(clk))
446 return; 457 return;
447 458
448 of_clk_add_provider(np, of_clk_src_simple_get, clk); 459 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
449} 460}
450CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb", 461CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb",
451 of_at91rm9200_clk_usb_setup); 462 of_at91rm9200_clk_usb_setup);
diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c
index 61fcf399e58c..aadabd9d1e2b 100644
--- a/drivers/clk/at91/clk-utmi.c
+++ b/drivers/clk/at91/clk-utmi.c
@@ -77,13 +77,14 @@ static const struct clk_ops utmi_ops = {
77 .recalc_rate = clk_utmi_recalc_rate, 77 .recalc_rate = clk_utmi_recalc_rate,
78}; 78};
79 79
80static struct clk * __init 80static struct clk_hw * __init
81at91_clk_register_utmi(struct regmap *regmap, 81at91_clk_register_utmi(struct regmap *regmap,
82 const char *name, const char *parent_name) 82 const char *name, const char *parent_name)
83{ 83{
84 struct clk_utmi *utmi; 84 struct clk_utmi *utmi;
85 struct clk *clk = NULL; 85 struct clk_hw *hw;
86 struct clk_init_data init; 86 struct clk_init_data init;
87 int ret;
87 88
88 utmi = kzalloc(sizeof(*utmi), GFP_KERNEL); 89 utmi = kzalloc(sizeof(*utmi), GFP_KERNEL);
89 if (!utmi) 90 if (!utmi)
@@ -98,16 +99,19 @@ at91_clk_register_utmi(struct regmap *regmap,
98 utmi->hw.init = &init; 99 utmi->hw.init = &init;
99 utmi->regmap = regmap; 100 utmi->regmap = regmap;
100 101
101 clk = clk_register(NULL, &utmi->hw); 102 hw = &utmi->hw;
102 if (IS_ERR(clk)) 103 ret = clk_hw_register(NULL, &utmi->hw);
104 if (ret) {
103 kfree(utmi); 105 kfree(utmi);
106 hw = ERR_PTR(ret);
107 }
104 108
105 return clk; 109 return hw;
106} 110}
107 111
108static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np) 112static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
109{ 113{
110 struct clk *clk; 114 struct clk_hw *hw;
111 const char *parent_name; 115 const char *parent_name;
112 const char *name = np->name; 116 const char *name = np->name;
113 struct regmap *regmap; 117 struct regmap *regmap;
@@ -120,11 +124,11 @@ static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
120 if (IS_ERR(regmap)) 124 if (IS_ERR(regmap))
121 return; 125 return;
122 126
123 clk = at91_clk_register_utmi(regmap, name, parent_name); 127 hw = at91_clk_register_utmi(regmap, name, parent_name);
124 if (IS_ERR(clk)) 128 if (IS_ERR(hw))
125 return; 129 return;
126 130
127 of_clk_add_provider(np, of_clk_src_simple_get, clk); 131 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
128 return; 132 return;
129} 133}
130CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi", 134CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi",
diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c
index 1184d76a7ab7..ab6ecefc49ad 100644
--- a/drivers/clk/at91/sckc.c
+++ b/drivers/clk/at91/sckc.c
@@ -12,11 +12,382 @@
12 12
13#include <linux/clk-provider.h> 13#include <linux/clk-provider.h>
14#include <linux/clkdev.h> 14#include <linux/clkdev.h>
15#include <linux/delay.h>
15#include <linux/of.h> 16#include <linux/of.h>
16#include <linux/of_address.h> 17#include <linux/of_address.h>
17#include <linux/io.h> 18#include <linux/io.h>
18 19
19#include "sckc.h" 20#define SLOW_CLOCK_FREQ 32768
21#define SLOWCK_SW_CYCLES 5
22#define SLOWCK_SW_TIME_USEC ((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \
23 SLOW_CLOCK_FREQ)
24
25#define AT91_SCKC_CR 0x00
26#define AT91_SCKC_RCEN (1 << 0)
27#define AT91_SCKC_OSC32EN (1 << 1)
28#define AT91_SCKC_OSC32BYP (1 << 2)
29#define AT91_SCKC_OSCSEL (1 << 3)
30
31struct clk_slow_osc {
32 struct clk_hw hw;
33 void __iomem *sckcr;
34 unsigned long startup_usec;
35};
36
37#define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw)
38
39struct clk_sama5d4_slow_osc {
40 struct clk_hw hw;
41 void __iomem *sckcr;
42 unsigned long startup_usec;
43 bool prepared;
44};
45
46#define to_clk_sama5d4_slow_osc(hw) container_of(hw, struct clk_sama5d4_slow_osc, hw)
47
48struct clk_slow_rc_osc {
49 struct clk_hw hw;
50 void __iomem *sckcr;
51 unsigned long frequency;
52 unsigned long accuracy;
53 unsigned long startup_usec;
54};
55
56#define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw)
57
58struct clk_sam9x5_slow {
59 struct clk_hw hw;
60 void __iomem *sckcr;
61 u8 parent;
62};
63
64#define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)
65
66static int clk_slow_osc_prepare(struct clk_hw *hw)
67{
68 struct clk_slow_osc *osc = to_clk_slow_osc(hw);
69 void __iomem *sckcr = osc->sckcr;
70 u32 tmp = readl(sckcr);
71
72 if (tmp & (AT91_SCKC_OSC32BYP | AT91_SCKC_OSC32EN))
73 return 0;
74
75 writel(tmp | AT91_SCKC_OSC32EN, sckcr);
76
77 usleep_range(osc->startup_usec, osc->startup_usec + 1);
78
79 return 0;
80}
81
82static void clk_slow_osc_unprepare(struct clk_hw *hw)
83{
84 struct clk_slow_osc *osc = to_clk_slow_osc(hw);
85 void __iomem *sckcr = osc->sckcr;
86 u32 tmp = readl(sckcr);
87
88 if (tmp & AT91_SCKC_OSC32BYP)
89 return;
90
91 writel(tmp & ~AT91_SCKC_OSC32EN, sckcr);
92}
93
94static int clk_slow_osc_is_prepared(struct clk_hw *hw)
95{
96 struct clk_slow_osc *osc = to_clk_slow_osc(hw);
97 void __iomem *sckcr = osc->sckcr;
98 u32 tmp = readl(sckcr);
99
100 if (tmp & AT91_SCKC_OSC32BYP)
101 return 1;
102
103 return !!(tmp & AT91_SCKC_OSC32EN);
104}
105
106static const struct clk_ops slow_osc_ops = {
107 .prepare = clk_slow_osc_prepare,
108 .unprepare = clk_slow_osc_unprepare,
109 .is_prepared = clk_slow_osc_is_prepared,
110};
111
112static struct clk_hw * __init
113at91_clk_register_slow_osc(void __iomem *sckcr,
114 const char *name,
115 const char *parent_name,
116 unsigned long startup,
117 bool bypass)
118{
119 struct clk_slow_osc *osc;
120 struct clk_hw *hw;
121 struct clk_init_data init;
122 int ret;
123
124 if (!sckcr || !name || !parent_name)
125 return ERR_PTR(-EINVAL);
126
127 osc = kzalloc(sizeof(*osc), GFP_KERNEL);
128 if (!osc)
129 return ERR_PTR(-ENOMEM);
130
131 init.name = name;
132 init.ops = &slow_osc_ops;
133 init.parent_names = &parent_name;
134 init.num_parents = 1;
135 init.flags = CLK_IGNORE_UNUSED;
136
137 osc->hw.init = &init;
138 osc->sckcr = sckcr;
139 osc->startup_usec = startup;
140
141 if (bypass)
142 writel((readl(sckcr) & ~AT91_SCKC_OSC32EN) | AT91_SCKC_OSC32BYP,
143 sckcr);
144
145 hw = &osc->hw;
146 ret = clk_hw_register(NULL, &osc->hw);
147 if (ret) {
148 kfree(osc);
149 hw = ERR_PTR(ret);
150 }
151
152 return hw;
153}
154
155static void __init
156of_at91sam9x5_clk_slow_osc_setup(struct device_node *np, void __iomem *sckcr)
157{
158 struct clk_hw *hw;
159 const char *parent_name;
160 const char *name = np->name;
161 u32 startup;
162 bool bypass;
163
164 parent_name = of_clk_get_parent_name(np, 0);
165 of_property_read_string(np, "clock-output-names", &name);
166 of_property_read_u32(np, "atmel,startup-time-usec", &startup);
167 bypass = of_property_read_bool(np, "atmel,osc-bypass");
168
169 hw = at91_clk_register_slow_osc(sckcr, name, parent_name, startup,
170 bypass);
171 if (IS_ERR(hw))
172 return;
173
174 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
175}
176
177static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw,
178 unsigned long parent_rate)
179{
180 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
181
182 return osc->frequency;
183}
184
185static unsigned long clk_slow_rc_osc_recalc_accuracy(struct clk_hw *hw,
186 unsigned long parent_acc)
187{
188 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
189
190 return osc->accuracy;
191}
192
193static int clk_slow_rc_osc_prepare(struct clk_hw *hw)
194{
195 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
196 void __iomem *sckcr = osc->sckcr;
197
198 writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr);
199
200 usleep_range(osc->startup_usec, osc->startup_usec + 1);
201
202 return 0;
203}
204
205static void clk_slow_rc_osc_unprepare(struct clk_hw *hw)
206{
207 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
208 void __iomem *sckcr = osc->sckcr;
209
210 writel(readl(sckcr) & ~AT91_SCKC_RCEN, sckcr);
211}
212
213static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw)
214{
215 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
216
217 return !!(readl(osc->sckcr) & AT91_SCKC_RCEN);
218}
219
220static const struct clk_ops slow_rc_osc_ops = {
221 .prepare = clk_slow_rc_osc_prepare,
222 .unprepare = clk_slow_rc_osc_unprepare,
223 .is_prepared = clk_slow_rc_osc_is_prepared,
224 .recalc_rate = clk_slow_rc_osc_recalc_rate,
225 .recalc_accuracy = clk_slow_rc_osc_recalc_accuracy,
226};
227
228static struct clk_hw * __init
229at91_clk_register_slow_rc_osc(void __iomem *sckcr,
230 const char *name,
231 unsigned long frequency,
232 unsigned long accuracy,
233 unsigned long startup)
234{
235 struct clk_slow_rc_osc *osc;
236 struct clk_hw *hw;
237 struct clk_init_data init;
238 int ret;
239
240 if (!sckcr || !name)
241 return ERR_PTR(-EINVAL);
242
243 osc = kzalloc(sizeof(*osc), GFP_KERNEL);
244 if (!osc)
245 return ERR_PTR(-ENOMEM);
246
247 init.name = name;
248 init.ops = &slow_rc_osc_ops;
249 init.parent_names = NULL;
250 init.num_parents = 0;
251 init.flags = CLK_IGNORE_UNUSED;
252
253 osc->hw.init = &init;
254 osc->sckcr = sckcr;
255 osc->frequency = frequency;
256 osc->accuracy = accuracy;
257 osc->startup_usec = startup;
258
259 hw = &osc->hw;
260 ret = clk_hw_register(NULL, &osc->hw);
261 if (ret) {
262 kfree(osc);
263 hw = ERR_PTR(ret);
264 }
265
266 return hw;
267}
268
269static void __init
270of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np, void __iomem *sckcr)
271{
272 struct clk_hw *hw;
273 u32 frequency = 0;
274 u32 accuracy = 0;
275 u32 startup = 0;
276 const char *name = np->name;
277
278 of_property_read_string(np, "clock-output-names", &name);
279 of_property_read_u32(np, "clock-frequency", &frequency);
280 of_property_read_u32(np, "clock-accuracy", &accuracy);
281 of_property_read_u32(np, "atmel,startup-time-usec", &startup);
282
283 hw = at91_clk_register_slow_rc_osc(sckcr, name, frequency, accuracy,
284 startup);
285 if (IS_ERR(hw))
286 return;
287
288 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
289}
290
291static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
292{
293 struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
294 void __iomem *sckcr = slowck->sckcr;
295 u32 tmp;
296
297 if (index > 1)
298 return -EINVAL;
299
300 tmp = readl(sckcr);
301
302 if ((!index && !(tmp & AT91_SCKC_OSCSEL)) ||
303 (index && (tmp & AT91_SCKC_OSCSEL)))
304 return 0;
305
306 if (index)
307 tmp |= AT91_SCKC_OSCSEL;
308 else
309 tmp &= ~AT91_SCKC_OSCSEL;
310
311 writel(tmp, sckcr);
312
313 usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1);
314
315 return 0;
316}
317
318static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw)
319{
320 struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
321
322 return !!(readl(slowck->sckcr) & AT91_SCKC_OSCSEL);
323}
324
325static const struct clk_ops sam9x5_slow_ops = {
326 .set_parent = clk_sam9x5_slow_set_parent,
327 .get_parent = clk_sam9x5_slow_get_parent,
328};
329
330static struct clk_hw * __init
331at91_clk_register_sam9x5_slow(void __iomem *sckcr,
332 const char *name,
333 const char **parent_names,
334 int num_parents)
335{
336 struct clk_sam9x5_slow *slowck;
337 struct clk_hw *hw;
338 struct clk_init_data init;
339 int ret;
340
341 if (!sckcr || !name || !parent_names || !num_parents)
342 return ERR_PTR(-EINVAL);
343
344 slowck = kzalloc(sizeof(*slowck), GFP_KERNEL);
345 if (!slowck)
346 return ERR_PTR(-ENOMEM);
347
348 init.name = name;
349 init.ops = &sam9x5_slow_ops;
350 init.parent_names = parent_names;
351 init.num_parents = num_parents;
352 init.flags = 0;
353
354 slowck->hw.init = &init;
355 slowck->sckcr = sckcr;
356 slowck->parent = !!(readl(sckcr) & AT91_SCKC_OSCSEL);
357
358 hw = &slowck->hw;
359 ret = clk_hw_register(NULL, &slowck->hw);
360 if (ret) {
361 kfree(slowck);
362 hw = ERR_PTR(ret);
363 }
364
365 return hw;
366}
367
368static void __init
369of_at91sam9x5_clk_slow_setup(struct device_node *np, void __iomem *sckcr)
370{
371 struct clk_hw *hw;
372 const char *parent_names[2];
373 unsigned int num_parents;
374 const char *name = np->name;
375
376 num_parents = of_clk_get_parent_count(np);
377 if (num_parents == 0 || num_parents > 2)
378 return;
379
380 of_clk_parent_fill(np, parent_names, num_parents);
381
382 of_property_read_string(np, "clock-output-names", &name);
383
384 hw = at91_clk_register_sam9x5_slow(sckcr, name, parent_names,
385 num_parents);
386 if (IS_ERR(hw))
387 return;
388
389 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
390}
20 391
21static const struct of_device_id sckc_clk_ids[] __initconst = { 392static const struct of_device_id sckc_clk_ids[] __initconst = {
22 /* Slow clock */ 393 /* Slow clock */
@@ -55,3 +426,94 @@ static void __init of_at91sam9x5_sckc_setup(struct device_node *np)
55} 426}
56CLK_OF_DECLARE(at91sam9x5_clk_sckc, "atmel,at91sam9x5-sckc", 427CLK_OF_DECLARE(at91sam9x5_clk_sckc, "atmel,at91sam9x5-sckc",
57 of_at91sam9x5_sckc_setup); 428 of_at91sam9x5_sckc_setup);
429
430static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw)
431{
432 struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);
433
434 if (osc->prepared)
435 return 0;
436
437 /*
438 * Assume that if it has already been selected (for example by the
439 * bootloader), enough time has aready passed.
440 */
441 if ((readl(osc->sckcr) & AT91_SCKC_OSCSEL)) {
442 osc->prepared = true;
443 return 0;
444 }
445
446 usleep_range(osc->startup_usec, osc->startup_usec + 1);
447 osc->prepared = true;
448
449 return 0;
450}
451
452static int clk_sama5d4_slow_osc_is_prepared(struct clk_hw *hw)
453{
454 struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);
455
456 return osc->prepared;
457}
458
459static const struct clk_ops sama5d4_slow_osc_ops = {
460 .prepare = clk_sama5d4_slow_osc_prepare,
461 .is_prepared = clk_sama5d4_slow_osc_is_prepared,
462};
463
464static void __init of_sama5d4_sckc_setup(struct device_node *np)
465{
466 void __iomem *regbase = of_iomap(np, 0);
467 struct clk_hw *hw;
468 struct clk_sama5d4_slow_osc *osc;
469 struct clk_init_data init;
470 const char *xtal_name;
471 const char *parent_names[2] = { "slow_rc_osc", "slow_osc" };
472 bool bypass;
473 int ret;
474
475 if (!regbase)
476 return;
477
478 hw = clk_hw_register_fixed_rate_with_accuracy(NULL, parent_names[0],
479 NULL, 0, 32768,
480 250000000);
481 if (IS_ERR(hw))
482 return;
483
484 xtal_name = of_clk_get_parent_name(np, 0);
485
486 bypass = of_property_read_bool(np, "atmel,osc-bypass");
487
488 osc = kzalloc(sizeof(*osc), GFP_KERNEL);
489 if (!osc)
490 return;
491
492 init.name = parent_names[1];
493 init.ops = &sama5d4_slow_osc_ops;
494 init.parent_names = &xtal_name;
495 init.num_parents = 1;
496 init.flags = CLK_IGNORE_UNUSED;
497
498 osc->hw.init = &init;
499 osc->sckcr = regbase;
500 osc->startup_usec = 1200000;
501
502 if (bypass)
503 writel((readl(regbase) | AT91_SCKC_OSC32BYP), regbase);
504
505 hw = &osc->hw;
506 ret = clk_hw_register(NULL, &osc->hw);
507 if (ret) {
508 kfree(osc);
509 return;
510 }
511
512 hw = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_names, 2);
513 if (IS_ERR(hw))
514 return;
515
516 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
517}
518CLK_OF_DECLARE(sama5d4_clk_sckc, "atmel,sama5d4-sckc",
519 of_sama5d4_sckc_setup);
diff --git a/drivers/clk/at91/sckc.h b/drivers/clk/at91/sckc.h
deleted file mode 100644
index 836fcf59820f..000000000000
--- a/drivers/clk/at91/sckc.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/*
2 * drivers/clk/at91/sckc.h
3 *
4 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#ifndef __AT91_SCKC_H_
13#define __AT91_SCKC_H_
14
15extern void __init of_at91sam9x5_clk_slow_osc_setup(struct device_node *np,
16 void __iomem *sckcr);
17extern void __init of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np,
18 void __iomem *sckcr);
19extern void __init of_at91sam9x5_clk_slow_setup(struct device_node *np,
20 void __iomem *sckcr);
21
22#endif /* __AT91_SCKC_H_ */
diff --git a/drivers/clk/axis/clk-artpec6.c b/drivers/clk/axis/clk-artpec6.c
index ffc988b098e4..da1a073c2236 100644
--- a/drivers/clk/axis/clk-artpec6.c
+++ b/drivers/clk/axis/clk-artpec6.c
@@ -113,8 +113,8 @@ static void of_artpec6_clkctrl_setup(struct device_node *np)
113 of_clk_add_provider(np, of_clk_src_onecell_get, &clkdata->clk_data); 113 of_clk_add_provider(np, of_clk_src_onecell_get, &clkdata->clk_data);
114} 114}
115 115
116CLK_OF_DECLARE(artpec6_clkctrl, "axis,artpec6-clkctrl", 116CLK_OF_DECLARE_DRIVER(artpec6_clkctrl, "axis,artpec6-clkctrl",
117 of_artpec6_clkctrl_setup); 117 of_artpec6_clkctrl_setup);
118 118
119static int artpec6_clkctrl_probe(struct platform_device *pdev) 119static int artpec6_clkctrl_probe(struct platform_device *pdev)
120{ 120{
diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig
index f2878459199a..f21e9b7afd1a 100644
--- a/drivers/clk/bcm/Kconfig
+++ b/drivers/clk/bcm/Kconfig
@@ -19,8 +19,36 @@ config CLK_BCM_KONA
19 in the BCM281xx and BCM21664 families. 19 in the BCM281xx and BCM21664 families.
20 20
21config COMMON_CLK_IPROC 21config COMMON_CLK_IPROC
22 bool 22 bool "Broadcom iProc clock support"
23 depends on ARCH_BCM_IPROC || COMPILE_TEST
23 depends on COMMON_CLK 24 depends on COMMON_CLK
25 default ARCH_BCM_IPROC
24 help 26 help
25 Enable common clock framework support for Broadcom SoCs 27 Enable common clock framework support for Broadcom SoCs
26 based on the iProc architecture 28 based on the iProc architecture
29
30if COMMON_CLK_IPROC
31
32config CLK_BCM_CYGNUS
33 bool "Broadcom Cygnus clock support"
34 depends on ARCH_BCM_CYGNUS || COMPILE_TEST
35 default ARCH_BCM_CYGNUS
36 help
37 Enable common clock framework support for the Broadcom Cygnus SoC
38
39config CLK_BCM_NSP
40 bool "Broadcom Northstar/Northstar Plus clock support"
41 depends on ARCH_BCM_5301X || ARCH_BCM_NSP || COMPILE_TEST
42 default ARCH_BCM_5301X || ARCH_BCM_NSP
43 help
44 Enable common clock framework support for the Broadcom Northstar and
45 Northstar Plus SoCs
46
47config CLK_BCM_NS2
48 bool "Broadcom Northstar 2 clock support"
49 depends on ARCH_BCM_IPROC || COMPILE_TEST
50 default ARCH_BCM_IPROC
51 help
52 Enable common clock framework support for the Broadcom Northstar 2 SoC
53
54endif
diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile
index 1d79bd2c36f0..d9dc848f18c9 100644
--- a/drivers/clk/bcm/Makefile
+++ b/drivers/clk/bcm/Makefile
@@ -6,7 +6,7 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o
6obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o 6obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o
7obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o 7obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
8obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835-aux.o 8obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835-aux.o
9obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o 9obj-$(CONFIG_ARCH_BCM_53573) += clk-bcm53573-ilp.o
10obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o 10obj-$(CONFIG_CLK_BCM_CYGNUS) += clk-cygnus.o
11obj-$(CONFIG_ARCH_BCM_NSP) += clk-nsp.o 11obj-$(CONFIG_CLK_BCM_NSP) += clk-nsp.o
12obj-$(CONFIG_ARCH_BCM_5301X) += clk-nsp.o 12obj-$(CONFIG_CLK_BCM_NS2) += clk-ns2.o
diff --git a/drivers/clk/bcm/clk-bcm2835-aux.c b/drivers/clk/bcm/clk-bcm2835-aux.c
index 3a177ade6e6c..bd750cf2238d 100644
--- a/drivers/clk/bcm/clk-bcm2835-aux.c
+++ b/drivers/clk/bcm/clk-bcm2835-aux.c
@@ -25,7 +25,7 @@
25static int bcm2835_aux_clk_probe(struct platform_device *pdev) 25static int bcm2835_aux_clk_probe(struct platform_device *pdev)
26{ 26{
27 struct device *dev = &pdev->dev; 27 struct device *dev = &pdev->dev;
28 struct clk_onecell_data *onecell; 28 struct clk_hw_onecell_data *onecell;
29 const char *parent; 29 const char *parent;
30 struct clk *parent_clk; 30 struct clk *parent_clk;
31 struct resource *res; 31 struct resource *res;
@@ -41,28 +41,24 @@ static int bcm2835_aux_clk_probe(struct platform_device *pdev)
41 if (IS_ERR(reg)) 41 if (IS_ERR(reg))
42 return PTR_ERR(reg); 42 return PTR_ERR(reg);
43 43
44 onecell = devm_kmalloc(dev, sizeof(*onecell), GFP_KERNEL); 44 onecell = devm_kmalloc(dev, sizeof(*onecell) + sizeof(*onecell->hws) *
45 BCM2835_AUX_CLOCK_COUNT, GFP_KERNEL);
45 if (!onecell) 46 if (!onecell)
46 return -ENOMEM; 47 return -ENOMEM;
47 onecell->clk_num = BCM2835_AUX_CLOCK_COUNT; 48 onecell->num = BCM2835_AUX_CLOCK_COUNT;
48 onecell->clks = devm_kcalloc(dev, BCM2835_AUX_CLOCK_COUNT,
49 sizeof(*onecell->clks), GFP_KERNEL);
50 if (!onecell->clks)
51 return -ENOMEM;
52 49
53 gate = reg + BCM2835_AUXENB; 50 gate = reg + BCM2835_AUXENB;
54 onecell->clks[BCM2835_AUX_CLOCK_UART] = 51 onecell->hws[BCM2835_AUX_CLOCK_UART] =
55 clk_register_gate(dev, "aux_uart", parent, 0, gate, 0, 0, NULL); 52 clk_hw_register_gate(dev, "aux_uart", parent, 0, gate, 0, 0, NULL);
56
57 onecell->clks[BCM2835_AUX_CLOCK_SPI1] =
58 clk_register_gate(dev, "aux_spi1", parent, 0, gate, 1, 0, NULL);
59 53
60 onecell->clks[BCM2835_AUX_CLOCK_SPI2] = 54 onecell->hws[BCM2835_AUX_CLOCK_SPI1] =
61 clk_register_gate(dev, "aux_spi2", parent, 0, gate, 2, 0, NULL); 55 clk_hw_register_gate(dev, "aux_spi1", parent, 0, gate, 1, 0, NULL);
62 56
63 of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, onecell); 57 onecell->hws[BCM2835_AUX_CLOCK_SPI2] =
58 clk_hw_register_gate(dev, "aux_spi2", parent, 0, gate, 2, 0, NULL);
64 59
65 return 0; 60 return of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
61 onecell);
66} 62}
67 63
68static const struct of_device_id bcm2835_aux_clk_of_match[] = { 64static const struct of_device_id bcm2835_aux_clk_of_match[] = {
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 7a7970865c2d..b68bf573dcfb 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -36,6 +36,7 @@
36 36
37#include <linux/clk-provider.h> 37#include <linux/clk-provider.h>
38#include <linux/clkdev.h> 38#include <linux/clkdev.h>
39#include <linux/clk.h>
39#include <linux/clk/bcm2835.h> 40#include <linux/clk/bcm2835.h>
40#include <linux/debugfs.h> 41#include <linux/debugfs.h>
41#include <linux/module.h> 42#include <linux/module.h>
@@ -302,8 +303,8 @@ struct bcm2835_cprman {
302 spinlock_t regs_lock; /* spinlock for all clocks */ 303 spinlock_t regs_lock; /* spinlock for all clocks */
303 const char *osc_name; 304 const char *osc_name;
304 305
305 struct clk_onecell_data onecell; 306 /* Must be last */
306 struct clk *clks[]; 307 struct clk_hw_onecell_data onecell;
307}; 308};
308 309
309static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val) 310static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val)
@@ -344,24 +345,24 @@ static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base,
344 */ 345 */
345void __init bcm2835_init_clocks(void) 346void __init bcm2835_init_clocks(void)
346{ 347{
347 struct clk *clk; 348 struct clk_hw *hw;
348 int ret; 349 int ret;
349 350
350 clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 126000000); 351 hw = clk_hw_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 126000000);
351 if (IS_ERR(clk)) 352 if (IS_ERR(hw))
352 pr_err("apb_pclk not registered\n"); 353 pr_err("apb_pclk not registered\n");
353 354
354 clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, 0, 3000000); 355 hw = clk_hw_register_fixed_rate(NULL, "uart0_pclk", NULL, 0, 3000000);
355 if (IS_ERR(clk)) 356 if (IS_ERR(hw))
356 pr_err("uart0_pclk not registered\n"); 357 pr_err("uart0_pclk not registered\n");
357 ret = clk_register_clkdev(clk, NULL, "20201000.uart"); 358 ret = clk_hw_register_clkdev(hw, NULL, "20201000.uart");
358 if (ret) 359 if (ret)
359 pr_err("uart0_pclk alias not registered\n"); 360 pr_err("uart0_pclk alias not registered\n");
360 361
361 clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, 0, 125000000); 362 hw = clk_hw_register_fixed_rate(NULL, "uart1_pclk", NULL, 0, 125000000);
362 if (IS_ERR(clk)) 363 if (IS_ERR(hw))
363 pr_err("uart1_pclk not registered\n"); 364 pr_err("uart1_pclk not registered\n");
364 ret = clk_register_clkdev(clk, NULL, "20215000.uart"); 365 ret = clk_hw_register_clkdev(hw, NULL, "20215000.uart");
365 if (ret) 366 if (ret)
366 pr_err("uart1_pclk alias not registered\n"); 367 pr_err("uart1_pclk alias not registered\n");
367} 368}
@@ -443,6 +444,8 @@ struct bcm2835_clock_data {
443 /* Number of fractional bits in the divider */ 444 /* Number of fractional bits in the divider */
444 u32 frac_bits; 445 u32 frac_bits;
445 446
447 u32 flags;
448
446 bool is_vpu_clock; 449 bool is_vpu_clock;
447 bool is_mash_clock; 450 bool is_mash_clock;
448}; 451};
@@ -1006,16 +1009,28 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw,
1006 return 0; 1009 return 0;
1007} 1010}
1008 1011
1012static bool
1013bcm2835_clk_is_pllc(struct clk_hw *hw)
1014{
1015 if (!hw)
1016 return false;
1017
1018 return strncmp(clk_hw_get_name(hw), "pllc", 4) == 0;
1019}
1020
1009static int bcm2835_clock_determine_rate(struct clk_hw *hw, 1021static int bcm2835_clock_determine_rate(struct clk_hw *hw,
1010 struct clk_rate_request *req) 1022 struct clk_rate_request *req)
1011{ 1023{
1012 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); 1024 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
1013 struct clk_hw *parent, *best_parent = NULL; 1025 struct clk_hw *parent, *best_parent = NULL;
1026 bool current_parent_is_pllc;
1014 unsigned long rate, best_rate = 0; 1027 unsigned long rate, best_rate = 0;
1015 unsigned long prate, best_prate = 0; 1028 unsigned long prate, best_prate = 0;
1016 size_t i; 1029 size_t i;
1017 u32 div; 1030 u32 div;
1018 1031
1032 current_parent_is_pllc = bcm2835_clk_is_pllc(clk_hw_get_parent(hw));
1033
1019 /* 1034 /*
1020 * Select parent clock that results in the closest but lower rate 1035 * Select parent clock that results in the closest but lower rate
1021 */ 1036 */
@@ -1023,6 +1038,17 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw,
1023 parent = clk_hw_get_parent_by_index(hw, i); 1038 parent = clk_hw_get_parent_by_index(hw, i);
1024 if (!parent) 1039 if (!parent)
1025 continue; 1040 continue;
1041
1042 /*
1043 * Don't choose a PLLC-derived clock as our parent
1044 * unless it had been manually set that way. PLLC's
1045 * frequency gets adjusted by the firmware due to
1046 * over-temp or under-voltage conditions, without
1047 * prior notification to our clock consumer.
1048 */
1049 if (bcm2835_clk_is_pllc(parent) && !current_parent_is_pllc)
1050 continue;
1051
1026 prate = clk_hw_get_rate(parent); 1052 prate = clk_hw_get_rate(parent);
1027 div = bcm2835_clock_choose_div(hw, req->rate, prate, true); 1053 div = bcm2835_clock_choose_div(hw, req->rate, prate, true);
1028 rate = bcm2835_clock_rate_from_divisor(clock, prate, div); 1054 rate = bcm2835_clock_rate_from_divisor(clock, prate, div);
@@ -1121,11 +1147,12 @@ static const struct clk_ops bcm2835_vpu_clock_clk_ops = {
1121 .debug_init = bcm2835_clock_debug_init, 1147 .debug_init = bcm2835_clock_debug_init,
1122}; 1148};
1123 1149
1124static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman, 1150static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman,
1125 const struct bcm2835_pll_data *data) 1151 const struct bcm2835_pll_data *data)
1126{ 1152{
1127 struct bcm2835_pll *pll; 1153 struct bcm2835_pll *pll;
1128 struct clk_init_data init; 1154 struct clk_init_data init;
1155 int ret;
1129 1156
1130 memset(&init, 0, sizeof(init)); 1157 memset(&init, 0, sizeof(init));
1131 1158
@@ -1144,17 +1171,20 @@ static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman,
1144 pll->data = data; 1171 pll->data = data;
1145 pll->hw.init = &init; 1172 pll->hw.init = &init;
1146 1173
1147 return devm_clk_register(cprman->dev, &pll->hw); 1174 ret = devm_clk_hw_register(cprman->dev, &pll->hw);
1175 if (ret)
1176 return NULL;
1177 return &pll->hw;
1148} 1178}
1149 1179
1150static struct clk * 1180static struct clk_hw *
1151bcm2835_register_pll_divider(struct bcm2835_cprman *cprman, 1181bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
1152 const struct bcm2835_pll_divider_data *data) 1182 const struct bcm2835_pll_divider_data *data)
1153{ 1183{
1154 struct bcm2835_pll_divider *divider; 1184 struct bcm2835_pll_divider *divider;
1155 struct clk_init_data init; 1185 struct clk_init_data init;
1156 struct clk *clk;
1157 const char *divider_name; 1186 const char *divider_name;
1187 int ret;
1158 1188
1159 if (data->fixed_divider != 1) { 1189 if (data->fixed_divider != 1) {
1160 divider_name = devm_kasprintf(cprman->dev, GFP_KERNEL, 1190 divider_name = devm_kasprintf(cprman->dev, GFP_KERNEL,
@@ -1188,32 +1218,33 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
1188 divider->cprman = cprman; 1218 divider->cprman = cprman;
1189 divider->data = data; 1219 divider->data = data;
1190 1220
1191 clk = devm_clk_register(cprman->dev, &divider->div.hw); 1221 ret = devm_clk_hw_register(cprman->dev, &divider->div.hw);
1192 if (IS_ERR(clk)) 1222 if (ret)
1193 return clk; 1223 return ERR_PTR(ret);
1194 1224
1195 /* 1225 /*
1196 * PLLH's channels have a fixed divide by 10 afterwards, which 1226 * PLLH's channels have a fixed divide by 10 afterwards, which
1197 * is what our consumers are actually using. 1227 * is what our consumers are actually using.
1198 */ 1228 */
1199 if (data->fixed_divider != 1) { 1229 if (data->fixed_divider != 1) {
1200 return clk_register_fixed_factor(cprman->dev, data->name, 1230 return clk_hw_register_fixed_factor(cprman->dev, data->name,
1201 divider_name, 1231 divider_name,
1202 CLK_SET_RATE_PARENT, 1232 CLK_SET_RATE_PARENT,
1203 1, 1233 1,
1204 data->fixed_divider); 1234 data->fixed_divider);
1205 } 1235 }
1206 1236
1207 return clk; 1237 return &divider->div.hw;
1208} 1238}
1209 1239
1210static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman, 1240static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman,
1211 const struct bcm2835_clock_data *data) 1241 const struct bcm2835_clock_data *data)
1212{ 1242{
1213 struct bcm2835_clock *clock; 1243 struct bcm2835_clock *clock;
1214 struct clk_init_data init; 1244 struct clk_init_data init;
1215 const char *parents[1 << CM_SRC_BITS]; 1245 const char *parents[1 << CM_SRC_BITS];
1216 size_t i; 1246 size_t i;
1247 int ret;
1217 1248
1218 /* 1249 /*
1219 * Replace our "xosc" references with the oscillator's 1250 * Replace our "xosc" references with the oscillator's
@@ -1230,13 +1261,19 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
1230 init.parent_names = parents; 1261 init.parent_names = parents;
1231 init.num_parents = data->num_mux_parents; 1262 init.num_parents = data->num_mux_parents;
1232 init.name = data->name; 1263 init.name = data->name;
1233 init.flags = CLK_IGNORE_UNUSED; 1264 init.flags = data->flags | CLK_IGNORE_UNUSED;
1234 1265
1235 if (data->is_vpu_clock) { 1266 if (data->is_vpu_clock) {
1236 init.ops = &bcm2835_vpu_clock_clk_ops; 1267 init.ops = &bcm2835_vpu_clock_clk_ops;
1237 } else { 1268 } else {
1238 init.ops = &bcm2835_clock_clk_ops; 1269 init.ops = &bcm2835_clock_clk_ops;
1239 init.flags |= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; 1270 init.flags |= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
1271
1272 /* If the clock wasn't actually enabled at boot, it's not
1273 * critical.
1274 */
1275 if (!(cprman_read(cprman, data->ctl_reg) & CM_ENABLE))
1276 init.flags &= ~CLK_IS_CRITICAL;
1240 } 1277 }
1241 1278
1242 clock = devm_kzalloc(cprman->dev, sizeof(*clock), GFP_KERNEL); 1279 clock = devm_kzalloc(cprman->dev, sizeof(*clock), GFP_KERNEL);
@@ -1247,7 +1284,10 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
1247 clock->data = data; 1284 clock->data = data;
1248 clock->hw.init = &init; 1285 clock->hw.init = &init;
1249 1286
1250 return devm_clk_register(cprman->dev, &clock->hw); 1287 ret = devm_clk_hw_register(cprman->dev, &clock->hw);
1288 if (ret)
1289 return ERR_PTR(ret);
1290 return &clock->hw;
1251} 1291}
1252 1292
1253static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman, 1293static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman,
@@ -1259,8 +1299,8 @@ static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman,
1259 CM_GATE_BIT, 0, &cprman->regs_lock); 1299 CM_GATE_BIT, 0, &cprman->regs_lock);
1260} 1300}
1261 1301
1262typedef struct clk *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman, 1302typedef struct clk_hw *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman,
1263 const void *data); 1303 const void *data);
1264struct bcm2835_clk_desc { 1304struct bcm2835_clk_desc {
1265 bcm2835_clk_register clk_register; 1305 bcm2835_clk_register clk_register;
1266 const void *data; 1306 const void *data;
@@ -1649,6 +1689,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1649 .div_reg = CM_VPUDIV, 1689 .div_reg = CM_VPUDIV,
1650 .int_bits = 12, 1690 .int_bits = 12,
1651 .frac_bits = 8, 1691 .frac_bits = 8,
1692 .flags = CLK_IS_CRITICAL,
1652 .is_vpu_clock = true), 1693 .is_vpu_clock = true),
1653 1694
1654 /* clocks with per parent mux */ 1695 /* clocks with per parent mux */
@@ -1705,13 +1746,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1705 .div_reg = CM_GP1DIV, 1746 .div_reg = CM_GP1DIV,
1706 .int_bits = 12, 1747 .int_bits = 12,
1707 .frac_bits = 12, 1748 .frac_bits = 12,
1749 .flags = CLK_IS_CRITICAL,
1708 .is_mash_clock = true), 1750 .is_mash_clock = true),
1709 [BCM2835_CLOCK_GP2] = REGISTER_PER_CLK( 1751 [BCM2835_CLOCK_GP2] = REGISTER_PER_CLK(
1710 .name = "gp2", 1752 .name = "gp2",
1711 .ctl_reg = CM_GP2CTL, 1753 .ctl_reg = CM_GP2CTL,
1712 .div_reg = CM_GP2DIV, 1754 .div_reg = CM_GP2DIV,
1713 .int_bits = 12, 1755 .int_bits = 12,
1714 .frac_bits = 12), 1756 .frac_bits = 12,
1757 .flags = CLK_IS_CRITICAL),
1715 1758
1716 /* HDMI state machine */ 1759 /* HDMI state machine */
1717 [BCM2835_CLOCK_HSM] = REGISTER_PER_CLK( 1760 [BCM2835_CLOCK_HSM] = REGISTER_PER_CLK(
@@ -1790,18 +1833,38 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1790 .ctl_reg = CM_PERIICTL), 1833 .ctl_reg = CM_PERIICTL),
1791}; 1834};
1792 1835
1836/*
1837 * Permanently take a reference on the parent of the SDRAM clock.
1838 *
1839 * While the SDRAM is being driven by its dedicated PLL most of the
1840 * time, there is a little loop running in the firmware that
1841 * periodically switches the SDRAM to using our CM clock to do PVT
1842 * recalibration, with the assumption that the previously configured
1843 * SDRAM parent is still enabled and running.
1844 */
1845static int bcm2835_mark_sdc_parent_critical(struct clk *sdc)
1846{
1847 struct clk *parent = clk_get_parent(sdc);
1848
1849 if (IS_ERR(parent))
1850 return PTR_ERR(parent);
1851
1852 return clk_prepare_enable(parent);
1853}
1854
1793static int bcm2835_clk_probe(struct platform_device *pdev) 1855static int bcm2835_clk_probe(struct platform_device *pdev)
1794{ 1856{
1795 struct device *dev = &pdev->dev; 1857 struct device *dev = &pdev->dev;
1796 struct clk **clks; 1858 struct clk_hw **hws;
1797 struct bcm2835_cprman *cprman; 1859 struct bcm2835_cprman *cprman;
1798 struct resource *res; 1860 struct resource *res;
1799 const struct bcm2835_clk_desc *desc; 1861 const struct bcm2835_clk_desc *desc;
1800 const size_t asize = ARRAY_SIZE(clk_desc_array); 1862 const size_t asize = ARRAY_SIZE(clk_desc_array);
1801 size_t i; 1863 size_t i;
1864 int ret;
1802 1865
1803 cprman = devm_kzalloc(dev, 1866 cprman = devm_kzalloc(dev, sizeof(*cprman) +
1804 sizeof(*cprman) + asize * sizeof(*clks), 1867 sizeof(*cprman->onecell.hws) * asize,
1805 GFP_KERNEL); 1868 GFP_KERNEL);
1806 if (!cprman) 1869 if (!cprman)
1807 return -ENOMEM; 1870 return -ENOMEM;
@@ -1819,18 +1882,21 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
1819 1882
1820 platform_set_drvdata(pdev, cprman); 1883 platform_set_drvdata(pdev, cprman);
1821 1884
1822 cprman->onecell.clk_num = asize; 1885 cprman->onecell.num = asize;
1823 cprman->onecell.clks = cprman->clks; 1886 hws = cprman->onecell.hws;
1824 clks = cprman->clks;
1825 1887
1826 for (i = 0; i < asize; i++) { 1888 for (i = 0; i < asize; i++) {
1827 desc = &clk_desc_array[i]; 1889 desc = &clk_desc_array[i];
1828 if (desc->clk_register && desc->data) 1890 if (desc->clk_register && desc->data)
1829 clks[i] = desc->clk_register(cprman, desc->data); 1891 hws[i] = desc->clk_register(cprman, desc->data);
1830 } 1892 }
1831 1893
1832 return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, 1894 ret = bcm2835_mark_sdc_parent_critical(hws[BCM2835_CLOCK_SDRAM]->clk);
1833 &cprman->onecell); 1895 if (ret)
1896 return ret;
1897
1898 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
1899 &cprman->onecell);
1834} 1900}
1835 1901
1836static const struct of_device_id bcm2835_clk_of_match[] = { 1902static const struct of_device_id bcm2835_clk_of_match[] = {
diff --git a/drivers/clk/bcm/clk-bcm53573-ilp.c b/drivers/clk/bcm/clk-bcm53573-ilp.c
new file mode 100644
index 000000000000..36eb3716ffb0
--- /dev/null
+++ b/drivers/clk/bcm/clk-bcm53573-ilp.c
@@ -0,0 +1,148 @@
1/*
2 * Copyright (C) 2016 Rafał Miłecki <rafal@milecki.pl>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/clk-provider.h>
10#include <linux/err.h>
11#include <linux/io.h>
12#include <linux/mfd/syscon.h>
13#include <linux/of.h>
14#include <linux/of_address.h>
15#include <linux/regmap.h>
16#include <linux/slab.h>
17
18#define PMU_XTAL_FREQ_RATIO 0x66c
19#define XTAL_ALP_PER_4ILP 0x00001fff
20#define XTAL_CTL_EN 0x80000000
21#define PMU_SLOW_CLK_PERIOD 0x6dc
22
23struct bcm53573_ilp {
24 struct clk_hw hw;
25 struct regmap *regmap;
26};
27
28static int bcm53573_ilp_enable(struct clk_hw *hw)
29{
30 struct bcm53573_ilp *ilp = container_of(hw, struct bcm53573_ilp, hw);
31
32 regmap_write(ilp->regmap, PMU_SLOW_CLK_PERIOD, 0x10199);
33 regmap_write(ilp->regmap, 0x674, 0x10000);
34
35 return 0;
36}
37
38static void bcm53573_ilp_disable(struct clk_hw *hw)
39{
40 struct bcm53573_ilp *ilp = container_of(hw, struct bcm53573_ilp, hw);
41
42 regmap_write(ilp->regmap, PMU_SLOW_CLK_PERIOD, 0);
43 regmap_write(ilp->regmap, 0x674, 0);
44}
45
46static unsigned long bcm53573_ilp_recalc_rate(struct clk_hw *hw,
47 unsigned long parent_rate)
48{
49 struct bcm53573_ilp *ilp = container_of(hw, struct bcm53573_ilp, hw);
50 struct regmap *regmap = ilp->regmap;
51 u32 last_val, cur_val;
52 int sum = 0, num = 0, loop_num = 0;
53 int avg;
54
55 /* Enable measurement */
56 regmap_write(regmap, PMU_XTAL_FREQ_RATIO, XTAL_CTL_EN);
57
58 /* Read initial value */
59 regmap_read(regmap, PMU_XTAL_FREQ_RATIO, &last_val);
60 last_val &= XTAL_ALP_PER_4ILP;
61
62 /*
63 * At minimum we should loop for a bit to let hardware do the
64 * measurement. This isn't very accurate however, so for a better
65 * precision lets try getting 20 different values for and use average.
66 */
67 while (num < 20) {
68 regmap_read(regmap, PMU_XTAL_FREQ_RATIO, &cur_val);
69 cur_val &= XTAL_ALP_PER_4ILP;
70
71 if (cur_val != last_val) {
72 /* Got different value, use it */
73 sum += cur_val;
74 num++;
75 loop_num = 0;
76 last_val = cur_val;
77 } else if (++loop_num > 5000) {
78 /* Same value over and over, give up */
79 sum += cur_val;
80 num++;
81 break;
82 }
83
84 cpu_relax();
85 }
86
87 /* Disable measurement to save power */
88 regmap_write(regmap, PMU_XTAL_FREQ_RATIO, 0x0);
89
90 avg = sum / num;
91
92 return parent_rate * 4 / avg;
93}
94
95static const struct clk_ops bcm53573_ilp_clk_ops = {
96 .enable = bcm53573_ilp_enable,
97 .disable = bcm53573_ilp_disable,
98 .recalc_rate = bcm53573_ilp_recalc_rate,
99};
100
101static void bcm53573_ilp_init(struct device_node *np)
102{
103 struct bcm53573_ilp *ilp;
104 struct clk_init_data init = { };
105 const char *parent_name;
106 int err;
107
108 ilp = kzalloc(sizeof(*ilp), GFP_KERNEL);
109 if (!ilp)
110 return;
111
112 parent_name = of_clk_get_parent_name(np, 0);
113 if (!parent_name) {
114 err = -ENOENT;
115 goto err_free_ilp;
116 }
117
118 ilp->regmap = syscon_node_to_regmap(of_get_parent(np));
119 if (IS_ERR(ilp->regmap)) {
120 err = PTR_ERR(ilp->regmap);
121 goto err_free_ilp;
122 }
123
124 init.name = np->name;
125 init.ops = &bcm53573_ilp_clk_ops;
126 init.parent_names = &parent_name;
127 init.num_parents = 1;
128
129 ilp->hw.init = &init;
130 err = clk_hw_register(NULL, &ilp->hw);
131 if (err)
132 goto err_free_ilp;
133
134 err = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &ilp->hw);
135 if (err)
136 goto err_clk_hw_unregister;
137
138 return;
139
140err_clk_hw_unregister:
141 clk_hw_unregister(&ilp->hw);
142err_free_ilp:
143 kfree(ilp);
144 pr_err("Failed to init ILP clock: %d\n", err);
145}
146
147/* We need it very early for arch code, before device model gets ready */
148CLK_OF_DECLARE(bcm53573_ilp_clk, "brcm,bcm53573-ilp", bcm53573_ilp_init);
diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c
index 526b0b0e9a9f..c37a7f0e83aa 100644
--- a/drivers/clk/bcm/clk-kona-setup.c
+++ b/drivers/clk/bcm/clk-kona-setup.c
@@ -586,8 +586,8 @@ static u32 *parent_process(const char *clocks[],
586 } 586 }
587 587
588 /* There is at least one parent, so allocate a selector array */ 588 /* There is at least one parent, so allocate a selector array */
589 589 parent_sel = kmalloc_array(parent_count, sizeof(*parent_sel),
590 parent_sel = kmalloc(parent_count * sizeof(*parent_sel), GFP_KERNEL); 590 GFP_KERNEL);
591 if (!parent_sel) { 591 if (!parent_sel) {
592 pr_err("%s: error allocating %u parent selectors\n", __func__, 592 pr_err("%s: error allocating %u parent selectors\n", __func__,
593 parent_count); 593 parent_count);
@@ -696,77 +696,69 @@ static void bcm_clk_teardown(struct kona_clk *bcm_clk)
696 bcm_clk->type = bcm_clk_none; 696 bcm_clk->type = bcm_clk_none;
697} 697}
698 698
699static void kona_clk_teardown(struct clk *clk) 699static void kona_clk_teardown(struct clk_hw *hw)
700{ 700{
701 struct clk_hw *hw;
702 struct kona_clk *bcm_clk; 701 struct kona_clk *bcm_clk;
703 702
704 if (!clk) 703 if (!hw)
705 return; 704 return;
706 705
707 hw = __clk_get_hw(clk); 706 clk_hw_unregister(hw);
708 if (!hw) {
709 pr_err("%s: clk %p has null hw pointer\n", __func__, clk);
710 return;
711 }
712 clk_unregister(clk);
713 707
714 bcm_clk = to_kona_clk(hw); 708 bcm_clk = to_kona_clk(hw);
715 bcm_clk_teardown(bcm_clk); 709 bcm_clk_teardown(bcm_clk);
716} 710}
717 711
718struct clk *kona_clk_setup(struct kona_clk *bcm_clk) 712static int kona_clk_setup(struct kona_clk *bcm_clk)
719{ 713{
714 int ret;
720 struct clk_init_data *init_data = &bcm_clk->init_data; 715 struct clk_init_data *init_data = &bcm_clk->init_data;
721 struct clk *clk = NULL;
722 716
723 switch (bcm_clk->type) { 717 switch (bcm_clk->type) {
724 case bcm_clk_peri: 718 case bcm_clk_peri:
725 if (peri_clk_setup(bcm_clk->u.data, init_data)) 719 ret = peri_clk_setup(bcm_clk->u.data, init_data);
726 return NULL; 720 if (ret)
721 return ret;
727 break; 722 break;
728 default: 723 default:
729 pr_err("%s: clock type %d invalid for %s\n", __func__, 724 pr_err("%s: clock type %d invalid for %s\n", __func__,
730 (int)bcm_clk->type, init_data->name); 725 (int)bcm_clk->type, init_data->name);
731 return NULL; 726 return -EINVAL;
732 } 727 }
733 728
734 /* Make sure everything makes sense before we set it up */ 729 /* Make sure everything makes sense before we set it up */
735 if (!kona_clk_valid(bcm_clk)) { 730 if (!kona_clk_valid(bcm_clk)) {
736 pr_err("%s: clock data invalid for %s\n", __func__, 731 pr_err("%s: clock data invalid for %s\n", __func__,
737 init_data->name); 732 init_data->name);
733 ret = -EINVAL;
738 goto out_teardown; 734 goto out_teardown;
739 } 735 }
740 736
741 bcm_clk->hw.init = init_data; 737 bcm_clk->hw.init = init_data;
742 clk = clk_register(NULL, &bcm_clk->hw); 738 ret = clk_hw_register(NULL, &bcm_clk->hw);
743 if (IS_ERR(clk)) { 739 if (ret) {
744 pr_err("%s: error registering clock %s (%ld)\n", __func__, 740 pr_err("%s: error registering clock %s (%d)\n", __func__,
745 init_data->name, PTR_ERR(clk)); 741 init_data->name, ret);
746 goto out_teardown; 742 goto out_teardown;
747 } 743 }
748 BUG_ON(!clk);
749 744
750 return clk; 745 return 0;
751out_teardown: 746out_teardown:
752 bcm_clk_teardown(bcm_clk); 747 bcm_clk_teardown(bcm_clk);
753 748
754 return NULL; 749 return ret;
755} 750}
756 751
757static void ccu_clks_teardown(struct ccu_data *ccu) 752static void ccu_clks_teardown(struct ccu_data *ccu)
758{ 753{
759 u32 i; 754 u32 i;
760 755
761 for (i = 0; i < ccu->clk_data.clk_num; i++) 756 for (i = 0; i < ccu->clk_num; i++)
762 kona_clk_teardown(ccu->clk_data.clks[i]); 757 kona_clk_teardown(&ccu->kona_clks[i].hw);
763 kfree(ccu->clk_data.clks);
764} 758}
765 759
766static void kona_ccu_teardown(struct ccu_data *ccu) 760static void kona_ccu_teardown(struct ccu_data *ccu)
767{ 761{
768 kfree(ccu->clk_data.clks);
769 ccu->clk_data.clks = NULL;
770 if (!ccu->base) 762 if (!ccu->base)
771 return; 763 return;
772 764
@@ -793,6 +785,20 @@ static bool ccu_data_valid(struct ccu_data *ccu)
793 return true; 785 return true;
794} 786}
795 787
788static struct clk_hw *
789of_clk_kona_onecell_get(struct of_phandle_args *clkspec, void *data)
790{
791 struct ccu_data *ccu = data;
792 unsigned int idx = clkspec->args[0];
793
794 if (idx >= ccu->clk_num) {
795 pr_err("%s: invalid index %u\n", __func__, idx);
796 return ERR_PTR(-EINVAL);
797 }
798
799 return &ccu->kona_clks[idx].hw;
800}
801
796/* 802/*
797 * Set up a CCU. Call the provided ccu_clks_setup callback to 803 * Set up a CCU. Call the provided ccu_clks_setup callback to
798 * initialize the array of clocks provided by the CCU. 804 * initialize the array of clocks provided by the CCU.
@@ -805,18 +811,6 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu,
805 unsigned int i; 811 unsigned int i;
806 int ret; 812 int ret;
807 813
808 if (ccu->clk_data.clk_num) {
809 size_t size;
810
811 size = ccu->clk_data.clk_num * sizeof(*ccu->clk_data.clks);
812 ccu->clk_data.clks = kzalloc(size, GFP_KERNEL);
813 if (!ccu->clk_data.clks) {
814 pr_err("%s: unable to allocate %u clocks for %s\n",
815 __func__, ccu->clk_data.clk_num, node->name);
816 return;
817 }
818 }
819
820 ret = of_address_to_resource(node, 0, &res); 814 ret = of_address_to_resource(node, 0, &res);
821 if (ret) { 815 if (ret) {
822 pr_err("%s: no valid CCU registers found for %s\n", __func__, 816 pr_err("%s: no valid CCU registers found for %s\n", __func__,
@@ -851,13 +845,13 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu,
851 * the clock framework clock array (in ccu->data). Then 845 * the clock framework clock array (in ccu->data). Then
852 * register as a provider for these clocks. 846 * register as a provider for these clocks.
853 */ 847 */
854 for (i = 0; i < ccu->clk_data.clk_num; i++) { 848 for (i = 0; i < ccu->clk_num; i++) {
855 if (!ccu->kona_clks[i].ccu) 849 if (!ccu->kona_clks[i].ccu)
856 continue; 850 continue;
857 ccu->clk_data.clks[i] = kona_clk_setup(&ccu->kona_clks[i]); 851 kona_clk_setup(&ccu->kona_clks[i]);
858 } 852 }
859 853
860 ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->clk_data); 854 ret = of_clk_add_hw_provider(node, of_clk_kona_onecell_get, ccu);
861 if (ret) { 855 if (ret) {
862 pr_err("%s: error adding ccu %s as provider (%d)\n", __func__, 856 pr_err("%s: error adding ccu %s as provider (%d)\n", __func__,
863 node->name, ret); 857 node->name, ret);
diff --git a/drivers/clk/bcm/clk-kona.c b/drivers/clk/bcm/clk-kona.c
index 3a15347b4233..eee64b9e5d10 100644
--- a/drivers/clk/bcm/clk-kona.c
+++ b/drivers/clk/bcm/clk-kona.c
@@ -1256,19 +1256,18 @@ bool __init kona_ccu_init(struct ccu_data *ccu)
1256{ 1256{
1257 unsigned long flags; 1257 unsigned long flags;
1258 unsigned int which; 1258 unsigned int which;
1259 struct clk **clks = ccu->clk_data.clks;
1260 struct kona_clk *kona_clks = ccu->kona_clks; 1259 struct kona_clk *kona_clks = ccu->kona_clks;
1261 bool success = true; 1260 bool success = true;
1262 1261
1263 flags = ccu_lock(ccu); 1262 flags = ccu_lock(ccu);
1264 __ccu_write_enable(ccu); 1263 __ccu_write_enable(ccu);
1265 1264
1266 for (which = 0; which < ccu->clk_data.clk_num; which++) { 1265 for (which = 0; which < ccu->clk_num; which++) {
1267 struct kona_clk *bcm_clk; 1266 struct kona_clk *bcm_clk = &kona_clks[which];
1268 1267
1269 if (!clks[which]) 1268 if (!bcm_clk->ccu)
1270 continue; 1269 continue;
1271 bcm_clk = &kona_clks[which]; 1270
1272 success &= __kona_clk_init(bcm_clk); 1271 success &= __kona_clk_init(bcm_clk);
1273 } 1272 }
1274 1273
diff --git a/drivers/clk/bcm/clk-kona.h b/drivers/clk/bcm/clk-kona.h
index 906576ec97b6..f4b39bb5558a 100644
--- a/drivers/clk/bcm/clk-kona.h
+++ b/drivers/clk/bcm/clk-kona.h
@@ -481,7 +481,7 @@ struct ccu_data {
481 bool write_enabled; /* write access is currently enabled */ 481 bool write_enabled; /* write access is currently enabled */
482 struct ccu_policy policy; 482 struct ccu_policy policy;
483 struct device_node *node; 483 struct device_node *node;
484 struct clk_onecell_data clk_data; 484 size_t clk_num;
485 const char *name; 485 const char *name;
486 u32 range; /* byte range of address space */ 486 u32 range; /* byte range of address space */
487 struct kona_clk kona_clks[]; /* must be last */ 487 struct kona_clk kona_clks[]; /* must be last */
@@ -491,9 +491,7 @@ struct ccu_data {
491#define KONA_CCU_COMMON(_prefix, _name, _ccuname) \ 491#define KONA_CCU_COMMON(_prefix, _name, _ccuname) \
492 .name = #_name "_ccu", \ 492 .name = #_name "_ccu", \
493 .lock = __SPIN_LOCK_UNLOCKED(_name ## _ccu_data.lock), \ 493 .lock = __SPIN_LOCK_UNLOCKED(_name ## _ccu_data.lock), \
494 .clk_data = { \ 494 .clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT
495 .clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT, \
496 }
497 495
498/* Exported globals */ 496/* Exported globals */
499 497
@@ -505,7 +503,6 @@ extern u64 scaled_div_max(struct bcm_clk_div *div);
505extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, 503extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value,
506 u32 billionths); 504 u32 billionths);
507 505
508extern struct clk *kona_clk_setup(struct kona_clk *bcm_clk);
509extern void __init kona_dt_ccu_setup(struct ccu_data *ccu, 506extern void __init kona_dt_ccu_setup(struct ccu_data *ccu,
510 struct device_node *node); 507 struct device_node *node);
511extern bool __init kona_ccu_init(struct ccu_data *ccu); 508extern bool __init kona_ccu_init(struct ccu_data *ccu);
diff --git a/drivers/clk/berlin/berlin2-avpll.c b/drivers/clk/berlin/berlin2-avpll.c
index fd0f26c38465..cfcae468e989 100644
--- a/drivers/clk/berlin/berlin2-avpll.c
+++ b/drivers/clk/berlin/berlin2-avpll.c
@@ -188,7 +188,7 @@ static const struct clk_ops berlin2_avpll_vco_ops = {
188 .recalc_rate = berlin2_avpll_vco_recalc_rate, 188 .recalc_rate = berlin2_avpll_vco_recalc_rate,
189}; 189};
190 190
191struct clk * __init berlin2_avpll_vco_register(void __iomem *base, 191int __init berlin2_avpll_vco_register(void __iomem *base,
192 const char *name, const char *parent_name, 192 const char *name, const char *parent_name,
193 u8 vco_flags, unsigned long flags) 193 u8 vco_flags, unsigned long flags)
194{ 194{
@@ -197,7 +197,7 @@ struct clk * __init berlin2_avpll_vco_register(void __iomem *base,
197 197
198 vco = kzalloc(sizeof(*vco), GFP_KERNEL); 198 vco = kzalloc(sizeof(*vco), GFP_KERNEL);
199 if (!vco) 199 if (!vco)
200 return ERR_PTR(-ENOMEM); 200 return -ENOMEM;
201 201
202 vco->base = base; 202 vco->base = base;
203 vco->flags = vco_flags; 203 vco->flags = vco_flags;
@@ -208,7 +208,7 @@ struct clk * __init berlin2_avpll_vco_register(void __iomem *base,
208 init.num_parents = 1; 208 init.num_parents = 1;
209 init.flags = flags; 209 init.flags = flags;
210 210
211 return clk_register(NULL, &vco->hw); 211 return clk_hw_register(NULL, &vco->hw);
212} 212}
213 213
214struct berlin2_avpll_channel { 214struct berlin2_avpll_channel {
@@ -364,7 +364,7 @@ static const struct clk_ops berlin2_avpll_channel_ops = {
364 */ 364 */
365static const u8 quirk_index[] __initconst = { 0, 6, 5, 4, 3, 2, 1, 7 }; 365static const u8 quirk_index[] __initconst = { 0, 6, 5, 4, 3, 2, 1, 7 };
366 366
367struct clk * __init berlin2_avpll_channel_register(void __iomem *base, 367int __init berlin2_avpll_channel_register(void __iomem *base,
368 const char *name, u8 index, const char *parent_name, 368 const char *name, u8 index, const char *parent_name,
369 u8 ch_flags, unsigned long flags) 369 u8 ch_flags, unsigned long flags)
370{ 370{
@@ -373,7 +373,7 @@ struct clk * __init berlin2_avpll_channel_register(void __iomem *base,
373 373
374 ch = kzalloc(sizeof(*ch), GFP_KERNEL); 374 ch = kzalloc(sizeof(*ch), GFP_KERNEL);
375 if (!ch) 375 if (!ch)
376 return ERR_PTR(-ENOMEM); 376 return -ENOMEM;
377 377
378 ch->base = base; 378 ch->base = base;
379 if (ch_flags & BERLIN2_AVPLL_SCRAMBLE_QUIRK) 379 if (ch_flags & BERLIN2_AVPLL_SCRAMBLE_QUIRK)
@@ -389,5 +389,5 @@ struct clk * __init berlin2_avpll_channel_register(void __iomem *base,
389 init.num_parents = 1; 389 init.num_parents = 1;
390 init.flags = flags; 390 init.flags = flags;
391 391
392 return clk_register(NULL, &ch->hw); 392 return clk_hw_register(NULL, &ch->hw);
393} 393}
diff --git a/drivers/clk/berlin/berlin2-avpll.h b/drivers/clk/berlin/berlin2-avpll.h
index a37f5068d299..17e311153b42 100644
--- a/drivers/clk/berlin/berlin2-avpll.h
+++ b/drivers/clk/berlin/berlin2-avpll.h
@@ -19,17 +19,13 @@
19#ifndef __BERLIN2_AVPLL_H 19#ifndef __BERLIN2_AVPLL_H
20#define __BERLIN2_AVPLL_H 20#define __BERLIN2_AVPLL_H
21 21
22struct clk;
23
24#define BERLIN2_AVPLL_BIT_QUIRK BIT(0) 22#define BERLIN2_AVPLL_BIT_QUIRK BIT(0)
25#define BERLIN2_AVPLL_SCRAMBLE_QUIRK BIT(1) 23#define BERLIN2_AVPLL_SCRAMBLE_QUIRK BIT(1)
26 24
27struct clk * __init 25int berlin2_avpll_vco_register(void __iomem *base, const char *name,
28berlin2_avpll_vco_register(void __iomem *base, const char *name,
29 const char *parent_name, u8 vco_flags, unsigned long flags); 26 const char *parent_name, u8 vco_flags, unsigned long flags);
30 27
31struct clk * __init 28int berlin2_avpll_channel_register(void __iomem *base, const char *name,
32berlin2_avpll_channel_register(void __iomem *base, const char *name,
33 u8 index, const char *parent_name, u8 ch_flags, 29 u8 index, const char *parent_name, u8 ch_flags,
34 unsigned long flags); 30 unsigned long flags);
35 31
diff --git a/drivers/clk/berlin/berlin2-div.c b/drivers/clk/berlin/berlin2-div.c
index 81ff97f8aa0b..41ab2d392c57 100644
--- a/drivers/clk/berlin/berlin2-div.c
+++ b/drivers/clk/berlin/berlin2-div.c
@@ -234,7 +234,7 @@ static const struct clk_ops berlin2_div_mux_ops = {
234 .get_parent = berlin2_div_get_parent, 234 .get_parent = berlin2_div_get_parent,
235}; 235};
236 236
237struct clk * __init 237struct clk_hw * __init
238berlin2_div_register(const struct berlin2_div_map *map, 238berlin2_div_register(const struct berlin2_div_map *map,
239 void __iomem *base, const char *name, u8 div_flags, 239 void __iomem *base, const char *name, u8 div_flags,
240 const char **parent_names, int num_parents, 240 const char **parent_names, int num_parents,
@@ -259,7 +259,7 @@ berlin2_div_register(const struct berlin2_div_map *map,
259 if ((div_flags & BERLIN2_DIV_HAS_MUX) == 0) 259 if ((div_flags & BERLIN2_DIV_HAS_MUX) == 0)
260 mux_ops = NULL; 260 mux_ops = NULL;
261 261
262 return clk_register_composite(NULL, name, parent_names, num_parents, 262 return clk_hw_register_composite(NULL, name, parent_names, num_parents,
263 &div->hw, mux_ops, &div->hw, rate_ops, 263 &div->hw, mux_ops, &div->hw, rate_ops,
264 &div->hw, gate_ops, flags); 264 &div->hw, gate_ops, flags);
265} 265}
diff --git a/drivers/clk/berlin/berlin2-div.h b/drivers/clk/berlin/berlin2-div.h
index 15e3384f3116..e835ddf8374a 100644
--- a/drivers/clk/berlin/berlin2-div.h
+++ b/drivers/clk/berlin/berlin2-div.h
@@ -19,7 +19,7 @@
19#ifndef __BERLIN2_DIV_H 19#ifndef __BERLIN2_DIV_H
20#define __BERLIN2_DIV_H 20#define __BERLIN2_DIV_H
21 21
22struct clk; 22struct clk_hw;
23 23
24#define BERLIN2_DIV_HAS_GATE BIT(0) 24#define BERLIN2_DIV_HAS_GATE BIT(0)
25#define BERLIN2_DIV_HAS_MUX BIT(1) 25#define BERLIN2_DIV_HAS_MUX BIT(1)
@@ -80,7 +80,7 @@ struct berlin2_div_data {
80 u8 div_flags; 80 u8 div_flags;
81}; 81};
82 82
83struct clk * __init 83struct clk_hw *
84berlin2_div_register(const struct berlin2_div_map *map, 84berlin2_div_register(const struct berlin2_div_map *map,
85 void __iomem *base, const char *name, u8 div_flags, 85 void __iomem *base, const char *name, u8 div_flags,
86 const char **parent_names, int num_parents, 86 const char **parent_names, int num_parents,
diff --git a/drivers/clk/berlin/berlin2-pll.c b/drivers/clk/berlin/berlin2-pll.c
index 1c2294d3ba85..4ffbe80f6323 100644
--- a/drivers/clk/berlin/berlin2-pll.c
+++ b/drivers/clk/berlin/berlin2-pll.c
@@ -84,7 +84,7 @@ static const struct clk_ops berlin2_pll_ops = {
84 .recalc_rate = berlin2_pll_recalc_rate, 84 .recalc_rate = berlin2_pll_recalc_rate,
85}; 85};
86 86
87struct clk * __init 87int __init
88berlin2_pll_register(const struct berlin2_pll_map *map, 88berlin2_pll_register(const struct berlin2_pll_map *map,
89 void __iomem *base, const char *name, 89 void __iomem *base, const char *name,
90 const char *parent_name, unsigned long flags) 90 const char *parent_name, unsigned long flags)
@@ -94,7 +94,7 @@ berlin2_pll_register(const struct berlin2_pll_map *map,
94 94
95 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 95 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
96 if (!pll) 96 if (!pll)
97 return ERR_PTR(-ENOMEM); 97 return -ENOMEM;
98 98
99 /* copy pll_map to allow __initconst */ 99 /* copy pll_map to allow __initconst */
100 memcpy(&pll->map, map, sizeof(*map)); 100 memcpy(&pll->map, map, sizeof(*map));
@@ -106,5 +106,5 @@ berlin2_pll_register(const struct berlin2_pll_map *map,
106 init.num_parents = 1; 106 init.num_parents = 1;
107 init.flags = flags; 107 init.flags = flags;
108 108
109 return clk_register(NULL, &pll->hw); 109 return clk_hw_register(NULL, &pll->hw);
110} 110}
diff --git a/drivers/clk/berlin/berlin2-pll.h b/drivers/clk/berlin/berlin2-pll.h
index 8831ce27ac1e..583e024b9bed 100644
--- a/drivers/clk/berlin/berlin2-pll.h
+++ b/drivers/clk/berlin/berlin2-pll.h
@@ -19,8 +19,6 @@
19#ifndef __BERLIN2_PLL_H 19#ifndef __BERLIN2_PLL_H
20#define __BERLIN2_PLL_H 20#define __BERLIN2_PLL_H
21 21
22struct clk;
23
24struct berlin2_pll_map { 22struct berlin2_pll_map {
25 const u8 vcodiv[16]; 23 const u8 vcodiv[16];
26 u8 mult; 24 u8 mult;
@@ -29,9 +27,8 @@ struct berlin2_pll_map {
29 u8 divsel_shift; 27 u8 divsel_shift;
30}; 28};
31 29
32struct clk * __init 30int berlin2_pll_register(const struct berlin2_pll_map *map,
33berlin2_pll_register(const struct berlin2_pll_map *map, 31 void __iomem *base, const char *name,
34 void __iomem *base, const char *name, 32 const char *parent_name, unsigned long flags);
35 const char *parent_name, unsigned long flags);
36 33
37#endif /* __BERLIN2_PLL_H */ 34#endif /* __BERLIN2_PLL_H */
diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c
index 23e0e3be6c37..edf3b96b3b73 100644
--- a/drivers/clk/berlin/bg2.c
+++ b/drivers/clk/berlin/bg2.c
@@ -92,8 +92,7 @@
92 */ 92 */
93 93
94#define MAX_CLKS 41 94#define MAX_CLKS 41
95static struct clk *clks[MAX_CLKS]; 95static struct clk_hw_onecell_data *clk_data;
96static struct clk_onecell_data clk_data;
97static DEFINE_SPINLOCK(lock); 96static DEFINE_SPINLOCK(lock);
98static void __iomem *gbase; 97static void __iomem *gbase;
99 98
@@ -505,8 +504,17 @@ static void __init berlin2_clock_setup(struct device_node *np)
505 struct device_node *parent_np = of_get_parent(np); 504 struct device_node *parent_np = of_get_parent(np);
506 const char *parent_names[9]; 505 const char *parent_names[9];
507 struct clk *clk; 506 struct clk *clk;
507 struct clk_hw *hw;
508 struct clk_hw **hws;
508 u8 avpll_flags = 0; 509 u8 avpll_flags = 0;
509 int n; 510 int n, ret;
511
512 clk_data = kzalloc(sizeof(*clk_data) +
513 sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL);
514 if (!clk_data)
515 return;
516 clk_data->num = MAX_CLKS;
517 hws = clk_data->hws;
510 518
511 gbase = of_iomap(parent_np, 0); 519 gbase = of_iomap(parent_np, 0);
512 if (!gbase) 520 if (!gbase)
@@ -526,118 +534,118 @@ static void __init berlin2_clock_setup(struct device_node *np)
526 } 534 }
527 535
528 /* simple register PLLs */ 536 /* simple register PLLs */
529 clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_SYSPLLCTL0, 537 ret = berlin2_pll_register(&bg2_pll_map, gbase + REG_SYSPLLCTL0,
530 clk_names[SYSPLL], clk_names[REFCLK], 0); 538 clk_names[SYSPLL], clk_names[REFCLK], 0);
531 if (IS_ERR(clk)) 539 if (ret)
532 goto bg2_fail; 540 goto bg2_fail;
533 541
534 clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_MEMPLLCTL0, 542 ret = berlin2_pll_register(&bg2_pll_map, gbase + REG_MEMPLLCTL0,
535 clk_names[MEMPLL], clk_names[REFCLK], 0); 543 clk_names[MEMPLL], clk_names[REFCLK], 0);
536 if (IS_ERR(clk)) 544 if (ret)
537 goto bg2_fail; 545 goto bg2_fail;
538 546
539 clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_CPUPLLCTL0, 547 ret = berlin2_pll_register(&bg2_pll_map, gbase + REG_CPUPLLCTL0,
540 clk_names[CPUPLL], clk_names[REFCLK], 0); 548 clk_names[CPUPLL], clk_names[REFCLK], 0);
541 if (IS_ERR(clk)) 549 if (ret)
542 goto bg2_fail; 550 goto bg2_fail;
543 551
544 if (of_device_is_compatible(np, "marvell,berlin2-global-register")) 552 if (of_device_is_compatible(np, "marvell,berlin2-global-register"))
545 avpll_flags |= BERLIN2_AVPLL_SCRAMBLE_QUIRK; 553 avpll_flags |= BERLIN2_AVPLL_SCRAMBLE_QUIRK;
546 554
547 /* audio/video VCOs */ 555 /* audio/video VCOs */
548 clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL0, "avpll_vcoA", 556 ret = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL0, "avpll_vcoA",
549 clk_names[REFCLK], avpll_flags, 0); 557 clk_names[REFCLK], avpll_flags, 0);
550 if (IS_ERR(clk)) 558 if (ret)
551 goto bg2_fail; 559 goto bg2_fail;
552 560
553 for (n = 0; n < 8; n++) { 561 for (n = 0; n < 8; n++) {
554 clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL0, 562 ret = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL0,
555 clk_names[AVPLL_A1 + n], n, "avpll_vcoA", 563 clk_names[AVPLL_A1 + n], n, "avpll_vcoA",
556 avpll_flags, 0); 564 avpll_flags, 0);
557 if (IS_ERR(clk)) 565 if (ret)
558 goto bg2_fail; 566 goto bg2_fail;
559 } 567 }
560 568
561 clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL31, "avpll_vcoB", 569 ret = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL31, "avpll_vcoB",
562 clk_names[REFCLK], BERLIN2_AVPLL_BIT_QUIRK | 570 clk_names[REFCLK], BERLIN2_AVPLL_BIT_QUIRK |
563 avpll_flags, 0); 571 avpll_flags, 0);
564 if (IS_ERR(clk)) 572 if (ret)
565 goto bg2_fail; 573 goto bg2_fail;
566 574
567 for (n = 0; n < 8; n++) { 575 for (n = 0; n < 8; n++) {
568 clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL31, 576 ret = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL31,
569 clk_names[AVPLL_B1 + n], n, "avpll_vcoB", 577 clk_names[AVPLL_B1 + n], n, "avpll_vcoB",
570 BERLIN2_AVPLL_BIT_QUIRK | avpll_flags, 0); 578 BERLIN2_AVPLL_BIT_QUIRK | avpll_flags, 0);
571 if (IS_ERR(clk)) 579 if (ret)
572 goto bg2_fail; 580 goto bg2_fail;
573 } 581 }
574 582
575 /* reference clock bypass switches */ 583 /* reference clock bypass switches */
576 parent_names[0] = clk_names[SYSPLL]; 584 parent_names[0] = clk_names[SYSPLL];
577 parent_names[1] = clk_names[REFCLK]; 585 parent_names[1] = clk_names[REFCLK];
578 clk = clk_register_mux(NULL, "syspll_byp", parent_names, 2, 586 hw = clk_hw_register_mux(NULL, "syspll_byp", parent_names, 2,
579 0, gbase + REG_CLKSWITCH0, 0, 1, 0, &lock); 587 0, gbase + REG_CLKSWITCH0, 0, 1, 0, &lock);
580 if (IS_ERR(clk)) 588 if (IS_ERR(hw))
581 goto bg2_fail; 589 goto bg2_fail;
582 clk_names[SYSPLL] = __clk_get_name(clk); 590 clk_names[SYSPLL] = clk_hw_get_name(hw);
583 591
584 parent_names[0] = clk_names[MEMPLL]; 592 parent_names[0] = clk_names[MEMPLL];
585 parent_names[1] = clk_names[REFCLK]; 593 parent_names[1] = clk_names[REFCLK];
586 clk = clk_register_mux(NULL, "mempll_byp", parent_names, 2, 594 hw = clk_hw_register_mux(NULL, "mempll_byp", parent_names, 2,
587 0, gbase + REG_CLKSWITCH0, 1, 1, 0, &lock); 595 0, gbase + REG_CLKSWITCH0, 1, 1, 0, &lock);
588 if (IS_ERR(clk)) 596 if (IS_ERR(hw))
589 goto bg2_fail; 597 goto bg2_fail;
590 clk_names[MEMPLL] = __clk_get_name(clk); 598 clk_names[MEMPLL] = clk_hw_get_name(hw);
591 599
592 parent_names[0] = clk_names[CPUPLL]; 600 parent_names[0] = clk_names[CPUPLL];
593 parent_names[1] = clk_names[REFCLK]; 601 parent_names[1] = clk_names[REFCLK];
594 clk = clk_register_mux(NULL, "cpupll_byp", parent_names, 2, 602 hw = clk_hw_register_mux(NULL, "cpupll_byp", parent_names, 2,
595 0, gbase + REG_CLKSWITCH0, 2, 1, 0, &lock); 603 0, gbase + REG_CLKSWITCH0, 2, 1, 0, &lock);
596 if (IS_ERR(clk)) 604 if (IS_ERR(hw))
597 goto bg2_fail; 605 goto bg2_fail;
598 clk_names[CPUPLL] = __clk_get_name(clk); 606 clk_names[CPUPLL] = clk_hw_get_name(hw);
599 607
600 /* clock muxes */ 608 /* clock muxes */
601 parent_names[0] = clk_names[AVPLL_B3]; 609 parent_names[0] = clk_names[AVPLL_B3];
602 parent_names[1] = clk_names[AVPLL_A3]; 610 parent_names[1] = clk_names[AVPLL_A3];
603 clk = clk_register_mux(NULL, clk_names[AUDIO1_PLL], parent_names, 2, 611 hw = clk_hw_register_mux(NULL, clk_names[AUDIO1_PLL], parent_names, 2,
604 0, gbase + REG_CLKSELECT2, 29, 1, 0, &lock); 612 0, gbase + REG_CLKSELECT2, 29, 1, 0, &lock);
605 if (IS_ERR(clk)) 613 if (IS_ERR(hw))
606 goto bg2_fail; 614 goto bg2_fail;
607 615
608 parent_names[0] = clk_names[VIDEO0_PLL]; 616 parent_names[0] = clk_names[VIDEO0_PLL];
609 parent_names[1] = clk_names[VIDEO_EXT0]; 617 parent_names[1] = clk_names[VIDEO_EXT0];
610 clk = clk_register_mux(NULL, clk_names[VIDEO0_IN], parent_names, 2, 618 hw = clk_hw_register_mux(NULL, clk_names[VIDEO0_IN], parent_names, 2,
611 0, gbase + REG_CLKSELECT3, 4, 1, 0, &lock); 619 0, gbase + REG_CLKSELECT3, 4, 1, 0, &lock);
612 if (IS_ERR(clk)) 620 if (IS_ERR(hw))
613 goto bg2_fail; 621 goto bg2_fail;
614 622
615 parent_names[0] = clk_names[VIDEO1_PLL]; 623 parent_names[0] = clk_names[VIDEO1_PLL];
616 parent_names[1] = clk_names[VIDEO_EXT0]; 624 parent_names[1] = clk_names[VIDEO_EXT0];
617 clk = clk_register_mux(NULL, clk_names[VIDEO1_IN], parent_names, 2, 625 hw = clk_hw_register_mux(NULL, clk_names[VIDEO1_IN], parent_names, 2,
618 0, gbase + REG_CLKSELECT3, 6, 1, 0, &lock); 626 0, gbase + REG_CLKSELECT3, 6, 1, 0, &lock);
619 if (IS_ERR(clk)) 627 if (IS_ERR(hw))
620 goto bg2_fail; 628 goto bg2_fail;
621 629
622 parent_names[0] = clk_names[AVPLL_A2]; 630 parent_names[0] = clk_names[AVPLL_A2];
623 parent_names[1] = clk_names[AVPLL_B2]; 631 parent_names[1] = clk_names[AVPLL_B2];
624 clk = clk_register_mux(NULL, clk_names[VIDEO1_PLL], parent_names, 2, 632 hw = clk_hw_register_mux(NULL, clk_names[VIDEO1_PLL], parent_names, 2,
625 0, gbase + REG_CLKSELECT3, 7, 1, 0, &lock); 633 0, gbase + REG_CLKSELECT3, 7, 1, 0, &lock);
626 if (IS_ERR(clk)) 634 if (IS_ERR(hw))
627 goto bg2_fail; 635 goto bg2_fail;
628 636
629 parent_names[0] = clk_names[VIDEO2_PLL]; 637 parent_names[0] = clk_names[VIDEO2_PLL];
630 parent_names[1] = clk_names[VIDEO_EXT0]; 638 parent_names[1] = clk_names[VIDEO_EXT0];
631 clk = clk_register_mux(NULL, clk_names[VIDEO2_IN], parent_names, 2, 639 hw = clk_hw_register_mux(NULL, clk_names[VIDEO2_IN], parent_names, 2,
632 0, gbase + REG_CLKSELECT3, 9, 1, 0, &lock); 640 0, gbase + REG_CLKSELECT3, 9, 1, 0, &lock);
633 if (IS_ERR(clk)) 641 if (IS_ERR(hw))
634 goto bg2_fail; 642 goto bg2_fail;
635 643
636 parent_names[0] = clk_names[AVPLL_B1]; 644 parent_names[0] = clk_names[AVPLL_B1];
637 parent_names[1] = clk_names[AVPLL_A5]; 645 parent_names[1] = clk_names[AVPLL_A5];
638 clk = clk_register_mux(NULL, clk_names[VIDEO2_PLL], parent_names, 2, 646 hw = clk_hw_register_mux(NULL, clk_names[VIDEO2_PLL], parent_names, 2,
639 0, gbase + REG_CLKSELECT3, 10, 1, 0, &lock); 647 0, gbase + REG_CLKSELECT3, 10, 1, 0, &lock);
640 if (IS_ERR(clk)) 648 if (IS_ERR(hw))
641 goto bg2_fail; 649 goto bg2_fail;
642 650
643 /* clock divider cells */ 651 /* clock divider cells */
@@ -648,7 +656,7 @@ static void __init berlin2_clock_setup(struct device_node *np)
648 for (k = 0; k < dd->num_parents; k++) 656 for (k = 0; k < dd->num_parents; k++)
649 parent_names[k] = clk_names[dd->parent_ids[k]]; 657 parent_names[k] = clk_names[dd->parent_ids[k]];
650 658
651 clks[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase, 659 hws[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase,
652 dd->name, dd->div_flags, parent_names, 660 dd->name, dd->div_flags, parent_names,
653 dd->num_parents, dd->flags, &lock); 661 dd->num_parents, dd->flags, &lock);
654 } 662 }
@@ -657,18 +665,18 @@ static void __init berlin2_clock_setup(struct device_node *np)
657 for (n = 0; n < ARRAY_SIZE(bg2_gates); n++) { 665 for (n = 0; n < ARRAY_SIZE(bg2_gates); n++) {
658 const struct berlin2_gate_data *gd = &bg2_gates[n]; 666 const struct berlin2_gate_data *gd = &bg2_gates[n];
659 667
660 clks[CLKID_GETH0 + n] = clk_register_gate(NULL, gd->name, 668 hws[CLKID_GETH0 + n] = clk_hw_register_gate(NULL, gd->name,
661 gd->parent_name, gd->flags, gbase + REG_CLKENABLE, 669 gd->parent_name, gd->flags, gbase + REG_CLKENABLE,
662 gd->bit_idx, 0, &lock); 670 gd->bit_idx, 0, &lock);
663 } 671 }
664 672
665 /* twdclk is derived from cpu/3 */ 673 /* twdclk is derived from cpu/3 */
666 clks[CLKID_TWD] = 674 hws[CLKID_TWD] =
667 clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3); 675 clk_hw_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
668 676
669 /* check for errors on leaf clocks */ 677 /* check for errors on leaf clocks */
670 for (n = 0; n < MAX_CLKS; n++) { 678 for (n = 0; n < MAX_CLKS; n++) {
671 if (!IS_ERR(clks[n])) 679 if (!IS_ERR(hws[n]))
672 continue; 680 continue;
673 681
674 pr_err("%s: Unable to register leaf clock %d\n", 682 pr_err("%s: Unable to register leaf clock %d\n",
@@ -677,9 +685,7 @@ static void __init berlin2_clock_setup(struct device_node *np)
677 } 685 }
678 686
679 /* register clk-provider */ 687 /* register clk-provider */
680 clk_data.clks = clks; 688 of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data);
681 clk_data.clk_num = MAX_CLKS;
682 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
683 689
684 return; 690 return;
685 691
diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c
index f144547cf76c..0718e831475f 100644
--- a/drivers/clk/berlin/bg2q.c
+++ b/drivers/clk/berlin/bg2q.c
@@ -46,8 +46,7 @@
46#define REG_SDIO1XIN_CLKCTL 0x015c 46#define REG_SDIO1XIN_CLKCTL 0x015c
47 47
48#define MAX_CLKS 28 48#define MAX_CLKS 28
49static struct clk *clks[MAX_CLKS]; 49static struct clk_hw_onecell_data *clk_data;
50static struct clk_onecell_data clk_data;
51static DEFINE_SPINLOCK(lock); 50static DEFINE_SPINLOCK(lock);
52static void __iomem *gbase; 51static void __iomem *gbase;
53static void __iomem *cpupll_base; 52static void __iomem *cpupll_base;
@@ -293,7 +292,15 @@ static void __init berlin2q_clock_setup(struct device_node *np)
293 struct device_node *parent_np = of_get_parent(np); 292 struct device_node *parent_np = of_get_parent(np);
294 const char *parent_names[9]; 293 const char *parent_names[9];
295 struct clk *clk; 294 struct clk *clk;
296 int n; 295 struct clk_hw **hws;
296 int n, ret;
297
298 clk_data = kzalloc(sizeof(*clk_data) +
299 sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL);
300 if (!clk_data)
301 return;
302 clk_data->num = MAX_CLKS;
303 hws = clk_data->hws;
297 304
298 gbase = of_iomap(parent_np, 0); 305 gbase = of_iomap(parent_np, 0);
299 if (!gbase) { 306 if (!gbase) {
@@ -317,14 +324,14 @@ static void __init berlin2q_clock_setup(struct device_node *np)
317 } 324 }
318 325
319 /* simple register PLLs */ 326 /* simple register PLLs */
320 clk = berlin2_pll_register(&bg2q_pll_map, gbase + REG_SYSPLLCTL0, 327 ret = berlin2_pll_register(&bg2q_pll_map, gbase + REG_SYSPLLCTL0,
321 clk_names[SYSPLL], clk_names[REFCLK], 0); 328 clk_names[SYSPLL], clk_names[REFCLK], 0);
322 if (IS_ERR(clk)) 329 if (ret)
323 goto bg2q_fail; 330 goto bg2q_fail;
324 331
325 clk = berlin2_pll_register(&bg2q_pll_map, cpupll_base, 332 ret = berlin2_pll_register(&bg2q_pll_map, cpupll_base,
326 clk_names[CPUPLL], clk_names[REFCLK], 0); 333 clk_names[CPUPLL], clk_names[REFCLK], 0);
327 if (IS_ERR(clk)) 334 if (ret)
328 goto bg2q_fail; 335 goto bg2q_fail;
329 336
330 /* TODO: add BG2Q AVPLL */ 337 /* TODO: add BG2Q AVPLL */
@@ -342,7 +349,7 @@ static void __init berlin2q_clock_setup(struct device_node *np)
342 for (k = 0; k < dd->num_parents; k++) 349 for (k = 0; k < dd->num_parents; k++)
343 parent_names[k] = clk_names[dd->parent_ids[k]]; 350 parent_names[k] = clk_names[dd->parent_ids[k]];
344 351
345 clks[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase, 352 hws[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase,
346 dd->name, dd->div_flags, parent_names, 353 dd->name, dd->div_flags, parent_names,
347 dd->num_parents, dd->flags, &lock); 354 dd->num_parents, dd->flags, &lock);
348 } 355 }
@@ -351,22 +358,22 @@ static void __init berlin2q_clock_setup(struct device_node *np)
351 for (n = 0; n < ARRAY_SIZE(bg2q_gates); n++) { 358 for (n = 0; n < ARRAY_SIZE(bg2q_gates); n++) {
352 const struct berlin2_gate_data *gd = &bg2q_gates[n]; 359 const struct berlin2_gate_data *gd = &bg2q_gates[n];
353 360
354 clks[CLKID_GFX2DAXI + n] = clk_register_gate(NULL, gd->name, 361 hws[CLKID_GFX2DAXI + n] = clk_hw_register_gate(NULL, gd->name,
355 gd->parent_name, gd->flags, gbase + REG_CLKENABLE, 362 gd->parent_name, gd->flags, gbase + REG_CLKENABLE,
356 gd->bit_idx, 0, &lock); 363 gd->bit_idx, 0, &lock);
357 } 364 }
358 365
359 /* cpuclk divider is fixed to 1 */ 366 /* cpuclk divider is fixed to 1 */
360 clks[CLKID_CPU] = 367 hws[CLKID_CPU] =
361 clk_register_fixed_factor(NULL, "cpu", clk_names[CPUPLL], 368 clk_hw_register_fixed_factor(NULL, "cpu", clk_names[CPUPLL],
362 0, 1, 1); 369 0, 1, 1);
363 /* twdclk is derived from cpu/3 */ 370 /* twdclk is derived from cpu/3 */
364 clks[CLKID_TWD] = 371 hws[CLKID_TWD] =
365 clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3); 372 clk_hw_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
366 373
367 /* check for errors on leaf clocks */ 374 /* check for errors on leaf clocks */
368 for (n = 0; n < MAX_CLKS; n++) { 375 for (n = 0; n < MAX_CLKS; n++) {
369 if (!IS_ERR(clks[n])) 376 if (!IS_ERR(hws[n]))
370 continue; 377 continue;
371 378
372 pr_err("%s: Unable to register leaf clock %d\n", 379 pr_err("%s: Unable to register leaf clock %d\n",
@@ -375,9 +382,7 @@ static void __init berlin2q_clock_setup(struct device_node *np)
375 } 382 }
376 383
377 /* register clk-provider */ 384 /* register clk-provider */
378 clk_data.clks = clks; 385 of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data);
379 clk_data.clk_num = MAX_CLKS;
380 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
381 386
382 return; 387 return;
383 388
diff --git a/drivers/clk/clk-asm9260.c b/drivers/clk/clk-asm9260.c
index 90897af8d9f7..ea8568536193 100644
--- a/drivers/clk/clk-asm9260.c
+++ b/drivers/clk/clk-asm9260.c
@@ -68,8 +68,7 @@
68#define HW_LCDCLKDIV 0x01fc 68#define HW_LCDCLKDIV 0x01fc
69#define HW_ADCANACLKDIV 0x0200 69#define HW_ADCANACLKDIV 0x0200
70 70
71static struct clk *clks[MAX_CLKS]; 71static struct clk_hw_onecell_data *clk_data;
72static struct clk_onecell_data clk_data;
73static DEFINE_SPINLOCK(asm9260_clk_lock); 72static DEFINE_SPINLOCK(asm9260_clk_lock);
74 73
75struct asm9260_div_clk { 74struct asm9260_div_clk {
@@ -267,12 +266,20 @@ static struct asm9260_mux_clock asm9260_mux_clks[] __initdata = {
267 266
268static void __init asm9260_acc_init(struct device_node *np) 267static void __init asm9260_acc_init(struct device_node *np)
269{ 268{
270 struct clk *clk; 269 struct clk_hw *hw;
270 struct clk_hw **hws;
271 const char *ref_clk, *pll_clk = "pll"; 271 const char *ref_clk, *pll_clk = "pll";
272 u32 rate; 272 u32 rate;
273 int n; 273 int n;
274 u32 accuracy = 0; 274 u32 accuracy = 0;
275 275
276 clk_data = kzalloc(sizeof(*clk_data) +
277 sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL);
278 if (!clk_data)
279 return;
280 clk_data->num = MAX_CLKS;
281 hws = clk_data->hws;
282
276 base = of_io_request_and_map(np, 0, np->name); 283 base = of_io_request_and_map(np, 0, np->name);
277 if (IS_ERR(base)) 284 if (IS_ERR(base))
278 panic("%s: unable to map resource", np->name); 285 panic("%s: unable to map resource", np->name);
@@ -282,10 +289,10 @@ static void __init asm9260_acc_init(struct device_node *np)
282 289
283 ref_clk = of_clk_get_parent_name(np, 0); 290 ref_clk = of_clk_get_parent_name(np, 0);
284 accuracy = clk_get_accuracy(__clk_lookup(ref_clk)); 291 accuracy = clk_get_accuracy(__clk_lookup(ref_clk));
285 clk = clk_register_fixed_rate_with_accuracy(NULL, pll_clk, 292 hw = clk_hw_register_fixed_rate_with_accuracy(NULL, pll_clk,
286 ref_clk, 0, rate, accuracy); 293 ref_clk, 0, rate, accuracy);
287 294
288 if (IS_ERR(clk)) 295 if (IS_ERR(hw))
289 panic("%s: can't register REFCLK. Check DT!", np->name); 296 panic("%s: can't register REFCLK. Check DT!", np->name);
290 297
291 for (n = 0; n < ARRAY_SIZE(asm9260_mux_clks); n++) { 298 for (n = 0; n < ARRAY_SIZE(asm9260_mux_clks); n++) {
@@ -293,7 +300,7 @@ static void __init asm9260_acc_init(struct device_node *np)
293 300
294 mc->parent_names[0] = ref_clk; 301 mc->parent_names[0] = ref_clk;
295 mc->parent_names[1] = pll_clk; 302 mc->parent_names[1] = pll_clk;
296 clk = clk_register_mux_table(NULL, mc->name, mc->parent_names, 303 hw = clk_hw_register_mux_table(NULL, mc->name, mc->parent_names,
297 mc->num_parents, mc->flags, base + mc->offset, 304 mc->num_parents, mc->flags, base + mc->offset,
298 0, mc->mask, 0, mc->table, &asm9260_clk_lock); 305 0, mc->mask, 0, mc->table, &asm9260_clk_lock);
299 } 306 }
@@ -302,7 +309,7 @@ static void __init asm9260_acc_init(struct device_node *np)
302 for (n = 0; n < ARRAY_SIZE(asm9260_mux_gates); n++) { 309 for (n = 0; n < ARRAY_SIZE(asm9260_mux_gates); n++) {
303 const struct asm9260_gate_data *gd = &asm9260_mux_gates[n]; 310 const struct asm9260_gate_data *gd = &asm9260_mux_gates[n];
304 311
305 clk = clk_register_gate(NULL, gd->name, 312 hw = clk_hw_register_gate(NULL, gd->name,
306 gd->parent_name, gd->flags | CLK_SET_RATE_PARENT, 313 gd->parent_name, gd->flags | CLK_SET_RATE_PARENT,
307 base + gd->reg, gd->bit_idx, 0, &asm9260_clk_lock); 314 base + gd->reg, gd->bit_idx, 0, &asm9260_clk_lock);
308 } 315 }
@@ -311,7 +318,7 @@ static void __init asm9260_acc_init(struct device_node *np)
311 for (n = 0; n < ARRAY_SIZE(asm9260_div_clks); n++) { 318 for (n = 0; n < ARRAY_SIZE(asm9260_div_clks); n++) {
312 const struct asm9260_div_clk *dc = &asm9260_div_clks[n]; 319 const struct asm9260_div_clk *dc = &asm9260_div_clks[n];
313 320
314 clks[dc->idx] = clk_register_divider(NULL, dc->name, 321 hws[dc->idx] = clk_hw_register_divider(NULL, dc->name,
315 dc->parent_name, CLK_SET_RATE_PARENT, 322 dc->parent_name, CLK_SET_RATE_PARENT,
316 base + dc->reg, 0, 8, CLK_DIVIDER_ONE_BASED, 323 base + dc->reg, 0, 8, CLK_DIVIDER_ONE_BASED,
317 &asm9260_clk_lock); 324 &asm9260_clk_lock);
@@ -321,14 +328,14 @@ static void __init asm9260_acc_init(struct device_node *np)
321 for (n = 0; n < ARRAY_SIZE(asm9260_ahb_gates); n++) { 328 for (n = 0; n < ARRAY_SIZE(asm9260_ahb_gates); n++) {
322 const struct asm9260_gate_data *gd = &asm9260_ahb_gates[n]; 329 const struct asm9260_gate_data *gd = &asm9260_ahb_gates[n];
323 330
324 clks[gd->idx] = clk_register_gate(NULL, gd->name, 331 hws[gd->idx] = clk_hw_register_gate(NULL, gd->name,
325 gd->parent_name, gd->flags, base + gd->reg, 332 gd->parent_name, gd->flags, base + gd->reg,
326 gd->bit_idx, 0, &asm9260_clk_lock); 333 gd->bit_idx, 0, &asm9260_clk_lock);
327 } 334 }
328 335
329 /* check for errors on leaf clocks */ 336 /* check for errors on leaf clocks */
330 for (n = 0; n < MAX_CLKS; n++) { 337 for (n = 0; n < MAX_CLKS; n++) {
331 if (!IS_ERR(clks[n])) 338 if (!IS_ERR(hws[n]))
332 continue; 339 continue;
333 340
334 pr_err("%s: Unable to register leaf clock %d\n", 341 pr_err("%s: Unable to register leaf clock %d\n",
@@ -337,9 +344,7 @@ static void __init asm9260_acc_init(struct device_node *np)
337 } 344 }
338 345
339 /* register clk-provider */ 346 /* register clk-provider */
340 clk_data.clks = clks; 347 of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
341 clk_data.clk_num = MAX_CLKS;
342 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
343 return; 348 return;
344fail: 349fail:
345 iounmap(base); 350 iounmap(base);
diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c
index 3294db3b4e4e..5e918e7afaba 100644
--- a/drivers/clk/clk-axi-clkgen.c
+++ b/drivers/clk/clk-axi-clkgen.c
@@ -392,8 +392,8 @@ static int axi_clkgen_probe(struct platform_device *pdev)
392 const char *parent_names[2]; 392 const char *parent_names[2];
393 const char *clk_name; 393 const char *clk_name;
394 struct resource *mem; 394 struct resource *mem;
395 struct clk *clk;
396 unsigned int i; 395 unsigned int i;
396 int ret;
397 397
398 if (!pdev->dev.of_node) 398 if (!pdev->dev.of_node)
399 return -ENODEV; 399 return -ENODEV;
@@ -433,12 +433,12 @@ static int axi_clkgen_probe(struct platform_device *pdev)
433 axi_clkgen_mmcm_enable(axi_clkgen, false); 433 axi_clkgen_mmcm_enable(axi_clkgen, false);
434 434
435 axi_clkgen->clk_hw.init = &init; 435 axi_clkgen->clk_hw.init = &init;
436 clk = devm_clk_register(&pdev->dev, &axi_clkgen->clk_hw); 436 ret = devm_clk_hw_register(&pdev->dev, &axi_clkgen->clk_hw);
437 if (IS_ERR(clk)) 437 if (ret)
438 return PTR_ERR(clk); 438 return ret;
439 439
440 return of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get, 440 return of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_simple_get,
441 clk); 441 &axi_clkgen->clk_hw);
442} 442}
443 443
444static int axi_clkgen_remove(struct platform_device *pdev) 444static int axi_clkgen_remove(struct platform_device *pdev)
diff --git a/drivers/clk/clk-axm5516.c b/drivers/clk/clk-axm5516.c
index c7c91a5ecf8b..5d7ae333257e 100644
--- a/drivers/clk/clk-axm5516.c
+++ b/drivers/clk/clk-axm5516.c
@@ -516,6 +516,19 @@ static struct axxia_clk *axmclk_clocks[] = {
516 [AXXIA_CLK_MMC] = &clk_mmc_mux.aclk, 516 [AXXIA_CLK_MMC] = &clk_mmc_mux.aclk,
517}; 517};
518 518
519static struct clk_hw *
520of_clk_axmclk_get(struct of_phandle_args *clkspec, void *unused)
521{
522 unsigned int idx = clkspec->args[0];
523
524 if (idx >= ARRAY_SIZE(axmclk_clocks)) {
525 pr_err("%s: invalid index %u\n", __func__, idx);
526 return ERR_PTR(-EINVAL);
527 }
528
529 return &axmclk_clocks[idx]->hw;
530}
531
519static const struct regmap_config axmclk_regmap_config = { 532static const struct regmap_config axmclk_regmap_config = {
520 .reg_bits = 32, 533 .reg_bits = 32,
521 .reg_stride = 4, 534 .reg_stride = 4,
@@ -530,21 +543,14 @@ static const struct of_device_id axmclk_match_table[] = {
530}; 543};
531MODULE_DEVICE_TABLE(of, axmclk_match_table); 544MODULE_DEVICE_TABLE(of, axmclk_match_table);
532 545
533struct axmclk_priv {
534 struct clk_onecell_data onecell;
535 struct clk *clks[];
536};
537
538static int axmclk_probe(struct platform_device *pdev) 546static int axmclk_probe(struct platform_device *pdev)
539{ 547{
540 void __iomem *base; 548 void __iomem *base;
541 struct resource *res; 549 struct resource *res;
542 int i, ret; 550 int i, ret;
543 struct device *dev = &pdev->dev; 551 struct device *dev = &pdev->dev;
544 struct clk *clk;
545 struct regmap *regmap; 552 struct regmap *regmap;
546 size_t num_clks; 553 size_t num_clks;
547 struct axmclk_priv *priv;
548 554
549 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 555 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
550 base = devm_ioremap_resource(dev, res); 556 base = devm_ioremap_resource(dev, res);
@@ -557,29 +563,18 @@ static int axmclk_probe(struct platform_device *pdev)
557 563
558 num_clks = ARRAY_SIZE(axmclk_clocks); 564 num_clks = ARRAY_SIZE(axmclk_clocks);
559 pr_info("axmclk: supporting %zu clocks\n", num_clks); 565 pr_info("axmclk: supporting %zu clocks\n", num_clks);
560 priv = devm_kzalloc(dev, sizeof(*priv) + sizeof(*priv->clks) * num_clks,
561 GFP_KERNEL);
562 if (!priv)
563 return -ENOMEM;
564
565 priv->onecell.clks = priv->clks;
566 priv->onecell.clk_num = num_clks;
567 566
568 /* Update each entry with the allocated regmap and register the clock 567 /* Update each entry with the allocated regmap and register the clock
569 * with the common clock framework 568 * with the common clock framework
570 */ 569 */
571 for (i = 0; i < num_clks; i++) { 570 for (i = 0; i < num_clks; i++) {
572 axmclk_clocks[i]->regmap = regmap; 571 axmclk_clocks[i]->regmap = regmap;
573 clk = devm_clk_register(dev, &axmclk_clocks[i]->hw); 572 ret = devm_clk_hw_register(dev, &axmclk_clocks[i]->hw);
574 if (IS_ERR(clk)) 573 if (ret)
575 return PTR_ERR(clk); 574 return ret;
576 priv->clks[i] = clk;
577 } 575 }
578 576
579 ret = of_clk_add_provider(dev->of_node, 577 return of_clk_add_hw_provider(dev->of_node, of_clk_axmclk_get, NULL);
580 of_clk_src_onecell_get, &priv->onecell);
581
582 return ret;
583} 578}
584 579
585static int axmclk_remove(struct platform_device *pdev) 580static int axmclk_remove(struct platform_device *pdev)
diff --git a/drivers/clk/clk-cdce706.c b/drivers/clk/clk-cdce706.c
index 01877f64eff6..f21d9092564f 100644
--- a/drivers/clk/clk-cdce706.c
+++ b/drivers/clk/clk-cdce706.c
@@ -71,7 +71,6 @@ struct cdce706_hw_data {
71 struct cdce706_dev_data *dev_data; 71 struct cdce706_dev_data *dev_data;
72 unsigned idx; 72 unsigned idx;
73 unsigned parent; 73 unsigned parent;
74 struct clk *clk;
75 struct clk_hw hw; 74 struct clk_hw hw;
76 unsigned div; 75 unsigned div;
77 unsigned mul; 76 unsigned mul;
@@ -81,8 +80,6 @@ struct cdce706_hw_data {
81struct cdce706_dev_data { 80struct cdce706_dev_data {
82 struct i2c_client *client; 81 struct i2c_client *client;
83 struct regmap *regmap; 82 struct regmap *regmap;
84 struct clk_onecell_data onecell;
85 struct clk *clks[6];
86 struct clk *clkin_clk[2]; 83 struct clk *clkin_clk[2];
87 const char *clkin_name[2]; 84 const char *clkin_name[2];
88 struct cdce706_hw_data clkin[1]; 85 struct cdce706_hw_data clkin[1];
@@ -455,18 +452,19 @@ static int cdce706_register_hw(struct cdce706_dev_data *cdce,
455 struct clk_init_data *init) 452 struct clk_init_data *init)
456{ 453{
457 unsigned i; 454 unsigned i;
455 int ret;
458 456
459 for (i = 0; i < num_hw; ++i, ++hw) { 457 for (i = 0; i < num_hw; ++i, ++hw) {
460 init->name = clk_names[i]; 458 init->name = clk_names[i];
461 hw->dev_data = cdce; 459 hw->dev_data = cdce;
462 hw->idx = i; 460 hw->idx = i;
463 hw->hw.init = init; 461 hw->hw.init = init;
464 hw->clk = devm_clk_register(&cdce->client->dev, 462 ret = devm_clk_hw_register(&cdce->client->dev,
465 &hw->hw); 463 &hw->hw);
466 if (IS_ERR(hw->clk)) { 464 if (ret) {
467 dev_err(&cdce->client->dev, "Failed to register %s\n", 465 dev_err(&cdce->client->dev, "Failed to register %s\n",
468 clk_names[i]); 466 clk_names[i]);
469 return PTR_ERR(hw->clk); 467 return ret;
470 } 468 }
471 } 469 }
472 return 0; 470 return 0;
@@ -613,13 +611,23 @@ static int cdce706_register_clkouts(struct cdce706_dev_data *cdce)
613 cdce->clkout[i].parent); 611 cdce->clkout[i].parent);
614 } 612 }
615 613
616 ret = cdce706_register_hw(cdce, cdce->clkout, 614 return cdce706_register_hw(cdce, cdce->clkout,
617 ARRAY_SIZE(cdce->clkout), 615 ARRAY_SIZE(cdce->clkout),
618 cdce706_clkout_name, &init); 616 cdce706_clkout_name, &init);
619 for (i = 0; i < ARRAY_SIZE(cdce->clkout); ++i) 617}
620 cdce->clks[i] = cdce->clkout[i].clk;
621 618
622 return ret; 619static struct clk_hw *
620of_clk_cdce_get(struct of_phandle_args *clkspec, void *data)
621{
622 struct cdce706_dev_data *cdce = data;
623 unsigned int idx = clkspec->args[0];
624
625 if (idx >= ARRAY_SIZE(cdce->clkout)) {
626 pr_err("%s: invalid index %u\n", __func__, idx);
627 return ERR_PTR(-EINVAL);
628 }
629
630 return &cdce->clkout[idx].hw;
623} 631}
624 632
625static int cdce706_probe(struct i2c_client *client, 633static int cdce706_probe(struct i2c_client *client,
@@ -657,12 +665,8 @@ static int cdce706_probe(struct i2c_client *client,
657 ret = cdce706_register_clkouts(cdce); 665 ret = cdce706_register_clkouts(cdce);
658 if (ret < 0) 666 if (ret < 0)
659 return ret; 667 return ret;
660 cdce->onecell.clks = cdce->clks; 668 return of_clk_add_hw_provider(client->dev.of_node, of_clk_cdce_get,
661 cdce->onecell.clk_num = ARRAY_SIZE(cdce->clks); 669 cdce);
662 ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get,
663 &cdce->onecell);
664
665 return ret;
666} 670}
667 671
668static int cdce706_remove(struct i2c_client *client) 672static int cdce706_remove(struct i2c_client *client)
diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c
index 089bf88ffa8d..b8459c14a1b7 100644
--- a/drivers/clk/clk-cdce925.c
+++ b/drivers/clk/clk-cdce925.c
@@ -62,8 +62,6 @@ struct clk_cdce925_chip {
62 struct i2c_client *i2c_client; 62 struct i2c_client *i2c_client;
63 struct clk_cdce925_pll pll[NUMBER_OF_PLLS]; 63 struct clk_cdce925_pll pll[NUMBER_OF_PLLS];
64 struct clk_cdce925_output clk[NUMBER_OF_OUTPUTS]; 64 struct clk_cdce925_output clk[NUMBER_OF_OUTPUTS];
65 struct clk *dt_clk[NUMBER_OF_OUTPUTS];
66 struct clk_onecell_data onecell;
67}; 65};
68 66
69/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ 67/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
@@ -557,6 +555,20 @@ static int cdce925_regmap_i2c_read(void *context,
557 return -EIO; 555 return -EIO;
558} 556}
559 557
558static struct clk_hw *
559of_clk_cdce925_get(struct of_phandle_args *clkspec, void *_data)
560{
561 struct clk_cdce925_chip *data = _data;
562 unsigned int idx = clkspec->args[0];
563
564 if (idx >= ARRAY_SIZE(data->clk)) {
565 pr_err("%s: invalid index %u\n", __func__, idx);
566 return ERR_PTR(-EINVAL);
567 }
568
569 return &data->clk[idx].hw;
570}
571
560/* The CDCE925 uses a funky way to read/write registers. Bulk mode is 572/* The CDCE925 uses a funky way to read/write registers. Bulk mode is
561 * just weird, so just use the single byte mode exclusively. */ 573 * just weird, so just use the single byte mode exclusively. */
562static struct regmap_bus regmap_cdce925_bus = { 574static struct regmap_bus regmap_cdce925_bus = {
@@ -572,7 +584,6 @@ static int cdce925_probe(struct i2c_client *client,
572 const char *parent_name; 584 const char *parent_name;
573 const char *pll_clk_name[NUMBER_OF_PLLS] = {NULL,}; 585 const char *pll_clk_name[NUMBER_OF_PLLS] = {NULL,};
574 struct clk_init_data init; 586 struct clk_init_data init;
575 struct clk *clk;
576 u32 value; 587 u32 value;
577 int i; 588 int i;
578 int err; 589 int err;
@@ -622,10 +633,9 @@ static int cdce925_probe(struct i2c_client *client,
622 data->pll[i].chip = data; 633 data->pll[i].chip = data;
623 data->pll[i].hw.init = &init; 634 data->pll[i].hw.init = &init;
624 data->pll[i].index = i; 635 data->pll[i].index = i;
625 clk = devm_clk_register(&client->dev, &data->pll[i].hw); 636 err = devm_clk_hw_register(&client->dev, &data->pll[i].hw);
626 if (IS_ERR(clk)) { 637 if (err) {
627 dev_err(&client->dev, "Failed register PLL %d\n", i); 638 dev_err(&client->dev, "Failed register PLL %d\n", i);
628 err = PTR_ERR(clk);
629 goto error; 639 goto error;
630 } 640 }
631 sprintf(child_name, "PLL%d", i+1); 641 sprintf(child_name, "PLL%d", i+1);
@@ -634,7 +644,7 @@ static int cdce925_probe(struct i2c_client *client,
634 continue; 644 continue;
635 if (!of_property_read_u32(np_output, 645 if (!of_property_read_u32(np_output,
636 "clock-frequency", &value)) { 646 "clock-frequency", &value)) {
637 err = clk_set_rate(clk, value); 647 err = clk_set_rate(data->pll[i].hw.clk, value);
638 if (err) 648 if (err)
639 dev_err(&client->dev, 649 dev_err(&client->dev,
640 "unable to set PLL frequency %ud\n", 650 "unable to set PLL frequency %ud\n",
@@ -663,14 +673,12 @@ static int cdce925_probe(struct i2c_client *client,
663 data->clk[0].hw.init = &init; 673 data->clk[0].hw.init = &init;
664 data->clk[0].index = 0; 674 data->clk[0].index = 0;
665 data->clk[0].pdiv = 1; 675 data->clk[0].pdiv = 1;
666 clk = devm_clk_register(&client->dev, &data->clk[0].hw); 676 err = devm_clk_hw_register(&client->dev, &data->clk[0].hw);
667 kfree(init.name); /* clock framework made a copy of the name */ 677 kfree(init.name); /* clock framework made a copy of the name */
668 if (IS_ERR(clk)) { 678 if (err) {
669 dev_err(&client->dev, "clock registration Y1 failed\n"); 679 dev_err(&client->dev, "clock registration Y1 failed\n");
670 err = PTR_ERR(clk);
671 goto error; 680 goto error;
672 } 681 }
673 data->dt_clk[0] = clk;
674 682
675 /* Register output clocks Y2 .. Y5*/ 683 /* Register output clocks Y2 .. Y5*/
676 init.ops = &cdce925_clk_ops; 684 init.ops = &cdce925_clk_ops;
@@ -695,21 +703,17 @@ static int cdce925_probe(struct i2c_client *client,
695 init.parent_names = &pll_clk_name[1]; 703 init.parent_names = &pll_clk_name[1];
696 break; 704 break;
697 } 705 }
698 clk = devm_clk_register(&client->dev, &data->clk[i].hw); 706 err = devm_clk_hw_register(&client->dev, &data->clk[i].hw);
699 kfree(init.name); /* clock framework made a copy of the name */ 707 kfree(init.name); /* clock framework made a copy of the name */
700 if (IS_ERR(clk)) { 708 if (err) {
701 dev_err(&client->dev, "clock registration failed\n"); 709 dev_err(&client->dev, "clock registration failed\n");
702 err = PTR_ERR(clk);
703 goto error; 710 goto error;
704 } 711 }
705 data->dt_clk[i] = clk;
706 } 712 }
707 713
708 /* Register the output clocks */ 714 /* Register the output clocks */
709 data->onecell.clk_num = NUMBER_OF_OUTPUTS; 715 err = of_clk_add_hw_provider(client->dev.of_node, of_clk_cdce925_get,
710 data->onecell.clks = data->dt_clk; 716 data);
711 err = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get,
712 &data->onecell);
713 if (err) 717 if (err)
714 dev_err(&client->dev, "unable to add OF clock provider\n"); 718 dev_err(&client->dev, "unable to add OF clock provider\n");
715 719
diff --git a/drivers/clk/clk-clps711x.c b/drivers/clk/clk-clps711x.c
index adaf109f2fe2..9193f64561f6 100644
--- a/drivers/clk/clk-clps711x.c
+++ b/drivers/clk/clk-clps711x.c
@@ -40,9 +40,8 @@ static const struct clk_div_table timer_div_table[] = {
40}; 40};
41 41
42struct clps711x_clk { 42struct clps711x_clk {
43 struct clk_onecell_data clk_data; 43 spinlock_t lock;
44 spinlock_t lock; 44 struct clk_hw_onecell_data clk_data;
45 struct clk *clks[CLPS711X_CLK_MAX];
46}; 45};
47 46
48static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base, 47static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
@@ -55,7 +54,9 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
55 if (!base) 54 if (!base)
56 return ERR_PTR(-ENOMEM); 55 return ERR_PTR(-ENOMEM);
57 56
58 clps711x_clk = kzalloc(sizeof(*clps711x_clk), GFP_KERNEL); 57 clps711x_clk = kzalloc(sizeof(*clps711x_clk) +
58 sizeof(*clps711x_clk->clk_data.hws) * CLPS711X_CLK_MAX,
59 GFP_KERNEL);
59 if (!clps711x_clk) 60 if (!clps711x_clk)
60 return ERR_PTR(-ENOMEM); 61 return ERR_PTR(-ENOMEM);
61 62
@@ -106,40 +107,40 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
106 tmp |= SYSCON1_TC2M | SYSCON1_TC2S; 107 tmp |= SYSCON1_TC2M | SYSCON1_TC2S;
107 writel(tmp, base + CLPS711X_SYSCON1); 108 writel(tmp, base + CLPS711X_SYSCON1);
108 109
109 clps711x_clk->clks[CLPS711X_CLK_DUMMY] = 110 clps711x_clk->clk_data.hws[CLPS711X_CLK_DUMMY] =
110 clk_register_fixed_rate(NULL, "dummy", NULL, 0, 0); 111 clk_hw_register_fixed_rate(NULL, "dummy", NULL, 0, 0);
111 clps711x_clk->clks[CLPS711X_CLK_CPU] = 112 clps711x_clk->clk_data.hws[CLPS711X_CLK_CPU] =
112 clk_register_fixed_rate(NULL, "cpu", NULL, 0, f_cpu); 113 clk_hw_register_fixed_rate(NULL, "cpu", NULL, 0, f_cpu);
113 clps711x_clk->clks[CLPS711X_CLK_BUS] = 114 clps711x_clk->clk_data.hws[CLPS711X_CLK_BUS] =
114 clk_register_fixed_rate(NULL, "bus", NULL, 0, f_bus); 115 clk_hw_register_fixed_rate(NULL, "bus", NULL, 0, f_bus);
115 clps711x_clk->clks[CLPS711X_CLK_PLL] = 116 clps711x_clk->clk_data.hws[CLPS711X_CLK_PLL] =
116 clk_register_fixed_rate(NULL, "pll", NULL, 0, f_pll); 117 clk_hw_register_fixed_rate(NULL, "pll", NULL, 0, f_pll);
117 clps711x_clk->clks[CLPS711X_CLK_TIMERREF] = 118 clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMERREF] =
118 clk_register_fixed_rate(NULL, "timer_ref", NULL, 0, f_tim); 119 clk_hw_register_fixed_rate(NULL, "timer_ref", NULL, 0, f_tim);
119 clps711x_clk->clks[CLPS711X_CLK_TIMER1] = 120 clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER1] =
120 clk_register_divider_table(NULL, "timer1", "timer_ref", 0, 121 clk_hw_register_divider_table(NULL, "timer1", "timer_ref", 0,
121 base + CLPS711X_SYSCON1, 5, 1, 0, 122 base + CLPS711X_SYSCON1, 5, 1, 0,
122 timer_div_table, &clps711x_clk->lock); 123 timer_div_table, &clps711x_clk->lock);
123 clps711x_clk->clks[CLPS711X_CLK_TIMER2] = 124 clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER2] =
124 clk_register_divider_table(NULL, "timer2", "timer_ref", 0, 125 clk_hw_register_divider_table(NULL, "timer2", "timer_ref", 0,
125 base + CLPS711X_SYSCON1, 7, 1, 0, 126 base + CLPS711X_SYSCON1, 7, 1, 0,
126 timer_div_table, &clps711x_clk->lock); 127 timer_div_table, &clps711x_clk->lock);
127 clps711x_clk->clks[CLPS711X_CLK_PWM] = 128 clps711x_clk->clk_data.hws[CLPS711X_CLK_PWM] =
128 clk_register_fixed_rate(NULL, "pwm", NULL, 0, f_pwm); 129 clk_hw_register_fixed_rate(NULL, "pwm", NULL, 0, f_pwm);
129 clps711x_clk->clks[CLPS711X_CLK_SPIREF] = 130 clps711x_clk->clk_data.hws[CLPS711X_CLK_SPIREF] =
130 clk_register_fixed_rate(NULL, "spi_ref", NULL, 0, f_spi); 131 clk_hw_register_fixed_rate(NULL, "spi_ref", NULL, 0, f_spi);
131 clps711x_clk->clks[CLPS711X_CLK_SPI] = 132 clps711x_clk->clk_data.hws[CLPS711X_CLK_SPI] =
132 clk_register_divider_table(NULL, "spi", "spi_ref", 0, 133 clk_hw_register_divider_table(NULL, "spi", "spi_ref", 0,
133 base + CLPS711X_SYSCON1, 16, 2, 0, 134 base + CLPS711X_SYSCON1, 16, 2, 0,
134 spi_div_table, &clps711x_clk->lock); 135 spi_div_table, &clps711x_clk->lock);
135 clps711x_clk->clks[CLPS711X_CLK_UART] = 136 clps711x_clk->clk_data.hws[CLPS711X_CLK_UART] =
136 clk_register_fixed_factor(NULL, "uart", "bus", 0, 1, 10); 137 clk_hw_register_fixed_factor(NULL, "uart", "bus", 0, 1, 10);
137 clps711x_clk->clks[CLPS711X_CLK_TICK] = 138 clps711x_clk->clk_data.hws[CLPS711X_CLK_TICK] =
138 clk_register_fixed_rate(NULL, "tick", NULL, 0, 64); 139 clk_hw_register_fixed_rate(NULL, "tick", NULL, 0, 64);
139 for (i = 0; i < CLPS711X_CLK_MAX; i++) 140 for (i = 0; i < CLPS711X_CLK_MAX; i++)
140 if (IS_ERR(clps711x_clk->clks[i])) 141 if (IS_ERR(clps711x_clk->clk_data.hws[i]))
141 pr_err("clk %i: register failed with %ld\n", 142 pr_err("clk %i: register failed with %ld\n",
142 i, PTR_ERR(clps711x_clk->clks[i])); 143 i, PTR_ERR(clps711x_clk->clk_data.hws[i]));
143 144
144 return clps711x_clk; 145 return clps711x_clk;
145} 146}
@@ -153,17 +154,17 @@ void __init clps711x_clk_init(void __iomem *base)
153 BUG_ON(IS_ERR(clps711x_clk)); 154 BUG_ON(IS_ERR(clps711x_clk));
154 155
155 /* Clocksource */ 156 /* Clocksource */
156 clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_TIMER1], 157 clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER1],
157 NULL, "clps711x-timer.0"); 158 NULL, "clps711x-timer.0");
158 clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_TIMER2], 159 clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER2],
159 NULL, "clps711x-timer.1"); 160 NULL, "clps711x-timer.1");
160 161
161 /* Drivers */ 162 /* Drivers */
162 clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_PWM], 163 clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_PWM],
163 NULL, "clps711x-pwm"); 164 NULL, "clps711x-pwm");
164 clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_UART], 165 clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_UART],
165 NULL, "clps711x-uart.0"); 166 NULL, "clps711x-uart.0");
166 clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_UART], 167 clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_UART],
167 NULL, "clps711x-uart.1"); 168 NULL, "clps711x-uart.1");
168} 169}
169 170
@@ -179,10 +180,9 @@ static void __init clps711x_clk_init_dt(struct device_node *np)
179 clps711x_clk = _clps711x_clk_init(base, fref); 180 clps711x_clk = _clps711x_clk_init(base, fref);
180 BUG_ON(IS_ERR(clps711x_clk)); 181 BUG_ON(IS_ERR(clps711x_clk));
181 182
182 clps711x_clk->clk_data.clks = clps711x_clk->clks; 183 clps711x_clk->clk_data.num = CLPS711X_CLK_MAX;
183 clps711x_clk->clk_data.clk_num = CLPS711X_CLK_MAX; 184 of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
184 of_clk_add_provider(np, of_clk_src_onecell_get, 185 &clps711x_clk->clk_data);
185 &clps711x_clk->clk_data);
186} 186}
187CLK_OF_DECLARE(clps711x, "cirrus,ep7209-clk", clps711x_clk_init_dt); 187CLK_OF_DECLARE(clps711x, "cirrus,ep7209-clk", clps711x_clk_init_dt);
188#endif 188#endif
diff --git a/drivers/clk/clk-cs2000-cp.c b/drivers/clk/clk-cs2000-cp.c
index 7379de8dc894..021f3daf34e1 100644
--- a/drivers/clk/clk-cs2000-cp.c
+++ b/drivers/clk/clk-cs2000-cp.c
@@ -59,7 +59,6 @@ struct cs2000_priv {
59 struct i2c_client *client; 59 struct i2c_client *client;
60 struct clk *clk_in; 60 struct clk *clk_in;
61 struct clk *ref_clk; 61 struct clk *ref_clk;
62 struct clk *clk_out;
63}; 62};
64 63
65static const struct of_device_id cs2000_of_match[] = { 64static const struct of_device_id cs2000_of_match[] = {
@@ -371,7 +370,6 @@ static int cs2000_clk_register(struct cs2000_priv *priv)
371 struct device_node *np = dev->of_node; 370 struct device_node *np = dev->of_node;
372 struct clk_init_data init; 371 struct clk_init_data init;
373 const char *name = np->name; 372 const char *name = np->name;
374 struct clk *clk;
375 static const char *parent_names[CLK_MAX]; 373 static const char *parent_names[CLK_MAX];
376 int ch = 0; /* it uses ch0 only at this point */ 374 int ch = 0; /* it uses ch0 only at this point */
377 int rate; 375 int rate;
@@ -400,18 +398,16 @@ static int cs2000_clk_register(struct cs2000_priv *priv)
400 398
401 priv->hw.init = &init; 399 priv->hw.init = &init;
402 400
403 clk = clk_register(dev, &priv->hw); 401 ret = clk_hw_register(dev, &priv->hw);
404 if (IS_ERR(clk)) 402 if (ret)
405 return PTR_ERR(clk); 403 return ret;
406 404
407 ret = of_clk_add_provider(np, of_clk_src_simple_get, clk); 405 ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw);
408 if (ret < 0) { 406 if (ret < 0) {
409 clk_unregister(clk); 407 clk_hw_unregister(&priv->hw);
410 return ret; 408 return ret;
411 } 409 }
412 410
413 priv->clk_out = clk;
414
415 return 0; 411 return 0;
416} 412}
417 413
@@ -454,7 +450,7 @@ static int cs2000_remove(struct i2c_client *client)
454 450
455 of_clk_del_provider(np); 451 of_clk_del_provider(np);
456 452
457 clk_unregister(priv->clk_out); 453 clk_hw_unregister(&priv->hw);
458 454
459 return 0; 455 return 0;
460} 456}
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index a0f55bc1ad3d..96386ffc8483 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -352,7 +352,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
352 352
353 /* if read only, just return current value */ 353 /* if read only, just return current value */
354 if (divider->flags & CLK_DIVIDER_READ_ONLY) { 354 if (divider->flags & CLK_DIVIDER_READ_ONLY) {
355 bestdiv = readl(divider->reg) >> divider->shift; 355 bestdiv = clk_readl(divider->reg) >> divider->shift;
356 bestdiv &= div_mask(divider->width); 356 bestdiv &= div_mask(divider->width);
357 bestdiv = _get_div(divider->table, bestdiv, divider->flags, 357 bestdiv = _get_div(divider->table, bestdiv, divider->flags,
358 divider->width); 358 divider->width);
diff --git a/drivers/clk/clk-efm32gg.c b/drivers/clk/clk-efm32gg.c
index 22e4c659704e..8802a2dd56ac 100644
--- a/drivers/clk/clk-efm32gg.c
+++ b/drivers/clk/clk-efm32gg.c
@@ -10,24 +10,31 @@
10#include <linux/clk-provider.h> 10#include <linux/clk-provider.h>
11#include <linux/of.h> 11#include <linux/of.h>
12#include <linux/of_address.h> 12#include <linux/of_address.h>
13#include <linux/slab.h>
13 14
14#include <dt-bindings/clock/efm32-cmu.h> 15#include <dt-bindings/clock/efm32-cmu.h>
15 16
16#define CMU_HFPERCLKEN0 0x44 17#define CMU_HFPERCLKEN0 0x44
18#define CMU_MAX_CLKS 37
17 19
18static struct clk *clk[37]; 20static struct clk_hw_onecell_data *clk_data;
19static struct clk_onecell_data clk_data = {
20 .clks = clk,
21 .clk_num = ARRAY_SIZE(clk),
22};
23 21
24static void __init efm32gg_cmu_init(struct device_node *np) 22static void __init efm32gg_cmu_init(struct device_node *np)
25{ 23{
26 int i; 24 int i;
27 void __iomem *base; 25 void __iomem *base;
26 struct clk_hw **hws;
28 27
29 for (i = 0; i < ARRAY_SIZE(clk); ++i) 28 clk_data = kzalloc(sizeof(*clk_data) +
30 clk[i] = ERR_PTR(-ENOENT); 29 sizeof(*clk_data->hws) * CMU_MAX_CLKS, GFP_KERNEL);
30
31 if (!clk_data)
32 return;
33
34 hws = clk_data->hws;
35
36 for (i = 0; i < CMU_MAX_CLKS; ++i)
37 hws[i] = ERR_PTR(-ENOENT);
31 38
32 base = of_iomap(np, 0); 39 base = of_iomap(np, 0);
33 if (!base) { 40 if (!base) {
@@ -35,46 +42,46 @@ static void __init efm32gg_cmu_init(struct device_node *np)
35 return; 42 return;
36 } 43 }
37 44
38 clk[clk_HFXO] = clk_register_fixed_rate(NULL, "HFXO", NULL, 45 hws[clk_HFXO] = clk_hw_register_fixed_rate(NULL, "HFXO", NULL, 0,
39 0, 48000000); 46 48000000);
40 47
41 clk[clk_HFPERCLKUSART0] = clk_register_gate(NULL, "HFPERCLK.USART0", 48 hws[clk_HFPERCLKUSART0] = clk_hw_register_gate(NULL, "HFPERCLK.USART0",
42 "HFXO", 0, base + CMU_HFPERCLKEN0, 0, 0, NULL); 49 "HFXO", 0, base + CMU_HFPERCLKEN0, 0, 0, NULL);
43 clk[clk_HFPERCLKUSART1] = clk_register_gate(NULL, "HFPERCLK.USART1", 50 hws[clk_HFPERCLKUSART1] = clk_hw_register_gate(NULL, "HFPERCLK.USART1",
44 "HFXO", 0, base + CMU_HFPERCLKEN0, 1, 0, NULL); 51 "HFXO", 0, base + CMU_HFPERCLKEN0, 1, 0, NULL);
45 clk[clk_HFPERCLKUSART2] = clk_register_gate(NULL, "HFPERCLK.USART2", 52 hws[clk_HFPERCLKUSART2] = clk_hw_register_gate(NULL, "HFPERCLK.USART2",
46 "HFXO", 0, base + CMU_HFPERCLKEN0, 2, 0, NULL); 53 "HFXO", 0, base + CMU_HFPERCLKEN0, 2, 0, NULL);
47 clk[clk_HFPERCLKUART0] = clk_register_gate(NULL, "HFPERCLK.UART0", 54 hws[clk_HFPERCLKUART0] = clk_hw_register_gate(NULL, "HFPERCLK.UART0",
48 "HFXO", 0, base + CMU_HFPERCLKEN0, 3, 0, NULL); 55 "HFXO", 0, base + CMU_HFPERCLKEN0, 3, 0, NULL);
49 clk[clk_HFPERCLKUART1] = clk_register_gate(NULL, "HFPERCLK.UART1", 56 hws[clk_HFPERCLKUART1] = clk_hw_register_gate(NULL, "HFPERCLK.UART1",
50 "HFXO", 0, base + CMU_HFPERCLKEN0, 4, 0, NULL); 57 "HFXO", 0, base + CMU_HFPERCLKEN0, 4, 0, NULL);
51 clk[clk_HFPERCLKTIMER0] = clk_register_gate(NULL, "HFPERCLK.TIMER0", 58 hws[clk_HFPERCLKTIMER0] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER0",
52 "HFXO", 0, base + CMU_HFPERCLKEN0, 5, 0, NULL); 59 "HFXO", 0, base + CMU_HFPERCLKEN0, 5, 0, NULL);
53 clk[clk_HFPERCLKTIMER1] = clk_register_gate(NULL, "HFPERCLK.TIMER1", 60 hws[clk_HFPERCLKTIMER1] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER1",
54 "HFXO", 0, base + CMU_HFPERCLKEN0, 6, 0, NULL); 61 "HFXO", 0, base + CMU_HFPERCLKEN0, 6, 0, NULL);
55 clk[clk_HFPERCLKTIMER2] = clk_register_gate(NULL, "HFPERCLK.TIMER2", 62 hws[clk_HFPERCLKTIMER2] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER2",
56 "HFXO", 0, base + CMU_HFPERCLKEN0, 7, 0, NULL); 63 "HFXO", 0, base + CMU_HFPERCLKEN0, 7, 0, NULL);
57 clk[clk_HFPERCLKTIMER3] = clk_register_gate(NULL, "HFPERCLK.TIMER3", 64 hws[clk_HFPERCLKTIMER3] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER3",
58 "HFXO", 0, base + CMU_HFPERCLKEN0, 8, 0, NULL); 65 "HFXO", 0, base + CMU_HFPERCLKEN0, 8, 0, NULL);
59 clk[clk_HFPERCLKACMP0] = clk_register_gate(NULL, "HFPERCLK.ACMP0", 66 hws[clk_HFPERCLKACMP0] = clk_hw_register_gate(NULL, "HFPERCLK.ACMP0",
60 "HFXO", 0, base + CMU_HFPERCLKEN0, 9, 0, NULL); 67 "HFXO", 0, base + CMU_HFPERCLKEN0, 9, 0, NULL);
61 clk[clk_HFPERCLKACMP1] = clk_register_gate(NULL, "HFPERCLK.ACMP1", 68 hws[clk_HFPERCLKACMP1] = clk_hw_register_gate(NULL, "HFPERCLK.ACMP1",
62 "HFXO", 0, base + CMU_HFPERCLKEN0, 10, 0, NULL); 69 "HFXO", 0, base + CMU_HFPERCLKEN0, 10, 0, NULL);
63 clk[clk_HFPERCLKI2C0] = clk_register_gate(NULL, "HFPERCLK.I2C0", 70 hws[clk_HFPERCLKI2C0] = clk_hw_register_gate(NULL, "HFPERCLK.I2C0",
64 "HFXO", 0, base + CMU_HFPERCLKEN0, 11, 0, NULL); 71 "HFXO", 0, base + CMU_HFPERCLKEN0, 11, 0, NULL);
65 clk[clk_HFPERCLKI2C1] = clk_register_gate(NULL, "HFPERCLK.I2C1", 72 hws[clk_HFPERCLKI2C1] = clk_hw_register_gate(NULL, "HFPERCLK.I2C1",
66 "HFXO", 0, base + CMU_HFPERCLKEN0, 12, 0, NULL); 73 "HFXO", 0, base + CMU_HFPERCLKEN0, 12, 0, NULL);
67 clk[clk_HFPERCLKGPIO] = clk_register_gate(NULL, "HFPERCLK.GPIO", 74 hws[clk_HFPERCLKGPIO] = clk_hw_register_gate(NULL, "HFPERCLK.GPIO",
68 "HFXO", 0, base + CMU_HFPERCLKEN0, 13, 0, NULL); 75 "HFXO", 0, base + CMU_HFPERCLKEN0, 13, 0, NULL);
69 clk[clk_HFPERCLKVCMP] = clk_register_gate(NULL, "HFPERCLK.VCMP", 76 hws[clk_HFPERCLKVCMP] = clk_hw_register_gate(NULL, "HFPERCLK.VCMP",
70 "HFXO", 0, base + CMU_HFPERCLKEN0, 14, 0, NULL); 77 "HFXO", 0, base + CMU_HFPERCLKEN0, 14, 0, NULL);
71 clk[clk_HFPERCLKPRS] = clk_register_gate(NULL, "HFPERCLK.PRS", 78 hws[clk_HFPERCLKPRS] = clk_hw_register_gate(NULL, "HFPERCLK.PRS",
72 "HFXO", 0, base + CMU_HFPERCLKEN0, 15, 0, NULL); 79 "HFXO", 0, base + CMU_HFPERCLKEN0, 15, 0, NULL);
73 clk[clk_HFPERCLKADC0] = clk_register_gate(NULL, "HFPERCLK.ADC0", 80 hws[clk_HFPERCLKADC0] = clk_hw_register_gate(NULL, "HFPERCLK.ADC0",
74 "HFXO", 0, base + CMU_HFPERCLKEN0, 16, 0, NULL); 81 "HFXO", 0, base + CMU_HFPERCLKEN0, 16, 0, NULL);
75 clk[clk_HFPERCLKDAC0] = clk_register_gate(NULL, "HFPERCLK.DAC0", 82 hws[clk_HFPERCLKDAC0] = clk_hw_register_gate(NULL, "HFPERCLK.DAC0",
76 "HFXO", 0, base + CMU_HFPERCLKEN0, 17, 0, NULL); 83 "HFXO", 0, base + CMU_HFPERCLKEN0, 17, 0, NULL);
77 84
78 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 85 of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data);
79} 86}
80CLK_OF_DECLARE(efm32ggcmu, "efm32gg,cmu", efm32gg_cmu_init); 87CLK_OF_DECLARE(efm32ggcmu, "efm32gg,cmu", efm32gg_cmu_init);
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index 4db3be214077..a5d402de5584 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -12,6 +12,7 @@
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/err.h> 13#include <linux/err.h>
14#include <linux/of.h> 14#include <linux/of.h>
15#include <linux/platform_device.h>
15 16
16/* 17/*
17 * DOC: basic fixed multiplier and divider clock that cannot gate 18 * DOC: basic fixed multiplier and divider clock that cannot gate
@@ -147,27 +148,25 @@ static const struct of_device_id set_rate_parent_matches[] = {
147 { /* Sentinel */ }, 148 { /* Sentinel */ },
148}; 149};
149 150
150/** 151static struct clk *_of_fixed_factor_clk_setup(struct device_node *node)
151 * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
152 */
153void __init of_fixed_factor_clk_setup(struct device_node *node)
154{ 152{
155 struct clk *clk; 153 struct clk *clk;
156 const char *clk_name = node->name; 154 const char *clk_name = node->name;
157 const char *parent_name; 155 const char *parent_name;
158 unsigned long flags = 0; 156 unsigned long flags = 0;
159 u32 div, mult; 157 u32 div, mult;
158 int ret;
160 159
161 if (of_property_read_u32(node, "clock-div", &div)) { 160 if (of_property_read_u32(node, "clock-div", &div)) {
162 pr_err("%s Fixed factor clock <%s> must have a clock-div property\n", 161 pr_err("%s Fixed factor clock <%s> must have a clock-div property\n",
163 __func__, node->name); 162 __func__, node->name);
164 return; 163 return ERR_PTR(-EIO);
165 } 164 }
166 165
167 if (of_property_read_u32(node, "clock-mult", &mult)) { 166 if (of_property_read_u32(node, "clock-mult", &mult)) {
168 pr_err("%s Fixed factor clock <%s> must have a clock-mult property\n", 167 pr_err("%s Fixed factor clock <%s> must have a clock-mult property\n",
169 __func__, node->name); 168 __func__, node->name);
170 return; 169 return ERR_PTR(-EIO);
171 } 170 }
172 171
173 of_property_read_string(node, "clock-output-names", &clk_name); 172 of_property_read_string(node, "clock-output-names", &clk_name);
@@ -178,10 +177,67 @@ void __init of_fixed_factor_clk_setup(struct device_node *node)
178 177
179 clk = clk_register_fixed_factor(NULL, clk_name, parent_name, flags, 178 clk = clk_register_fixed_factor(NULL, clk_name, parent_name, flags,
180 mult, div); 179 mult, div);
181 if (!IS_ERR(clk)) 180 if (IS_ERR(clk))
182 of_clk_add_provider(node, of_clk_src_simple_get, clk); 181 return clk;
182
183 ret = of_clk_add_provider(node, of_clk_src_simple_get, clk);
184 if (ret) {
185 clk_unregister(clk);
186 return ERR_PTR(ret);
187 }
188
189 return clk;
190}
191
192/**
193 * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
194 */
195void __init of_fixed_factor_clk_setup(struct device_node *node)
196{
197 _of_fixed_factor_clk_setup(node);
183} 198}
184EXPORT_SYMBOL_GPL(of_fixed_factor_clk_setup);
185CLK_OF_DECLARE(fixed_factor_clk, "fixed-factor-clock", 199CLK_OF_DECLARE(fixed_factor_clk, "fixed-factor-clock",
186 of_fixed_factor_clk_setup); 200 of_fixed_factor_clk_setup);
201
202static int of_fixed_factor_clk_remove(struct platform_device *pdev)
203{
204 struct clk *clk = platform_get_drvdata(pdev);
205
206 clk_unregister_fixed_factor(clk);
207
208 return 0;
209}
210
211static int of_fixed_factor_clk_probe(struct platform_device *pdev)
212{
213 struct clk *clk;
214
215 /*
216 * This function is not executed when of_fixed_factor_clk_setup
217 * succeeded.
218 */
219 clk = _of_fixed_factor_clk_setup(pdev->dev.of_node);
220 if (IS_ERR(clk))
221 return PTR_ERR(clk);
222
223 platform_set_drvdata(pdev, clk);
224
225 return 0;
226}
227
228static const struct of_device_id of_fixed_factor_clk_ids[] = {
229 { .compatible = "fixed-factor-clock" },
230 { }
231};
232MODULE_DEVICE_TABLE(of, of_fixed_factor_clk_ids);
233
234static struct platform_driver of_fixed_factor_clk_driver = {
235 .driver = {
236 .name = "of_fixed_factor_clk",
237 .of_match_table = of_fixed_factor_clk_ids,
238 },
239 .probe = of_fixed_factor_clk_probe,
240 .remove = of_fixed_factor_clk_remove,
241};
242builtin_platform_driver(of_fixed_factor_clk_driver);
187#endif 243#endif
diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c
index 2edb39342a02..b5c46b3f8764 100644
--- a/drivers/clk/clk-fixed-rate.c
+++ b/drivers/clk/clk-fixed-rate.c
@@ -15,6 +15,7 @@
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/of.h> 17#include <linux/of.h>
18#include <linux/platform_device.h>
18 19
19/* 20/*
20 * DOC: basic fixed-rate clock that cannot gate 21 * DOC: basic fixed-rate clock that cannot gate
@@ -157,18 +158,16 @@ void clk_hw_unregister_fixed_rate(struct clk_hw *hw)
157EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_rate); 158EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_rate);
158 159
159#ifdef CONFIG_OF 160#ifdef CONFIG_OF
160/** 161static struct clk *_of_fixed_clk_setup(struct device_node *node)
161 * of_fixed_clk_setup() - Setup function for simple fixed rate clock
162 */
163void of_fixed_clk_setup(struct device_node *node)
164{ 162{
165 struct clk *clk; 163 struct clk *clk;
166 const char *clk_name = node->name; 164 const char *clk_name = node->name;
167 u32 rate; 165 u32 rate;
168 u32 accuracy = 0; 166 u32 accuracy = 0;
167 int ret;
169 168
170 if (of_property_read_u32(node, "clock-frequency", &rate)) 169 if (of_property_read_u32(node, "clock-frequency", &rate))
171 return; 170 return ERR_PTR(-EIO);
172 171
173 of_property_read_u32(node, "clock-accuracy", &accuracy); 172 of_property_read_u32(node, "clock-accuracy", &accuracy);
174 173
@@ -176,9 +175,66 @@ void of_fixed_clk_setup(struct device_node *node)
176 175
177 clk = clk_register_fixed_rate_with_accuracy(NULL, clk_name, NULL, 176 clk = clk_register_fixed_rate_with_accuracy(NULL, clk_name, NULL,
178 0, rate, accuracy); 177 0, rate, accuracy);
179 if (!IS_ERR(clk)) 178 if (IS_ERR(clk))
180 of_clk_add_provider(node, of_clk_src_simple_get, clk); 179 return clk;
180
181 ret = of_clk_add_provider(node, of_clk_src_simple_get, clk);
182 if (ret) {
183 clk_unregister(clk);
184 return ERR_PTR(ret);
185 }
186
187 return clk;
188}
189
190/**
191 * of_fixed_clk_setup() - Setup function for simple fixed rate clock
192 */
193void __init of_fixed_clk_setup(struct device_node *node)
194{
195 _of_fixed_clk_setup(node);
181} 196}
182EXPORT_SYMBOL_GPL(of_fixed_clk_setup);
183CLK_OF_DECLARE(fixed_clk, "fixed-clock", of_fixed_clk_setup); 197CLK_OF_DECLARE(fixed_clk, "fixed-clock", of_fixed_clk_setup);
198
199static int of_fixed_clk_remove(struct platform_device *pdev)
200{
201 struct clk *clk = platform_get_drvdata(pdev);
202
203 clk_unregister_fixed_rate(clk);
204
205 return 0;
206}
207
208static int of_fixed_clk_probe(struct platform_device *pdev)
209{
210 struct clk *clk;
211
212 /*
213 * This function is not executed when of_fixed_clk_setup
214 * succeeded.
215 */
216 clk = _of_fixed_clk_setup(pdev->dev.of_node);
217 if (IS_ERR(clk))
218 return PTR_ERR(clk);
219
220 platform_set_drvdata(pdev, clk);
221
222 return 0;
223}
224
225static const struct of_device_id of_fixed_clk_ids[] = {
226 { .compatible = "fixed-clock" },
227 { }
228};
229MODULE_DEVICE_TABLE(of, of_fixed_clk_ids);
230
231static struct platform_driver of_fixed_clk_driver = {
232 .driver = {
233 .name = "of_fixed_clk",
234 .of_match_table = of_fixed_clk_ids,
235 },
236 .probe = of_fixed_clk_probe,
237 .remove = of_fixed_clk_remove,
238};
239builtin_platform_driver(of_fixed_clk_driver);
184#endif 240#endif
diff --git a/drivers/clk/clk-ls1x.c b/drivers/clk/clk-ls1x.c
deleted file mode 100644
index 5097831387ff..000000000000
--- a/drivers/clk/clk-ls1x.c
+++ /dev/null
@@ -1,161 +0,0 @@
1/*
2 * Copyright (c) 2012 Zhang, Keguang <keguang.zhang@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#include <linux/clkdev.h>
11#include <linux/clk-provider.h>
12#include <linux/io.h>
13#include <linux/slab.h>
14#include <linux/err.h>
15
16#include <loongson1.h>
17
18#define OSC (33 * 1000000)
19#define DIV_APB 2
20
21static DEFINE_SPINLOCK(_lock);
22
23static int ls1x_pll_clk_enable(struct clk_hw *hw)
24{
25 return 0;
26}
27
28static void ls1x_pll_clk_disable(struct clk_hw *hw)
29{
30}
31
32static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw,
33 unsigned long parent_rate)
34{
35 u32 pll, rate;
36
37 pll = __raw_readl(LS1X_CLK_PLL_FREQ);
38 rate = 12 + (pll & 0x3f) + (((pll >> 8) & 0x3ff) >> 10);
39 rate *= OSC;
40 rate >>= 1;
41
42 return rate;
43}
44
45static const struct clk_ops ls1x_pll_clk_ops = {
46 .enable = ls1x_pll_clk_enable,
47 .disable = ls1x_pll_clk_disable,
48 .recalc_rate = ls1x_pll_recalc_rate,
49};
50
51static struct clk *__init clk_register_pll(struct device *dev,
52 const char *name,
53 const char *parent_name,
54 unsigned long flags)
55{
56 struct clk_hw *hw;
57 struct clk *clk;
58 struct clk_init_data init;
59
60 /* allocate the divider */
61 hw = kzalloc(sizeof(struct clk_hw), GFP_KERNEL);
62 if (!hw) {
63 pr_err("%s: could not allocate clk_hw\n", __func__);
64 return ERR_PTR(-ENOMEM);
65 }
66
67 init.name = name;
68 init.ops = &ls1x_pll_clk_ops;
69 init.flags = flags | CLK_IS_BASIC;
70 init.parent_names = (parent_name ? &parent_name : NULL);
71 init.num_parents = (parent_name ? 1 : 0);
72 hw->init = &init;
73
74 /* register the clock */
75 clk = clk_register(dev, hw);
76
77 if (IS_ERR(clk))
78 kfree(hw);
79
80 return clk;
81}
82
83static const char * const cpu_parents[] = { "cpu_clk_div", "osc_33m_clk", };
84static const char * const ahb_parents[] = { "ahb_clk_div", "osc_33m_clk", };
85static const char * const dc_parents[] = { "dc_clk_div", "osc_33m_clk", };
86
87void __init ls1x_clk_init(void)
88{
89 struct clk *clk;
90
91 clk = clk_register_fixed_rate(NULL, "osc_33m_clk", NULL, 0, OSC);
92 clk_register_clkdev(clk, "osc_33m_clk", NULL);
93
94 /* clock derived from 33 MHz OSC clk */
95 clk = clk_register_pll(NULL, "pll_clk", "osc_33m_clk", 0);
96 clk_register_clkdev(clk, "pll_clk", NULL);
97
98 /* clock derived from PLL clk */
99 /* _____
100 * _______________________| |
101 * OSC ___/ | MUX |___ CPU CLK
102 * \___ PLL ___ CPU DIV ___| |
103 * |_____|
104 */
105 clk = clk_register_divider(NULL, "cpu_clk_div", "pll_clk",
106 CLK_GET_RATE_NOCACHE, LS1X_CLK_PLL_DIV,
107 DIV_CPU_SHIFT, DIV_CPU_WIDTH,
108 CLK_DIVIDER_ONE_BASED |
109 CLK_DIVIDER_ROUND_CLOSEST, &_lock);
110 clk_register_clkdev(clk, "cpu_clk_div", NULL);
111 clk = clk_register_mux(NULL, "cpu_clk", cpu_parents,
112 ARRAY_SIZE(cpu_parents),
113 CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV,
114 BYPASS_CPU_SHIFT, BYPASS_CPU_WIDTH, 0, &_lock);
115 clk_register_clkdev(clk, "cpu_clk", NULL);
116
117 /* _____
118 * _______________________| |
119 * OSC ___/ | MUX |___ DC CLK
120 * \___ PLL ___ DC DIV ___| |
121 * |_____|
122 */
123 clk = clk_register_divider(NULL, "dc_clk_div", "pll_clk",
124 0, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT,
125 DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock);
126 clk_register_clkdev(clk, "dc_clk_div", NULL);
127 clk = clk_register_mux(NULL, "dc_clk", dc_parents,
128 ARRAY_SIZE(dc_parents),
129 CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV,
130 BYPASS_DC_SHIFT, BYPASS_DC_WIDTH, 0, &_lock);
131 clk_register_clkdev(clk, "dc_clk", NULL);
132
133 /* _____
134 * _______________________| |
135 * OSC ___/ | MUX |___ DDR CLK
136 * \___ PLL ___ DDR DIV ___| |
137 * |_____|
138 */
139 clk = clk_register_divider(NULL, "ahb_clk_div", "pll_clk",
140 0, LS1X_CLK_PLL_DIV, DIV_DDR_SHIFT,
141 DIV_DDR_WIDTH, CLK_DIVIDER_ONE_BASED,
142 &_lock);
143 clk_register_clkdev(clk, "ahb_clk_div", NULL);
144 clk = clk_register_mux(NULL, "ahb_clk", ahb_parents,
145 ARRAY_SIZE(ahb_parents),
146 CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV,
147 BYPASS_DDR_SHIFT, BYPASS_DDR_WIDTH, 0, &_lock);
148 clk_register_clkdev(clk, "ahb_clk", NULL);
149 clk_register_clkdev(clk, "stmmaceth", NULL);
150
151 /* clock derived from AHB clk */
152 /* APB clk is always half of the AHB clk */
153 clk = clk_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1,
154 DIV_APB);
155 clk_register_clkdev(clk, "apb_clk", NULL);
156 clk_register_clkdev(clk, "ls1x_i2c", NULL);
157 clk_register_clkdev(clk, "ls1x_pwmtimer", NULL);
158 clk_register_clkdev(clk, "ls1x_spi", NULL);
159 clk_register_clkdev(clk, "ls1x_wdt", NULL);
160 clk_register_clkdev(clk, "serial8250", NULL);
161}
diff --git a/drivers/clk/clk-max-gen.c b/drivers/clk/clk-max-gen.c
deleted file mode 100644
index 35af9cb6da4f..000000000000
--- a/drivers/clk/clk-max-gen.c
+++ /dev/null
@@ -1,194 +0,0 @@
1/*
2 * clk-max-gen.c - Generic clock driver for Maxim PMICs clocks
3 *
4 * Copyright (C) 2014 Google, Inc
5 *
6 * Copyright (C) 2012 Samsung Electornics
7 * Jonghwa Lee <jonghwa3.lee@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * This driver is based on clk-max77686.c
20 *
21 */
22
23#include <linux/kernel.h>
24#include <linux/slab.h>
25#include <linux/err.h>
26#include <linux/regmap.h>
27#include <linux/platform_device.h>
28#include <linux/clk-provider.h>
29#include <linux/mutex.h>
30#include <linux/clkdev.h>
31#include <linux/of.h>
32#include <linux/export.h>
33
34#include "clk-max-gen.h"
35
36struct max_gen_clk {
37 struct regmap *regmap;
38 u32 mask;
39 u32 reg;
40 struct clk_hw hw;
41};
42
43static struct max_gen_clk *to_max_gen_clk(struct clk_hw *hw)
44{
45 return container_of(hw, struct max_gen_clk, hw);
46}
47
48static int max_gen_clk_prepare(struct clk_hw *hw)
49{
50 struct max_gen_clk *max_gen = to_max_gen_clk(hw);
51
52 return regmap_update_bits(max_gen->regmap, max_gen->reg,
53 max_gen->mask, max_gen->mask);
54}
55
56static void max_gen_clk_unprepare(struct clk_hw *hw)
57{
58 struct max_gen_clk *max_gen = to_max_gen_clk(hw);
59
60 regmap_update_bits(max_gen->regmap, max_gen->reg,
61 max_gen->mask, ~max_gen->mask);
62}
63
64static int max_gen_clk_is_prepared(struct clk_hw *hw)
65{
66 struct max_gen_clk *max_gen = to_max_gen_clk(hw);
67 int ret;
68 u32 val;
69
70 ret = regmap_read(max_gen->regmap, max_gen->reg, &val);
71
72 if (ret < 0)
73 return -EINVAL;
74
75 return val & max_gen->mask;
76}
77
78static unsigned long max_gen_recalc_rate(struct clk_hw *hw,
79 unsigned long parent_rate)
80{
81 return 32768;
82}
83
84struct clk_ops max_gen_clk_ops = {
85 .prepare = max_gen_clk_prepare,
86 .unprepare = max_gen_clk_unprepare,
87 .is_prepared = max_gen_clk_is_prepared,
88 .recalc_rate = max_gen_recalc_rate,
89};
90EXPORT_SYMBOL_GPL(max_gen_clk_ops);
91
92static struct clk *max_gen_clk_register(struct device *dev,
93 struct max_gen_clk *max_gen)
94{
95 struct clk *clk;
96 struct clk_hw *hw = &max_gen->hw;
97 int ret;
98
99 clk = devm_clk_register(dev, hw);
100 if (IS_ERR(clk))
101 return clk;
102
103 ret = clk_register_clkdev(clk, hw->init->name, NULL);
104
105 if (ret)
106 return ERR_PTR(ret);
107
108 return clk;
109}
110
111int max_gen_clk_probe(struct platform_device *pdev, struct regmap *regmap,
112 u32 reg, struct clk_init_data *clks_init, int num_init)
113{
114 int i, ret;
115 struct max_gen_clk *max_gen_clks;
116 struct clk **clocks;
117 struct device *dev = pdev->dev.parent;
118 const char *clk_name;
119 struct clk_init_data *init;
120
121 clocks = devm_kzalloc(dev, sizeof(struct clk *) * num_init, GFP_KERNEL);
122 if (!clocks)
123 return -ENOMEM;
124
125 max_gen_clks = devm_kzalloc(dev, sizeof(struct max_gen_clk)
126 * num_init, GFP_KERNEL);
127 if (!max_gen_clks)
128 return -ENOMEM;
129
130 for (i = 0; i < num_init; i++) {
131 max_gen_clks[i].regmap = regmap;
132 max_gen_clks[i].mask = 1 << i;
133 max_gen_clks[i].reg = reg;
134
135 init = devm_kzalloc(dev, sizeof(*init), GFP_KERNEL);
136 if (!init)
137 return -ENOMEM;
138
139 if (dev->of_node &&
140 !of_property_read_string_index(dev->of_node,
141 "clock-output-names",
142 i, &clk_name))
143 init->name = clk_name;
144 else
145 init->name = clks_init[i].name;
146
147 init->ops = clks_init[i].ops;
148 init->flags = clks_init[i].flags;
149
150 max_gen_clks[i].hw.init = init;
151
152 clocks[i] = max_gen_clk_register(dev, &max_gen_clks[i]);
153 if (IS_ERR(clocks[i])) {
154 ret = PTR_ERR(clocks[i]);
155 dev_err(dev, "failed to register %s\n",
156 max_gen_clks[i].hw.init->name);
157 return ret;
158 }
159 }
160
161 platform_set_drvdata(pdev, clocks);
162
163 if (dev->of_node) {
164 struct clk_onecell_data *of_data;
165
166 of_data = devm_kzalloc(dev, sizeof(*of_data), GFP_KERNEL);
167 if (!of_data)
168 return -ENOMEM;
169
170 of_data->clks = clocks;
171 of_data->clk_num = num_init;
172 ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
173 of_data);
174
175 if (ret) {
176 dev_err(dev, "failed to register OF clock provider\n");
177 return ret;
178 }
179 }
180
181 return 0;
182}
183EXPORT_SYMBOL_GPL(max_gen_clk_probe);
184
185int max_gen_clk_remove(struct platform_device *pdev, int num_init)
186{
187 struct device *dev = pdev->dev.parent;
188
189 if (dev->of_node)
190 of_clk_del_provider(dev->of_node);
191
192 return 0;
193}
194EXPORT_SYMBOL_GPL(max_gen_clk_remove);
diff --git a/drivers/clk/clk-max-gen.h b/drivers/clk/clk-max-gen.h
deleted file mode 100644
index 997e86fc3f4d..000000000000
--- a/drivers/clk/clk-max-gen.h
+++ /dev/null
@@ -1,32 +0,0 @@
1/*
2 * clk-max-gen.h - Generic clock driver for Maxim PMICs clocks
3 *
4 * Copyright (C) 2014 Google, Inc
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#ifndef __CLK_MAX_GEN_H__
19#define __CLK_MAX_GEN_H__
20
21#include <linux/types.h>
22#include <linux/device.h>
23#include <linux/clkdev.h>
24#include <linux/regmap.h>
25#include <linux/platform_device.h>
26
27int max_gen_clk_probe(struct platform_device *pdev, struct regmap *regmap,
28 u32 reg, struct clk_init_data *clks_init, int num_init);
29int max_gen_clk_remove(struct platform_device *pdev, int num_init);
30extern struct clk_ops max_gen_clk_ops;
31
32#endif /* __CLK_MAX_GEN_H__ */
diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c
index 9b6f2772e948..b637f5979023 100644
--- a/drivers/clk/clk-max77686.c
+++ b/drivers/clk/clk-max77686.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * clk-max77686.c - Clock driver for Maxim 77686 2 * clk-max77686.c - Clock driver for Maxim 77686/MAX77802
3 * 3 *
4 * Copyright (C) 2012 Samsung Electornics 4 * Copyright (C) 2012 Samsung Electornics
5 * Jonghwa Lee <jonghwa3.lee@samsung.com> 5 * Jonghwa Lee <jonghwa3.lee@samsung.com>
@@ -25,46 +25,284 @@
25#include <linux/err.h> 25#include <linux/err.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/mfd/max77620.h>
28#include <linux/mfd/max77686.h> 29#include <linux/mfd/max77686.h>
29#include <linux/mfd/max77686-private.h> 30#include <linux/mfd/max77686-private.h>
30#include <linux/clk-provider.h> 31#include <linux/clk-provider.h>
31#include <linux/mutex.h> 32#include <linux/mutex.h>
32#include <linux/clkdev.h> 33#include <linux/clkdev.h>
34#include <linux/of.h>
35#include <linux/regmap.h>
33 36
34#include <dt-bindings/clock/maxim,max77686.h> 37#include <dt-bindings/clock/maxim,max77686.h>
35#include "clk-max-gen.h" 38#include <dt-bindings/clock/maxim,max77802.h>
39#include <dt-bindings/clock/maxim,max77620.h>
36 40
37static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = { 41#define MAX77802_CLOCK_LOW_JITTER_SHIFT 0x3
42
43enum max77686_chip_name {
44 CHIP_MAX77686,
45 CHIP_MAX77802,
46 CHIP_MAX77620,
47};
48
49struct max77686_hw_clk_info {
50 const char *name;
51 u32 clk_reg;
52 u32 clk_enable_mask;
53 u32 flags;
54};
55
56struct max77686_clk_init_data {
57 struct regmap *regmap;
58 struct clk_hw hw;
59 struct clk_init_data clk_idata;
60 const struct max77686_hw_clk_info *clk_info;
61};
62
63struct max77686_clk_driver_data {
64 enum max77686_chip_name chip;
65 struct max77686_clk_init_data *max_clk_data;
66 size_t num_clks;
67};
68
69static const struct
70max77686_hw_clk_info max77686_hw_clks_info[MAX77686_CLKS_NUM] = {
38 [MAX77686_CLK_AP] = { 71 [MAX77686_CLK_AP] = {
39 .name = "32khz_ap", 72 .name = "32khz_ap",
40 .ops = &max_gen_clk_ops, 73 .clk_reg = MAX77686_REG_32KHZ,
74 .clk_enable_mask = BIT(MAX77686_CLK_AP),
41 }, 75 },
42 [MAX77686_CLK_CP] = { 76 [MAX77686_CLK_CP] = {
43 .name = "32khz_cp", 77 .name = "32khz_cp",
44 .ops = &max_gen_clk_ops, 78 .clk_reg = MAX77686_REG_32KHZ,
79 .clk_enable_mask = BIT(MAX77686_CLK_CP),
45 }, 80 },
46 [MAX77686_CLK_PMIC] = { 81 [MAX77686_CLK_PMIC] = {
47 .name = "32khz_pmic", 82 .name = "32khz_pmic",
48 .ops = &max_gen_clk_ops, 83 .clk_reg = MAX77686_REG_32KHZ,
84 .clk_enable_mask = BIT(MAX77686_CLK_PMIC),
85 },
86};
87
88static const struct
89max77686_hw_clk_info max77802_hw_clks_info[MAX77802_CLKS_NUM] = {
90 [MAX77802_CLK_32K_AP] = {
91 .name = "32khz_ap",
92 .clk_reg = MAX77802_REG_32KHZ,
93 .clk_enable_mask = BIT(MAX77802_CLK_32K_AP),
94 },
95 [MAX77802_CLK_32K_CP] = {
96 .name = "32khz_cp",
97 .clk_reg = MAX77802_REG_32KHZ,
98 .clk_enable_mask = BIT(MAX77802_CLK_32K_CP),
99 },
100};
101
102static const struct
103max77686_hw_clk_info max77620_hw_clks_info[MAX77620_CLKS_NUM] = {
104 [MAX77620_CLK_32K_OUT0] = {
105 .name = "32khz_out0",
106 .clk_reg = MAX77620_REG_CNFG1_32K,
107 .clk_enable_mask = MAX77620_CNFG1_32K_OUT0_EN,
49 }, 108 },
50}; 109};
51 110
111static struct max77686_clk_init_data *to_max77686_clk_init_data(
112 struct clk_hw *hw)
113{
114 return container_of(hw, struct max77686_clk_init_data, hw);
115}
116
117static int max77686_clk_prepare(struct clk_hw *hw)
118{
119 struct max77686_clk_init_data *max77686 = to_max77686_clk_init_data(hw);
120
121 return regmap_update_bits(max77686->regmap, max77686->clk_info->clk_reg,
122 max77686->clk_info->clk_enable_mask,
123 max77686->clk_info->clk_enable_mask);
124}
125
126static void max77686_clk_unprepare(struct clk_hw *hw)
127{
128 struct max77686_clk_init_data *max77686 = to_max77686_clk_init_data(hw);
129
130 regmap_update_bits(max77686->regmap, max77686->clk_info->clk_reg,
131 max77686->clk_info->clk_enable_mask,
132 ~max77686->clk_info->clk_enable_mask);
133}
134
135static int max77686_clk_is_prepared(struct clk_hw *hw)
136{
137 struct max77686_clk_init_data *max77686 = to_max77686_clk_init_data(hw);
138 int ret;
139 u32 val;
140
141 ret = regmap_read(max77686->regmap, max77686->clk_info->clk_reg, &val);
142
143 if (ret < 0)
144 return -EINVAL;
145
146 return val & max77686->clk_info->clk_enable_mask;
147}
148
149static unsigned long max77686_recalc_rate(struct clk_hw *hw,
150 unsigned long parent_rate)
151{
152 return 32768;
153}
154
155static struct clk_ops max77686_clk_ops = {
156 .prepare = max77686_clk_prepare,
157 .unprepare = max77686_clk_unprepare,
158 .is_prepared = max77686_clk_is_prepared,
159 .recalc_rate = max77686_recalc_rate,
160};
161
162static struct clk_hw *
163of_clk_max77686_get(struct of_phandle_args *clkspec, void *data)
164{
165 struct max77686_clk_driver_data *drv_data = data;
166 unsigned int idx = clkspec->args[0];
167
168 if (idx >= drv_data->num_clks) {
169 pr_err("%s: invalid index %u\n", __func__, idx);
170 return ERR_PTR(-EINVAL);
171 }
172
173 return &drv_data->max_clk_data[idx].hw;
174}
175
52static int max77686_clk_probe(struct platform_device *pdev) 176static int max77686_clk_probe(struct platform_device *pdev)
53{ 177{
54 struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); 178 struct device *dev = &pdev->dev;
179 struct device *parent = dev->parent;
180 const struct platform_device_id *id = platform_get_device_id(pdev);
181 struct max77686_clk_driver_data *drv_data;
182 const struct max77686_hw_clk_info *hw_clks;
183 struct regmap *regmap;
184 int i, ret, num_clks;
185
186 drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);
187 if (!drv_data)
188 return -ENOMEM;
189
190 regmap = dev_get_regmap(parent, NULL);
191 if (!regmap) {
192 dev_err(dev, "Failed to get rtc regmap\n");
193 return -ENODEV;
194 }
195
196 drv_data->chip = id->driver_data;
197
198 switch (drv_data->chip) {
199 case CHIP_MAX77686:
200 num_clks = MAX77686_CLKS_NUM;
201 hw_clks = max77686_hw_clks_info;
202 break;
203
204 case CHIP_MAX77802:
205 num_clks = MAX77802_CLKS_NUM;
206 hw_clks = max77802_hw_clks_info;
207 break;
208
209 case CHIP_MAX77620:
210 num_clks = MAX77620_CLKS_NUM;
211 hw_clks = max77620_hw_clks_info;
212 break;
55 213
56 return max_gen_clk_probe(pdev, iodev->regmap, MAX77686_REG_32KHZ, 214 default:
57 max77686_clks_init, MAX77686_CLKS_NUM); 215 dev_err(dev, "Unknown Chip ID\n");
216 return -EINVAL;
217 }
218
219 drv_data->max_clk_data = devm_kcalloc(dev, num_clks,
220 sizeof(*drv_data->max_clk_data),
221 GFP_KERNEL);
222 if (!drv_data->max_clk_data)
223 return -ENOMEM;
224
225 for (i = 0; i < num_clks; i++) {
226 struct max77686_clk_init_data *max_clk_data;
227 const char *clk_name;
228
229 max_clk_data = &drv_data->max_clk_data[i];
230
231 max_clk_data->regmap = regmap;
232 max_clk_data->clk_info = &hw_clks[i];
233 max_clk_data->clk_idata.flags = hw_clks[i].flags;
234 max_clk_data->clk_idata.ops = &max77686_clk_ops;
235
236 if (parent->of_node &&
237 !of_property_read_string_index(parent->of_node,
238 "clock-output-names",
239 i, &clk_name))
240 max_clk_data->clk_idata.name = clk_name;
241 else
242 max_clk_data->clk_idata.name = hw_clks[i].name;
243
244 max_clk_data->hw.init = &max_clk_data->clk_idata;
245
246 ret = devm_clk_hw_register(dev, &max_clk_data->hw);
247 if (ret) {
248 dev_err(dev, "Failed to clock register: %d\n", ret);
249 return ret;
250 }
251
252 ret = clk_hw_register_clkdev(&max_clk_data->hw,
253 max_clk_data->clk_idata.name, NULL);
254 if (ret < 0) {
255 dev_err(dev, "Failed to clkdev register: %d\n", ret);
256 return ret;
257 }
258 }
259
260 if (parent->of_node) {
261 ret = of_clk_add_hw_provider(parent->of_node, of_clk_max77686_get,
262 drv_data);
263
264 if (ret < 0) {
265 dev_err(dev, "Failed to register OF clock provider: %d\n",
266 ret);
267 return ret;
268 }
269 }
270
271 /* MAX77802: Enable low-jitter mode on the 32khz clocks. */
272 if (drv_data->chip == CHIP_MAX77802) {
273 ret = regmap_update_bits(regmap, MAX77802_REG_32KHZ,
274 1 << MAX77802_CLOCK_LOW_JITTER_SHIFT,
275 1 << MAX77802_CLOCK_LOW_JITTER_SHIFT);
276 if (ret < 0) {
277 dev_err(dev, "Failed to config low-jitter: %d\n", ret);
278 goto remove_of_clk_provider;
279 }
280 }
281
282 return 0;
283
284remove_of_clk_provider:
285 if (parent->of_node)
286 of_clk_del_provider(parent->of_node);
287
288 return ret;
58} 289}
59 290
60static int max77686_clk_remove(struct platform_device *pdev) 291static int max77686_clk_remove(struct platform_device *pdev)
61{ 292{
62 return max_gen_clk_remove(pdev, MAX77686_CLKS_NUM); 293 struct device *parent = pdev->dev.parent;
294
295 if (parent->of_node)
296 of_clk_del_provider(parent->of_node);
297
298 return 0;
63} 299}
64 300
65static const struct platform_device_id max77686_clk_id[] = { 301static const struct platform_device_id max77686_clk_id[] = {
66 { "max77686-clk", 0}, 302 { "max77686-clk", .driver_data = CHIP_MAX77686, },
67 { }, 303 { "max77802-clk", .driver_data = CHIP_MAX77802, },
304 { "max77620-clock", .driver_data = CHIP_MAX77620, },
305 {},
68}; 306};
69MODULE_DEVICE_TABLE(platform, max77686_clk_id); 307MODULE_DEVICE_TABLE(platform, max77686_clk_id);
70 308
diff --git a/drivers/clk/clk-max77802.c b/drivers/clk/clk-max77802.c
deleted file mode 100644
index 355dd2e522c3..000000000000
--- a/drivers/clk/clk-max77802.c
+++ /dev/null
@@ -1,96 +0,0 @@
1/*
2 * clk-max77802.c - Clock driver for Maxim 77802
3 *
4 * Copyright (C) 2014 Google, Inc
5 *
6 * Copyright (C) 2012 Samsung Electornics
7 * Jonghwa Lee <jonghwa3.lee@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * This driver is based on clk-max77686.c
20 */
21
22#include <linux/kernel.h>
23#include <linux/slab.h>
24#include <linux/err.h>
25#include <linux/module.h>
26#include <linux/platform_device.h>
27#include <linux/mfd/max77686-private.h>
28#include <linux/clk-provider.h>
29#include <linux/mutex.h>
30#include <linux/clkdev.h>
31
32#include <dt-bindings/clock/maxim,max77802.h>
33#include "clk-max-gen.h"
34
35#define MAX77802_CLOCK_OPMODE_MASK 0x1
36#define MAX77802_CLOCK_LOW_JITTER_SHIFT 0x3
37
38static struct clk_init_data max77802_clks_init[MAX77802_CLKS_NUM] = {
39 [MAX77802_CLK_32K_AP] = {
40 .name = "32khz_ap",
41 .ops = &max_gen_clk_ops,
42 },
43 [MAX77802_CLK_32K_CP] = {
44 .name = "32khz_cp",
45 .ops = &max_gen_clk_ops,
46 },
47};
48
49static int max77802_clk_probe(struct platform_device *pdev)
50{
51 struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
52 int ret;
53
54 ret = max_gen_clk_probe(pdev, iodev->regmap, MAX77802_REG_32KHZ,
55 max77802_clks_init, MAX77802_CLKS_NUM);
56
57 if (ret) {
58 dev_err(&pdev->dev, "generic probe failed %d\n", ret);
59 return ret;
60 }
61
62 /* Enable low-jitter mode on the 32khz clocks. */
63 ret = regmap_update_bits(iodev->regmap, MAX77802_REG_32KHZ,
64 1 << MAX77802_CLOCK_LOW_JITTER_SHIFT,
65 1 << MAX77802_CLOCK_LOW_JITTER_SHIFT);
66 if (ret < 0)
67 dev_err(&pdev->dev, "failed to enable low-jitter mode\n");
68
69 return ret;
70}
71
72static int max77802_clk_remove(struct platform_device *pdev)
73{
74 return max_gen_clk_remove(pdev, MAX77802_CLKS_NUM);
75}
76
77static const struct platform_device_id max77802_clk_id[] = {
78 { "max77802-clk", 0},
79 { },
80};
81MODULE_DEVICE_TABLE(platform, max77802_clk_id);
82
83static struct platform_driver max77802_clk_driver = {
84 .driver = {
85 .name = "max77802-clk",
86 },
87 .probe = max77802_clk_probe,
88 .remove = max77802_clk_remove,
89 .id_table = max77802_clk_id,
90};
91
92module_platform_driver(max77802_clk_driver);
93
94MODULE_DESCRIPTION("MAXIM 77802 Clock Driver");
95MODULE_AUTHOR("Javier Martinez Canillas <javier@osg.samsung.com");
96MODULE_LICENSE("GPL");
diff --git a/drivers/clk/clk-mb86s7x.c b/drivers/clk/clk-mb86s7x.c
index e0817754ca3e..2a83a3ff1d09 100644
--- a/drivers/clk/clk-mb86s7x.c
+++ b/drivers/clk/clk-mb86s7x.c
@@ -327,10 +327,11 @@ static struct clk_ops clk_clc_ops = {
327 .set_rate = clc_set_rate, 327 .set_rate = clc_set_rate,
328}; 328};
329 329
330struct clk *mb86s7x_clclk_register(struct device *cpu_dev) 330static struct clk_hw *mb86s7x_clclk_register(struct device *cpu_dev)
331{ 331{
332 struct clk_init_data init; 332 struct clk_init_data init;
333 struct cl_clk *clc; 333 struct cl_clk *clc;
334 int ret;
334 335
335 clc = kzalloc(sizeof(*clc), GFP_KERNEL); 336 clc = kzalloc(sizeof(*clc), GFP_KERNEL);
336 if (!clc) 337 if (!clc)
@@ -344,14 +345,17 @@ struct clk *mb86s7x_clclk_register(struct device *cpu_dev)
344 init.flags = CLK_GET_RATE_NOCACHE; 345 init.flags = CLK_GET_RATE_NOCACHE;
345 init.num_parents = 0; 346 init.num_parents = 0;
346 347
347 return devm_clk_register(cpu_dev, &clc->hw); 348 ret = devm_clk_hw_register(cpu_dev, &clc->hw);
349 if (ret)
350 return ERR_PTR(ret);
351 return &clc->hw;
348} 352}
349 353
350static int mb86s7x_clclk_of_init(void) 354static int mb86s7x_clclk_of_init(void)
351{ 355{
352 int cpu, ret = -ENODEV; 356 int cpu, ret = -ENODEV;
353 struct device_node *np; 357 struct device_node *np;
354 struct clk *clk; 358 struct clk_hw *hw;
355 359
356 np = of_find_compatible_node(NULL, NULL, "fujitsu,mb86s70-scb-1.0"); 360 np = of_find_compatible_node(NULL, NULL, "fujitsu,mb86s70-scb-1.0");
357 if (!np || !of_device_is_available(np)) 361 if (!np || !of_device_is_available(np))
@@ -365,12 +369,12 @@ static int mb86s7x_clclk_of_init(void)
365 continue; 369 continue;
366 } 370 }
367 371
368 clk = mb86s7x_clclk_register(cpu_dev); 372 hw = mb86s7x_clclk_register(cpu_dev);
369 if (IS_ERR(clk)) { 373 if (IS_ERR(hw)) {
370 pr_err("failed to register cpu%d clock\n", cpu); 374 pr_err("failed to register cpu%d clock\n", cpu);
371 continue; 375 continue;
372 } 376 }
373 if (clk_register_clkdev(clk, NULL, dev_name(cpu_dev))) { 377 if (clk_hw_register_clkdev(hw, NULL, dev_name(cpu_dev))) {
374 pr_err("failed to register cpu%d clock lookup\n", cpu); 378 pr_err("failed to register cpu%d clock lookup\n", cpu);
375 continue; 379 continue;
376 } 380 }
diff --git a/drivers/clk/clk-moxart.c b/drivers/clk/clk-moxart.c
index f37f719643ec..b86dac851116 100644
--- a/drivers/clk/clk-moxart.c
+++ b/drivers/clk/clk-moxart.c
@@ -19,7 +19,8 @@
19static void __init moxart_of_pll_clk_init(struct device_node *node) 19static void __init moxart_of_pll_clk_init(struct device_node *node)
20{ 20{
21 static void __iomem *base; 21 static void __iomem *base;
22 struct clk *clk, *ref_clk; 22 struct clk_hw *hw;
23 struct clk *ref_clk;
23 unsigned int mul; 24 unsigned int mul;
24 const char *name = node->name; 25 const char *name = node->name;
25 const char *parent_name; 26 const char *parent_name;
@@ -42,14 +43,14 @@ static void __init moxart_of_pll_clk_init(struct device_node *node)
42 return; 43 return;
43 } 44 }
44 45
45 clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mul, 1); 46 hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mul, 1);
46 if (IS_ERR(clk)) { 47 if (IS_ERR(hw)) {
47 pr_err("%s: failed to register clock\n", node->full_name); 48 pr_err("%s: failed to register clock\n", node->full_name);
48 return; 49 return;
49 } 50 }
50 51
51 clk_register_clkdev(clk, NULL, name); 52 clk_hw_register_clkdev(hw, NULL, name);
52 of_clk_add_provider(node, of_clk_src_simple_get, clk); 53 of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
53} 54}
54CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock", 55CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock",
55 moxart_of_pll_clk_init); 56 moxart_of_pll_clk_init);
@@ -57,7 +58,8 @@ CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock",
57static void __init moxart_of_apb_clk_init(struct device_node *node) 58static void __init moxart_of_apb_clk_init(struct device_node *node)
58{ 59{
59 static void __iomem *base; 60 static void __iomem *base;
60 struct clk *clk, *pll_clk; 61 struct clk_hw *hw;
62 struct clk *pll_clk;
61 unsigned int div, val; 63 unsigned int div, val;
62 unsigned int div_idx[] = { 2, 3, 4, 6, 8}; 64 unsigned int div_idx[] = { 2, 3, 4, 6, 8};
63 const char *name = node->name; 65 const char *name = node->name;
@@ -85,14 +87,14 @@ static void __init moxart_of_apb_clk_init(struct device_node *node)
85 return; 87 return;
86 } 88 }
87 89
88 clk = clk_register_fixed_factor(NULL, name, parent_name, 0, 1, div); 90 hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, 1, div);
89 if (IS_ERR(clk)) { 91 if (IS_ERR(hw)) {
90 pr_err("%s: failed to register clock\n", node->full_name); 92 pr_err("%s: failed to register clock\n", node->full_name);
91 return; 93 return;
92 } 94 }
93 95
94 clk_register_clkdev(clk, NULL, name); 96 clk_hw_register_clkdev(hw, NULL, name);
95 of_clk_add_provider(node, of_clk_src_simple_get, clk); 97 of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
96} 98}
97CLK_OF_DECLARE(moxart_apb_clock, "moxa,moxart-apb-clock", 99CLK_OF_DECLARE(moxart_apb_clock, "moxa,moxart-apb-clock",
98 moxart_of_apb_clk_init); 100 moxart_of_apb_clk_init);
diff --git a/drivers/clk/clk-nspire.c b/drivers/clk/clk-nspire.c
index 64f196a90816..f861011d5d21 100644
--- a/drivers/clk/clk-nspire.c
+++ b/drivers/clk/clk-nspire.c
@@ -69,7 +69,7 @@ static void __init nspire_ahbdiv_setup(struct device_node *node,
69{ 69{
70 u32 val; 70 u32 val;
71 void __iomem *io; 71 void __iomem *io;
72 struct clk *clk; 72 struct clk_hw *hw;
73 const char *clk_name = node->name; 73 const char *clk_name = node->name;
74 const char *parent_name; 74 const char *parent_name;
75 struct nspire_clk_info info; 75 struct nspire_clk_info info;
@@ -85,10 +85,10 @@ static void __init nspire_ahbdiv_setup(struct device_node *node,
85 of_property_read_string(node, "clock-output-names", &clk_name); 85 of_property_read_string(node, "clock-output-names", &clk_name);
86 parent_name = of_clk_get_parent_name(node, 0); 86 parent_name = of_clk_get_parent_name(node, 0);
87 87
88 clk = clk_register_fixed_factor(NULL, clk_name, parent_name, 0, 88 hw = clk_hw_register_fixed_factor(NULL, clk_name, parent_name, 0,
89 1, info.base_ahb_ratio); 89 1, info.base_ahb_ratio);
90 if (!IS_ERR(clk)) 90 if (!IS_ERR(hw))
91 of_clk_add_provider(node, of_clk_src_simple_get, clk); 91 of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
92} 92}
93 93
94static void __init nspire_ahbdiv_setup_cx(struct device_node *node) 94static void __init nspire_ahbdiv_setup_cx(struct device_node *node)
@@ -111,7 +111,7 @@ static void __init nspire_clk_setup(struct device_node *node,
111{ 111{
112 u32 val; 112 u32 val;
113 void __iomem *io; 113 void __iomem *io;
114 struct clk *clk; 114 struct clk_hw *hw;
115 const char *clk_name = node->name; 115 const char *clk_name = node->name;
116 struct nspire_clk_info info; 116 struct nspire_clk_info info;
117 117
@@ -125,9 +125,10 @@ static void __init nspire_clk_setup(struct device_node *node,
125 125
126 of_property_read_string(node, "clock-output-names", &clk_name); 126 of_property_read_string(node, "clock-output-names", &clk_name);
127 127
128 clk = clk_register_fixed_rate(NULL, clk_name, NULL, 0, info.base_clock); 128 hw = clk_hw_register_fixed_rate(NULL, clk_name, NULL, 0,
129 if (!IS_ERR(clk)) 129 info.base_clock);
130 of_clk_add_provider(node, of_clk_src_simple_get, clk); 130 if (!IS_ERR(hw))
131 of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
131 else 132 else
132 return; 133 return;
133 134
diff --git a/drivers/clk/clk-palmas.c b/drivers/clk/clk-palmas.c
index 8328863cb0e0..31f590cea493 100644
--- a/drivers/clk/clk-palmas.c
+++ b/drivers/clk/clk-palmas.c
@@ -41,7 +41,6 @@ struct palmas_clk32k_desc {
41 41
42struct palmas_clock_info { 42struct palmas_clock_info {
43 struct device *dev; 43 struct device *dev;
44 struct clk *clk;
45 struct clk_hw hw; 44 struct clk_hw hw;
46 struct palmas *palmas; 45 struct palmas *palmas;
47 const struct palmas_clk32k_desc *clk_desc; 46 const struct palmas_clk32k_desc *clk_desc;
@@ -218,7 +217,7 @@ static int palmas_clks_init_configure(struct palmas_clock_info *cinfo)
218 } 217 }
219 218
220 if (cinfo->ext_control_pin) { 219 if (cinfo->ext_control_pin) {
221 ret = clk_prepare(cinfo->clk); 220 ret = clk_prepare(cinfo->hw.clk);
222 if (ret < 0) { 221 if (ret < 0) {
223 dev_err(cinfo->dev, "Clock prep failed, %d\n", ret); 222 dev_err(cinfo->dev, "Clock prep failed, %d\n", ret);
224 return ret; 223 return ret;
@@ -242,7 +241,6 @@ static int palmas_clks_probe(struct platform_device *pdev)
242 struct device_node *node = pdev->dev.of_node; 241 struct device_node *node = pdev->dev.of_node;
243 const struct palmas_clks_of_match_data *match_data; 242 const struct palmas_clks_of_match_data *match_data;
244 struct palmas_clock_info *cinfo; 243 struct palmas_clock_info *cinfo;
245 struct clk *clk;
246 int ret; 244 int ret;
247 245
248 match_data = of_device_get_match_data(&pdev->dev); 246 match_data = of_device_get_match_data(&pdev->dev);
@@ -261,22 +259,20 @@ static int palmas_clks_probe(struct platform_device *pdev)
261 259
262 cinfo->clk_desc = &match_data->desc; 260 cinfo->clk_desc = &match_data->desc;
263 cinfo->hw.init = &match_data->init; 261 cinfo->hw.init = &match_data->init;
264 clk = devm_clk_register(&pdev->dev, &cinfo->hw); 262 ret = devm_clk_hw_register(&pdev->dev, &cinfo->hw);
265 if (IS_ERR(clk)) { 263 if (ret) {
266 ret = PTR_ERR(clk);
267 dev_err(&pdev->dev, "Fail to register clock %s, %d\n", 264 dev_err(&pdev->dev, "Fail to register clock %s, %d\n",
268 match_data->desc.clk_name, ret); 265 match_data->desc.clk_name, ret);
269 return ret; 266 return ret;
270 } 267 }
271 268
272 cinfo->clk = clk;
273 ret = palmas_clks_init_configure(cinfo); 269 ret = palmas_clks_init_configure(cinfo);
274 if (ret < 0) { 270 if (ret < 0) {
275 dev_err(&pdev->dev, "Clock config failed, %d\n", ret); 271 dev_err(&pdev->dev, "Clock config failed, %d\n", ret);
276 return ret; 272 return ret;
277 } 273 }
278 274
279 ret = of_clk_add_provider(node, of_clk_src_simple_get, cinfo->clk); 275 ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &cinfo->hw);
280 if (ret < 0) 276 if (ret < 0)
281 dev_err(&pdev->dev, "Fail to add clock driver, %d\n", ret); 277 dev_err(&pdev->dev, "Fail to add clock driver, %d\n", ret);
282 return ret; 278 return ret;
diff --git a/drivers/clk/clk-pwm.c b/drivers/clk/clk-pwm.c
index 1630a1f085f7..8cb9d117fdbf 100644
--- a/drivers/clk/clk-pwm.c
+++ b/drivers/clk/clk-pwm.c
@@ -61,7 +61,6 @@ static int clk_pwm_probe(struct platform_device *pdev)
61 struct pwm_device *pwm; 61 struct pwm_device *pwm;
62 struct pwm_args pargs; 62 struct pwm_args pargs;
63 const char *clk_name; 63 const char *clk_name;
64 struct clk *clk;
65 int ret; 64 int ret;
66 65
67 clk_pwm = devm_kzalloc(&pdev->dev, sizeof(*clk_pwm), GFP_KERNEL); 66 clk_pwm = devm_kzalloc(&pdev->dev, sizeof(*clk_pwm), GFP_KERNEL);
@@ -107,11 +106,11 @@ static int clk_pwm_probe(struct platform_device *pdev)
107 106
108 clk_pwm->pwm = pwm; 107 clk_pwm->pwm = pwm;
109 clk_pwm->hw.init = &init; 108 clk_pwm->hw.init = &init;
110 clk = devm_clk_register(&pdev->dev, &clk_pwm->hw); 109 ret = devm_clk_hw_register(&pdev->dev, &clk_pwm->hw);
111 if (IS_ERR(clk)) 110 if (ret)
112 return PTR_ERR(clk); 111 return ret;
113 112
114 return of_clk_add_provider(node, of_clk_src_simple_get, clk); 113 return of_clk_add_hw_provider(node, of_clk_hw_simple_get, &clk_pwm->hw);
115} 114}
116 115
117static int clk_pwm_remove(struct platform_device *pdev) 116static int clk_pwm_remove(struct platform_device *pdev)
diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
index 58566a17944a..20b105584f82 100644
--- a/drivers/clk/clk-qoriq.c
+++ b/drivers/clk/clk-qoriq.c
@@ -766,7 +766,11 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
766 if (!hwc) 766 if (!hwc)
767 return NULL; 767 return NULL;
768 768
769 hwc->reg = cg->regs + 0x20 * idx; 769 if (cg->info.flags & CG_VER3)
770 hwc->reg = cg->regs + 0x70000 + 0x20 * idx;
771 else
772 hwc->reg = cg->regs + 0x20 * idx;
773
770 hwc->info = cg->info.cmux_groups[cg->info.cmux_to_group[idx]]; 774 hwc->info = cg->info.cmux_groups[cg->info.cmux_to_group[idx]];
771 775
772 /* 776 /*
diff --git a/drivers/clk/clk-rk808.c b/drivers/clk/clk-rk808.c
index 74383039761e..6461f2820a5b 100644
--- a/drivers/clk/clk-rk808.c
+++ b/drivers/clk/clk-rk808.c
@@ -22,11 +22,8 @@
22#include <linux/mfd/rk808.h> 22#include <linux/mfd/rk808.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24 24
25#define RK808_NR_OUTPUT 2
26
27struct rk808_clkout { 25struct rk808_clkout {
28 struct rk808 *rk808; 26 struct rk808 *rk808;
29 struct clk_onecell_data clk_data;
30 struct clk_hw clkout1_hw; 27 struct clk_hw clkout1_hw;
31 struct clk_hw clkout2_hw; 28 struct clk_hw clkout2_hw;
32}; 29};
@@ -85,14 +82,28 @@ static const struct clk_ops rk808_clkout2_ops = {
85 .recalc_rate = rk808_clkout_recalc_rate, 82 .recalc_rate = rk808_clkout_recalc_rate,
86}; 83};
87 84
85static struct clk_hw *
86of_clk_rk808_get(struct of_phandle_args *clkspec, void *data)
87{
88 struct rk808_clkout *rk808_clkout = data;
89 unsigned int idx = clkspec->args[0];
90
91 if (idx >= 2) {
92 pr_err("%s: invalid index %u\n", __func__, idx);
93 return ERR_PTR(-EINVAL);
94 }
95
96 return idx ? &rk808_clkout->clkout2_hw : &rk808_clkout->clkout1_hw;
97}
98
88static int rk808_clkout_probe(struct platform_device *pdev) 99static int rk808_clkout_probe(struct platform_device *pdev)
89{ 100{
90 struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); 101 struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
91 struct i2c_client *client = rk808->i2c; 102 struct i2c_client *client = rk808->i2c;
92 struct device_node *node = client->dev.of_node; 103 struct device_node *node = client->dev.of_node;
93 struct clk_init_data init = {}; 104 struct clk_init_data init = {};
94 struct clk **clk_table;
95 struct rk808_clkout *rk808_clkout; 105 struct rk808_clkout *rk808_clkout;
106 int ret;
96 107
97 rk808_clkout = devm_kzalloc(&client->dev, 108 rk808_clkout = devm_kzalloc(&client->dev,
98 sizeof(*rk808_clkout), GFP_KERNEL); 109 sizeof(*rk808_clkout), GFP_KERNEL);
@@ -101,11 +112,6 @@ static int rk808_clkout_probe(struct platform_device *pdev)
101 112
102 rk808_clkout->rk808 = rk808; 113 rk808_clkout->rk808 = rk808;
103 114
104 clk_table = devm_kcalloc(&client->dev, RK808_NR_OUTPUT,
105 sizeof(struct clk *), GFP_KERNEL);
106 if (!clk_table)
107 return -ENOMEM;
108
109 init.parent_names = NULL; 115 init.parent_names = NULL;
110 init.num_parents = 0; 116 init.num_parents = 0;
111 init.name = "rk808-clkout1"; 117 init.name = "rk808-clkout1";
@@ -116,10 +122,9 @@ static int rk808_clkout_probe(struct platform_device *pdev)
116 of_property_read_string_index(node, "clock-output-names", 122 of_property_read_string_index(node, "clock-output-names",
117 0, &init.name); 123 0, &init.name);
118 124
119 clk_table[0] = devm_clk_register(&client->dev, 125 ret = devm_clk_hw_register(&client->dev, &rk808_clkout->clkout1_hw);
120 &rk808_clkout->clkout1_hw); 126 if (ret)
121 if (IS_ERR(clk_table[0])) 127 return ret;
122 return PTR_ERR(clk_table[0]);
123 128
124 init.name = "rk808-clkout2"; 129 init.name = "rk808-clkout2";
125 init.ops = &rk808_clkout2_ops; 130 init.ops = &rk808_clkout2_ops;
@@ -129,16 +134,11 @@ static int rk808_clkout_probe(struct platform_device *pdev)
129 of_property_read_string_index(node, "clock-output-names", 134 of_property_read_string_index(node, "clock-output-names",
130 1, &init.name); 135 1, &init.name);
131 136
132 clk_table[1] = devm_clk_register(&client->dev, 137 ret = devm_clk_hw_register(&client->dev, &rk808_clkout->clkout2_hw);
133 &rk808_clkout->clkout2_hw); 138 if (ret)
134 if (IS_ERR(clk_table[1])) 139 return ret;
135 return PTR_ERR(clk_table[1]);
136
137 rk808_clkout->clk_data.clks = clk_table;
138 rk808_clkout->clk_data.clk_num = RK808_NR_OUTPUT;
139 140
140 return of_clk_add_provider(node, of_clk_src_onecell_get, 141 return of_clk_add_hw_provider(node, of_clk_rk808_get, rk808_clkout);
141 &rk808_clkout->clk_data);
142} 142}
143 143
144static int rk808_clkout_remove(struct platform_device *pdev) 144static int rk808_clkout_remove(struct platform_device *pdev)
diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c
index 6962ee5d1e9a..2a3e9d8e88b0 100644
--- a/drivers/clk/clk-scpi.c
+++ b/drivers/clk/clk-scpi.c
@@ -146,13 +146,13 @@ static const struct of_device_id scpi_clk_match[] = {
146 {} 146 {}
147}; 147};
148 148
149static struct clk * 149static int
150scpi_clk_ops_init(struct device *dev, const struct of_device_id *match, 150scpi_clk_ops_init(struct device *dev, const struct of_device_id *match,
151 struct scpi_clk *sclk, const char *name) 151 struct scpi_clk *sclk, const char *name)
152{ 152{
153 struct clk_init_data init; 153 struct clk_init_data init;
154 struct clk *clk;
155 unsigned long min = 0, max = 0; 154 unsigned long min = 0, max = 0;
155 int ret;
156 156
157 init.name = name; 157 init.name = name;
158 init.flags = 0; 158 init.flags = 0;
@@ -164,18 +164,18 @@ scpi_clk_ops_init(struct device *dev, const struct of_device_id *match,
164 if (init.ops == &scpi_dvfs_ops) { 164 if (init.ops == &scpi_dvfs_ops) {
165 sclk->info = sclk->scpi_ops->dvfs_get_info(sclk->id); 165 sclk->info = sclk->scpi_ops->dvfs_get_info(sclk->id);
166 if (IS_ERR(sclk->info)) 166 if (IS_ERR(sclk->info))
167 return NULL; 167 return PTR_ERR(sclk->info);
168 } else if (init.ops == &scpi_clk_ops) { 168 } else if (init.ops == &scpi_clk_ops) {
169 if (sclk->scpi_ops->clk_get_range(sclk->id, &min, &max) || !max) 169 if (sclk->scpi_ops->clk_get_range(sclk->id, &min, &max) || !max)
170 return NULL; 170 return -EINVAL;
171 } else { 171 } else {
172 return NULL; 172 return -EINVAL;
173 } 173 }
174 174
175 clk = devm_clk_register(dev, &sclk->hw); 175 ret = devm_clk_hw_register(dev, &sclk->hw);
176 if (!IS_ERR(clk) && max) 176 if (!ret && max)
177 clk_hw_set_rate_range(&sclk->hw, min, max); 177 clk_hw_set_rate_range(&sclk->hw, min, max);
178 return clk; 178 return ret;
179} 179}
180 180
181struct scpi_clk_data { 181struct scpi_clk_data {
@@ -183,7 +183,7 @@ struct scpi_clk_data {
183 unsigned int clk_num; 183 unsigned int clk_num;
184}; 184};
185 185
186static struct clk * 186static struct clk_hw *
187scpi_of_clk_src_get(struct of_phandle_args *clkspec, void *data) 187scpi_of_clk_src_get(struct of_phandle_args *clkspec, void *data)
188{ 188{
189 struct scpi_clk *sclk; 189 struct scpi_clk *sclk;
@@ -193,7 +193,7 @@ scpi_of_clk_src_get(struct of_phandle_args *clkspec, void *data)
193 for (count = 0; count < clk_data->clk_num; count++) { 193 for (count = 0; count < clk_data->clk_num; count++) {
194 sclk = clk_data->clk[count]; 194 sclk = clk_data->clk[count];
195 if (idx == sclk->id) 195 if (idx == sclk->id)
196 return sclk->hw.clk; 196 return &sclk->hw;
197 } 197 }
198 198
199 return ERR_PTR(-EINVAL); 199 return ERR_PTR(-EINVAL);
@@ -202,8 +202,7 @@ scpi_of_clk_src_get(struct of_phandle_args *clkspec, void *data)
202static int scpi_clk_add(struct device *dev, struct device_node *np, 202static int scpi_clk_add(struct device *dev, struct device_node *np,
203 const struct of_device_id *match) 203 const struct of_device_id *match)
204{ 204{
205 struct clk **clks; 205 int idx, count, err;
206 int idx, count;
207 struct scpi_clk_data *clk_data; 206 struct scpi_clk_data *clk_data;
208 207
209 count = of_property_count_strings(np, "clock-output-names"); 208 count = of_property_count_strings(np, "clock-output-names");
@@ -222,10 +221,6 @@ static int scpi_clk_add(struct device *dev, struct device_node *np,
222 if (!clk_data->clk) 221 if (!clk_data->clk)
223 return -ENOMEM; 222 return -ENOMEM;
224 223
225 clks = devm_kcalloc(dev, count, sizeof(*clks), GFP_KERNEL);
226 if (!clks)
227 return -ENOMEM;
228
229 for (idx = 0; idx < count; idx++) { 224 for (idx = 0; idx < count; idx++) {
230 struct scpi_clk *sclk; 225 struct scpi_clk *sclk;
231 const char *name; 226 const char *name;
@@ -249,15 +244,15 @@ static int scpi_clk_add(struct device *dev, struct device_node *np,
249 244
250 sclk->id = val; 245 sclk->id = val;
251 246
252 clks[idx] = scpi_clk_ops_init(dev, match, sclk, name); 247 err = scpi_clk_ops_init(dev, match, sclk, name);
253 if (IS_ERR_OR_NULL(clks[idx])) 248 if (err)
254 dev_err(dev, "failed to register clock '%s'\n", name); 249 dev_err(dev, "failed to register clock '%s'\n", name);
255 else 250 else
256 dev_dbg(dev, "Registered clock '%s'\n", name); 251 dev_dbg(dev, "Registered clock '%s'\n", name);
257 clk_data->clk[idx] = sclk; 252 clk_data->clk[idx] = sclk;
258 } 253 }
259 254
260 return of_clk_add_provider(np, scpi_of_clk_src_get, clk_data); 255 return of_clk_add_hw_provider(np, scpi_of_clk_src_get, clk_data);
261} 256}
262 257
263static int scpi_clocks_remove(struct platform_device *pdev) 258static int scpi_clocks_remove(struct platform_device *pdev)
diff --git a/drivers/clk/clk-si514.c b/drivers/clk/clk-si514.c
index ceef25b0990b..09b6718956bd 100644
--- a/drivers/clk/clk-si514.c
+++ b/drivers/clk/clk-si514.c
@@ -305,7 +305,6 @@ static int si514_probe(struct i2c_client *client,
305{ 305{
306 struct clk_si514 *data; 306 struct clk_si514 *data;
307 struct clk_init_data init; 307 struct clk_init_data init;
308 struct clk *clk;
309 int err; 308 int err;
310 309
311 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); 310 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
@@ -330,13 +329,13 @@ static int si514_probe(struct i2c_client *client,
330 329
331 i2c_set_clientdata(client, data); 330 i2c_set_clientdata(client, data);
332 331
333 clk = devm_clk_register(&client->dev, &data->hw); 332 err = devm_clk_hw_register(&client->dev, &data->hw);
334 if (IS_ERR(clk)) { 333 if (err) {
335 dev_err(&client->dev, "clock registration failed\n"); 334 dev_err(&client->dev, "clock registration failed\n");
336 return PTR_ERR(clk); 335 return err;
337 } 336 }
338 err = of_clk_add_provider(client->dev.of_node, of_clk_src_simple_get, 337 err = of_clk_add_hw_provider(client->dev.of_node, of_clk_hw_simple_get,
339 clk); 338 &data->hw);
340 if (err) { 339 if (err) {
341 dev_err(&client->dev, "unable to add clk provider\n"); 340 dev_err(&client->dev, "unable to add clk provider\n");
342 return err; 341 return err;
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
index b1bc12c045d3..b051db43fae1 100644
--- a/drivers/clk/clk-si5351.c
+++ b/drivers/clk/clk-si5351.c
@@ -54,7 +54,6 @@ struct si5351_driver_data {
54 enum si5351_variant variant; 54 enum si5351_variant variant;
55 struct i2c_client *client; 55 struct i2c_client *client;
56 struct regmap *regmap; 56 struct regmap *regmap;
57 struct clk_onecell_data onecell;
58 57
59 struct clk *pxtal; 58 struct clk *pxtal;
60 const char *pxtal_name; 59 const char *pxtal_name;
@@ -66,6 +65,7 @@ struct si5351_driver_data {
66 struct si5351_hw_data pll[2]; 65 struct si5351_hw_data pll[2];
67 struct si5351_hw_data *msynth; 66 struct si5351_hw_data *msynth;
68 struct si5351_hw_data *clkout; 67 struct si5351_hw_data *clkout;
68 size_t num_clkout;
69}; 69};
70 70
71static const char * const si5351_input_names[] = { 71static const char * const si5351_input_names[] = {
@@ -1307,11 +1307,31 @@ put_child:
1307 of_node_put(child); 1307 of_node_put(child);
1308 return -EINVAL; 1308 return -EINVAL;
1309} 1309}
1310
1311static struct clk_hw *
1312si53351_of_clk_get(struct of_phandle_args *clkspec, void *data)
1313{
1314 struct si5351_driver_data *drvdata = data;
1315 unsigned int idx = clkspec->args[0];
1316
1317 if (idx >= drvdata->num_clkout) {
1318 pr_err("%s: invalid index %u\n", __func__, idx);
1319 return ERR_PTR(-EINVAL);
1320 }
1321
1322 return &drvdata->clkout[idx].hw;
1323}
1310#else 1324#else
1311static int si5351_dt_parse(struct i2c_client *client, enum si5351_variant variant) 1325static int si5351_dt_parse(struct i2c_client *client, enum si5351_variant variant)
1312{ 1326{
1313 return 0; 1327 return 0;
1314} 1328}
1329
1330static struct clk_hw *
1331si53351_of_clk_get(struct of_phandle_args *clkspec, void *data)
1332{
1333 return NULL;
1334}
1315#endif /* CONFIG_OF */ 1335#endif /* CONFIG_OF */
1316 1336
1317static int si5351_i2c_probe(struct i2c_client *client, 1337static int si5351_i2c_probe(struct i2c_client *client,
@@ -1321,7 +1341,6 @@ static int si5351_i2c_probe(struct i2c_client *client,
1321 struct si5351_platform_data *pdata; 1341 struct si5351_platform_data *pdata;
1322 struct si5351_driver_data *drvdata; 1342 struct si5351_driver_data *drvdata;
1323 struct clk_init_data init; 1343 struct clk_init_data init;
1324 struct clk *clk;
1325 const char *parent_names[4]; 1344 const char *parent_names[4];
1326 u8 num_parents, num_clocks; 1345 u8 num_parents, num_clocks;
1327 int ret, n; 1346 int ret, n;
@@ -1438,10 +1457,9 @@ static int si5351_i2c_probe(struct i2c_client *client,
1438 init.num_parents = 1; 1457 init.num_parents = 1;
1439 } 1458 }
1440 drvdata->xtal.init = &init; 1459 drvdata->xtal.init = &init;
1441 clk = devm_clk_register(&client->dev, &drvdata->xtal); 1460 ret = devm_clk_hw_register(&client->dev, &drvdata->xtal);
1442 if (IS_ERR(clk)) { 1461 if (ret) {
1443 dev_err(&client->dev, "unable to register %s\n", init.name); 1462 dev_err(&client->dev, "unable to register %s\n", init.name);
1444 ret = PTR_ERR(clk);
1445 goto err_clk; 1463 goto err_clk;
1446 } 1464 }
1447 1465
@@ -1456,11 +1474,10 @@ static int si5351_i2c_probe(struct i2c_client *client,
1456 init.num_parents = 1; 1474 init.num_parents = 1;
1457 } 1475 }
1458 drvdata->clkin.init = &init; 1476 drvdata->clkin.init = &init;
1459 clk = devm_clk_register(&client->dev, &drvdata->clkin); 1477 ret = devm_clk_hw_register(&client->dev, &drvdata->clkin);
1460 if (IS_ERR(clk)) { 1478 if (ret) {
1461 dev_err(&client->dev, "unable to register %s\n", 1479 dev_err(&client->dev, "unable to register %s\n",
1462 init.name); 1480 init.name);
1463 ret = PTR_ERR(clk);
1464 goto err_clk; 1481 goto err_clk;
1465 } 1482 }
1466 } 1483 }
@@ -1480,10 +1497,9 @@ static int si5351_i2c_probe(struct i2c_client *client,
1480 init.flags = 0; 1497 init.flags = 0;
1481 init.parent_names = parent_names; 1498 init.parent_names = parent_names;
1482 init.num_parents = num_parents; 1499 init.num_parents = num_parents;
1483 clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw); 1500 ret = devm_clk_hw_register(&client->dev, &drvdata->pll[0].hw);
1484 if (IS_ERR(clk)) { 1501 if (ret) {
1485 dev_err(&client->dev, "unable to register %s\n", init.name); 1502 dev_err(&client->dev, "unable to register %s\n", init.name);
1486 ret = PTR_ERR(clk);
1487 goto err_clk; 1503 goto err_clk;
1488 } 1504 }
1489 1505
@@ -1505,10 +1521,9 @@ static int si5351_i2c_probe(struct i2c_client *client,
1505 init.parent_names = parent_names; 1521 init.parent_names = parent_names;
1506 init.num_parents = num_parents; 1522 init.num_parents = num_parents;
1507 } 1523 }
1508 clk = devm_clk_register(&client->dev, &drvdata->pll[1].hw); 1524 ret = devm_clk_hw_register(&client->dev, &drvdata->pll[1].hw);
1509 if (IS_ERR(clk)) { 1525 if (ret) {
1510 dev_err(&client->dev, "unable to register %s\n", init.name); 1526 dev_err(&client->dev, "unable to register %s\n", init.name);
1511 ret = PTR_ERR(clk);
1512 goto err_clk; 1527 goto err_clk;
1513 } 1528 }
1514 1529
@@ -1524,13 +1539,9 @@ static int si5351_i2c_probe(struct i2c_client *client,
1524 sizeof(*drvdata->msynth), GFP_KERNEL); 1539 sizeof(*drvdata->msynth), GFP_KERNEL);
1525 drvdata->clkout = devm_kzalloc(&client->dev, num_clocks * 1540 drvdata->clkout = devm_kzalloc(&client->dev, num_clocks *
1526 sizeof(*drvdata->clkout), GFP_KERNEL); 1541 sizeof(*drvdata->clkout), GFP_KERNEL);
1542 drvdata->num_clkout = num_clocks;
1527 1543
1528 drvdata->onecell.clk_num = num_clocks; 1544 if (WARN_ON(!drvdata->msynth || !drvdata->clkout)) {
1529 drvdata->onecell.clks = devm_kzalloc(&client->dev,
1530 num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL);
1531
1532 if (WARN_ON(!drvdata->msynth || !drvdata->clkout ||
1533 !drvdata->onecell.clks)) {
1534 ret = -ENOMEM; 1545 ret = -ENOMEM;
1535 goto err_clk; 1546 goto err_clk;
1536 } 1547 }
@@ -1547,11 +1558,11 @@ static int si5351_i2c_probe(struct i2c_client *client,
1547 init.flags |= CLK_SET_RATE_PARENT; 1558 init.flags |= CLK_SET_RATE_PARENT;
1548 init.parent_names = parent_names; 1559 init.parent_names = parent_names;
1549 init.num_parents = 2; 1560 init.num_parents = 2;
1550 clk = devm_clk_register(&client->dev, &drvdata->msynth[n].hw); 1561 ret = devm_clk_hw_register(&client->dev,
1551 if (IS_ERR(clk)) { 1562 &drvdata->msynth[n].hw);
1563 if (ret) {
1552 dev_err(&client->dev, "unable to register %s\n", 1564 dev_err(&client->dev, "unable to register %s\n",
1553 init.name); 1565 init.name);
1554 ret = PTR_ERR(clk);
1555 goto err_clk; 1566 goto err_clk;
1556 } 1567 }
1557 } 1568 }
@@ -1575,19 +1586,19 @@ static int si5351_i2c_probe(struct i2c_client *client,
1575 init.flags |= CLK_SET_RATE_PARENT; 1586 init.flags |= CLK_SET_RATE_PARENT;
1576 init.parent_names = parent_names; 1587 init.parent_names = parent_names;
1577 init.num_parents = num_parents; 1588 init.num_parents = num_parents;
1578 clk = devm_clk_register(&client->dev, &drvdata->clkout[n].hw); 1589 ret = devm_clk_hw_register(&client->dev,
1579 if (IS_ERR(clk)) { 1590 &drvdata->clkout[n].hw);
1591 if (ret) {
1580 dev_err(&client->dev, "unable to register %s\n", 1592 dev_err(&client->dev, "unable to register %s\n",
1581 init.name); 1593 init.name);
1582 ret = PTR_ERR(clk);
1583 goto err_clk; 1594 goto err_clk;
1584 } 1595 }
1585 drvdata->onecell.clks[n] = clk;
1586 1596
1587 /* set initial clkout rate */ 1597 /* set initial clkout rate */
1588 if (pdata->clkout[n].rate != 0) { 1598 if (pdata->clkout[n].rate != 0) {
1589 int ret; 1599 int ret;
1590 ret = clk_set_rate(clk, pdata->clkout[n].rate); 1600 ret = clk_set_rate(drvdata->clkout[n].hw.clk,
1601 pdata->clkout[n].rate);
1591 if (ret != 0) { 1602 if (ret != 0) {
1592 dev_err(&client->dev, "Cannot set rate : %d\n", 1603 dev_err(&client->dev, "Cannot set rate : %d\n",
1593 ret); 1604 ret);
@@ -1595,8 +1606,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
1595 } 1606 }
1596 } 1607 }
1597 1608
1598 ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get, 1609 ret = of_clk_add_hw_provider(client->dev.of_node, si53351_of_clk_get,
1599 &drvdata->onecell); 1610 drvdata);
1600 if (ret) { 1611 if (ret) {
1601 dev_err(&client->dev, "unable to add clk provider\n"); 1612 dev_err(&client->dev, "unable to add clk provider\n");
1602 goto err_clk; 1613 goto err_clk;
diff --git a/drivers/clk/clk-si570.c b/drivers/clk/clk-si570.c
index d56648521a95..646af1d1898d 100644
--- a/drivers/clk/clk-si570.c
+++ b/drivers/clk/clk-si570.c
@@ -408,7 +408,6 @@ static int si570_probe(struct i2c_client *client,
408{ 408{
409 struct clk_si570 *data; 409 struct clk_si570 *data;
410 struct clk_init_data init; 410 struct clk_init_data init;
411 struct clk *clk;
412 u32 initial_fout, factory_fout, stability; 411 u32 initial_fout, factory_fout, stability;
413 int err; 412 int err;
414 enum clk_si570_variant variant = id->driver_data; 413 enum clk_si570_variant variant = id->driver_data;
@@ -462,13 +461,13 @@ static int si570_probe(struct i2c_client *client,
462 if (err) 461 if (err)
463 return err; 462 return err;
464 463
465 clk = devm_clk_register(&client->dev, &data->hw); 464 err = devm_clk_hw_register(&client->dev, &data->hw);
466 if (IS_ERR(clk)) { 465 if (err) {
467 dev_err(&client->dev, "clock registration failed\n"); 466 dev_err(&client->dev, "clock registration failed\n");
468 return PTR_ERR(clk); 467 return err;
469 } 468 }
470 err = of_clk_add_provider(client->dev.of_node, of_clk_src_simple_get, 469 err = of_clk_add_hw_provider(client->dev.of_node, of_clk_hw_simple_get,
471 clk); 470 &data->hw);
472 if (err) { 471 if (err) {
473 dev_err(&client->dev, "unable to add clk provider\n"); 472 dev_err(&client->dev, "unable to add clk provider\n");
474 return err; 473 return err;
@@ -477,7 +476,7 @@ static int si570_probe(struct i2c_client *client,
477 /* Read the requested initial output frequency from device tree */ 476 /* Read the requested initial output frequency from device tree */
478 if (!of_property_read_u32(client->dev.of_node, "clock-frequency", 477 if (!of_property_read_u32(client->dev.of_node, "clock-frequency",
479 &initial_fout)) { 478 &initial_fout)) {
480 err = clk_set_rate(clk, initial_fout); 479 err = clk_set_rate(data->hw.clk, initial_fout);
481 if (err) { 480 if (err) {
482 of_clk_del_provider(client->dev.of_node); 481 of_clk_del_provider(client->dev.of_node);
483 return err; 482 return err;
diff --git a/drivers/clk/clk-twl6040.c b/drivers/clk/clk-twl6040.c
index 697c66757400..7b222a5db931 100644
--- a/drivers/clk/clk-twl6040.c
+++ b/drivers/clk/clk-twl6040.c
@@ -26,60 +26,73 @@
26#include <linux/mfd/twl6040.h> 26#include <linux/mfd/twl6040.h>
27#include <linux/clk-provider.h> 27#include <linux/clk-provider.h>
28 28
29struct twl6040_clk { 29struct twl6040_pdmclk {
30 struct twl6040 *twl6040; 30 struct twl6040 *twl6040;
31 struct device *dev; 31 struct device *dev;
32 struct clk_hw mcpdm_fclk; 32 struct clk_hw pdmclk_hw;
33 struct clk *clk;
34 int enabled; 33 int enabled;
35}; 34};
36 35
37static int twl6040_bitclk_is_enabled(struct clk_hw *hw) 36static int twl6040_pdmclk_is_prepared(struct clk_hw *hw)
38{ 37{
39 struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk, 38 struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk,
40 mcpdm_fclk); 39 pdmclk_hw);
41 return twl6040_clk->enabled; 40
41 return pdmclk->enabled;
42} 42}
43 43
44static int twl6040_bitclk_prepare(struct clk_hw *hw) 44static int twl6040_pdmclk_prepare(struct clk_hw *hw)
45{ 45{
46 struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk, 46 struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk,
47 mcpdm_fclk); 47 pdmclk_hw);
48 int ret; 48 int ret;
49 49
50 ret = twl6040_power(twl6040_clk->twl6040, 1); 50 ret = twl6040_power(pdmclk->twl6040, 1);
51 if (!ret) 51 if (!ret)
52 twl6040_clk->enabled = 1; 52 pdmclk->enabled = 1;
53 53
54 return ret; 54 return ret;
55} 55}
56 56
57static void twl6040_bitclk_unprepare(struct clk_hw *hw) 57static void twl6040_pdmclk_unprepare(struct clk_hw *hw)
58{ 58{
59 struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk, 59 struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk,
60 mcpdm_fclk); 60 pdmclk_hw);
61 int ret; 61 int ret;
62 62
63 ret = twl6040_power(twl6040_clk->twl6040, 0); 63 ret = twl6040_power(pdmclk->twl6040, 0);
64 if (!ret) 64 if (!ret)
65 twl6040_clk->enabled = 0; 65 pdmclk->enabled = 0;
66
66} 67}
67 68
68static const struct clk_ops twl6040_mcpdm_ops = { 69static unsigned long twl6040_pdmclk_recalc_rate(struct clk_hw *hw,
69 .is_enabled = twl6040_bitclk_is_enabled, 70 unsigned long parent_rate)
70 .prepare = twl6040_bitclk_prepare, 71{
71 .unprepare = twl6040_bitclk_unprepare, 72 struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk,
73 pdmclk_hw);
74
75 return twl6040_get_sysclk(pdmclk->twl6040);
76}
77
78static const struct clk_ops twl6040_pdmclk_ops = {
79 .is_prepared = twl6040_pdmclk_is_prepared,
80 .prepare = twl6040_pdmclk_prepare,
81 .unprepare = twl6040_pdmclk_unprepare,
82 .recalc_rate = twl6040_pdmclk_recalc_rate,
72}; 83};
73 84
74static struct clk_init_data wm831x_clkout_init = { 85static struct clk_init_data twl6040_pdmclk_init = {
75 .name = "mcpdm_fclk", 86 .name = "pdmclk",
76 .ops = &twl6040_mcpdm_ops, 87 .ops = &twl6040_pdmclk_ops,
88 .flags = CLK_GET_RATE_NOCACHE,
77}; 89};
78 90
79static int twl6040_clk_probe(struct platform_device *pdev) 91static int twl6040_pdmclk_probe(struct platform_device *pdev)
80{ 92{
81 struct twl6040 *twl6040 = dev_get_drvdata(pdev->dev.parent); 93 struct twl6040 *twl6040 = dev_get_drvdata(pdev->dev.parent);
82 struct twl6040_clk *clkdata; 94 struct twl6040_pdmclk *clkdata;
95 int ret;
83 96
84 clkdata = devm_kzalloc(&pdev->dev, sizeof(*clkdata), GFP_KERNEL); 97 clkdata = devm_kzalloc(&pdev->dev, sizeof(*clkdata), GFP_KERNEL);
85 if (!clkdata) 98 if (!clkdata)
@@ -88,26 +101,28 @@ static int twl6040_clk_probe(struct platform_device *pdev)
88 clkdata->dev = &pdev->dev; 101 clkdata->dev = &pdev->dev;
89 clkdata->twl6040 = twl6040; 102 clkdata->twl6040 = twl6040;
90 103
91 clkdata->mcpdm_fclk.init = &wm831x_clkout_init; 104 clkdata->pdmclk_hw.init = &twl6040_pdmclk_init;
92 clkdata->clk = devm_clk_register(&pdev->dev, &clkdata->mcpdm_fclk); 105 ret = devm_clk_hw_register(&pdev->dev, &clkdata->pdmclk_hw);
93 if (IS_ERR(clkdata->clk)) 106 if (ret)
94 return PTR_ERR(clkdata->clk); 107 return ret;
95 108
96 platform_set_drvdata(pdev, clkdata); 109 platform_set_drvdata(pdev, clkdata);
97 110
98 return 0; 111 return of_clk_add_hw_provider(pdev->dev.parent->of_node,
112 of_clk_hw_simple_get,
113 &clkdata->pdmclk_hw);
99} 114}
100 115
101static struct platform_driver twl6040_clk_driver = { 116static struct platform_driver twl6040_pdmclk_driver = {
102 .driver = { 117 .driver = {
103 .name = "twl6040-clk", 118 .name = "twl6040-pdmclk",
104 }, 119 },
105 .probe = twl6040_clk_probe, 120 .probe = twl6040_pdmclk_probe,
106}; 121};
107 122
108module_platform_driver(twl6040_clk_driver); 123module_platform_driver(twl6040_pdmclk_driver);
109 124
110MODULE_DESCRIPTION("TWL6040 clock driver for McPDM functional clock"); 125MODULE_DESCRIPTION("TWL6040 clock driver for McPDM functional clock");
111MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); 126MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
112MODULE_ALIAS("platform:twl6040-clk"); 127MODULE_ALIAS("platform:twl6040-pdmclk");
113MODULE_LICENSE("GPL"); 128MODULE_LICENSE("GPL");
diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c
index 37368a399ff9..4161a6f25741 100644
--- a/drivers/clk/clk-vt8500.c
+++ b/drivers/clk/clk-vt8500.c
@@ -232,7 +232,7 @@ static const struct clk_ops vt8500_gated_divisor_clk_ops = {
232static __init void vtwm_device_clk_init(struct device_node *node) 232static __init void vtwm_device_clk_init(struct device_node *node)
233{ 233{
234 u32 en_reg, div_reg; 234 u32 en_reg, div_reg;
235 struct clk *clk; 235 struct clk_hw *hw;
236 struct clk_device *dev_clk; 236 struct clk_device *dev_clk;
237 const char *clk_name = node->name; 237 const char *clk_name = node->name;
238 const char *parent_name; 238 const char *parent_name;
@@ -301,13 +301,14 @@ static __init void vtwm_device_clk_init(struct device_node *node)
301 301
302 dev_clk->hw.init = &init; 302 dev_clk->hw.init = &init;
303 303
304 clk = clk_register(NULL, &dev_clk->hw); 304 hw = &dev_clk->hw;
305 if (WARN_ON(IS_ERR(clk))) { 305 rc = clk_hw_register(NULL, hw);
306 if (WARN_ON(rc)) {
306 kfree(dev_clk); 307 kfree(dev_clk);
307 return; 308 return;
308 } 309 }
309 rc = of_clk_add_provider(node, of_clk_src_simple_get, clk); 310 rc = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
310 clk_register_clkdev(clk, clk_name, NULL); 311 clk_hw_register_clkdev(hw, clk_name, NULL);
311} 312}
312CLK_OF_DECLARE(vt8500_device, "via,vt8500-device-clock", vtwm_device_clk_init); 313CLK_OF_DECLARE(vt8500_device, "via,vt8500-device-clock", vtwm_device_clk_init);
313 314
@@ -681,7 +682,7 @@ static const struct clk_ops vtwm_pll_ops = {
681static __init void vtwm_pll_clk_init(struct device_node *node, int pll_type) 682static __init void vtwm_pll_clk_init(struct device_node *node, int pll_type)
682{ 683{
683 u32 reg; 684 u32 reg;
684 struct clk *clk; 685 struct clk_hw *hw;
685 struct clk_pll *pll_clk; 686 struct clk_pll *pll_clk;
686 const char *clk_name = node->name; 687 const char *clk_name = node->name;
687 const char *parent_name; 688 const char *parent_name;
@@ -714,13 +715,14 @@ static __init void vtwm_pll_clk_init(struct device_node *node, int pll_type)
714 715
715 pll_clk->hw.init = &init; 716 pll_clk->hw.init = &init;
716 717
717 clk = clk_register(NULL, &pll_clk->hw); 718 hw = &pll_clk->hw;
718 if (WARN_ON(IS_ERR(clk))) { 719 rc = clk_hw_register(NULL, &pll_clk->hw);
720 if (WARN_ON(rc)) {
719 kfree(pll_clk); 721 kfree(pll_clk);
720 return; 722 return;
721 } 723 }
722 rc = of_clk_add_provider(node, of_clk_src_simple_get, clk); 724 rc = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
723 clk_register_clkdev(clk, clk_name, NULL); 725 clk_hw_register_clkdev(hw, clk_name, NULL);
724} 726}
725 727
726 728
diff --git a/drivers/clk/clk-wm831x.c b/drivers/clk/clk-wm831x.c
index 88def4b2761c..f4fdac55727c 100644
--- a/drivers/clk/clk-wm831x.c
+++ b/drivers/clk/clk-wm831x.c
@@ -24,9 +24,6 @@ struct wm831x_clk {
24 struct clk_hw xtal_hw; 24 struct clk_hw xtal_hw;
25 struct clk_hw fll_hw; 25 struct clk_hw fll_hw;
26 struct clk_hw clkout_hw; 26 struct clk_hw clkout_hw;
27 struct clk *xtal;
28 struct clk *fll;
29 struct clk *clkout;
30 bool xtal_ena; 27 bool xtal_ena;
31}; 28};
32 29
@@ -370,19 +367,19 @@ static int wm831x_clk_probe(struct platform_device *pdev)
370 clkdata->xtal_ena = ret & WM831X_XTAL_ENA; 367 clkdata->xtal_ena = ret & WM831X_XTAL_ENA;
371 368
372 clkdata->xtal_hw.init = &wm831x_xtal_init; 369 clkdata->xtal_hw.init = &wm831x_xtal_init;
373 clkdata->xtal = devm_clk_register(&pdev->dev, &clkdata->xtal_hw); 370 ret = devm_clk_hw_register(&pdev->dev, &clkdata->xtal_hw);
374 if (IS_ERR(clkdata->xtal)) 371 if (ret)
375 return PTR_ERR(clkdata->xtal); 372 return ret;
376 373
377 clkdata->fll_hw.init = &wm831x_fll_init; 374 clkdata->fll_hw.init = &wm831x_fll_init;
378 clkdata->fll = devm_clk_register(&pdev->dev, &clkdata->fll_hw); 375 ret = devm_clk_hw_register(&pdev->dev, &clkdata->fll_hw);
379 if (IS_ERR(clkdata->fll)) 376 if (ret)
380 return PTR_ERR(clkdata->fll); 377 return ret;
381 378
382 clkdata->clkout_hw.init = &wm831x_clkout_init; 379 clkdata->clkout_hw.init = &wm831x_clkout_init;
383 clkdata->clkout = devm_clk_register(&pdev->dev, &clkdata->clkout_hw); 380 ret = devm_clk_hw_register(&pdev->dev, &clkdata->clkout_hw);
384 if (IS_ERR(clkdata->clkout)) 381 if (ret)
385 return PTR_ERR(clkdata->clkout); 382 return ret;
386 383
387 platform_set_drvdata(pdev, clkdata); 384 platform_set_drvdata(pdev, clkdata);
388 385
diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c
index 343313250c58..5daddf5ecc4b 100644
--- a/drivers/clk/clk-xgene.c
+++ b/drivers/clk/clk-xgene.c
@@ -217,6 +217,226 @@ static void xgene_pcppllclk_init(struct device_node *np)
217 xgene_pllclk_init(np, PLL_TYPE_PCP); 217 xgene_pllclk_init(np, PLL_TYPE_PCP);
218} 218}
219 219
220/**
221 * struct xgene_clk_pmd - PMD clock
222 *
223 * @hw: handle between common and hardware-specific interfaces
224 * @reg: register containing the fractional scale multiplier (scaler)
225 * @shift: shift to the unit bit field
226 * @denom: 1/denominator unit
227 * @lock: register lock
228 * Flags:
229 * XGENE_CLK_PMD_SCALE_INVERTED - By default the scaler is the value read
230 * from the register plus one. For example,
231 * 0 for (0 + 1) / denom,
232 * 1 for (1 + 1) / denom and etc.
233 * If this flag is set, it is
234 * 0 for (denom - 0) / denom,
235 * 1 for (denom - 1) / denom and etc.
236 *
237 */
238struct xgene_clk_pmd {
239 struct clk_hw hw;
240 void __iomem *reg;
241 u8 shift;
242 u32 mask;
243 u64 denom;
244 u32 flags;
245 spinlock_t *lock;
246};
247
248#define to_xgene_clk_pmd(_hw) container_of(_hw, struct xgene_clk_pmd, hw)
249
250#define XGENE_CLK_PMD_SCALE_INVERTED BIT(0)
251#define XGENE_CLK_PMD_SHIFT 8
252#define XGENE_CLK_PMD_WIDTH 3
253
254static unsigned long xgene_clk_pmd_recalc_rate(struct clk_hw *hw,
255 unsigned long parent_rate)
256{
257 struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);
258 unsigned long flags = 0;
259 u64 ret, scale;
260 u32 val;
261
262 if (fd->lock)
263 spin_lock_irqsave(fd->lock, flags);
264 else
265 __acquire(fd->lock);
266
267 val = clk_readl(fd->reg);
268
269 if (fd->lock)
270 spin_unlock_irqrestore(fd->lock, flags);
271 else
272 __release(fd->lock);
273
274 ret = (u64)parent_rate;
275
276 scale = (val & fd->mask) >> fd->shift;
277 if (fd->flags & XGENE_CLK_PMD_SCALE_INVERTED)
278 scale = fd->denom - scale;
279 else
280 scale++;
281
282 /* freq = parent_rate * scaler / denom */
283 do_div(ret, fd->denom);
284 ret *= scale;
285 if (ret == 0)
286 ret = (u64)parent_rate;
287
288 return ret;
289}
290
291static long xgene_clk_pmd_round_rate(struct clk_hw *hw, unsigned long rate,
292 unsigned long *parent_rate)
293{
294 struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);
295 u64 ret, scale;
296
297 if (!rate || rate >= *parent_rate)
298 return *parent_rate;
299
300 /* freq = parent_rate * scaler / denom */
301 ret = rate * fd->denom;
302 scale = DIV_ROUND_UP_ULL(ret, *parent_rate);
303
304 ret = (u64)*parent_rate * scale;
305 do_div(ret, fd->denom);
306
307 return ret;
308}
309
310static int xgene_clk_pmd_set_rate(struct clk_hw *hw, unsigned long rate,
311 unsigned long parent_rate)
312{
313 struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);
314 unsigned long flags = 0;
315 u64 scale, ret;
316 u32 val;
317
318 /*
319 * Compute the scaler:
320 *
321 * freq = parent_rate * scaler / denom, or
322 * scaler = freq * denom / parent_rate
323 */
324 ret = rate * fd->denom;
325 scale = DIV_ROUND_UP_ULL(ret, (u64)parent_rate);
326
327 /* Check if inverted */
328 if (fd->flags & XGENE_CLK_PMD_SCALE_INVERTED)
329 scale = fd->denom - scale;
330 else
331 scale--;
332
333 if (fd->lock)
334 spin_lock_irqsave(fd->lock, flags);
335 else
336 __acquire(fd->lock);
337
338 val = clk_readl(fd->reg);
339 val &= ~fd->mask;
340 val |= (scale << fd->shift);
341 clk_writel(val, fd->reg);
342
343 if (fd->lock)
344 spin_unlock_irqrestore(fd->lock, flags);
345 else
346 __release(fd->lock);
347
348 return 0;
349}
350
351static const struct clk_ops xgene_clk_pmd_ops = {
352 .recalc_rate = xgene_clk_pmd_recalc_rate,
353 .round_rate = xgene_clk_pmd_round_rate,
354 .set_rate = xgene_clk_pmd_set_rate,
355};
356
357static struct clk *
358xgene_register_clk_pmd(struct device *dev,
359 const char *name, const char *parent_name,
360 unsigned long flags, void __iomem *reg, u8 shift,
361 u8 width, u64 denom, u32 clk_flags, spinlock_t *lock)
362{
363 struct xgene_clk_pmd *fd;
364 struct clk_init_data init;
365 struct clk *clk;
366
367 fd = kzalloc(sizeof(*fd), GFP_KERNEL);
368 if (!fd)
369 return ERR_PTR(-ENOMEM);
370
371 init.name = name;
372 init.ops = &xgene_clk_pmd_ops;
373 init.flags = flags;
374 init.parent_names = parent_name ? &parent_name : NULL;
375 init.num_parents = parent_name ? 1 : 0;
376
377 fd->reg = reg;
378 fd->shift = shift;
379 fd->mask = (BIT(width) - 1) << shift;
380 fd->denom = denom;
381 fd->flags = clk_flags;
382 fd->lock = lock;
383 fd->hw.init = &init;
384
385 clk = clk_register(dev, &fd->hw);
386 if (IS_ERR(clk)) {
387 pr_err("%s: could not register clk %s\n", __func__, name);
388 kfree(fd);
389 return NULL;
390 }
391
392 return clk;
393}
394
395static void xgene_pmdclk_init(struct device_node *np)
396{
397 const char *clk_name = np->full_name;
398 void __iomem *csr_reg;
399 struct resource res;
400 struct clk *clk;
401 u64 denom;
402 u32 flags = 0;
403 int rc;
404
405 /* Check if the entry is disabled */
406 if (!of_device_is_available(np))
407 return;
408
409 /* Parse the DTS register for resource */
410 rc = of_address_to_resource(np, 0, &res);
411 if (rc != 0) {
412 pr_err("no DTS register for %s\n", np->full_name);
413 return;
414 }
415 csr_reg = of_iomap(np, 0);
416 if (!csr_reg) {
417 pr_err("Unable to map resource for %s\n", np->full_name);
418 return;
419 }
420 of_property_read_string(np, "clock-output-names", &clk_name);
421
422 denom = BIT(XGENE_CLK_PMD_WIDTH);
423 flags |= XGENE_CLK_PMD_SCALE_INVERTED;
424
425 clk = xgene_register_clk_pmd(NULL, clk_name,
426 of_clk_get_parent_name(np, 0), 0,
427 csr_reg, XGENE_CLK_PMD_SHIFT,
428 XGENE_CLK_PMD_WIDTH, denom,
429 flags, &clk_lock);
430 if (!IS_ERR(clk)) {
431 of_clk_add_provider(np, of_clk_src_simple_get, clk);
432 clk_register_clkdev(clk, clk_name, NULL);
433 pr_debug("Add %s clock\n", clk_name);
434 } else {
435 if (csr_reg)
436 iounmap(csr_reg);
437 }
438}
439
220/* IP Clock */ 440/* IP Clock */
221struct xgene_dev_parameters { 441struct xgene_dev_parameters {
222 void __iomem *csr_reg; /* CSR for IP clock */ 442 void __iomem *csr_reg; /* CSR for IP clock */
@@ -543,6 +763,7 @@ err:
543 763
544CLK_OF_DECLARE(xgene_socpll_clock, "apm,xgene-socpll-clock", xgene_socpllclk_init); 764CLK_OF_DECLARE(xgene_socpll_clock, "apm,xgene-socpll-clock", xgene_socpllclk_init);
545CLK_OF_DECLARE(xgene_pcppll_clock, "apm,xgene-pcppll-clock", xgene_pcppllclk_init); 765CLK_OF_DECLARE(xgene_pcppll_clock, "apm,xgene-pcppll-clock", xgene_pcppllclk_init);
766CLK_OF_DECLARE(xgene_pmd_clock, "apm,xgene-pmd-clock", xgene_pmdclk_init);
546CLK_OF_DECLARE(xgene_socpll_v2_clock, "apm,xgene-socpll-v2-clock", 767CLK_OF_DECLARE(xgene_socpll_v2_clock, "apm,xgene-socpll-v2-clock",
547 xgene_socpllclk_init); 768 xgene_socpllclk_init);
548CLK_OF_DECLARE(xgene_pcppll_v2_clock, "apm,xgene-pcppll-v2-clock", 769CLK_OF_DECLARE(xgene_pcppll_v2_clock, "apm,xgene-pcppll-v2-clock",
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 820a939fb6bb..0fb39fe217d1 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1908,10 +1908,6 @@ int clk_set_phase(struct clk *clk, int degrees)
1908 1908
1909 clk_prepare_lock(); 1909 clk_prepare_lock();
1910 1910
1911 /* bail early if nothing to do */
1912 if (degrees == clk->core->phase)
1913 goto out;
1914
1915 trace_clk_set_phase(clk->core, degrees); 1911 trace_clk_set_phase(clk->core, degrees);
1916 1912
1917 if (clk->core->ops->set_phase) 1913 if (clk->core->ops->set_phase)
@@ -1922,7 +1918,6 @@ int clk_set_phase(struct clk *clk, int degrees)
1922 if (!ret) 1918 if (!ret)
1923 clk->core->phase = degrees; 1919 clk->core->phase = degrees;
1924 1920
1925out:
1926 clk_prepare_unlock(); 1921 clk_prepare_unlock();
1927 1922
1928 return ret; 1923 return ret;
@@ -2449,8 +2444,16 @@ static int __clk_core_init(struct clk_core *core)
2449 hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { 2444 hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
2450 struct clk_core *parent = __clk_init_parent(orphan); 2445 struct clk_core *parent = __clk_init_parent(orphan);
2451 2446
2452 if (parent) 2447 /*
2453 clk_core_reparent(orphan, parent); 2448 * we could call __clk_set_parent, but that would result in a
2449 * redundant call to the .set_rate op, if it exists
2450 */
2451 if (parent) {
2452 __clk_set_parent_before(orphan, parent);
2453 __clk_set_parent_after(orphan, parent, NULL);
2454 __clk_recalc_accuracies(orphan);
2455 __clk_recalc_rates(orphan, 0);
2456 }
2454 } 2457 }
2455 2458
2456 /* 2459 /*
@@ -2491,7 +2494,7 @@ struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
2491 2494
2492 /* This is to allow this function to be chained to others */ 2495 /* This is to allow this function to be chained to others */
2493 if (IS_ERR_OR_NULL(hw)) 2496 if (IS_ERR_OR_NULL(hw))
2494 return (struct clk *) hw; 2497 return ERR_CAST(hw);
2495 2498
2496 clk = kzalloc(sizeof(*clk), GFP_KERNEL); 2499 clk = kzalloc(sizeof(*clk), GFP_KERNEL);
2497 if (!clk) 2500 if (!clk)
@@ -3166,19 +3169,14 @@ __of_clk_get_hw_from_provider(struct of_clk_provider *provider,
3166 struct of_phandle_args *clkspec) 3169 struct of_phandle_args *clkspec)
3167{ 3170{
3168 struct clk *clk; 3171 struct clk *clk;
3169 struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
3170 3172
3171 if (provider->get_hw) { 3173 if (provider->get_hw)
3172 hw = provider->get_hw(clkspec, provider->data); 3174 return provider->get_hw(clkspec, provider->data);
3173 } else if (provider->get) {
3174 clk = provider->get(clkspec, provider->data);
3175 if (!IS_ERR(clk))
3176 hw = __clk_get_hw(clk);
3177 else
3178 hw = ERR_CAST(clk);
3179 }
3180 3175
3181 return hw; 3176 clk = provider->get(clkspec, provider->data);
3177 if (IS_ERR(clk))
3178 return ERR_CAST(clk);
3179 return __clk_get_hw(clk);
3182} 3180}
3183 3181
3184struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, 3182struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
@@ -3186,7 +3184,7 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
3186{ 3184{
3187 struct of_clk_provider *provider; 3185 struct of_clk_provider *provider;
3188 struct clk *clk = ERR_PTR(-EPROBE_DEFER); 3186 struct clk *clk = ERR_PTR(-EPROBE_DEFER);
3189 struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER); 3187 struct clk_hw *hw;
3190 3188
3191 if (!clkspec) 3189 if (!clkspec)
3192 return ERR_PTR(-EINVAL); 3190 return ERR_PTR(-EINVAL);
@@ -3194,12 +3192,13 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
3194 /* Check if we have such a provider in our array */ 3192 /* Check if we have such a provider in our array */
3195 mutex_lock(&of_clk_mutex); 3193 mutex_lock(&of_clk_mutex);
3196 list_for_each_entry(provider, &of_clk_providers, link) { 3194 list_for_each_entry(provider, &of_clk_providers, link) {
3197 if (provider->node == clkspec->np) 3195 if (provider->node == clkspec->np) {
3198 hw = __of_clk_get_hw_from_provider(provider, clkspec); 3196 hw = __of_clk_get_hw_from_provider(provider, clkspec);
3199 if (!IS_ERR(hw)) {
3200 clk = __clk_create_clk(hw, dev_id, con_id); 3197 clk = __clk_create_clk(hw, dev_id, con_id);
3198 }
3201 3199
3202 if (!IS_ERR(clk) && !__clk_get(clk)) { 3200 if (!IS_ERR(clk)) {
3201 if (!__clk_get(clk)) {
3203 __clk_free_clk(clk); 3202 __clk_free_clk(clk);
3204 clk = ERR_PTR(-ENOENT); 3203 clk = ERR_PTR(-ENOENT);
3205 } 3204 }
@@ -3451,6 +3450,10 @@ void __init of_clk_init(const struct of_device_id *matches)
3451 &clk_provider_list, node) { 3450 &clk_provider_list, node) {
3452 if (force || parent_ready(clk_provider->np)) { 3451 if (force || parent_ready(clk_provider->np)) {
3453 3452
3453 /* Don't populate platform devices */
3454 of_node_set_flag(clk_provider->np,
3455 OF_POPULATED);
3456
3454 clk_provider->clk_init_cb(clk_provider->np); 3457 clk_provider->clk_init_cb(clk_provider->np);
3455 of_clk_set_defaults(clk_provider->np, true); 3458 of_clk_set_defaults(clk_provider->np, true);
3456 3459
diff --git a/drivers/clk/h8300/clk-div.c b/drivers/clk/h8300/clk-div.c
index 4bf44a25d950..715b882205a8 100644
--- a/drivers/clk/h8300/clk-div.c
+++ b/drivers/clk/h8300/clk-div.c
@@ -14,7 +14,7 @@ static DEFINE_SPINLOCK(clklock);
14static void __init h8300_div_clk_setup(struct device_node *node) 14static void __init h8300_div_clk_setup(struct device_node *node)
15{ 15{
16 unsigned int num_parents; 16 unsigned int num_parents;
17 struct clk *clk; 17 struct clk_hw *hw;
18 const char *clk_name = node->name; 18 const char *clk_name = node->name;
19 const char *parent_name; 19 const char *parent_name;
20 void __iomem *divcr = NULL; 20 void __iomem *divcr = NULL;
@@ -38,15 +38,15 @@ static void __init h8300_div_clk_setup(struct device_node *node)
38 38
39 parent_name = of_clk_get_parent_name(node, 0); 39 parent_name = of_clk_get_parent_name(node, 0);
40 of_property_read_u32(node, "renesas,width", &width); 40 of_property_read_u32(node, "renesas,width", &width);
41 clk = clk_register_divider(NULL, clk_name, parent_name, 41 hw = clk_hw_register_divider(NULL, clk_name, parent_name,
42 CLK_SET_RATE_GATE, divcr, offset, width, 42 CLK_SET_RATE_GATE, divcr, offset, width,
43 CLK_DIVIDER_POWER_OF_TWO, &clklock); 43 CLK_DIVIDER_POWER_OF_TWO, &clklock);
44 if (!IS_ERR(clk)) { 44 if (!IS_ERR(hw)) {
45 of_clk_add_provider(node, of_clk_src_simple_get, clk); 45 of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
46 return; 46 return;
47 } 47 }
48 pr_err("%s: failed to register %s div clock (%ld)\n", 48 pr_err("%s: failed to register %s div clock (%ld)\n",
49 __func__, clk_name, PTR_ERR(clk)); 49 __func__, clk_name, PTR_ERR(hw));
50error: 50error:
51 if (divcr) 51 if (divcr)
52 iounmap(divcr); 52 iounmap(divcr);
diff --git a/drivers/clk/h8300/clk-h8s2678.c b/drivers/clk/h8300/clk-h8s2678.c
index c9c2fd575ef7..a26312460621 100644
--- a/drivers/clk/h8300/clk-h8s2678.c
+++ b/drivers/clk/h8300/clk-h8s2678.c
@@ -84,11 +84,11 @@ static const struct clk_ops pll_ops = {
84static void __init h8s2678_pll_clk_setup(struct device_node *node) 84static void __init h8s2678_pll_clk_setup(struct device_node *node)
85{ 85{
86 unsigned int num_parents; 86 unsigned int num_parents;
87 struct clk *clk;
88 const char *clk_name = node->name; 87 const char *clk_name = node->name;
89 const char *parent_name; 88 const char *parent_name;
90 struct pll_clock *pll_clock; 89 struct pll_clock *pll_clock;
91 struct clk_init_data init; 90 struct clk_init_data init;
91 int ret;
92 92
93 num_parents = of_clk_get_parent_count(node); 93 num_parents = of_clk_get_parent_count(node);
94 if (!num_parents) { 94 if (!num_parents) {
@@ -121,14 +121,14 @@ static void __init h8s2678_pll_clk_setup(struct device_node *node)
121 init.num_parents = 1; 121 init.num_parents = 1;
122 pll_clock->hw.init = &init; 122 pll_clock->hw.init = &init;
123 123
124 clk = clk_register(NULL, &pll_clock->hw); 124 ret = clk_hw_register(NULL, &pll_clock->hw);
125 if (IS_ERR(clk)) { 125 if (ret) {
126 pr_err("%s: failed to register %s div clock (%ld)\n", 126 pr_err("%s: failed to register %s div clock (%d)\n",
127 __func__, clk_name, PTR_ERR(clk)); 127 __func__, clk_name, ret);
128 goto unmap_pllcr; 128 goto unmap_pllcr;
129 } 129 }
130 130
131 of_clk_add_provider(node, of_clk_src_simple_get, clk); 131 of_clk_add_hw_provider(node, of_clk_hw_simple_get, &pll_clock->hw);
132 return; 132 return;
133 133
134unmap_pllcr: 134unmap_pllcr:
diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c
index b0978d3b83e2..203cad6c9aab 100644
--- a/drivers/clk/imx/clk-imx35.c
+++ b/drivers/clk/imx/clk-imx35.c
@@ -66,20 +66,22 @@ static const char *std_sel[] = {"ppll", "arm"};
66static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"}; 66static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"};
67 67
68enum mx35_clks { 68enum mx35_clks {
69 ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg, 69 /* 0 */ ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb,
70 arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel, 70 /* 9 */ ipg, arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div,
71 esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre, 71 /* 15 */ esdhc_sel, esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel,
72 spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre, 72 /* 20 */ spdif_div_pre, spdif_div_post, ssi_sel, ssi1_div_pre,
73 ssi2_div_post, usb_sel, usb_div, nfc_div, asrc_gate, pata_gate, 73 /* 24 */ ssi1_div_post, ssi2_div_pre, ssi2_div_post, usb_sel, usb_div,
74 audmux_gate, can1_gate, can2_gate, cspi1_gate, cspi2_gate, ect_gate, 74 /* 29 */ nfc_div, asrc_gate, pata_gate, audmux_gate, can1_gate,
75 edio_gate, emi_gate, epit1_gate, epit2_gate, esai_gate, esdhc1_gate, 75 /* 34 */ can2_gate, cspi1_gate, cspi2_gate, ect_gate, edio_gate,
76 esdhc2_gate, esdhc3_gate, fec_gate, gpio1_gate, gpio2_gate, gpio3_gate, 76 /* 39 */ emi_gate, epit1_gate, epit2_gate, esai_gate, esdhc1_gate,
77 gpt_gate, i2c1_gate, i2c2_gate, i2c3_gate, iomuxc_gate, ipu_gate, 77 /* 44 */ esdhc2_gate, esdhc3_gate, fec_gate, gpio1_gate, gpio2_gate,
78 kpp_gate, mlb_gate, mshc_gate, owire_gate, pwm_gate, rngc_gate, 78 /* 49 */ gpio3_gate, gpt_gate, i2c1_gate, i2c2_gate, i2c3_gate,
79 rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate, 79 /* 54 */ iomuxc_gate, ipu_gate, kpp_gate, mlb_gate, mshc_gate,
80 ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate, 80 /* 59 */ owire_gate, pwm_gate, rngc_gate, rtc_gate, rtic_gate, scc_gate,
81 wdog_gate, max_gate, admux_gate, csi_gate, csi_div, csi_sel, iim_gate, 81 /* 65 */ sdma_gate, spba_gate, spdif_gate, ssi1_gate, ssi2_gate,
82 gpu2d_gate, ckil, clk_max 82 /* 70 */ uart1_gate, uart2_gate, uart3_gate, usbotg_gate, wdog_gate,
83 /* 75 */ max_gate, admux_gate, csi_gate, csi_div, csi_sel, iim_gate,
84 /* 81 */ gpu2d_gate, ckil, clk_max
83}; 85};
84 86
85static struct clk *clk[clk_max]; 87static struct clk *clk[clk_max];
@@ -115,7 +117,7 @@ static void __init _mx35_clocks_init(void)
115 } 117 }
116 118
117 clk[ckih] = imx_clk_fixed("ckih", 24000000); 119 clk[ckih] = imx_clk_fixed("ckih", 24000000);
118 clk[ckil] = imx_clk_fixed("ckih", 32768); 120 clk[ckil] = imx_clk_fixed("ckil", 32768);
119 clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "mpll", "ckih", base + MX35_CCM_MPCTL); 121 clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "mpll", "ckih", base + MX35_CCM_MPCTL);
120 clk[ppll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "ppll", "ckih", base + MX35_CCM_PPCTL); 122 clk[ppll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "ppll", "ckih", base + MX35_CCM_PPCTL);
121 123
diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c
index 29d4c44ef356..1e3c9ea5f9dc 100644
--- a/drivers/clk/imx/clk-imx51-imx53.c
+++ b/drivers/clk/imx/clk-imx51-imx53.c
@@ -126,6 +126,7 @@ static const char *spdif0_com_sel[] = { "spdif0_podf", "ssi1_root_gate", };
126static const char *mx51_spdif1_com_sel[] = { "spdif1_podf", "ssi2_root_gate", }; 126static const char *mx51_spdif1_com_sel[] = { "spdif1_podf", "ssi2_root_gate", };
127static const char *step_sels[] = { "lp_apm", }; 127static const char *step_sels[] = { "lp_apm", };
128static const char *cpu_podf_sels[] = { "pll1_sw", "step_sel" }; 128static const char *cpu_podf_sels[] = { "pll1_sw", "step_sel" };
129static const char *ieee1588_sels[] = { "pll3_sw", "pll4_sw", "dummy" /* usbphy2_clk */, "dummy" /* fec_phy_clk */ };
129 130
130static struct clk *clk[IMX5_CLK_END]; 131static struct clk *clk[IMX5_CLK_END];
131static struct clk_onecell_data clk_data; 132static struct clk_onecell_data clk_data;
@@ -543,6 +544,25 @@ static void __init mx53_clocks_init(struct device_node *np)
543 clk[IMX5_CLK_I2C3_GATE] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22); 544 clk[IMX5_CLK_I2C3_GATE] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
544 clk[IMX5_CLK_SATA_GATE] = imx_clk_gate2("sata_gate", "ipg", MXC_CCM_CCGR4, 2); 545 clk[IMX5_CLK_SATA_GATE] = imx_clk_gate2("sata_gate", "ipg", MXC_CCM_CCGR4, 2);
545 546
547 clk[IMX5_CLK_FIRI_SEL] = imx_clk_mux("firi_sel", MXC_CCM_CSCMR2, 12, 2,
548 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
549 clk[IMX5_CLK_FIRI_PRED] = imx_clk_divider("firi_pred", "firi_sel", MXC_CCM_CSCDR3, 6, 3);
550 clk[IMX5_CLK_FIRI_PODF] = imx_clk_divider("firi_podf", "firi_pred", MXC_CCM_CSCDR3, 0, 6);
551 clk[IMX5_CLK_FIRI_SERIAL_GATE] = imx_clk_gate2("firi_serial_gate", "firi_podf", MXC_CCM_CCGR1, 28);
552 clk[IMX5_CLK_FIRI_IPG_GATE] = imx_clk_gate2("firi_ipg_gate", "ipg", MXC_CCM_CCGR1, 26);
553
554 clk[IMX5_CLK_CSI0_MCLK1_SEL] = imx_clk_mux("csi0_mclk1_sel", MXC_CCM_CSCMR2, 22, 2,
555 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
556 clk[IMX5_CLK_CSI0_MCLK1_PRED] = imx_clk_divider("csi0_mclk1_pred", "csi0_mclk1_sel", MXC_CCM_CSCDR4, 6, 3);
557 clk[IMX5_CLK_CSI0_MCLK1_PODF] = imx_clk_divider("csi0_mclk1_podf", "csi0_mclk1_pred", MXC_CCM_CSCDR4, 0, 6);
558 clk[IMX5_CLK_CSI0_MCLK1_GATE] = imx_clk_gate2("csi0_mclk1_serial_gate", "csi0_mclk1_podf", MXC_CCM_CCGR6, 4);
559
560 clk[IMX5_CLK_IEEE1588_SEL] = imx_clk_mux("ieee1588_sel", MXC_CCM_CSCMR2, 14, 2,
561 ieee1588_sels, ARRAY_SIZE(ieee1588_sels));
562 clk[IMX5_CLK_IEEE1588_PRED] = imx_clk_divider("ieee1588_pred", "ieee1588_sel", MXC_CCM_CSCDR2, 6, 3);
563 clk[IMX5_CLK_IEEE1588_PODF] = imx_clk_divider("ieee1588_podf", "ieee1588_pred", MXC_CCM_CSCDR2, 0, 6);
564 clk[IMX5_CLK_IEEE1588_GATE] = imx_clk_gate2("ieee1588_serial_gate", "ieee1588_podf", MXC_CCM_CCGR7, 6);
565
546 clk[IMX5_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4, 566 clk[IMX5_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
547 mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel)); 567 mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
548 clk[IMX5_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3); 568 clk[IMX5_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3);
diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index ba1c1ae72ac2..ce8ea10407e4 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -318,11 +318,16 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
318 clk[IMX6QDL_CLK_IPG_PER_SEL] = imx_clk_mux("ipg_per_sel", base + 0x1c, 6, 1, ipg_per_sels, ARRAY_SIZE(ipg_per_sels)); 318 clk[IMX6QDL_CLK_IPG_PER_SEL] = imx_clk_mux("ipg_per_sel", base + 0x1c, 6, 1, ipg_per_sels, ARRAY_SIZE(ipg_per_sels));
319 clk[IMX6QDL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); 319 clk[IMX6QDL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
320 clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels_2, ARRAY_SIZE(gpu2d_core_sels_2)); 320 clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels_2, ARRAY_SIZE(gpu2d_core_sels_2));
321 } else if (clk_on_imx6dl()) {
322 clk[IMX6QDL_CLK_MLB_SEL] = imx_clk_mux("mlb_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels));
321 } else { 323 } else {
322 clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels)); 324 clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels));
323 } 325 }
324 clk[IMX6QDL_CLK_GPU3D_CORE_SEL] = imx_clk_mux("gpu3d_core_sel", base + 0x18, 4, 2, gpu3d_core_sels, ARRAY_SIZE(gpu3d_core_sels)); 326 clk[IMX6QDL_CLK_GPU3D_CORE_SEL] = imx_clk_mux("gpu3d_core_sel", base + 0x18, 4, 2, gpu3d_core_sels, ARRAY_SIZE(gpu3d_core_sels));
325 clk[IMX6QDL_CLK_GPU3D_SHADER_SEL] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels)); 327 if (clk_on_imx6dl())
328 clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels));
329 else
330 clk[IMX6QDL_CLK_GPU3D_SHADER_SEL] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels));
326 clk[IMX6QDL_CLK_IPU1_SEL] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); 331 clk[IMX6QDL_CLK_IPU1_SEL] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
327 clk[IMX6QDL_CLK_IPU2_SEL] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); 332 clk[IMX6QDL_CLK_IPU2_SEL] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
328 clk[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); 333 clk[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
@@ -400,9 +405,15 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
400 clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); 405 clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
401 clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); 406 clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
402 } 407 }
403 clk[IMX6QDL_CLK_GPU2D_CORE_PODF] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3); 408 if (clk_on_imx6dl())
409 clk[IMX6QDL_CLK_MLB_PODF] = imx_clk_divider("mlb_podf", "mlb_sel", base + 0x18, 23, 3);
410 else
411 clk[IMX6QDL_CLK_GPU2D_CORE_PODF] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3);
404 clk[IMX6QDL_CLK_GPU3D_CORE_PODF] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3); 412 clk[IMX6QDL_CLK_GPU3D_CORE_PODF] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3);
405 clk[IMX6QDL_CLK_GPU3D_SHADER] = imx_clk_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3); 413 if (clk_on_imx6dl())
414 clk[IMX6QDL_CLK_GPU2D_CORE_PODF] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 29, 3);
415 else
416 clk[IMX6QDL_CLK_GPU3D_SHADER] = imx_clk_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3);
406 clk[IMX6QDL_CLK_IPU1_PODF] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3); 417 clk[IMX6QDL_CLK_IPU1_PODF] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3);
407 clk[IMX6QDL_CLK_IPU2_PODF] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3); 418 clk[IMX6QDL_CLK_IPU2_PODF] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3);
408 clk[IMX6QDL_CLK_LDB_DI0_PODF] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0); 419 clk[IMX6QDL_CLK_LDB_DI0_PODF] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0);
@@ -473,14 +484,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
473 clk[IMX6QDL_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); 484 clk[IMX6QDL_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai);
474 clk[IMX6QDL_CLK_GPT_IPG] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20); 485 clk[IMX6QDL_CLK_GPT_IPG] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20);
475 clk[IMX6QDL_CLK_GPT_IPG_PER] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22); 486 clk[IMX6QDL_CLK_GPT_IPG_PER] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22);
476 if (clk_on_imx6dl()) 487 clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24);
477 /*
478 * The multiplexer and divider of imx6q clock gpu3d_shader get
479 * redefined/reused as gpu2d_core_sel and gpu2d_core_podf on imx6dl.
480 */
481 clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu3d_shader", base + 0x6c, 24);
482 else
483 clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24);
484 clk[IMX6QDL_CLK_GPU3D_CORE] = imx_clk_gate2("gpu3d_core", "gpu3d_core_podf", base + 0x6c, 26); 488 clk[IMX6QDL_CLK_GPU3D_CORE] = imx_clk_gate2("gpu3d_core", "gpu3d_core_podf", base + 0x6c, 26);
485 clk[IMX6QDL_CLK_HDMI_IAHB] = imx_clk_gate2("hdmi_iahb", "ahb", base + 0x70, 0); 489 clk[IMX6QDL_CLK_HDMI_IAHB] = imx_clk_gate2("hdmi_iahb", "ahb", base + 0x70, 0);
486 clk[IMX6QDL_CLK_HDMI_ISFR] = imx_clk_gate2("hdmi_isfr", "video_27m", base + 0x70, 4); 490 clk[IMX6QDL_CLK_HDMI_ISFR] = imx_clk_gate2("hdmi_isfr", "video_27m", base + 0x70, 4);
@@ -511,7 +515,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
511 * The multiplexer and divider of the imx6q clock gpu2d get 515 * The multiplexer and divider of the imx6q clock gpu2d get
512 * redefined/reused as mlb_sys_sel and mlb_sys_clk_podf on imx6dl. 516 * redefined/reused as mlb_sys_sel and mlb_sys_clk_podf on imx6dl.
513 */ 517 */
514 clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "gpu2d_core_podf", base + 0x74, 18); 518 clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "mlb_podf", base + 0x74, 18);
515 else 519 else
516 clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "axi", base + 0x74, 18); 520 clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "axi", base + 0x74, 18);
517 clk[IMX6QDL_CLK_MMDC_CH0_AXI] = imx_clk_gate2("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20); 521 clk[IMX6QDL_CLK_MMDC_CH0_AXI] = imx_clk_gate2("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20);
@@ -629,6 +633,24 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
629 if (IS_ENABLED(CONFIG_PCI_IMX6)) 633 if (IS_ENABLED(CONFIG_PCI_IMX6))
630 clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]); 634 clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]);
631 635
636 /*
637 * Initialize the GPU clock muxes, so that the maximum specified clock
638 * rates for the respective SoC are not exceeded.
639 */
640 if (clk_on_imx6dl()) {
641 clk_set_parent(clk[IMX6QDL_CLK_GPU3D_CORE_SEL],
642 clk[IMX6QDL_CLK_PLL2_PFD1_594M]);
643 clk_set_parent(clk[IMX6QDL_CLK_GPU2D_CORE_SEL],
644 clk[IMX6QDL_CLK_PLL2_PFD1_594M]);
645 } else if (clk_on_imx6q()) {
646 clk_set_parent(clk[IMX6QDL_CLK_GPU3D_CORE_SEL],
647 clk[IMX6QDL_CLK_MMDC_CH0_AXI]);
648 clk_set_parent(clk[IMX6QDL_CLK_GPU3D_SHADER_SEL],
649 clk[IMX6QDL_CLK_PLL2_PFD1_594M]);
650 clk_set_parent(clk[IMX6QDL_CLK_GPU2D_CORE_SEL],
651 clk[IMX6QDL_CLK_PLL3_USB_OTG]);
652 }
653
632 imx_register_uart_clocks(uart_clks); 654 imx_register_uart_clocks(uart_clks);
633} 655}
634CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init); 656CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
index 6ed4f8fa0667..e7c7353a86fc 100644
--- a/drivers/clk/imx/clk-imx7d.c
+++ b/drivers/clk/imx/clk-imx7d.c
@@ -22,43 +22,63 @@
22 22
23#include "clk.h" 23#include "clk.h"
24 24
25static u32 share_count_sai1;
26static u32 share_count_sai2;
27static u32 share_count_sai3;
28
29static struct clk_div_table test_div_table[] = {
30 { .val = 3, .div = 1, },
31 { .val = 2, .div = 1, },
32 { .val = 1, .div = 2, },
33 { .val = 0, .div = 4, },
34 { }
35};
36
37static struct clk_div_table post_div_table[] = {
38 { .val = 3, .div = 4, },
39 { .val = 2, .div = 1, },
40 { .val = 1, .div = 2, },
41 { .val = 0, .div = 1, },
42 { }
43};
44
25static struct clk *clks[IMX7D_CLK_END]; 45static struct clk *clks[IMX7D_CLK_END];
26static const char *arm_a7_sel[] = { "osc", "pll_arm_main_clk", 46static const char *arm_a7_sel[] = { "osc", "pll_arm_main_clk",
27 "pll_enet_500m_clk", "pll_dram_main_clk", 47 "pll_enet_500m_clk", "pll_dram_main_clk",
28 "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_audio_main_clk", 48 "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_audio_post_div",
29 "pll_usb_main_clk", }; 49 "pll_usb_main_clk", };
30 50
31static const char *arm_m4_sel[] = { "osc", "pll_sys_main_240m_clk", 51static const char *arm_m4_sel[] = { "osc", "pll_sys_main_240m_clk",
32 "pll_enet_250m_clk", "pll_sys_pfd2_270m_clk", 52 "pll_enet_250m_clk", "pll_sys_pfd2_270m_clk",
33 "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk", 53 "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main_clk",
34 "pll_usb_main_clk", }; 54 "pll_usb_main_clk", };
35 55
36static const char *arm_m0_sel[] = { "osc", "pll_sys_main_120m_clk", 56static const char *arm_m0_sel[] = { "osc", "pll_sys_main_120m_clk",
37 "pll_enet_125m_clk", "pll_sys_pfd2_135m_clk", 57 "pll_enet_125m_clk", "pll_sys_pfd2_135m_clk",
38 "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk", 58 "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main_clk",
39 "pll_usb_main_clk", }; 59 "pll_usb_main_clk", };
40 60
41static const char *axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk", 61static const char *axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
42 "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd5_clk", 62 "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd5_clk",
43 "pll_audio_main_clk", "pll_video_main_clk", "pll_sys_pfd7_clk", }; 63 "pll_audio_post_div", "pll_video_main_clk", "pll_sys_pfd7_clk", };
44 64
45static const char *disp_axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk", 65static const char *disp_axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
46 "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd6_clk", 66 "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd6_clk",
47 "pll_sys_pfd7_clk", "pll_audio_main_clk", "pll_video_main_clk", }; 67 "pll_sys_pfd7_clk", "pll_audio_post_div", "pll_video_main_clk", };
48 68
49static const char *enet_axi_sel[] = { "osc", "pll_sys_pfd2_270m_clk", 69static const char *enet_axi_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
50 "pll_dram_533m_clk", "pll_enet_250m_clk", 70 "pll_dram_533m_clk", "pll_enet_250m_clk",
51 "pll_sys_main_240m_clk", "pll_audio_main_clk", "pll_video_main_clk", 71 "pll_sys_main_240m_clk", "pll_audio_post_div", "pll_video_main_clk",
52 "pll_sys_pfd4_clk", }; 72 "pll_sys_pfd4_clk", };
53 73
54static const char *nand_usdhc_bus_sel[] = { "osc", "pll_sys_pfd2_270m_clk", 74static const char *nand_usdhc_bus_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
55 "pll_dram_533m_clk", "pll_sys_main_240m_clk", 75 "pll_dram_533m_clk", "pll_sys_main_240m_clk",
56 "pll_sys_pfd2_135m_clk", "pll_sys_pfd6_clk", "pll_enet_250m_clk", 76 "pll_sys_pfd2_135m_clk", "pll_sys_pfd6_clk", "pll_enet_250m_clk",
57 "pll_audio_main_clk", }; 77 "pll_audio_post_div", };
58 78
59static const char *ahb_channel_sel[] = { "osc", "pll_sys_pfd2_270m_clk", 79static const char *ahb_channel_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
60 "pll_dram_533m_clk", "pll_sys_pfd0_392m_clk", 80 "pll_dram_533m_clk", "pll_sys_pfd0_392m_clk",
61 "pll_enet_125m_clk", "pll_usb_main_clk", "pll_audio_main_clk", 81 "pll_enet_125m_clk", "pll_usb_main_clk", "pll_audio_post_div",
62 "pll_video_main_clk", }; 82 "pll_video_main_clk", };
63 83
64static const char *dram_phym_sel[] = { "pll_dram_main_clk", 84static const char *dram_phym_sel[] = { "pll_dram_main_clk",
@@ -69,13 +89,13 @@ static const char *dram_sel[] = { "pll_dram_main_clk",
69 89
70static const char *dram_phym_alt_sel[] = { "osc", "pll_dram_533m_clk", 90static const char *dram_phym_alt_sel[] = { "osc", "pll_dram_533m_clk",
71 "pll_sys_main_clk", "pll_enet_500m_clk", 91 "pll_sys_main_clk", "pll_enet_500m_clk",
72 "pll_usb_main_clk", "pll_sys_pfd7_clk", "pll_audio_main_clk", 92 "pll_usb_main_clk", "pll_sys_pfd7_clk", "pll_audio_post_div",
73 "pll_video_main_clk", }; 93 "pll_video_main_clk", };
74 94
75static const char *dram_alt_sel[] = { "osc", "pll_dram_533m_clk", 95static const char *dram_alt_sel[] = { "osc", "pll_dram_533m_clk",
76 "pll_sys_main_clk", "pll_enet_500m_clk", 96 "pll_sys_main_clk", "pll_enet_500m_clk",
77 "pll_enet_250m_clk", "pll_sys_pfd0_392m_clk", 97 "pll_enet_250m_clk", "pll_sys_pfd0_392m_clk",
78 "pll_audio_main_clk", "pll_sys_pfd2_270m_clk", }; 98 "pll_audio_post_div", "pll_sys_pfd2_270m_clk", };
79 99
80static const char *usb_hsic_sel[] = { "osc", "pll_sys_main_clk", 100static const char *usb_hsic_sel[] = { "osc", "pll_sys_main_clk",
81 "pll_usb_main_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk", 101 "pll_usb_main_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk",
@@ -101,53 +121,53 @@ static const char *lcdif_pixel_sel[] = { "osc", "pll_sys_pfd5_clk",
101 121
102static const char *mipi_dsi_sel[] = { "osc", "pll_sys_pfd5_clk", 122static const char *mipi_dsi_sel[] = { "osc", "pll_sys_pfd5_clk",
103 "pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk", 123 "pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk",
104 "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_main_clk", }; 124 "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_post_div", };
105 125
106static const char *mipi_csi_sel[] = { "osc", "pll_sys_pfd4_clk", 126static const char *mipi_csi_sel[] = { "osc", "pll_sys_pfd4_clk",
107 "pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk", 127 "pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk",
108 "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_main_clk", }; 128 "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_post_div", };
109 129
110static const char *mipi_dphy_sel[] = { "osc", "pll_sys_main_120m_clk", 130static const char *mipi_dphy_sel[] = { "osc", "pll_sys_main_120m_clk",
111 "pll_dram_533m_clk", "pll_sys_pfd5_clk", "ref_1m_clk", "ext_clk_2", 131 "pll_dram_533m_clk", "pll_sys_pfd5_clk", "ref_1m_clk", "ext_clk_2",
112 "pll_video_main_clk", "ext_clk_3", }; 132 "pll_video_main_clk", "ext_clk_3", };
113 133
114static const char *sai1_sel[] = { "osc", "pll_sys_pfd2_135m_clk", 134static const char *sai1_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
115 "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk", 135 "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main_clk",
116 "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", }; 136 "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", };
117 137
118static const char *sai2_sel[] = { "osc", "pll_sys_pfd2_135m_clk", 138static const char *sai2_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
119 "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk", 139 "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main_clk",
120 "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", }; 140 "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", };
121 141
122static const char *sai3_sel[] = { "osc", "pll_sys_pfd2_135m_clk", 142static const char *sai3_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
123 "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk", 143 "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main_clk",
124 "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_3", }; 144 "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_3", };
125 145
126static const char *spdif_sel[] = { "osc", "pll_sys_pfd2_135m_clk", 146static const char *spdif_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
127 "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk", 147 "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main_clk",
128 "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_3_clk", }; 148 "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_3_clk", };
129 149
130static const char *enet1_ref_sel[] = { "osc", "pll_enet_125m_clk", 150static const char *enet1_ref_sel[] = { "osc", "pll_enet_125m_clk",
131 "pll_enet_50m_clk", "pll_enet_25m_clk", 151 "pll_enet_50m_clk", "pll_enet_25m_clk",
132 "pll_sys_main_120m_clk", "pll_audio_main_clk", "pll_video_main_clk", 152 "pll_sys_main_120m_clk", "pll_audio_post_div", "pll_video_main_clk",
133 "ext_clk_4", }; 153 "ext_clk_4", };
134 154
135static const char *enet1_time_sel[] = { "osc", "pll_enet_100m_clk", 155static const char *enet1_time_sel[] = { "osc", "pll_enet_100m_clk",
136 "pll_audio_main_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3", 156 "pll_audio_post_div", "ext_clk_1", "ext_clk_2", "ext_clk_3",
137 "ext_clk_4", "pll_video_main_clk", }; 157 "ext_clk_4", "pll_video_main_clk", };
138 158
139static const char *enet2_ref_sel[] = { "osc", "pll_enet_125m_clk", 159static const char *enet2_ref_sel[] = { "osc", "pll_enet_125m_clk",
140 "pll_enet_50m_clk", "pll_enet_25m_clk", 160 "pll_enet_50m_clk", "pll_enet_25m_clk",
141 "pll_sys_main_120m_clk", "pll_audio_main_clk", "pll_video_main_clk", 161 "pll_sys_main_120m_clk", "pll_audio_post_div", "pll_video_main_clk",
142 "ext_clk_4", }; 162 "ext_clk_4", };
143 163
144static const char *enet2_time_sel[] = { "osc", "pll_enet_100m_clk", 164static const char *enet2_time_sel[] = { "osc", "pll_enet_100m_clk",
145 "pll_audio_main_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3", 165 "pll_audio_post_div", "ext_clk_1", "ext_clk_2", "ext_clk_3",
146 "ext_clk_4", "pll_video_main_clk", }; 166 "ext_clk_4", "pll_video_main_clk", };
147 167
148static const char *enet_phy_ref_sel[] = { "osc", "pll_enet_25m_clk", 168static const char *enet_phy_ref_sel[] = { "osc", "pll_enet_25m_clk",
149 "pll_enet_50m_clk", "pll_enet_125m_clk", 169 "pll_enet_50m_clk", "pll_enet_125m_clk",
150 "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk", 170 "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main_clk",
151 "pll_sys_pfd3_clk", }; 171 "pll_sys_pfd3_clk", };
152 172
153static const char *eim_sel[] = { "osc", "pll_sys_pfd2_135m_clk", 173static const char *eim_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
@@ -188,22 +208,22 @@ static const char *can2_sel[] = { "osc", "pll_sys_main_120m_clk",
188 208
189static const char *i2c1_sel[] = { "osc", "pll_sys_main_120m_clk", 209static const char *i2c1_sel[] = { "osc", "pll_sys_main_120m_clk",
190 "pll_enet_50m_clk", "pll_dram_533m_clk", 210 "pll_enet_50m_clk", "pll_dram_533m_clk",
191 "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk", 211 "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk",
192 "pll_sys_pfd2_135m_clk", }; 212 "pll_sys_pfd2_135m_clk", };
193 213
194static const char *i2c2_sel[] = { "osc", "pll_sys_main_120m_clk", 214static const char *i2c2_sel[] = { "osc", "pll_sys_main_120m_clk",
195 "pll_enet_50m_clk", "pll_dram_533m_clk", 215 "pll_enet_50m_clk", "pll_dram_533m_clk",
196 "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk", 216 "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk",
197 "pll_sys_pfd2_135m_clk", }; 217 "pll_sys_pfd2_135m_clk", };
198 218
199static const char *i2c3_sel[] = { "osc", "pll_sys_main_120m_clk", 219static const char *i2c3_sel[] = { "osc", "pll_sys_main_120m_clk",
200 "pll_enet_50m_clk", "pll_dram_533m_clk", 220 "pll_enet_50m_clk", "pll_dram_533m_clk",
201 "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk", 221 "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk",
202 "pll_sys_pfd2_135m_clk", }; 222 "pll_sys_pfd2_135m_clk", };
203 223
204static const char *i2c4_sel[] = { "osc", "pll_sys_main_120m_clk", 224static const char *i2c4_sel[] = { "osc", "pll_sys_main_120m_clk",
205 "pll_enet_50m_clk", "pll_dram_533m_clk", 225 "pll_enet_50m_clk", "pll_dram_533m_clk",
206 "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk", 226 "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk",
207 "pll_sys_pfd2_135m_clk", }; 227 "pll_sys_pfd2_135m_clk", };
208 228
209static const char *uart1_sel[] = { "osc", "pll_sys_main_240m_clk", 229static const char *uart1_sel[] = { "osc", "pll_sys_main_240m_clk",
@@ -262,32 +282,32 @@ static const char *ecspi4_sel[] = { "osc", "pll_sys_main_240m_clk",
262 "pll_usb_main_clk", }; 282 "pll_usb_main_clk", };
263 283
264static const char *pwm1_sel[] = { "osc", "pll_enet_100m_clk", 284static const char *pwm1_sel[] = { "osc", "pll_enet_100m_clk",
265 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", 285 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
266 "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", }; 286 "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", };
267 287
268static const char *pwm2_sel[] = { "osc", "pll_enet_100m_clk", 288static const char *pwm2_sel[] = { "osc", "pll_enet_100m_clk",
269 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", 289 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
270 "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", }; 290 "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", };
271 291
272static const char *pwm3_sel[] = { "osc", "pll_enet_100m_clk", 292static const char *pwm3_sel[] = { "osc", "pll_enet_100m_clk",
273 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", 293 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
274 "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", }; 294 "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", };
275 295
276static const char *pwm4_sel[] = { "osc", "pll_enet_100m_clk", 296static const char *pwm4_sel[] = { "osc", "pll_enet_100m_clk",
277 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", 297 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
278 "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", }; 298 "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", };
279 299
280static const char *flextimer1_sel[] = { "osc", "pll_enet_100m_clk", 300static const char *flextimer1_sel[] = { "osc", "pll_enet_100m_clk",
281 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", 301 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
282 "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", }; 302 "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", };
283 303
284static const char *flextimer2_sel[] = { "osc", "pll_enet_100m_clk", 304static const char *flextimer2_sel[] = { "osc", "pll_enet_100m_clk",
285 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", 305 "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
286 "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", }; 306 "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", };
287 307
288static const char *sim1_sel[] = { "osc", "pll_sys_pfd2_135m_clk", 308static const char *sim1_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
289 "pll_sys_main_120m_clk", "pll_dram_533m_clk", 309 "pll_sys_main_120m_clk", "pll_dram_533m_clk",
290 "pll_usb_main_clk", "pll_audio_main_clk", "pll_enet_125m_clk", 310 "pll_usb_main_clk", "pll_audio_post_div", "pll_enet_125m_clk",
291 "pll_sys_pfd7_clk", }; 311 "pll_sys_pfd7_clk", };
292 312
293static const char *sim2_sel[] = { "osc", "pll_sys_pfd2_135m_clk", 313static const char *sim2_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
@@ -297,19 +317,19 @@ static const char *sim2_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
297 317
298static const char *gpt1_sel[] = { "osc", "pll_enet_100m_clk", 318static const char *gpt1_sel[] = { "osc", "pll_enet_100m_clk",
299 "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk", 319 "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
300 "ref_1m_clk", "pll_audio_main_clk", "ext_clk_1", }; 320 "ref_1m_clk", "pll_audio_post_div", "ext_clk_1", };
301 321
302static const char *gpt2_sel[] = { "osc", "pll_enet_100m_clk", 322static const char *gpt2_sel[] = { "osc", "pll_enet_100m_clk",
303 "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk", 323 "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
304 "ref_1m_clk", "pll_audio_main_clk", "ext_clk_2", }; 324 "ref_1m_clk", "pll_audio_post_div", "ext_clk_2", };
305 325
306static const char *gpt3_sel[] = { "osc", "pll_enet_100m_clk", 326static const char *gpt3_sel[] = { "osc", "pll_enet_100m_clk",
307 "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk", 327 "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
308 "ref_1m_clk", "pll_audio_main_clk", "ext_clk_3", }; 328 "ref_1m_clk", "pll_audio_post_div", "ext_clk_3", };
309 329
310static const char *gpt4_sel[] = { "osc", "pll_enet_100m_clk", 330static const char *gpt4_sel[] = { "osc", "pll_enet_100m_clk",
311 "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk", 331 "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
312 "ref_1m_clk", "pll_audio_main_clk", "ext_clk_4", }; 332 "ref_1m_clk", "pll_audio_post_div", "ext_clk_4", };
313 333
314static const char *trace_sel[] = { "osc", "pll_sys_pfd2_135m_clk", 334static const char *trace_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
315 "pll_sys_main_120m_clk", "pll_dram_533m_clk", 335 "pll_sys_main_120m_clk", "pll_dram_533m_clk",
@@ -323,12 +343,12 @@ static const char *wdog_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
323 343
324static const char *csi_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk", 344static const char *csi_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
325 "pll_sys_main_120m_clk", "pll_dram_533m_clk", 345 "pll_sys_main_120m_clk", "pll_dram_533m_clk",
326 "pll_enet_125m_clk", "pll_audio_main_clk", "pll_video_main_clk", 346 "pll_enet_125m_clk", "pll_audio_post_div", "pll_video_main_clk",
327 "pll_usb_main_clk", }; 347 "pll_usb_main_clk", };
328 348
329static const char *audio_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk", 349static const char *audio_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
330 "pll_sys_main_120m_clk", "pll_dram_533m_clk", 350 "pll_sys_main_120m_clk", "pll_dram_533m_clk",
331 "pll_enet_125m_clk", "pll_audio_main_clk", "pll_video_main_clk", 351 "pll_enet_125m_clk", "pll_audio_post_div", "pll_video_main_clk",
332 "pll_usb_main_clk", }; 352 "pll_usb_main_clk", };
333 353
334static const char *wrclk_sel[] = { "osc", "pll_enet_40m_clk", 354static const char *wrclk_sel[] = { "osc", "pll_enet_40m_clk",
@@ -342,13 +362,13 @@ static const char *clko1_sel[] = { "osc", "pll_sys_main_clk",
342 362
343static const char *clko2_sel[] = { "osc", "pll_sys_main_240m_clk", 363static const char *clko2_sel[] = { "osc", "pll_sys_main_240m_clk",
344 "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_166m_clk", "pll_sys_pfd4_clk", 364 "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_166m_clk", "pll_sys_pfd4_clk",
345 "pll_audio_main_clk", "pll_video_main_clk", "ckil", }; 365 "pll_audio_post_div", "pll_video_main_clk", "ckil", };
346 366
347static const char *lvds1_sel[] = { "pll_arm_main_clk", 367static const char *lvds1_sel[] = { "pll_arm_main_clk",
348 "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_332m_clk", 368 "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_332m_clk",
349 "pll_sys_pfd2_270m_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk", 369 "pll_sys_pfd2_270m_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk",
350 "pll_sys_pfd5_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", 370 "pll_sys_pfd5_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk",
351 "pll_audio_main_clk", "pll_video_main_clk", "pll_enet_500m_clk", 371 "pll_audio_post_div", "pll_video_main_clk", "pll_enet_500m_clk",
352 "pll_enet_250m_clk", "pll_enet_125m_clk", "pll_enet_100m_clk", 372 "pll_enet_250m_clk", "pll_enet_125m_clk", "pll_enet_100m_clk",
353 "pll_enet_50m_clk", "pll_enet_40m_clk", "pll_enet_25m_clk", 373 "pll_enet_50m_clk", "pll_enet_40m_clk", "pll_enet_25m_clk",
354 "pll_dram_main_clk", }; 374 "pll_dram_main_clk", };
@@ -430,6 +450,11 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
430 clks[IMX7D_PLL_AUDIO_MAIN_CLK] = imx_clk_gate("pll_audio_main_clk", "pll_audio_main_bypass", base + 0xf0, 13); 450 clks[IMX7D_PLL_AUDIO_MAIN_CLK] = imx_clk_gate("pll_audio_main_clk", "pll_audio_main_bypass", base + 0xf0, 13);
431 clks[IMX7D_PLL_VIDEO_MAIN_CLK] = imx_clk_gate("pll_video_main_clk", "pll_video_main_bypass", base + 0x130, 13); 451 clks[IMX7D_PLL_VIDEO_MAIN_CLK] = imx_clk_gate("pll_video_main_clk", "pll_video_main_bypass", base + 0x130, 13);
432 452
453 clks[IMX7D_PLL_AUDIO_TEST_DIV] = clk_register_divider_table(NULL, "pll_audio_test_div", "pll_audio_main_clk",
454 CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xf0, 19, 2, 0, test_div_table, &imx_ccm_lock);
455 clks[IMX7D_PLL_AUDIO_POST_DIV] = clk_register_divider_table(NULL, "pll_audio_post_div", "pll_audio_test_div",
456 CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xf0, 22, 2, 0, post_div_table, &imx_ccm_lock);
457
433 clks[IMX7D_PLL_SYS_PFD0_392M_CLK] = imx_clk_pfd("pll_sys_pfd0_392m_clk", "pll_sys_main_clk", base + 0xc0, 0); 458 clks[IMX7D_PLL_SYS_PFD0_392M_CLK] = imx_clk_pfd("pll_sys_pfd0_392m_clk", "pll_sys_main_clk", base + 0xc0, 0);
434 clks[IMX7D_PLL_SYS_PFD1_332M_CLK] = imx_clk_pfd("pll_sys_pfd1_332m_clk", "pll_sys_main_clk", base + 0xc0, 1); 459 clks[IMX7D_PLL_SYS_PFD1_332M_CLK] = imx_clk_pfd("pll_sys_pfd1_332m_clk", "pll_sys_main_clk", base + 0xc0, 1);
435 clks[IMX7D_PLL_SYS_PFD2_270M_CLK] = imx_clk_pfd("pll_sys_pfd2_270m_clk", "pll_sys_main_clk", base + 0xc0, 2); 460 clks[IMX7D_PLL_SYS_PFD2_270M_CLK] = imx_clk_pfd("pll_sys_pfd2_270m_clk", "pll_sys_main_clk", base + 0xc0, 2);
@@ -779,6 +804,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
779 clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate4("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0); 804 clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate4("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0);
780 clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0); 805 clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0);
781 clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0); 806 clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0);
807 clks[IMX7D_SDMA_CORE_CLK] = imx_clk_gate4("sdma_root_clk", "ahb_root_clk", base + 0x4480, 0);
782 clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate4("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0); 808 clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate4("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0);
783 clks[IMX7D_PCIE_PHY_ROOT_CLK] = imx_clk_gate4("pcie_phy_root_clk", "pcie_phy_post_div", base + 0x4600, 0); 809 clks[IMX7D_PCIE_PHY_ROOT_CLK] = imx_clk_gate4("pcie_phy_root_clk", "pcie_phy_post_div", base + 0x4600, 0);
784 clks[IMX7D_EPDC_PIXEL_ROOT_CLK] = imx_clk_gate4("epdc_pixel_root_clk", "epdc_pixel_post_div", base + 0x44a0, 0); 810 clks[IMX7D_EPDC_PIXEL_ROOT_CLK] = imx_clk_gate4("epdc_pixel_root_clk", "epdc_pixel_post_div", base + 0x44a0, 0);
@@ -786,9 +812,12 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
786 clks[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_gate4("mipi_dsi_root_clk", "mipi_dsi_post_div", base + 0x4650, 0); 812 clks[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_gate4("mipi_dsi_root_clk", "mipi_dsi_post_div", base + 0x4650, 0);
787 clks[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_gate4("mipi_csi_root_clk", "mipi_csi_post_div", base + 0x4640, 0); 813 clks[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_gate4("mipi_csi_root_clk", "mipi_csi_post_div", base + 0x4640, 0);
788 clks[IMX7D_MIPI_DPHY_ROOT_CLK] = imx_clk_gate4("mipi_dphy_root_clk", "mipi_dphy_post_div", base + 0x4660, 0); 814 clks[IMX7D_MIPI_DPHY_ROOT_CLK] = imx_clk_gate4("mipi_dphy_root_clk", "mipi_dphy_post_div", base + 0x4660, 0);
789 clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate4("sai1_root_clk", "sai1_post_div", base + 0x48c0, 0); 815 clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate2_shared2("sai1_root_clk", "sai1_post_div", base + 0x48c0, 0, &share_count_sai1);
790 clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate4("sai2_root_clk", "sai2_post_div", base + 0x48d0, 0); 816 clks[IMX7D_SAI1_IPG_CLK] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_root_clk", base + 0x48c0, 0, &share_count_sai1);
791 clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate4("sai3_root_clk", "sai3_post_div", base + 0x48e0, 0); 817 clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate2_shared2("sai2_root_clk", "sai2_post_div", base + 0x48d0, 0, &share_count_sai2);
818 clks[IMX7D_SAI2_IPG_CLK] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_root_clk", base + 0x48d0, 0, &share_count_sai2);
819 clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate2_shared2("sai3_root_clk", "sai3_post_div", base + 0x48e0, 0, &share_count_sai3);
820 clks[IMX7D_SAI3_IPG_CLK] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_root_clk", base + 0x48e0, 0, &share_count_sai3);
792 clks[IMX7D_SPDIF_ROOT_CLK] = imx_clk_gate4("spdif_root_clk", "spdif_post_div", base + 0x44d0, 0); 821 clks[IMX7D_SPDIF_ROOT_CLK] = imx_clk_gate4("spdif_root_clk", "spdif_post_div", base + 0x44d0, 0);
793 clks[IMX7D_ENET1_REF_ROOT_CLK] = imx_clk_gate4("enet1_ref_root_clk", "enet1_ref_post_div", base + 0x44e0, 0); 822 clks[IMX7D_ENET1_REF_ROOT_CLK] = imx_clk_gate4("enet1_ref_root_clk", "enet1_ref_post_div", base + 0x44e0, 0);
794 clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate4("enet1_time_root_clk", "enet1_time_post_div", base + 0x44f0, 0); 823 clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate4("enet1_time_root_clk", "enet1_time_post_div", base + 0x44f0, 0);
@@ -860,8 +889,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
860 /* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */ 889 /* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */
861 clk_set_parent(clks[IMX7D_GPT1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]); 890 clk_set_parent(clks[IMX7D_GPT1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
862 891
863 clk_set_parent(clks[IMX7D_ENET_AXI_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_250M_CLK]);
864
865 /* set uart module clock's parent clock source that must be great then 80MHz */ 892 /* set uart module clock's parent clock source that must be great then 80MHz */
866 clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]); 893 clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
867 894
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index a81c0385ed64..3799ff82a9b4 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -134,6 +134,15 @@ static inline struct clk *imx_clk_gate2_shared(const char *name,
134 shift, 0x3, 0, &imx_ccm_lock, share_count); 134 shift, 0x3, 0, &imx_ccm_lock, share_count);
135} 135}
136 136
137static inline struct clk *imx_clk_gate2_shared2(const char *name,
138 const char *parent, void __iomem *reg, u8 shift,
139 unsigned int *share_count)
140{
141 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
142 CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0,
143 &imx_ccm_lock, share_count);
144}
145
137static inline struct clk *imx_clk_gate2_cgr(const char *name, 146static inline struct clk *imx_clk_gate2_cgr(const char *name,
138 const char *parent, void __iomem *reg, u8 shift, u8 cgr_val) 147 const char *parent, void __iomem *reg, u8 shift, u8 cgr_val)
139{ 148{
diff --git a/drivers/clk/loongson1/Makefile b/drivers/clk/loongson1/Makefile
new file mode 100644
index 000000000000..b7f6a16390e0
--- /dev/null
+++ b/drivers/clk/loongson1/Makefile
@@ -0,0 +1,3 @@
1obj-y += clk.o
2obj-$(CONFIG_LOONGSON1_LS1B) += clk-loongson1b.o
3obj-$(CONFIG_LOONGSON1_LS1C) += clk-loongson1c.o
diff --git a/drivers/clk/loongson1/clk-loongson1b.c b/drivers/clk/loongson1/clk-loongson1b.c
new file mode 100644
index 000000000000..f36a97e993c0
--- /dev/null
+++ b/drivers/clk/loongson1/clk-loongson1b.c
@@ -0,0 +1,122 @@
1/*
2 * Copyright (c) 2012-2016 Zhang, Keguang <keguang.zhang@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#include <linux/clkdev.h>
11#include <linux/clk-provider.h>
12#include <linux/io.h>
13#include <linux/err.h>
14
15#include <loongson1.h>
16#include "clk.h"
17
18#define OSC (33 * 1000000)
19#define DIV_APB 2
20
21static DEFINE_SPINLOCK(_lock);
22
23static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw,
24 unsigned long parent_rate)
25{
26 u32 pll, rate;
27
28 pll = __raw_readl(LS1X_CLK_PLL_FREQ);
29 rate = 12 + (pll & GENMASK(5, 0));
30 rate *= OSC;
31 rate >>= 1;
32
33 return rate;
34}
35
36static const struct clk_ops ls1x_pll_clk_ops = {
37 .recalc_rate = ls1x_pll_recalc_rate,
38};
39
40static const char *const cpu_parents[] = { "cpu_clk_div", "osc_clk", };
41static const char *const ahb_parents[] = { "ahb_clk_div", "osc_clk", };
42static const char *const dc_parents[] = { "dc_clk_div", "osc_clk", };
43
44void __init ls1x_clk_init(void)
45{
46 struct clk_hw *hw;
47
48 hw = clk_hw_register_fixed_rate(NULL, "osc_clk", NULL, 0, OSC);
49 clk_hw_register_clkdev(hw, "osc_clk", NULL);
50
51 /* clock derived from 33 MHz OSC clk */
52 hw = clk_hw_register_pll(NULL, "pll_clk", "osc_clk",
53 &ls1x_pll_clk_ops, 0);
54 clk_hw_register_clkdev(hw, "pll_clk", NULL);
55
56 /* clock derived from PLL clk */
57 /* _____
58 * _______________________| |
59 * OSC ___/ | MUX |___ CPU CLK
60 * \___ PLL ___ CPU DIV ___| |
61 * |_____|
62 */
63 hw = clk_hw_register_divider(NULL, "cpu_clk_div", "pll_clk",
64 CLK_GET_RATE_NOCACHE, LS1X_CLK_PLL_DIV,
65 DIV_CPU_SHIFT, DIV_CPU_WIDTH,
66 CLK_DIVIDER_ONE_BASED |
67 CLK_DIVIDER_ROUND_CLOSEST, &_lock);
68 clk_hw_register_clkdev(hw, "cpu_clk_div", NULL);
69 hw = clk_hw_register_mux(NULL, "cpu_clk", cpu_parents,
70 ARRAY_SIZE(cpu_parents),
71 CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV,
72 BYPASS_CPU_SHIFT, BYPASS_CPU_WIDTH, 0, &_lock);
73 clk_hw_register_clkdev(hw, "cpu_clk", NULL);
74
75 /* _____
76 * _______________________| |
77 * OSC ___/ | MUX |___ DC CLK
78 * \___ PLL ___ DC DIV ___| |
79 * |_____|
80 */
81 hw = clk_hw_register_divider(NULL, "dc_clk_div", "pll_clk",
82 0, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT,
83 DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock);
84 clk_hw_register_clkdev(hw, "dc_clk_div", NULL);
85 hw = clk_hw_register_mux(NULL, "dc_clk", dc_parents,
86 ARRAY_SIZE(dc_parents),
87 CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV,
88 BYPASS_DC_SHIFT, BYPASS_DC_WIDTH, 0, &_lock);
89 clk_hw_register_clkdev(hw, "dc_clk", NULL);
90
91 /* _____
92 * _______________________| |
93 * OSC ___/ | MUX |___ DDR CLK
94 * \___ PLL ___ DDR DIV ___| |
95 * |_____|
96 */
97 hw = clk_hw_register_divider(NULL, "ahb_clk_div", "pll_clk",
98 0, LS1X_CLK_PLL_DIV, DIV_DDR_SHIFT,
99 DIV_DDR_WIDTH, CLK_DIVIDER_ONE_BASED,
100 &_lock);
101 clk_hw_register_clkdev(hw, "ahb_clk_div", NULL);
102 hw = clk_hw_register_mux(NULL, "ahb_clk", ahb_parents,
103 ARRAY_SIZE(ahb_parents),
104 CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV,
105 BYPASS_DDR_SHIFT, BYPASS_DDR_WIDTH, 0, &_lock);
106 clk_hw_register_clkdev(hw, "ahb_clk", NULL);
107 clk_hw_register_clkdev(hw, "ls1x-dma", NULL);
108 clk_hw_register_clkdev(hw, "stmmaceth", NULL);
109
110 /* clock derived from AHB clk */
111 /* APB clk is always half of the AHB clk */
112 hw = clk_hw_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1,
113 DIV_APB);
114 clk_hw_register_clkdev(hw, "apb_clk", NULL);
115 clk_hw_register_clkdev(hw, "ls1x-ac97", NULL);
116 clk_hw_register_clkdev(hw, "ls1x-i2c", NULL);
117 clk_hw_register_clkdev(hw, "ls1x-nand", NULL);
118 clk_hw_register_clkdev(hw, "ls1x-pwmtimer", NULL);
119 clk_hw_register_clkdev(hw, "ls1x-spi", NULL);
120 clk_hw_register_clkdev(hw, "ls1x-wdt", NULL);
121 clk_hw_register_clkdev(hw, "serial8250", NULL);
122}
diff --git a/drivers/clk/loongson1/clk-loongson1c.c b/drivers/clk/loongson1/clk-loongson1c.c
new file mode 100644
index 000000000000..3466f7320b40
--- /dev/null
+++ b/drivers/clk/loongson1/clk-loongson1c.c
@@ -0,0 +1,97 @@
1/*
2 * Copyright (c) 2016 Yang Ling <gnaygnil@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#include <linux/clkdev.h>
11#include <linux/clk-provider.h>
12
13#include <loongson1.h>
14#include "clk.h"
15
16#define OSC (24 * 1000000)
17#define DIV_APB 1
18
19static DEFINE_SPINLOCK(_lock);
20
21static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw,
22 unsigned long parent_rate)
23{
24 u32 pll, rate;
25
26 pll = __raw_readl(LS1X_CLK_PLL_FREQ);
27 rate = ((pll >> 8) & 0xff) + ((pll >> 16) & 0xff);
28 rate *= OSC;
29 rate >>= 2;
30
31 return rate;
32}
33
34static const struct clk_ops ls1x_pll_clk_ops = {
35 .recalc_rate = ls1x_pll_recalc_rate,
36};
37
38static const struct clk_div_table ahb_div_table[] = {
39 [0] = { .val = 0, .div = 2 },
40 [1] = { .val = 1, .div = 4 },
41 [2] = { .val = 2, .div = 3 },
42 [3] = { .val = 3, .div = 3 },
43};
44
45void __init ls1x_clk_init(void)
46{
47 struct clk_hw *hw;
48
49 hw = clk_hw_register_fixed_rate(NULL, "osc_clk", NULL, 0, OSC);
50 clk_hw_register_clkdev(hw, "osc_clk", NULL);
51
52 /* clock derived from 24 MHz OSC clk */
53 hw = clk_hw_register_pll(NULL, "pll_clk", "osc_clk",
54 &ls1x_pll_clk_ops, 0);
55 clk_hw_register_clkdev(hw, "pll_clk", NULL);
56
57 hw = clk_hw_register_divider(NULL, "cpu_clk_div", "pll_clk",
58 CLK_GET_RATE_NOCACHE, LS1X_CLK_PLL_DIV,
59 DIV_CPU_SHIFT, DIV_CPU_WIDTH,
60 CLK_DIVIDER_ONE_BASED |
61 CLK_DIVIDER_ROUND_CLOSEST, &_lock);
62 clk_hw_register_clkdev(hw, "cpu_clk_div", NULL);
63 hw = clk_hw_register_fixed_factor(NULL, "cpu_clk", "cpu_clk_div",
64 0, 1, 1);
65 clk_hw_register_clkdev(hw, "cpu_clk", NULL);
66
67 hw = clk_hw_register_divider(NULL, "dc_clk_div", "pll_clk",
68 0, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT,
69 DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock);
70 clk_hw_register_clkdev(hw, "dc_clk_div", NULL);
71 hw = clk_hw_register_fixed_factor(NULL, "dc_clk", "dc_clk_div",
72 0, 1, 1);
73 clk_hw_register_clkdev(hw, "dc_clk", NULL);
74
75 hw = clk_hw_register_divider_table(NULL, "ahb_clk_div", "cpu_clk_div",
76 0, LS1X_CLK_PLL_FREQ, DIV_DDR_SHIFT,
77 DIV_DDR_WIDTH, CLK_DIVIDER_ALLOW_ZERO,
78 ahb_div_table, &_lock);
79 clk_hw_register_clkdev(hw, "ahb_clk_div", NULL);
80 hw = clk_hw_register_fixed_factor(NULL, "ahb_clk", "ahb_clk_div",
81 0, 1, 1);
82 clk_hw_register_clkdev(hw, "ahb_clk", NULL);
83 clk_hw_register_clkdev(hw, "ls1x-dma", NULL);
84 clk_hw_register_clkdev(hw, "stmmaceth", NULL);
85
86 /* clock derived from AHB clk */
87 hw = clk_hw_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1,
88 DIV_APB);
89 clk_hw_register_clkdev(hw, "apb_clk", NULL);
90 clk_hw_register_clkdev(hw, "ls1x-ac97", NULL);
91 clk_hw_register_clkdev(hw, "ls1x-i2c", NULL);
92 clk_hw_register_clkdev(hw, "ls1x-nand", NULL);
93 clk_hw_register_clkdev(hw, "ls1x-pwmtimer", NULL);
94 clk_hw_register_clkdev(hw, "ls1x-spi", NULL);
95 clk_hw_register_clkdev(hw, "ls1x-wdt", NULL);
96 clk_hw_register_clkdev(hw, "serial8250", NULL);
97}
diff --git a/drivers/clk/loongson1/clk.c b/drivers/clk/loongson1/clk.c
new file mode 100644
index 000000000000..cfcfd143fccb
--- /dev/null
+++ b/drivers/clk/loongson1/clk.c
@@ -0,0 +1,43 @@
1/*
2 * Copyright (c) 2012-2016 Zhang, Keguang <keguang.zhang@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#include <linux/clk-provider.h>
11#include <linux/slab.h>
12
13struct clk_hw *__init clk_hw_register_pll(struct device *dev,
14 const char *name,
15 const char *parent_name,
16 const struct clk_ops *ops,
17 unsigned long flags)
18{
19 int ret;
20 struct clk_hw *hw;
21 struct clk_init_data init;
22
23 /* allocate the divider */
24 hw = kzalloc(sizeof(*hw), GFP_KERNEL);
25 if (!hw)
26 return ERR_PTR(-ENOMEM);
27
28 init.name = name;
29 init.ops = ops;
30 init.flags = flags | CLK_IS_BASIC;
31 init.parent_names = (parent_name ? &parent_name : NULL);
32 init.num_parents = (parent_name ? 1 : 0);
33 hw->init = &init;
34
35 /* register the clock */
36 ret = clk_hw_register(dev, hw);
37 if (ret) {
38 kfree(hw);
39 hw = ERR_PTR(ret);
40 }
41
42 return hw;
43}
diff --git a/drivers/clk/loongson1/clk.h b/drivers/clk/loongson1/clk.h
new file mode 100644
index 000000000000..085d74b5d496
--- /dev/null
+++ b/drivers/clk/loongson1/clk.h
@@ -0,0 +1,19 @@
1/*
2 * Copyright (c) 2012-2016 Zhang, Keguang <keguang.zhang@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#ifndef __LOONGSON1_CLK_H
11#define __LOONGSON1_CLK_H
12
13struct clk_hw *clk_hw_register_pll(struct device *dev,
14 const char *name,
15 const char *parent_name,
16 const struct clk_ops *ops,
17 unsigned long flags);
18
19#endif /* __LOONGSON1_CLK_H */
diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
new file mode 100644
index 000000000000..380c372d528e
--- /dev/null
+++ b/drivers/clk/mediatek/Kconfig
@@ -0,0 +1,21 @@
1#
2# MediaTek SoC drivers
3#
4config COMMON_CLK_MEDIATEK
5 bool
6 ---help---
7 Mediatek SoCs' clock support.
8
9config COMMON_CLK_MT8135
10 bool "Clock driver for Mediatek MT8135"
11 select COMMON_CLK_MEDIATEK
12 default ARCH_MEDIATEK
13 ---help---
14 This driver supports Mediatek MT8135 clocks.
15
16config COMMON_CLK_MT8173
17 bool "Clock driver for Mediatek MT8173"
18 select COMMON_CLK_MEDIATEK
19 default ARCH_MEDIATEK
20 ---help---
21 This driver supports Mediatek MT8173 clocks.
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 95fdfacb2ebf..32e7222e7305 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1,4 +1,4 @@
1obj-y += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o 1obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o
2obj-$(CONFIG_RESET_CONTROLLER) += reset.o 2obj-$(CONFIG_RESET_CONTROLLER) += reset.o
3obj-y += clk-mt8135.o 3obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
4obj-y += clk-mt8173.o 4obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o
diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
index 2a76901bf04b..d8787bf444eb 100644
--- a/drivers/clk/mediatek/clk-gate.c
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -97,7 +97,7 @@ const struct clk_ops mtk_clk_gate_ops_setclr_inv = {
97 .disable = mtk_cg_disable_inv, 97 .disable = mtk_cg_disable_inv,
98}; 98};
99 99
100struct clk * __init mtk_clk_register_gate( 100struct clk *mtk_clk_register_gate(
101 const char *name, 101 const char *name,
102 const char *parent_name, 102 const char *parent_name,
103 struct regmap *regmap, 103 struct regmap *regmap,
diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 10c986018a08..0ac3aee87726 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -1074,8 +1074,10 @@ static void __init mtk_apmixedsys_init(struct device_node *node)
1074 } 1074 }
1075 1075
1076 mt8173_pll_clk_data = clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); 1076 mt8173_pll_clk_data = clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
1077 if (!clk_data) 1077 if (!clk_data) {
1078 iounmap(base);
1078 return; 1079 return;
1080 }
1079 1081
1080 mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); 1082 mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
1081 1083
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 5ada644e6200..bb30f7063569 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -24,7 +24,7 @@
24#include "clk-mtk.h" 24#include "clk-mtk.h"
25#include "clk-gate.h" 25#include "clk-gate.h"
26 26
27struct clk_onecell_data * __init mtk_alloc_clk_data(unsigned int clk_num) 27struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
28{ 28{
29 int i; 29 int i;
30 struct clk_onecell_data *clk_data; 30 struct clk_onecell_data *clk_data;
@@ -49,7 +49,7 @@ err_out:
49 return NULL; 49 return NULL;
50} 50}
51 51
52void __init mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, 52void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
53 int num, struct clk_onecell_data *clk_data) 53 int num, struct clk_onecell_data *clk_data)
54{ 54{
55 int i; 55 int i;
@@ -72,7 +72,7 @@ void __init mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
72 } 72 }
73} 73}
74 74
75void __init mtk_clk_register_factors(const struct mtk_fixed_factor *clks, 75void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
76 int num, struct clk_onecell_data *clk_data) 76 int num, struct clk_onecell_data *clk_data)
77{ 77{
78 int i; 78 int i;
@@ -95,7 +95,7 @@ void __init mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
95 } 95 }
96} 96}
97 97
98int __init mtk_clk_register_gates(struct device_node *node, 98int mtk_clk_register_gates(struct device_node *node,
99 const struct mtk_gate *clks, 99 const struct mtk_gate *clks,
100 int num, struct clk_onecell_data *clk_data) 100 int num, struct clk_onecell_data *clk_data)
101{ 101{
@@ -135,7 +135,7 @@ int __init mtk_clk_register_gates(struct device_node *node,
135 return 0; 135 return 0;
136} 136}
137 137
138struct clk * __init mtk_clk_register_composite(const struct mtk_composite *mc, 138struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
139 void __iomem *base, spinlock_t *lock) 139 void __iomem *base, spinlock_t *lock)
140{ 140{
141 struct clk *clk; 141 struct clk *clk;
@@ -222,7 +222,7 @@ err_out:
222 return ERR_PTR(ret); 222 return ERR_PTR(ret);
223} 223}
224 224
225void __init mtk_clk_register_composites(const struct mtk_composite *mcs, 225void mtk_clk_register_composites(const struct mtk_composite *mcs,
226 int num, void __iomem *base, spinlock_t *lock, 226 int num, void __iomem *base, spinlock_t *lock,
227 struct clk_onecell_data *clk_data) 227 struct clk_onecell_data *clk_data)
228{ 228{
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index 966cab1348da..0c2deac17ce9 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -313,7 +313,7 @@ static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data,
313 return clk; 313 return clk;
314} 314}
315 315
316void __init mtk_clk_register_plls(struct device_node *node, 316void mtk_clk_register_plls(struct device_node *node,
317 const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data) 317 const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
318{ 318{
319 void __iomem *base; 319 void __iomem *base;
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 197e40175166..349583405b7c 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -3,5 +3,5 @@
3# 3#
4 4
5obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o 5obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o
6obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b-clkc.o 6obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o
7obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o 7obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index 53326c32e853..9bb70e7a7d6a 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -98,7 +98,7 @@ struct meson_clk_mpll {
98}; 98};
99 99
100#define MESON_GATE(_name, _reg, _bit) \ 100#define MESON_GATE(_name, _reg, _bit) \
101struct clk_gate gxbb_##_name = { \ 101struct clk_gate _name = { \
102 .reg = (void __iomem *) _reg, \ 102 .reg = (void __iomem *) _reg, \
103 .bit_idx = (_bit), \ 103 .bit_idx = (_bit), \
104 .lock = &clk_lock, \ 104 .lock = &clk_lock, \
diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c
new file mode 100644
index 000000000000..b45c5fba7e35
--- /dev/null
+++ b/drivers/clk/meson/gxbb-aoclk.c
@@ -0,0 +1,191 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright (c) 2016 BayLibre, SAS.
8 * Author: Neil Armstrong <narmstrong@baylibre.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 * The full GNU General Public License is included in this distribution
22 * in the file called COPYING.
23 *
24 * BSD LICENSE
25 *
26 * Copyright (c) 2016 BayLibre, SAS.
27 * Author: Neil Armstrong <narmstrong@baylibre.com>
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55#include <linux/clk-provider.h>
56#include <linux/of_address.h>
57#include <linux/platform_device.h>
58#include <linux/reset-controller.h>
59#include <linux/init.h>
60#include <dt-bindings/clock/gxbb-aoclkc.h>
61#include <dt-bindings/reset/gxbb-aoclkc.h>
62
63static DEFINE_SPINLOCK(gxbb_aoclk_lock);
64
65struct gxbb_aoclk_reset_controller {
66 struct reset_controller_dev reset;
67 unsigned int *data;
68 void __iomem *base;
69};
70
71static int gxbb_aoclk_do_reset(struct reset_controller_dev *rcdev,
72 unsigned long id)
73{
74 struct gxbb_aoclk_reset_controller *reset =
75 container_of(rcdev, struct gxbb_aoclk_reset_controller, reset);
76
77 writel(BIT(reset->data[id]), reset->base);
78
79 return 0;
80}
81
82static const struct reset_control_ops gxbb_aoclk_reset_ops = {
83 .reset = gxbb_aoclk_do_reset,
84};
85
86#define GXBB_AO_GATE(_name, _bit) \
87static struct clk_gate _name##_ao = { \
88 .reg = (void __iomem *)0, \
89 .bit_idx = (_bit), \
90 .lock = &gxbb_aoclk_lock, \
91 .hw.init = &(struct clk_init_data) { \
92 .name = #_name "_ao", \
93 .ops = &clk_gate_ops, \
94 .parent_names = (const char *[]){ "clk81" }, \
95 .num_parents = 1, \
96 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
97 }, \
98}
99
100GXBB_AO_GATE(remote, 0);
101GXBB_AO_GATE(i2c_master, 1);
102GXBB_AO_GATE(i2c_slave, 2);
103GXBB_AO_GATE(uart1, 3);
104GXBB_AO_GATE(uart2, 5);
105GXBB_AO_GATE(ir_blaster, 6);
106
107static unsigned int gxbb_aoclk_reset[] = {
108 [RESET_AO_REMOTE] = 16,
109 [RESET_AO_I2C_MASTER] = 18,
110 [RESET_AO_I2C_SLAVE] = 19,
111 [RESET_AO_UART1] = 17,
112 [RESET_AO_UART2] = 22,
113 [RESET_AO_IR_BLASTER] = 23,
114};
115
116static struct clk_gate *gxbb_aoclk_gate[] = {
117 [CLKID_AO_REMOTE] = &remote_ao,
118 [CLKID_AO_I2C_MASTER] = &i2c_master_ao,
119 [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao,
120 [CLKID_AO_UART1] = &uart1_ao,
121 [CLKID_AO_UART2] = &uart2_ao,
122 [CLKID_AO_IR_BLASTER] = &ir_blaster_ao,
123};
124
125static struct clk_hw_onecell_data gxbb_aoclk_onecell_data = {
126 .hws = {
127 [CLKID_AO_REMOTE] = &remote_ao.hw,
128 [CLKID_AO_I2C_MASTER] = &i2c_master_ao.hw,
129 [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao.hw,
130 [CLKID_AO_UART1] = &uart1_ao.hw,
131 [CLKID_AO_UART2] = &uart2_ao.hw,
132 [CLKID_AO_IR_BLASTER] = &ir_blaster_ao.hw,
133 },
134 .num = ARRAY_SIZE(gxbb_aoclk_gate),
135};
136
137static int gxbb_aoclkc_probe(struct platform_device *pdev)
138{
139 struct resource *res;
140 void __iomem *base;
141 int ret, clkid;
142 struct device *dev = &pdev->dev;
143 struct gxbb_aoclk_reset_controller *rstc;
144
145 rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL);
146 if (!rstc)
147 return -ENOMEM;
148
149 /* Generic clocks */
150 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
151 base = devm_ioremap_resource(dev, res);
152 if (IS_ERR(base))
153 return PTR_ERR(base);
154
155 /* Reset Controller */
156 rstc->base = base;
157 rstc->data = gxbb_aoclk_reset;
158 rstc->reset.ops = &gxbb_aoclk_reset_ops;
159 rstc->reset.nr_resets = ARRAY_SIZE(gxbb_aoclk_reset);
160 rstc->reset.of_node = dev->of_node;
161 ret = devm_reset_controller_register(dev, &rstc->reset);
162
163 /*
164 * Populate base address and register all clks
165 */
166 for (clkid = 0; clkid < gxbb_aoclk_onecell_data.num; clkid++) {
167 gxbb_aoclk_gate[clkid]->reg = base;
168
169 ret = devm_clk_hw_register(dev,
170 gxbb_aoclk_onecell_data.hws[clkid]);
171 if (ret)
172 return ret;
173 }
174
175 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
176 &gxbb_aoclk_onecell_data);
177}
178
179static const struct of_device_id gxbb_aoclkc_match_table[] = {
180 { .compatible = "amlogic,gxbb-aoclkc" },
181 { }
182};
183
184static struct platform_driver gxbb_aoclkc_driver = {
185 .probe = gxbb_aoclkc_probe,
186 .driver = {
187 .name = "gxbb-aoclkc",
188 .of_match_table = gxbb_aoclkc_match_table,
189 },
190};
191builtin_platform_driver(gxbb_aoclkc_driver);
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index a4c6684b3019..9d9af446bafc 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -565,90 +565,93 @@ static struct clk_gate gxbb_clk81 = {
565}; 565};
566 566
567/* Everything Else (EE) domain gates */ 567/* Everything Else (EE) domain gates */
568static MESON_GATE(ddr, HHI_GCLK_MPEG0, 0); 568static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0);
569static MESON_GATE(dos, HHI_GCLK_MPEG0, 1); 569static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1);
570static MESON_GATE(isa, HHI_GCLK_MPEG0, 5); 570static MESON_GATE(gxbb_isa, HHI_GCLK_MPEG0, 5);
571static MESON_GATE(pl301, HHI_GCLK_MPEG0, 6); 571static MESON_GATE(gxbb_pl301, HHI_GCLK_MPEG0, 6);
572static MESON_GATE(periphs, HHI_GCLK_MPEG0, 7); 572static MESON_GATE(gxbb_periphs, HHI_GCLK_MPEG0, 7);
573static MESON_GATE(spicc, HHI_GCLK_MPEG0, 8); 573static MESON_GATE(gxbb_spicc, HHI_GCLK_MPEG0, 8);
574static MESON_GATE(i2c, HHI_GCLK_MPEG0, 9); 574static MESON_GATE(gxbb_i2c, HHI_GCLK_MPEG0, 9);
575static MESON_GATE(sar_adc, HHI_GCLK_MPEG0, 10); 575static MESON_GATE(gxbb_sar_adc, HHI_GCLK_MPEG0, 10);
576static MESON_GATE(smart_card, HHI_GCLK_MPEG0, 11); 576static MESON_GATE(gxbb_smart_card, HHI_GCLK_MPEG0, 11);
577static MESON_GATE(rng0, HHI_GCLK_MPEG0, 12); 577static MESON_GATE(gxbb_rng0, HHI_GCLK_MPEG0, 12);
578static MESON_GATE(uart0, HHI_GCLK_MPEG0, 13); 578static MESON_GATE(gxbb_uart0, HHI_GCLK_MPEG0, 13);
579static MESON_GATE(sdhc, HHI_GCLK_MPEG0, 14); 579static MESON_GATE(gxbb_sdhc, HHI_GCLK_MPEG0, 14);
580static MESON_GATE(stream, HHI_GCLK_MPEG0, 15); 580static MESON_GATE(gxbb_stream, HHI_GCLK_MPEG0, 15);
581static MESON_GATE(async_fifo, HHI_GCLK_MPEG0, 16); 581static MESON_GATE(gxbb_async_fifo, HHI_GCLK_MPEG0, 16);
582static MESON_GATE(sdio, HHI_GCLK_MPEG0, 17); 582static MESON_GATE(gxbb_sdio, HHI_GCLK_MPEG0, 17);
583static MESON_GATE(abuf, HHI_GCLK_MPEG0, 18); 583static MESON_GATE(gxbb_abuf, HHI_GCLK_MPEG0, 18);
584static MESON_GATE(hiu_iface, HHI_GCLK_MPEG0, 19); 584static MESON_GATE(gxbb_hiu_iface, HHI_GCLK_MPEG0, 19);
585static MESON_GATE(assist_misc, HHI_GCLK_MPEG0, 23); 585static MESON_GATE(gxbb_assist_misc, HHI_GCLK_MPEG0, 23);
586static MESON_GATE(spi, HHI_GCLK_MPEG0, 30); 586static MESON_GATE(gxbb_emmc_a, HHI_GCLK_MPEG0, 24);
587 587static MESON_GATE(gxbb_emmc_b, HHI_GCLK_MPEG0, 25);
588static MESON_GATE(i2s_spdif, HHI_GCLK_MPEG1, 2); 588static MESON_GATE(gxbb_emmc_c, HHI_GCLK_MPEG0, 26);
589static MESON_GATE(eth, HHI_GCLK_MPEG1, 3); 589static MESON_GATE(gxbb_spi, HHI_GCLK_MPEG0, 30);
590static MESON_GATE(demux, HHI_GCLK_MPEG1, 4); 590
591static MESON_GATE(aiu_glue, HHI_GCLK_MPEG1, 6); 591static MESON_GATE(gxbb_i2s_spdif, HHI_GCLK_MPEG1, 2);
592static MESON_GATE(iec958, HHI_GCLK_MPEG1, 7); 592static MESON_GATE(gxbb_eth, HHI_GCLK_MPEG1, 3);
593static MESON_GATE(i2s_out, HHI_GCLK_MPEG1, 8); 593static MESON_GATE(gxbb_demux, HHI_GCLK_MPEG1, 4);
594static MESON_GATE(amclk, HHI_GCLK_MPEG1, 9); 594static MESON_GATE(gxbb_aiu_glue, HHI_GCLK_MPEG1, 6);
595static MESON_GATE(aififo2, HHI_GCLK_MPEG1, 10); 595static MESON_GATE(gxbb_iec958, HHI_GCLK_MPEG1, 7);
596static MESON_GATE(mixer, HHI_GCLK_MPEG1, 11); 596static MESON_GATE(gxbb_i2s_out, HHI_GCLK_MPEG1, 8);
597static MESON_GATE(mixer_iface, HHI_GCLK_MPEG1, 12); 597static MESON_GATE(gxbb_amclk, HHI_GCLK_MPEG1, 9);
598static MESON_GATE(adc, HHI_GCLK_MPEG1, 13); 598static MESON_GATE(gxbb_aififo2, HHI_GCLK_MPEG1, 10);
599static MESON_GATE(blkmv, HHI_GCLK_MPEG1, 14); 599static MESON_GATE(gxbb_mixer, HHI_GCLK_MPEG1, 11);
600static MESON_GATE(aiu, HHI_GCLK_MPEG1, 15); 600static MESON_GATE(gxbb_mixer_iface, HHI_GCLK_MPEG1, 12);
601static MESON_GATE(uart1, HHI_GCLK_MPEG1, 16); 601static MESON_GATE(gxbb_adc, HHI_GCLK_MPEG1, 13);
602static MESON_GATE(g2d, HHI_GCLK_MPEG1, 20); 602static MESON_GATE(gxbb_blkmv, HHI_GCLK_MPEG1, 14);
603static MESON_GATE(usb0, HHI_GCLK_MPEG1, 21); 603static MESON_GATE(gxbb_aiu, HHI_GCLK_MPEG1, 15);
604static MESON_GATE(usb1, HHI_GCLK_MPEG1, 22); 604static MESON_GATE(gxbb_uart1, HHI_GCLK_MPEG1, 16);
605static MESON_GATE(reset, HHI_GCLK_MPEG1, 23); 605static MESON_GATE(gxbb_g2d, HHI_GCLK_MPEG1, 20);
606static MESON_GATE(nand, HHI_GCLK_MPEG1, 24); 606static MESON_GATE(gxbb_usb0, HHI_GCLK_MPEG1, 21);
607static MESON_GATE(dos_parser, HHI_GCLK_MPEG1, 25); 607static MESON_GATE(gxbb_usb1, HHI_GCLK_MPEG1, 22);
608static MESON_GATE(usb, HHI_GCLK_MPEG1, 26); 608static MESON_GATE(gxbb_reset, HHI_GCLK_MPEG1, 23);
609static MESON_GATE(vdin1, HHI_GCLK_MPEG1, 28); 609static MESON_GATE(gxbb_nand, HHI_GCLK_MPEG1, 24);
610static MESON_GATE(ahb_arb0, HHI_GCLK_MPEG1, 29); 610static MESON_GATE(gxbb_dos_parser, HHI_GCLK_MPEG1, 25);
611static MESON_GATE(efuse, HHI_GCLK_MPEG1, 30); 611static MESON_GATE(gxbb_usb, HHI_GCLK_MPEG1, 26);
612static MESON_GATE(boot_rom, HHI_GCLK_MPEG1, 31); 612static MESON_GATE(gxbb_vdin1, HHI_GCLK_MPEG1, 28);
613 613static MESON_GATE(gxbb_ahb_arb0, HHI_GCLK_MPEG1, 29);
614static MESON_GATE(ahb_data_bus, HHI_GCLK_MPEG2, 1); 614static MESON_GATE(gxbb_efuse, HHI_GCLK_MPEG1, 30);
615static MESON_GATE(ahb_ctrl_bus, HHI_GCLK_MPEG2, 2); 615static MESON_GATE(gxbb_boot_rom, HHI_GCLK_MPEG1, 31);
616static MESON_GATE(hdmi_intr_sync, HHI_GCLK_MPEG2, 3); 616
617static MESON_GATE(hdmi_pclk, HHI_GCLK_MPEG2, 4); 617static MESON_GATE(gxbb_ahb_data_bus, HHI_GCLK_MPEG2, 1);
618static MESON_GATE(usb1_ddr_bridge, HHI_GCLK_MPEG2, 8); 618static MESON_GATE(gxbb_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2);
619static MESON_GATE(usb0_ddr_bridge, HHI_GCLK_MPEG2, 9); 619static MESON_GATE(gxbb_hdmi_intr_sync, HHI_GCLK_MPEG2, 3);
620static MESON_GATE(mmc_pclk, HHI_GCLK_MPEG2, 11); 620static MESON_GATE(gxbb_hdmi_pclk, HHI_GCLK_MPEG2, 4);
621static MESON_GATE(dvin, HHI_GCLK_MPEG2, 12); 621static MESON_GATE(gxbb_usb1_ddr_bridge, HHI_GCLK_MPEG2, 8);
622static MESON_GATE(uart2, HHI_GCLK_MPEG2, 15); 622static MESON_GATE(gxbb_usb0_ddr_bridge, HHI_GCLK_MPEG2, 9);
623static MESON_GATE(sana, HHI_GCLK_MPEG2, 22); 623static MESON_GATE(gxbb_mmc_pclk, HHI_GCLK_MPEG2, 11);
624static MESON_GATE(vpu_intr, HHI_GCLK_MPEG2, 25); 624static MESON_GATE(gxbb_dvin, HHI_GCLK_MPEG2, 12);
625static MESON_GATE(sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26); 625static MESON_GATE(gxbb_uart2, HHI_GCLK_MPEG2, 15);
626static MESON_GATE(clk81_a53, HHI_GCLK_MPEG2, 29); 626static MESON_GATE(gxbb_sana, HHI_GCLK_MPEG2, 22);
627 627static MESON_GATE(gxbb_vpu_intr, HHI_GCLK_MPEG2, 25);
628static MESON_GATE(vclk2_venci0, HHI_GCLK_OTHER, 1); 628static MESON_GATE(gxbb_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26);
629static MESON_GATE(vclk2_venci1, HHI_GCLK_OTHER, 2); 629static MESON_GATE(gxbb_clk81_a53, HHI_GCLK_MPEG2, 29);
630static MESON_GATE(vclk2_vencp0, HHI_GCLK_OTHER, 3); 630
631static MESON_GATE(vclk2_vencp1, HHI_GCLK_OTHER, 4); 631static MESON_GATE(gxbb_vclk2_venci0, HHI_GCLK_OTHER, 1);
632static MESON_GATE(gclk_venci_int0, HHI_GCLK_OTHER, 8); 632static MESON_GATE(gxbb_vclk2_venci1, HHI_GCLK_OTHER, 2);
633static MESON_GATE(gclk_vencp_int, HHI_GCLK_OTHER, 9); 633static MESON_GATE(gxbb_vclk2_vencp0, HHI_GCLK_OTHER, 3);
634static MESON_GATE(dac_clk, HHI_GCLK_OTHER, 10); 634static MESON_GATE(gxbb_vclk2_vencp1, HHI_GCLK_OTHER, 4);
635static MESON_GATE(aoclk_gate, HHI_GCLK_OTHER, 14); 635static MESON_GATE(gxbb_gclk_venci_int0, HHI_GCLK_OTHER, 8);
636static MESON_GATE(iec958_gate, HHI_GCLK_OTHER, 16); 636static MESON_GATE(gxbb_gclk_vencp_int, HHI_GCLK_OTHER, 9);
637static MESON_GATE(enc480p, HHI_GCLK_OTHER, 20); 637static MESON_GATE(gxbb_dac_clk, HHI_GCLK_OTHER, 10);
638static MESON_GATE(rng1, HHI_GCLK_OTHER, 21); 638static MESON_GATE(gxbb_aoclk_gate, HHI_GCLK_OTHER, 14);
639static MESON_GATE(gclk_venci_int1, HHI_GCLK_OTHER, 22); 639static MESON_GATE(gxbb_iec958_gate, HHI_GCLK_OTHER, 16);
640static MESON_GATE(vclk2_venclmcc, HHI_GCLK_OTHER, 24); 640static MESON_GATE(gxbb_enc480p, HHI_GCLK_OTHER, 20);
641static MESON_GATE(vclk2_vencl, HHI_GCLK_OTHER, 25); 641static MESON_GATE(gxbb_rng1, HHI_GCLK_OTHER, 21);
642static MESON_GATE(vclk_other, HHI_GCLK_OTHER, 26); 642static MESON_GATE(gxbb_gclk_venci_int1, HHI_GCLK_OTHER, 22);
643static MESON_GATE(edp, HHI_GCLK_OTHER, 31); 643static MESON_GATE(gxbb_vclk2_venclmcc, HHI_GCLK_OTHER, 24);
644static MESON_GATE(gxbb_vclk2_vencl, HHI_GCLK_OTHER, 25);
645static MESON_GATE(gxbb_vclk_other, HHI_GCLK_OTHER, 26);
646static MESON_GATE(gxbb_edp, HHI_GCLK_OTHER, 31);
644 647
645/* Always On (AO) domain gates */ 648/* Always On (AO) domain gates */
646 649
647static MESON_GATE(ao_media_cpu, HHI_GCLK_AO, 0); 650static MESON_GATE(gxbb_ao_media_cpu, HHI_GCLK_AO, 0);
648static MESON_GATE(ao_ahb_sram, HHI_GCLK_AO, 1); 651static MESON_GATE(gxbb_ao_ahb_sram, HHI_GCLK_AO, 1);
649static MESON_GATE(ao_ahb_bus, HHI_GCLK_AO, 2); 652static MESON_GATE(gxbb_ao_ahb_bus, HHI_GCLK_AO, 2);
650static MESON_GATE(ao_iface, HHI_GCLK_AO, 3); 653static MESON_GATE(gxbb_ao_iface, HHI_GCLK_AO, 3);
651static MESON_GATE(ao_i2c, HHI_GCLK_AO, 4); 654static MESON_GATE(gxbb_ao_i2c, HHI_GCLK_AO, 4);
652 655
653/* Array of all clocks provided by this provider */ 656/* Array of all clocks provided by this provider */
654 657
@@ -748,6 +751,9 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
748 [CLKID_AO_AHB_BUS] = &gxbb_ao_ahb_bus.hw, 751 [CLKID_AO_AHB_BUS] = &gxbb_ao_ahb_bus.hw,
749 [CLKID_AO_IFACE] = &gxbb_ao_iface.hw, 752 [CLKID_AO_IFACE] = &gxbb_ao_iface.hw,
750 [CLKID_AO_I2C] = &gxbb_ao_i2c.hw, 753 [CLKID_AO_I2C] = &gxbb_ao_i2c.hw,
754 [CLKID_SD_EMMC_A] = &gxbb_emmc_a.hw,
755 [CLKID_SD_EMMC_B] = &gxbb_emmc_b.hw,
756 [CLKID_SD_EMMC_C] = &gxbb_emmc_c.hw,
751 }, 757 },
752 .num = NR_CLKS, 758 .num = NR_CLKS,
753}; 759};
@@ -847,6 +853,9 @@ static struct clk_gate *gxbb_clk_gates[] = {
847 &gxbb_ao_ahb_bus, 853 &gxbb_ao_ahb_bus,
848 &gxbb_ao_iface, 854 &gxbb_ao_iface,
849 &gxbb_ao_i2c, 855 &gxbb_ao_i2c,
856 &gxbb_emmc_a,
857 &gxbb_emmc_b,
858 &gxbb_emmc_c,
850}; 859};
851 860
852static int gxbb_clkc_probe(struct platform_device *pdev) 861static int gxbb_clkc_probe(struct platform_device *pdev)
@@ -937,8 +946,4 @@ static struct platform_driver gxbb_driver = {
937 }, 946 },
938}; 947};
939 948
940static int __init gxbb_clkc_init(void) 949builtin_platform_driver(gxbb_driver);
941{
942 return platform_driver_register(&gxbb_driver);
943}
944device_initcall(gxbb_clkc_init);
diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h
index a2adf3448b59..ae461b16af75 100644
--- a/drivers/clk/meson/gxbb.h
+++ b/drivers/clk/meson/gxbb.h
@@ -170,11 +170,11 @@
170 */ 170 */
171#define CLKID_SYS_PLL 0 171#define CLKID_SYS_PLL 0
172/* CLKID_CPUCLK */ 172/* CLKID_CPUCLK */
173#define CLKID_HDMI_PLL 2 173/* CLKID_HDMI_PLL */
174#define CLKID_FIXED_PLL 3 174#define CLKID_FIXED_PLL 3
175#define CLKID_FCLK_DIV2 4 175/* CLKID_FCLK_DIV2 */
176#define CLKID_FCLK_DIV3 5 176/* CLKID_FCLK_DIV3 */
177#define CLKID_FCLK_DIV4 6 177/* CLKID_FCLK_DIV4 */
178#define CLKID_FCLK_DIV5 7 178#define CLKID_FCLK_DIV5 7
179#define CLKID_FCLK_DIV7 8 179#define CLKID_FCLK_DIV7 8
180#define CLKID_GP0_PLL 9 180#define CLKID_GP0_PLL 9
@@ -262,8 +262,11 @@
262#define CLKID_AO_AHB_BUS 91 262#define CLKID_AO_AHB_BUS 91
263#define CLKID_AO_IFACE 92 263#define CLKID_AO_IFACE 92
264#define CLKID_AO_I2C 93 264#define CLKID_AO_I2C 93
265/* CLKID_SD_EMMC_A */
266/* CLKID_SD_EMMC_B */
267/* CLKID_SD_EMMC_C */
265 268
266#define NR_CLKS 94 269#define NR_CLKS 97
267 270
268/* include the CLKIDs that have been made part of the stable DT binding */ 271/* include the CLKIDs that have been made part of the stable DT binding */
269#include <dt-bindings/clock/gxbb-clkc.h> 272#include <dt-bindings/clock/gxbb-clkc.h>
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b.c
index 4c9413cdf373..3f1be46cbb33 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b.c
@@ -23,27 +23,11 @@
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/clk-provider.h> 24#include <linux/clk-provider.h>
25#include <linux/of_address.h> 25#include <linux/of_address.h>
26#include <dt-bindings/clock/meson8b-clkc.h>
27#include <linux/platform_device.h> 26#include <linux/platform_device.h>
28#include <linux/init.h> 27#include <linux/init.h>
29 28
30#include "clkc.h" 29#include "clkc.h"
31 30#include "meson8b.h"
32/*
33 * Clock controller register offsets
34 *
35 * Register offsets from the HardKernel[0] data sheet are listed in comment
36 * blocks below. Those offsets must be multiplied by 4 before adding them to
37 * the base address to get the right value
38 *
39 * [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
40 */
41#define MESON8B_REG_SYS_CPU_CNTL1 0x015c /* 0x57 offset in data sheet */
42#define MESON8B_REG_HHI_MPEG 0x0174 /* 0x5d offset in data sheet */
43#define MESON8B_REG_MALI 0x01b0 /* 0x6c offset in data sheet */
44#define MESON8B_REG_PLL_FIXED 0x0280
45#define MESON8B_REG_PLL_SYS 0x0300
46#define MESON8B_REG_PLL_VID 0x0320
47 31
48static DEFINE_SPINLOCK(clk_lock); 32static DEFINE_SPINLOCK(clk_lock);
49 33
@@ -128,17 +112,17 @@ static struct clk_fixed_rate meson8b_xtal = {
128 112
129static struct meson_clk_pll meson8b_fixed_pll = { 113static struct meson_clk_pll meson8b_fixed_pll = {
130 .m = { 114 .m = {
131 .reg_off = MESON8B_REG_PLL_FIXED, 115 .reg_off = HHI_MPLL_CNTL,
132 .shift = 0, 116 .shift = 0,
133 .width = 9, 117 .width = 9,
134 }, 118 },
135 .n = { 119 .n = {
136 .reg_off = MESON8B_REG_PLL_FIXED, 120 .reg_off = HHI_MPLL_CNTL,
137 .shift = 9, 121 .shift = 9,
138 .width = 5, 122 .width = 5,
139 }, 123 },
140 .od = { 124 .od = {
141 .reg_off = MESON8B_REG_PLL_FIXED, 125 .reg_off = HHI_MPLL_CNTL,
142 .shift = 16, 126 .shift = 16,
143 .width = 2, 127 .width = 2,
144 }, 128 },
@@ -154,17 +138,17 @@ static struct meson_clk_pll meson8b_fixed_pll = {
154 138
155static struct meson_clk_pll meson8b_vid_pll = { 139static struct meson_clk_pll meson8b_vid_pll = {
156 .m = { 140 .m = {
157 .reg_off = MESON8B_REG_PLL_VID, 141 .reg_off = HHI_VID_PLL_CNTL,
158 .shift = 0, 142 .shift = 0,
159 .width = 9, 143 .width = 9,
160 }, 144 },
161 .n = { 145 .n = {
162 .reg_off = MESON8B_REG_PLL_VID, 146 .reg_off = HHI_VID_PLL_CNTL,
163 .shift = 9, 147 .shift = 9,
164 .width = 5, 148 .width = 5,
165 }, 149 },
166 .od = { 150 .od = {
167 .reg_off = MESON8B_REG_PLL_VID, 151 .reg_off = HHI_VID_PLL_CNTL,
168 .shift = 16, 152 .shift = 16,
169 .width = 2, 153 .width = 2,
170 }, 154 },
@@ -180,17 +164,17 @@ static struct meson_clk_pll meson8b_vid_pll = {
180 164
181static struct meson_clk_pll meson8b_sys_pll = { 165static struct meson_clk_pll meson8b_sys_pll = {
182 .m = { 166 .m = {
183 .reg_off = MESON8B_REG_PLL_SYS, 167 .reg_off = HHI_SYS_PLL_CNTL,
184 .shift = 0, 168 .shift = 0,
185 .width = 9, 169 .width = 9,
186 }, 170 },
187 .n = { 171 .n = {
188 .reg_off = MESON8B_REG_PLL_SYS, 172 .reg_off = HHI_SYS_PLL_CNTL,
189 .shift = 9, 173 .shift = 9,
190 .width = 5, 174 .width = 5,
191 }, 175 },
192 .od = { 176 .od = {
193 .reg_off = MESON8B_REG_PLL_SYS, 177 .reg_off = HHI_SYS_PLL_CNTL,
194 .shift = 16, 178 .shift = 16,
195 .width = 2, 179 .width = 2,
196 }, 180 },
@@ -267,7 +251,7 @@ static struct clk_fixed_factor meson8b_fclk_div7 = {
267 * forthcoming coordinated clock rates feature 251 * forthcoming coordinated clock rates feature
268 */ 252 */
269static struct meson_clk_cpu meson8b_cpu_clk = { 253static struct meson_clk_cpu meson8b_cpu_clk = {
270 .reg_off = MESON8B_REG_SYS_CPU_CNTL1, 254 .reg_off = HHI_SYS_CPU_CLK_CNTL1,
271 .div_table = cpu_div_table, 255 .div_table = cpu_div_table,
272 .clk_nb.notifier_call = meson_clk_cpu_notifier_cb, 256 .clk_nb.notifier_call = meson_clk_cpu_notifier_cb,
273 .hw.init = &(struct clk_init_data){ 257 .hw.init = &(struct clk_init_data){
@@ -281,7 +265,7 @@ static struct meson_clk_cpu meson8b_cpu_clk = {
281static u32 mux_table_clk81[] = { 6, 5, 7 }; 265static u32 mux_table_clk81[] = { 6, 5, 7 };
282 266
283struct clk_mux meson8b_mpeg_clk_sel = { 267struct clk_mux meson8b_mpeg_clk_sel = {
284 .reg = (void *)MESON8B_REG_HHI_MPEG, 268 .reg = (void *)HHI_MPEG_CLK_CNTL,
285 .mask = 0x7, 269 .mask = 0x7,
286 .shift = 12, 270 .shift = 12,
287 .flags = CLK_MUX_READ_ONLY, 271 .flags = CLK_MUX_READ_ONLY,
@@ -303,7 +287,7 @@ struct clk_mux meson8b_mpeg_clk_sel = {
303}; 287};
304 288
305struct clk_divider meson8b_mpeg_clk_div = { 289struct clk_divider meson8b_mpeg_clk_div = {
306 .reg = (void *)MESON8B_REG_HHI_MPEG, 290 .reg = (void *)HHI_MPEG_CLK_CNTL,
307 .shift = 0, 291 .shift = 0,
308 .width = 7, 292 .width = 7,
309 .lock = &clk_lock, 293 .lock = &clk_lock,
@@ -317,7 +301,7 @@ struct clk_divider meson8b_mpeg_clk_div = {
317}; 301};
318 302
319struct clk_gate meson8b_clk81 = { 303struct clk_gate meson8b_clk81 = {
320 .reg = (void *)MESON8B_REG_HHI_MPEG, 304 .reg = (void *)HHI_MPEG_CLK_CNTL,
321 .bit_idx = 7, 305 .bit_idx = 7,
322 .lock = &clk_lock, 306 .lock = &clk_lock,
323 .hw.init = &(struct clk_init_data){ 307 .hw.init = &(struct clk_init_data){
@@ -329,6 +313,92 @@ struct clk_gate meson8b_clk81 = {
329 }, 313 },
330}; 314};
331 315
316/* Everything Else (EE) domain gates */
317
318static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0);
319static MESON_GATE(meson8b_dos, HHI_GCLK_MPEG0, 1);
320static MESON_GATE(meson8b_isa, HHI_GCLK_MPEG0, 5);
321static MESON_GATE(meson8b_pl301, HHI_GCLK_MPEG0, 6);
322static MESON_GATE(meson8b_periphs, HHI_GCLK_MPEG0, 7);
323static MESON_GATE(meson8b_spicc, HHI_GCLK_MPEG0, 8);
324static MESON_GATE(meson8b_i2c, HHI_GCLK_MPEG0, 9);
325static MESON_GATE(meson8b_sar_adc, HHI_GCLK_MPEG0, 10);
326static MESON_GATE(meson8b_smart_card, HHI_GCLK_MPEG0, 11);
327static MESON_GATE(meson8b_rng0, HHI_GCLK_MPEG0, 12);
328static MESON_GATE(meson8b_uart0, HHI_GCLK_MPEG0, 13);
329static MESON_GATE(meson8b_sdhc, HHI_GCLK_MPEG0, 14);
330static MESON_GATE(meson8b_stream, HHI_GCLK_MPEG0, 15);
331static MESON_GATE(meson8b_async_fifo, HHI_GCLK_MPEG0, 16);
332static MESON_GATE(meson8b_sdio, HHI_GCLK_MPEG0, 17);
333static MESON_GATE(meson8b_abuf, HHI_GCLK_MPEG0, 18);
334static MESON_GATE(meson8b_hiu_iface, HHI_GCLK_MPEG0, 19);
335static MESON_GATE(meson8b_assist_misc, HHI_GCLK_MPEG0, 23);
336static MESON_GATE(meson8b_spi, HHI_GCLK_MPEG0, 30);
337
338static MESON_GATE(meson8b_i2s_spdif, HHI_GCLK_MPEG1, 2);
339static MESON_GATE(meson8b_eth, HHI_GCLK_MPEG1, 3);
340static MESON_GATE(meson8b_demux, HHI_GCLK_MPEG1, 4);
341static MESON_GATE(meson8b_aiu_glue, HHI_GCLK_MPEG1, 6);
342static MESON_GATE(meson8b_iec958, HHI_GCLK_MPEG1, 7);
343static MESON_GATE(meson8b_i2s_out, HHI_GCLK_MPEG1, 8);
344static MESON_GATE(meson8b_amclk, HHI_GCLK_MPEG1, 9);
345static MESON_GATE(meson8b_aififo2, HHI_GCLK_MPEG1, 10);
346static MESON_GATE(meson8b_mixer, HHI_GCLK_MPEG1, 11);
347static MESON_GATE(meson8b_mixer_iface, HHI_GCLK_MPEG1, 12);
348static MESON_GATE(meson8b_adc, HHI_GCLK_MPEG1, 13);
349static MESON_GATE(meson8b_blkmv, HHI_GCLK_MPEG1, 14);
350static MESON_GATE(meson8b_aiu, HHI_GCLK_MPEG1, 15);
351static MESON_GATE(meson8b_uart1, HHI_GCLK_MPEG1, 16);
352static MESON_GATE(meson8b_g2d, HHI_GCLK_MPEG1, 20);
353static MESON_GATE(meson8b_usb0, HHI_GCLK_MPEG1, 21);
354static MESON_GATE(meson8b_usb1, HHI_GCLK_MPEG1, 22);
355static MESON_GATE(meson8b_reset, HHI_GCLK_MPEG1, 23);
356static MESON_GATE(meson8b_nand, HHI_GCLK_MPEG1, 24);
357static MESON_GATE(meson8b_dos_parser, HHI_GCLK_MPEG1, 25);
358static MESON_GATE(meson8b_usb, HHI_GCLK_MPEG1, 26);
359static MESON_GATE(meson8b_vdin1, HHI_GCLK_MPEG1, 28);
360static MESON_GATE(meson8b_ahb_arb0, HHI_GCLK_MPEG1, 29);
361static MESON_GATE(meson8b_efuse, HHI_GCLK_MPEG1, 30);
362static MESON_GATE(meson8b_boot_rom, HHI_GCLK_MPEG1, 31);
363
364static MESON_GATE(meson8b_ahb_data_bus, HHI_GCLK_MPEG2, 1);
365static MESON_GATE(meson8b_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2);
366static MESON_GATE(meson8b_hdmi_intr_sync, HHI_GCLK_MPEG2, 3);
367static MESON_GATE(meson8b_hdmi_pclk, HHI_GCLK_MPEG2, 4);
368static MESON_GATE(meson8b_usb1_ddr_bridge, HHI_GCLK_MPEG2, 8);
369static MESON_GATE(meson8b_usb0_ddr_bridge, HHI_GCLK_MPEG2, 9);
370static MESON_GATE(meson8b_mmc_pclk, HHI_GCLK_MPEG2, 11);
371static MESON_GATE(meson8b_dvin, HHI_GCLK_MPEG2, 12);
372static MESON_GATE(meson8b_uart2, HHI_GCLK_MPEG2, 15);
373static MESON_GATE(meson8b_sana, HHI_GCLK_MPEG2, 22);
374static MESON_GATE(meson8b_vpu_intr, HHI_GCLK_MPEG2, 25);
375static MESON_GATE(meson8b_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26);
376static MESON_GATE(meson8b_clk81_a9, HHI_GCLK_MPEG2, 29);
377
378static MESON_GATE(meson8b_vclk2_venci0, HHI_GCLK_OTHER, 1);
379static MESON_GATE(meson8b_vclk2_venci1, HHI_GCLK_OTHER, 2);
380static MESON_GATE(meson8b_vclk2_vencp0, HHI_GCLK_OTHER, 3);
381static MESON_GATE(meson8b_vclk2_vencp1, HHI_GCLK_OTHER, 4);
382static MESON_GATE(meson8b_gclk_venci_int, HHI_GCLK_OTHER, 8);
383static MESON_GATE(meson8b_gclk_vencp_int, HHI_GCLK_OTHER, 9);
384static MESON_GATE(meson8b_dac_clk, HHI_GCLK_OTHER, 10);
385static MESON_GATE(meson8b_aoclk_gate, HHI_GCLK_OTHER, 14);
386static MESON_GATE(meson8b_iec958_gate, HHI_GCLK_OTHER, 16);
387static MESON_GATE(meson8b_enc480p, HHI_GCLK_OTHER, 20);
388static MESON_GATE(meson8b_rng1, HHI_GCLK_OTHER, 21);
389static MESON_GATE(meson8b_gclk_vencl_int, HHI_GCLK_OTHER, 22);
390static MESON_GATE(meson8b_vclk2_venclmcc, HHI_GCLK_OTHER, 24);
391static MESON_GATE(meson8b_vclk2_vencl, HHI_GCLK_OTHER, 25);
392static MESON_GATE(meson8b_vclk2_other, HHI_GCLK_OTHER, 26);
393static MESON_GATE(meson8b_edp, HHI_GCLK_OTHER, 31);
394
395/* Always On (AO) domain gates */
396
397static MESON_GATE(meson8b_ao_media_cpu, HHI_GCLK_AO, 0);
398static MESON_GATE(meson8b_ao_ahb_sram, HHI_GCLK_AO, 1);
399static MESON_GATE(meson8b_ao_ahb_bus, HHI_GCLK_AO, 2);
400static MESON_GATE(meson8b_ao_iface, HHI_GCLK_AO, 3);
401
332static struct clk_hw_onecell_data meson8b_hw_onecell_data = { 402static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
333 .hws = { 403 .hws = {
334 [CLKID_XTAL] = &meson8b_xtal.hw, 404 [CLKID_XTAL] = &meson8b_xtal.hw,
@@ -344,6 +414,83 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
344 [CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw, 414 [CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw,
345 [CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw, 415 [CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw,
346 [CLKID_CLK81] = &meson8b_clk81.hw, 416 [CLKID_CLK81] = &meson8b_clk81.hw,
417 [CLKID_DDR] = &meson8b_ddr.hw,
418 [CLKID_DOS] = &meson8b_dos.hw,
419 [CLKID_ISA] = &meson8b_isa.hw,
420 [CLKID_PL301] = &meson8b_pl301.hw,
421 [CLKID_PERIPHS] = &meson8b_periphs.hw,
422 [CLKID_SPICC] = &meson8b_spicc.hw,
423 [CLKID_I2C] = &meson8b_i2c.hw,
424 [CLKID_SAR_ADC] = &meson8b_sar_adc.hw,
425 [CLKID_SMART_CARD] = &meson8b_smart_card.hw,
426 [CLKID_RNG0] = &meson8b_rng0.hw,
427 [CLKID_UART0] = &meson8b_uart0.hw,
428 [CLKID_SDHC] = &meson8b_sdhc.hw,
429 [CLKID_STREAM] = &meson8b_stream.hw,
430 [CLKID_ASYNC_FIFO] = &meson8b_async_fifo.hw,
431 [CLKID_SDIO] = &meson8b_sdio.hw,
432 [CLKID_ABUF] = &meson8b_abuf.hw,
433 [CLKID_HIU_IFACE] = &meson8b_hiu_iface.hw,
434 [CLKID_ASSIST_MISC] = &meson8b_assist_misc.hw,
435 [CLKID_SPI] = &meson8b_spi.hw,
436 [CLKID_I2S_SPDIF] = &meson8b_i2s_spdif.hw,
437 [CLKID_ETH] = &meson8b_eth.hw,
438 [CLKID_DEMUX] = &meson8b_demux.hw,
439 [CLKID_AIU_GLUE] = &meson8b_aiu_glue.hw,
440 [CLKID_IEC958] = &meson8b_iec958.hw,
441 [CLKID_I2S_OUT] = &meson8b_i2s_out.hw,
442 [CLKID_AMCLK] = &meson8b_amclk.hw,
443 [CLKID_AIFIFO2] = &meson8b_aififo2.hw,
444 [CLKID_MIXER] = &meson8b_mixer.hw,
445 [CLKID_MIXER_IFACE] = &meson8b_mixer_iface.hw,
446 [CLKID_ADC] = &meson8b_adc.hw,
447 [CLKID_BLKMV] = &meson8b_blkmv.hw,
448 [CLKID_AIU] = &meson8b_aiu.hw,
449 [CLKID_UART1] = &meson8b_uart1.hw,
450 [CLKID_G2D] = &meson8b_g2d.hw,
451 [CLKID_USB0] = &meson8b_usb0.hw,
452 [CLKID_USB1] = &meson8b_usb1.hw,
453 [CLKID_RESET] = &meson8b_reset.hw,
454 [CLKID_NAND] = &meson8b_nand.hw,
455 [CLKID_DOS_PARSER] = &meson8b_dos_parser.hw,
456 [CLKID_USB] = &meson8b_usb.hw,
457 [CLKID_VDIN1] = &meson8b_vdin1.hw,
458 [CLKID_AHB_ARB0] = &meson8b_ahb_arb0.hw,
459 [CLKID_EFUSE] = &meson8b_efuse.hw,
460 [CLKID_BOOT_ROM] = &meson8b_boot_rom.hw,
461 [CLKID_AHB_DATA_BUS] = &meson8b_ahb_data_bus.hw,
462 [CLKID_AHB_CTRL_BUS] = &meson8b_ahb_ctrl_bus.hw,
463 [CLKID_HDMI_INTR_SYNC] = &meson8b_hdmi_intr_sync.hw,
464 [CLKID_HDMI_PCLK] = &meson8b_hdmi_pclk.hw,
465 [CLKID_USB1_DDR_BRIDGE] = &meson8b_usb1_ddr_bridge.hw,
466 [CLKID_USB0_DDR_BRIDGE] = &meson8b_usb0_ddr_bridge.hw,
467 [CLKID_MMC_PCLK] = &meson8b_mmc_pclk.hw,
468 [CLKID_DVIN] = &meson8b_dvin.hw,
469 [CLKID_UART2] = &meson8b_uart2.hw,
470 [CLKID_SANA] = &meson8b_sana.hw,
471 [CLKID_VPU_INTR] = &meson8b_vpu_intr.hw,
472 [CLKID_SEC_AHB_AHB3_BRIDGE] = &meson8b_sec_ahb_ahb3_bridge.hw,
473 [CLKID_CLK81_A9] = &meson8b_clk81_a9.hw,
474 [CLKID_VCLK2_VENCI0] = &meson8b_vclk2_venci0.hw,
475 [CLKID_VCLK2_VENCI1] = &meson8b_vclk2_venci1.hw,
476 [CLKID_VCLK2_VENCP0] = &meson8b_vclk2_vencp0.hw,
477 [CLKID_VCLK2_VENCP1] = &meson8b_vclk2_vencp1.hw,
478 [CLKID_GCLK_VENCI_INT] = &meson8b_gclk_venci_int.hw,
479 [CLKID_GCLK_VENCP_INT] = &meson8b_gclk_vencp_int.hw,
480 [CLKID_DAC_CLK] = &meson8b_dac_clk.hw,
481 [CLKID_AOCLK_GATE] = &meson8b_aoclk_gate.hw,
482 [CLKID_IEC958_GATE] = &meson8b_iec958_gate.hw,
483 [CLKID_ENC480P] = &meson8b_enc480p.hw,
484 [CLKID_RNG1] = &meson8b_rng1.hw,
485 [CLKID_GCLK_VENCL_INT] = &meson8b_gclk_vencl_int.hw,
486 [CLKID_VCLK2_VENCLMCC] = &meson8b_vclk2_venclmcc.hw,
487 [CLKID_VCLK2_VENCL] = &meson8b_vclk2_vencl.hw,
488 [CLKID_VCLK2_OTHER] = &meson8b_vclk2_other.hw,
489 [CLKID_EDP] = &meson8b_edp.hw,
490 [CLKID_AO_MEDIA_CPU] = &meson8b_ao_media_cpu.hw,
491 [CLKID_AO_AHB_SRAM] = &meson8b_ao_ahb_sram.hw,
492 [CLKID_AO_AHB_BUS] = &meson8b_ao_ahb_bus.hw,
493 [CLKID_AO_IFACE] = &meson8b_ao_iface.hw,
347 }, 494 },
348 .num = CLK_NR_CLKS, 495 .num = CLK_NR_CLKS,
349}; 496};
@@ -354,6 +501,87 @@ static struct meson_clk_pll *const meson8b_clk_plls[] = {
354 &meson8b_sys_pll, 501 &meson8b_sys_pll,
355}; 502};
356 503
504static struct clk_gate *meson8b_clk_gates[] = {
505 &meson8b_clk81,
506 &meson8b_ddr,
507 &meson8b_dos,
508 &meson8b_isa,
509 &meson8b_pl301,
510 &meson8b_periphs,
511 &meson8b_spicc,
512 &meson8b_i2c,
513 &meson8b_sar_adc,
514 &meson8b_smart_card,
515 &meson8b_rng0,
516 &meson8b_uart0,
517 &meson8b_sdhc,
518 &meson8b_stream,
519 &meson8b_async_fifo,
520 &meson8b_sdio,
521 &meson8b_abuf,
522 &meson8b_hiu_iface,
523 &meson8b_assist_misc,
524 &meson8b_spi,
525 &meson8b_i2s_spdif,
526 &meson8b_eth,
527 &meson8b_demux,
528 &meson8b_aiu_glue,
529 &meson8b_iec958,
530 &meson8b_i2s_out,
531 &meson8b_amclk,
532 &meson8b_aififo2,
533 &meson8b_mixer,
534 &meson8b_mixer_iface,
535 &meson8b_adc,
536 &meson8b_blkmv,
537 &meson8b_aiu,
538 &meson8b_uart1,
539 &meson8b_g2d,
540 &meson8b_usb0,
541 &meson8b_usb1,
542 &meson8b_reset,
543 &meson8b_nand,
544 &meson8b_dos_parser,
545 &meson8b_usb,
546 &meson8b_vdin1,
547 &meson8b_ahb_arb0,
548 &meson8b_efuse,
549 &meson8b_boot_rom,
550 &meson8b_ahb_data_bus,
551 &meson8b_ahb_ctrl_bus,
552 &meson8b_hdmi_intr_sync,
553 &meson8b_hdmi_pclk,
554 &meson8b_usb1_ddr_bridge,
555 &meson8b_usb0_ddr_bridge,
556 &meson8b_mmc_pclk,
557 &meson8b_dvin,
558 &meson8b_uart2,
559 &meson8b_sana,
560 &meson8b_vpu_intr,
561 &meson8b_sec_ahb_ahb3_bridge,
562 &meson8b_clk81_a9,
563 &meson8b_vclk2_venci0,
564 &meson8b_vclk2_venci1,
565 &meson8b_vclk2_vencp0,
566 &meson8b_vclk2_vencp1,
567 &meson8b_gclk_venci_int,
568 &meson8b_gclk_vencp_int,
569 &meson8b_dac_clk,
570 &meson8b_aoclk_gate,
571 &meson8b_iec958_gate,
572 &meson8b_enc480p,
573 &meson8b_rng1,
574 &meson8b_gclk_vencl_int,
575 &meson8b_vclk2_venclmcc,
576 &meson8b_vclk2_vencl,
577 &meson8b_vclk2_other,
578 &meson8b_edp,
579 &meson8b_ao_media_cpu,
580 &meson8b_ao_ahb_sram,
581 &meson8b_ao_ahb_bus,
582 &meson8b_ao_iface,
583};
584
357static int meson8b_clkc_probe(struct platform_device *pdev) 585static int meson8b_clkc_probe(struct platform_device *pdev)
358{ 586{
359 void __iomem *clk_base; 587 void __iomem *clk_base;
@@ -381,6 +609,11 @@ static int meson8b_clkc_probe(struct platform_device *pdev)
381 meson8b_mpeg_clk_div.reg = clk_base + (u32)meson8b_mpeg_clk_div.reg; 609 meson8b_mpeg_clk_div.reg = clk_base + (u32)meson8b_mpeg_clk_div.reg;
382 meson8b_clk81.reg = clk_base + (u32)meson8b_clk81.reg; 610 meson8b_clk81.reg = clk_base + (u32)meson8b_clk81.reg;
383 611
612 /* Populate base address for gates */
613 for (i = 0; i < ARRAY_SIZE(meson8b_clk_gates); i++)
614 meson8b_clk_gates[i]->reg = clk_base +
615 (u32)meson8b_clk_gates[i]->reg;
616
384 /* 617 /*
385 * register all clks 618 * register all clks
386 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1 619 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
@@ -440,8 +673,4 @@ static struct platform_driver meson8b_driver = {
440 }, 673 },
441}; 674};
442 675
443static int __init meson8b_clkc_init(void) 676builtin_platform_driver(meson8b_driver);
444{
445 return platform_driver_register(&meson8b_driver);
446}
447device_initcall(meson8b_clkc_init);
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
new file mode 100644
index 000000000000..010e9582888d
--- /dev/null
+++ b/drivers/clk/meson/meson8b.h
@@ -0,0 +1,151 @@
1/*
2 * Copyright (c) 2015 Endless Mobile, Inc.
3 * Author: Carlo Caione <carlo@endlessm.com>
4 *
5 * Copyright (c) 2016 BayLibre, Inc.
6 * Michael Turquette <mturquette@baylibre.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef __MESON8B_H
22#define __MESON8B_H
23
24/*
25 * Clock controller register offsets
26 *
27 * Register offsets from the HardKernel[0] data sheet are listed in comment
28 * blocks below. Those offsets must be multiplied by 4 before adding them to
29 * the base address to get the right value
30 *
31 * [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
32 */
33#define HHI_GCLK_MPEG0 0x140 /* 0x50 offset in data sheet */
34#define HHI_GCLK_MPEG1 0x144 /* 0x51 offset in data sheet */
35#define HHI_GCLK_MPEG2 0x148 /* 0x52 offset in data sheet */
36#define HHI_GCLK_OTHER 0x150 /* 0x54 offset in data sheet */
37#define HHI_GCLK_AO 0x154 /* 0x55 offset in data sheet */
38#define HHI_SYS_CPU_CLK_CNTL1 0x15c /* 0x57 offset in data sheet */
39#define HHI_MPEG_CLK_CNTL 0x174 /* 0x5d offset in data sheet */
40#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */
41#define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */
42#define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
43
44/*
45 * CLKID index values
46 *
47 * These indices are entirely contrived and do not map onto the hardware.
48 * Migrate them out of this header and into the DT header file when they need
49 * to be exposed to client nodes in DT: include/dt-bindings/clock/meson8b-clkc.h
50 */
51
52/* CLKID_UNUSED */
53/* CLKID_XTAL */
54/* CLKID_PLL_FIXED */
55/* CLKID_PLL_VID */
56/* CLKID_PLL_SYS */
57/* CLKID_FCLK_DIV2 */
58/* CLKID_FCLK_DIV3 */
59/* CLKID_FCLK_DIV4 */
60/* CLKID_FCLK_DIV5 */
61/* CLKID_FCLK_DIV7 */
62/* CLKID_CLK81 */
63/* CLKID_MALI */
64/* CLKID_CPUCLK */
65/* CLKID_ZERO */
66/* CLKID_MPEG_SEL */
67/* CLKID_MPEG_DIV */
68#define CLKID_DDR 16
69#define CLKID_DOS 17
70#define CLKID_ISA 18
71#define CLKID_PL301 19
72#define CLKID_PERIPHS 20
73#define CLKID_SPICC 21
74#define CLKID_I2C 22
75#define CLKID_SAR_ADC 23
76#define CLKID_SMART_CARD 24
77#define CLKID_RNG0 25
78#define CLKID_UART0 26
79#define CLKID_SDHC 27
80#define CLKID_STREAM 28
81#define CLKID_ASYNC_FIFO 29
82#define CLKID_SDIO 30
83#define CLKID_ABUF 31
84#define CLKID_HIU_IFACE 32
85#define CLKID_ASSIST_MISC 33
86#define CLKID_SPI 34
87#define CLKID_I2S_SPDIF 35
88#define CLKID_ETH 36
89#define CLKID_DEMUX 37
90#define CLKID_AIU_GLUE 38
91#define CLKID_IEC958 39
92#define CLKID_I2S_OUT 40
93#define CLKID_AMCLK 41
94#define CLKID_AIFIFO2 42
95#define CLKID_MIXER 43
96#define CLKID_MIXER_IFACE 44
97#define CLKID_ADC 45
98#define CLKID_BLKMV 46
99#define CLKID_AIU 47
100#define CLKID_UART1 48
101#define CLKID_G2D 49
102#define CLKID_USB0 50
103#define CLKID_USB1 51
104#define CLKID_RESET 52
105#define CLKID_NAND 53
106#define CLKID_DOS_PARSER 54
107#define CLKID_USB 55
108#define CLKID_VDIN1 56
109#define CLKID_AHB_ARB0 57
110#define CLKID_EFUSE 58
111#define CLKID_BOOT_ROM 59
112#define CLKID_AHB_DATA_BUS 60
113#define CLKID_AHB_CTRL_BUS 61
114#define CLKID_HDMI_INTR_SYNC 62
115#define CLKID_HDMI_PCLK 63
116#define CLKID_USB1_DDR_BRIDGE 64
117#define CLKID_USB0_DDR_BRIDGE 65
118#define CLKID_MMC_PCLK 66
119#define CLKID_DVIN 67
120#define CLKID_UART2 68
121#define CLKID_SANA 69
122#define CLKID_VPU_INTR 70
123#define CLKID_SEC_AHB_AHB3_BRIDGE 71
124#define CLKID_CLK81_A9 72
125#define CLKID_VCLK2_VENCI0 73
126#define CLKID_VCLK2_VENCI1 74
127#define CLKID_VCLK2_VENCP0 75
128#define CLKID_VCLK2_VENCP1 76
129#define CLKID_GCLK_VENCI_INT 77
130#define CLKID_GCLK_VENCP_INT 78
131#define CLKID_DAC_CLK 79
132#define CLKID_AOCLK_GATE 80
133#define CLKID_IEC958_GATE 81
134#define CLKID_ENC480P 82
135#define CLKID_RNG1 83
136#define CLKID_GCLK_VENCL_INT 84
137#define CLKID_VCLK2_VENCLMCC 85
138#define CLKID_VCLK2_VENCL 86
139#define CLKID_VCLK2_OTHER 87
140#define CLKID_EDP 88
141#define CLKID_AO_MEDIA_CPU 89
142#define CLKID_AO_AHB_SRAM 90
143#define CLKID_AO_AHB_BUS 91
144#define CLKID_AO_IFACE 92
145
146#define CLK_NR_CLKS 93
147
148/* include the CLKIDs that have been made part of the stable DT binding */
149#include <dt-bindings/clock/meson8b-clkc.h>
150
151#endif /* __MESON8B_H */
diff --git a/drivers/clk/microchip/clk-core.c b/drivers/clk/microchip/clk-core.c
index ca85cea17839..c3b301463425 100644
--- a/drivers/clk/microchip/clk-core.c
+++ b/drivers/clk/microchip/clk-core.c
@@ -199,9 +199,9 @@ static int pbclk_set_rate(struct clk_hw *hw, unsigned long rate,
199 199
200 spin_unlock_irqrestore(&pb->core->reg_lock, flags); 200 spin_unlock_irqrestore(&pb->core->reg_lock, flags);
201 201
202 /* wait again, for pbdivready */ 202 /* wait again for DIV_READY */
203 err = readl_poll_timeout_atomic(pb->ctrl_reg, v, v & PB_DIV_READY, 203 err = readl_poll_timeout(pb->ctrl_reg, v, v & PB_DIV_READY,
204 1, LOCK_TIMEOUT_US); 204 1, LOCK_TIMEOUT_US);
205 if (err) 205 if (err)
206 return err; 206 return err;
207 207
diff --git a/drivers/clk/microchip/clk-pic32mzda.c b/drivers/clk/microchip/clk-pic32mzda.c
index 51f54380474b..9f734779be92 100644
--- a/drivers/clk/microchip/clk-pic32mzda.c
+++ b/drivers/clk/microchip/clk-pic32mzda.c
@@ -118,6 +118,7 @@ static const struct pic32_sec_osc_data sosc_clk = {
118 .status_reg = 0x1d0, 118 .status_reg = 0x1d0,
119 .enable_mask = BIT(1), 119 .enable_mask = BIT(1),
120 .status_mask = BIT(4), 120 .status_mask = BIT(4),
121 .fixed_rate = 32768,
121 .init_data = { 122 .init_data = {
122 .name = "sosc_clk", 123 .name = "sosc_clk",
123 .parent_names = NULL, 124 .parent_names = NULL,
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index 383f6a4f64f0..038023483b98 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -16,6 +16,7 @@
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/clk/mmp.h>
19 20
20#include "clk.h" 21#include "clk.h"
21 22
diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig
index 3165da77d525..fddc8ac5faff 100644
--- a/drivers/clk/mvebu/Kconfig
+++ b/drivers/clk/mvebu/Kconfig
@@ -24,6 +24,9 @@ config ARMADA_39X_CLK
24 bool 24 bool
25 select MVEBU_CLK_COMMON 25 select MVEBU_CLK_COMMON
26 26
27config ARMADA_37XX_CLK
28 bool
29
27config ARMADA_XP_CLK 30config ARMADA_XP_CLK
28 bool 31 bool
29 select MVEBU_CLK_COMMON 32 select MVEBU_CLK_COMMON
diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile
index 7172ef65693d..d9ae97fb43c4 100644
--- a/drivers/clk/mvebu/Makefile
+++ b/drivers/clk/mvebu/Makefile
@@ -6,6 +6,9 @@ obj-$(CONFIG_ARMADA_370_CLK) += armada-370.o
6obj-$(CONFIG_ARMADA_375_CLK) += armada-375.o 6obj-$(CONFIG_ARMADA_375_CLK) += armada-375.o
7obj-$(CONFIG_ARMADA_38X_CLK) += armada-38x.o 7obj-$(CONFIG_ARMADA_38X_CLK) += armada-38x.o
8obj-$(CONFIG_ARMADA_39X_CLK) += armada-39x.o 8obj-$(CONFIG_ARMADA_39X_CLK) += armada-39x.o
9obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-xtal.o
10obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-tbg.o
11obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-periph.o
9obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o 12obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o
10obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o 13obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o
11obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o 14obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o
diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c
new file mode 100644
index 000000000000..45905fc0d75b
--- /dev/null
+++ b/drivers/clk/mvebu/armada-37xx-periph.c
@@ -0,0 +1,447 @@
1/*
2 * Marvell Armada 37xx SoC Peripheral clocks
3 *
4 * Copyright (C) 2016 Marvell
5 *
6 * Gregory CLEMENT <gregory.clement@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2 or later. This program is licensed "as is"
10 * without any warranty of any kind, whether express or implied.
11 *
12 * Most of the peripheral clocks can be modelled like this:
13 * _____ _______ _______
14 * TBG-A-P --| | | | | | ______
15 * TBG-B-P --| Mux |--| /div1 |--| /div2 |--| Gate |--> perip_clk
16 * TBG-A-S --| | | | | | |______|
17 * TBG-B-S --|_____| |_______| |_______|
18 *
19 * However some clocks may use only one or two block or and use the
20 * xtal clock as parent.
21 */
22
23#include <linux/clk-provider.h>
24#include <linux/of.h>
25#include <linux/of_device.h>
26#include <linux/platform_device.h>
27#include <linux/slab.h>
28
29#define TBG_SEL 0x0
30#define DIV_SEL0 0x4
31#define DIV_SEL1 0x8
32#define DIV_SEL2 0xC
33#define CLK_SEL 0x10
34#define CLK_DIS 0x14
35
36struct clk_periph_driver_data {
37 struct clk_hw_onecell_data *hw_data;
38 spinlock_t lock;
39};
40
41struct clk_double_div {
42 struct clk_hw hw;
43 void __iomem *reg1;
44 u8 shift1;
45 void __iomem *reg2;
46 u8 shift2;
47};
48
49#define to_clk_double_div(_hw) container_of(_hw, struct clk_double_div, hw)
50
51struct clk_periph_data {
52 const char *name;
53 const char * const *parent_names;
54 int num_parents;
55 struct clk_hw *mux_hw;
56 struct clk_hw *rate_hw;
57 struct clk_hw *gate_hw;
58 bool is_double_div;
59};
60
61static const struct clk_div_table clk_table6[] = {
62 { .val = 1, .div = 1, },
63 { .val = 2, .div = 2, },
64 { .val = 3, .div = 3, },
65 { .val = 4, .div = 4, },
66 { .val = 5, .div = 5, },
67 { .val = 6, .div = 6, },
68 { .val = 0, .div = 0, }, /* last entry */
69};
70
71static const struct clk_div_table clk_table1[] = {
72 { .val = 0, .div = 1, },
73 { .val = 1, .div = 2, },
74 { .val = 0, .div = 0, }, /* last entry */
75};
76
77static const struct clk_div_table clk_table2[] = {
78 { .val = 0, .div = 2, },
79 { .val = 1, .div = 4, },
80 { .val = 0, .div = 0, }, /* last entry */
81};
82static const struct clk_ops clk_double_div_ops;
83
84#define PERIPH_GATE(_name, _bit) \
85struct clk_gate gate_##_name = { \
86 .reg = (void *)CLK_DIS, \
87 .bit_idx = _bit, \
88 .hw.init = &(struct clk_init_data){ \
89 .ops = &clk_gate_ops, \
90 } \
91};
92
93#define PERIPH_MUX(_name, _shift) \
94struct clk_mux mux_##_name = { \
95 .reg = (void *)TBG_SEL, \
96 .shift = _shift, \
97 .mask = 3, \
98 .hw.init = &(struct clk_init_data){ \
99 .ops = &clk_mux_ro_ops, \
100 } \
101};
102
103#define PERIPH_DOUBLEDIV(_name, _reg1, _reg2, _shift1, _shift2) \
104struct clk_double_div rate_##_name = { \
105 .reg1 = (void *)_reg1, \
106 .reg2 = (void *)_reg2, \
107 .shift1 = _shift1, \
108 .shift2 = _shift2, \
109 .hw.init = &(struct clk_init_data){ \
110 .ops = &clk_double_div_ops, \
111 } \
112};
113
114#define PERIPH_DIV(_name, _reg, _shift, _table) \
115struct clk_divider rate_##_name = { \
116 .reg = (void *)_reg, \
117 .table = _table, \
118 .shift = _shift, \
119 .hw.init = &(struct clk_init_data){ \
120 .ops = &clk_divider_ro_ops, \
121 } \
122};
123
124#define PERIPH_CLK_FULL_DD(_name, _bit, _shift, _reg1, _reg2, _shift1, _shift2)\
125static PERIPH_GATE(_name, _bit); \
126static PERIPH_MUX(_name, _shift); \
127static PERIPH_DOUBLEDIV(_name, _reg1, _reg2, _shift1, _shift2);
128
129#define PERIPH_CLK_FULL(_name, _bit, _shift, _reg, _shift1, _table) \
130static PERIPH_GATE(_name, _bit); \
131static PERIPH_MUX(_name, _shift); \
132static PERIPH_DIV(_name, _reg, _shift1, _table);
133
134#define PERIPH_CLK_GATE_DIV(_name, _bit, _reg, _shift, _table) \
135static PERIPH_GATE(_name, _bit); \
136static PERIPH_DIV(_name, _reg, _shift, _table);
137
138#define PERIPH_CLK_MUX_DIV(_name, _shift, _reg, _shift_div, _table) \
139static PERIPH_MUX(_name, _shift); \
140static PERIPH_DIV(_name, _reg, _shift_div, _table);
141
142#define PERIPH_CLK_MUX_DD(_name, _shift, _reg1, _reg2, _shift1, _shift2)\
143static PERIPH_MUX(_name, _shift); \
144static PERIPH_DOUBLEDIV(_name, _reg1, _reg2, _shift1, _shift2);
145
146#define REF_CLK_FULL(_name) \
147 { .name = #_name, \
148 .parent_names = (const char *[]){ "TBG-A-P", \
149 "TBG-B-P", "TBG-A-S", "TBG-B-S"}, \
150 .num_parents = 4, \
151 .mux_hw = &mux_##_name.hw, \
152 .gate_hw = &gate_##_name.hw, \
153 .rate_hw = &rate_##_name.hw, \
154 }
155
156#define REF_CLK_FULL_DD(_name) \
157 { .name = #_name, \
158 .parent_names = (const char *[]){ "TBG-A-P", \
159 "TBG-B-P", "TBG-A-S", "TBG-B-S"}, \
160 .num_parents = 4, \
161 .mux_hw = &mux_##_name.hw, \
162 .gate_hw = &gate_##_name.hw, \
163 .rate_hw = &rate_##_name.hw, \
164 .is_double_div = true, \
165 }
166
167#define REF_CLK_GATE(_name, _parent_name) \
168 { .name = #_name, \
169 .parent_names = (const char *[]){ _parent_name}, \
170 .num_parents = 1, \
171 .gate_hw = &gate_##_name.hw, \
172 }
173
174#define REF_CLK_GATE_DIV(_name, _parent_name) \
175 { .name = #_name, \
176 .parent_names = (const char *[]){ _parent_name}, \
177 .num_parents = 1, \
178 .gate_hw = &gate_##_name.hw, \
179 .rate_hw = &rate_##_name.hw, \
180 }
181
182#define REF_CLK_MUX_DIV(_name) \
183 { .name = #_name, \
184 .parent_names = (const char *[]){ "TBG-A-P", \
185 "TBG-B-P", "TBG-A-S", "TBG-B-S"}, \
186 .num_parents = 4, \
187 .mux_hw = &mux_##_name.hw, \
188 .rate_hw = &rate_##_name.hw, \
189 }
190
191#define REF_CLK_MUX_DD(_name) \
192 { .name = #_name, \
193 .parent_names = (const char *[]){ "TBG-A-P", \
194 "TBG-B-P", "TBG-A-S", "TBG-B-S"}, \
195 .num_parents = 4, \
196 .mux_hw = &mux_##_name.hw, \
197 .rate_hw = &rate_##_name.hw, \
198 .is_double_div = true, \
199 }
200
201/* NB periph clocks */
202PERIPH_CLK_FULL_DD(mmc, 2, 0, DIV_SEL2, DIV_SEL2, 16, 13);
203PERIPH_CLK_FULL_DD(sata_host, 3, 2, DIV_SEL2, DIV_SEL2, 10, 7);
204PERIPH_CLK_FULL_DD(sec_at, 6, 4, DIV_SEL1, DIV_SEL1, 3, 0);
205PERIPH_CLK_FULL_DD(sec_dap, 7, 6, DIV_SEL1, DIV_SEL1, 9, 6);
206PERIPH_CLK_FULL_DD(tscem, 8, 8, DIV_SEL1, DIV_SEL1, 15, 12);
207PERIPH_CLK_FULL(tscem_tmx, 10, 10, DIV_SEL1, 18, clk_table6);
208static PERIPH_GATE(avs, 11);
209PERIPH_CLK_FULL_DD(pwm, 13, 14, DIV_SEL0, DIV_SEL0, 3, 0);
210PERIPH_CLK_FULL_DD(sqf, 12, 12, DIV_SEL1, DIV_SEL1, 27, 24);
211static PERIPH_GATE(i2c_2, 16);
212static PERIPH_GATE(i2c_1, 17);
213PERIPH_CLK_GATE_DIV(ddr_phy, 19, DIV_SEL0, 18, clk_table2);
214PERIPH_CLK_FULL_DD(ddr_fclk, 21, 16, DIV_SEL0, DIV_SEL0, 15, 12);
215PERIPH_CLK_FULL(trace, 22, 18, DIV_SEL0, 20, clk_table6);
216PERIPH_CLK_FULL(counter, 23, 20, DIV_SEL0, 23, clk_table6);
217PERIPH_CLK_FULL_DD(eip97, 24, 24, DIV_SEL2, DIV_SEL2, 22, 19);
218PERIPH_CLK_MUX_DIV(cpu, 22, DIV_SEL0, 28, clk_table6);
219
220static struct clk_periph_data data_nb[] ={
221 REF_CLK_FULL_DD(mmc),
222 REF_CLK_FULL_DD(sata_host),
223 REF_CLK_FULL_DD(sec_at),
224 REF_CLK_FULL_DD(sec_dap),
225 REF_CLK_FULL_DD(tscem),
226 REF_CLK_FULL(tscem_tmx),
227 REF_CLK_GATE(avs, "xtal"),
228 REF_CLK_FULL_DD(sqf),
229 REF_CLK_FULL_DD(pwm),
230 REF_CLK_GATE(i2c_2, "xtal"),
231 REF_CLK_GATE(i2c_1, "xtal"),
232 REF_CLK_GATE_DIV(ddr_phy, "TBG-A-S"),
233 REF_CLK_FULL_DD(ddr_fclk),
234 REF_CLK_FULL(trace),
235 REF_CLK_FULL(counter),
236 REF_CLK_FULL_DD(eip97),
237 REF_CLK_MUX_DIV(cpu),
238 { },
239};
240
241/* SB periph clocks */
242PERIPH_CLK_MUX_DD(gbe_50, 6, DIV_SEL2, DIV_SEL2, 6, 9);
243PERIPH_CLK_MUX_DD(gbe_core, 8, DIV_SEL1, DIV_SEL1, 18, 21);
244PERIPH_CLK_MUX_DD(gbe_125, 10, DIV_SEL1, DIV_SEL1, 6, 9);
245static PERIPH_GATE(gbe1_50, 0);
246static PERIPH_GATE(gbe0_50, 1);
247static PERIPH_GATE(gbe1_125, 2);
248static PERIPH_GATE(gbe0_125, 3);
249PERIPH_CLK_GATE_DIV(gbe1_core, 4, DIV_SEL1, 13, clk_table1);
250PERIPH_CLK_GATE_DIV(gbe0_core, 5, DIV_SEL1, 14, clk_table1);
251PERIPH_CLK_GATE_DIV(gbe_bm, 12, DIV_SEL1, 0, clk_table1);
252PERIPH_CLK_FULL_DD(sdio, 11, 14, DIV_SEL0, DIV_SEL0, 3, 6);
253PERIPH_CLK_FULL_DD(usb32_usb2_sys, 16, 16, DIV_SEL0, DIV_SEL0, 9, 12);
254PERIPH_CLK_FULL_DD(usb32_ss_sys, 17, 18, DIV_SEL0, DIV_SEL0, 15, 18);
255
256static struct clk_periph_data data_sb[] = {
257 REF_CLK_MUX_DD(gbe_50),
258 REF_CLK_MUX_DD(gbe_core),
259 REF_CLK_MUX_DD(gbe_125),
260 REF_CLK_GATE(gbe1_50, "gbe_50"),
261 REF_CLK_GATE(gbe0_50, "gbe_50"),
262 REF_CLK_GATE(gbe1_125, "gbe_125"),
263 REF_CLK_GATE(gbe0_125, "gbe_125"),
264 REF_CLK_GATE_DIV(gbe1_core, "gbe_core"),
265 REF_CLK_GATE_DIV(gbe0_core, "gbe_core"),
266 REF_CLK_GATE_DIV(gbe_bm, "gbe_core"),
267 REF_CLK_FULL_DD(sdio),
268 REF_CLK_FULL_DD(usb32_usb2_sys),
269 REF_CLK_FULL_DD(usb32_ss_sys),
270 { },
271};
272
273static unsigned int get_div(void __iomem *reg, int shift)
274{
275 u32 val;
276
277 val = (readl(reg) >> shift) & 0x7;
278 if (val > 6)
279 return 0;
280 return val;
281}
282
283static unsigned long clk_double_div_recalc_rate(struct clk_hw *hw,
284 unsigned long parent_rate)
285{
286 struct clk_double_div *double_div = to_clk_double_div(hw);
287 unsigned int div;
288
289 div = get_div(double_div->reg1, double_div->shift1);
290 div *= get_div(double_div->reg2, double_div->shift2);
291
292 return DIV_ROUND_UP_ULL((u64)parent_rate, div);
293}
294
295static const struct clk_ops clk_double_div_ops = {
296 .recalc_rate = clk_double_div_recalc_rate,
297};
298
299static const struct of_device_id armada_3700_periph_clock_of_match[] = {
300 { .compatible = "marvell,armada-3700-periph-clock-nb",
301 .data = data_nb, },
302 { .compatible = "marvell,armada-3700-periph-clock-sb",
303 .data = data_sb, },
304 { }
305};
306static int armada_3700_add_composite_clk(const struct clk_periph_data *data,
307 void __iomem *reg, spinlock_t *lock,
308 struct device *dev, struct clk_hw *hw)
309{
310 const struct clk_ops *mux_ops = NULL, *gate_ops = NULL,
311 *rate_ops = NULL;
312 struct clk_hw *mux_hw = NULL, *gate_hw = NULL, *rate_hw = NULL;
313
314 if (data->mux_hw) {
315 struct clk_mux *mux;
316
317 mux_hw = data->mux_hw;
318 mux = to_clk_mux(mux_hw);
319 mux->lock = lock;
320 mux_ops = mux_hw->init->ops;
321 mux->reg = reg + (u64)mux->reg;
322 }
323
324 if (data->gate_hw) {
325 struct clk_gate *gate;
326
327 gate_hw = data->gate_hw;
328 gate = to_clk_gate(gate_hw);
329 gate->lock = lock;
330 gate_ops = gate_hw->init->ops;
331 gate->reg = reg + (u64)gate->reg;
332 }
333
334 if (data->rate_hw) {
335 rate_hw = data->rate_hw;
336 rate_ops = rate_hw->init->ops;
337 if (data->is_double_div) {
338 struct clk_double_div *rate;
339
340 rate = to_clk_double_div(rate_hw);
341 rate->reg1 = reg + (u64)rate->reg1;
342 rate->reg2 = reg + (u64)rate->reg2;
343 } else {
344 struct clk_divider *rate = to_clk_divider(rate_hw);
345 const struct clk_div_table *clkt;
346 int table_size = 0;
347
348 rate->reg = reg + (u64)rate->reg;
349 for (clkt = rate->table; clkt->div; clkt++)
350 table_size++;
351 rate->width = order_base_2(table_size);
352 rate->lock = lock;
353 }
354 }
355
356 hw = clk_hw_register_composite(dev, data->name, data->parent_names,
357 data->num_parents, mux_hw,
358 mux_ops, rate_hw, rate_ops,
359 gate_hw, gate_ops, CLK_IGNORE_UNUSED);
360
361 if (IS_ERR(hw))
362 return PTR_ERR(hw);
363
364 return 0;
365}
366
367static int armada_3700_periph_clock_probe(struct platform_device *pdev)
368{
369 struct clk_periph_driver_data *driver_data;
370 struct device_node *np = pdev->dev.of_node;
371 const struct clk_periph_data *data;
372 struct device *dev = &pdev->dev;
373 int num_periph = 0, i, ret;
374 struct resource *res;
375 void __iomem *reg;
376
377 data = of_device_get_match_data(dev);
378 if (!data)
379 return -ENODEV;
380
381 while (data[num_periph].name)
382 num_periph++;
383
384 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
385 reg = devm_ioremap_resource(dev, res);
386 if (IS_ERR(reg))
387 return PTR_ERR(reg);
388
389 driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL);
390 if (!driver_data)
391 return -ENOMEM;
392
393 driver_data->hw_data = devm_kzalloc(dev, sizeof(*driver_data->hw_data) +
394 sizeof(*driver_data->hw_data->hws) * num_periph,
395 GFP_KERNEL);
396 if (!driver_data->hw_data)
397 return -ENOMEM;
398 driver_data->hw_data->num = num_periph;
399
400 spin_lock_init(&driver_data->lock);
401
402 for (i = 0; i < num_periph; i++) {
403 struct clk_hw *hw = driver_data->hw_data->hws[i];
404
405 if (armada_3700_add_composite_clk(&data[i], reg,
406 &driver_data->lock, dev, hw))
407 dev_err(dev, "Can't register periph clock %s\n",
408 data[i].name);
409
410 }
411
412 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
413 driver_data->hw_data);
414 if (ret) {
415 for (i = 0; i < num_periph; i++)
416 clk_hw_unregister(driver_data->hw_data->hws[i]);
417 return ret;
418 }
419
420 platform_set_drvdata(pdev, driver_data);
421 return 0;
422}
423
424static int armada_3700_periph_clock_remove(struct platform_device *pdev)
425{
426 struct clk_periph_driver_data *data = platform_get_drvdata(pdev);
427 struct clk_hw_onecell_data *hw_data = data->hw_data;
428 int i;
429
430 of_clk_del_provider(pdev->dev.of_node);
431
432 for (i = 0; i < hw_data->num; i++)
433 clk_hw_unregister(hw_data->hws[i]);
434
435 return 0;
436}
437
438static struct platform_driver armada_3700_periph_clock_driver = {
439 .probe = armada_3700_periph_clock_probe,
440 .remove = armada_3700_periph_clock_remove,
441 .driver = {
442 .name = "marvell-armada-3700-periph-clock",
443 .of_match_table = armada_3700_periph_clock_of_match,
444 },
445};
446
447builtin_platform_driver(armada_3700_periph_clock_driver);
diff --git a/drivers/clk/mvebu/armada-37xx-tbg.c b/drivers/clk/mvebu/armada-37xx-tbg.c
new file mode 100644
index 000000000000..aa80db11f543
--- /dev/null
+++ b/drivers/clk/mvebu/armada-37xx-tbg.c
@@ -0,0 +1,158 @@
1/*
2 * Marvell Armada 37xx SoC Time Base Generator clocks
3 *
4 * Copyright (C) 2016 Marvell
5 *
6 * Gregory CLEMENT <gregory.clement@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2 or later. This program is licensed "as is"
10 * without any warranty of any kind, whether express or implied.
11 */
12
13#include <linux/clk-provider.h>
14#include <linux/clk.h>
15#include <linux/of.h>
16#include <linux/of_address.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19
20#define NUM_TBG 4
21
22#define TBG_CTRL0 0x4
23#define TBG_CTRL1 0x8
24#define TBG_CTRL7 0x20
25#define TBG_CTRL8 0x30
26
27#define TBG_DIV_MASK 0x1FF
28
29#define TBG_A_REFDIV 0
30#define TBG_B_REFDIV 16
31
32#define TBG_A_FBDIV 2
33#define TBG_B_FBDIV 18
34
35#define TBG_A_VCODIV_SE 0
36#define TBG_B_VCODIV_SE 16
37
38#define TBG_A_VCODIV_DIFF 1
39#define TBG_B_VCODIV_DIFF 17
40
41struct tbg_def {
42 char *name;
43 u32 refdiv_offset;
44 u32 fbdiv_offset;
45 u32 vcodiv_reg;
46 u32 vcodiv_offset;
47};
48
49static const struct tbg_def tbg[NUM_TBG] = {
50 {"TBG-A-P", TBG_A_REFDIV, TBG_A_FBDIV, TBG_CTRL8, TBG_A_VCODIV_DIFF},
51 {"TBG-B-P", TBG_B_REFDIV, TBG_B_FBDIV, TBG_CTRL8, TBG_B_VCODIV_DIFF},
52 {"TBG-A-S", TBG_A_REFDIV, TBG_A_FBDIV, TBG_CTRL1, TBG_A_VCODIV_SE},
53 {"TBG-B-S", TBG_B_REFDIV, TBG_B_FBDIV, TBG_CTRL1, TBG_B_VCODIV_SE},
54};
55
56static unsigned int tbg_get_mult(void __iomem *reg, const struct tbg_def *ptbg)
57{
58 u32 val;
59
60 val = readl(reg + TBG_CTRL0);
61
62 return ((val >> ptbg->fbdiv_offset) & TBG_DIV_MASK) << 2;
63}
64
65static unsigned int tbg_get_div(void __iomem *reg, const struct tbg_def *ptbg)
66{
67 u32 val;
68 unsigned int div;
69
70 val = readl(reg + TBG_CTRL7);
71
72 div = (val >> ptbg->refdiv_offset) & TBG_DIV_MASK;
73 if (div == 0)
74 div = 1;
75 val = readl(reg + ptbg->vcodiv_reg);
76
77 div *= 1 << ((val >> ptbg->vcodiv_offset) & TBG_DIV_MASK);
78
79 return div;
80}
81
82
83static int armada_3700_tbg_clock_probe(struct platform_device *pdev)
84{
85 struct device_node *np = pdev->dev.of_node;
86 struct clk_hw_onecell_data *hw_tbg_data;
87 struct device *dev = &pdev->dev;
88 const char *parent_name;
89 struct resource *res;
90 struct clk *parent;
91 void __iomem *reg;
92 int i, ret;
93
94 hw_tbg_data = devm_kzalloc(&pdev->dev, sizeof(*hw_tbg_data)
95 + sizeof(*hw_tbg_data->hws) * NUM_TBG,
96 GFP_KERNEL);
97 if (!hw_tbg_data)
98 return -ENOMEM;
99 hw_tbg_data->num = NUM_TBG;
100 platform_set_drvdata(pdev, hw_tbg_data);
101
102 parent = devm_clk_get(dev, NULL);
103 if (IS_ERR(parent)) {
104 dev_err(dev, "Could get the clock parent\n");
105 return -EINVAL;
106 }
107 parent_name = __clk_get_name(parent);
108
109 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
110 reg = devm_ioremap_resource(dev, res);
111 if (IS_ERR(reg))
112 return PTR_ERR(reg);
113
114 for (i = 0; i < NUM_TBG; i++) {
115 const char *name;
116 unsigned int mult, div;
117
118 name = tbg[i].name;
119 mult = tbg_get_mult(reg, &tbg[i]);
120 div = tbg_get_div(reg, &tbg[i]);
121 hw_tbg_data->hws[i] = clk_hw_register_fixed_factor(NULL, name,
122 parent_name, 0, mult, div);
123 if (IS_ERR(hw_tbg_data->hws[i]))
124 dev_err(dev, "Can't register TBG clock %s\n", name);
125 }
126
127 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, hw_tbg_data);
128
129 return ret;
130}
131
132static int armada_3700_tbg_clock_remove(struct platform_device *pdev)
133{
134 int i;
135 struct clk_hw_onecell_data *hw_tbg_data = platform_get_drvdata(pdev);
136
137 of_clk_del_provider(pdev->dev.of_node);
138 for (i = 0; i < hw_tbg_data->num; i++)
139 clk_hw_unregister_fixed_factor(hw_tbg_data->hws[i]);
140
141 return 0;
142}
143
144static const struct of_device_id armada_3700_tbg_clock_of_match[] = {
145 { .compatible = "marvell,armada-3700-tbg-clock", },
146 { }
147};
148
149static struct platform_driver armada_3700_tbg_clock_driver = {
150 .probe = armada_3700_tbg_clock_probe,
151 .remove = armada_3700_tbg_clock_remove,
152 .driver = {
153 .name = "marvell-armada-3700-tbg-clock",
154 .of_match_table = armada_3700_tbg_clock_of_match,
155 },
156};
157
158builtin_platform_driver(armada_3700_tbg_clock_driver);
diff --git a/drivers/clk/mvebu/armada-37xx-xtal.c b/drivers/clk/mvebu/armada-37xx-xtal.c
new file mode 100644
index 000000000000..612d65ede10a
--- /dev/null
+++ b/drivers/clk/mvebu/armada-37xx-xtal.c
@@ -0,0 +1,91 @@
1/*
2 * Marvell Armada 37xx SoC xtal clocks
3 *
4 * Copyright (C) 2016 Marvell
5 *
6 * Gregory CLEMENT <gregory.clement@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/clk-provider.h>
14#include <linux/mfd/syscon.h>
15#include <linux/platform_device.h>
16#include <linux/regmap.h>
17
18#define NB_GPIO1_LATCH 0xC
19#define XTAL_MODE BIT(31)
20
21static int armada_3700_xtal_clock_probe(struct platform_device *pdev)
22{
23 struct device_node *np = pdev->dev.of_node;
24 const char *xtal_name = "xtal";
25 struct device_node *parent;
26 struct regmap *regmap;
27 struct clk_hw *xtal_hw;
28 unsigned int rate;
29 u32 reg;
30 int ret;
31
32 xtal_hw = devm_kzalloc(&pdev->dev, sizeof(*xtal_hw), GFP_KERNEL);
33 if (!xtal_hw)
34 return -ENOMEM;
35
36 platform_set_drvdata(pdev, xtal_hw);
37
38 parent = np->parent;
39 if (!parent) {
40 dev_err(&pdev->dev, "no parent\n");
41 return -ENODEV;
42 }
43
44 regmap = syscon_node_to_regmap(parent);
45 if (IS_ERR(regmap)) {
46 dev_err(&pdev->dev, "cannot get regmap\n");
47 return PTR_ERR(regmap);
48 }
49
50 ret = regmap_read(regmap, NB_GPIO1_LATCH, &reg);
51 if (ret) {
52 dev_err(&pdev->dev, "cannot read from regmap\n");
53 return ret;
54 }
55
56 if (reg & XTAL_MODE)
57 rate = 40000000;
58 else
59 rate = 25000000;
60
61 of_property_read_string_index(np, "clock-output-names", 0, &xtal_name);
62 xtal_hw = clk_hw_register_fixed_rate(NULL, xtal_name, NULL, 0, rate);
63 if (IS_ERR(xtal_hw))
64 return PTR_ERR(xtal_hw);
65 ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, xtal_hw);
66
67 return ret;
68}
69
70static int armada_3700_xtal_clock_remove(struct platform_device *pdev)
71{
72 of_clk_del_provider(pdev->dev.of_node);
73
74 return 0;
75}
76
77static const struct of_device_id armada_3700_xtal_clock_of_match[] = {
78 { .compatible = "marvell,armada-3700-xtal-clock", },
79 { }
80};
81
82static struct platform_driver armada_3700_xtal_clock_driver = {
83 .probe = armada_3700_xtal_clock_probe,
84 .remove = armada_3700_xtal_clock_remove,
85 .driver = {
86 .name = "marvell-armada-3700-xtal-clock",
87 .of_match_table = armada_3700_xtal_clock_of_match,
88 },
89};
90
91builtin_platform_driver(armada_3700_xtal_clock_driver);
diff --git a/drivers/clk/mvebu/armada-39x.c b/drivers/clk/mvebu/armada-39x.c
index efb974df9822..4fdfd32247a9 100644
--- a/drivers/clk/mvebu/armada-39x.c
+++ b/drivers/clk/mvebu/armada-39x.c
@@ -142,6 +142,8 @@ static const struct clk_gating_soc_desc armada_39x_gating_desc[] __initconst = {
142 { "pex3", NULL, 7 }, 142 { "pex3", NULL, 7 },
143 { "pex0", NULL, 8 }, 143 { "pex0", NULL, 8 },
144 { "usb3h0", NULL, 9 }, 144 { "usb3h0", NULL, 9 },
145 { "usb3h1", NULL, 10 },
146 { "sata0", NULL, 15 },
145 { "sdio", NULL, 17 }, 147 { "sdio", NULL, 17 },
146 { "xor0", NULL, 22 }, 148 { "xor0", NULL, 22 },
147 { "xor1", NULL, 28 }, 149 { "xor1", NULL, 28 },
diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c
index 7fa42d6b2b92..f2303da7fda7 100644
--- a/drivers/clk/mvebu/cp110-system-controller.c
+++ b/drivers/clk/mvebu/cp110-system-controller.c
@@ -81,13 +81,6 @@ enum {
81#define CP110_GATE_EIP150 25 81#define CP110_GATE_EIP150 25
82#define CP110_GATE_EIP197 26 82#define CP110_GATE_EIP197 26
83 83
84static struct clk *cp110_clks[CP110_CLK_NUM];
85
86static struct clk_onecell_data cp110_clk_data = {
87 .clks = cp110_clks,
88 .clk_num = CP110_CLK_NUM,
89};
90
91struct cp110_gate_clk { 84struct cp110_gate_clk {
92 struct clk_hw hw; 85 struct clk_hw hw;
93 struct regmap *regmap; 86 struct regmap *regmap;
@@ -142,6 +135,8 @@ static struct clk *cp110_register_gate(const char *name,
142 if (!gate) 135 if (!gate)
143 return ERR_PTR(-ENOMEM); 136 return ERR_PTR(-ENOMEM);
144 137
138 memset(&init, 0, sizeof(init));
139
145 init.name = name; 140 init.name = name;
146 init.ops = &cp110_gate_ops; 141 init.ops = &cp110_gate_ops;
147 init.parent_names = &parent_name; 142 init.parent_names = &parent_name;
@@ -194,7 +189,8 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
194 struct regmap *regmap; 189 struct regmap *regmap;
195 struct device_node *np = pdev->dev.of_node; 190 struct device_node *np = pdev->dev.of_node;
196 const char *ppv2_name, *apll_name, *core_name, *eip_name, *nand_name; 191 const char *ppv2_name, *apll_name, *core_name, *eip_name, *nand_name;
197 struct clk *clk; 192 struct clk_onecell_data *cp110_clk_data;
193 struct clk *clk, **cp110_clks;
198 u32 nand_clk_ctrl; 194 u32 nand_clk_ctrl;
199 int i, ret; 195 int i, ret;
200 196
@@ -207,6 +203,20 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
207 if (ret) 203 if (ret)
208 return ret; 204 return ret;
209 205
206 cp110_clks = devm_kcalloc(&pdev->dev, sizeof(struct clk *),
207 CP110_CLK_NUM, GFP_KERNEL);
208 if (!cp110_clks)
209 return -ENOMEM;
210
211 cp110_clk_data = devm_kzalloc(&pdev->dev,
212 sizeof(*cp110_clk_data),
213 GFP_KERNEL);
214 if (!cp110_clk_data)
215 return -ENOMEM;
216
217 cp110_clk_data->clks = cp110_clks;
218 cp110_clk_data->clk_num = CP110_CLK_NUM;
219
210 /* Register the APLL which is the root of the clk tree */ 220 /* Register the APLL which is the root of the clk tree */
211 of_property_read_string_index(np, "core-clock-output-names", 221 of_property_read_string_index(np, "core-clock-output-names",
212 CP110_CORE_APLL, &apll_name); 222 CP110_CORE_APLL, &apll_name);
@@ -334,10 +344,12 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
334 cp110_clks[CP110_MAX_CORE_CLOCKS + i] = clk; 344 cp110_clks[CP110_MAX_CORE_CLOCKS + i] = clk;
335 } 345 }
336 346
337 ret = of_clk_add_provider(np, cp110_of_clk_get, &cp110_clk_data); 347 ret = of_clk_add_provider(np, cp110_of_clk_get, cp110_clk_data);
338 if (ret) 348 if (ret)
339 goto fail_clk_add; 349 goto fail_clk_add;
340 350
351 platform_set_drvdata(pdev, cp110_clks);
352
341 return 0; 353 return 0;
342 354
343fail_clk_add: 355fail_clk_add:
@@ -364,6 +376,7 @@ fail0:
364 376
365static int cp110_syscon_clk_remove(struct platform_device *pdev) 377static int cp110_syscon_clk_remove(struct platform_device *pdev)
366{ 378{
379 struct clk **cp110_clks = platform_get_drvdata(pdev);
367 int i; 380 int i;
368 381
369 of_clk_del_provider(pdev->dev.of_node); 382 of_clk_del_provider(pdev->dev.of_node);
diff --git a/drivers/clk/nxp/clk-lpc18xx-creg.c b/drivers/clk/nxp/clk-lpc18xx-creg.c
index 9e35749dafdf..c6e802e7e6ec 100644
--- a/drivers/clk/nxp/clk-lpc18xx-creg.c
+++ b/drivers/clk/nxp/clk-lpc18xx-creg.c
@@ -184,7 +184,8 @@ static void __init lpc18xx_creg_clk_init(struct device_node *np)
184 184
185 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_creg_early_data); 185 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_creg_early_data);
186} 186}
187CLK_OF_DECLARE(lpc18xx_creg_clk, "nxp,lpc1850-creg-clk", lpc18xx_creg_clk_init); 187CLK_OF_DECLARE_DRIVER(lpc18xx_creg_clk, "nxp,lpc1850-creg-clk",
188 lpc18xx_creg_clk_init);
188 189
189static struct clk *clk_creg[CREG_CLK_MAX]; 190static struct clk *clk_creg[CREG_CLK_MAX];
190static struct clk_onecell_data clk_creg_data = { 191static struct clk_onecell_data clk_creg_data = {
diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c
index 90d740a2fc0d..34c97353cdeb 100644
--- a/drivers/clk/nxp/clk-lpc32xx.c
+++ b/drivers/clk/nxp/clk-lpc32xx.c
@@ -1513,6 +1513,7 @@ static void __init lpc32xx_clk_init(struct device_node *np)
1513 if (IS_ERR(clk_regmap)) { 1513 if (IS_ERR(clk_regmap)) {
1514 pr_err("failed to regmap system control block: %ld\n", 1514 pr_err("failed to regmap system control block: %ld\n",
1515 PTR_ERR(clk_regmap)); 1515 PTR_ERR(clk_regmap));
1516 iounmap(base);
1516 return; 1517 return;
1517 } 1518 }
1518 1519
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 95e3b3e0fa1c..0146d3c2547f 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -87,6 +87,23 @@ config MSM_LCC_8960
87 Say Y if you want to use audio devices such as i2s, pcm, 87 Say Y if you want to use audio devices such as i2s, pcm,
88 SLIMBus, etc. 88 SLIMBus, etc.
89 89
90config MDM_GCC_9615
91 tristate "MDM9615 Global Clock Controller"
92 depends on COMMON_CLK_QCOM
93 help
94 Support for the global clock controller on mdm9615 devices.
95 Say Y if you want to use peripheral devices such as UART, SPI,
96 i2c, USB, SD/eMMC, etc.
97
98config MDM_LCC_9615
99 tristate "MDM9615 LPASS Clock Controller"
100 select MDM_GCC_9615
101 depends on COMMON_CLK_QCOM
102 help
103 Support for the LPASS clock controller on mdm9615 devices.
104 Say Y if you want to use audio devices such as i2s, pcm,
105 SLIMBus, etc.
106
90config MSM_MMCC_8960 107config MSM_MMCC_8960
91 tristate "MSM8960 Multimedia Clock Controller" 108 tristate "MSM8960 Multimedia Clock Controller"
92 select MSM_GCC_8960 109 select MSM_GCC_8960
@@ -117,6 +134,7 @@ config MSM_MMCC_8974
117 134
118config MSM_GCC_8996 135config MSM_GCC_8996
119 tristate "MSM8996 Global Clock Controller" 136 tristate "MSM8996 Global Clock Controller"
137 select QCOM_GDSC
120 depends on COMMON_CLK_QCOM 138 depends on COMMON_CLK_QCOM
121 help 139 help
122 Support for the global clock controller on msm8996 devices. 140 Support for the global clock controller on msm8996 devices.
@@ -126,6 +144,7 @@ config MSM_GCC_8996
126config MSM_MMCC_8996 144config MSM_MMCC_8996
127 tristate "MSM8996 Multimedia Clock Controller" 145 tristate "MSM8996 Multimedia Clock Controller"
128 select MSM_GCC_8996 146 select MSM_GCC_8996
147 select QCOM_GDSC
129 depends on COMMON_CLK_QCOM 148 depends on COMMON_CLK_QCOM
130 help 149 help
131 Support for the multimedia clock controller on msm8996 devices. 150 Support for the multimedia clock controller on msm8996 devices.
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 2a25f4e75f49..1fb1f5476cb0 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -12,17 +12,20 @@ clk-qcom-y += clk-regmap-mux.o
12clk-qcom-y += reset.o 12clk-qcom-y += reset.o
13clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o 13clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
14 14
15# Keep alphabetically sorted by config
15obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o 16obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
16obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o 17obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
17obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o 18obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
18obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o 19obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
19obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o 20obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o
21obj-$(CONFIG_MDM_GCC_9615) += gcc-mdm9615.o
22obj-$(CONFIG_MDM_LCC_9615) += lcc-mdm9615.o
20obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o 23obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
21obj-$(CONFIG_MSM_GCC_8916) += gcc-msm8916.o 24obj-$(CONFIG_MSM_GCC_8916) += gcc-msm8916.o
22obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o 25obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
23obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o
24obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o 26obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
25obj-$(CONFIG_MSM_GCC_8996) += gcc-msm8996.o 27obj-$(CONFIG_MSM_GCC_8996) += gcc-msm8996.o
28obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o
26obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o 29obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
27obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o 30obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
28obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o 31obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
diff --git a/drivers/clk/qcom/clk-regmap.c b/drivers/clk/qcom/clk-regmap.c
index a58ba39a900c..1c856d330733 100644
--- a/drivers/clk/qcom/clk-regmap.c
+++ b/drivers/clk/qcom/clk-regmap.c
@@ -101,14 +101,13 @@ EXPORT_SYMBOL_GPL(clk_disable_regmap);
101 * clk_regmap struct via this function so that the regmap is initialized 101 * clk_regmap struct via this function so that the regmap is initialized
102 * and so that the clock is registered with the common clock framework. 102 * and so that the clock is registered with the common clock framework.
103 */ 103 */
104struct clk *devm_clk_register_regmap(struct device *dev, 104int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk)
105 struct clk_regmap *rclk)
106{ 105{
107 if (dev && dev_get_regmap(dev, NULL)) 106 if (dev && dev_get_regmap(dev, NULL))
108 rclk->regmap = dev_get_regmap(dev, NULL); 107 rclk->regmap = dev_get_regmap(dev, NULL);
109 else if (dev && dev->parent) 108 else if (dev && dev->parent)
110 rclk->regmap = dev_get_regmap(dev->parent, NULL); 109 rclk->regmap = dev_get_regmap(dev->parent, NULL);
111 110
112 return devm_clk_register(dev, &rclk->hw); 111 return devm_clk_hw_register(dev, &rclk->hw);
113} 112}
114EXPORT_SYMBOL_GPL(devm_clk_register_regmap); 113EXPORT_SYMBOL_GPL(devm_clk_register_regmap);
diff --git a/drivers/clk/qcom/clk-regmap.h b/drivers/clk/qcom/clk-regmap.h
index 491a63d537df..90d95cd11ec6 100644
--- a/drivers/clk/qcom/clk-regmap.h
+++ b/drivers/clk/qcom/clk-regmap.h
@@ -39,7 +39,6 @@ struct clk_regmap {
39int clk_is_enabled_regmap(struct clk_hw *hw); 39int clk_is_enabled_regmap(struct clk_hw *hw);
40int clk_enable_regmap(struct clk_hw *hw); 40int clk_enable_regmap(struct clk_hw *hw);
41void clk_disable_regmap(struct clk_hw *hw); 41void clk_disable_regmap(struct clk_hw *hw);
42struct clk * 42int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk);
43devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk);
44 43
45#endif 44#endif
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
index f7c226ab4307..fffcbaf0fba7 100644
--- a/drivers/clk/qcom/common.c
+++ b/drivers/clk/qcom/common.c
@@ -27,8 +27,8 @@
27 27
28struct qcom_cc { 28struct qcom_cc {
29 struct qcom_reset_controller reset; 29 struct qcom_reset_controller reset;
30 struct clk_onecell_data data; 30 struct clk_regmap **rclks;
31 struct clk *clks[]; 31 size_t num_rclks;
32}; 32};
33 33
34const 34const
@@ -102,8 +102,8 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path,
102 struct device_node *clocks_node; 102 struct device_node *clocks_node;
103 struct clk_fixed_factor *factor; 103 struct clk_fixed_factor *factor;
104 struct clk_fixed_rate *fixed; 104 struct clk_fixed_rate *fixed;
105 struct clk *clk;
106 struct clk_init_data init_data = { }; 105 struct clk_init_data init_data = { };
106 int ret;
107 107
108 clocks_node = of_find_node_by_path("/clocks"); 108 clocks_node = of_find_node_by_path("/clocks");
109 if (clocks_node) 109 if (clocks_node)
@@ -121,9 +121,9 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path,
121 init_data.name = path; 121 init_data.name = path;
122 init_data.ops = &clk_fixed_rate_ops; 122 init_data.ops = &clk_fixed_rate_ops;
123 123
124 clk = devm_clk_register(dev, &fixed->hw); 124 ret = devm_clk_hw_register(dev, &fixed->hw);
125 if (IS_ERR(clk)) 125 if (ret)
126 return PTR_ERR(clk); 126 return ret;
127 } 127 }
128 of_node_put(node); 128 of_node_put(node);
129 129
@@ -141,9 +141,9 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path,
141 init_data.flags = 0; 141 init_data.flags = 0;
142 init_data.ops = &clk_fixed_factor_ops; 142 init_data.ops = &clk_fixed_factor_ops;
143 143
144 clk = devm_clk_register(dev, &factor->hw); 144 ret = devm_clk_hw_register(dev, &factor->hw);
145 if (IS_ERR(clk)) 145 if (ret)
146 return PTR_ERR(clk); 146 return ret;
147 } 147 }
148 148
149 return 0; 149 return 0;
@@ -174,42 +174,48 @@ int qcom_cc_register_sleep_clk(struct device *dev)
174} 174}
175EXPORT_SYMBOL_GPL(qcom_cc_register_sleep_clk); 175EXPORT_SYMBOL_GPL(qcom_cc_register_sleep_clk);
176 176
177static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec,
178 void *data)
179{
180 struct qcom_cc *cc = data;
181 unsigned int idx = clkspec->args[0];
182
183 if (idx >= cc->num_rclks) {
184 pr_err("%s: invalid index %u\n", __func__, idx);
185 return ERR_PTR(-EINVAL);
186 }
187
188 return cc->rclks[idx] ? &cc->rclks[idx]->hw : ERR_PTR(-ENOENT);
189}
190
177int qcom_cc_really_probe(struct platform_device *pdev, 191int qcom_cc_really_probe(struct platform_device *pdev,
178 const struct qcom_cc_desc *desc, struct regmap *regmap) 192 const struct qcom_cc_desc *desc, struct regmap *regmap)
179{ 193{
180 int i, ret; 194 int i, ret;
181 struct device *dev = &pdev->dev; 195 struct device *dev = &pdev->dev;
182 struct clk *clk;
183 struct clk_onecell_data *data;
184 struct clk **clks;
185 struct qcom_reset_controller *reset; 196 struct qcom_reset_controller *reset;
186 struct qcom_cc *cc; 197 struct qcom_cc *cc;
187 struct gdsc_desc *scd; 198 struct gdsc_desc *scd;
188 size_t num_clks = desc->num_clks; 199 size_t num_clks = desc->num_clks;
189 struct clk_regmap **rclks = desc->clks; 200 struct clk_regmap **rclks = desc->clks;
190 201
191 cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, 202 cc = devm_kzalloc(dev, sizeof(*cc), GFP_KERNEL);
192 GFP_KERNEL);
193 if (!cc) 203 if (!cc)
194 return -ENOMEM; 204 return -ENOMEM;
195 205
196 clks = cc->clks; 206 cc->rclks = rclks;
197 data = &cc->data; 207 cc->num_rclks = num_clks;
198 data->clks = clks;
199 data->clk_num = num_clks;
200 208
201 for (i = 0; i < num_clks; i++) { 209 for (i = 0; i < num_clks; i++) {
202 if (!rclks[i]) { 210 if (!rclks[i])
203 clks[i] = ERR_PTR(-ENOENT);
204 continue; 211 continue;
205 } 212
206 clk = devm_clk_register_regmap(dev, rclks[i]); 213 ret = devm_clk_register_regmap(dev, rclks[i]);
207 if (IS_ERR(clk)) 214 if (ret)
208 return PTR_ERR(clk); 215 return ret;
209 clks[i] = clk;
210 } 216 }
211 217
212 ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); 218 ret = of_clk_add_hw_provider(dev->of_node, qcom_cc_clk_hw_get, cc);
213 if (ret) 219 if (ret)
214 return ret; 220 return ret;
215 221
diff --git a/drivers/clk/qcom/gcc-ipq4019.c b/drivers/clk/qcom/gcc-ipq4019.c
index 3cd1af0af0d9..b593065de8db 100644
--- a/drivers/clk/qcom/gcc-ipq4019.c
+++ b/drivers/clk/qcom/gcc-ipq4019.c
@@ -1332,7 +1332,6 @@ static struct platform_driver gcc_ipq4019_driver = {
1332 .probe = gcc_ipq4019_probe, 1332 .probe = gcc_ipq4019_probe,
1333 .driver = { 1333 .driver = {
1334 .name = "qcom,gcc-ipq4019", 1334 .name = "qcom,gcc-ipq4019",
1335 .owner = THIS_MODULE,
1336 .of_match_table = gcc_ipq4019_match_table, 1335 .of_match_table = gcc_ipq4019_match_table,
1337 }, 1336 },
1338}; 1337};
diff --git a/drivers/clk/qcom/gcc-mdm9615.c b/drivers/clk/qcom/gcc-mdm9615.c
new file mode 100644
index 000000000000..581a17f67379
--- /dev/null
+++ b/drivers/clk/qcom/gcc-mdm9615.c
@@ -0,0 +1,1727 @@
1/*
2 * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
3 * Copyright (c) BayLibre, SAS.
4 * Author : Neil Armstrong <narmstrong@baylibre.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/kernel.h>
17#include <linux/bitops.h>
18#include <linux/err.h>
19#include <linux/platform_device.h>
20#include <linux/module.h>
21#include <linux/of.h>
22#include <linux/of_device.h>
23#include <linux/clk-provider.h>
24#include <linux/regmap.h>
25#include <linux/reset-controller.h>
26
27#include <dt-bindings/clock/qcom,gcc-mdm9615.h>
28#include <dt-bindings/reset/qcom,gcc-mdm9615.h>
29
30#include "common.h"
31#include "clk-regmap.h"
32#include "clk-pll.h"
33#include "clk-rcg.h"
34#include "clk-branch.h"
35#include "reset.h"
36
37static struct clk_fixed_factor cxo = {
38 .mult = 1,
39 .div = 1,
40 .hw.init = &(struct clk_init_data){
41 .name = "cxo",
42 .parent_names = (const char *[]){ "cxo_board" },
43 .num_parents = 1,
44 .ops = &clk_fixed_factor_ops,
45 },
46};
47
48static struct clk_pll pll0 = {
49 .l_reg = 0x30c4,
50 .m_reg = 0x30c8,
51 .n_reg = 0x30cc,
52 .config_reg = 0x30d4,
53 .mode_reg = 0x30c0,
54 .status_reg = 0x30d8,
55 .status_bit = 16,
56 .clkr.hw.init = &(struct clk_init_data){
57 .name = "pll0",
58 .parent_names = (const char *[]){ "cxo" },
59 .num_parents = 1,
60 .ops = &clk_pll_ops,
61 },
62};
63
64static struct clk_regmap pll0_vote = {
65 .enable_reg = 0x34c0,
66 .enable_mask = BIT(0),
67 .hw.init = &(struct clk_init_data){
68 .name = "pll0_vote",
69 .parent_names = (const char *[]){ "pll8" },
70 .num_parents = 1,
71 .ops = &clk_pll_vote_ops,
72 },
73};
74
75static struct clk_regmap pll4_vote = {
76 .enable_reg = 0x34c0,
77 .enable_mask = BIT(4),
78 .hw.init = &(struct clk_init_data){
79 .name = "pll4_vote",
80 .parent_names = (const char *[]){ "pll4" },
81 .num_parents = 1,
82 .ops = &clk_pll_vote_ops,
83 },
84};
85
86static struct clk_pll pll8 = {
87 .l_reg = 0x3144,
88 .m_reg = 0x3148,
89 .n_reg = 0x314c,
90 .config_reg = 0x3154,
91 .mode_reg = 0x3140,
92 .status_reg = 0x3158,
93 .status_bit = 16,
94 .clkr.hw.init = &(struct clk_init_data){
95 .name = "pll8",
96 .parent_names = (const char *[]){ "cxo" },
97 .num_parents = 1,
98 .ops = &clk_pll_ops,
99 },
100};
101
102static struct clk_regmap pll8_vote = {
103 .enable_reg = 0x34c0,
104 .enable_mask = BIT(8),
105 .hw.init = &(struct clk_init_data){
106 .name = "pll8_vote",
107 .parent_names = (const char *[]){ "pll8" },
108 .num_parents = 1,
109 .ops = &clk_pll_vote_ops,
110 },
111};
112
113static struct clk_pll pll14 = {
114 .l_reg = 0x31c4,
115 .m_reg = 0x31c8,
116 .n_reg = 0x31cc,
117 .config_reg = 0x31d4,
118 .mode_reg = 0x31c0,
119 .status_reg = 0x31d8,
120 .status_bit = 16,
121 .clkr.hw.init = &(struct clk_init_data){
122 .name = "pll14",
123 .parent_names = (const char *[]){ "cxo" },
124 .num_parents = 1,
125 .ops = &clk_pll_ops,
126 },
127};
128
129static struct clk_regmap pll14_vote = {
130 .enable_reg = 0x34c0,
131 .enable_mask = BIT(11),
132 .hw.init = &(struct clk_init_data){
133 .name = "pll14_vote",
134 .parent_names = (const char *[]){ "pll14" },
135 .num_parents = 1,
136 .ops = &clk_pll_vote_ops,
137 },
138};
139
140enum {
141 P_CXO,
142 P_PLL8,
143 P_PLL14,
144};
145
146static const struct parent_map gcc_cxo_pll8_map[] = {
147 { P_CXO, 0 },
148 { P_PLL8, 3 }
149};
150
151static const char * const gcc_cxo_pll8[] = {
152 "cxo",
153 "pll8_vote",
154};
155
156static const struct parent_map gcc_cxo_pll14_map[] = {
157 { P_CXO, 0 },
158 { P_PLL14, 4 }
159};
160
161static const char * const gcc_cxo_pll14[] = {
162 "cxo",
163 "pll14_vote",
164};
165
166static const struct parent_map gcc_cxo_map[] = {
167 { P_CXO, 0 },
168};
169
170static const char * const gcc_cxo[] = {
171 "cxo",
172};
173
174static struct freq_tbl clk_tbl_gsbi_uart[] = {
175 { 1843200, P_PLL8, 2, 6, 625 },
176 { 3686400, P_PLL8, 2, 12, 625 },
177 { 7372800, P_PLL8, 2, 24, 625 },
178 { 14745600, P_PLL8, 2, 48, 625 },
179 { 16000000, P_PLL8, 4, 1, 6 },
180 { 24000000, P_PLL8, 4, 1, 4 },
181 { 32000000, P_PLL8, 4, 1, 3 },
182 { 40000000, P_PLL8, 1, 5, 48 },
183 { 46400000, P_PLL8, 1, 29, 240 },
184 { 48000000, P_PLL8, 4, 1, 2 },
185 { 51200000, P_PLL8, 1, 2, 15 },
186 { 56000000, P_PLL8, 1, 7, 48 },
187 { 58982400, P_PLL8, 1, 96, 625 },
188 { 64000000, P_PLL8, 2, 1, 3 },
189 { }
190};
191
192static struct clk_rcg gsbi1_uart_src = {
193 .ns_reg = 0x29d4,
194 .md_reg = 0x29d0,
195 .mn = {
196 .mnctr_en_bit = 8,
197 .mnctr_reset_bit = 7,
198 .mnctr_mode_shift = 5,
199 .n_val_shift = 16,
200 .m_val_shift = 16,
201 .width = 16,
202 },
203 .p = {
204 .pre_div_shift = 3,
205 .pre_div_width = 2,
206 },
207 .s = {
208 .src_sel_shift = 0,
209 .parent_map = gcc_cxo_pll8_map,
210 },
211 .freq_tbl = clk_tbl_gsbi_uart,
212 .clkr = {
213 .enable_reg = 0x29d4,
214 .enable_mask = BIT(11),
215 .hw.init = &(struct clk_init_data){
216 .name = "gsbi1_uart_src",
217 .parent_names = gcc_cxo_pll8,
218 .num_parents = 2,
219 .ops = &clk_rcg_ops,
220 .flags = CLK_SET_PARENT_GATE,
221 },
222 },
223};
224
225static struct clk_branch gsbi1_uart_clk = {
226 .halt_reg = 0x2fcc,
227 .halt_bit = 10,
228 .clkr = {
229 .enable_reg = 0x29d4,
230 .enable_mask = BIT(9),
231 .hw.init = &(struct clk_init_data){
232 .name = "gsbi1_uart_clk",
233 .parent_names = (const char *[]){
234 "gsbi1_uart_src",
235 },
236 .num_parents = 1,
237 .ops = &clk_branch_ops,
238 .flags = CLK_SET_RATE_PARENT,
239 },
240 },
241};
242
243static struct clk_rcg gsbi2_uart_src = {
244 .ns_reg = 0x29f4,
245 .md_reg = 0x29f0,
246 .mn = {
247 .mnctr_en_bit = 8,
248 .mnctr_reset_bit = 7,
249 .mnctr_mode_shift = 5,
250 .n_val_shift = 16,
251 .m_val_shift = 16,
252 .width = 16,
253 },
254 .p = {
255 .pre_div_shift = 3,
256 .pre_div_width = 2,
257 },
258 .s = {
259 .src_sel_shift = 0,
260 .parent_map = gcc_cxo_pll8_map,
261 },
262 .freq_tbl = clk_tbl_gsbi_uart,
263 .clkr = {
264 .enable_reg = 0x29f4,
265 .enable_mask = BIT(11),
266 .hw.init = &(struct clk_init_data){
267 .name = "gsbi2_uart_src",
268 .parent_names = gcc_cxo_pll8,
269 .num_parents = 2,
270 .ops = &clk_rcg_ops,
271 .flags = CLK_SET_PARENT_GATE,
272 },
273 },
274};
275
276static struct clk_branch gsbi2_uart_clk = {
277 .halt_reg = 0x2fcc,
278 .halt_bit = 6,
279 .clkr = {
280 .enable_reg = 0x29f4,
281 .enable_mask = BIT(9),
282 .hw.init = &(struct clk_init_data){
283 .name = "gsbi2_uart_clk",
284 .parent_names = (const char *[]){
285 "gsbi2_uart_src",
286 },
287 .num_parents = 1,
288 .ops = &clk_branch_ops,
289 .flags = CLK_SET_RATE_PARENT,
290 },
291 },
292};
293
294static struct clk_rcg gsbi3_uart_src = {
295 .ns_reg = 0x2a14,
296 .md_reg = 0x2a10,
297 .mn = {
298 .mnctr_en_bit = 8,
299 .mnctr_reset_bit = 7,
300 .mnctr_mode_shift = 5,
301 .n_val_shift = 16,
302 .m_val_shift = 16,
303 .width = 16,
304 },
305 .p = {
306 .pre_div_shift = 3,
307 .pre_div_width = 2,
308 },
309 .s = {
310 .src_sel_shift = 0,
311 .parent_map = gcc_cxo_pll8_map,
312 },
313 .freq_tbl = clk_tbl_gsbi_uart,
314 .clkr = {
315 .enable_reg = 0x2a14,
316 .enable_mask = BIT(11),
317 .hw.init = &(struct clk_init_data){
318 .name = "gsbi3_uart_src",
319 .parent_names = gcc_cxo_pll8,
320 .num_parents = 2,
321 .ops = &clk_rcg_ops,
322 .flags = CLK_SET_PARENT_GATE,
323 },
324 },
325};
326
327static struct clk_branch gsbi3_uart_clk = {
328 .halt_reg = 0x2fcc,
329 .halt_bit = 2,
330 .clkr = {
331 .enable_reg = 0x2a14,
332 .enable_mask = BIT(9),
333 .hw.init = &(struct clk_init_data){
334 .name = "gsbi3_uart_clk",
335 .parent_names = (const char *[]){
336 "gsbi3_uart_src",
337 },
338 .num_parents = 1,
339 .ops = &clk_branch_ops,
340 .flags = CLK_SET_RATE_PARENT,
341 },
342 },
343};
344
345static struct clk_rcg gsbi4_uart_src = {
346 .ns_reg = 0x2a34,
347 .md_reg = 0x2a30,
348 .mn = {
349 .mnctr_en_bit = 8,
350 .mnctr_reset_bit = 7,
351 .mnctr_mode_shift = 5,
352 .n_val_shift = 16,
353 .m_val_shift = 16,
354 .width = 16,
355 },
356 .p = {
357 .pre_div_shift = 3,
358 .pre_div_width = 2,
359 },
360 .s = {
361 .src_sel_shift = 0,
362 .parent_map = gcc_cxo_pll8_map,
363 },
364 .freq_tbl = clk_tbl_gsbi_uart,
365 .clkr = {
366 .enable_reg = 0x2a34,
367 .enable_mask = BIT(11),
368 .hw.init = &(struct clk_init_data){
369 .name = "gsbi4_uart_src",
370 .parent_names = gcc_cxo_pll8,
371 .num_parents = 2,
372 .ops = &clk_rcg_ops,
373 .flags = CLK_SET_PARENT_GATE,
374 },
375 },
376};
377
378static struct clk_branch gsbi4_uart_clk = {
379 .halt_reg = 0x2fd0,
380 .halt_bit = 26,
381 .clkr = {
382 .enable_reg = 0x2a34,
383 .enable_mask = BIT(9),
384 .hw.init = &(struct clk_init_data){
385 .name = "gsbi4_uart_clk",
386 .parent_names = (const char *[]){
387 "gsbi4_uart_src",
388 },
389 .num_parents = 1,
390 .ops = &clk_branch_ops,
391 .flags = CLK_SET_RATE_PARENT,
392 },
393 },
394};
395
396static struct clk_rcg gsbi5_uart_src = {
397 .ns_reg = 0x2a54,
398 .md_reg = 0x2a50,
399 .mn = {
400 .mnctr_en_bit = 8,
401 .mnctr_reset_bit = 7,
402 .mnctr_mode_shift = 5,
403 .n_val_shift = 16,
404 .m_val_shift = 16,
405 .width = 16,
406 },
407 .p = {
408 .pre_div_shift = 3,
409 .pre_div_width = 2,
410 },
411 .s = {
412 .src_sel_shift = 0,
413 .parent_map = gcc_cxo_pll8_map,
414 },
415 .freq_tbl = clk_tbl_gsbi_uart,
416 .clkr = {
417 .enable_reg = 0x2a54,
418 .enable_mask = BIT(11),
419 .hw.init = &(struct clk_init_data){
420 .name = "gsbi5_uart_src",
421 .parent_names = gcc_cxo_pll8,
422 .num_parents = 2,
423 .ops = &clk_rcg_ops,
424 .flags = CLK_SET_PARENT_GATE,
425 },
426 },
427};
428
429static struct clk_branch gsbi5_uart_clk = {
430 .halt_reg = 0x2fd0,
431 .halt_bit = 22,
432 .clkr = {
433 .enable_reg = 0x2a54,
434 .enable_mask = BIT(9),
435 .hw.init = &(struct clk_init_data){
436 .name = "gsbi5_uart_clk",
437 .parent_names = (const char *[]){
438 "gsbi5_uart_src",
439 },
440 .num_parents = 1,
441 .ops = &clk_branch_ops,
442 .flags = CLK_SET_RATE_PARENT,
443 },
444 },
445};
446
447static struct freq_tbl clk_tbl_gsbi_qup[] = {
448 { 960000, P_CXO, 4, 1, 5 },
449 { 4800000, P_CXO, 4, 0, 1 },
450 { 9600000, P_CXO, 2, 0, 1 },
451 { 15060000, P_PLL8, 1, 2, 51 },
452 { 24000000, P_PLL8, 4, 1, 4 },
453 { 25600000, P_PLL8, 1, 1, 15 },
454 { 48000000, P_PLL8, 4, 1, 2 },
455 { 51200000, P_PLL8, 1, 2, 15 },
456 { }
457};
458
459static struct clk_rcg gsbi1_qup_src = {
460 .ns_reg = 0x29cc,
461 .md_reg = 0x29c8,
462 .mn = {
463 .mnctr_en_bit = 8,
464 .mnctr_reset_bit = 7,
465 .mnctr_mode_shift = 5,
466 .n_val_shift = 16,
467 .m_val_shift = 16,
468 .width = 8,
469 },
470 .p = {
471 .pre_div_shift = 3,
472 .pre_div_width = 2,
473 },
474 .s = {
475 .src_sel_shift = 0,
476 .parent_map = gcc_cxo_pll8_map,
477 },
478 .freq_tbl = clk_tbl_gsbi_qup,
479 .clkr = {
480 .enable_reg = 0x29cc,
481 .enable_mask = BIT(11),
482 .hw.init = &(struct clk_init_data){
483 .name = "gsbi1_qup_src",
484 .parent_names = gcc_cxo_pll8,
485 .num_parents = 2,
486 .ops = &clk_rcg_ops,
487 .flags = CLK_SET_PARENT_GATE,
488 },
489 },
490};
491
492static struct clk_branch gsbi1_qup_clk = {
493 .halt_reg = 0x2fcc,
494 .halt_bit = 9,
495 .clkr = {
496 .enable_reg = 0x29cc,
497 .enable_mask = BIT(9),
498 .hw.init = &(struct clk_init_data){
499 .name = "gsbi1_qup_clk",
500 .parent_names = (const char *[]){ "gsbi1_qup_src" },
501 .num_parents = 1,
502 .ops = &clk_branch_ops,
503 .flags = CLK_SET_RATE_PARENT,
504 },
505 },
506};
507
508static struct clk_rcg gsbi2_qup_src = {
509 .ns_reg = 0x29ec,
510 .md_reg = 0x29e8,
511 .mn = {
512 .mnctr_en_bit = 8,
513 .mnctr_reset_bit = 7,
514 .mnctr_mode_shift = 5,
515 .n_val_shift = 16,
516 .m_val_shift = 16,
517 .width = 8,
518 },
519 .p = {
520 .pre_div_shift = 3,
521 .pre_div_width = 2,
522 },
523 .s = {
524 .src_sel_shift = 0,
525 .parent_map = gcc_cxo_pll8_map,
526 },
527 .freq_tbl = clk_tbl_gsbi_qup,
528 .clkr = {
529 .enable_reg = 0x29ec,
530 .enable_mask = BIT(11),
531 .hw.init = &(struct clk_init_data){
532 .name = "gsbi2_qup_src",
533 .parent_names = gcc_cxo_pll8,
534 .num_parents = 2,
535 .ops = &clk_rcg_ops,
536 .flags = CLK_SET_PARENT_GATE,
537 },
538 },
539};
540
541static struct clk_branch gsbi2_qup_clk = {
542 .halt_reg = 0x2fcc,
543 .halt_bit = 4,
544 .clkr = {
545 .enable_reg = 0x29ec,
546 .enable_mask = BIT(9),
547 .hw.init = &(struct clk_init_data){
548 .name = "gsbi2_qup_clk",
549 .parent_names = (const char *[]){ "gsbi2_qup_src" },
550 .num_parents = 1,
551 .ops = &clk_branch_ops,
552 .flags = CLK_SET_RATE_PARENT,
553 },
554 },
555};
556
557static struct clk_rcg gsbi3_qup_src = {
558 .ns_reg = 0x2a0c,
559 .md_reg = 0x2a08,
560 .mn = {
561 .mnctr_en_bit = 8,
562 .mnctr_reset_bit = 7,
563 .mnctr_mode_shift = 5,
564 .n_val_shift = 16,
565 .m_val_shift = 16,
566 .width = 8,
567 },
568 .p = {
569 .pre_div_shift = 3,
570 .pre_div_width = 2,
571 },
572 .s = {
573 .src_sel_shift = 0,
574 .parent_map = gcc_cxo_pll8_map,
575 },
576 .freq_tbl = clk_tbl_gsbi_qup,
577 .clkr = {
578 .enable_reg = 0x2a0c,
579 .enable_mask = BIT(11),
580 .hw.init = &(struct clk_init_data){
581 .name = "gsbi3_qup_src",
582 .parent_names = gcc_cxo_pll8,
583 .num_parents = 2,
584 .ops = &clk_rcg_ops,
585 .flags = CLK_SET_PARENT_GATE,
586 },
587 },
588};
589
590static struct clk_branch gsbi3_qup_clk = {
591 .halt_reg = 0x2fcc,
592 .halt_bit = 0,
593 .clkr = {
594 .enable_reg = 0x2a0c,
595 .enable_mask = BIT(9),
596 .hw.init = &(struct clk_init_data){
597 .name = "gsbi3_qup_clk",
598 .parent_names = (const char *[]){ "gsbi3_qup_src" },
599 .num_parents = 1,
600 .ops = &clk_branch_ops,
601 .flags = CLK_SET_RATE_PARENT,
602 },
603 },
604};
605
606static struct clk_rcg gsbi4_qup_src = {
607 .ns_reg = 0x2a2c,
608 .md_reg = 0x2a28,
609 .mn = {
610 .mnctr_en_bit = 8,
611 .mnctr_reset_bit = 7,
612 .mnctr_mode_shift = 5,
613 .n_val_shift = 16,
614 .m_val_shift = 16,
615 .width = 8,
616 },
617 .p = {
618 .pre_div_shift = 3,
619 .pre_div_width = 2,
620 },
621 .s = {
622 .src_sel_shift = 0,
623 .parent_map = gcc_cxo_pll8_map,
624 },
625 .freq_tbl = clk_tbl_gsbi_qup,
626 .clkr = {
627 .enable_reg = 0x2a2c,
628 .enable_mask = BIT(11),
629 .hw.init = &(struct clk_init_data){
630 .name = "gsbi4_qup_src",
631 .parent_names = gcc_cxo_pll8,
632 .num_parents = 2,
633 .ops = &clk_rcg_ops,
634 .flags = CLK_SET_PARENT_GATE,
635 },
636 },
637};
638
639static struct clk_branch gsbi4_qup_clk = {
640 .halt_reg = 0x2fd0,
641 .halt_bit = 24,
642 .clkr = {
643 .enable_reg = 0x2a2c,
644 .enable_mask = BIT(9),
645 .hw.init = &(struct clk_init_data){
646 .name = "gsbi4_qup_clk",
647 .parent_names = (const char *[]){ "gsbi4_qup_src" },
648 .num_parents = 1,
649 .ops = &clk_branch_ops,
650 .flags = CLK_SET_RATE_PARENT,
651 },
652 },
653};
654
655static struct clk_rcg gsbi5_qup_src = {
656 .ns_reg = 0x2a4c,
657 .md_reg = 0x2a48,
658 .mn = {
659 .mnctr_en_bit = 8,
660 .mnctr_reset_bit = 7,
661 .mnctr_mode_shift = 5,
662 .n_val_shift = 16,
663 .m_val_shift = 16,
664 .width = 8,
665 },
666 .p = {
667 .pre_div_shift = 3,
668 .pre_div_width = 2,
669 },
670 .s = {
671 .src_sel_shift = 0,
672 .parent_map = gcc_cxo_pll8_map,
673 },
674 .freq_tbl = clk_tbl_gsbi_qup,
675 .clkr = {
676 .enable_reg = 0x2a4c,
677 .enable_mask = BIT(11),
678 .hw.init = &(struct clk_init_data){
679 .name = "gsbi5_qup_src",
680 .parent_names = gcc_cxo_pll8,
681 .num_parents = 2,
682 .ops = &clk_rcg_ops,
683 .flags = CLK_SET_PARENT_GATE,
684 },
685 },
686};
687
688static struct clk_branch gsbi5_qup_clk = {
689 .halt_reg = 0x2fd0,
690 .halt_bit = 20,
691 .clkr = {
692 .enable_reg = 0x2a4c,
693 .enable_mask = BIT(9),
694 .hw.init = &(struct clk_init_data){
695 .name = "gsbi5_qup_clk",
696 .parent_names = (const char *[]){ "gsbi5_qup_src" },
697 .num_parents = 1,
698 .ops = &clk_branch_ops,
699 .flags = CLK_SET_RATE_PARENT,
700 },
701 },
702};
703
704static const struct freq_tbl clk_tbl_gp[] = {
705 { 9600000, P_CXO, 2, 0, 0 },
706 { 19200000, P_CXO, 1, 0, 0 },
707 { }
708};
709
710static struct clk_rcg gp0_src = {
711 .ns_reg = 0x2d24,
712 .md_reg = 0x2d00,
713 .mn = {
714 .mnctr_en_bit = 8,
715 .mnctr_reset_bit = 7,
716 .mnctr_mode_shift = 5,
717 .n_val_shift = 16,
718 .m_val_shift = 16,
719 .width = 8,
720 },
721 .p = {
722 .pre_div_shift = 3,
723 .pre_div_width = 2,
724 },
725 .s = {
726 .src_sel_shift = 0,
727 .parent_map = gcc_cxo_map,
728 },
729 .freq_tbl = clk_tbl_gp,
730 .clkr = {
731 .enable_reg = 0x2d24,
732 .enable_mask = BIT(11),
733 .hw.init = &(struct clk_init_data){
734 .name = "gp0_src",
735 .parent_names = gcc_cxo,
736 .num_parents = 1,
737 .ops = &clk_rcg_ops,
738 .flags = CLK_SET_PARENT_GATE,
739 },
740 }
741};
742
743static struct clk_branch gp0_clk = {
744 .halt_reg = 0x2fd8,
745 .halt_bit = 7,
746 .clkr = {
747 .enable_reg = 0x2d24,
748 .enable_mask = BIT(9),
749 .hw.init = &(struct clk_init_data){
750 .name = "gp0_clk",
751 .parent_names = (const char *[]){ "gp0_src" },
752 .num_parents = 1,
753 .ops = &clk_branch_ops,
754 .flags = CLK_SET_RATE_PARENT,
755 },
756 },
757};
758
759static struct clk_rcg gp1_src = {
760 .ns_reg = 0x2d44,
761 .md_reg = 0x2d40,
762 .mn = {
763 .mnctr_en_bit = 8,
764 .mnctr_reset_bit = 7,
765 .mnctr_mode_shift = 5,
766 .n_val_shift = 16,
767 .m_val_shift = 16,
768 .width = 8,
769 },
770 .p = {
771 .pre_div_shift = 3,
772 .pre_div_width = 2,
773 },
774 .s = {
775 .src_sel_shift = 0,
776 .parent_map = gcc_cxo_map,
777 },
778 .freq_tbl = clk_tbl_gp,
779 .clkr = {
780 .enable_reg = 0x2d44,
781 .enable_mask = BIT(11),
782 .hw.init = &(struct clk_init_data){
783 .name = "gp1_src",
784 .parent_names = gcc_cxo,
785 .num_parents = 1,
786 .ops = &clk_rcg_ops,
787 .flags = CLK_SET_RATE_GATE,
788 },
789 }
790};
791
792static struct clk_branch gp1_clk = {
793 .halt_reg = 0x2fd8,
794 .halt_bit = 6,
795 .clkr = {
796 .enable_reg = 0x2d44,
797 .enable_mask = BIT(9),
798 .hw.init = &(struct clk_init_data){
799 .name = "gp1_clk",
800 .parent_names = (const char *[]){ "gp1_src" },
801 .num_parents = 1,
802 .ops = &clk_branch_ops,
803 .flags = CLK_SET_RATE_PARENT,
804 },
805 },
806};
807
808static struct clk_rcg gp2_src = {
809 .ns_reg = 0x2d64,
810 .md_reg = 0x2d60,
811 .mn = {
812 .mnctr_en_bit = 8,
813 .mnctr_reset_bit = 7,
814 .mnctr_mode_shift = 5,
815 .n_val_shift = 16,
816 .m_val_shift = 16,
817 .width = 8,
818 },
819 .p = {
820 .pre_div_shift = 3,
821 .pre_div_width = 2,
822 },
823 .s = {
824 .src_sel_shift = 0,
825 .parent_map = gcc_cxo_map,
826 },
827 .freq_tbl = clk_tbl_gp,
828 .clkr = {
829 .enable_reg = 0x2d64,
830 .enable_mask = BIT(11),
831 .hw.init = &(struct clk_init_data){
832 .name = "gp2_src",
833 .parent_names = gcc_cxo,
834 .num_parents = 1,
835 .ops = &clk_rcg_ops,
836 .flags = CLK_SET_RATE_GATE,
837 },
838 }
839};
840
841static struct clk_branch gp2_clk = {
842 .halt_reg = 0x2fd8,
843 .halt_bit = 5,
844 .clkr = {
845 .enable_reg = 0x2d64,
846 .enable_mask = BIT(9),
847 .hw.init = &(struct clk_init_data){
848 .name = "gp2_clk",
849 .parent_names = (const char *[]){ "gp2_src" },
850 .num_parents = 1,
851 .ops = &clk_branch_ops,
852 .flags = CLK_SET_RATE_PARENT,
853 },
854 },
855};
856
857static struct clk_branch pmem_clk = {
858 .hwcg_reg = 0x25a0,
859 .hwcg_bit = 6,
860 .halt_reg = 0x2fc8,
861 .halt_bit = 20,
862 .clkr = {
863 .enable_reg = 0x25a0,
864 .enable_mask = BIT(4),
865 .hw.init = &(struct clk_init_data){
866 .name = "pmem_clk",
867 .ops = &clk_branch_ops,
868 },
869 },
870};
871
872static struct clk_rcg prng_src = {
873 .ns_reg = 0x2e80,
874 .p = {
875 .pre_div_shift = 3,
876 .pre_div_width = 4,
877 },
878 .s = {
879 .src_sel_shift = 0,
880 .parent_map = gcc_cxo_pll8_map,
881 },
882 .clkr = {
883 .hw.init = &(struct clk_init_data){
884 .name = "prng_src",
885 .parent_names = gcc_cxo_pll8,
886 .num_parents = 2,
887 .ops = &clk_rcg_ops,
888 },
889 },
890};
891
892static struct clk_branch prng_clk = {
893 .halt_reg = 0x2fd8,
894 .halt_check = BRANCH_HALT_VOTED,
895 .halt_bit = 10,
896 .clkr = {
897 .enable_reg = 0x3080,
898 .enable_mask = BIT(10),
899 .hw.init = &(struct clk_init_data){
900 .name = "prng_clk",
901 .parent_names = (const char *[]){ "prng_src" },
902 .num_parents = 1,
903 .ops = &clk_branch_ops,
904 },
905 },
906};
907
908static const struct freq_tbl clk_tbl_sdc[] = {
909 { 144000, P_CXO, 1, 1, 133 },
910 { 400000, P_PLL8, 4, 1, 240 },
911 { 16000000, P_PLL8, 4, 1, 6 },
912 { 17070000, P_PLL8, 1, 2, 45 },
913 { 20210000, P_PLL8, 1, 1, 19 },
914 { 24000000, P_PLL8, 4, 1, 4 },
915 { 38400000, P_PLL8, 2, 1, 5 },
916 { 48000000, P_PLL8, 4, 1, 2 },
917 { 64000000, P_PLL8, 3, 1, 2 },
918 { 76800000, P_PLL8, 1, 1, 5 },
919 { }
920};
921
922static struct clk_rcg sdc1_src = {
923 .ns_reg = 0x282c,
924 .md_reg = 0x2828,
925 .mn = {
926 .mnctr_en_bit = 8,
927 .mnctr_reset_bit = 7,
928 .mnctr_mode_shift = 5,
929 .n_val_shift = 16,
930 .m_val_shift = 16,
931 .width = 8,
932 },
933 .p = {
934 .pre_div_shift = 3,
935 .pre_div_width = 2,
936 },
937 .s = {
938 .src_sel_shift = 0,
939 .parent_map = gcc_cxo_pll8_map,
940 },
941 .freq_tbl = clk_tbl_sdc,
942 .clkr = {
943 .enable_reg = 0x282c,
944 .enable_mask = BIT(11),
945 .hw.init = &(struct clk_init_data){
946 .name = "sdc1_src",
947 .parent_names = gcc_cxo_pll8,
948 .num_parents = 2,
949 .ops = &clk_rcg_ops,
950 .flags = CLK_SET_RATE_GATE,
951 },
952 }
953};
954
955static struct clk_branch sdc1_clk = {
956 .halt_reg = 0x2fc8,
957 .halt_bit = 6,
958 .clkr = {
959 .enable_reg = 0x282c,
960 .enable_mask = BIT(9),
961 .hw.init = &(struct clk_init_data){
962 .name = "sdc1_clk",
963 .parent_names = (const char *[]){ "sdc1_src" },
964 .num_parents = 1,
965 .ops = &clk_branch_ops,
966 .flags = CLK_SET_RATE_PARENT,
967 },
968 },
969};
970
971static struct clk_rcg sdc2_src = {
972 .ns_reg = 0x284c,
973 .md_reg = 0x2848,
974 .mn = {
975 .mnctr_en_bit = 8,
976 .mnctr_reset_bit = 7,
977 .mnctr_mode_shift = 5,
978 .n_val_shift = 16,
979 .m_val_shift = 16,
980 .width = 8,
981 },
982 .p = {
983 .pre_div_shift = 3,
984 .pre_div_width = 2,
985 },
986 .s = {
987 .src_sel_shift = 0,
988 .parent_map = gcc_cxo_pll8_map,
989 },
990 .freq_tbl = clk_tbl_sdc,
991 .clkr = {
992 .enable_reg = 0x284c,
993 .enable_mask = BIT(11),
994 .hw.init = &(struct clk_init_data){
995 .name = "sdc2_src",
996 .parent_names = gcc_cxo_pll8,
997 .num_parents = 2,
998 .ops = &clk_rcg_ops,
999 .flags = CLK_SET_RATE_GATE,
1000 },
1001 }
1002};
1003
1004static struct clk_branch sdc2_clk = {
1005 .halt_reg = 0x2fc8,
1006 .halt_bit = 5,
1007 .clkr = {
1008 .enable_reg = 0x284c,
1009 .enable_mask = BIT(9),
1010 .hw.init = &(struct clk_init_data){
1011 .name = "sdc2_clk",
1012 .parent_names = (const char *[]){ "sdc2_src" },
1013 .num_parents = 1,
1014 .ops = &clk_branch_ops,
1015 .flags = CLK_SET_RATE_PARENT,
1016 },
1017 },
1018};
1019
1020static const struct freq_tbl clk_tbl_usb[] = {
1021 { 60000000, P_PLL8, 1, 5, 32 },
1022 { }
1023};
1024
1025static struct clk_rcg usb_hs1_xcvr_src = {
1026 .ns_reg = 0x290c,
1027 .md_reg = 0x2908,
1028 .mn = {
1029 .mnctr_en_bit = 8,
1030 .mnctr_reset_bit = 7,
1031 .mnctr_mode_shift = 5,
1032 .n_val_shift = 16,
1033 .m_val_shift = 16,
1034 .width = 8,
1035 },
1036 .p = {
1037 .pre_div_shift = 3,
1038 .pre_div_width = 2,
1039 },
1040 .s = {
1041 .src_sel_shift = 0,
1042 .parent_map = gcc_cxo_pll8_map,
1043 },
1044 .freq_tbl = clk_tbl_usb,
1045 .clkr = {
1046 .enable_reg = 0x290c,
1047 .enable_mask = BIT(11),
1048 .hw.init = &(struct clk_init_data){
1049 .name = "usb_hs1_xcvr_src",
1050 .parent_names = gcc_cxo_pll8,
1051 .num_parents = 2,
1052 .ops = &clk_rcg_ops,
1053 .flags = CLK_SET_RATE_GATE,
1054 },
1055 }
1056};
1057
1058static struct clk_branch usb_hs1_xcvr_clk = {
1059 .halt_reg = 0x2fc8,
1060 .halt_bit = 0,
1061 .clkr = {
1062 .enable_reg = 0x290c,
1063 .enable_mask = BIT(9),
1064 .hw.init = &(struct clk_init_data){
1065 .name = "usb_hs1_xcvr_clk",
1066 .parent_names = (const char *[]){ "usb_hs1_xcvr_src" },
1067 .num_parents = 1,
1068 .ops = &clk_branch_ops,
1069 .flags = CLK_SET_RATE_PARENT,
1070 },
1071 },
1072};
1073
1074static struct clk_rcg usb_hsic_xcvr_fs_src = {
1075 .ns_reg = 0x2928,
1076 .md_reg = 0x2924,
1077 .mn = {
1078 .mnctr_en_bit = 8,
1079 .mnctr_reset_bit = 7,
1080 .mnctr_mode_shift = 5,
1081 .n_val_shift = 16,
1082 .m_val_shift = 16,
1083 .width = 8,
1084 },
1085 .p = {
1086 .pre_div_shift = 3,
1087 .pre_div_width = 2,
1088 },
1089 .s = {
1090 .src_sel_shift = 0,
1091 .parent_map = gcc_cxo_pll8_map,
1092 },
1093 .freq_tbl = clk_tbl_usb,
1094 .clkr = {
1095 .enable_reg = 0x2928,
1096 .enable_mask = BIT(11),
1097 .hw.init = &(struct clk_init_data){
1098 .name = "usb_hsic_xcvr_fs_src",
1099 .parent_names = gcc_cxo_pll8,
1100 .num_parents = 2,
1101 .ops = &clk_rcg_ops,
1102 .flags = CLK_SET_RATE_GATE,
1103 },
1104 }
1105};
1106
1107static struct clk_branch usb_hsic_xcvr_fs_clk = {
1108 .halt_reg = 0x2fc8,
1109 .halt_bit = 9,
1110 .clkr = {
1111 .enable_reg = 0x2928,
1112 .enable_mask = BIT(9),
1113 .hw.init = &(struct clk_init_data){
1114 .name = "usb_hsic_xcvr_fs_clk",
1115 .parent_names =
1116 (const char *[]){ "usb_hsic_xcvr_fs_src" },
1117 .num_parents = 1,
1118 .ops = &clk_branch_ops,
1119 .flags = CLK_SET_RATE_PARENT,
1120 },
1121 },
1122};
1123
1124static const struct freq_tbl clk_tbl_usb_hs1_system[] = {
1125 { 60000000, P_PLL8, 1, 5, 32 },
1126 { }
1127};
1128
1129static struct clk_rcg usb_hs1_system_src = {
1130 .ns_reg = 0x36a4,
1131 .md_reg = 0x36a0,
1132 .mn = {
1133 .mnctr_en_bit = 8,
1134 .mnctr_reset_bit = 7,
1135 .mnctr_mode_shift = 5,
1136 .n_val_shift = 16,
1137 .m_val_shift = 16,
1138 .width = 8,
1139 },
1140 .p = {
1141 .pre_div_shift = 3,
1142 .pre_div_width = 2,
1143 },
1144 .s = {
1145 .src_sel_shift = 0,
1146 .parent_map = gcc_cxo_pll8_map,
1147 },
1148 .freq_tbl = clk_tbl_usb_hs1_system,
1149 .clkr = {
1150 .enable_reg = 0x36a4,
1151 .enable_mask = BIT(11),
1152 .hw.init = &(struct clk_init_data){
1153 .name = "usb_hs1_system_src",
1154 .parent_names = gcc_cxo_pll8,
1155 .num_parents = 2,
1156 .ops = &clk_rcg_ops,
1157 .flags = CLK_SET_RATE_GATE,
1158 },
1159 }
1160};
1161
1162static struct clk_branch usb_hs1_system_clk = {
1163 .halt_reg = 0x2fc8,
1164 .halt_bit = 4,
1165 .clkr = {
1166 .enable_reg = 0x36a4,
1167 .enable_mask = BIT(9),
1168 .hw.init = &(struct clk_init_data){
1169 .parent_names =
1170 (const char *[]){ "usb_hs1_system_src" },
1171 .num_parents = 1,
1172 .name = "usb_hs1_system_clk",
1173 .ops = &clk_branch_ops,
1174 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1175 },
1176 },
1177};
1178
1179static const struct freq_tbl clk_tbl_usb_hsic_system[] = {
1180 { 64000000, P_PLL8, 1, 1, 6 },
1181 { }
1182};
1183
1184static struct clk_rcg usb_hsic_system_src = {
1185 .ns_reg = 0x2b58,
1186 .md_reg = 0x2b54,
1187 .mn = {
1188 .mnctr_en_bit = 8,
1189 .mnctr_reset_bit = 7,
1190 .mnctr_mode_shift = 5,
1191 .n_val_shift = 16,
1192 .m_val_shift = 16,
1193 .width = 8,
1194 },
1195 .p = {
1196 .pre_div_shift = 3,
1197 .pre_div_width = 2,
1198 },
1199 .s = {
1200 .src_sel_shift = 0,
1201 .parent_map = gcc_cxo_pll8_map,
1202 },
1203 .freq_tbl = clk_tbl_usb_hsic_system,
1204 .clkr = {
1205 .enable_reg = 0x2b58,
1206 .enable_mask = BIT(11),
1207 .hw.init = &(struct clk_init_data){
1208 .name = "usb_hsic_system_src",
1209 .parent_names = gcc_cxo_pll8,
1210 .num_parents = 2,
1211 .ops = &clk_rcg_ops,
1212 .flags = CLK_SET_RATE_GATE,
1213 },
1214 }
1215};
1216
1217static struct clk_branch usb_hsic_system_clk = {
1218 .halt_reg = 0x2fc8,
1219 .halt_bit = 7,
1220 .clkr = {
1221 .enable_reg = 0x2b58,
1222 .enable_mask = BIT(9),
1223 .hw.init = &(struct clk_init_data){
1224 .parent_names =
1225 (const char *[]){ "usb_hsic_system_src" },
1226 .num_parents = 1,
1227 .name = "usb_hsic_system_clk",
1228 .ops = &clk_branch_ops,
1229 .flags = CLK_SET_RATE_PARENT,
1230 },
1231 },
1232};
1233
1234static const struct freq_tbl clk_tbl_usb_hsic_hsic[] = {
1235 { 48000000, P_PLL14, 1, 0, 0 },
1236 { }
1237};
1238
1239static struct clk_rcg usb_hsic_hsic_src = {
1240 .ns_reg = 0x2b50,
1241 .md_reg = 0x2b4c,
1242 .mn = {
1243 .mnctr_en_bit = 8,
1244 .mnctr_reset_bit = 7,
1245 .mnctr_mode_shift = 5,
1246 .n_val_shift = 16,
1247 .m_val_shift = 16,
1248 .width = 8,
1249 },
1250 .p = {
1251 .pre_div_shift = 3,
1252 .pre_div_width = 2,
1253 },
1254 .s = {
1255 .src_sel_shift = 0,
1256 .parent_map = gcc_cxo_pll14_map,
1257 },
1258 .freq_tbl = clk_tbl_usb_hsic_hsic,
1259 .clkr = {
1260 .enable_reg = 0x2b50,
1261 .enable_mask = BIT(11),
1262 .hw.init = &(struct clk_init_data){
1263 .name = "usb_hsic_hsic_src",
1264 .parent_names = gcc_cxo_pll14,
1265 .num_parents = 2,
1266 .ops = &clk_rcg_ops,
1267 .flags = CLK_SET_RATE_GATE,
1268 },
1269 }
1270};
1271
1272static struct clk_branch usb_hsic_hsic_clk = {
1273 .halt_check = BRANCH_HALT_DELAY,
1274 .clkr = {
1275 .enable_reg = 0x2b50,
1276 .enable_mask = BIT(9),
1277 .hw.init = &(struct clk_init_data){
1278 .parent_names = (const char *[]){ "usb_hsic_hsic_src" },
1279 .num_parents = 1,
1280 .name = "usb_hsic_hsic_clk",
1281 .ops = &clk_branch_ops,
1282 .flags = CLK_SET_RATE_PARENT,
1283 },
1284 },
1285};
1286
1287static struct clk_branch usb_hsic_hsio_cal_clk = {
1288 .halt_reg = 0x2fc8,
1289 .halt_bit = 8,
1290 .clkr = {
1291 .enable_reg = 0x2b48,
1292 .enable_mask = BIT(0),
1293 .hw.init = &(struct clk_init_data){
1294 .parent_names = (const char *[]){ "cxo" },
1295 .num_parents = 1,
1296 .name = "usb_hsic_hsio_cal_clk",
1297 .ops = &clk_branch_ops,
1298 },
1299 },
1300};
1301
1302static struct clk_branch ce1_core_clk = {
1303 .hwcg_reg = 0x2724,
1304 .hwcg_bit = 6,
1305 .halt_reg = 0x2fd4,
1306 .halt_bit = 27,
1307 .clkr = {
1308 .enable_reg = 0x2724,
1309 .enable_mask = BIT(4),
1310 .hw.init = &(struct clk_init_data){
1311 .name = "ce1_core_clk",
1312 .ops = &clk_branch_ops,
1313 },
1314 },
1315};
1316
1317static struct clk_branch ce1_h_clk = {
1318 .halt_reg = 0x2fd4,
1319 .halt_bit = 1,
1320 .clkr = {
1321 .enable_reg = 0x2720,
1322 .enable_mask = BIT(4),
1323 .hw.init = &(struct clk_init_data){
1324 .name = "ce1_h_clk",
1325 .ops = &clk_branch_ops,
1326 },
1327 },
1328};
1329
1330static struct clk_branch dma_bam_h_clk = {
1331 .hwcg_reg = 0x25c0,
1332 .hwcg_bit = 6,
1333 .halt_reg = 0x2fc8,
1334 .halt_bit = 12,
1335 .clkr = {
1336 .enable_reg = 0x25c0,
1337 .enable_mask = BIT(4),
1338 .hw.init = &(struct clk_init_data){
1339 .name = "dma_bam_h_clk",
1340 .ops = &clk_branch_ops,
1341 },
1342 },
1343};
1344
1345static struct clk_branch gsbi1_h_clk = {
1346 .hwcg_reg = 0x29c0,
1347 .hwcg_bit = 6,
1348 .halt_reg = 0x2fcc,
1349 .halt_bit = 11,
1350 .clkr = {
1351 .enable_reg = 0x29c0,
1352 .enable_mask = BIT(4),
1353 .hw.init = &(struct clk_init_data){
1354 .name = "gsbi1_h_clk",
1355 .ops = &clk_branch_ops,
1356 },
1357 },
1358};
1359
1360static struct clk_branch gsbi2_h_clk = {
1361 .hwcg_reg = 0x29e0,
1362 .hwcg_bit = 6,
1363 .halt_reg = 0x2fcc,
1364 .halt_bit = 7,
1365 .clkr = {
1366 .enable_reg = 0x29e0,
1367 .enable_mask = BIT(4),
1368 .hw.init = &(struct clk_init_data){
1369 .name = "gsbi2_h_clk",
1370 .ops = &clk_branch_ops,
1371 },
1372 },
1373};
1374
1375static struct clk_branch gsbi3_h_clk = {
1376 .hwcg_reg = 0x2a00,
1377 .hwcg_bit = 6,
1378 .halt_reg = 0x2fcc,
1379 .halt_bit = 3,
1380 .clkr = {
1381 .enable_reg = 0x2a00,
1382 .enable_mask = BIT(4),
1383 .hw.init = &(struct clk_init_data){
1384 .name = "gsbi3_h_clk",
1385 .ops = &clk_branch_ops,
1386 },
1387 },
1388};
1389
1390static struct clk_branch gsbi4_h_clk = {
1391 .hwcg_reg = 0x2a20,
1392 .hwcg_bit = 6,
1393 .halt_reg = 0x2fd0,
1394 .halt_bit = 27,
1395 .clkr = {
1396 .enable_reg = 0x2a20,
1397 .enable_mask = BIT(4),
1398 .hw.init = &(struct clk_init_data){
1399 .name = "gsbi4_h_clk",
1400 .ops = &clk_branch_ops,
1401 },
1402 },
1403};
1404
1405static struct clk_branch gsbi5_h_clk = {
1406 .hwcg_reg = 0x2a40,
1407 .hwcg_bit = 6,
1408 .halt_reg = 0x2fd0,
1409 .halt_bit = 23,
1410 .clkr = {
1411 .enable_reg = 0x2a40,
1412 .enable_mask = BIT(4),
1413 .hw.init = &(struct clk_init_data){
1414 .name = "gsbi5_h_clk",
1415 .ops = &clk_branch_ops,
1416 },
1417 },
1418};
1419
1420static struct clk_branch usb_hs1_h_clk = {
1421 .hwcg_reg = 0x2900,
1422 .hwcg_bit = 6,
1423 .halt_reg = 0x2fc8,
1424 .halt_bit = 1,
1425 .clkr = {
1426 .enable_reg = 0x2900,
1427 .enable_mask = BIT(4),
1428 .hw.init = &(struct clk_init_data){
1429 .name = "usb_hs1_h_clk",
1430 .ops = &clk_branch_ops,
1431 },
1432 },
1433};
1434
1435static struct clk_branch usb_hsic_h_clk = {
1436 .halt_reg = 0x2fcc,
1437 .halt_bit = 28,
1438 .clkr = {
1439 .enable_reg = 0x2920,
1440 .enable_mask = BIT(4),
1441 .hw.init = &(struct clk_init_data){
1442 .name = "usb_hsic_h_clk",
1443 .ops = &clk_branch_ops,
1444 },
1445 },
1446};
1447
1448static struct clk_branch sdc1_h_clk = {
1449 .hwcg_reg = 0x2820,
1450 .hwcg_bit = 6,
1451 .halt_reg = 0x2fc8,
1452 .halt_bit = 11,
1453 .clkr = {
1454 .enable_reg = 0x2820,
1455 .enable_mask = BIT(4),
1456 .hw.init = &(struct clk_init_data){
1457 .name = "sdc1_h_clk",
1458 .ops = &clk_branch_ops,
1459 },
1460 },
1461};
1462
1463static struct clk_branch sdc2_h_clk = {
1464 .hwcg_reg = 0x2840,
1465 .hwcg_bit = 6,
1466 .halt_reg = 0x2fc8,
1467 .halt_bit = 10,
1468 .clkr = {
1469 .enable_reg = 0x2840,
1470 .enable_mask = BIT(4),
1471 .hw.init = &(struct clk_init_data){
1472 .name = "sdc2_h_clk",
1473 .ops = &clk_branch_ops,
1474 },
1475 },
1476};
1477
1478static struct clk_branch adm0_clk = {
1479 .halt_reg = 0x2fdc,
1480 .halt_check = BRANCH_HALT_VOTED,
1481 .halt_bit = 14,
1482 .clkr = {
1483 .enable_reg = 0x3080,
1484 .enable_mask = BIT(2),
1485 .hw.init = &(struct clk_init_data){
1486 .name = "adm0_clk",
1487 .ops = &clk_branch_ops,
1488 },
1489 },
1490};
1491
1492static struct clk_branch adm0_pbus_clk = {
1493 .hwcg_reg = 0x2208,
1494 .hwcg_bit = 6,
1495 .halt_reg = 0x2fdc,
1496 .halt_check = BRANCH_HALT_VOTED,
1497 .halt_bit = 13,
1498 .clkr = {
1499 .enable_reg = 0x3080,
1500 .enable_mask = BIT(3),
1501 .hw.init = &(struct clk_init_data){
1502 .name = "adm0_pbus_clk",
1503 .ops = &clk_branch_ops,
1504 },
1505 },
1506};
1507
1508static struct clk_branch pmic_arb0_h_clk = {
1509 .halt_reg = 0x2fd8,
1510 .halt_check = BRANCH_HALT_VOTED,
1511 .halt_bit = 22,
1512 .clkr = {
1513 .enable_reg = 0x3080,
1514 .enable_mask = BIT(8),
1515 .hw.init = &(struct clk_init_data){
1516 .name = "pmic_arb0_h_clk",
1517 .ops = &clk_branch_ops,
1518 },
1519 },
1520};
1521
1522static struct clk_branch pmic_arb1_h_clk = {
1523 .halt_reg = 0x2fd8,
1524 .halt_check = BRANCH_HALT_VOTED,
1525 .halt_bit = 21,
1526 .clkr = {
1527 .enable_reg = 0x3080,
1528 .enable_mask = BIT(9),
1529 .hw.init = &(struct clk_init_data){
1530 .name = "pmic_arb1_h_clk",
1531 .ops = &clk_branch_ops,
1532 },
1533 },
1534};
1535
1536static struct clk_branch pmic_ssbi2_clk = {
1537 .halt_reg = 0x2fd8,
1538 .halt_check = BRANCH_HALT_VOTED,
1539 .halt_bit = 23,
1540 .clkr = {
1541 .enable_reg = 0x3080,
1542 .enable_mask = BIT(7),
1543 .hw.init = &(struct clk_init_data){
1544 .name = "pmic_ssbi2_clk",
1545 .ops = &clk_branch_ops,
1546 },
1547 },
1548};
1549
1550static struct clk_branch rpm_msg_ram_h_clk = {
1551 .hwcg_reg = 0x27e0,
1552 .hwcg_bit = 6,
1553 .halt_reg = 0x2fd8,
1554 .halt_check = BRANCH_HALT_VOTED,
1555 .halt_bit = 12,
1556 .clkr = {
1557 .enable_reg = 0x3080,
1558 .enable_mask = BIT(6),
1559 .hw.init = &(struct clk_init_data){
1560 .name = "rpm_msg_ram_h_clk",
1561 .ops = &clk_branch_ops,
1562 },
1563 },
1564};
1565
1566static struct clk_hw *gcc_mdm9615_hws[] = {
1567 &cxo.hw,
1568};
1569
1570static struct clk_regmap *gcc_mdm9615_clks[] = {
1571 [PLL0] = &pll0.clkr,
1572 [PLL0_VOTE] = &pll0_vote,
1573 [PLL4_VOTE] = &pll4_vote,
1574 [PLL8] = &pll8.clkr,
1575 [PLL8_VOTE] = &pll8_vote,
1576 [PLL14] = &pll14.clkr,
1577 [PLL14_VOTE] = &pll14_vote,
1578 [GSBI1_UART_SRC] = &gsbi1_uart_src.clkr,
1579 [GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr,
1580 [GSBI2_UART_SRC] = &gsbi2_uart_src.clkr,
1581 [GSBI2_UART_CLK] = &gsbi2_uart_clk.clkr,
1582 [GSBI3_UART_SRC] = &gsbi3_uart_src.clkr,
1583 [GSBI3_UART_CLK] = &gsbi3_uart_clk.clkr,
1584 [GSBI4_UART_SRC] = &gsbi4_uart_src.clkr,
1585 [GSBI4_UART_CLK] = &gsbi4_uart_clk.clkr,
1586 [GSBI5_UART_SRC] = &gsbi5_uart_src.clkr,
1587 [GSBI5_UART_CLK] = &gsbi5_uart_clk.clkr,
1588 [GSBI1_QUP_SRC] = &gsbi1_qup_src.clkr,
1589 [GSBI1_QUP_CLK] = &gsbi1_qup_clk.clkr,
1590 [GSBI2_QUP_SRC] = &gsbi2_qup_src.clkr,
1591 [GSBI2_QUP_CLK] = &gsbi2_qup_clk.clkr,
1592 [GSBI3_QUP_SRC] = &gsbi3_qup_src.clkr,
1593 [GSBI3_QUP_CLK] = &gsbi3_qup_clk.clkr,
1594 [GSBI4_QUP_SRC] = &gsbi4_qup_src.clkr,
1595 [GSBI4_QUP_CLK] = &gsbi4_qup_clk.clkr,
1596 [GSBI5_QUP_SRC] = &gsbi5_qup_src.clkr,
1597 [GSBI5_QUP_CLK] = &gsbi5_qup_clk.clkr,
1598 [GP0_SRC] = &gp0_src.clkr,
1599 [GP0_CLK] = &gp0_clk.clkr,
1600 [GP1_SRC] = &gp1_src.clkr,
1601 [GP1_CLK] = &gp1_clk.clkr,
1602 [GP2_SRC] = &gp2_src.clkr,
1603 [GP2_CLK] = &gp2_clk.clkr,
1604 [PMEM_A_CLK] = &pmem_clk.clkr,
1605 [PRNG_SRC] = &prng_src.clkr,
1606 [PRNG_CLK] = &prng_clk.clkr,
1607 [SDC1_SRC] = &sdc1_src.clkr,
1608 [SDC1_CLK] = &sdc1_clk.clkr,
1609 [SDC2_SRC] = &sdc2_src.clkr,
1610 [SDC2_CLK] = &sdc2_clk.clkr,
1611 [USB_HS1_XCVR_SRC] = &usb_hs1_xcvr_src.clkr,
1612 [USB_HS1_XCVR_CLK] = &usb_hs1_xcvr_clk.clkr,
1613 [USB_HS1_SYSTEM_CLK_SRC] = &usb_hs1_system_src.clkr,
1614 [USB_HS1_SYSTEM_CLK] = &usb_hs1_system_clk.clkr,
1615 [USB_HSIC_XCVR_FS_SRC] = &usb_hsic_xcvr_fs_src.clkr,
1616 [USB_HSIC_XCVR_FS_CLK] = &usb_hsic_xcvr_fs_clk.clkr,
1617 [USB_HSIC_SYSTEM_CLK_SRC] = &usb_hsic_system_src.clkr,
1618 [USB_HSIC_SYSTEM_CLK] = &usb_hsic_system_clk.clkr,
1619 [USB_HSIC_HSIC_CLK_SRC] = &usb_hsic_hsic_src.clkr,
1620 [USB_HSIC_HSIC_CLK] = &usb_hsic_hsic_clk.clkr,
1621 [USB_HSIC_HSIO_CAL_CLK] = &usb_hsic_hsio_cal_clk.clkr,
1622 [CE1_CORE_CLK] = &ce1_core_clk.clkr,
1623 [CE1_H_CLK] = &ce1_h_clk.clkr,
1624 [DMA_BAM_H_CLK] = &dma_bam_h_clk.clkr,
1625 [GSBI1_H_CLK] = &gsbi1_h_clk.clkr,
1626 [GSBI2_H_CLK] = &gsbi2_h_clk.clkr,
1627 [GSBI3_H_CLK] = &gsbi3_h_clk.clkr,
1628 [GSBI4_H_CLK] = &gsbi4_h_clk.clkr,
1629 [GSBI5_H_CLK] = &gsbi5_h_clk.clkr,
1630 [USB_HS1_H_CLK] = &usb_hs1_h_clk.clkr,
1631 [USB_HSIC_H_CLK] = &usb_hsic_h_clk.clkr,
1632 [SDC1_H_CLK] = &sdc1_h_clk.clkr,
1633 [SDC2_H_CLK] = &sdc2_h_clk.clkr,
1634 [ADM0_CLK] = &adm0_clk.clkr,
1635 [ADM0_PBUS_CLK] = &adm0_pbus_clk.clkr,
1636 [PMIC_ARB0_H_CLK] = &pmic_arb0_h_clk.clkr,
1637 [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr,
1638 [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr,
1639 [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr,
1640};
1641
1642static const struct qcom_reset_map gcc_mdm9615_resets[] = {
1643 [DMA_BAM_RESET] = { 0x25c0, 7 },
1644 [CE1_H_RESET] = { 0x2720, 7 },
1645 [CE1_CORE_RESET] = { 0x2724, 7 },
1646 [SDC1_RESET] = { 0x2830 },
1647 [SDC2_RESET] = { 0x2850 },
1648 [ADM0_C2_RESET] = { 0x220c, 4 },
1649 [ADM0_C1_RESET] = { 0x220c, 3 },
1650 [ADM0_C0_RESET] = { 0x220c, 2 },
1651 [ADM0_PBUS_RESET] = { 0x220c, 1 },
1652 [ADM0_RESET] = { 0x220c },
1653 [USB_HS1_RESET] = { 0x2910 },
1654 [USB_HSIC_RESET] = { 0x2934 },
1655 [GSBI1_RESET] = { 0x29dc },
1656 [GSBI2_RESET] = { 0x29fc },
1657 [GSBI3_RESET] = { 0x2a1c },
1658 [GSBI4_RESET] = { 0x2a3c },
1659 [GSBI5_RESET] = { 0x2a5c },
1660 [PDM_RESET] = { 0x2CC0, 12 },
1661};
1662
1663static const struct regmap_config gcc_mdm9615_regmap_config = {
1664 .reg_bits = 32,
1665 .reg_stride = 4,
1666 .val_bits = 32,
1667 .max_register = 0x3660,
1668 .fast_io = true,
1669};
1670
1671static const struct qcom_cc_desc gcc_mdm9615_desc = {
1672 .config = &gcc_mdm9615_regmap_config,
1673 .clks = gcc_mdm9615_clks,
1674 .num_clks = ARRAY_SIZE(gcc_mdm9615_clks),
1675 .resets = gcc_mdm9615_resets,
1676 .num_resets = ARRAY_SIZE(gcc_mdm9615_resets),
1677};
1678
1679static const struct of_device_id gcc_mdm9615_match_table[] = {
1680 { .compatible = "qcom,gcc-mdm9615" },
1681 { }
1682};
1683MODULE_DEVICE_TABLE(of, gcc_mdm9615_match_table);
1684
1685static int gcc_mdm9615_probe(struct platform_device *pdev)
1686{
1687 struct device *dev = &pdev->dev;
1688 struct regmap *regmap;
1689 int ret;
1690 int i;
1691
1692 regmap = qcom_cc_map(pdev, &gcc_mdm9615_desc);
1693 if (IS_ERR(regmap))
1694 return PTR_ERR(regmap);
1695
1696 for (i = 0; i < ARRAY_SIZE(gcc_mdm9615_hws); i++) {
1697 ret = devm_clk_hw_register(dev, gcc_mdm9615_hws[i]);
1698 if (ret)
1699 return ret;
1700 }
1701
1702 return qcom_cc_really_probe(pdev, &gcc_mdm9615_desc, regmap);
1703}
1704
1705static struct platform_driver gcc_mdm9615_driver = {
1706 .probe = gcc_mdm9615_probe,
1707 .driver = {
1708 .name = "gcc-mdm9615",
1709 .of_match_table = gcc_mdm9615_match_table,
1710 },
1711};
1712
1713static int __init gcc_mdm9615_init(void)
1714{
1715 return platform_driver_register(&gcc_mdm9615_driver);
1716}
1717core_initcall(gcc_mdm9615_init);
1718
1719static void __exit gcc_mdm9615_exit(void)
1720{
1721 platform_driver_unregister(&gcc_mdm9615_driver);
1722}
1723module_exit(gcc_mdm9615_exit);
1724
1725MODULE_DESCRIPTION("QCOM GCC MDM9615 Driver");
1726MODULE_LICENSE("GPL v2");
1727MODULE_ALIAS("platform:gcc-mdm9615");
diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
index bbf732bbc3fd..fe03e6fbc7df 100644
--- a/drivers/clk/qcom/gcc-msm8996.c
+++ b/drivers/clk/qcom/gcc-msm8996.c
@@ -2592,9 +2592,9 @@ static struct clk_branch gcc_pcie_2_aux_clk = {
2592}; 2592};
2593 2593
2594static struct clk_branch gcc_pcie_2_pipe_clk = { 2594static struct clk_branch gcc_pcie_2_pipe_clk = {
2595 .halt_reg = 0x6e108, 2595 .halt_reg = 0x6e018,
2596 .clkr = { 2596 .clkr = {
2597 .enable_reg = 0x6e108, 2597 .enable_reg = 0x6e018,
2598 .enable_mask = BIT(0), 2598 .enable_mask = BIT(0),
2599 .hw.init = &(struct clk_init_data){ 2599 .hw.init = &(struct clk_init_data){
2600 .name = "gcc_pcie_2_pipe_clk", 2600 .name = "gcc_pcie_2_pipe_clk",
@@ -3329,6 +3329,8 @@ static const struct qcom_reset_map gcc_msm8996_resets[] = {
3329 [GCC_USB_20_BCR] = { 0x12000 }, 3329 [GCC_USB_20_BCR] = { 0x12000 },
3330 [GCC_QUSB2PHY_PRIM_BCR] = { 0x12038 }, 3330 [GCC_QUSB2PHY_PRIM_BCR] = { 0x12038 },
3331 [GCC_QUSB2PHY_SEC_BCR] = { 0x1203c }, 3331 [GCC_QUSB2PHY_SEC_BCR] = { 0x1203c },
3332 [GCC_USB3_PHY_BCR] = { 0x50020 },
3333 [GCC_USB3PHY_PHY_BCR] = { 0x50024 },
3332 [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 }, 3334 [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 },
3333 [GCC_SDCC1_BCR] = { 0x13000 }, 3335 [GCC_SDCC1_BCR] = { 0x13000 },
3334 [GCC_SDCC2_BCR] = { 0x14000 }, 3336 [GCC_SDCC2_BCR] = { 0x14000 },
@@ -3404,6 +3406,8 @@ static const struct qcom_reset_map gcc_msm8996_resets[] = {
3404 [GCC_PCIE_2_BCR] = { 0x6e000 }, 3406 [GCC_PCIE_2_BCR] = { 0x6e000 },
3405 [GCC_PCIE_2_PHY_BCR] = { 0x6e038 }, 3407 [GCC_PCIE_2_PHY_BCR] = { 0x6e038 },
3406 [GCC_PCIE_PHY_BCR] = { 0x6f000 }, 3408 [GCC_PCIE_PHY_BCR] = { 0x6f000 },
3409 [GCC_PCIE_PHY_COM_BCR] = { 0x6f014 },
3410 [GCC_PCIE_PHY_COM_NOCSR_BCR] = { 0x6f00c },
3407 [GCC_DCD_BCR] = { 0x70000 }, 3411 [GCC_DCD_BCR] = { 0x70000 },
3408 [GCC_OBT_ODT_BCR] = { 0x73000 }, 3412 [GCC_OBT_ODT_BCR] = { 0x73000 },
3409 [GCC_UFS_BCR] = { 0x75000 }, 3413 [GCC_UFS_BCR] = { 0x75000 },
@@ -3447,9 +3451,8 @@ MODULE_DEVICE_TABLE(of, gcc_msm8996_match_table);
3447 3451
3448static int gcc_msm8996_probe(struct platform_device *pdev) 3452static int gcc_msm8996_probe(struct platform_device *pdev)
3449{ 3453{
3450 struct clk *clk;
3451 struct device *dev = &pdev->dev; 3454 struct device *dev = &pdev->dev;
3452 int i; 3455 int i, ret;
3453 struct regmap *regmap; 3456 struct regmap *regmap;
3454 3457
3455 regmap = qcom_cc_map(pdev, &gcc_msm8996_desc); 3458 regmap = qcom_cc_map(pdev, &gcc_msm8996_desc);
@@ -3463,9 +3466,9 @@ static int gcc_msm8996_probe(struct platform_device *pdev)
3463 regmap_update_bits(regmap, 0x52008, BIT(21), BIT(21)); 3466 regmap_update_bits(regmap, 0x52008, BIT(21), BIT(21));
3464 3467
3465 for (i = 0; i < ARRAY_SIZE(gcc_msm8996_hws); i++) { 3468 for (i = 0; i < ARRAY_SIZE(gcc_msm8996_hws); i++) {
3466 clk = devm_clk_register(dev, gcc_msm8996_hws[i]); 3469 ret = devm_clk_hw_register(dev, gcc_msm8996_hws[i]);
3467 if (IS_ERR(clk)) 3470 if (ret)
3468 return PTR_ERR(clk); 3471 return ret;
3469 } 3472 }
3470 3473
3471 return qcom_cc_really_probe(pdev, &gcc_msm8996_desc, regmap); 3474 return qcom_cc_really_probe(pdev, &gcc_msm8996_desc, regmap);
diff --git a/drivers/clk/qcom/lcc-mdm9615.c b/drivers/clk/qcom/lcc-mdm9615.c
new file mode 100644
index 000000000000..3237ef4c1197
--- /dev/null
+++ b/drivers/clk/qcom/lcc-mdm9615.c
@@ -0,0 +1,580 @@
1/*
2 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
3 * Copyright (c) BayLibre, SAS.
4 * Author : Neil Armstrong <narmstrong@baylibre.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/kernel.h>
17#include <linux/bitops.h>
18#include <linux/err.h>
19#include <linux/platform_device.h>
20#include <linux/module.h>
21#include <linux/of.h>
22#include <linux/of_device.h>
23#include <linux/clk-provider.h>
24#include <linux/regmap.h>
25
26#include <dt-bindings/clock/qcom,lcc-mdm9615.h>
27
28#include "common.h"
29#include "clk-regmap.h"
30#include "clk-pll.h"
31#include "clk-rcg.h"
32#include "clk-branch.h"
33#include "clk-regmap-divider.h"
34#include "clk-regmap-mux.h"
35
36static struct clk_pll pll4 = {
37 .l_reg = 0x4,
38 .m_reg = 0x8,
39 .n_reg = 0xc,
40 .config_reg = 0x14,
41 .mode_reg = 0x0,
42 .status_reg = 0x18,
43 .status_bit = 16,
44 .clkr.hw.init = &(struct clk_init_data){
45 .name = "pll4",
46 .parent_names = (const char *[]){ "cxo" },
47 .num_parents = 1,
48 .ops = &clk_pll_ops,
49 },
50};
51
52enum {
53 P_CXO,
54 P_PLL4,
55};
56
57static const struct parent_map lcc_cxo_pll4_map[] = {
58 { P_CXO, 0 },
59 { P_PLL4, 2 }
60};
61
62static const char * const lcc_cxo_pll4[] = {
63 "cxo",
64 "pll4_vote",
65};
66
67static struct freq_tbl clk_tbl_aif_osr_492[] = {
68 { 512000, P_PLL4, 4, 1, 240 },
69 { 768000, P_PLL4, 4, 1, 160 },
70 { 1024000, P_PLL4, 4, 1, 120 },
71 { 1536000, P_PLL4, 4, 1, 80 },
72 { 2048000, P_PLL4, 4, 1, 60 },
73 { 3072000, P_PLL4, 4, 1, 40 },
74 { 4096000, P_PLL4, 4, 1, 30 },
75 { 6144000, P_PLL4, 4, 1, 20 },
76 { 8192000, P_PLL4, 4, 1, 15 },
77 { 12288000, P_PLL4, 4, 1, 10 },
78 { 24576000, P_PLL4, 4, 1, 5 },
79 { 27000000, P_CXO, 1, 0, 0 },
80 { }
81};
82
83static struct freq_tbl clk_tbl_aif_osr_393[] = {
84 { 512000, P_PLL4, 4, 1, 192 },
85 { 768000, P_PLL4, 4, 1, 128 },
86 { 1024000, P_PLL4, 4, 1, 96 },
87 { 1536000, P_PLL4, 4, 1, 64 },
88 { 2048000, P_PLL4, 4, 1, 48 },
89 { 3072000, P_PLL4, 4, 1, 32 },
90 { 4096000, P_PLL4, 4, 1, 24 },
91 { 6144000, P_PLL4, 4, 1, 16 },
92 { 8192000, P_PLL4, 4, 1, 12 },
93 { 12288000, P_PLL4, 4, 1, 8 },
94 { 24576000, P_PLL4, 4, 1, 4 },
95 { 27000000, P_CXO, 1, 0, 0 },
96 { }
97};
98
99static struct clk_rcg mi2s_osr_src = {
100 .ns_reg = 0x48,
101 .md_reg = 0x4c,
102 .mn = {
103 .mnctr_en_bit = 8,
104 .mnctr_reset_bit = 7,
105 .mnctr_mode_shift = 5,
106 .n_val_shift = 24,
107 .m_val_shift = 8,
108 .width = 8,
109 },
110 .p = {
111 .pre_div_shift = 3,
112 .pre_div_width = 2,
113 },
114 .s = {
115 .src_sel_shift = 0,
116 .parent_map = lcc_cxo_pll4_map,
117 },
118 .freq_tbl = clk_tbl_aif_osr_393,
119 .clkr = {
120 .enable_reg = 0x48,
121 .enable_mask = BIT(9),
122 .hw.init = &(struct clk_init_data){
123 .name = "mi2s_osr_src",
124 .parent_names = lcc_cxo_pll4,
125 .num_parents = 2,
126 .ops = &clk_rcg_ops,
127 .flags = CLK_SET_RATE_GATE,
128 },
129 },
130};
131
132static const char * const lcc_mi2s_parents[] = {
133 "mi2s_osr_src",
134};
135
136static struct clk_branch mi2s_osr_clk = {
137 .halt_reg = 0x50,
138 .halt_bit = 1,
139 .halt_check = BRANCH_HALT_ENABLE,
140 .clkr = {
141 .enable_reg = 0x48,
142 .enable_mask = BIT(17),
143 .hw.init = &(struct clk_init_data){
144 .name = "mi2s_osr_clk",
145 .parent_names = lcc_mi2s_parents,
146 .num_parents = 1,
147 .ops = &clk_branch_ops,
148 .flags = CLK_SET_RATE_PARENT,
149 },
150 },
151};
152
153static struct clk_regmap_div mi2s_div_clk = {
154 .reg = 0x48,
155 .shift = 10,
156 .width = 4,
157 .clkr = {
158 .enable_reg = 0x48,
159 .enable_mask = BIT(15),
160 .hw.init = &(struct clk_init_data){
161 .name = "mi2s_div_clk",
162 .parent_names = lcc_mi2s_parents,
163 .num_parents = 1,
164 .ops = &clk_regmap_div_ops,
165 },
166 },
167};
168
169static struct clk_branch mi2s_bit_div_clk = {
170 .halt_reg = 0x50,
171 .halt_bit = 0,
172 .halt_check = BRANCH_HALT_ENABLE,
173 .clkr = {
174 .enable_reg = 0x48,
175 .enable_mask = BIT(15),
176 .hw.init = &(struct clk_init_data){
177 .name = "mi2s_bit_div_clk",
178 .parent_names = (const char *[]){ "mi2s_div_clk" },
179 .num_parents = 1,
180 .ops = &clk_branch_ops,
181 .flags = CLK_SET_RATE_PARENT,
182 },
183 },
184};
185
186static struct clk_regmap_mux mi2s_bit_clk = {
187 .reg = 0x48,
188 .shift = 14,
189 .width = 1,
190 .clkr = {
191 .hw.init = &(struct clk_init_data){
192 .name = "mi2s_bit_clk",
193 .parent_names = (const char *[]){
194 "mi2s_bit_div_clk",
195 "mi2s_codec_clk",
196 },
197 .num_parents = 2,
198 .ops = &clk_regmap_mux_closest_ops,
199 .flags = CLK_SET_RATE_PARENT,
200 },
201 },
202};
203
204#define CLK_AIF_OSR_DIV(prefix, _ns, _md, hr) \
205static struct clk_rcg prefix##_osr_src = { \
206 .ns_reg = _ns, \
207 .md_reg = _md, \
208 .mn = { \
209 .mnctr_en_bit = 8, \
210 .mnctr_reset_bit = 7, \
211 .mnctr_mode_shift = 5, \
212 .n_val_shift = 24, \
213 .m_val_shift = 8, \
214 .width = 8, \
215 }, \
216 .p = { \
217 .pre_div_shift = 3, \
218 .pre_div_width = 2, \
219 }, \
220 .s = { \
221 .src_sel_shift = 0, \
222 .parent_map = lcc_cxo_pll4_map, \
223 }, \
224 .freq_tbl = clk_tbl_aif_osr_393, \
225 .clkr = { \
226 .enable_reg = _ns, \
227 .enable_mask = BIT(9), \
228 .hw.init = &(struct clk_init_data){ \
229 .name = #prefix "_osr_src", \
230 .parent_names = lcc_cxo_pll4, \
231 .num_parents = 2, \
232 .ops = &clk_rcg_ops, \
233 .flags = CLK_SET_RATE_GATE, \
234 }, \
235 }, \
236}; \
237 \
238static const char * const lcc_##prefix##_parents[] = { \
239 #prefix "_osr_src", \
240}; \
241 \
242static struct clk_branch prefix##_osr_clk = { \
243 .halt_reg = hr, \
244 .halt_bit = 1, \
245 .halt_check = BRANCH_HALT_ENABLE, \
246 .clkr = { \
247 .enable_reg = _ns, \
248 .enable_mask = BIT(21), \
249 .hw.init = &(struct clk_init_data){ \
250 .name = #prefix "_osr_clk", \
251 .parent_names = lcc_##prefix##_parents, \
252 .num_parents = 1, \
253 .ops = &clk_branch_ops, \
254 .flags = CLK_SET_RATE_PARENT, \
255 }, \
256 }, \
257}; \
258 \
259static struct clk_regmap_div prefix##_div_clk = { \
260 .reg = _ns, \
261 .shift = 10, \
262 .width = 8, \
263 .clkr = { \
264 .hw.init = &(struct clk_init_data){ \
265 .name = #prefix "_div_clk", \
266 .parent_names = lcc_##prefix##_parents, \
267 .num_parents = 1, \
268 .ops = &clk_regmap_div_ops, \
269 }, \
270 }, \
271}; \
272 \
273static struct clk_branch prefix##_bit_div_clk = { \
274 .halt_reg = hr, \
275 .halt_bit = 0, \
276 .halt_check = BRANCH_HALT_ENABLE, \
277 .clkr = { \
278 .enable_reg = _ns, \
279 .enable_mask = BIT(19), \
280 .hw.init = &(struct clk_init_data){ \
281 .name = #prefix "_bit_div_clk", \
282 .parent_names = (const char *[]){ \
283 #prefix "_div_clk" \
284 }, \
285 .num_parents = 1, \
286 .ops = &clk_branch_ops, \
287 .flags = CLK_SET_RATE_PARENT, \
288 }, \
289 }, \
290}; \
291 \
292static struct clk_regmap_mux prefix##_bit_clk = { \
293 .reg = _ns, \
294 .shift = 18, \
295 .width = 1, \
296 .clkr = { \
297 .hw.init = &(struct clk_init_data){ \
298 .name = #prefix "_bit_clk", \
299 .parent_names = (const char *[]){ \
300 #prefix "_bit_div_clk", \
301 #prefix "_codec_clk", \
302 }, \
303 .num_parents = 2, \
304 .ops = &clk_regmap_mux_closest_ops, \
305 .flags = CLK_SET_RATE_PARENT, \
306 }, \
307 }, \
308}
309
310CLK_AIF_OSR_DIV(codec_i2s_mic, 0x60, 0x64, 0x68);
311CLK_AIF_OSR_DIV(spare_i2s_mic, 0x78, 0x7c, 0x80);
312CLK_AIF_OSR_DIV(codec_i2s_spkr, 0x6c, 0x70, 0x74);
313CLK_AIF_OSR_DIV(spare_i2s_spkr, 0x84, 0x88, 0x8c);
314
315static struct freq_tbl clk_tbl_pcm_492[] = {
316 { 256000, P_PLL4, 4, 1, 480 },
317 { 512000, P_PLL4, 4, 1, 240 },
318 { 768000, P_PLL4, 4, 1, 160 },
319 { 1024000, P_PLL4, 4, 1, 120 },
320 { 1536000, P_PLL4, 4, 1, 80 },
321 { 2048000, P_PLL4, 4, 1, 60 },
322 { 3072000, P_PLL4, 4, 1, 40 },
323 { 4096000, P_PLL4, 4, 1, 30 },
324 { 6144000, P_PLL4, 4, 1, 20 },
325 { 8192000, P_PLL4, 4, 1, 15 },
326 { 12288000, P_PLL4, 4, 1, 10 },
327 { 24576000, P_PLL4, 4, 1, 5 },
328 { 27000000, P_CXO, 1, 0, 0 },
329 { }
330};
331
332static struct freq_tbl clk_tbl_pcm_393[] = {
333 { 256000, P_PLL4, 4, 1, 384 },
334 { 512000, P_PLL4, 4, 1, 192 },
335 { 768000, P_PLL4, 4, 1, 128 },
336 { 1024000, P_PLL4, 4, 1, 96 },
337 { 1536000, P_PLL4, 4, 1, 64 },
338 { 2048000, P_PLL4, 4, 1, 48 },
339 { 3072000, P_PLL4, 4, 1, 32 },
340 { 4096000, P_PLL4, 4, 1, 24 },
341 { 6144000, P_PLL4, 4, 1, 16 },
342 { 8192000, P_PLL4, 4, 1, 12 },
343 { 12288000, P_PLL4, 4, 1, 8 },
344 { 24576000, P_PLL4, 4, 1, 4 },
345 { 27000000, P_CXO, 1, 0, 0 },
346 { }
347};
348
349static struct clk_rcg pcm_src = {
350 .ns_reg = 0x54,
351 .md_reg = 0x58,
352 .mn = {
353 .mnctr_en_bit = 8,
354 .mnctr_reset_bit = 7,
355 .mnctr_mode_shift = 5,
356 .n_val_shift = 16,
357 .m_val_shift = 16,
358 .width = 16,
359 },
360 .p = {
361 .pre_div_shift = 3,
362 .pre_div_width = 2,
363 },
364 .s = {
365 .src_sel_shift = 0,
366 .parent_map = lcc_cxo_pll4_map,
367 },
368 .freq_tbl = clk_tbl_pcm_393,
369 .clkr = {
370 .enable_reg = 0x54,
371 .enable_mask = BIT(9),
372 .hw.init = &(struct clk_init_data){
373 .name = "pcm_src",
374 .parent_names = lcc_cxo_pll4,
375 .num_parents = 2,
376 .ops = &clk_rcg_ops,
377 .flags = CLK_SET_RATE_GATE,
378 },
379 },
380};
381
382static struct clk_branch pcm_clk_out = {
383 .halt_reg = 0x5c,
384 .halt_bit = 0,
385 .halt_check = BRANCH_HALT_ENABLE,
386 .clkr = {
387 .enable_reg = 0x54,
388 .enable_mask = BIT(11),
389 .hw.init = &(struct clk_init_data){
390 .name = "pcm_clk_out",
391 .parent_names = (const char *[]){ "pcm_src" },
392 .num_parents = 1,
393 .ops = &clk_branch_ops,
394 .flags = CLK_SET_RATE_PARENT,
395 },
396 },
397};
398
399static struct clk_regmap_mux pcm_clk = {
400 .reg = 0x54,
401 .shift = 10,
402 .width = 1,
403 .clkr = {
404 .hw.init = &(struct clk_init_data){
405 .name = "pcm_clk",
406 .parent_names = (const char *[]){
407 "pcm_clk_out",
408 "pcm_codec_clk",
409 },
410 .num_parents = 2,
411 .ops = &clk_regmap_mux_closest_ops,
412 .flags = CLK_SET_RATE_PARENT,
413 },
414 },
415};
416
417static struct clk_rcg slimbus_src = {
418 .ns_reg = 0xcc,
419 .md_reg = 0xd0,
420 .mn = {
421 .mnctr_en_bit = 8,
422 .mnctr_reset_bit = 7,
423 .mnctr_mode_shift = 5,
424 .n_val_shift = 24,
425 .m_val_shift = 8,
426 .width = 8,
427 },
428 .p = {
429 .pre_div_shift = 3,
430 .pre_div_width = 2,
431 },
432 .s = {
433 .src_sel_shift = 0,
434 .parent_map = lcc_cxo_pll4_map,
435 },
436 .freq_tbl = clk_tbl_aif_osr_393,
437 .clkr = {
438 .enable_reg = 0xcc,
439 .enable_mask = BIT(9),
440 .hw.init = &(struct clk_init_data){
441 .name = "slimbus_src",
442 .parent_names = lcc_cxo_pll4,
443 .num_parents = 2,
444 .ops = &clk_rcg_ops,
445 .flags = CLK_SET_RATE_GATE,
446 },
447 },
448};
449
450static const char * const lcc_slimbus_parents[] = {
451 "slimbus_src",
452};
453
454static struct clk_branch audio_slimbus_clk = {
455 .halt_reg = 0xd4,
456 .halt_bit = 0,
457 .halt_check = BRANCH_HALT_ENABLE,
458 .clkr = {
459 .enable_reg = 0xcc,
460 .enable_mask = BIT(10),
461 .hw.init = &(struct clk_init_data){
462 .name = "audio_slimbus_clk",
463 .parent_names = lcc_slimbus_parents,
464 .num_parents = 1,
465 .ops = &clk_branch_ops,
466 .flags = CLK_SET_RATE_PARENT,
467 },
468 },
469};
470
471static struct clk_branch sps_slimbus_clk = {
472 .halt_reg = 0xd4,
473 .halt_bit = 1,
474 .halt_check = BRANCH_HALT_ENABLE,
475 .clkr = {
476 .enable_reg = 0xcc,
477 .enable_mask = BIT(12),
478 .hw.init = &(struct clk_init_data){
479 .name = "sps_slimbus_clk",
480 .parent_names = lcc_slimbus_parents,
481 .num_parents = 1,
482 .ops = &clk_branch_ops,
483 .flags = CLK_SET_RATE_PARENT,
484 },
485 },
486};
487
488static struct clk_regmap *lcc_mdm9615_clks[] = {
489 [PLL4] = &pll4.clkr,
490 [MI2S_OSR_SRC] = &mi2s_osr_src.clkr,
491 [MI2S_OSR_CLK] = &mi2s_osr_clk.clkr,
492 [MI2S_DIV_CLK] = &mi2s_div_clk.clkr,
493 [MI2S_BIT_DIV_CLK] = &mi2s_bit_div_clk.clkr,
494 [MI2S_BIT_CLK] = &mi2s_bit_clk.clkr,
495 [PCM_SRC] = &pcm_src.clkr,
496 [PCM_CLK_OUT] = &pcm_clk_out.clkr,
497 [PCM_CLK] = &pcm_clk.clkr,
498 [SLIMBUS_SRC] = &slimbus_src.clkr,
499 [AUDIO_SLIMBUS_CLK] = &audio_slimbus_clk.clkr,
500 [SPS_SLIMBUS_CLK] = &sps_slimbus_clk.clkr,
501 [CODEC_I2S_MIC_OSR_SRC] = &codec_i2s_mic_osr_src.clkr,
502 [CODEC_I2S_MIC_OSR_CLK] = &codec_i2s_mic_osr_clk.clkr,
503 [CODEC_I2S_MIC_DIV_CLK] = &codec_i2s_mic_div_clk.clkr,
504 [CODEC_I2S_MIC_BIT_DIV_CLK] = &codec_i2s_mic_bit_div_clk.clkr,
505 [CODEC_I2S_MIC_BIT_CLK] = &codec_i2s_mic_bit_clk.clkr,
506 [SPARE_I2S_MIC_OSR_SRC] = &spare_i2s_mic_osr_src.clkr,
507 [SPARE_I2S_MIC_OSR_CLK] = &spare_i2s_mic_osr_clk.clkr,
508 [SPARE_I2S_MIC_DIV_CLK] = &spare_i2s_mic_div_clk.clkr,
509 [SPARE_I2S_MIC_BIT_DIV_CLK] = &spare_i2s_mic_bit_div_clk.clkr,
510 [SPARE_I2S_MIC_BIT_CLK] = &spare_i2s_mic_bit_clk.clkr,
511 [CODEC_I2S_SPKR_OSR_SRC] = &codec_i2s_spkr_osr_src.clkr,
512 [CODEC_I2S_SPKR_OSR_CLK] = &codec_i2s_spkr_osr_clk.clkr,
513 [CODEC_I2S_SPKR_DIV_CLK] = &codec_i2s_spkr_div_clk.clkr,
514 [CODEC_I2S_SPKR_BIT_DIV_CLK] = &codec_i2s_spkr_bit_div_clk.clkr,
515 [CODEC_I2S_SPKR_BIT_CLK] = &codec_i2s_spkr_bit_clk.clkr,
516 [SPARE_I2S_SPKR_OSR_SRC] = &spare_i2s_spkr_osr_src.clkr,
517 [SPARE_I2S_SPKR_OSR_CLK] = &spare_i2s_spkr_osr_clk.clkr,
518 [SPARE_I2S_SPKR_DIV_CLK] = &spare_i2s_spkr_div_clk.clkr,
519 [SPARE_I2S_SPKR_BIT_DIV_CLK] = &spare_i2s_spkr_bit_div_clk.clkr,
520 [SPARE_I2S_SPKR_BIT_CLK] = &spare_i2s_spkr_bit_clk.clkr,
521};
522
523static const struct regmap_config lcc_mdm9615_regmap_config = {
524 .reg_bits = 32,
525 .reg_stride = 4,
526 .val_bits = 32,
527 .max_register = 0xfc,
528 .fast_io = true,
529};
530
531static const struct qcom_cc_desc lcc_mdm9615_desc = {
532 .config = &lcc_mdm9615_regmap_config,
533 .clks = lcc_mdm9615_clks,
534 .num_clks = ARRAY_SIZE(lcc_mdm9615_clks),
535};
536
537static const struct of_device_id lcc_mdm9615_match_table[] = {
538 { .compatible = "qcom,lcc-mdm9615" },
539 { }
540};
541MODULE_DEVICE_TABLE(of, lcc_mdm9615_match_table);
542
543static int lcc_mdm9615_probe(struct platform_device *pdev)
544{
545 u32 val;
546 struct regmap *regmap;
547
548 regmap = qcom_cc_map(pdev, &lcc_mdm9615_desc);
549 if (IS_ERR(regmap))
550 return PTR_ERR(regmap);
551
552 /* Use the correct frequency plan depending on speed of PLL4 */
553 regmap_read(regmap, 0x4, &val);
554 if (val == 0x12) {
555 slimbus_src.freq_tbl = clk_tbl_aif_osr_492;
556 mi2s_osr_src.freq_tbl = clk_tbl_aif_osr_492;
557 codec_i2s_mic_osr_src.freq_tbl = clk_tbl_aif_osr_492;
558 spare_i2s_mic_osr_src.freq_tbl = clk_tbl_aif_osr_492;
559 codec_i2s_spkr_osr_src.freq_tbl = clk_tbl_aif_osr_492;
560 spare_i2s_spkr_osr_src.freq_tbl = clk_tbl_aif_osr_492;
561 pcm_src.freq_tbl = clk_tbl_pcm_492;
562 }
563 /* Enable PLL4 source on the LPASS Primary PLL Mux */
564 regmap_write(regmap, 0xc4, 0x1);
565
566 return qcom_cc_really_probe(pdev, &lcc_mdm9615_desc, regmap);
567}
568
569static struct platform_driver lcc_mdm9615_driver = {
570 .probe = lcc_mdm9615_probe,
571 .driver = {
572 .name = "lcc-mdm9615",
573 .of_match_table = lcc_mdm9615_match_table,
574 },
575};
576module_platform_driver(lcc_mdm9615_driver);
577
578MODULE_DESCRIPTION("QCOM LCC MDM9615 Driver");
579MODULE_LICENSE("GPL v2");
580MODULE_ALIAS("platform:lcc-mdm9615");
diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c
index 847dd9dadeca..ca97e1151797 100644
--- a/drivers/clk/qcom/mmcc-msm8996.c
+++ b/drivers/clk/qcom/mmcc-msm8996.c
@@ -2888,6 +2888,14 @@ static struct clk_hw *mmcc_msm8996_hws[] = {
2888 &gpll0_div.hw, 2888 &gpll0_div.hw,
2889}; 2889};
2890 2890
2891static struct gdsc mmagic_bimc_gdsc = {
2892 .gdscr = 0x529c,
2893 .pd = {
2894 .name = "mmagic_bimc",
2895 },
2896 .pwrsts = PWRSTS_OFF_ON,
2897};
2898
2891static struct gdsc mmagic_video_gdsc = { 2899static struct gdsc mmagic_video_gdsc = {
2892 .gdscr = 0x119c, 2900 .gdscr = 0x119c,
2893 .gds_hw_ctrl = 0x120c, 2901 .gds_hw_ctrl = 0x120c,
@@ -3201,6 +3209,7 @@ static struct clk_regmap *mmcc_msm8996_clocks[] = {
3201}; 3209};
3202 3210
3203static struct gdsc *mmcc_msm8996_gdscs[] = { 3211static struct gdsc *mmcc_msm8996_gdscs[] = {
3212 [MMAGIC_BIMC_GDSC] = &mmagic_bimc_gdsc,
3204 [MMAGIC_VIDEO_GDSC] = &mmagic_video_gdsc, 3213 [MMAGIC_VIDEO_GDSC] = &mmagic_video_gdsc,
3205 [MMAGIC_MDSS_GDSC] = &mmagic_mdss_gdsc, 3214 [MMAGIC_MDSS_GDSC] = &mmagic_mdss_gdsc,
3206 [MMAGIC_CAMSS_GDSC] = &mmagic_camss_gdsc, 3215 [MMAGIC_CAMSS_GDSC] = &mmagic_camss_gdsc,
@@ -3305,9 +3314,8 @@ MODULE_DEVICE_TABLE(of, mmcc_msm8996_match_table);
3305 3314
3306static int mmcc_msm8996_probe(struct platform_device *pdev) 3315static int mmcc_msm8996_probe(struct platform_device *pdev)
3307{ 3316{
3308 struct clk *clk;
3309 struct device *dev = &pdev->dev; 3317 struct device *dev = &pdev->dev;
3310 int i; 3318 int i, ret;
3311 struct regmap *regmap; 3319 struct regmap *regmap;
3312 3320
3313 regmap = qcom_cc_map(pdev, &mmcc_msm8996_desc); 3321 regmap = qcom_cc_map(pdev, &mmcc_msm8996_desc);
@@ -3320,9 +3328,9 @@ static int mmcc_msm8996_probe(struct platform_device *pdev)
3320 regmap_update_bits(regmap, 0x5054, BIT(15), 0); 3328 regmap_update_bits(regmap, 0x5054, BIT(15), 0);
3321 3329
3322 for (i = 0; i < ARRAY_SIZE(mmcc_msm8996_hws); i++) { 3330 for (i = 0; i < ARRAY_SIZE(mmcc_msm8996_hws); i++) {
3323 clk = devm_clk_register(dev, mmcc_msm8996_hws[i]); 3331 ret = devm_clk_hw_register(dev, mmcc_msm8996_hws[i]);
3324 if (IS_ERR(clk)) 3332 if (ret)
3325 return PTR_ERR(clk); 3333 return ret;
3326 } 3334 }
3327 3335
3328 return qcom_cc_really_probe(pdev, &mmcc_msm8996_desc, regmap); 3336 return qcom_cc_really_probe(pdev, &mmcc_msm8996_desc, regmap);
diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c
index 5093a250650d..9375777776d9 100644
--- a/drivers/clk/renesas/clk-mstp.c
+++ b/drivers/clk/renesas/clk-mstp.c
@@ -167,7 +167,7 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
167 unsigned int i; 167 unsigned int i;
168 168
169 group = kzalloc(sizeof(*group), GFP_KERNEL); 169 group = kzalloc(sizeof(*group), GFP_KERNEL);
170 clks = kmalloc(MSTP_MAX_CLOCKS * sizeof(*clks), GFP_KERNEL); 170 clks = kmalloc_array(MSTP_MAX_CLOCKS, sizeof(*clks), GFP_KERNEL);
171 if (group == NULL || clks == NULL) { 171 if (group == NULL || clks == NULL) {
172 kfree(group); 172 kfree(group);
173 kfree(clks); 173 kfree(clks);
diff --git a/drivers/clk/renesas/clk-rz.c b/drivers/clk/renesas/clk-rz.c
index f6312c62f16b..5adb934326d1 100644
--- a/drivers/clk/renesas/clk-rz.c
+++ b/drivers/clk/renesas/clk-rz.c
@@ -25,10 +25,31 @@ struct rz_cpg {
25#define CPG_FRQCR 0x10 25#define CPG_FRQCR 0x10
26#define CPG_FRQCR2 0x14 26#define CPG_FRQCR2 0x14
27 27
28#define PPR0 0xFCFE3200
29#define PIBC0 0xFCFE7000
30
31#define MD_CLK(x) ((x >> 2) & 1) /* P0_2 */
32
28/* ----------------------------------------------------------------------------- 33/* -----------------------------------------------------------------------------
29 * Initialization 34 * Initialization
30 */ 35 */
31 36
37static u16 __init rz_cpg_read_mode_pins(void)
38{
39 void __iomem *ppr0, *pibc0;
40 u16 modes;
41
42 ppr0 = ioremap_nocache(PPR0, 2);
43 pibc0 = ioremap_nocache(PIBC0, 2);
44 BUG_ON(!ppr0 || !pibc0);
45 iowrite16(4, pibc0); /* enable input buffer */
46 modes = ioread16(ppr0);
47 iounmap(ppr0);
48 iounmap(pibc0);
49
50 return modes;
51}
52
32static struct clk * __init 53static struct clk * __init
33rz_cpg_register_clock(struct device_node *np, struct rz_cpg *cpg, const char *name) 54rz_cpg_register_clock(struct device_node *np, struct rz_cpg *cpg, const char *name)
34{ 55{
@@ -37,8 +58,7 @@ rz_cpg_register_clock(struct device_node *np, struct rz_cpg *cpg, const char *na
37 static const unsigned frqcr_tab[4] = { 3, 2, 0, 1 }; 58 static const unsigned frqcr_tab[4] = { 3, 2, 0, 1 };
38 59
39 if (strcmp(name, "pll") == 0) { 60 if (strcmp(name, "pll") == 0) {
40 /* FIXME: cpg_mode should be read from GPIO. But no GPIO support yet */ 61 unsigned int cpg_mode = MD_CLK(rz_cpg_read_mode_pins());
41 unsigned cpg_mode = 0; /* hardcoded to EXTAL for now */
42 const char *parent_name = of_clk_get_parent_name(np, cpg_mode); 62 const char *parent_name = of_clk_get_parent_name(np, cpg_mode);
43 63
44 mult = cpg_mode ? (32 / 4) : 30; 64 mult = cpg_mode ? (32 / 4) : 30;
diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c
index e38bf60c0ff4..f255e451e8ca 100644
--- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
@@ -123,6 +123,10 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
123 DEF_MOD("sys-dmac2", 217, R8A7795_CLK_S3D1), 123 DEF_MOD("sys-dmac2", 217, R8A7795_CLK_S3D1),
124 DEF_MOD("sys-dmac1", 218, R8A7795_CLK_S3D1), 124 DEF_MOD("sys-dmac1", 218, R8A7795_CLK_S3D1),
125 DEF_MOD("sys-dmac0", 219, R8A7795_CLK_S3D1), 125 DEF_MOD("sys-dmac0", 219, R8A7795_CLK_S3D1),
126 DEF_MOD("cmt3", 300, R8A7795_CLK_R),
127 DEF_MOD("cmt2", 301, R8A7795_CLK_R),
128 DEF_MOD("cmt1", 302, R8A7795_CLK_R),
129 DEF_MOD("cmt0", 303, R8A7795_CLK_R),
126 DEF_MOD("scif2", 310, R8A7795_CLK_S3D4), 130 DEF_MOD("scif2", 310, R8A7795_CLK_S3D4),
127 DEF_MOD("sdif3", 311, R8A7795_CLK_SD3), 131 DEF_MOD("sdif3", 311, R8A7795_CLK_SD3),
128 DEF_MOD("sdif2", 312, R8A7795_CLK_SD2), 132 DEF_MOD("sdif2", 312, R8A7795_CLK_SD2),
diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c
index c84b549c14d2..eb347ed265f2 100644
--- a/drivers/clk/renesas/r8a7796-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c
@@ -45,6 +45,7 @@ enum clk_ids {
45 CLK_S3, 45 CLK_S3,
46 CLK_SDSRC, 46 CLK_SDSRC,
47 CLK_SSPSRC, 47 CLK_SSPSRC,
48 CLK_RINT,
48 49
49 /* Module Clocks */ 50 /* Module Clocks */
50 MOD_CLK_BASE 51 MOD_CLK_BASE
@@ -69,6 +70,7 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = {
69 DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), 70 DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1),
70 DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), 71 DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1),
71 DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), 72 DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1),
73 DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1),
72 74
73 /* Core Clock Outputs */ 75 /* Core Clock Outputs */
74 DEF_FIXED("ztr", R8A7796_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), 76 DEF_FIXED("ztr", R8A7796_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
@@ -92,13 +94,42 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = {
92 DEF_FIXED("s3d2", R8A7796_CLK_S3D2, CLK_S3, 2, 1), 94 DEF_FIXED("s3d2", R8A7796_CLK_S3D2, CLK_S3, 2, 1),
93 DEF_FIXED("s3d4", R8A7796_CLK_S3D4, CLK_S3, 4, 1), 95 DEF_FIXED("s3d4", R8A7796_CLK_S3D4, CLK_S3, 4, 1),
94 96
97 DEF_GEN3_SD("sd0", R8A7796_CLK_SD0, CLK_SDSRC, 0x0074),
98 DEF_GEN3_SD("sd1", R8A7796_CLK_SD1, CLK_SDSRC, 0x0078),
99 DEF_GEN3_SD("sd2", R8A7796_CLK_SD2, CLK_SDSRC, 0x0268),
100 DEF_GEN3_SD("sd3", R8A7796_CLK_SD3, CLK_SDSRC, 0x026c),
101
95 DEF_FIXED("cl", R8A7796_CLK_CL, CLK_PLL1_DIV2, 48, 1), 102 DEF_FIXED("cl", R8A7796_CLK_CL, CLK_PLL1_DIV2, 48, 1),
96 DEF_FIXED("cp", R8A7796_CLK_CP, CLK_EXTAL, 2, 1), 103 DEF_FIXED("cp", R8A7796_CLK_CP, CLK_EXTAL, 2, 1),
104
105 DEF_DIV6_RO("osc", R8A7796_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8),
106 DEF_DIV6_RO("r_int", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32),
107
108 DEF_BASE("r", R8A7796_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT),
97}; 109};
98 110
99static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = { 111static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = {
112 DEF_MOD("cmt3", 300, R8A7796_CLK_R),
113 DEF_MOD("cmt2", 301, R8A7796_CLK_R),
114 DEF_MOD("cmt1", 302, R8A7796_CLK_R),
115 DEF_MOD("cmt0", 303, R8A7796_CLK_R),
100 DEF_MOD("scif2", 310, R8A7796_CLK_S3D4), 116 DEF_MOD("scif2", 310, R8A7796_CLK_S3D4),
117 DEF_MOD("sdif3", 311, R8A7796_CLK_SD3),
118 DEF_MOD("sdif2", 312, R8A7796_CLK_SD2),
119 DEF_MOD("sdif1", 313, R8A7796_CLK_SD1),
120 DEF_MOD("sdif0", 314, R8A7796_CLK_SD0),
121 DEF_MOD("rwdt0", 402, R8A7796_CLK_R),
101 DEF_MOD("intc-ap", 408, R8A7796_CLK_S3D1), 122 DEF_MOD("intc-ap", 408, R8A7796_CLK_S3D1),
123 DEF_MOD("thermal", 522, R8A7796_CLK_CP),
124 DEF_MOD("etheravb", 812, R8A7796_CLK_S0D6),
125 DEF_MOD("gpio7", 905, R8A7796_CLK_S3D4),
126 DEF_MOD("gpio6", 906, R8A7796_CLK_S3D4),
127 DEF_MOD("gpio5", 907, R8A7796_CLK_S3D4),
128 DEF_MOD("gpio4", 908, R8A7796_CLK_S3D4),
129 DEF_MOD("gpio3", 909, R8A7796_CLK_S3D4),
130 DEF_MOD("gpio2", 910, R8A7796_CLK_S3D4),
131 DEF_MOD("gpio1", 911, R8A7796_CLK_S3D4),
132 DEF_MOD("gpio0", 912, R8A7796_CLK_S3D4),
102}; 133};
103 134
104static const unsigned int r8a7796_crit_mod_clks[] __initconst = { 135static const unsigned int r8a7796_crit_mod_clks[] __initconst = {
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index f47a2fa962d2..b5f2c8ed12e1 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -8,6 +8,7 @@ obj-y += clk-pll.o
8obj-y += clk-cpu.o 8obj-y += clk-cpu.o
9obj-y += clk-inverter.o 9obj-y += clk-inverter.o
10obj-y += clk-mmc-phase.o 10obj-y += clk-mmc-phase.o
11obj-y += clk-ddr.o
11obj-$(CONFIG_RESET_CONTROLLER) += softrst.o 12obj-$(CONFIG_RESET_CONTROLLER) += softrst.o
12 13
13obj-y += clk-rk3036.o 14obj-y += clk-rk3036.o
diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c
new file mode 100644
index 000000000000..8feba93672c5
--- /dev/null
+++ b/drivers/clk/rockchip/clk-ddr.c
@@ -0,0 +1,154 @@
1/*
2 * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
3 * Author: Lin Huang <hl@rock-chips.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/arm-smccc.h>
17#include <linux/clk.h>
18#include <linux/clk-provider.h>
19#include <linux/io.h>
20#include <linux/slab.h>
21#include <soc/rockchip/rockchip_sip.h>
22#include "clk.h"
23
24struct rockchip_ddrclk {
25 struct clk_hw hw;
26 void __iomem *reg_base;
27 int mux_offset;
28 int mux_shift;
29 int mux_width;
30 int div_shift;
31 int div_width;
32 int ddr_flag;
33 spinlock_t *lock;
34};
35
36#define to_rockchip_ddrclk_hw(hw) container_of(hw, struct rockchip_ddrclk, hw)
37
38static int rockchip_ddrclk_sip_set_rate(struct clk_hw *hw, unsigned long drate,
39 unsigned long prate)
40{
41 struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
42 unsigned long flags;
43 struct arm_smccc_res res;
44
45 spin_lock_irqsave(ddrclk->lock, flags);
46 arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, drate, 0,
47 ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE,
48 0, 0, 0, 0, &res);
49 spin_unlock_irqrestore(ddrclk->lock, flags);
50
51 return res.a0;
52}
53
54static unsigned long
55rockchip_ddrclk_sip_recalc_rate(struct clk_hw *hw,
56 unsigned long parent_rate)
57{
58 struct arm_smccc_res res;
59
60 arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0,
61 ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE,
62 0, 0, 0, 0, &res);
63
64 return res.a0;
65}
66
67static long rockchip_ddrclk_sip_round_rate(struct clk_hw *hw,
68 unsigned long rate,
69 unsigned long *prate)
70{
71 struct arm_smccc_res res;
72
73 arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, rate, 0,
74 ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE,
75 0, 0, 0, 0, &res);
76
77 return res.a0;
78}
79
80static u8 rockchip_ddrclk_get_parent(struct clk_hw *hw)
81{
82 struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
83 int num_parents = clk_hw_get_num_parents(hw);
84 u32 val;
85
86 val = clk_readl(ddrclk->reg_base +
87 ddrclk->mux_offset) >> ddrclk->mux_shift;
88 val &= GENMASK(ddrclk->mux_width - 1, 0);
89
90 if (val >= num_parents)
91 return -EINVAL;
92
93 return val;
94}
95
96static const struct clk_ops rockchip_ddrclk_sip_ops = {
97 .recalc_rate = rockchip_ddrclk_sip_recalc_rate,
98 .set_rate = rockchip_ddrclk_sip_set_rate,
99 .round_rate = rockchip_ddrclk_sip_round_rate,
100 .get_parent = rockchip_ddrclk_get_parent,
101};
102
103struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
104 const char *const *parent_names,
105 u8 num_parents, int mux_offset,
106 int mux_shift, int mux_width,
107 int div_shift, int div_width,
108 int ddr_flag, void __iomem *reg_base,
109 spinlock_t *lock)
110{
111 struct rockchip_ddrclk *ddrclk;
112 struct clk_init_data init;
113 struct clk *clk;
114
115 ddrclk = kzalloc(sizeof(*ddrclk), GFP_KERNEL);
116 if (!ddrclk)
117 return ERR_PTR(-ENOMEM);
118
119 init.name = name;
120 init.parent_names = parent_names;
121 init.num_parents = num_parents;
122
123 init.flags = flags;
124 init.flags |= CLK_SET_RATE_NO_REPARENT;
125
126 switch (ddr_flag) {
127 case ROCKCHIP_DDRCLK_SIP:
128 init.ops = &rockchip_ddrclk_sip_ops;
129 break;
130 default:
131 pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag);
132 kfree(ddrclk);
133 return ERR_PTR(-EINVAL);
134 }
135
136 ddrclk->reg_base = reg_base;
137 ddrclk->lock = lock;
138 ddrclk->hw.init = &init;
139 ddrclk->mux_offset = mux_offset;
140 ddrclk->mux_shift = mux_shift;
141 ddrclk->mux_width = mux_width;
142 ddrclk->div_shift = div_shift;
143 ddrclk->div_width = div_width;
144 ddrclk->ddr_flag = ddr_flag;
145
146 clk = clk_register(NULL, &ddrclk->hw);
147 if (IS_ERR(clk)) {
148 pr_err("%s: could not register ddrclk %s\n", __func__, name);
149 kfree(ddrclk);
150 return NULL;
151 }
152
153 return clk;
154}
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index db81e454166b..9c1373e81683 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -837,7 +837,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
837 u8 num_parents, int con_offset, int grf_lock_offset, 837 u8 num_parents, int con_offset, int grf_lock_offset,
838 int lock_shift, int mode_offset, int mode_shift, 838 int lock_shift, int mode_offset, int mode_shift,
839 struct rockchip_pll_rate_table *rate_table, 839 struct rockchip_pll_rate_table *rate_table,
840 u8 clk_pll_flags) 840 unsigned long flags, u8 clk_pll_flags)
841{ 841{
842 const char *pll_parents[3]; 842 const char *pll_parents[3];
843 struct clk_init_data init; 843 struct clk_init_data init;
@@ -892,7 +892,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
892 init.name = pll_name; 892 init.name = pll_name;
893 893
894 /* keep all plls untouched for now */ 894 /* keep all plls untouched for now */
895 init.flags = CLK_IGNORE_UNUSED; 895 init.flags = flags | CLK_IGNORE_UNUSED;
896 896
897 init.parent_names = &parent_names[0]; 897 init.parent_names = &parent_names[0];
898 init.num_parents = 1; 898 init.num_parents = 1;
diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c
index cdfabeb9a034..8387c7a40bda 100644
--- a/drivers/clk/rockchip/clk-rk3399.c
+++ b/drivers/clk/rockchip/clk-rk3399.c
@@ -100,8 +100,10 @@ static struct rockchip_pll_rate_table rk3399_pll_rates[] = {
100 RK3036_PLL_RATE( 297000000, 1, 99, 4, 2, 1, 0), 100 RK3036_PLL_RATE( 297000000, 1, 99, 4, 2, 1, 0),
101 RK3036_PLL_RATE( 216000000, 1, 72, 4, 2, 1, 0), 101 RK3036_PLL_RATE( 216000000, 1, 72, 4, 2, 1, 0),
102 RK3036_PLL_RATE( 148500000, 1, 99, 4, 4, 1, 0), 102 RK3036_PLL_RATE( 148500000, 1, 99, 4, 4, 1, 0),
103 RK3036_PLL_RATE( 106500000, 1, 71, 4, 4, 1, 0),
103 RK3036_PLL_RATE( 96000000, 1, 64, 4, 4, 1, 0), 104 RK3036_PLL_RATE( 96000000, 1, 64, 4, 4, 1, 0),
104 RK3036_PLL_RATE( 74250000, 2, 99, 4, 4, 1, 0), 105 RK3036_PLL_RATE( 74250000, 2, 99, 4, 4, 1, 0),
106 RK3036_PLL_RATE( 65000000, 1, 65, 6, 4, 1, 0),
105 RK3036_PLL_RATE( 54000000, 1, 54, 6, 4, 1, 0), 107 RK3036_PLL_RATE( 54000000, 1, 54, 6, 4, 1, 0),
106 RK3036_PLL_RATE( 27000000, 1, 27, 6, 4, 1, 0), 108 RK3036_PLL_RATE( 27000000, 1, 27, 6, 4, 1, 0),
107 { /* sentinel */ }, 109 { /* sentinel */ },
@@ -118,6 +120,10 @@ PNAME(mux_armclkb_p) = { "clk_core_b_lpll_src",
118 "clk_core_b_bpll_src", 120 "clk_core_b_bpll_src",
119 "clk_core_b_dpll_src", 121 "clk_core_b_dpll_src",
120 "clk_core_b_gpll_src" }; 122 "clk_core_b_gpll_src" };
123PNAME(mux_ddrclk_p) = { "clk_ddrc_lpll_src",
124 "clk_ddrc_bpll_src",
125 "clk_ddrc_dpll_src",
126 "clk_ddrc_gpll_src" };
121PNAME(mux_aclk_cci_p) = { "cpll_aclk_cci_src", 127PNAME(mux_aclk_cci_p) = { "cpll_aclk_cci_src",
122 "gpll_aclk_cci_src", 128 "gpll_aclk_cci_src",
123 "npll_aclk_cci_src", 129 "npll_aclk_cci_src",
@@ -373,6 +379,7 @@ static struct rockchip_cpuclk_rate_table rk3399_cpuclkb_rates[] __initdata = {
373 RK3399_CPUCLKB_RATE(2184000000, 1, 11, 11), 379 RK3399_CPUCLKB_RATE(2184000000, 1, 11, 11),
374 RK3399_CPUCLKB_RATE(2088000000, 1, 10, 10), 380 RK3399_CPUCLKB_RATE(2088000000, 1, 10, 10),
375 RK3399_CPUCLKB_RATE(2040000000, 1, 10, 10), 381 RK3399_CPUCLKB_RATE(2040000000, 1, 10, 10),
382 RK3399_CPUCLKB_RATE(2016000000, 1, 9, 9),
376 RK3399_CPUCLKB_RATE(1992000000, 1, 9, 9), 383 RK3399_CPUCLKB_RATE(1992000000, 1, 9, 9),
377 RK3399_CPUCLKB_RATE(1896000000, 1, 9, 9), 384 RK3399_CPUCLKB_RATE(1896000000, 1, 9, 9),
378 RK3399_CPUCLKB_RATE(1800000000, 1, 8, 8), 385 RK3399_CPUCLKB_RATE(1800000000, 1, 8, 8),
@@ -578,7 +585,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
578 COMPOSITE(0, "clk_spdif_div", mux_pll_src_cpll_gpll_p, 0, 585 COMPOSITE(0, "clk_spdif_div", mux_pll_src_cpll_gpll_p, 0,
579 RK3399_CLKSEL_CON(32), 7, 1, MFLAGS, 0, 7, DFLAGS, 586 RK3399_CLKSEL_CON(32), 7, 1, MFLAGS, 0, 7, DFLAGS,
580 RK3399_CLKGATE_CON(8), 13, GFLAGS), 587 RK3399_CLKGATE_CON(8), 13, GFLAGS),
581 COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", CLK_SET_RATE_PARENT, 588 COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", 0,
582 RK3399_CLKSEL_CON(99), 0, 589 RK3399_CLKSEL_CON(99), 0,
583 RK3399_CLKGATE_CON(8), 14, GFLAGS, 590 RK3399_CLKGATE_CON(8), 14, GFLAGS,
584 &rk3399_spdif_fracmux), 591 &rk3399_spdif_fracmux),
@@ -592,7 +599,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
592 COMPOSITE(0, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, 0, 599 COMPOSITE(0, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, 0,
593 RK3399_CLKSEL_CON(28), 7, 1, MFLAGS, 0, 7, DFLAGS, 600 RK3399_CLKSEL_CON(28), 7, 1, MFLAGS, 0, 7, DFLAGS,
594 RK3399_CLKGATE_CON(8), 3, GFLAGS), 601 RK3399_CLKGATE_CON(8), 3, GFLAGS),
595 COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", CLK_SET_RATE_PARENT, 602 COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", 0,
596 RK3399_CLKSEL_CON(96), 0, 603 RK3399_CLKSEL_CON(96), 0,
597 RK3399_CLKGATE_CON(8), 4, GFLAGS, 604 RK3399_CLKGATE_CON(8), 4, GFLAGS,
598 &rk3399_i2s0_fracmux), 605 &rk3399_i2s0_fracmux),
@@ -602,7 +609,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
602 COMPOSITE(0, "clk_i2s1_div", mux_pll_src_cpll_gpll_p, 0, 609 COMPOSITE(0, "clk_i2s1_div", mux_pll_src_cpll_gpll_p, 0,
603 RK3399_CLKSEL_CON(29), 7, 1, MFLAGS, 0, 7, DFLAGS, 610 RK3399_CLKSEL_CON(29), 7, 1, MFLAGS, 0, 7, DFLAGS,
604 RK3399_CLKGATE_CON(8), 6, GFLAGS), 611 RK3399_CLKGATE_CON(8), 6, GFLAGS),
605 COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", CLK_SET_RATE_PARENT, 612 COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", 0,
606 RK3399_CLKSEL_CON(97), 0, 613 RK3399_CLKSEL_CON(97), 0,
607 RK3399_CLKGATE_CON(8), 7, GFLAGS, 614 RK3399_CLKGATE_CON(8), 7, GFLAGS,
608 &rk3399_i2s1_fracmux), 615 &rk3399_i2s1_fracmux),
@@ -612,7 +619,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
612 COMPOSITE(0, "clk_i2s2_div", mux_pll_src_cpll_gpll_p, 0, 619 COMPOSITE(0, "clk_i2s2_div", mux_pll_src_cpll_gpll_p, 0,
613 RK3399_CLKSEL_CON(30), 7, 1, MFLAGS, 0, 7, DFLAGS, 620 RK3399_CLKSEL_CON(30), 7, 1, MFLAGS, 0, 7, DFLAGS,
614 RK3399_CLKGATE_CON(8), 9, GFLAGS), 621 RK3399_CLKGATE_CON(8), 9, GFLAGS),
615 COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", CLK_SET_RATE_PARENT, 622 COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", 0,
616 RK3399_CLKSEL_CON(98), 0, 623 RK3399_CLKSEL_CON(98), 0,
617 RK3399_CLKGATE_CON(8), 10, GFLAGS, 624 RK3399_CLKGATE_CON(8), 10, GFLAGS,
618 &rk3399_i2s2_fracmux), 625 &rk3399_i2s2_fracmux),
@@ -631,7 +638,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
631 COMPOSITE_NOMUX(0, "clk_uart0_div", "clk_uart0_src", 0, 638 COMPOSITE_NOMUX(0, "clk_uart0_div", "clk_uart0_src", 0,
632 RK3399_CLKSEL_CON(33), 0, 7, DFLAGS, 639 RK3399_CLKSEL_CON(33), 0, 7, DFLAGS,
633 RK3399_CLKGATE_CON(9), 0, GFLAGS), 640 RK3399_CLKGATE_CON(9), 0, GFLAGS),
634 COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", CLK_SET_RATE_PARENT, 641 COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", 0,
635 RK3399_CLKSEL_CON(100), 0, 642 RK3399_CLKSEL_CON(100), 0,
636 RK3399_CLKGATE_CON(9), 1, GFLAGS, 643 RK3399_CLKGATE_CON(9), 1, GFLAGS,
637 &rk3399_uart0_fracmux), 644 &rk3399_uart0_fracmux),
@@ -641,7 +648,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
641 COMPOSITE_NOMUX(0, "clk_uart1_div", "clk_uart_src", 0, 648 COMPOSITE_NOMUX(0, "clk_uart1_div", "clk_uart_src", 0,
642 RK3399_CLKSEL_CON(34), 0, 7, DFLAGS, 649 RK3399_CLKSEL_CON(34), 0, 7, DFLAGS,
643 RK3399_CLKGATE_CON(9), 2, GFLAGS), 650 RK3399_CLKGATE_CON(9), 2, GFLAGS),
644 COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", CLK_SET_RATE_PARENT, 651 COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", 0,
645 RK3399_CLKSEL_CON(101), 0, 652 RK3399_CLKSEL_CON(101), 0,
646 RK3399_CLKGATE_CON(9), 3, GFLAGS, 653 RK3399_CLKGATE_CON(9), 3, GFLAGS,
647 &rk3399_uart1_fracmux), 654 &rk3399_uart1_fracmux),
@@ -649,7 +656,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
649 COMPOSITE_NOMUX(0, "clk_uart2_div", "clk_uart_src", 0, 656 COMPOSITE_NOMUX(0, "clk_uart2_div", "clk_uart_src", 0,
650 RK3399_CLKSEL_CON(35), 0, 7, DFLAGS, 657 RK3399_CLKSEL_CON(35), 0, 7, DFLAGS,
651 RK3399_CLKGATE_CON(9), 4, GFLAGS), 658 RK3399_CLKGATE_CON(9), 4, GFLAGS),
652 COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", CLK_SET_RATE_PARENT, 659 COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", 0,
653 RK3399_CLKSEL_CON(102), 0, 660 RK3399_CLKSEL_CON(102), 0,
654 RK3399_CLKGATE_CON(9), 5, GFLAGS, 661 RK3399_CLKGATE_CON(9), 5, GFLAGS,
655 &rk3399_uart2_fracmux), 662 &rk3399_uart2_fracmux),
@@ -657,7 +664,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
657 COMPOSITE_NOMUX(0, "clk_uart3_div", "clk_uart_src", 0, 664 COMPOSITE_NOMUX(0, "clk_uart3_div", "clk_uart_src", 0,
658 RK3399_CLKSEL_CON(36), 0, 7, DFLAGS, 665 RK3399_CLKSEL_CON(36), 0, 7, DFLAGS,
659 RK3399_CLKGATE_CON(9), 6, GFLAGS), 666 RK3399_CLKGATE_CON(9), 6, GFLAGS),
660 COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_div", CLK_SET_RATE_PARENT, 667 COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_div", 0,
661 RK3399_CLKSEL_CON(103), 0, 668 RK3399_CLKSEL_CON(103), 0,
662 RK3399_CLKGATE_CON(9), 7, GFLAGS, 669 RK3399_CLKGATE_CON(9), 7, GFLAGS,
663 &rk3399_uart3_fracmux), 670 &rk3399_uart3_fracmux),
@@ -846,9 +853,9 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
846 RK3399_CLKSEL_CON(14), 12, 2, DFLAGS, 853 RK3399_CLKSEL_CON(14), 12, 2, DFLAGS,
847 RK3399_CLKGATE_CON(5), 4, GFLAGS), 854 RK3399_CLKGATE_CON(5), 4, GFLAGS),
848 855
849 GATE(ACLK_PERF_PCIE, "aclk_perf_pcie", "aclk_perihp", CLK_IGNORE_UNUSED, 856 GATE(ACLK_PERF_PCIE, "aclk_perf_pcie", "aclk_perihp", 0,
850 RK3399_CLKGATE_CON(20), 2, GFLAGS), 857 RK3399_CLKGATE_CON(20), 2, GFLAGS),
851 GATE(ACLK_PCIE, "aclk_pcie", "aclk_perihp", CLK_IGNORE_UNUSED, 858 GATE(ACLK_PCIE, "aclk_pcie", "aclk_perihp", 0,
852 RK3399_CLKGATE_CON(20), 10, GFLAGS), 859 RK3399_CLKGATE_CON(20), 10, GFLAGS),
853 GATE(0, "aclk_perihp_noc", "aclk_perihp", CLK_IGNORE_UNUSED, 860 GATE(0, "aclk_perihp_noc", "aclk_perihp", CLK_IGNORE_UNUSED,
854 RK3399_CLKGATE_CON(20), 12, GFLAGS), 861 RK3399_CLKGATE_CON(20), 12, GFLAGS),
@@ -1161,7 +1168,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
1161 RK3399_CLKSEL_CON(49), 8, 2, MFLAGS, 0, 8, DFLAGS, 1168 RK3399_CLKSEL_CON(49), 8, 2, MFLAGS, 0, 8, DFLAGS,
1162 RK3399_CLKGATE_CON(10), 12, GFLAGS), 1169 RK3399_CLKGATE_CON(10), 12, GFLAGS),
1163 1170
1164 COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop0_frac", "dclk_vop0_div", CLK_SET_RATE_PARENT, 1171 COMPOSITE_FRACMUX_NOGATE(DCLK_VOP0_FRAC, "dclk_vop0_frac", "dclk_vop0_div", 0,
1165 RK3399_CLKSEL_CON(106), 0, 1172 RK3399_CLKSEL_CON(106), 0,
1166 &rk3399_dclk_vop0_fracmux), 1173 &rk3399_dclk_vop0_fracmux),
1167 1174
@@ -1191,7 +1198,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
1191 RK3399_CLKSEL_CON(50), 8, 2, MFLAGS, 0, 8, DFLAGS, 1198 RK3399_CLKSEL_CON(50), 8, 2, MFLAGS, 0, 8, DFLAGS,
1192 RK3399_CLKGATE_CON(10), 13, GFLAGS), 1199 RK3399_CLKGATE_CON(10), 13, GFLAGS),
1193 1200
1194 COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop1_frac", "dclk_vop1_div", CLK_SET_RATE_PARENT, 1201 COMPOSITE_FRACMUX_NOGATE(DCLK_VOP1_FRAC, "dclk_vop1_frac", "dclk_vop1_div", 0,
1195 RK3399_CLKSEL_CON(107), 0, 1202 RK3399_CLKSEL_CON(107), 0,
1196 &rk3399_dclk_vop1_fracmux), 1203 &rk3399_dclk_vop1_fracmux),
1197 1204
@@ -1305,7 +1312,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
1305 /* testout */ 1312 /* testout */
1306 MUX(0, "clk_test_pre", mux_pll_src_cpll_gpll_p, CLK_SET_RATE_PARENT, 1313 MUX(0, "clk_test_pre", mux_pll_src_cpll_gpll_p, CLK_SET_RATE_PARENT,
1307 RK3399_CLKSEL_CON(58), 7, 1, MFLAGS), 1314 RK3399_CLKSEL_CON(58), 7, 1, MFLAGS),
1308 COMPOSITE_FRAC(0, "clk_test_frac", "clk_test_pre", CLK_SET_RATE_PARENT, 1315 COMPOSITE_FRAC(0, "clk_test_frac", "clk_test_pre", 0,
1309 RK3399_CLKSEL_CON(105), 0, 1316 RK3399_CLKSEL_CON(105), 0,
1310 RK3399_CLKGATE_CON(13), 9, GFLAGS), 1317 RK3399_CLKGATE_CON(13), 9, GFLAGS),
1311 1318
@@ -1377,6 +1384,18 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
1377 COMPOSITE_NOMUX(0, "clk_test", "clk_test_pre", CLK_IGNORE_UNUSED, 1384 COMPOSITE_NOMUX(0, "clk_test", "clk_test_pre", CLK_IGNORE_UNUSED,
1378 RK3368_CLKSEL_CON(58), 0, 5, DFLAGS, 1385 RK3368_CLKSEL_CON(58), 0, 5, DFLAGS,
1379 RK3368_CLKGATE_CON(13), 11, GFLAGS), 1386 RK3368_CLKGATE_CON(13), 11, GFLAGS),
1387
1388 /* ddrc */
1389 GATE(0, "clk_ddrc_lpll_src", "lpll", 0, RK3399_CLKGATE_CON(3),
1390 0, GFLAGS),
1391 GATE(0, "clk_ddrc_bpll_src", "bpll", 0, RK3399_CLKGATE_CON(3),
1392 1, GFLAGS),
1393 GATE(0, "clk_ddrc_dpll_src", "dpll", 0, RK3399_CLKGATE_CON(3),
1394 2, GFLAGS),
1395 GATE(0, "clk_ddrc_gpll_src", "gpll", 0, RK3399_CLKGATE_CON(3),
1396 3, GFLAGS),
1397 COMPOSITE_DDRCLK(SCLK_DDRC, "sclk_ddrc", mux_ddrclk_p, 0,
1398 RK3399_CLKSEL_CON(6), 4, 2, 0, 0, ROCKCHIP_DDRCLK_SIP),
1380}; 1399};
1381 1400
1382static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = { 1401static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
@@ -1398,7 +1417,7 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
1398 RK3399_PMU_CLKSEL_CON(1), 13, 1, MFLAGS, 8, 5, DFLAGS, 1417 RK3399_PMU_CLKSEL_CON(1), 13, 1, MFLAGS, 8, 5, DFLAGS,
1399 RK3399_PMU_CLKGATE_CON(0), 8, GFLAGS), 1418 RK3399_PMU_CLKGATE_CON(0), 8, GFLAGS),
1400 1419
1401 COMPOSITE_FRACMUX_NOGATE(0, "clk_wifi_frac", "clk_wifi_div", CLK_SET_RATE_PARENT, 1420 COMPOSITE_FRACMUX_NOGATE(0, "clk_wifi_frac", "clk_wifi_div", 0,
1402 RK3399_PMU_CLKSEL_CON(7), 0, 1421 RK3399_PMU_CLKSEL_CON(7), 0,
1403 &rk3399_pmuclk_wifi_fracmux), 1422 &rk3399_pmuclk_wifi_fracmux),
1404 1423
@@ -1426,7 +1445,7 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
1426 RK3399_PMU_CLKSEL_CON(5), 10, 1, MFLAGS, 0, 7, DFLAGS, 1445 RK3399_PMU_CLKSEL_CON(5), 10, 1, MFLAGS, 0, 7, DFLAGS,
1427 RK3399_PMU_CLKGATE_CON(0), 5, GFLAGS), 1446 RK3399_PMU_CLKGATE_CON(0), 5, GFLAGS),
1428 1447
1429 COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_div", CLK_SET_RATE_PARENT, 1448 COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_div", 0,
1430 RK3399_PMU_CLKSEL_CON(6), 0, 1449 RK3399_PMU_CLKSEL_CON(6), 0,
1431 RK3399_PMU_CLKGATE_CON(0), 6, GFLAGS, 1450 RK3399_PMU_CLKGATE_CON(0), 6, GFLAGS,
1432 &rk3399_uart4_pmu_fracmux), 1451 &rk3399_uart4_pmu_fracmux),
@@ -1468,6 +1487,9 @@ static const char *const rk3399_cru_critical_clocks[] __initconst = {
1468 "aclk_cci_pre", 1487 "aclk_cci_pre",
1469 "aclk_gic", 1488 "aclk_gic",
1470 "aclk_gic_noc", 1489 "aclk_gic_noc",
1490 "aclk_hdcp_noc",
1491 "hclk_hdcp_noc",
1492 "pclk_hdcp_noc",
1471 "pclk_perilp0", 1493 "pclk_perilp0",
1472 "pclk_perilp0", 1494 "pclk_perilp0",
1473 "hclk_perilp0", 1495 "hclk_perilp0",
@@ -1488,6 +1510,10 @@ static const char *const rk3399_cru_critical_clocks[] __initconst = {
1488 "gpll_hclk_perilp1_src", 1510 "gpll_hclk_perilp1_src",
1489 "gpll_aclk_perilp0_src", 1511 "gpll_aclk_perilp0_src",
1490 "gpll_aclk_perihp_src", 1512 "gpll_aclk_perihp_src",
1513 "aclk_vio_noc",
1514
1515 /* ddrc */
1516 "sclk_ddrc"
1491}; 1517};
1492 1518
1493static const char *const rk3399_pmucru_critical_clocks[] __initconst = { 1519static const char *const rk3399_pmucru_critical_clocks[] __initconst = {
diff --git a/drivers/clk/rockchip/clk-rockchip.c b/drivers/clk/rockchip/clk-rockchip.c
index 4cf838d52ef6..2c9bb81144c9 100644
--- a/drivers/clk/rockchip/clk-rockchip.c
+++ b/drivers/clk/rockchip/clk-rockchip.c
@@ -49,14 +49,19 @@ static void __init rk2928_gate_clk_init(struct device_node *node)
49 } 49 }
50 50
51 reg = of_iomap(node, 0); 51 reg = of_iomap(node, 0);
52 if (!reg)
53 return;
52 54
53 clk_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); 55 clk_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
54 if (!clk_data) 56 if (!clk_data) {
57 iounmap(reg);
55 return; 58 return;
59 }
56 60
57 clk_data->clks = kzalloc(qty * sizeof(struct clk *), GFP_KERNEL); 61 clk_data->clks = kzalloc(qty * sizeof(struct clk *), GFP_KERNEL);
58 if (!clk_data->clks) { 62 if (!clk_data->clks) {
59 kfree(clk_data); 63 kfree(clk_data);
64 iounmap(reg);
60 return; 65 return;
61 } 66 }
62 67
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 7ffd134995f2..b886be30f34f 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -385,7 +385,7 @@ void __init rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
385 list->con_offset, grf_lock_offset, 385 list->con_offset, grf_lock_offset,
386 list->lock_shift, list->mode_offset, 386 list->lock_shift, list->mode_offset,
387 list->mode_shift, list->rate_table, 387 list->mode_shift, list->rate_table,
388 list->pll_flags); 388 list->flags, list->pll_flags);
389 if (IS_ERR(clk)) { 389 if (IS_ERR(clk)) {
390 pr_err("%s: failed to register clock %s\n", __func__, 390 pr_err("%s: failed to register clock %s\n", __func__,
391 list->name); 391 list->name);
@@ -484,6 +484,15 @@ void __init rockchip_clk_register_branches(
484 list->gate_offset, list->gate_shift, 484 list->gate_offset, list->gate_shift,
485 list->gate_flags, flags, &ctx->lock); 485 list->gate_flags, flags, &ctx->lock);
486 break; 486 break;
487 case branch_ddrclk:
488 clk = rockchip_clk_register_ddrclk(
489 list->name, list->flags,
490 list->parent_names, list->num_parents,
491 list->muxdiv_offset, list->mux_shift,
492 list->mux_width, list->div_shift,
493 list->div_width, list->div_flags,
494 ctx->reg_base, &ctx->lock);
495 break;
487 } 496 }
488 497
489 /* none of the cases above matched */ 498 /* none of the cases above matched */
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 2194ffa8c9fd..1653edd792a5 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -238,7 +238,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
238 u8 num_parents, int con_offset, int grf_lock_offset, 238 u8 num_parents, int con_offset, int grf_lock_offset,
239 int lock_shift, int mode_offset, int mode_shift, 239 int lock_shift, int mode_offset, int mode_shift,
240 struct rockchip_pll_rate_table *rate_table, 240 struct rockchip_pll_rate_table *rate_table,
241 u8 clk_pll_flags); 241 unsigned long flags, u8 clk_pll_flags);
242 242
243struct rockchip_cpuclk_clksel { 243struct rockchip_cpuclk_clksel {
244 int reg; 244 int reg;
@@ -281,6 +281,20 @@ struct clk *rockchip_clk_register_mmc(const char *name,
281 const char *const *parent_names, u8 num_parents, 281 const char *const *parent_names, u8 num_parents,
282 void __iomem *reg, int shift); 282 void __iomem *reg, int shift);
283 283
284/*
285 * DDRCLK flags, including method of setting the rate
286 * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate.
287 */
288#define ROCKCHIP_DDRCLK_SIP BIT(0)
289
290struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
291 const char *const *parent_names,
292 u8 num_parents, int mux_offset,
293 int mux_shift, int mux_width,
294 int div_shift, int div_width,
295 int ddr_flags, void __iomem *reg_base,
296 spinlock_t *lock);
297
284#define ROCKCHIP_INVERTER_HIWORD_MASK BIT(0) 298#define ROCKCHIP_INVERTER_HIWORD_MASK BIT(0)
285 299
286struct clk *rockchip_clk_register_inverter(const char *name, 300struct clk *rockchip_clk_register_inverter(const char *name,
@@ -299,6 +313,7 @@ enum rockchip_clk_branch_type {
299 branch_mmc, 313 branch_mmc,
300 branch_inverter, 314 branch_inverter,
301 branch_factor, 315 branch_factor,
316 branch_ddrclk,
302}; 317};
303 318
304struct rockchip_clk_branch { 319struct rockchip_clk_branch {
@@ -488,6 +503,24 @@ struct rockchip_clk_branch {
488 .child = ch, \ 503 .child = ch, \
489 } 504 }
490 505
506#define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw, \
507 ds, dw, df) \
508 { \
509 .id = _id, \
510 .branch_type = branch_ddrclk, \
511 .name = cname, \
512 .parent_names = pnames, \
513 .num_parents = ARRAY_SIZE(pnames), \
514 .flags = f, \
515 .muxdiv_offset = mo, \
516 .mux_shift = ms, \
517 .mux_width = mw, \
518 .div_shift = ds, \
519 .div_width = dw, \
520 .div_flags = df, \
521 .gate_offset = -1, \
522 }
523
491#define MUX(_id, cname, pnames, f, o, s, w, mf) \ 524#define MUX(_id, cname, pnames, f, o, s, w, mf) \
492 { \ 525 { \
493 .id = _id, \ 526 .id = _id, \
diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c
index bdf8b971f332..51d152f735cc 100644
--- a/drivers/clk/samsung/clk-exynos-audss.c
+++ b/drivers/clk/samsung/clk-exynos-audss.c
@@ -14,18 +14,13 @@
14#include <linux/clk.h> 14#include <linux/clk.h>
15#include <linux/clk-provider.h> 15#include <linux/clk-provider.h>
16#include <linux/of_address.h> 16#include <linux/of_address.h>
17#include <linux/of_device.h>
17#include <linux/syscore_ops.h> 18#include <linux/syscore_ops.h>
18#include <linux/module.h> 19#include <linux/module.h>
19#include <linux/platform_device.h> 20#include <linux/platform_device.h>
20 21
21#include <dt-bindings/clock/exynos-audss-clk.h> 22#include <dt-bindings/clock/exynos-audss-clk.h>
22 23
23enum exynos_audss_clk_type {
24 TYPE_EXYNOS4210,
25 TYPE_EXYNOS5250,
26 TYPE_EXYNOS5420,
27};
28
29static DEFINE_SPINLOCK(lock); 24static DEFINE_SPINLOCK(lock);
30static struct clk **clk_table; 25static struct clk **clk_table;
31static void __iomem *reg_base; 26static void __iomem *reg_base;
@@ -44,9 +39,9 @@ static struct clk *epll;
44 39
45#ifdef CONFIG_PM_SLEEP 40#ifdef CONFIG_PM_SLEEP
46static unsigned long reg_save[][2] = { 41static unsigned long reg_save[][2] = {
47 {ASS_CLK_SRC, 0}, 42 { ASS_CLK_SRC, 0 },
48 {ASS_CLK_DIV, 0}, 43 { ASS_CLK_DIV, 0 },
49 {ASS_CLK_GATE, 0}, 44 { ASS_CLK_GATE, 0 },
50}; 45};
51 46
52static int exynos_audss_clk_suspend(void) 47static int exynos_audss_clk_suspend(void)
@@ -73,14 +68,43 @@ static struct syscore_ops exynos_audss_clk_syscore_ops = {
73}; 68};
74#endif /* CONFIG_PM_SLEEP */ 69#endif /* CONFIG_PM_SLEEP */
75 70
71struct exynos_audss_clk_drvdata {
72 unsigned int has_adma_clk:1;
73 unsigned int has_mst_clk:1;
74 unsigned int enable_epll:1;
75 unsigned int num_clks;
76};
77
78static const struct exynos_audss_clk_drvdata exynos4210_drvdata = {
79 .num_clks = EXYNOS_AUDSS_MAX_CLKS - 1,
80};
81
82static const struct exynos_audss_clk_drvdata exynos5410_drvdata = {
83 .num_clks = EXYNOS_AUDSS_MAX_CLKS - 1,
84 .has_mst_clk = 1,
85};
86
87static const struct exynos_audss_clk_drvdata exynos5420_drvdata = {
88 .num_clks = EXYNOS_AUDSS_MAX_CLKS,
89 .has_adma_clk = 1,
90 .enable_epll = 1,
91};
92
76static const struct of_device_id exynos_audss_clk_of_match[] = { 93static const struct of_device_id exynos_audss_clk_of_match[] = {
77 { .compatible = "samsung,exynos4210-audss-clock", 94 {
78 .data = (void *)TYPE_EXYNOS4210, }, 95 .compatible = "samsung,exynos4210-audss-clock",
79 { .compatible = "samsung,exynos5250-audss-clock", 96 .data = &exynos4210_drvdata,
80 .data = (void *)TYPE_EXYNOS5250, }, 97 }, {
81 { .compatible = "samsung,exynos5420-audss-clock", 98 .compatible = "samsung,exynos5250-audss-clock",
82 .data = (void *)TYPE_EXYNOS5420, }, 99 .data = &exynos4210_drvdata,
83 {}, 100 }, {
101 .compatible = "samsung,exynos5410-audss-clock",
102 .data = &exynos5410_drvdata,
103 }, {
104 .compatible = "samsung,exynos5420-audss-clock",
105 .data = &exynos5420_drvdata,
106 },
107 { },
84}; 108};
85 109
86static void exynos_audss_clk_teardown(void) 110static void exynos_audss_clk_teardown(void)
@@ -106,19 +130,17 @@ static void exynos_audss_clk_teardown(void)
106/* register exynos_audss clocks */ 130/* register exynos_audss clocks */
107static int exynos_audss_clk_probe(struct platform_device *pdev) 131static int exynos_audss_clk_probe(struct platform_device *pdev)
108{ 132{
109 int i, ret = 0;
110 struct resource *res;
111 const char *mout_audss_p[] = {"fin_pll", "fout_epll"}; 133 const char *mout_audss_p[] = {"fin_pll", "fout_epll"};
112 const char *mout_i2s_p[] = {"mout_audss", "cdclk0", "sclk_audio0"}; 134 const char *mout_i2s_p[] = {"mout_audss", "cdclk0", "sclk_audio0"};
113 const char *sclk_pcm_p = "sclk_pcm0"; 135 const char *sclk_pcm_p = "sclk_pcm0";
114 struct clk *pll_ref, *pll_in, *cdclk, *sclk_audio, *sclk_pcm_in; 136 struct clk *pll_ref, *pll_in, *cdclk, *sclk_audio, *sclk_pcm_in;
115 const struct of_device_id *match; 137 const struct exynos_audss_clk_drvdata *variant;
116 enum exynos_audss_clk_type variant; 138 struct resource *res;
139 int i, ret = 0;
117 140
118 match = of_match_node(exynos_audss_clk_of_match, pdev->dev.of_node); 141 variant = of_device_get_match_data(&pdev->dev);
119 if (!match) 142 if (!variant)
120 return -EINVAL; 143 return -EINVAL;
121 variant = (enum exynos_audss_clk_type)match->data;
122 144
123 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 145 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
124 reg_base = devm_ioremap_resource(&pdev->dev, res); 146 reg_base = devm_ioremap_resource(&pdev->dev, res);
@@ -126,7 +148,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
126 dev_err(&pdev->dev, "failed to map audss registers\n"); 148 dev_err(&pdev->dev, "failed to map audss registers\n");
127 return PTR_ERR(reg_base); 149 return PTR_ERR(reg_base);
128 } 150 }
129 /* EPLL don't have to be enabled for boards other than Exynos5420 */ 151
130 epll = ERR_PTR(-ENODEV); 152 epll = ERR_PTR(-ENODEV);
131 153
132 clk_table = devm_kzalloc(&pdev->dev, 154 clk_table = devm_kzalloc(&pdev->dev,
@@ -136,10 +158,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
136 return -ENOMEM; 158 return -ENOMEM;
137 159
138 clk_data.clks = clk_table; 160 clk_data.clks = clk_table;
139 if (variant == TYPE_EXYNOS5420) 161 clk_data.clk_num = variant->num_clks;
140 clk_data.clk_num = EXYNOS_AUDSS_MAX_CLKS;
141 else
142 clk_data.clk_num = EXYNOS_AUDSS_MAX_CLKS - 1;
143 162
144 pll_ref = devm_clk_get(&pdev->dev, "pll_ref"); 163 pll_ref = devm_clk_get(&pdev->dev, "pll_ref");
145 pll_in = devm_clk_get(&pdev->dev, "pll_in"); 164 pll_in = devm_clk_get(&pdev->dev, "pll_in");
@@ -148,13 +167,13 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
148 if (!IS_ERR(pll_in)) { 167 if (!IS_ERR(pll_in)) {
149 mout_audss_p[1] = __clk_get_name(pll_in); 168 mout_audss_p[1] = __clk_get_name(pll_in);
150 169
151 if (variant == TYPE_EXYNOS5420) { 170 if (variant->enable_epll) {
152 epll = pll_in; 171 epll = pll_in;
153 172
154 ret = clk_prepare_enable(epll); 173 ret = clk_prepare_enable(epll);
155 if (ret) { 174 if (ret) {
156 dev_err(&pdev->dev, 175 dev_err(&pdev->dev,
157 "failed to prepare the epll clock\n"); 176 "failed to prepare the epll clock\n");
158 return ret; 177 return ret;
159 } 178 }
160 } 179 }
@@ -210,7 +229,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
210 sclk_pcm_p, CLK_SET_RATE_PARENT, 229 sclk_pcm_p, CLK_SET_RATE_PARENT,
211 reg_base + ASS_CLK_GATE, 5, 0, &lock); 230 reg_base + ASS_CLK_GATE, 5, 0, &lock);
212 231
213 if (variant == TYPE_EXYNOS5420) { 232 if (variant->has_adma_clk) {
214 clk_table[EXYNOS_ADMA] = clk_register_gate(NULL, "adma", 233 clk_table[EXYNOS_ADMA] = clk_register_gate(NULL, "adma",
215 "dout_srp", CLK_SET_RATE_PARENT, 234 "dout_srp", CLK_SET_RATE_PARENT,
216 reg_base + ASS_CLK_GATE, 9, 0, &lock); 235 reg_base + ASS_CLK_GATE, 9, 0, &lock);
@@ -234,9 +253,6 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
234#ifdef CONFIG_PM_SLEEP 253#ifdef CONFIG_PM_SLEEP
235 register_syscore_ops(&exynos_audss_clk_syscore_ops); 254 register_syscore_ops(&exynos_audss_clk_syscore_ops);
236#endif 255#endif
237
238 dev_info(&pdev->dev, "setup completed\n");
239
240 return 0; 256 return 0;
241 257
242unregister: 258unregister:
diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c
index a43642c36039..fd1d9bfc151b 100644
--- a/drivers/clk/samsung/clk-exynos5260.c
+++ b/drivers/clk/samsung/clk-exynos5260.c
@@ -131,21 +131,21 @@ static const struct samsung_gate_clock aud_gate_clks[] __initconst = {
131 EN_IP_AUD, 4, 0, 0), 131 EN_IP_AUD, 4, 0, 0),
132}; 132};
133 133
134static const struct samsung_cmu_info aud_cmu __initconst = {
135 .mux_clks = aud_mux_clks,
136 .nr_mux_clks = ARRAY_SIZE(aud_mux_clks),
137 .div_clks = aud_div_clks,
138 .nr_div_clks = ARRAY_SIZE(aud_div_clks),
139 .gate_clks = aud_gate_clks,
140 .nr_gate_clks = ARRAY_SIZE(aud_gate_clks),
141 .nr_clk_ids = AUD_NR_CLK,
142 .clk_regs = aud_clk_regs,
143 .nr_clk_regs = ARRAY_SIZE(aud_clk_regs),
144};
145
134static void __init exynos5260_clk_aud_init(struct device_node *np) 146static void __init exynos5260_clk_aud_init(struct device_node *np)
135{ 147{
136 struct samsung_cmu_info cmu = { NULL }; 148 samsung_cmu_register_one(np, &aud_cmu);
137
138 cmu.mux_clks = aud_mux_clks;
139 cmu.nr_mux_clks = ARRAY_SIZE(aud_mux_clks);
140 cmu.div_clks = aud_div_clks;
141 cmu.nr_div_clks = ARRAY_SIZE(aud_div_clks);
142 cmu.gate_clks = aud_gate_clks;
143 cmu.nr_gate_clks = ARRAY_SIZE(aud_gate_clks);
144 cmu.nr_clk_ids = AUD_NR_CLK;
145 cmu.clk_regs = aud_clk_regs;
146 cmu.nr_clk_regs = ARRAY_SIZE(aud_clk_regs);
147
148 samsung_cmu_register_one(np, &cmu);
149} 149}
150 150
151CLK_OF_DECLARE(exynos5260_clk_aud, "samsung,exynos5260-clock-aud", 151CLK_OF_DECLARE(exynos5260_clk_aud, "samsung,exynos5260-clock-aud",
@@ -321,21 +321,21 @@ static const struct samsung_gate_clock disp_gate_clks[] __initconst = {
321 EN_IP_DISP, 25, 0, 0), 321 EN_IP_DISP, 25, 0, 0),
322}; 322};
323 323
324static const struct samsung_cmu_info disp_cmu __initconst = {
325 .mux_clks = disp_mux_clks,
326 .nr_mux_clks = ARRAY_SIZE(disp_mux_clks),
327 .div_clks = disp_div_clks,
328 .nr_div_clks = ARRAY_SIZE(disp_div_clks),
329 .gate_clks = disp_gate_clks,
330 .nr_gate_clks = ARRAY_SIZE(disp_gate_clks),
331 .nr_clk_ids = DISP_NR_CLK,
332 .clk_regs = disp_clk_regs,
333 .nr_clk_regs = ARRAY_SIZE(disp_clk_regs),
334};
335
324static void __init exynos5260_clk_disp_init(struct device_node *np) 336static void __init exynos5260_clk_disp_init(struct device_node *np)
325{ 337{
326 struct samsung_cmu_info cmu = { NULL }; 338 samsung_cmu_register_one(np, &disp_cmu);
327
328 cmu.mux_clks = disp_mux_clks;
329 cmu.nr_mux_clks = ARRAY_SIZE(disp_mux_clks);
330 cmu.div_clks = disp_div_clks;
331 cmu.nr_div_clks = ARRAY_SIZE(disp_div_clks);
332 cmu.gate_clks = disp_gate_clks;
333 cmu.nr_gate_clks = ARRAY_SIZE(disp_gate_clks);
334 cmu.nr_clk_ids = DISP_NR_CLK;
335 cmu.clk_regs = disp_clk_regs;
336 cmu.nr_clk_regs = ARRAY_SIZE(disp_clk_regs);
337
338 samsung_cmu_register_one(np, &cmu);
339} 339}
340 340
341CLK_OF_DECLARE(exynos5260_clk_disp, "samsung,exynos5260-clock-disp", 341CLK_OF_DECLARE(exynos5260_clk_disp, "samsung,exynos5260-clock-disp",
@@ -385,21 +385,21 @@ static const struct samsung_pll_clock egl_pll_clks[] __initconst = {
385 pll2550_24mhz_tbl), 385 pll2550_24mhz_tbl),
386}; 386};
387 387
388static const struct samsung_cmu_info egl_cmu __initconst = {
389 .pll_clks = egl_pll_clks,
390 .nr_pll_clks = ARRAY_SIZE(egl_pll_clks),
391 .mux_clks = egl_mux_clks,
392 .nr_mux_clks = ARRAY_SIZE(egl_mux_clks),
393 .div_clks = egl_div_clks,
394 .nr_div_clks = ARRAY_SIZE(egl_div_clks),
395 .nr_clk_ids = EGL_NR_CLK,
396 .clk_regs = egl_clk_regs,
397 .nr_clk_regs = ARRAY_SIZE(egl_clk_regs),
398};
399
388static void __init exynos5260_clk_egl_init(struct device_node *np) 400static void __init exynos5260_clk_egl_init(struct device_node *np)
389{ 401{
390 struct samsung_cmu_info cmu = { NULL }; 402 samsung_cmu_register_one(np, &egl_cmu);
391
392 cmu.pll_clks = egl_pll_clks;
393 cmu.nr_pll_clks = ARRAY_SIZE(egl_pll_clks);
394 cmu.mux_clks = egl_mux_clks;
395 cmu.nr_mux_clks = ARRAY_SIZE(egl_mux_clks);
396 cmu.div_clks = egl_div_clks;
397 cmu.nr_div_clks = ARRAY_SIZE(egl_div_clks);
398 cmu.nr_clk_ids = EGL_NR_CLK;
399 cmu.clk_regs = egl_clk_regs;
400 cmu.nr_clk_regs = ARRAY_SIZE(egl_clk_regs);
401
402 samsung_cmu_register_one(np, &cmu);
403} 403}
404 404
405CLK_OF_DECLARE(exynos5260_clk_egl, "samsung,exynos5260-clock-egl", 405CLK_OF_DECLARE(exynos5260_clk_egl, "samsung,exynos5260-clock-egl",
@@ -487,19 +487,19 @@ static const struct samsung_gate_clock fsys_gate_clks[] __initconst = {
487 EN_IP_FSYS_SECURE_SMMU_RTIC, 12, 0, 0), 487 EN_IP_FSYS_SECURE_SMMU_RTIC, 12, 0, 0),
488}; 488};
489 489
490static const struct samsung_cmu_info fsys_cmu __initconst = {
491 .mux_clks = fsys_mux_clks,
492 .nr_mux_clks = ARRAY_SIZE(fsys_mux_clks),
493 .gate_clks = fsys_gate_clks,
494 .nr_gate_clks = ARRAY_SIZE(fsys_gate_clks),
495 .nr_clk_ids = FSYS_NR_CLK,
496 .clk_regs = fsys_clk_regs,
497 .nr_clk_regs = ARRAY_SIZE(fsys_clk_regs),
498};
499
490static void __init exynos5260_clk_fsys_init(struct device_node *np) 500static void __init exynos5260_clk_fsys_init(struct device_node *np)
491{ 501{
492 struct samsung_cmu_info cmu = { NULL }; 502 samsung_cmu_register_one(np, &fsys_cmu);
493
494 cmu.mux_clks = fsys_mux_clks;
495 cmu.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks);
496 cmu.gate_clks = fsys_gate_clks;
497 cmu.nr_gate_clks = ARRAY_SIZE(fsys_gate_clks);
498 cmu.nr_clk_ids = FSYS_NR_CLK;
499 cmu.clk_regs = fsys_clk_regs;
500 cmu.nr_clk_regs = ARRAY_SIZE(fsys_clk_regs);
501
502 samsung_cmu_register_one(np, &cmu);
503} 503}
504 504
505CLK_OF_DECLARE(exynos5260_clk_fsys, "samsung,exynos5260-clock-fsys", 505CLK_OF_DECLARE(exynos5260_clk_fsys, "samsung,exynos5260-clock-fsys",
@@ -576,21 +576,21 @@ static const struct samsung_gate_clock g2d_gate_clks[] __initconst = {
576 EN_IP_G2D_SECURE_SMMU_G2D, 15, 0, 0), 576 EN_IP_G2D_SECURE_SMMU_G2D, 15, 0, 0),
577}; 577};
578 578
579static const struct samsung_cmu_info g2d_cmu __initconst = {
580 .mux_clks = g2d_mux_clks,
581 .nr_mux_clks = ARRAY_SIZE(g2d_mux_clks),
582 .div_clks = g2d_div_clks,
583 .nr_div_clks = ARRAY_SIZE(g2d_div_clks),
584 .gate_clks = g2d_gate_clks,
585 .nr_gate_clks = ARRAY_SIZE(g2d_gate_clks),
586 .nr_clk_ids = G2D_NR_CLK,
587 .clk_regs = g2d_clk_regs,
588 .nr_clk_regs = ARRAY_SIZE(g2d_clk_regs),
589};
590
579static void __init exynos5260_clk_g2d_init(struct device_node *np) 591static void __init exynos5260_clk_g2d_init(struct device_node *np)
580{ 592{
581 struct samsung_cmu_info cmu = { NULL }; 593 samsung_cmu_register_one(np, &g2d_cmu);
582
583 cmu.mux_clks = g2d_mux_clks;
584 cmu.nr_mux_clks = ARRAY_SIZE(g2d_mux_clks);
585 cmu.div_clks = g2d_div_clks;
586 cmu.nr_div_clks = ARRAY_SIZE(g2d_div_clks);
587 cmu.gate_clks = g2d_gate_clks;
588 cmu.nr_gate_clks = ARRAY_SIZE(g2d_gate_clks);
589 cmu.nr_clk_ids = G2D_NR_CLK;
590 cmu.clk_regs = g2d_clk_regs;
591 cmu.nr_clk_regs = ARRAY_SIZE(g2d_clk_regs);
592
593 samsung_cmu_register_one(np, &cmu);
594} 594}
595 595
596CLK_OF_DECLARE(exynos5260_clk_g2d, "samsung,exynos5260-clock-g2d", 596CLK_OF_DECLARE(exynos5260_clk_g2d, "samsung,exynos5260-clock-g2d",
@@ -637,23 +637,23 @@ static const struct samsung_pll_clock g3d_pll_clks[] __initconst = {
637 pll2550_24mhz_tbl), 637 pll2550_24mhz_tbl),
638}; 638};
639 639
640static const struct samsung_cmu_info g3d_cmu __initconst = {
641 .pll_clks = g3d_pll_clks,
642 .nr_pll_clks = ARRAY_SIZE(g3d_pll_clks),
643 .mux_clks = g3d_mux_clks,
644 .nr_mux_clks = ARRAY_SIZE(g3d_mux_clks),
645 .div_clks = g3d_div_clks,
646 .nr_div_clks = ARRAY_SIZE(g3d_div_clks),
647 .gate_clks = g3d_gate_clks,
648 .nr_gate_clks = ARRAY_SIZE(g3d_gate_clks),
649 .nr_clk_ids = G3D_NR_CLK,
650 .clk_regs = g3d_clk_regs,
651 .nr_clk_regs = ARRAY_SIZE(g3d_clk_regs),
652};
653
640static void __init exynos5260_clk_g3d_init(struct device_node *np) 654static void __init exynos5260_clk_g3d_init(struct device_node *np)
641{ 655{
642 struct samsung_cmu_info cmu = { NULL }; 656 samsung_cmu_register_one(np, &g3d_cmu);
643
644 cmu.pll_clks = g3d_pll_clks;
645 cmu.nr_pll_clks = ARRAY_SIZE(g3d_pll_clks);
646 cmu.mux_clks = g3d_mux_clks;
647 cmu.nr_mux_clks = ARRAY_SIZE(g3d_mux_clks);
648 cmu.div_clks = g3d_div_clks;
649 cmu.nr_div_clks = ARRAY_SIZE(g3d_div_clks);
650 cmu.gate_clks = g3d_gate_clks;
651 cmu.nr_gate_clks = ARRAY_SIZE(g3d_gate_clks);
652 cmu.nr_clk_ids = G3D_NR_CLK;
653 cmu.clk_regs = g3d_clk_regs;
654 cmu.nr_clk_regs = ARRAY_SIZE(g3d_clk_regs);
655
656 samsung_cmu_register_one(np, &cmu);
657} 657}
658 658
659CLK_OF_DECLARE(exynos5260_clk_g3d, "samsung,exynos5260-clock-g3d", 659CLK_OF_DECLARE(exynos5260_clk_g3d, "samsung,exynos5260-clock-g3d",
@@ -772,21 +772,21 @@ static const struct samsung_gate_clock gscl_gate_clks[] __initconst = {
772 EN_IP_GSCL_SECURE_SMMU_MSCL1, 20, 0, 0), 772 EN_IP_GSCL_SECURE_SMMU_MSCL1, 20, 0, 0),
773}; 773};
774 774
775static const struct samsung_cmu_info gscl_cmu __initconst = {
776 .mux_clks = gscl_mux_clks,
777 .nr_mux_clks = ARRAY_SIZE(gscl_mux_clks),
778 .div_clks = gscl_div_clks,
779 .nr_div_clks = ARRAY_SIZE(gscl_div_clks),
780 .gate_clks = gscl_gate_clks,
781 .nr_gate_clks = ARRAY_SIZE(gscl_gate_clks),
782 .nr_clk_ids = GSCL_NR_CLK,
783 .clk_regs = gscl_clk_regs,
784 .nr_clk_regs = ARRAY_SIZE(gscl_clk_regs),
785};
786
775static void __init exynos5260_clk_gscl_init(struct device_node *np) 787static void __init exynos5260_clk_gscl_init(struct device_node *np)
776{ 788{
777 struct samsung_cmu_info cmu = { NULL }; 789 samsung_cmu_register_one(np, &gscl_cmu);
778
779 cmu.mux_clks = gscl_mux_clks;
780 cmu.nr_mux_clks = ARRAY_SIZE(gscl_mux_clks);
781 cmu.div_clks = gscl_div_clks;
782 cmu.nr_div_clks = ARRAY_SIZE(gscl_div_clks);
783 cmu.gate_clks = gscl_gate_clks;
784 cmu.nr_gate_clks = ARRAY_SIZE(gscl_gate_clks);
785 cmu.nr_clk_ids = GSCL_NR_CLK;
786 cmu.clk_regs = gscl_clk_regs;
787 cmu.nr_clk_regs = ARRAY_SIZE(gscl_clk_regs);
788
789 samsung_cmu_register_one(np, &cmu);
790} 790}
791 791
792CLK_OF_DECLARE(exynos5260_clk_gscl, "samsung,exynos5260-clock-gscl", 792CLK_OF_DECLARE(exynos5260_clk_gscl, "samsung,exynos5260-clock-gscl",
@@ -891,21 +891,21 @@ static const struct samsung_gate_clock isp_gate_clks[] __initconst = {
891 EN_SCLK_ISP, 9, CLK_SET_RATE_PARENT, 0), 891 EN_SCLK_ISP, 9, CLK_SET_RATE_PARENT, 0),
892}; 892};
893 893
894static const struct samsung_cmu_info isp_cmu __initconst = {
895 .mux_clks = isp_mux_clks,
896 .nr_mux_clks = ARRAY_SIZE(isp_mux_clks),
897 .div_clks = isp_div_clks,
898 .nr_div_clks = ARRAY_SIZE(isp_div_clks),
899 .gate_clks = isp_gate_clks,
900 .nr_gate_clks = ARRAY_SIZE(isp_gate_clks),
901 .nr_clk_ids = ISP_NR_CLK,
902 .clk_regs = isp_clk_regs,
903 .nr_clk_regs = ARRAY_SIZE(isp_clk_regs),
904};
905
894static void __init exynos5260_clk_isp_init(struct device_node *np) 906static void __init exynos5260_clk_isp_init(struct device_node *np)
895{ 907{
896 struct samsung_cmu_info cmu = { NULL }; 908 samsung_cmu_register_one(np, &isp_cmu);
897
898 cmu.mux_clks = isp_mux_clks;
899 cmu.nr_mux_clks = ARRAY_SIZE(isp_mux_clks);
900 cmu.div_clks = isp_div_clks;
901 cmu.nr_div_clks = ARRAY_SIZE(isp_div_clks);
902 cmu.gate_clks = isp_gate_clks;
903 cmu.nr_gate_clks = ARRAY_SIZE(isp_gate_clks);
904 cmu.nr_clk_ids = ISP_NR_CLK;
905 cmu.clk_regs = isp_clk_regs;
906 cmu.nr_clk_regs = ARRAY_SIZE(isp_clk_regs);
907
908 samsung_cmu_register_one(np, &cmu);
909} 909}
910 910
911CLK_OF_DECLARE(exynos5260_clk_isp, "samsung,exynos5260-clock-isp", 911CLK_OF_DECLARE(exynos5260_clk_isp, "samsung,exynos5260-clock-isp",
@@ -955,21 +955,21 @@ static const struct samsung_pll_clock kfc_pll_clks[] __initconst = {
955 pll2550_24mhz_tbl), 955 pll2550_24mhz_tbl),
956}; 956};
957 957
958static const struct samsung_cmu_info kfc_cmu __initconst = {
959 .pll_clks = kfc_pll_clks,
960 .nr_pll_clks = ARRAY_SIZE(kfc_pll_clks),
961 .mux_clks = kfc_mux_clks,
962 .nr_mux_clks = ARRAY_SIZE(kfc_mux_clks),
963 .div_clks = kfc_div_clks,
964 .nr_div_clks = ARRAY_SIZE(kfc_div_clks),
965 .nr_clk_ids = KFC_NR_CLK,
966 .clk_regs = kfc_clk_regs,
967 .nr_clk_regs = ARRAY_SIZE(kfc_clk_regs),
968};
969
958static void __init exynos5260_clk_kfc_init(struct device_node *np) 970static void __init exynos5260_clk_kfc_init(struct device_node *np)
959{ 971{
960 struct samsung_cmu_info cmu = { NULL }; 972 samsung_cmu_register_one(np, &kfc_cmu);
961
962 cmu.pll_clks = kfc_pll_clks;
963 cmu.nr_pll_clks = ARRAY_SIZE(kfc_pll_clks);
964 cmu.mux_clks = kfc_mux_clks;
965 cmu.nr_mux_clks = ARRAY_SIZE(kfc_mux_clks);
966 cmu.div_clks = kfc_div_clks;
967 cmu.nr_div_clks = ARRAY_SIZE(kfc_div_clks);
968 cmu.nr_clk_ids = KFC_NR_CLK;
969 cmu.clk_regs = kfc_clk_regs;
970 cmu.nr_clk_regs = ARRAY_SIZE(kfc_clk_regs);
971
972 samsung_cmu_register_one(np, &cmu);
973} 973}
974 974
975CLK_OF_DECLARE(exynos5260_clk_kfc, "samsung,exynos5260-clock-kfc", 975CLK_OF_DECLARE(exynos5260_clk_kfc, "samsung,exynos5260-clock-kfc",
@@ -1011,21 +1011,21 @@ static const struct samsung_gate_clock mfc_gate_clks[] __initconst = {
1011 EN_IP_MFC_SECURE_SMMU2_MFC, 7, 0, 0), 1011 EN_IP_MFC_SECURE_SMMU2_MFC, 7, 0, 0),
1012}; 1012};
1013 1013
1014static const struct samsung_cmu_info mfc_cmu __initconst = {
1015 .mux_clks = mfc_mux_clks,
1016 .nr_mux_clks = ARRAY_SIZE(mfc_mux_clks),
1017 .div_clks = mfc_div_clks,
1018 .nr_div_clks = ARRAY_SIZE(mfc_div_clks),
1019 .gate_clks = mfc_gate_clks,
1020 .nr_gate_clks = ARRAY_SIZE(mfc_gate_clks),
1021 .nr_clk_ids = MFC_NR_CLK,
1022 .clk_regs = mfc_clk_regs,
1023 .nr_clk_regs = ARRAY_SIZE(mfc_clk_regs),
1024};
1025
1014static void __init exynos5260_clk_mfc_init(struct device_node *np) 1026static void __init exynos5260_clk_mfc_init(struct device_node *np)
1015{ 1027{
1016 struct samsung_cmu_info cmu = { NULL }; 1028 samsung_cmu_register_one(np, &mfc_cmu);
1017
1018 cmu.mux_clks = mfc_mux_clks;
1019 cmu.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks);
1020 cmu.div_clks = mfc_div_clks;
1021 cmu.nr_div_clks = ARRAY_SIZE(mfc_div_clks);
1022 cmu.gate_clks = mfc_gate_clks;
1023 cmu.nr_gate_clks = ARRAY_SIZE(mfc_gate_clks);
1024 cmu.nr_clk_ids = MFC_NR_CLK;
1025 cmu.clk_regs = mfc_clk_regs;
1026 cmu.nr_clk_regs = ARRAY_SIZE(mfc_clk_regs);
1027
1028 samsung_cmu_register_one(np, &cmu);
1029} 1029}
1030 1030
1031CLK_OF_DECLARE(exynos5260_clk_mfc, "samsung,exynos5260-clock-mfc", 1031CLK_OF_DECLARE(exynos5260_clk_mfc, "samsung,exynos5260-clock-mfc",
@@ -1158,23 +1158,23 @@ static const struct samsung_pll_clock mif_pll_clks[] __initconst = {
1158 pll2550_24mhz_tbl), 1158 pll2550_24mhz_tbl),
1159}; 1159};
1160 1160
1161static const struct samsung_cmu_info mif_cmu __initconst = {
1162 .pll_clks = mif_pll_clks,
1163 .nr_pll_clks = ARRAY_SIZE(mif_pll_clks),
1164 .mux_clks = mif_mux_clks,
1165 .nr_mux_clks = ARRAY_SIZE(mif_mux_clks),
1166 .div_clks = mif_div_clks,
1167 .nr_div_clks = ARRAY_SIZE(mif_div_clks),
1168 .gate_clks = mif_gate_clks,
1169 .nr_gate_clks = ARRAY_SIZE(mif_gate_clks),
1170 .nr_clk_ids = MIF_NR_CLK,
1171 .clk_regs = mif_clk_regs,
1172 .nr_clk_regs = ARRAY_SIZE(mif_clk_regs),
1173};
1174
1161static void __init exynos5260_clk_mif_init(struct device_node *np) 1175static void __init exynos5260_clk_mif_init(struct device_node *np)
1162{ 1176{
1163 struct samsung_cmu_info cmu = { NULL }; 1177 samsung_cmu_register_one(np, &mif_cmu);
1164
1165 cmu.pll_clks = mif_pll_clks;
1166 cmu.nr_pll_clks = ARRAY_SIZE(mif_pll_clks);
1167 cmu.mux_clks = mif_mux_clks;
1168 cmu.nr_mux_clks = ARRAY_SIZE(mif_mux_clks);
1169 cmu.div_clks = mif_div_clks;
1170 cmu.nr_div_clks = ARRAY_SIZE(mif_div_clks);
1171 cmu.gate_clks = mif_gate_clks;
1172 cmu.nr_gate_clks = ARRAY_SIZE(mif_gate_clks);
1173 cmu.nr_clk_ids = MIF_NR_CLK;
1174 cmu.clk_regs = mif_clk_regs;
1175 cmu.nr_clk_regs = ARRAY_SIZE(mif_clk_regs);
1176
1177 samsung_cmu_register_one(np, &cmu);
1178} 1178}
1179 1179
1180CLK_OF_DECLARE(exynos5260_clk_mif, "samsung,exynos5260-clock-mif", 1180CLK_OF_DECLARE(exynos5260_clk_mif, "samsung,exynos5260-clock-mif",
@@ -1366,21 +1366,21 @@ static const struct samsung_gate_clock peri_gate_clks[] __initconst = {
1366 EN_IP_PERI_SECURE_TZPC, 20, 0, 0), 1366 EN_IP_PERI_SECURE_TZPC, 20, 0, 0),
1367}; 1367};
1368 1368
1369static const struct samsung_cmu_info peri_cmu __initconst = {
1370 .mux_clks = peri_mux_clks,
1371 .nr_mux_clks = ARRAY_SIZE(peri_mux_clks),
1372 .div_clks = peri_div_clks,
1373 .nr_div_clks = ARRAY_SIZE(peri_div_clks),
1374 .gate_clks = peri_gate_clks,
1375 .nr_gate_clks = ARRAY_SIZE(peri_gate_clks),
1376 .nr_clk_ids = PERI_NR_CLK,
1377 .clk_regs = peri_clk_regs,
1378 .nr_clk_regs = ARRAY_SIZE(peri_clk_regs),
1379};
1380
1369static void __init exynos5260_clk_peri_init(struct device_node *np) 1381static void __init exynos5260_clk_peri_init(struct device_node *np)
1370{ 1382{
1371 struct samsung_cmu_info cmu = { NULL }; 1383 samsung_cmu_register_one(np, &peri_cmu);
1372
1373 cmu.mux_clks = peri_mux_clks;
1374 cmu.nr_mux_clks = ARRAY_SIZE(peri_mux_clks);
1375 cmu.div_clks = peri_div_clks;
1376 cmu.nr_div_clks = ARRAY_SIZE(peri_div_clks);
1377 cmu.gate_clks = peri_gate_clks;
1378 cmu.nr_gate_clks = ARRAY_SIZE(peri_gate_clks);
1379 cmu.nr_clk_ids = PERI_NR_CLK;
1380 cmu.clk_regs = peri_clk_regs;
1381 cmu.nr_clk_regs = ARRAY_SIZE(peri_clk_regs);
1382
1383 samsung_cmu_register_one(np, &cmu);
1384} 1384}
1385 1385
1386CLK_OF_DECLARE(exynos5260_clk_peri, "samsung,exynos5260-clock-peri", 1386CLK_OF_DECLARE(exynos5260_clk_peri, "samsung,exynos5260-clock-peri",
@@ -1818,25 +1818,25 @@ static const struct samsung_pll_clock top_pll_clks[] __initconst = {
1818 pll2650_24mhz_tbl), 1818 pll2650_24mhz_tbl),
1819}; 1819};
1820 1820
1821static const struct samsung_cmu_info top_cmu __initconst = {
1822 .pll_clks = top_pll_clks,
1823 .nr_pll_clks = ARRAY_SIZE(top_pll_clks),
1824 .mux_clks = top_mux_clks,
1825 .nr_mux_clks = ARRAY_SIZE(top_mux_clks),
1826 .div_clks = top_div_clks,
1827 .nr_div_clks = ARRAY_SIZE(top_div_clks),
1828 .gate_clks = top_gate_clks,
1829 .nr_gate_clks = ARRAY_SIZE(top_gate_clks),
1830 .fixed_clks = fixed_rate_clks,
1831 .nr_fixed_clks = ARRAY_SIZE(fixed_rate_clks),
1832 .nr_clk_ids = TOP_NR_CLK,
1833 .clk_regs = top_clk_regs,
1834 .nr_clk_regs = ARRAY_SIZE(top_clk_regs),
1835};
1836
1821static void __init exynos5260_clk_top_init(struct device_node *np) 1837static void __init exynos5260_clk_top_init(struct device_node *np)
1822{ 1838{
1823 struct samsung_cmu_info cmu = { NULL }; 1839 samsung_cmu_register_one(np, &top_cmu);
1824
1825 cmu.pll_clks = top_pll_clks;
1826 cmu.nr_pll_clks = ARRAY_SIZE(top_pll_clks);
1827 cmu.mux_clks = top_mux_clks;
1828 cmu.nr_mux_clks = ARRAY_SIZE(top_mux_clks);
1829 cmu.div_clks = top_div_clks;
1830 cmu.nr_div_clks = ARRAY_SIZE(top_div_clks);
1831 cmu.gate_clks = top_gate_clks;
1832 cmu.nr_gate_clks = ARRAY_SIZE(top_gate_clks);
1833 cmu.fixed_clks = fixed_rate_clks;
1834 cmu.nr_fixed_clks = ARRAY_SIZE(fixed_rate_clks);
1835 cmu.nr_clk_ids = TOP_NR_CLK;
1836 cmu.clk_regs = top_clk_regs;
1837 cmu.nr_clk_regs = ARRAY_SIZE(top_clk_regs);
1838
1839 samsung_cmu_register_one(np, &cmu);
1840} 1840}
1841 1841
1842CLK_OF_DECLARE(exynos5260_clk_top, "samsung,exynos5260-clock-top", 1842CLK_OF_DECLARE(exynos5260_clk_top, "samsung,exynos5260-clock-top",
diff --git a/drivers/clk/samsung/clk-exynos5410.c b/drivers/clk/samsung/clk-exynos5410.c
index 54ec486a5e45..fc471a49e8f4 100644
--- a/drivers/clk/samsung/clk-exynos5410.c
+++ b/drivers/clk/samsung/clk-exynos5410.c
@@ -14,6 +14,7 @@
14#include <linux/clk-provider.h> 14#include <linux/clk-provider.h>
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/of_address.h> 16#include <linux/of_address.h>
17#include <linux/clk.h>
17 18
18#include "clk.h" 19#include "clk.h"
19 20
@@ -21,6 +22,8 @@
21#define APLL_CON0 0x100 22#define APLL_CON0 0x100
22#define CPLL_LOCK 0x10020 23#define CPLL_LOCK 0x10020
23#define CPLL_CON0 0x10120 24#define CPLL_CON0 0x10120
25#define EPLL_LOCK 0x10040
26#define EPLL_CON0 0x10130
24#define MPLL_LOCK 0x4000 27#define MPLL_LOCK 0x4000
25#define MPLL_CON0 0x4100 28#define MPLL_CON0 0x4100
26#define BPLL_LOCK 0x20010 29#define BPLL_LOCK 0x20010
@@ -58,7 +61,7 @@
58 61
59/* list of PLLs */ 62/* list of PLLs */
60enum exynos5410_plls { 63enum exynos5410_plls {
61 apll, cpll, mpll, 64 apll, cpll, epll, mpll,
62 bpll, kpll, 65 bpll, kpll,
63 nr_plls /* number of PLLs */ 66 nr_plls /* number of PLLs */
64}; 67};
@@ -67,6 +70,7 @@ enum exynos5410_plls {
67PNAME(apll_p) = { "fin_pll", "fout_apll", }; 70PNAME(apll_p) = { "fin_pll", "fout_apll", };
68PNAME(bpll_p) = { "fin_pll", "fout_bpll", }; 71PNAME(bpll_p) = { "fin_pll", "fout_bpll", };
69PNAME(cpll_p) = { "fin_pll", "fout_cpll" }; 72PNAME(cpll_p) = { "fin_pll", "fout_cpll" };
73PNAME(epll_p) = { "fin_pll", "fout_epll" };
70PNAME(mpll_p) = { "fin_pll", "fout_mpll", }; 74PNAME(mpll_p) = { "fin_pll", "fout_mpll", };
71PNAME(kpll_p) = { "fin_pll", "fout_kpll", }; 75PNAME(kpll_p) = { "fin_pll", "fout_kpll", };
72 76
@@ -95,6 +99,8 @@ static const struct samsung_mux_clock exynos5410_mux_clks[] __initconst = {
95 MUX(0, "sclk_bpll", bpll_p, SRC_CDREX, 0, 1), 99 MUX(0, "sclk_bpll", bpll_p, SRC_CDREX, 0, 1),
96 MUX(0, "sclk_bpll_muxed", bpll_user_p, SRC_TOP2, 24, 1), 100 MUX(0, "sclk_bpll_muxed", bpll_user_p, SRC_TOP2, 24, 1),
97 101
102 MUX(0, "sclk_epll", epll_p, SRC_TOP2, 12, 1),
103
98 MUX(0, "sclk_cpll", cpll_p, SRC_TOP2, 8, 1), 104 MUX(0, "sclk_cpll", cpll_p, SRC_TOP2, 8, 1),
99 105
100 MUX(0, "sclk_mpll_bpll", mpll_bpll_p, SRC_TOP1, 20, 1), 106 MUX(0, "sclk_mpll_bpll", mpll_bpll_p, SRC_TOP1, 20, 1),
@@ -176,6 +182,8 @@ static const struct samsung_gate_clock exynos5410_gate_clks[] __initconst = {
176 GATE(CLK_MMC0, "sdmmc0", "aclk200", GATE_BUS_FSYS0, 12, 0, 0), 182 GATE(CLK_MMC0, "sdmmc0", "aclk200", GATE_BUS_FSYS0, 12, 0, 0),
177 GATE(CLK_MMC1, "sdmmc1", "aclk200", GATE_BUS_FSYS0, 13, 0, 0), 183 GATE(CLK_MMC1, "sdmmc1", "aclk200", GATE_BUS_FSYS0, 13, 0, 0),
178 GATE(CLK_MMC2, "sdmmc2", "aclk200", GATE_BUS_FSYS0, 14, 0, 0), 184 GATE(CLK_MMC2, "sdmmc2", "aclk200", GATE_BUS_FSYS0, 14, 0, 0),
185 GATE(CLK_PDMA1, "pdma1", "aclk200", GATE_BUS_FSYS0, 2, 0, 0),
186 GATE(CLK_PDMA0, "pdma0", "aclk200", GATE_BUS_FSYS0, 1, 0, 0),
179 187
180 GATE(CLK_SCLK_USBPHY301, "sclk_usbphy301", "dout_usbphy301", 188 GATE(CLK_SCLK_USBPHY301, "sclk_usbphy301", "dout_usbphy301",
181 GATE_TOP_SCLK_FSYS, 7, CLK_SET_RATE_PARENT, 0), 189 GATE_TOP_SCLK_FSYS, 7, CLK_SET_RATE_PARENT, 0),
@@ -217,11 +225,26 @@ static const struct samsung_gate_clock exynos5410_gate_clks[] __initconst = {
217 GATE(CLK_USBD301, "usbd301", "aclk200_fsys", GATE_IP_FSYS, 20, 0, 0), 225 GATE(CLK_USBD301, "usbd301", "aclk200_fsys", GATE_IP_FSYS, 20, 0, 0),
218}; 226};
219 227
220static const struct samsung_pll_clock exynos5410_plls[nr_plls] __initconst = { 228static const struct samsung_pll_rate_table exynos5410_pll2550x_24mhz_tbl[] __initconst = {
229 PLL_36XX_RATE(400000000U, 200, 3, 2, 0),
230 PLL_36XX_RATE(333000000U, 111, 2, 2, 0),
231 PLL_36XX_RATE(300000000U, 100, 2, 2, 0),
232 PLL_36XX_RATE(266000000U, 266, 3, 3, 0),
233 PLL_36XX_RATE(200000000U, 200, 3, 3, 0),
234 PLL_36XX_RATE(192000000U, 192, 3, 3, 0),
235 PLL_36XX_RATE(166000000U, 166, 3, 3, 0),
236 PLL_36XX_RATE(133000000U, 266, 3, 4, 0),
237 PLL_36XX_RATE(100000000U, 200, 3, 4, 0),
238 PLL_36XX_RATE(66000000U, 176, 2, 5, 0),
239};
240
241static struct samsung_pll_clock exynos5410_plls[nr_plls] __initdata = {
221 [apll] = PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK, 242 [apll] = PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK,
222 APLL_CON0, NULL), 243 APLL_CON0, NULL),
223 [cpll] = PLL(pll_35xx, CLK_FOUT_CPLL, "fout_cpll", "fin_pll", CPLL_LOCK, 244 [cpll] = PLL(pll_35xx, CLK_FOUT_CPLL, "fout_cpll", "fin_pll", CPLL_LOCK,
224 CPLL_CON0, NULL), 245 CPLL_CON0, NULL),
246 [epll] = PLL(pll_2650x, CLK_FOUT_EPLL, "fout_epll", "fin_pll", EPLL_LOCK,
247 EPLL_CON0, NULL),
225 [mpll] = PLL(pll_35xx, CLK_FOUT_MPLL, "fout_mpll", "fin_pll", MPLL_LOCK, 248 [mpll] = PLL(pll_35xx, CLK_FOUT_MPLL, "fout_mpll", "fin_pll", MPLL_LOCK,
226 MPLL_CON0, NULL), 249 MPLL_CON0, NULL),
227 [bpll] = PLL(pll_35xx, CLK_FOUT_BPLL, "fout_bpll", "fin_pll", BPLL_LOCK, 250 [bpll] = PLL(pll_35xx, CLK_FOUT_BPLL, "fout_bpll", "fin_pll", BPLL_LOCK,
@@ -230,29 +253,27 @@ static const struct samsung_pll_clock exynos5410_plls[nr_plls] __initconst = {
230 KPLL_CON0, NULL), 253 KPLL_CON0, NULL),
231}; 254};
232 255
256static const struct samsung_cmu_info cmu __initconst = {
257 .pll_clks = exynos5410_plls,
258 .nr_pll_clks = ARRAY_SIZE(exynos5410_plls),
259 .mux_clks = exynos5410_mux_clks,
260 .nr_mux_clks = ARRAY_SIZE(exynos5410_mux_clks),
261 .div_clks = exynos5410_div_clks,
262 .nr_div_clks = ARRAY_SIZE(exynos5410_div_clks),
263 .gate_clks = exynos5410_gate_clks,
264 .nr_gate_clks = ARRAY_SIZE(exynos5410_gate_clks),
265 .nr_clk_ids = CLK_NR_CLKS,
266};
267
233/* register exynos5410 clocks */ 268/* register exynos5410 clocks */
234static void __init exynos5410_clk_init(struct device_node *np) 269static void __init exynos5410_clk_init(struct device_node *np)
235{ 270{
236 struct samsung_clk_provider *ctx; 271 struct clk *xxti = of_clk_get(np, 0);
237 void __iomem *reg_base;
238
239 reg_base = of_iomap(np, 0);
240 if (!reg_base)
241 panic("%s: failed to map registers\n", __func__);
242
243 ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
244
245 samsung_clk_register_pll(ctx, exynos5410_plls,
246 ARRAY_SIZE(exynos5410_plls), reg_base);
247 272
248 samsung_clk_register_mux(ctx, exynos5410_mux_clks, 273 if (!IS_ERR(xxti) && clk_get_rate(xxti) == 24 * MHZ)
249 ARRAY_SIZE(exynos5410_mux_clks)); 274 exynos5410_plls[epll].rate_table = exynos5410_pll2550x_24mhz_tbl;
250 samsung_clk_register_div(ctx, exynos5410_div_clks,
251 ARRAY_SIZE(exynos5410_div_clks));
252 samsung_clk_register_gate(ctx, exynos5410_gate_clks,
253 ARRAY_SIZE(exynos5410_gate_clks));
254 275
255 samsung_clk_of_add_provider(np, ctx); 276 samsung_cmu_register_one(np, &cmu);
256 277
257 pr_debug("Exynos5410: clock setup completed.\n"); 278 pr_debug("Exynos5410: clock setup completed.\n");
258} 279}
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index bb196ca21a77..8c8b495cbf0d 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -131,6 +131,9 @@
131#define TOP_SPARE2 0x10b08 131#define TOP_SPARE2 0x10b08
132#define BPLL_LOCK 0x20010 132#define BPLL_LOCK 0x20010
133#define BPLL_CON0 0x20110 133#define BPLL_CON0 0x20110
134#define SRC_CDREX 0x20200
135#define DIV_CDREX0 0x20500
136#define DIV_CDREX1 0x20504
134#define KPLL_LOCK 0x28000 137#define KPLL_LOCK 0x28000
135#define KPLL_CON0 0x28100 138#define KPLL_CON0 0x28100
136#define SRC_KFC 0x28200 139#define SRC_KFC 0x28200
@@ -244,6 +247,9 @@ static const unsigned long exynos5x_clk_regs[] __initconst = {
244 GATE_TOP_SCLK_FSYS, 247 GATE_TOP_SCLK_FSYS,
245 GATE_TOP_SCLK_PERIC, 248 GATE_TOP_SCLK_PERIC,
246 TOP_SPARE2, 249 TOP_SPARE2,
250 SRC_CDREX,
251 DIV_CDREX0,
252 DIV_CDREX1,
247 SRC_KFC, 253 SRC_KFC,
248 DIV_KFC0, 254 DIV_KFC0,
249}; 255};
@@ -448,6 +454,8 @@ PNAME(mout_maudio0_p) = {"fin_pll", "maudio_clk", "mout_sclk_dpll",
448 "mout_sclk_epll", "mout_sclk_rpll"}; 454 "mout_sclk_epll", "mout_sclk_rpll"};
449PNAME(mout_mau_epll_clk_p) = {"mout_sclk_epll", "mout_sclk_dpll", 455PNAME(mout_mau_epll_clk_p) = {"mout_sclk_epll", "mout_sclk_dpll",
450 "mout_sclk_mpll", "mout_sclk_spll"}; 456 "mout_sclk_mpll", "mout_sclk_spll"};
457PNAME(mout_mclk_cdrex_p) = {"mout_bpll", "mout_mx_mspll_ccore"};
458
451/* List of parents specific to exynos5800 */ 459/* List of parents specific to exynos5800 */
452PNAME(mout_epll2_5800_p) = { "mout_sclk_epll", "ff_dout_epll2" }; 460PNAME(mout_epll2_5800_p) = { "mout_sclk_epll", "ff_dout_epll2" };
453PNAME(mout_group1_5800_p) = { "mout_sclk_cpll", "mout_sclk_dpll", 461PNAME(mout_group1_5800_p) = { "mout_sclk_cpll", "mout_sclk_dpll",
@@ -465,6 +473,9 @@ PNAME(mout_group6_5800_p) = { "mout_sclk_ipll", "mout_sclk_dpll",
465PNAME(mout_group7_5800_p) = { "mout_sclk_cpll", "mout_sclk_dpll", 473PNAME(mout_group7_5800_p) = { "mout_sclk_cpll", "mout_sclk_dpll",
466 "mout_sclk_mpll", "mout_sclk_spll", 474 "mout_sclk_mpll", "mout_sclk_spll",
467 "mout_epll2", "mout_sclk_ipll" }; 475 "mout_epll2", "mout_sclk_ipll" };
476PNAME(mout_mx_mspll_ccore_p) = {"sclk_bpll", "mout_sclk_dpll",
477 "mout_sclk_mpll", "ff_dout_spll2",
478 "mout_sclk_spll", "mout_sclk_epll"};
468PNAME(mout_mau_epll_clk_5800_p) = { "mout_sclk_epll", "mout_sclk_dpll", 479PNAME(mout_mau_epll_clk_5800_p) = { "mout_sclk_epll", "mout_sclk_dpll",
469 "mout_sclk_mpll", 480 "mout_sclk_mpll",
470 "ff_dout_spll2" }; 481 "ff_dout_spll2" };
@@ -523,6 +534,8 @@ static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = {
523 MUX(0, "mout_aclk300_disp1", mout_group5_5800_p, SRC_TOP2, 24, 2), 534 MUX(0, "mout_aclk300_disp1", mout_group5_5800_p, SRC_TOP2, 24, 2),
524 MUX(0, "mout_aclk300_gscl", mout_group5_5800_p, SRC_TOP2, 28, 2), 535 MUX(0, "mout_aclk300_gscl", mout_group5_5800_p, SRC_TOP2, 28, 2),
525 536
537 MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore",
538 mout_mx_mspll_ccore_p, SRC_TOP7, 16, 2),
526 MUX(0, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p, SRC_TOP7, 539 MUX(0, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p, SRC_TOP7,
527 20, 2), 540 20, 2),
528 MUX(0, "sclk_bpll", mout_bpll_p, SRC_TOP7, 24, 1), 541 MUX(0, "sclk_bpll", mout_bpll_p, SRC_TOP7, 24, 1),
@@ -601,6 +614,8 @@ static const struct samsung_mux_clock exynos5420_mux_clks[] __initconst = {
601 MUX(0, "mout_aclk300_disp1", mout_group1_p, SRC_TOP2, 24, 2), 614 MUX(0, "mout_aclk300_disp1", mout_group1_p, SRC_TOP2, 24, 2),
602 MUX(0, "mout_aclk300_gscl", mout_group1_p, SRC_TOP2, 28, 2), 615 MUX(0, "mout_aclk300_gscl", mout_group1_p, SRC_TOP2, 28, 2),
603 616
617 MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore",
618 mout_group5_5800_p, SRC_TOP7, 16, 2),
604 MUX(0, "mout_mau_epll_clk", mout_mau_epll_clk_p, SRC_TOP7, 20, 2), 619 MUX(0, "mout_mau_epll_clk", mout_mau_epll_clk_p, SRC_TOP7, 20, 2),
605 620
606 MUX(0, "mout_fimd1", mout_group3_p, SRC_DISP10, 4, 1), 621 MUX(0, "mout_fimd1", mout_group3_p, SRC_DISP10, 4, 1),
@@ -744,6 +759,12 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = {
744 759
745 MUX(0, "mout_fimd1_final", mout_fimd1_final_p, TOP_SPARE2, 8, 1), 760 MUX(0, "mout_fimd1_final", mout_fimd1_final_p, TOP_SPARE2, 8, 1),
746 761
762 /* CDREX block */
763 MUX_F(CLK_MOUT_MCLK_CDREX, "mout_mclk_cdrex", mout_mclk_cdrex_p,
764 SRC_CDREX, 4, 1, CLK_SET_RATE_PARENT, 0),
765 MUX_F(CLK_MOUT_BPLL, "mout_bpll", mout_bpll_p, SRC_CDREX, 0, 1,
766 CLK_SET_RATE_PARENT, 0),
767
747 /* MAU Block */ 768 /* MAU Block */
748 MUX(CLK_MOUT_MAUDIO0, "mout_maudio0", mout_maudio0_p, SRC_MAU, 28, 3), 769 MUX(CLK_MOUT_MAUDIO0, "mout_maudio0", mout_maudio0_p, SRC_MAU, 28, 3),
749 770
@@ -836,6 +857,21 @@ static const struct samsung_div_clock exynos5x_div_clks[] __initconst = {
836 DIV(CLK_DOUT_ACLK400_DISP1, "dout_aclk400_disp1", 857 DIV(CLK_DOUT_ACLK400_DISP1, "dout_aclk400_disp1",
837 "mout_aclk400_disp1", DIV_TOP2, 4, 3), 858 "mout_aclk400_disp1", DIV_TOP2, 4, 3),
838 859
860 /* CDREX Block */
861 DIV(CLK_DOUT_PCLK_CDREX, "dout_pclk_cdrex", "dout_aclk_cdrex1",
862 DIV_CDREX0, 28, 3),
863 DIV_F(CLK_DOUT_SCLK_CDREX, "dout_sclk_cdrex", "mout_mclk_cdrex",
864 DIV_CDREX0, 24, 3, CLK_SET_RATE_PARENT, 0),
865 DIV(CLK_DOUT_ACLK_CDREX1, "dout_aclk_cdrex1", "dout_clk2x_phy0",
866 DIV_CDREX0, 16, 3),
867 DIV(CLK_DOUT_CCLK_DREX0, "dout_cclk_drex0", "dout_clk2x_phy0",
868 DIV_CDREX0, 8, 3),
869 DIV(CLK_DOUT_CLK2X_PHY0, "dout_clk2x_phy0", "dout_sclk_cdrex",
870 DIV_CDREX0, 3, 5),
871
872 DIV(CLK_DOUT_PCLK_CORE_MEM, "dout_pclk_core_mem", "mout_mclk_cdrex",
873 DIV_CDREX1, 8, 3),
874
839 /* Audio Block */ 875 /* Audio Block */
840 DIV(0, "dout_maudio0", "mout_maudio0", DIV_MAU, 20, 4), 876 DIV(0, "dout_maudio0", "mout_maudio0", DIV_MAU, 20, 4),
841 DIV(0, "dout_maupcm0", "dout_maudio0", DIV_MAU, 24, 8), 877 DIV(0, "dout_maupcm0", "dout_maudio0", DIV_MAU, 24, 8),
@@ -1364,6 +1400,7 @@ static void __init exynos5x_clk_init(struct device_node *np,
1364 if (_get_rate("fin_pll") == 24 * MHZ) { 1400 if (_get_rate("fin_pll") == 24 * MHZ) {
1365 exynos5x_plls[apll].rate_table = exynos5420_pll2550x_24mhz_tbl; 1401 exynos5x_plls[apll].rate_table = exynos5420_pll2550x_24mhz_tbl;
1366 exynos5x_plls[kpll].rate_table = exynos5420_pll2550x_24mhz_tbl; 1402 exynos5x_plls[kpll].rate_table = exynos5420_pll2550x_24mhz_tbl;
1403 exynos5x_plls[bpll].rate_table = exynos5420_pll2550x_24mhz_tbl;
1367 } 1404 }
1368 1405
1369 samsung_clk_register_pll(ctx, exynos5x_plls, ARRAY_SIZE(exynos5x_plls), 1406 samsung_clk_register_pll(ctx, exynos5x_plls, ARRAY_SIZE(exynos5x_plls),
diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c
index a57d01b99b76..a80f3ef20801 100644
--- a/drivers/clk/samsung/clk-exynos5440.c
+++ b/drivers/clk/samsung/clk-exynos5440.c
@@ -112,6 +112,11 @@ static struct notifier_block exynos5440_clk_restart_handler = {
112 .priority = 128, 112 .priority = 128,
113}; 113};
114 114
115static const struct samsung_pll_clock exynos5440_plls[] __initconst = {
116 PLL(pll_2550x, CLK_CPLLA, "cplla", "xtal", 0, 0x4c, NULL),
117 PLL(pll_2550x, CLK_CPLLB, "cpllb", "xtal", 0, 0x50, NULL),
118};
119
115/* register exynos5440 clocks */ 120/* register exynos5440 clocks */
116static void __init exynos5440_clk_init(struct device_node *np) 121static void __init exynos5440_clk_init(struct device_node *np)
117{ 122{
@@ -129,8 +134,8 @@ static void __init exynos5440_clk_init(struct device_node *np)
129 samsung_clk_of_register_fixed_ext(ctx, exynos5440_fixed_rate_ext_clks, 134 samsung_clk_of_register_fixed_ext(ctx, exynos5440_fixed_rate_ext_clks,
130 ARRAY_SIZE(exynos5440_fixed_rate_ext_clks), ext_clk_match); 135 ARRAY_SIZE(exynos5440_fixed_rate_ext_clks), ext_clk_match);
131 136
132 samsung_clk_register_pll2550x("cplla", "xtal", reg_base + 0x1c, 0x10); 137 samsung_clk_register_pll(ctx, exynos5440_plls,
133 samsung_clk_register_pll2550x("cpllb", "xtal", reg_base + 0x20, 0x10); 138 ARRAY_SIZE(exynos5440_plls), ctx->reg_base);
134 139
135 samsung_clk_register_fixed_rate(ctx, exynos5440_fixed_rate_clks, 140 samsung_clk_register_fixed_rate(ctx, exynos5440_fixed_rate_clks,
136 ARRAY_SIZE(exynos5440_fixed_rate_clks)); 141 ARRAY_SIZE(exynos5440_fixed_rate_clks));
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 48139bd510f1..9617825daabb 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -890,22 +890,14 @@ static const struct clk_ops samsung_s3c2440_mpll_clk_ops = {
890#define PLL2550X_M_SHIFT (4) 890#define PLL2550X_M_SHIFT (4)
891#define PLL2550X_S_SHIFT (0) 891#define PLL2550X_S_SHIFT (0)
892 892
893struct samsung_clk_pll2550x {
894 struct clk_hw hw;
895 const void __iomem *reg_base;
896 unsigned long offset;
897};
898
899#define to_clk_pll2550x(_hw) container_of(_hw, struct samsung_clk_pll2550x, hw)
900
901static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw, 893static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw,
902 unsigned long parent_rate) 894 unsigned long parent_rate)
903{ 895{
904 struct samsung_clk_pll2550x *pll = to_clk_pll2550x(hw); 896 struct samsung_clk_pll *pll = to_clk_pll(hw);
905 u32 r, p, m, s, pll_stat; 897 u32 r, p, m, s, pll_stat;
906 u64 fvco = parent_rate; 898 u64 fvco = parent_rate;
907 899
908 pll_stat = readl_relaxed(pll->reg_base + pll->offset * 3); 900 pll_stat = readl_relaxed(pll->con_reg);
909 r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK; 901 r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK;
910 if (!r) 902 if (!r)
911 return 0; 903 return 0;
@@ -923,43 +915,6 @@ static const struct clk_ops samsung_pll2550x_clk_ops = {
923 .recalc_rate = samsung_pll2550x_recalc_rate, 915 .recalc_rate = samsung_pll2550x_recalc_rate,
924}; 916};
925 917
926struct clk * __init samsung_clk_register_pll2550x(const char *name,
927 const char *pname, const void __iomem *reg_base,
928 const unsigned long offset)
929{
930 struct samsung_clk_pll2550x *pll;
931 struct clk *clk;
932 struct clk_init_data init;
933
934 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
935 if (!pll) {
936 pr_err("%s: could not allocate pll clk %s\n", __func__, name);
937 return NULL;
938 }
939
940 init.name = name;
941 init.ops = &samsung_pll2550x_clk_ops;
942 init.flags = CLK_GET_RATE_NOCACHE;
943 init.parent_names = &pname;
944 init.num_parents = 1;
945
946 pll->hw.init = &init;
947 pll->reg_base = reg_base;
948 pll->offset = offset;
949
950 clk = clk_register(NULL, &pll->hw);
951 if (IS_ERR(clk)) {
952 pr_err("%s: failed to register pll clock %s\n", __func__,
953 name);
954 kfree(pll);
955 }
956
957 if (clk_register_clkdev(clk, name, NULL))
958 pr_err("%s: failed to register lookup for %s", __func__, name);
959
960 return clk;
961}
962
963/* 918/*
964 * PLL2550xx Clock Type 919 * PLL2550xx Clock Type
965 */ 920 */
@@ -1063,6 +1018,102 @@ static const struct clk_ops samsung_pll2550xx_clk_min_ops = {
1063}; 1018};
1064 1019
1065/* 1020/*
1021 * PLL2650x Clock Type
1022 */
1023
1024/* Maximum lock time can be 3000 * PDIV cycles */
1025#define PLL2650X_LOCK_FACTOR 3000
1026
1027#define PLL2650X_M_MASK 0x1ff
1028#define PLL2650X_P_MASK 0x3f
1029#define PLL2650X_S_MASK 0x7
1030#define PLL2650X_K_MASK 0xffff
1031#define PLL2650X_LOCK_STAT_MASK 0x1
1032#define PLL2650X_M_SHIFT 16
1033#define PLL2650X_P_SHIFT 8
1034#define PLL2650X_S_SHIFT 0
1035#define PLL2650X_K_SHIFT 0
1036#define PLL2650X_LOCK_STAT_SHIFT 29
1037#define PLL2650X_PLL_ENABLE_SHIFT 31
1038
1039static unsigned long samsung_pll2650x_recalc_rate(struct clk_hw *hw,
1040 unsigned long parent_rate)
1041{
1042 struct samsung_clk_pll *pll = to_clk_pll(hw);
1043 u64 fout = parent_rate;
1044 u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
1045 s16 kdiv;
1046
1047 pll_con0 = readl_relaxed(pll->con_reg);
1048 mdiv = (pll_con0 >> PLL2650X_M_SHIFT) & PLL2650X_M_MASK;
1049 pdiv = (pll_con0 >> PLL2650X_P_SHIFT) & PLL2650X_P_MASK;
1050 sdiv = (pll_con0 >> PLL2650X_S_SHIFT) & PLL2650X_S_MASK;
1051
1052 pll_con1 = readl_relaxed(pll->con_reg + 4);
1053 kdiv = (s16)((pll_con1 >> PLL2650X_K_SHIFT) & PLL2650X_K_MASK);
1054
1055 fout *= (mdiv << 16) + kdiv;
1056 do_div(fout, (pdiv << sdiv));
1057 fout >>= 16;
1058
1059 return (unsigned long)fout;
1060}
1061
1062static int samsung_pll2650x_set_rate(struct clk_hw *hw, unsigned long drate,
1063 unsigned long prate)
1064{
1065 struct samsung_clk_pll *pll = to_clk_pll(hw);
1066 const struct samsung_pll_rate_table *rate;
1067 u32 con0, con1;
1068
1069 /* Get required rate settings from table */
1070 rate = samsung_get_pll_settings(pll, drate);
1071 if (!rate) {
1072 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1073 drate, clk_hw_get_name(hw));
1074 return -EINVAL;
1075 }
1076
1077 con0 = readl_relaxed(pll->con_reg);
1078 con1 = readl_relaxed(pll->con_reg + 4);
1079
1080 /* Set PLL lock time. */
1081 writel_relaxed(rate->pdiv * PLL2650X_LOCK_FACTOR, pll->lock_reg);
1082
1083 /* Change PLL PMS values */
1084 con0 &= ~((PLL2650X_M_MASK << PLL2650X_M_SHIFT) |
1085 (PLL2650X_P_MASK << PLL2650X_P_SHIFT) |
1086 (PLL2650X_S_MASK << PLL2650X_S_SHIFT));
1087 con0 |= (rate->mdiv << PLL2650X_M_SHIFT) |
1088 (rate->pdiv << PLL2650X_P_SHIFT) |
1089 (rate->sdiv << PLL2650X_S_SHIFT);
1090 con0 |= (1 << PLL2650X_PLL_ENABLE_SHIFT);
1091 writel_relaxed(con0, pll->con_reg);
1092
1093 con1 &= ~(PLL2650X_K_MASK << PLL2650X_K_SHIFT);
1094 con1 |= ((rate->kdiv & PLL2650X_K_MASK) << PLL2650X_K_SHIFT);
1095 writel_relaxed(con1, pll->con_reg + 4);
1096
1097 do {
1098 cpu_relax();
1099 con0 = readl_relaxed(pll->con_reg);
1100 } while (!(con0 & (PLL2650X_LOCK_STAT_MASK
1101 << PLL2650X_LOCK_STAT_SHIFT)));
1102
1103 return 0;
1104}
1105
1106static const struct clk_ops samsung_pll2650x_clk_ops = {
1107 .recalc_rate = samsung_pll2650x_recalc_rate,
1108 .round_rate = samsung_pll_round_rate,
1109 .set_rate = samsung_pll2650x_set_rate,
1110};
1111
1112static const struct clk_ops samsung_pll2650x_clk_min_ops = {
1113 .recalc_rate = samsung_pll2650x_recalc_rate,
1114};
1115
1116/*
1066 * PLL2650XX Clock Type 1117 * PLL2650XX Clock Type
1067 */ 1118 */
1068 1119
@@ -1263,12 +1314,21 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1263 else 1314 else
1264 init.ops = &samsung_s3c2440_mpll_clk_ops; 1315 init.ops = &samsung_s3c2440_mpll_clk_ops;
1265 break; 1316 break;
1317 case pll_2550x:
1318 init.ops = &samsung_pll2550x_clk_ops;
1319 break;
1266 case pll_2550xx: 1320 case pll_2550xx:
1267 if (!pll->rate_table) 1321 if (!pll->rate_table)
1268 init.ops = &samsung_pll2550xx_clk_min_ops; 1322 init.ops = &samsung_pll2550xx_clk_min_ops;
1269 else 1323 else
1270 init.ops = &samsung_pll2550xx_clk_ops; 1324 init.ops = &samsung_pll2550xx_clk_ops;
1271 break; 1325 break;
1326 case pll_2650x:
1327 if (!pll->rate_table)
1328 init.ops = &samsung_pll2650x_clk_min_ops;
1329 else
1330 init.ops = &samsung_pll2650x_clk_ops;
1331 break;
1272 case pll_2650xx: 1332 case pll_2650xx:
1273 if (!pll->rate_table) 1333 if (!pll->rate_table)
1274 init.ops = &samsung_pll2650xx_clk_min_ops; 1334 init.ops = &samsung_pll2650xx_clk_min_ops;
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index 213de9af8b4f..a1ca0233cb4b 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -31,7 +31,9 @@ enum samsung_pll_type {
31 pll_s3c2410_mpll, 31 pll_s3c2410_mpll,
32 pll_s3c2410_upll, 32 pll_s3c2410_upll,
33 pll_s3c2440_mpll, 33 pll_s3c2440_mpll,
34 pll_2550x,
34 pll_2550xx, 35 pll_2550xx,
36 pll_2650x,
35 pll_2650xx, 37 pll_2650xx,
36 pll_1450x, 38 pll_1450x,
37 pll_1451x, 39 pll_1451x,
diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c
index 546bd79c8e3a..a485f3b284b9 100644
--- a/drivers/clk/st/clk-flexgen.c
+++ b/drivers/clk/st/clk-flexgen.c
@@ -15,6 +15,11 @@
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/of_address.h> 16#include <linux/of_address.h>
17 17
18struct clkgen_data {
19 unsigned long flags;
20 bool mode;
21};
22
18struct flexgen { 23struct flexgen {
19 struct clk_hw hw; 24 struct clk_hw hw;
20 25
@@ -28,9 +33,14 @@ struct flexgen {
28 struct clk_gate fgate; 33 struct clk_gate fgate;
29 /* Final divisor */ 34 /* Final divisor */
30 struct clk_divider fdiv; 35 struct clk_divider fdiv;
36 /* Asynchronous mode control */
37 struct clk_gate sync;
38 /* hw control flags */
39 bool control_mode;
31}; 40};
32 41
33#define to_flexgen(_hw) container_of(_hw, struct flexgen, hw) 42#define to_flexgen(_hw) container_of(_hw, struct flexgen, hw)
43#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
34 44
35static int flexgen_enable(struct clk_hw *hw) 45static int flexgen_enable(struct clk_hw *hw)
36{ 46{
@@ -139,12 +149,21 @@ static int flexgen_set_rate(struct clk_hw *hw, unsigned long rate,
139 struct flexgen *flexgen = to_flexgen(hw); 149 struct flexgen *flexgen = to_flexgen(hw);
140 struct clk_hw *pdiv_hw = &flexgen->pdiv.hw; 150 struct clk_hw *pdiv_hw = &flexgen->pdiv.hw;
141 struct clk_hw *fdiv_hw = &flexgen->fdiv.hw; 151 struct clk_hw *fdiv_hw = &flexgen->fdiv.hw;
152 struct clk_hw *sync_hw = &flexgen->sync.hw;
153 struct clk_gate *config = to_clk_gate(sync_hw);
142 unsigned long div = 0; 154 unsigned long div = 0;
143 int ret = 0; 155 int ret = 0;
156 u32 reg;
144 157
145 __clk_hw_set_clk(pdiv_hw, hw); 158 __clk_hw_set_clk(pdiv_hw, hw);
146 __clk_hw_set_clk(fdiv_hw, hw); 159 __clk_hw_set_clk(fdiv_hw, hw);
147 160
161 if (flexgen->control_mode) {
162 reg = readl(config->reg);
163 reg &= ~BIT(config->bit_idx);
164 writel(reg, config->reg);
165 }
166
148 div = clk_best_div(parent_rate, rate); 167 div = clk_best_div(parent_rate, rate);
149 168
150 /* 169 /*
@@ -178,7 +197,7 @@ static const struct clk_ops flexgen_ops = {
178static struct clk *clk_register_flexgen(const char *name, 197static struct clk *clk_register_flexgen(const char *name,
179 const char **parent_names, u8 num_parents, 198 const char **parent_names, u8 num_parents,
180 void __iomem *reg, spinlock_t *lock, u32 idx, 199 void __iomem *reg, spinlock_t *lock, u32 idx,
181 unsigned long flexgen_flags) { 200 unsigned long flexgen_flags, bool mode) {
182 struct flexgen *fgxbar; 201 struct flexgen *fgxbar;
183 struct clk *clk; 202 struct clk *clk;
184 struct clk_init_data init; 203 struct clk_init_data init;
@@ -227,6 +246,13 @@ static struct clk *clk_register_flexgen(const char *name,
227 fgxbar->fdiv.reg = fdiv_reg; 246 fgxbar->fdiv.reg = fdiv_reg;
228 fgxbar->fdiv.width = 6; 247 fgxbar->fdiv.width = 6;
229 248
249 /* Final divider sync config */
250 fgxbar->sync.lock = lock;
251 fgxbar->sync.reg = fdiv_reg;
252 fgxbar->sync.bit_idx = 7;
253
254 fgxbar->control_mode = mode;
255
230 fgxbar->hw.init = &init; 256 fgxbar->hw.init = &init;
231 257
232 clk = clk_register(NULL, &fgxbar->hw); 258 clk = clk_register(NULL, &fgxbar->hw);
@@ -259,6 +285,27 @@ static const char ** __init flexgen_get_parents(struct device_node *np,
259 return parents; 285 return parents;
260} 286}
261 287
288static const struct clkgen_data clkgen_audio = {
289 .flags = CLK_SET_RATE_PARENT,
290};
291
292static const struct clkgen_data clkgen_video = {
293 .flags = CLK_SET_RATE_PARENT,
294 .mode = 1,
295};
296
297static const struct of_device_id flexgen_of_match[] = {
298 {
299 .compatible = "st,flexgen-audio",
300 .data = &clkgen_audio,
301 },
302 {
303 .compatible = "st,flexgen-video",
304 .data = &clkgen_video,
305 },
306 {}
307};
308
262static void __init st_of_flexgen_setup(struct device_node *np) 309static void __init st_of_flexgen_setup(struct device_node *np)
263{ 310{
264 struct device_node *pnode; 311 struct device_node *pnode;
@@ -267,7 +314,11 @@ static void __init st_of_flexgen_setup(struct device_node *np)
267 const char **parents; 314 const char **parents;
268 int num_parents, i; 315 int num_parents, i;
269 spinlock_t *rlock = NULL; 316 spinlock_t *rlock = NULL;
317 const struct of_device_id *match;
318 struct clkgen_data *data = NULL;
319 unsigned long flex_flags = 0;
270 int ret; 320 int ret;
321 bool clk_mode = 0;
271 322
272 pnode = of_get_parent(np); 323 pnode = of_get_parent(np);
273 if (!pnode) 324 if (!pnode)
@@ -281,6 +332,13 @@ static void __init st_of_flexgen_setup(struct device_node *np)
281 if (!parents) 332 if (!parents)
282 return; 333 return;
283 334
335 match = of_match_node(flexgen_of_match, np);
336 if (match) {
337 data = (struct clkgen_data *)match->data;
338 flex_flags = data->flags;
339 clk_mode = data->mode;
340 }
341
284 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); 342 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
285 if (!clk_data) 343 if (!clk_data)
286 goto err; 344 goto err;
@@ -307,7 +365,6 @@ static void __init st_of_flexgen_setup(struct device_node *np)
307 for (i = 0; i < clk_data->clk_num; i++) { 365 for (i = 0; i < clk_data->clk_num; i++) {
308 struct clk *clk; 366 struct clk *clk;
309 const char *clk_name; 367 const char *clk_name;
310 unsigned long flex_flags = 0;
311 368
312 if (of_property_read_string_index(np, "clock-output-names", 369 if (of_property_read_string_index(np, "clock-output-names",
313 i, &clk_name)) { 370 i, &clk_name)) {
@@ -323,7 +380,7 @@ static void __init st_of_flexgen_setup(struct device_node *np)
323 continue; 380 continue;
324 381
325 clk = clk_register_flexgen(clk_name, parents, num_parents, 382 clk = clk_register_flexgen(clk_name, parents, num_parents,
326 reg, rlock, i, flex_flags); 383 reg, rlock, i, flex_flags, clk_mode);
327 384
328 if (IS_ERR(clk)) 385 if (IS_ERR(clk))
329 goto err; 386 goto err;
diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c
index 09afeb85109c..14819d919df1 100644
--- a/drivers/clk/st/clkgen-fsyn.c
+++ b/drivers/clk/st/clkgen-fsyn.c
@@ -42,79 +42,6 @@ struct stm_fs {
42 unsigned long nsdiv; 42 unsigned long nsdiv;
43}; 43};
44 44
45static const struct stm_fs fs216c65_rtbl[] = {
46 { .mdiv = 0x1f, .pe = 0x0, .sdiv = 0x7, .nsdiv = 0 }, /* 312.5 Khz */
47 { .mdiv = 0x17, .pe = 0x25ed, .sdiv = 0x1, .nsdiv = 0 }, /* 27 MHz */
48 { .mdiv = 0x1a, .pe = 0x7b36, .sdiv = 0x2, .nsdiv = 1 }, /* 36.87 MHz */
49 { .mdiv = 0x13, .pe = 0x0, .sdiv = 0x2, .nsdiv = 1 }, /* 48 MHz */
50 { .mdiv = 0x11, .pe = 0x1c72, .sdiv = 0x1, .nsdiv = 1 }, /* 108 MHz */
51};
52
53static const struct stm_fs fs432c65_rtbl[] = {
54 { .mdiv = 0x1f, .pe = 0x0, .sdiv = 0x7, .nsdiv = 0 }, /* 625 Khz */
55 { .mdiv = 0x13, .pe = 0x777c, .sdiv = 0x4, .nsdiv = 1 }, /* 25.175 MHz */
56 { .mdiv = 0x19, .pe = 0x4d35, .sdiv = 0x2, .nsdiv = 0 }, /* 25.200 MHz */
57 { .mdiv = 0x11, .pe = 0x1c72, .sdiv = 0x4, .nsdiv = 1 }, /* 27.000 MHz */
58 { .mdiv = 0x17, .pe = 0x28f5, .sdiv = 0x2, .nsdiv = 0 }, /* 27.027 MHz */
59 { .mdiv = 0x16, .pe = 0x3359, .sdiv = 0x2, .nsdiv = 0 }, /* 28.320 MHz */
60 { .mdiv = 0x1f, .pe = 0x2083, .sdiv = 0x3, .nsdiv = 1 }, /* 30.240 MHz */
61 { .mdiv = 0x1e, .pe = 0x430d, .sdiv = 0x3, .nsdiv = 1 }, /* 31.500 MHz */
62 { .mdiv = 0x17, .pe = 0x0, .sdiv = 0x3, .nsdiv = 1 }, /* 40.000 MHz */
63 { .mdiv = 0x19, .pe = 0x121a, .sdiv = 0x1, .nsdiv = 0 }, /* 49.500 MHz */
64 { .mdiv = 0x13, .pe = 0x6667, .sdiv = 0x3, .nsdiv = 1 }, /* 50.000 MHz */
65 { .mdiv = 0x10, .pe = 0x1ee6, .sdiv = 0x3, .nsdiv = 1 }, /* 57.284 MHz */
66 { .mdiv = 0x1d, .pe = 0x3b14, .sdiv = 0x2, .nsdiv = 1 }, /* 65.000 MHz */
67 { .mdiv = 0x12, .pe = 0x7c65, .sdiv = 0x1, .nsdiv = 0 }, /* 71.000 MHz */
68 { .mdiv = 0x19, .pe = 0xecd, .sdiv = 0x2, .nsdiv = 1 }, /* 74.176 MHz */
69 { .mdiv = 0x19, .pe = 0x121a, .sdiv = 0x2, .nsdiv = 1 }, /* 74.250 MHz */
70 { .mdiv = 0x19, .pe = 0x3334, .sdiv = 0x2, .nsdiv = 1 }, /* 75.000 MHz */
71 { .mdiv = 0x18, .pe = 0x5138, .sdiv = 0x2, .nsdiv = 1 }, /* 78.800 MHz */
72 { .mdiv = 0x1d, .pe = 0x77d, .sdiv = 0x0, .nsdiv = 0 }, /* 85.500 MHz */
73 { .mdiv = 0x1c, .pe = 0x13d5, .sdiv = 0x0, .nsdiv = 0 }, /* 88.750 MHz */
74 { .mdiv = 0x11, .pe = 0x1c72, .sdiv = 0x2, .nsdiv = 1 }, /* 108.000 MHz */
75 { .mdiv = 0x17, .pe = 0x28f5, .sdiv = 0x0, .nsdiv = 0 }, /* 108.108 MHz */
76 { .mdiv = 0x10, .pe = 0x6e26, .sdiv = 0x2, .nsdiv = 1 }, /* 118.963 MHz */
77 { .mdiv = 0x15, .pe = 0x3e63, .sdiv = 0x0, .nsdiv = 0 }, /* 119.000 MHz */
78 { .mdiv = 0x1c, .pe = 0x471d, .sdiv = 0x1, .nsdiv = 1 }, /* 135.000 MHz */
79 { .mdiv = 0x19, .pe = 0xecd, .sdiv = 0x1, .nsdiv = 1 }, /* 148.352 MHz */
80 { .mdiv = 0x19, .pe = 0x121a, .sdiv = 0x1, .nsdiv = 1 }, /* 148.500 MHz */
81 { .mdiv = 0x19, .pe = 0x121a, .sdiv = 0x0, .nsdiv = 1 }, /* 297 MHz */
82};
83
84static const struct stm_fs fs660c32_rtbl[] = {
85 { .mdiv = 0x14, .pe = 0x376b, .sdiv = 0x4, .nsdiv = 1 }, /* 25.175 MHz */
86 { .mdiv = 0x14, .pe = 0x30c3, .sdiv = 0x4, .nsdiv = 1 }, /* 25.200 MHz */
87 { .mdiv = 0x10, .pe = 0x71c7, .sdiv = 0x4, .nsdiv = 1 }, /* 27.000 MHz */
88 { .mdiv = 0x00, .pe = 0x47af, .sdiv = 0x3, .nsdiv = 0 }, /* 27.027 MHz */
89 { .mdiv = 0x0e, .pe = 0x4e1a, .sdiv = 0x4, .nsdiv = 1 }, /* 28.320 MHz */
90 { .mdiv = 0x0b, .pe = 0x534d, .sdiv = 0x4, .nsdiv = 1 }, /* 30.240 MHz */
91 { .mdiv = 0x17, .pe = 0x6fbf, .sdiv = 0x2, .nsdiv = 0 }, /* 31.500 MHz */
92 { .mdiv = 0x01, .pe = 0x0, .sdiv = 0x4, .nsdiv = 1 }, /* 40.000 MHz */
93 { .mdiv = 0x15, .pe = 0x2aab, .sdiv = 0x3, .nsdiv = 1 }, /* 49.500 MHz */
94 { .mdiv = 0x14, .pe = 0x6666, .sdiv = 0x3, .nsdiv = 1 }, /* 50.000 MHz */
95 { .mdiv = 0x1d, .pe = 0x395f, .sdiv = 0x1, .nsdiv = 0 }, /* 57.284 MHz */
96 { .mdiv = 0x08, .pe = 0x4ec5, .sdiv = 0x3, .nsdiv = 1 }, /* 65.000 MHz */
97 { .mdiv = 0x05, .pe = 0x1770, .sdiv = 0x3, .nsdiv = 1 }, /* 71.000 MHz */
98 { .mdiv = 0x03, .pe = 0x4ba7, .sdiv = 0x3, .nsdiv = 1 }, /* 74.176 MHz */
99 { .mdiv = 0x0f, .pe = 0x3426, .sdiv = 0x1, .nsdiv = 0 }, /* 74.250 MHz */
100 { .mdiv = 0x0e, .pe = 0x7777, .sdiv = 0x1, .nsdiv = 0 }, /* 75.000 MHz */
101 { .mdiv = 0x01, .pe = 0x4053, .sdiv = 0x3, .nsdiv = 1 }, /* 78.800 MHz */
102 { .mdiv = 0x09, .pe = 0x15b5, .sdiv = 0x1, .nsdiv = 0 }, /* 85.500 MHz */
103 { .mdiv = 0x1b, .pe = 0x3f19, .sdiv = 0x2, .nsdiv = 1 }, /* 88.750 MHz */
104 { .mdiv = 0x10, .pe = 0x71c7, .sdiv = 0x2, .nsdiv = 1 }, /* 108.000 MHz */
105 { .mdiv = 0x00, .pe = 0x47af, .sdiv = 0x1, .nsdiv = 0 }, /* 108.108 MHz */
106 { .mdiv = 0x0c, .pe = 0x3118, .sdiv = 0x2, .nsdiv = 1 }, /* 118.963 MHz */
107 { .mdiv = 0x0c, .pe = 0x2f54, .sdiv = 0x2, .nsdiv = 1 }, /* 119.000 MHz */
108 { .mdiv = 0x07, .pe = 0xe39, .sdiv = 0x2, .nsdiv = 1 }, /* 135.000 MHz */
109 { .mdiv = 0x03, .pe = 0x4ba7, .sdiv = 0x2, .nsdiv = 1 }, /* 148.352 MHz */
110 { .mdiv = 0x0f, .pe = 0x3426, .sdiv = 0x0, .nsdiv = 0 }, /* 148.500 MHz */
111 { .mdiv = 0x03, .pe = 0x4ba7, .sdiv = 0x1, .nsdiv = 1 }, /* 296.704 MHz */
112 { .mdiv = 0x03, .pe = 0x471c, .sdiv = 0x1, .nsdiv = 1 }, /* 297.000 MHz */
113 { .mdiv = 0x00, .pe = 0x295f, .sdiv = 0x1, .nsdiv = 1 }, /* 326.700 MHz */
114 { .mdiv = 0x1f, .pe = 0x3633, .sdiv = 0x0, .nsdiv = 1 }, /* 333.000 MHz */
115 { .mdiv = 0x1c, .pe = 0x0, .sdiv = 0x0, .nsdiv = 1 }, /* 352.000 Mhz */
116};
117
118struct clkgen_quadfs_data { 45struct clkgen_quadfs_data {
119 bool reset_present; 46 bool reset_present;
120 bool bwfilter_present; 47 bool bwfilter_present;
@@ -138,174 +65,18 @@ struct clkgen_quadfs_data {
138 struct clkgen_field nsdiv[QUADFS_MAX_CHAN]; 65 struct clkgen_field nsdiv[QUADFS_MAX_CHAN];
139 66
140 const struct clk_ops *pll_ops; 67 const struct clk_ops *pll_ops;
141 const struct stm_fs *rtbl; 68 int (*get_params)(unsigned long, unsigned long, struct stm_fs *);
142 u8 rtbl_cnt;
143 int (*get_rate)(unsigned long , const struct stm_fs *, 69 int (*get_rate)(unsigned long , const struct stm_fs *,
144 unsigned long *); 70 unsigned long *);
145}; 71};
146 72
147static const struct clk_ops st_quadfs_pll_c65_ops;
148static const struct clk_ops st_quadfs_pll_c32_ops; 73static const struct clk_ops st_quadfs_pll_c32_ops;
149static const struct clk_ops st_quadfs_fs216c65_ops;
150static const struct clk_ops st_quadfs_fs432c65_ops;
151static const struct clk_ops st_quadfs_fs660c32_ops; 74static const struct clk_ops st_quadfs_fs660c32_ops;
152 75
153static int clk_fs216c65_get_rate(unsigned long, const struct stm_fs *, 76static int clk_fs660c32_dig_get_params(unsigned long input,
154 unsigned long *); 77 unsigned long output, struct stm_fs *fs);
155static int clk_fs432c65_get_rate(unsigned long, const struct stm_fs *,
156 unsigned long *);
157static int clk_fs660c32_dig_get_rate(unsigned long, const struct stm_fs *, 78static int clk_fs660c32_dig_get_rate(unsigned long, const struct stm_fs *,
158 unsigned long *); 79 unsigned long *);
159/*
160 * Values for all of the standalone instances of this clock
161 * generator found in STiH415 and STiH416 SYSCFG register banks. Note
162 * that the individual channel standby control bits (nsb) are in the
163 * first register along with the PLL control bits.
164 */
165static const struct clkgen_quadfs_data st_fs216c65_416 = {
166 /* 416 specific */
167 .npda = CLKGEN_FIELD(0x0, 0x1, 14),
168 .nsb = { CLKGEN_FIELD(0x0, 0x1, 10),
169 CLKGEN_FIELD(0x0, 0x1, 11),
170 CLKGEN_FIELD(0x0, 0x1, 12),
171 CLKGEN_FIELD(0x0, 0x1, 13) },
172 .nsdiv_present = true,
173 .nsdiv = { CLKGEN_FIELD(0x0, 0x1, 18),
174 CLKGEN_FIELD(0x0, 0x1, 19),
175 CLKGEN_FIELD(0x0, 0x1, 20),
176 CLKGEN_FIELD(0x0, 0x1, 21) },
177 .mdiv = { CLKGEN_FIELD(0x4, 0x1f, 0),
178 CLKGEN_FIELD(0x14, 0x1f, 0),
179 CLKGEN_FIELD(0x24, 0x1f, 0),
180 CLKGEN_FIELD(0x34, 0x1f, 0) },
181 .en = { CLKGEN_FIELD(0x10, 0x1, 0),
182 CLKGEN_FIELD(0x20, 0x1, 0),
183 CLKGEN_FIELD(0x30, 0x1, 0),
184 CLKGEN_FIELD(0x40, 0x1, 0) },
185 .ndiv = CLKGEN_FIELD(0x0, 0x1, 15),
186 .bwfilter_present = true,
187 .ref_bw = CLKGEN_FIELD(0x0, 0x3, 16),
188 .pe = { CLKGEN_FIELD(0x8, 0xffff, 0),
189 CLKGEN_FIELD(0x18, 0xffff, 0),
190 CLKGEN_FIELD(0x28, 0xffff, 0),
191 CLKGEN_FIELD(0x38, 0xffff, 0) },
192 .sdiv = { CLKGEN_FIELD(0xC, 0x7, 0),
193 CLKGEN_FIELD(0x1C, 0x7, 0),
194 CLKGEN_FIELD(0x2C, 0x7, 0),
195 CLKGEN_FIELD(0x3C, 0x7, 0) },
196 .pll_ops = &st_quadfs_pll_c65_ops,
197 .rtbl = fs216c65_rtbl,
198 .rtbl_cnt = ARRAY_SIZE(fs216c65_rtbl),
199 .get_rate = clk_fs216c65_get_rate,
200};
201
202static const struct clkgen_quadfs_data st_fs432c65_416 = {
203 .npda = CLKGEN_FIELD(0x0, 0x1, 14),
204 .nsb = { CLKGEN_FIELD(0x0, 0x1, 10),
205 CLKGEN_FIELD(0x0, 0x1, 11),
206 CLKGEN_FIELD(0x0, 0x1, 12),
207 CLKGEN_FIELD(0x0, 0x1, 13) },
208 .nsdiv_present = true,
209 .nsdiv = { CLKGEN_FIELD(0x0, 0x1, 18),
210 CLKGEN_FIELD(0x0, 0x1, 19),
211 CLKGEN_FIELD(0x0, 0x1, 20),
212 CLKGEN_FIELD(0x0, 0x1, 21) },
213 .mdiv = { CLKGEN_FIELD(0x4, 0x1f, 0),
214 CLKGEN_FIELD(0x14, 0x1f, 0),
215 CLKGEN_FIELD(0x24, 0x1f, 0),
216 CLKGEN_FIELD(0x34, 0x1f, 0) },
217 .en = { CLKGEN_FIELD(0x10, 0x1, 0),
218 CLKGEN_FIELD(0x20, 0x1, 0),
219 CLKGEN_FIELD(0x30, 0x1, 0),
220 CLKGEN_FIELD(0x40, 0x1, 0) },
221 .ndiv = CLKGEN_FIELD(0x0, 0x1, 15),
222 .bwfilter_present = true,
223 .ref_bw = CLKGEN_FIELD(0x0, 0x3, 16),
224 .pe = { CLKGEN_FIELD(0x8, 0xffff, 0),
225 CLKGEN_FIELD(0x18, 0xffff, 0),
226 CLKGEN_FIELD(0x28, 0xffff, 0),
227 CLKGEN_FIELD(0x38, 0xffff, 0) },
228 .sdiv = { CLKGEN_FIELD(0xC, 0x7, 0),
229 CLKGEN_FIELD(0x1C, 0x7, 0),
230 CLKGEN_FIELD(0x2C, 0x7, 0),
231 CLKGEN_FIELD(0x3C, 0x7, 0) },
232 .pll_ops = &st_quadfs_pll_c65_ops,
233 .rtbl = fs432c65_rtbl,
234 .rtbl_cnt = ARRAY_SIZE(fs432c65_rtbl),
235 .get_rate = clk_fs432c65_get_rate,
236};
237
238static const struct clkgen_quadfs_data st_fs660c32_E_416 = {
239 .npda = CLKGEN_FIELD(0x0, 0x1, 14),
240 .nsb = { CLKGEN_FIELD(0x0, 0x1, 10),
241 CLKGEN_FIELD(0x0, 0x1, 11),
242 CLKGEN_FIELD(0x0, 0x1, 12),
243 CLKGEN_FIELD(0x0, 0x1, 13) },
244 .nsdiv_present = true,
245 .nsdiv = { CLKGEN_FIELD(0x0, 0x1, 18),
246 CLKGEN_FIELD(0x0, 0x1, 19),
247 CLKGEN_FIELD(0x0, 0x1, 20),
248 CLKGEN_FIELD(0x0, 0x1, 21) },
249 .mdiv = { CLKGEN_FIELD(0x4, 0x1f, 0),
250 CLKGEN_FIELD(0x14, 0x1f, 0),
251 CLKGEN_FIELD(0x24, 0x1f, 0),
252 CLKGEN_FIELD(0x34, 0x1f, 0) },
253 .en = { CLKGEN_FIELD(0x10, 0x1, 0),
254 CLKGEN_FIELD(0x20, 0x1, 0),
255 CLKGEN_FIELD(0x30, 0x1, 0),
256 CLKGEN_FIELD(0x40, 0x1, 0) },
257 .ndiv = CLKGEN_FIELD(0x0, 0x7, 15),
258 .pe = { CLKGEN_FIELD(0x8, 0x7fff, 0),
259 CLKGEN_FIELD(0x18, 0x7fff, 0),
260 CLKGEN_FIELD(0x28, 0x7fff, 0),
261 CLKGEN_FIELD(0x38, 0x7fff, 0) },
262 .sdiv = { CLKGEN_FIELD(0xC, 0xf, 0),
263 CLKGEN_FIELD(0x1C, 0xf, 0),
264 CLKGEN_FIELD(0x2C, 0xf, 0),
265 CLKGEN_FIELD(0x3C, 0xf, 0) },
266 .lockstatus_present = true,
267 .lock_status = CLKGEN_FIELD(0xAC, 0x1, 0),
268 .pll_ops = &st_quadfs_pll_c32_ops,
269 .rtbl = fs660c32_rtbl,
270 .rtbl_cnt = ARRAY_SIZE(fs660c32_rtbl),
271 .get_rate = clk_fs660c32_dig_get_rate,
272};
273
274static const struct clkgen_quadfs_data st_fs660c32_F_416 = {
275 .npda = CLKGEN_FIELD(0x0, 0x1, 14),
276 .nsb = { CLKGEN_FIELD(0x0, 0x1, 10),
277 CLKGEN_FIELD(0x0, 0x1, 11),
278 CLKGEN_FIELD(0x0, 0x1, 12),
279 CLKGEN_FIELD(0x0, 0x1, 13) },
280 .nsdiv_present = true,
281 .nsdiv = { CLKGEN_FIELD(0x0, 0x1, 18),
282 CLKGEN_FIELD(0x0, 0x1, 19),
283 CLKGEN_FIELD(0x0, 0x1, 20),
284 CLKGEN_FIELD(0x0, 0x1, 21) },
285 .mdiv = { CLKGEN_FIELD(0x4, 0x1f, 0),
286 CLKGEN_FIELD(0x14, 0x1f, 0),
287 CLKGEN_FIELD(0x24, 0x1f, 0),
288 CLKGEN_FIELD(0x34, 0x1f, 0) },
289 .en = { CLKGEN_FIELD(0x10, 0x1, 0),
290 CLKGEN_FIELD(0x20, 0x1, 0),
291 CLKGEN_FIELD(0x30, 0x1, 0),
292 CLKGEN_FIELD(0x40, 0x1, 0) },
293 .ndiv = CLKGEN_FIELD(0x0, 0x7, 15),
294 .pe = { CLKGEN_FIELD(0x8, 0x7fff, 0),
295 CLKGEN_FIELD(0x18, 0x7fff, 0),
296 CLKGEN_FIELD(0x28, 0x7fff, 0),
297 CLKGEN_FIELD(0x38, 0x7fff, 0) },
298 .sdiv = { CLKGEN_FIELD(0xC, 0xf, 0),
299 CLKGEN_FIELD(0x1C, 0xf, 0),
300 CLKGEN_FIELD(0x2C, 0xf, 0),
301 CLKGEN_FIELD(0x3C, 0xf, 0) },
302 .lockstatus_present = true,
303 .lock_status = CLKGEN_FIELD(0xEC, 0x1, 0),
304 .pll_ops = &st_quadfs_pll_c32_ops,
305 .rtbl = fs660c32_rtbl,
306 .rtbl_cnt = ARRAY_SIZE(fs660c32_rtbl),
307 .get_rate = clk_fs660c32_dig_get_rate,
308};
309 80
310static const struct clkgen_quadfs_data st_fs660c32_C = { 81static const struct clkgen_quadfs_data st_fs660c32_C = {
311 .nrst_present = true, 82 .nrst_present = true,
@@ -345,8 +116,7 @@ static const struct clkgen_quadfs_data st_fs660c32_C = {
345 .powerup_polarity = 1, 116 .powerup_polarity = 1,
346 .standby_polarity = 1, 117 .standby_polarity = 1,
347 .pll_ops = &st_quadfs_pll_c32_ops, 118 .pll_ops = &st_quadfs_pll_c32_ops,
348 .rtbl = fs660c32_rtbl, 119 .get_params = clk_fs660c32_dig_get_params,
349 .rtbl_cnt = ARRAY_SIZE(fs660c32_rtbl),
350 .get_rate = clk_fs660c32_dig_get_rate, 120 .get_rate = clk_fs660c32_dig_get_rate,
351}; 121};
352 122
@@ -388,8 +158,7 @@ static const struct clkgen_quadfs_data st_fs660c32_D = {
388 .powerup_polarity = 1, 158 .powerup_polarity = 1,
389 .standby_polarity = 1, 159 .standby_polarity = 1,
390 .pll_ops = &st_quadfs_pll_c32_ops, 160 .pll_ops = &st_quadfs_pll_c32_ops,
391 .rtbl = fs660c32_rtbl, 161 .get_params = clk_fs660c32_dig_get_params,
392 .rtbl_cnt = ARRAY_SIZE(fs660c32_rtbl),
393 .get_rate = clk_fs660c32_dig_get_rate,}; 162 .get_rate = clk_fs660c32_dig_get_rate,};
394 163
395/** 164/**
@@ -605,12 +374,6 @@ static int quadfs_pll_fs660c32_set_rate(struct clk_hw *hw, unsigned long rate,
605 return 0; 374 return 0;
606} 375}
607 376
608static const struct clk_ops st_quadfs_pll_c65_ops = {
609 .enable = quadfs_pll_enable,
610 .disable = quadfs_pll_disable,
611 .is_enabled = quadfs_pll_is_enabled,
612};
613
614static const struct clk_ops st_quadfs_pll_c32_ops = { 377static const struct clk_ops st_quadfs_pll_c32_ops = {
615 .enable = quadfs_pll_enable, 378 .enable = quadfs_pll_enable,
616 .disable = quadfs_pll_disable, 379 .disable = quadfs_pll_disable,
@@ -797,48 +560,6 @@ static int quadfs_fsynth_is_enabled(struct clk_hw *hw)
797 return fs->data->standby_polarity ? !nsb : !!nsb; 560 return fs->data->standby_polarity ? !nsb : !!nsb;
798} 561}
799 562
800#define P15 (uint64_t)(1 << 15)
801
802static int clk_fs216c65_get_rate(unsigned long input, const struct stm_fs *fs,
803 unsigned long *rate)
804{
805 uint64_t res;
806 unsigned long ns;
807 unsigned long nd = 8; /* ndiv stuck at 0 => val = 8 */
808 unsigned long s;
809 long m;
810
811 m = fs->mdiv - 32;
812 s = 1 << (fs->sdiv + 1);
813 ns = (fs->nsdiv ? 1 : 3);
814
815 res = (uint64_t)(s * ns * P15 * (uint64_t)(m + 33));
816 res = res - (s * ns * fs->pe);
817 *rate = div64_u64(P15 * nd * input * 32, res);
818
819 return 0;
820}
821
822static int clk_fs432c65_get_rate(unsigned long input, const struct stm_fs *fs,
823 unsigned long *rate)
824{
825 uint64_t res;
826 unsigned long nd = 16; /* ndiv value; stuck at 0 (30Mhz input) */
827 long m;
828 unsigned long sd;
829 unsigned long ns;
830
831 m = fs->mdiv - 32;
832 sd = 1 << (fs->sdiv + 1);
833 ns = (fs->nsdiv ? 1 : 3);
834
835 res = (uint64_t)(sd * ns * P15 * (uint64_t)(m + 33));
836 res = res - (sd * ns * fs->pe);
837 *rate = div64_u64(P15 * nd * input * 32, res);
838
839 return 0;
840}
841
842#define P20 (uint64_t)(1 << 20) 563#define P20 (uint64_t)(1 << 20)
843 564
844static int clk_fs660c32_dig_get_rate(unsigned long input, 565static int clk_fs660c32_dig_get_rate(unsigned long input,
@@ -864,6 +585,107 @@ static int clk_fs660c32_dig_get_rate(unsigned long input,
864 return 0; 585 return 0;
865} 586}
866 587
588
589static int clk_fs660c32_get_pe(int m, int si, unsigned long *deviation,
590 signed long input, unsigned long output, uint64_t *p,
591 struct stm_fs *fs)
592{
593 unsigned long new_freq, new_deviation;
594 struct stm_fs fs_tmp;
595 uint64_t val;
596
597 val = (uint64_t)output << si;
598
599 *p = (uint64_t)input * P20 - (32LL + (uint64_t)m) * val * (P20 / 32LL);
600
601 *p = div64_u64(*p, val);
602
603 if (*p > 32767LL)
604 return 1;
605
606 fs_tmp.mdiv = (unsigned long) m;
607 fs_tmp.pe = (unsigned long)*p;
608 fs_tmp.sdiv = si;
609 fs_tmp.nsdiv = 1;
610
611 clk_fs660c32_dig_get_rate(input, &fs_tmp, &new_freq);
612
613 new_deviation = abs(output - new_freq);
614
615 if (new_deviation < *deviation) {
616 fs->mdiv = m;
617 fs->pe = (unsigned long)*p;
618 fs->sdiv = si;
619 fs->nsdiv = 1;
620 *deviation = new_deviation;
621 }
622 return 0;
623}
624
625static int clk_fs660c32_dig_get_params(unsigned long input,
626 unsigned long output, struct stm_fs *fs)
627{
628 int si; /* sdiv_reg (8 downto 0) */
629 int m; /* md value */
630 unsigned long new_freq, new_deviation;
631 /* initial condition to say: "infinite deviation" */
632 unsigned long deviation = ~0;
633 uint64_t p, p1, p2; /* pe value */
634 int r1, r2;
635
636 struct stm_fs fs_tmp;
637
638 for (si = 0; (si <= 8) && deviation; si++) {
639
640 /* Boundary test to avoid useless iteration */
641 r1 = clk_fs660c32_get_pe(0, si, &deviation,
642 input, output, &p1, fs);
643 r2 = clk_fs660c32_get_pe(31, si, &deviation,
644 input, output, &p2, fs);
645
646 /* No solution */
647 if (r1 && r2 && (p1 > p2))
648 continue;
649
650 /* Try to find best deviation */
651 for (m = 1; (m < 31) && deviation; m++)
652 clk_fs660c32_get_pe(m, si, &deviation,
653 input, output, &p, fs);
654
655 }
656
657 if (deviation == ~0) /* No solution found */
658 return -1;
659
660 /* pe fine tuning if deviation not 0: +/- 2 around computed pe value */
661 if (deviation) {
662 fs_tmp.mdiv = fs->mdiv;
663 fs_tmp.sdiv = fs->sdiv;
664 fs_tmp.nsdiv = fs->nsdiv;
665
666 if (fs->pe > 2)
667 p2 = fs->pe - 2;
668 else
669 p2 = 0;
670
671 for (; p2 < 32768ll && (p2 <= (fs->pe + 2)); p2++) {
672 fs_tmp.pe = (unsigned long)p2;
673
674 clk_fs660c32_dig_get_rate(input, &fs_tmp, &new_freq);
675
676 new_deviation = abs(output - new_freq);
677
678 /* Check if this is a better solution */
679 if (new_deviation < deviation) {
680 fs->pe = (unsigned long)p2;
681 deviation = new_deviation;
682
683 }
684 }
685 }
686 return 0;
687}
688
867static int quadfs_fsynt_get_hw_value_for_recalc(struct st_clk_quadfs_fsynth *fs, 689static int quadfs_fsynt_get_hw_value_for_recalc(struct st_clk_quadfs_fsynth *fs,
868 struct stm_fs *params) 690 struct stm_fs *params)
869{ 691{
@@ -899,38 +721,14 @@ static long quadfs_find_best_rate(struct clk_hw *hw, unsigned long drate,
899 struct st_clk_quadfs_fsynth *fs = to_quadfs_fsynth(hw); 721 struct st_clk_quadfs_fsynth *fs = to_quadfs_fsynth(hw);
900 int (*clk_fs_get_rate)(unsigned long , 722 int (*clk_fs_get_rate)(unsigned long ,
901 const struct stm_fs *, unsigned long *); 723 const struct stm_fs *, unsigned long *);
902 struct stm_fs prev_params; 724 int (*clk_fs_get_params)(unsigned long, unsigned long, struct stm_fs *);
903 unsigned long prev_rate, rate = 0; 725 unsigned long rate = 0;
904 unsigned long diff_rate, prev_diff_rate = ~0;
905 int index;
906 726
907 clk_fs_get_rate = fs->data->get_rate; 727 clk_fs_get_rate = fs->data->get_rate;
728 clk_fs_get_params = fs->data->get_params;
908 729
909 for (index = 0; index < fs->data->rtbl_cnt; index++) { 730 if (!clk_fs_get_params(prate, drate, params))
910 prev_rate = rate; 731 clk_fs_get_rate(prate, params, &rate);
911
912 *params = fs->data->rtbl[index];
913 prev_params = *params;
914
915 clk_fs_get_rate(prate, &fs->data->rtbl[index], &rate);
916
917 diff_rate = abs(drate - rate);
918
919 if (diff_rate > prev_diff_rate) {
920 rate = prev_rate;
921 *params = prev_params;
922 break;
923 }
924
925 prev_diff_rate = diff_rate;
926
927 if (drate == rate)
928 return rate;
929 }
930
931
932 if (index == fs->data->rtbl_cnt)
933 *params = prev_params;
934 732
935 return rate; 733 return rate;
936} 734}
@@ -1063,34 +861,6 @@ static struct clk * __init st_clk_register_quadfs_fsynth(
1063 return clk; 861 return clk;
1064} 862}
1065 863
1066static const struct of_device_id quadfs_of_match[] = {
1067 {
1068 .compatible = "st,stih416-quadfs216",
1069 .data = &st_fs216c65_416
1070 },
1071 {
1072 .compatible = "st,stih416-quadfs432",
1073 .data = &st_fs432c65_416
1074 },
1075 {
1076 .compatible = "st,stih416-quadfs660-E",
1077 .data = &st_fs660c32_E_416
1078 },
1079 {
1080 .compatible = "st,stih416-quadfs660-F",
1081 .data = &st_fs660c32_F_416
1082 },
1083 {
1084 .compatible = "st,stih407-quadfs660-C",
1085 .data = &st_fs660c32_C
1086 },
1087 {
1088 .compatible = "st,stih407-quadfs660-D",
1089 .data = &st_fs660c32_D
1090 },
1091 {}
1092};
1093
1094static void __init st_of_create_quadfs_fsynths( 864static void __init st_of_create_quadfs_fsynths(
1095 struct device_node *np, const char *pll_name, 865 struct device_node *np, const char *pll_name,
1096 struct clkgen_quadfs_data *quadfs, void __iomem *reg, 866 struct clkgen_quadfs_data *quadfs, void __iomem *reg,
@@ -1150,18 +920,14 @@ static void __init st_of_create_quadfs_fsynths(
1150 of_clk_add_provider(np, of_clk_src_onecell_get, clk_data); 920 of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
1151} 921}
1152 922
1153static void __init st_of_quadfs_setup(struct device_node *np) 923static void __init st_of_quadfs_setup(struct device_node *np,
924 struct clkgen_quadfs_data *data)
1154{ 925{
1155 const struct of_device_id *match;
1156 struct clk *clk; 926 struct clk *clk;
1157 const char *pll_name, *clk_parent_name; 927 const char *pll_name, *clk_parent_name;
1158 void __iomem *reg; 928 void __iomem *reg;
1159 spinlock_t *lock; 929 spinlock_t *lock;
1160 930
1161 match = of_match_node(quadfs_of_match, np);
1162 if (WARN_ON(!match))
1163 return;
1164
1165 reg = of_iomap(np, 0); 931 reg = of_iomap(np, 0);
1166 if (!reg) 932 if (!reg)
1167 return; 933 return;
@@ -1180,8 +946,8 @@ static void __init st_of_quadfs_setup(struct device_node *np)
1180 946
1181 spin_lock_init(lock); 947 spin_lock_init(lock);
1182 948
1183 clk = st_clk_register_quadfs_pll(pll_name, clk_parent_name, 949 clk = st_clk_register_quadfs_pll(pll_name, clk_parent_name, data,
1184 (struct clkgen_quadfs_data *) match->data, reg, lock); 950 reg, lock);
1185 if (IS_ERR(clk)) 951 if (IS_ERR(clk))
1186 goto err_exit; 952 goto err_exit;
1187 else 953 else
@@ -1190,11 +956,20 @@ static void __init st_of_quadfs_setup(struct device_node *np)
1190 __clk_get_name(clk_get_parent(clk)), 956 __clk_get_name(clk_get_parent(clk)),
1191 (unsigned int)clk_get_rate(clk)); 957 (unsigned int)clk_get_rate(clk));
1192 958
1193 st_of_create_quadfs_fsynths(np, pll_name, 959 st_of_create_quadfs_fsynths(np, pll_name, data, reg, lock);
1194 (struct clkgen_quadfs_data *)match->data,
1195 reg, lock);
1196 960
1197err_exit: 961err_exit:
1198 kfree(pll_name); /* No longer need local copy of the PLL name */ 962 kfree(pll_name); /* No longer need local copy of the PLL name */
1199} 963}
1200CLK_OF_DECLARE(quadfs, "st,quadfs", st_of_quadfs_setup); 964
965static void __init st_of_quadfs660C_setup(struct device_node *np)
966{
967 st_of_quadfs_setup(np, (struct clkgen_quadfs_data *) &st_fs660c32_C);
968}
969CLK_OF_DECLARE(quadfs660C, "st,quadfs-pll", st_of_quadfs660C_setup);
970
971static void __init st_of_quadfs660D_setup(struct device_node *np)
972{
973 st_of_quadfs_setup(np, (struct clkgen_quadfs_data *) &st_fs660c32_D);
974}
975CLK_OF_DECLARE(quadfs660D, "st,quadfs", st_of_quadfs660D_setup);
diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c
index b1e10ffe7a44..c514d39760cb 100644
--- a/drivers/clk/st/clkgen-mux.c
+++ b/drivers/clk/st/clkgen-mux.c
@@ -19,9 +19,6 @@
19#include <linux/clk-provider.h> 19#include <linux/clk-provider.h>
20#include "clkgen.h" 20#include "clkgen.h"
21 21
22static DEFINE_SPINLOCK(clkgena_divmux_lock);
23static DEFINE_SPINLOCK(clkgenf_lock);
24
25static const char ** __init clkgen_mux_get_parents(struct device_node *np, 22static const char ** __init clkgen_mux_get_parents(struct device_node *np,
26 int *num_parents) 23 int *num_parents)
27{ 24{
@@ -40,498 +37,6 @@ static const char ** __init clkgen_mux_get_parents(struct device_node *np,
40 return parents; 37 return parents;
41} 38}
42 39
43/**
44 * DOC: Clock mux with a programmable divider on each of its three inputs.
45 * The mux has an input setting which effectively gates its output.
46 *
47 * Traits of this clock:
48 * prepare - clk_(un)prepare only ensures parent is (un)prepared
49 * enable - clk_enable and clk_disable are functional & control gating
50 * rate - set rate is supported
51 * parent - set/get parent
52 */
53
54#define NUM_INPUTS 3
55
56struct clkgena_divmux {
57 struct clk_hw hw;
58 /* Subclassed mux and divider structures */
59 struct clk_mux mux;
60 struct clk_divider div[NUM_INPUTS];
61 /* Enable/running feedback register bits for each input */
62 void __iomem *feedback_reg[NUM_INPUTS];
63 int feedback_bit_idx;
64
65 u8 muxsel;
66};
67
68#define to_clkgena_divmux(_hw) container_of(_hw, struct clkgena_divmux, hw)
69
70struct clkgena_divmux_data {
71 int num_outputs;
72 int mux_offset;
73 int mux_offset2;
74 int mux_start_bit;
75 int div_offsets[NUM_INPUTS];
76 int fb_offsets[NUM_INPUTS];
77 int fb_start_bit_idx;
78};
79
80#define CKGAX_CLKOPSRC_SWITCH_OFF 0x3
81
82static int clkgena_divmux_is_running(struct clkgena_divmux *mux)
83{
84 u32 regval = readl(mux->feedback_reg[mux->muxsel]);
85 u32 running = regval & BIT(mux->feedback_bit_idx);
86 return !!running;
87}
88
89static int clkgena_divmux_enable(struct clk_hw *hw)
90{
91 struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
92 struct clk_hw *mux_hw = &genamux->mux.hw;
93 unsigned long timeout;
94 int ret = 0;
95
96 __clk_hw_set_clk(mux_hw, hw);
97
98 ret = clk_mux_ops.set_parent(mux_hw, genamux->muxsel);
99 if (ret)
100 return ret;
101
102 timeout = jiffies + msecs_to_jiffies(10);
103
104 while (!clkgena_divmux_is_running(genamux)) {
105 if (time_after(jiffies, timeout))
106 return -ETIMEDOUT;
107 cpu_relax();
108 }
109
110 return 0;
111}
112
113static void clkgena_divmux_disable(struct clk_hw *hw)
114{
115 struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
116 struct clk_hw *mux_hw = &genamux->mux.hw;
117
118 __clk_hw_set_clk(mux_hw, hw);
119
120 clk_mux_ops.set_parent(mux_hw, CKGAX_CLKOPSRC_SWITCH_OFF);
121}
122
123static int clkgena_divmux_is_enabled(struct clk_hw *hw)
124{
125 struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
126 struct clk_hw *mux_hw = &genamux->mux.hw;
127
128 __clk_hw_set_clk(mux_hw, hw);
129
130 return (s8)clk_mux_ops.get_parent(mux_hw) > 0;
131}
132
133static u8 clkgena_divmux_get_parent(struct clk_hw *hw)
134{
135 struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
136 struct clk_hw *mux_hw = &genamux->mux.hw;
137
138 __clk_hw_set_clk(mux_hw, hw);
139
140 genamux->muxsel = clk_mux_ops.get_parent(mux_hw);
141 if ((s8)genamux->muxsel < 0) {
142 pr_debug("%s: %s: Invalid parent, setting to default.\n",
143 __func__, clk_hw_get_name(hw));
144 genamux->muxsel = 0;
145 }
146
147 return genamux->muxsel;
148}
149
150static int clkgena_divmux_set_parent(struct clk_hw *hw, u8 index)
151{
152 struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
153
154 if (index >= CKGAX_CLKOPSRC_SWITCH_OFF)
155 return -EINVAL;
156
157 genamux->muxsel = index;
158
159 /*
160 * If the mux is already enabled, call enable directly to set the
161 * new mux position and wait for it to start running again. Otherwise
162 * do nothing.
163 */
164 if (clkgena_divmux_is_enabled(hw))
165 clkgena_divmux_enable(hw);
166
167 return 0;
168}
169
170static unsigned long clkgena_divmux_recalc_rate(struct clk_hw *hw,
171 unsigned long parent_rate)
172{
173 struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
174 struct clk_hw *div_hw = &genamux->div[genamux->muxsel].hw;
175
176 __clk_hw_set_clk(div_hw, hw);
177
178 return clk_divider_ops.recalc_rate(div_hw, parent_rate);
179}
180
181static int clkgena_divmux_set_rate(struct clk_hw *hw, unsigned long rate,
182 unsigned long parent_rate)
183{
184 struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
185 struct clk_hw *div_hw = &genamux->div[genamux->muxsel].hw;
186
187 __clk_hw_set_clk(div_hw, hw);
188
189 return clk_divider_ops.set_rate(div_hw, rate, parent_rate);
190}
191
192static long clkgena_divmux_round_rate(struct clk_hw *hw, unsigned long rate,
193 unsigned long *prate)
194{
195 struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
196 struct clk_hw *div_hw = &genamux->div[genamux->muxsel].hw;
197
198 __clk_hw_set_clk(div_hw, hw);
199
200 return clk_divider_ops.round_rate(div_hw, rate, prate);
201}
202
203static const struct clk_ops clkgena_divmux_ops = {
204 .enable = clkgena_divmux_enable,
205 .disable = clkgena_divmux_disable,
206 .is_enabled = clkgena_divmux_is_enabled,
207 .get_parent = clkgena_divmux_get_parent,
208 .set_parent = clkgena_divmux_set_parent,
209 .round_rate = clkgena_divmux_round_rate,
210 .recalc_rate = clkgena_divmux_recalc_rate,
211 .set_rate = clkgena_divmux_set_rate,
212};
213
214/**
215 * clk_register_genamux - register a genamux clock with the clock framework
216 */
217static struct clk * __init clk_register_genamux(const char *name,
218 const char **parent_names, u8 num_parents,
219 void __iomem *reg,
220 const struct clkgena_divmux_data *muxdata,
221 u32 idx)
222{
223 /*
224 * Fixed constants across all ClockgenA variants
225 */
226 const int mux_width = 2;
227 const int divider_width = 5;
228 struct clkgena_divmux *genamux;
229 struct clk *clk;
230 struct clk_init_data init;
231 int i;
232
233 genamux = kzalloc(sizeof(*genamux), GFP_KERNEL);
234 if (!genamux)
235 return ERR_PTR(-ENOMEM);
236
237 init.name = name;
238 init.ops = &clkgena_divmux_ops;
239 init.flags = CLK_IS_BASIC | CLK_GET_RATE_NOCACHE;
240 init.parent_names = parent_names;
241 init.num_parents = num_parents;
242
243 genamux->mux.lock = &clkgena_divmux_lock;
244 genamux->mux.mask = BIT(mux_width) - 1;
245 genamux->mux.shift = muxdata->mux_start_bit + (idx * mux_width);
246 if (genamux->mux.shift > 31) {
247 /*
248 * We have spilled into the second mux register so
249 * adjust the register address and the bit shift accordingly
250 */
251 genamux->mux.reg = reg + muxdata->mux_offset2;
252 genamux->mux.shift -= 32;
253 } else {
254 genamux->mux.reg = reg + muxdata->mux_offset;
255 }
256
257 for (i = 0; i < NUM_INPUTS; i++) {
258 /*
259 * Divider config for each input
260 */
261 void __iomem *divbase = reg + muxdata->div_offsets[i];
262 genamux->div[i].width = divider_width;
263 genamux->div[i].reg = divbase + (idx * sizeof(u32));
264
265 /*
266 * Mux enabled/running feedback register for each input.
267 */
268 genamux->feedback_reg[i] = reg + muxdata->fb_offsets[i];
269 }
270
271 genamux->feedback_bit_idx = muxdata->fb_start_bit_idx + idx;
272 genamux->hw.init = &init;
273
274 clk = clk_register(NULL, &genamux->hw);
275 if (IS_ERR(clk)) {
276 kfree(genamux);
277 goto err;
278 }
279
280 pr_debug("%s: parent %s rate %lu\n",
281 __clk_get_name(clk),
282 __clk_get_name(clk_get_parent(clk)),
283 clk_get_rate(clk));
284err:
285 return clk;
286}
287
288static struct clkgena_divmux_data st_divmux_c65hs = {
289 .num_outputs = 4,
290 .mux_offset = 0x14,
291 .mux_start_bit = 0,
292 .div_offsets = { 0x800, 0x900, 0xb00 },
293 .fb_offsets = { 0x18, 0x1c, 0x20 },
294 .fb_start_bit_idx = 0,
295};
296
297static struct clkgena_divmux_data st_divmux_c65ls = {
298 .num_outputs = 14,
299 .mux_offset = 0x14,
300 .mux_offset2 = 0x24,
301 .mux_start_bit = 8,
302 .div_offsets = { 0x810, 0xa10, 0xb10 },
303 .fb_offsets = { 0x18, 0x1c, 0x20 },
304 .fb_start_bit_idx = 4,
305};
306
307static struct clkgena_divmux_data st_divmux_c32odf0 = {
308 .num_outputs = 8,
309 .mux_offset = 0x1c,
310 .mux_start_bit = 0,
311 .div_offsets = { 0x800, 0x900, 0xa60 },
312 .fb_offsets = { 0x2c, 0x24, 0x28 },
313 .fb_start_bit_idx = 0,
314};
315
316static struct clkgena_divmux_data st_divmux_c32odf1 = {
317 .num_outputs = 8,
318 .mux_offset = 0x1c,
319 .mux_start_bit = 16,
320 .div_offsets = { 0x820, 0x980, 0xa80 },
321 .fb_offsets = { 0x2c, 0x24, 0x28 },
322 .fb_start_bit_idx = 8,
323};
324
325static struct clkgena_divmux_data st_divmux_c32odf2 = {
326 .num_outputs = 8,
327 .mux_offset = 0x20,
328 .mux_start_bit = 0,
329 .div_offsets = { 0x840, 0xa20, 0xb10 },
330 .fb_offsets = { 0x2c, 0x24, 0x28 },
331 .fb_start_bit_idx = 16,
332};
333
334static struct clkgena_divmux_data st_divmux_c32odf3 = {
335 .num_outputs = 8,
336 .mux_offset = 0x20,
337 .mux_start_bit = 16,
338 .div_offsets = { 0x860, 0xa40, 0xb30 },
339 .fb_offsets = { 0x2c, 0x24, 0x28 },
340 .fb_start_bit_idx = 24,
341};
342
343static const struct of_device_id clkgena_divmux_of_match[] = {
344 {
345 .compatible = "st,clkgena-divmux-c65-hs",
346 .data = &st_divmux_c65hs,
347 },
348 {
349 .compatible = "st,clkgena-divmux-c65-ls",
350 .data = &st_divmux_c65ls,
351 },
352 {
353 .compatible = "st,clkgena-divmux-c32-odf0",
354 .data = &st_divmux_c32odf0,
355 },
356 {
357 .compatible = "st,clkgena-divmux-c32-odf1",
358 .data = &st_divmux_c32odf1,
359 },
360 {
361 .compatible = "st,clkgena-divmux-c32-odf2",
362 .data = &st_divmux_c32odf2,
363 },
364 {
365 .compatible = "st,clkgena-divmux-c32-odf3",
366 .data = &st_divmux_c32odf3,
367 },
368 {}
369};
370
371static void __iomem * __init clkgen_get_register_base(struct device_node *np)
372{
373 struct device_node *pnode;
374 void __iomem *reg;
375
376 pnode = of_get_parent(np);
377 if (!pnode)
378 return NULL;
379
380 reg = of_iomap(pnode, 0);
381
382 of_node_put(pnode);
383 return reg;
384}
385
386static void __init st_of_clkgena_divmux_setup(struct device_node *np)
387{
388 const struct of_device_id *match;
389 const struct clkgena_divmux_data *data;
390 struct clk_onecell_data *clk_data;
391 void __iomem *reg;
392 const char **parents;
393 int num_parents = 0, i;
394
395 match = of_match_node(clkgena_divmux_of_match, np);
396 if (WARN_ON(!match))
397 return;
398
399 data = match->data;
400
401 reg = clkgen_get_register_base(np);
402 if (!reg)
403 return;
404
405 parents = clkgen_mux_get_parents(np, &num_parents);
406 if (IS_ERR(parents))
407 goto err_parents;
408
409 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
410 if (!clk_data)
411 goto err_alloc;
412
413 clk_data->clk_num = data->num_outputs;
414 clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *),
415 GFP_KERNEL);
416
417 if (!clk_data->clks)
418 goto err_alloc_clks;
419
420 for (i = 0; i < clk_data->clk_num; i++) {
421 struct clk *clk;
422 const char *clk_name;
423
424 if (of_property_read_string_index(np, "clock-output-names",
425 i, &clk_name))
426 break;
427
428 /*
429 * If we read an empty clock name then the output is unused
430 */
431 if (*clk_name == '\0')
432 continue;
433
434 clk = clk_register_genamux(clk_name, parents, num_parents,
435 reg, data, i);
436
437 if (IS_ERR(clk))
438 goto err;
439
440 clk_data->clks[i] = clk;
441 }
442
443 kfree(parents);
444
445 of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
446 return;
447err:
448 kfree(clk_data->clks);
449err_alloc_clks:
450 kfree(clk_data);
451err_alloc:
452 kfree(parents);
453err_parents:
454 iounmap(reg);
455}
456CLK_OF_DECLARE(clkgenadivmux, "st,clkgena-divmux", st_of_clkgena_divmux_setup);
457
458struct clkgena_prediv_data {
459 u32 offset;
460 u8 shift;
461 struct clk_div_table *table;
462};
463
464static struct clk_div_table prediv_table16[] = {
465 { .val = 0, .div = 1 },
466 { .val = 1, .div = 16 },
467 { .div = 0 },
468};
469
470static struct clkgena_prediv_data prediv_c65_data = {
471 .offset = 0x4c,
472 .shift = 31,
473 .table = prediv_table16,
474};
475
476static struct clkgena_prediv_data prediv_c32_data = {
477 .offset = 0x50,
478 .shift = 1,
479 .table = prediv_table16,
480};
481
482static const struct of_device_id clkgena_prediv_of_match[] = {
483 { .compatible = "st,clkgena-prediv-c65", .data = &prediv_c65_data },
484 { .compatible = "st,clkgena-prediv-c32", .data = &prediv_c32_data },
485 {}
486};
487
488static void __init st_of_clkgena_prediv_setup(struct device_node *np)
489{
490 const struct of_device_id *match;
491 void __iomem *reg;
492 const char *parent_name, *clk_name;
493 struct clk *clk;
494 const struct clkgena_prediv_data *data;
495
496 match = of_match_node(clkgena_prediv_of_match, np);
497 if (!match) {
498 pr_err("%s: No matching data\n", __func__);
499 return;
500 }
501
502 data = match->data;
503
504 reg = clkgen_get_register_base(np);
505 if (!reg)
506 return;
507
508 parent_name = of_clk_get_parent_name(np, 0);
509 if (!parent_name)
510 goto err;
511
512 if (of_property_read_string_index(np, "clock-output-names",
513 0, &clk_name))
514 goto err;
515
516 clk = clk_register_divider_table(NULL, clk_name, parent_name,
517 CLK_GET_RATE_NOCACHE,
518 reg + data->offset, data->shift, 1,
519 0, data->table, NULL);
520 if (IS_ERR(clk))
521 goto err;
522
523 of_clk_add_provider(np, of_clk_src_simple_get, clk);
524 pr_debug("%s: parent %s rate %u\n",
525 __clk_get_name(clk),
526 __clk_get_name(clk_get_parent(clk)),
527 (unsigned int)clk_get_rate(clk));
528
529 return;
530err:
531 iounmap(reg);
532}
533CLK_OF_DECLARE(clkgenaprediv, "st,clkgena-prediv", st_of_clkgena_prediv_setup);
534
535struct clkgen_mux_data { 40struct clkgen_mux_data {
536 u32 offset; 41 u32 offset;
537 u8 shift; 42 u8 shift;
@@ -541,49 +46,6 @@ struct clkgen_mux_data {
541 u8 mux_flags; 46 u8 mux_flags;
542}; 47};
543 48
544static struct clkgen_mux_data clkgen_mux_c_vcc_hd_416 = {
545 .offset = 0,
546 .shift = 0,
547 .width = 1,
548};
549
550static struct clkgen_mux_data clkgen_mux_f_vcc_fvdp_416 = {
551 .offset = 0,
552 .shift = 0,
553 .width = 1,
554};
555
556static struct clkgen_mux_data clkgen_mux_f_vcc_hva_416 = {
557 .offset = 0,
558 .shift = 0,
559 .width = 1,
560};
561
562static struct clkgen_mux_data clkgen_mux_f_vcc_hd_416 = {
563 .offset = 0,
564 .shift = 16,
565 .width = 1,
566 .lock = &clkgenf_lock,
567};
568
569static struct clkgen_mux_data clkgen_mux_c_vcc_sd_416 = {
570 .offset = 0,
571 .shift = 17,
572 .width = 1,
573 .lock = &clkgenf_lock,
574};
575
576static struct clkgen_mux_data stih415_a9_mux_data = {
577 .offset = 0,
578 .shift = 1,
579 .width = 2,
580 .lock = &clkgen_a9_lock,
581};
582static struct clkgen_mux_data stih416_a9_mux_data = {
583 .offset = 0,
584 .shift = 0,
585 .width = 2,
586};
587static struct clkgen_mux_data stih407_a9_mux_data = { 49static struct clkgen_mux_data stih407_a9_mux_data = {
588 .offset = 0x1a4, 50 .offset = 0x1a4,
589 .shift = 0, 51 .shift = 0,
@@ -591,58 +53,13 @@ static struct clkgen_mux_data stih407_a9_mux_data = {
591 .lock = &clkgen_a9_lock, 53 .lock = &clkgen_a9_lock,
592}; 54};
593 55
594static const struct of_device_id mux_of_match[] = { 56static void __init st_of_clkgen_mux_setup(struct device_node *np,
595 { 57 struct clkgen_mux_data *data)
596 .compatible = "st,stih416-clkgenc-vcc-hd",
597 .data = &clkgen_mux_c_vcc_hd_416,
598 },
599 {
600 .compatible = "st,stih416-clkgenf-vcc-fvdp",
601 .data = &clkgen_mux_f_vcc_fvdp_416,
602 },
603 {
604 .compatible = "st,stih416-clkgenf-vcc-hva",
605 .data = &clkgen_mux_f_vcc_hva_416,
606 },
607 {
608 .compatible = "st,stih416-clkgenf-vcc-hd",
609 .data = &clkgen_mux_f_vcc_hd_416,
610 },
611 {
612 .compatible = "st,stih416-clkgenf-vcc-sd",
613 .data = &clkgen_mux_c_vcc_sd_416,
614 },
615 {
616 .compatible = "st,stih415-clkgen-a9-mux",
617 .data = &stih415_a9_mux_data,
618 },
619 {
620 .compatible = "st,stih416-clkgen-a9-mux",
621 .data = &stih416_a9_mux_data,
622 },
623 {
624 .compatible = "st,stih407-clkgen-a9-mux",
625 .data = &stih407_a9_mux_data,
626 },
627 {}
628};
629
630static void __init st_of_clkgen_mux_setup(struct device_node *np)
631{ 58{
632 const struct of_device_id *match;
633 struct clk *clk; 59 struct clk *clk;
634 void __iomem *reg; 60 void __iomem *reg;
635 const char **parents; 61 const char **parents;
636 int num_parents; 62 int num_parents = 0;
637 const struct clkgen_mux_data *data;
638
639 match = of_match_node(mux_of_match, np);
640 if (!match) {
641 pr_err("%s: No matching data\n", __func__);
642 return;
643 }
644
645 data = match->data;
646 63
647 reg = of_iomap(np, 0); 64 reg = of_iomap(np, 0);
648 if (!reg) { 65 if (!reg) {
@@ -679,161 +96,10 @@ err:
679err_parents: 96err_parents:
680 iounmap(reg); 97 iounmap(reg);
681} 98}
682CLK_OF_DECLARE(clkgen_mux, "st,clkgen-mux", st_of_clkgen_mux_setup);
683
684#define VCC_MAX_CHANNELS 16
685
686#define VCC_GATE_OFFSET 0x0
687#define VCC_MUX_OFFSET 0x4
688#define VCC_DIV_OFFSET 0x8
689
690struct clkgen_vcc_data {
691 spinlock_t *lock;
692 unsigned long clk_flags;
693};
694
695static struct clkgen_vcc_data st_clkgenc_vcc_416 = {
696 .clk_flags = CLK_SET_RATE_PARENT,
697};
698
699static struct clkgen_vcc_data st_clkgenf_vcc_416 = {
700 .lock = &clkgenf_lock,
701};
702
703static const struct of_device_id vcc_of_match[] = {
704 { .compatible = "st,stih416-clkgenc", .data = &st_clkgenc_vcc_416 },
705 { .compatible = "st,stih416-clkgenf", .data = &st_clkgenf_vcc_416 },
706 {}
707};
708 99
709static void __init st_of_clkgen_vcc_setup(struct device_node *np) 100static void __init st_of_clkgen_a9_mux_setup(struct device_node *np)
710{ 101{
711 const struct of_device_id *match; 102 st_of_clkgen_mux_setup(np, &stih407_a9_mux_data);
712 void __iomem *reg;
713 const char **parents;
714 int num_parents, i;
715 struct clk_onecell_data *clk_data;
716 const struct clkgen_vcc_data *data;
717
718 match = of_match_node(vcc_of_match, np);
719 if (WARN_ON(!match))
720 return;
721 data = match->data;
722
723 reg = of_iomap(np, 0);
724 if (!reg)
725 return;
726
727 parents = clkgen_mux_get_parents(np, &num_parents);
728 if (IS_ERR(parents))
729 goto err_parents;
730
731 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
732 if (!clk_data)
733 goto err_alloc;
734
735 clk_data->clk_num = VCC_MAX_CHANNELS;
736 clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *),
737 GFP_KERNEL);
738
739 if (!clk_data->clks)
740 goto err_alloc_clks;
741
742 for (i = 0; i < clk_data->clk_num; i++) {
743 struct clk *clk;
744 const char *clk_name;
745 struct clk_gate *gate;
746 struct clk_divider *div;
747 struct clk_mux *mux;
748
749 if (of_property_read_string_index(np, "clock-output-names",
750 i, &clk_name))
751 break;
752
753 /*
754 * If we read an empty clock name then the output is unused
755 */
756 if (*clk_name == '\0')
757 continue;
758
759 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
760 if (!gate)
761 goto err;
762
763 div = kzalloc(sizeof(*div), GFP_KERNEL);
764 if (!div) {
765 kfree(gate);
766 goto err;
767 }
768
769 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
770 if (!mux) {
771 kfree(gate);
772 kfree(div);
773 goto err;
774 }
775
776 gate->reg = reg + VCC_GATE_OFFSET;
777 gate->bit_idx = i;
778 gate->flags = CLK_GATE_SET_TO_DISABLE;
779 gate->lock = data->lock;
780
781 div->reg = reg + VCC_DIV_OFFSET;
782 div->shift = 2 * i;
783 div->width = 2;
784 div->flags = CLK_DIVIDER_POWER_OF_TWO |
785 CLK_DIVIDER_ROUND_CLOSEST;
786
787 mux->reg = reg + VCC_MUX_OFFSET;
788 mux->shift = 2 * i;
789 mux->mask = 0x3;
790
791 clk = clk_register_composite(NULL, clk_name, parents,
792 num_parents,
793 &mux->hw, &clk_mux_ops,
794 &div->hw, &clk_divider_ops,
795 &gate->hw, &clk_gate_ops,
796 data->clk_flags |
797 CLK_GET_RATE_NOCACHE);
798 if (IS_ERR(clk)) {
799 kfree(gate);
800 kfree(div);
801 kfree(mux);
802 goto err;
803 }
804
805 pr_debug("%s: parent %s rate %u\n",
806 __clk_get_name(clk),
807 __clk_get_name(clk_get_parent(clk)),
808 (unsigned int)clk_get_rate(clk));
809
810 clk_data->clks[i] = clk;
811 }
812
813 kfree(parents);
814
815 of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
816 return;
817
818err:
819 for (i = 0; i < clk_data->clk_num; i++) {
820 struct clk_composite *composite;
821
822 if (!clk_data->clks[i])
823 continue;
824
825 composite = to_clk_composite(__clk_get_hw(clk_data->clks[i]));
826 kfree(to_clk_gate(composite->gate_hw));
827 kfree(to_clk_divider(composite->rate_hw));
828 kfree(to_clk_mux(composite->mux_hw));
829 }
830
831 kfree(clk_data->clks);
832err_alloc_clks:
833 kfree(clk_data);
834err_alloc:
835 kfree(parents);
836err_parents:
837 iounmap(reg);
838} 103}
839CLK_OF_DECLARE(clkgen_vcc, "st,clkgen-vcc", st_of_clkgen_vcc_setup); 104CLK_OF_DECLARE(clkgen_a9mux, "st,stih407-clkgen-a9-mux",
105 st_of_clkgen_a9_mux_setup);
diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c
index 0b5990e82e0d..25bda48a5d35 100644
--- a/drivers/clk/st/clkgen-pll.c
+++ b/drivers/clk/st/clkgen-pll.c
@@ -26,14 +26,6 @@ static DEFINE_SPINLOCK(clkgena_c32_odf_lock);
26DEFINE_SPINLOCK(clkgen_a9_lock); 26DEFINE_SPINLOCK(clkgen_a9_lock);
27 27
28/* 28/*
29 * Common PLL configuration register bits for PLL800 and PLL1600 C65
30 */
31#define C65_MDIV_PLL800_MASK (0xff)
32#define C65_MDIV_PLL1600_MASK (0x7)
33#define C65_NDIV_MASK (0xff)
34#define C65_PDIV_MASK (0x7)
35
36/*
37 * PLL configuration register bits for PLL3200 C32 29 * PLL configuration register bits for PLL3200 C32
38 */ 30 */
39#define C32_NDIV_MASK (0xff) 31#define C32_NDIV_MASK (0xff)
@@ -70,144 +62,10 @@ struct clkgen_pll_data {
70 const struct clk_ops *ops; 62 const struct clk_ops *ops;
71}; 63};
72 64
73static const struct clk_ops st_pll1600c65_ops;
74static const struct clk_ops st_pll800c65_ops;
75static const struct clk_ops stm_pll3200c32_ops; 65static const struct clk_ops stm_pll3200c32_ops;
76static const struct clk_ops stm_pll3200c32_a9_ops; 66static const struct clk_ops stm_pll3200c32_a9_ops;
77static const struct clk_ops st_pll1200c32_ops;
78static const struct clk_ops stm_pll4600c28_ops; 67static const struct clk_ops stm_pll4600c28_ops;
79 68
80static const struct clkgen_pll_data st_pll1600c65_ax = {
81 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19),
82 .pdn_ctrl = CLKGEN_FIELD(0x10, 0x1, 0),
83 .locked_status = CLKGEN_FIELD(0x0, 0x1, 31),
84 .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL1600_MASK, 0),
85 .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8),
86 .ops = &st_pll1600c65_ops
87};
88
89static const struct clkgen_pll_data st_pll800c65_ax = {
90 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19),
91 .pdn_ctrl = CLKGEN_FIELD(0xC, 0x1, 1),
92 .locked_status = CLKGEN_FIELD(0x0, 0x1, 31),
93 .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL800_MASK, 0),
94 .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8),
95 .pdiv = CLKGEN_FIELD(0x0, C65_PDIV_MASK, 16),
96 .ops = &st_pll800c65_ops
97};
98
99static const struct clkgen_pll_data st_pll3200c32_a1x_0 = {
100 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 31),
101 .pdn_ctrl = CLKGEN_FIELD(0x18, 0x1, 0),
102 .locked_status = CLKGEN_FIELD(0x4, 0x1, 31),
103 .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 0x0),
104 .idf = CLKGEN_FIELD(0x4, C32_IDF_MASK, 0x0),
105 .num_odfs = 4,
106 .odf = { CLKGEN_FIELD(0x54, C32_ODF_MASK, 4),
107 CLKGEN_FIELD(0x54, C32_ODF_MASK, 10),
108 CLKGEN_FIELD(0x54, C32_ODF_MASK, 16),
109 CLKGEN_FIELD(0x54, C32_ODF_MASK, 22) },
110 .odf_gate = { CLKGEN_FIELD(0x54, 0x1, 0),
111 CLKGEN_FIELD(0x54, 0x1, 1),
112 CLKGEN_FIELD(0x54, 0x1, 2),
113 CLKGEN_FIELD(0x54, 0x1, 3) },
114 .ops = &stm_pll3200c32_ops,
115};
116
117static const struct clkgen_pll_data st_pll3200c32_a1x_1 = {
118 .pdn_status = CLKGEN_FIELD(0xC, 0x1, 31),
119 .pdn_ctrl = CLKGEN_FIELD(0x18, 0x1, 1),
120 .locked_status = CLKGEN_FIELD(0x10, 0x1, 31),
121 .ndiv = CLKGEN_FIELD(0xC, C32_NDIV_MASK, 0x0),
122 .idf = CLKGEN_FIELD(0x10, C32_IDF_MASK, 0x0),
123 .num_odfs = 4,
124 .odf = { CLKGEN_FIELD(0x58, C32_ODF_MASK, 4),
125 CLKGEN_FIELD(0x58, C32_ODF_MASK, 10),
126 CLKGEN_FIELD(0x58, C32_ODF_MASK, 16),
127 CLKGEN_FIELD(0x58, C32_ODF_MASK, 22) },
128 .odf_gate = { CLKGEN_FIELD(0x58, 0x1, 0),
129 CLKGEN_FIELD(0x58, 0x1, 1),
130 CLKGEN_FIELD(0x58, 0x1, 2),
131 CLKGEN_FIELD(0x58, 0x1, 3) },
132 .ops = &stm_pll3200c32_ops,
133};
134
135/* 415 specific */
136static const struct clkgen_pll_data st_pll3200c32_a9_415 = {
137 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
138 .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0),
139 .locked_status = CLKGEN_FIELD(0x6C, 0x1, 0),
140 .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 9),
141 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 22),
142 .num_odfs = 1,
143 .odf = { CLKGEN_FIELD(0x0, C32_ODF_MASK, 3) },
144 .odf_gate = { CLKGEN_FIELD(0x0, 0x1, 28) },
145 .ops = &stm_pll3200c32_ops,
146};
147
148static const struct clkgen_pll_data st_pll3200c32_ddr_415 = {
149 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
150 .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0),
151 .locked_status = CLKGEN_FIELD(0x100, 0x1, 0),
152 .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0),
153 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25),
154 .num_odfs = 2,
155 .odf = { CLKGEN_FIELD(0x8, C32_ODF_MASK, 8),
156 CLKGEN_FIELD(0x8, C32_ODF_MASK, 14) },
157 .odf_gate = { CLKGEN_FIELD(0x4, 0x1, 28),
158 CLKGEN_FIELD(0x4, 0x1, 29) },
159 .ops = &stm_pll3200c32_ops,
160};
161
162static const struct clkgen_pll_data st_pll1200c32_gpu_415 = {
163 .pdn_status = CLKGEN_FIELD(0x4, 0x1, 0),
164 .pdn_ctrl = CLKGEN_FIELD(0x4, 0x1, 0),
165 .locked_status = CLKGEN_FIELD(0x168, 0x1, 0),
166 .ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3),
167 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 0),
168 .num_odfs = 0,
169 .odf = { CLKGEN_FIELD(0x0, C32_ODF_MASK, 10) },
170 .ops = &st_pll1200c32_ops,
171};
172
173/* 416 specific */
174static const struct clkgen_pll_data st_pll3200c32_a9_416 = {
175 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
176 .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0),
177 .locked_status = CLKGEN_FIELD(0x6C, 0x1, 0),
178 .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0),
179 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25),
180 .num_odfs = 1,
181 .odf = { CLKGEN_FIELD(0x8, C32_ODF_MASK, 8) },
182 .odf_gate = { CLKGEN_FIELD(0x4, 0x1, 28) },
183 .ops = &stm_pll3200c32_ops,
184};
185
186static const struct clkgen_pll_data st_pll3200c32_ddr_416 = {
187 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
188 .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0),
189 .locked_status = CLKGEN_FIELD(0x10C, 0x1, 0),
190 .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0),
191 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25),
192 .num_odfs = 2,
193 .odf = { CLKGEN_FIELD(0x8, C32_ODF_MASK, 8),
194 CLKGEN_FIELD(0x8, C32_ODF_MASK, 14) },
195 .odf_gate = { CLKGEN_FIELD(0x4, 0x1, 28),
196 CLKGEN_FIELD(0x4, 0x1, 29) },
197 .ops = &stm_pll3200c32_ops,
198};
199
200static const struct clkgen_pll_data st_pll1200c32_gpu_416 = {
201 .pdn_status = CLKGEN_FIELD(0x8E4, 0x1, 3),
202 .pdn_ctrl = CLKGEN_FIELD(0x8E4, 0x1, 3),
203 .locked_status = CLKGEN_FIELD(0x90C, 0x1, 0),
204 .ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3),
205 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 0),
206 .num_odfs = 0,
207 .odf = { CLKGEN_FIELD(0x0, C32_ODF_MASK, 10) },
208 .ops = &st_pll1200c32_ops,
209};
210
211static const struct clkgen_pll_data st_pll3200c32_407_a0 = { 69static const struct clkgen_pll_data st_pll3200c32_407_a0 = {
212 /* 407 A0 */ 70 /* 407 A0 */
213 .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8), 71 .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8),
@@ -410,57 +268,6 @@ static void clkgen_pll_disable(struct clk_hw *hw)
410 spin_unlock_irqrestore(pll->lock, flags); 268 spin_unlock_irqrestore(pll->lock, flags);
411} 269}
412 270
413static unsigned long recalc_stm_pll800c65(struct clk_hw *hw,
414 unsigned long parent_rate)
415{
416 struct clkgen_pll *pll = to_clkgen_pll(hw);
417 unsigned long mdiv, ndiv, pdiv;
418 unsigned long rate;
419 uint64_t res;
420
421 if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
422 return 0;
423
424 pdiv = CLKGEN_READ(pll, pdiv);
425 mdiv = CLKGEN_READ(pll, mdiv);
426 ndiv = CLKGEN_READ(pll, ndiv);
427
428 if (!mdiv)
429 mdiv++; /* mdiv=0 or 1 => MDIV=1 */
430
431 res = (uint64_t)2 * (uint64_t)parent_rate * (uint64_t)ndiv;
432 rate = (unsigned long)div64_u64(res, mdiv * (1 << pdiv));
433
434 pr_debug("%s:%s rate %lu\n", clk_hw_get_name(hw), __func__, rate);
435
436 return rate;
437
438}
439
440static unsigned long recalc_stm_pll1600c65(struct clk_hw *hw,
441 unsigned long parent_rate)
442{
443 struct clkgen_pll *pll = to_clkgen_pll(hw);
444 unsigned long mdiv, ndiv;
445 unsigned long rate;
446
447 if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
448 return 0;
449
450 mdiv = CLKGEN_READ(pll, mdiv);
451 ndiv = CLKGEN_READ(pll, ndiv);
452
453 if (!mdiv)
454 mdiv = 1;
455
456 /* Note: input is divided by 1000 to avoid overflow */
457 rate = ((2 * (parent_rate / 1000) * ndiv) / mdiv) * 1000;
458
459 pr_debug("%s:%s rate %lu\n", clk_hw_get_name(hw), __func__, rate);
460
461 return rate;
462}
463
464static int clk_pll3200c32_get_params(unsigned long input, unsigned long output, 271static int clk_pll3200c32_get_params(unsigned long input, unsigned long output,
465 struct stm_pll *pll) 272 struct stm_pll *pll)
466{ 273{
@@ -608,33 +415,6 @@ static int set_rate_stm_pll3200c32(struct clk_hw *hw, unsigned long rate,
608 return 0; 415 return 0;
609} 416}
610 417
611static unsigned long recalc_stm_pll1200c32(struct clk_hw *hw,
612 unsigned long parent_rate)
613{
614 struct clkgen_pll *pll = to_clkgen_pll(hw);
615 unsigned long odf, ldf, idf;
616 unsigned long rate;
617
618 if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
619 return 0;
620
621 odf = CLKGEN_READ(pll, odf[0]);
622 ldf = CLKGEN_READ(pll, ldf);
623 idf = CLKGEN_READ(pll, idf);
624
625 if (!idf) /* idf==0 means 1 */
626 idf = 1;
627 if (!odf) /* odf==0 means 1 */
628 odf = 1;
629
630 /* Note: input is divided by 1000 to avoid overflow */
631 rate = (((parent_rate / 1000) * ldf) / (odf * idf)) * 1000;
632
633 pr_debug("%s:%s rate %lu\n", clk_hw_get_name(hw), __func__, rate);
634
635 return rate;
636}
637
638/* PLL output structure 418/* PLL output structure
639 * FVCO >> /2 >> FVCOBY2 (no output) 419 * FVCO >> /2 >> FVCOBY2 (no output)
640 * |> Divider (ODF) >> PHI 420 * |> Divider (ODF) >> PHI
@@ -792,20 +572,6 @@ static int set_rate_stm_pll4600c28(struct clk_hw *hw, unsigned long rate,
792 return 0; 572 return 0;
793} 573}
794 574
795static const struct clk_ops st_pll1600c65_ops = {
796 .enable = clkgen_pll_enable,
797 .disable = clkgen_pll_disable,
798 .is_enabled = clkgen_pll_is_enabled,
799 .recalc_rate = recalc_stm_pll1600c65,
800};
801
802static const struct clk_ops st_pll800c65_ops = {
803 .enable = clkgen_pll_enable,
804 .disable = clkgen_pll_disable,
805 .is_enabled = clkgen_pll_is_enabled,
806 .recalc_rate = recalc_stm_pll800c65,
807};
808
809static const struct clk_ops stm_pll3200c32_ops = { 575static const struct clk_ops stm_pll3200c32_ops = {
810 .enable = clkgen_pll_enable, 576 .enable = clkgen_pll_enable,
811 .disable = clkgen_pll_disable, 577 .disable = clkgen_pll_disable,
@@ -822,13 +588,6 @@ static const struct clk_ops stm_pll3200c32_a9_ops = {
822 .set_rate = set_rate_stm_pll3200c32, 588 .set_rate = set_rate_stm_pll3200c32,
823}; 589};
824 590
825static const struct clk_ops st_pll1200c32_ops = {
826 .enable = clkgen_pll_enable,
827 .disable = clkgen_pll_disable,
828 .is_enabled = clkgen_pll_is_enabled,
829 .recalc_rate = recalc_stm_pll1200c32,
830};
831
832static const struct clk_ops stm_pll4600c28_ops = { 591static const struct clk_ops stm_pll4600c28_ops = {
833 .enable = clkgen_pll_enable, 592 .enable = clkgen_pll_enable,
834 .disable = clkgen_pll_disable, 593 .disable = clkgen_pll_disable,
@@ -877,22 +636,6 @@ static struct clk * __init clkgen_pll_register(const char *parent_name,
877 return clk; 636 return clk;
878} 637}
879 638
880static struct clk * __init clkgen_c65_lsdiv_register(const char *parent_name,
881 const char *clk_name)
882{
883 struct clk *clk;
884
885 clk = clk_register_fixed_factor(NULL, clk_name, parent_name, 0, 1, 2);
886 if (IS_ERR(clk))
887 return clk;
888
889 pr_debug("%s: parent %s rate %lu\n",
890 __clk_get_name(clk),
891 __clk_get_name(clk_get_parent(clk)),
892 clk_get_rate(clk));
893 return clk;
894}
895
896static void __iomem * __init clkgen_get_register_base( 639static void __iomem * __init clkgen_get_register_base(
897 struct device_node *np) 640 struct device_node *np)
898{ 641{
@@ -909,89 +652,6 @@ static void __iomem * __init clkgen_get_register_base(
909 return reg; 652 return reg;
910} 653}
911 654
912#define CLKGENAx_PLL0_OFFSET 0x0
913#define CLKGENAx_PLL1_OFFSET 0x4
914
915static void __init clkgena_c65_pll_setup(struct device_node *np)
916{
917 const int num_pll_outputs = 3;
918 struct clk_onecell_data *clk_data;
919 const char *parent_name;
920 void __iomem *reg;
921 const char *clk_name;
922
923 parent_name = of_clk_get_parent_name(np, 0);
924 if (!parent_name)
925 return;
926
927 reg = clkgen_get_register_base(np);
928 if (!reg)
929 return;
930
931 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
932 if (!clk_data)
933 return;
934
935 clk_data->clk_num = num_pll_outputs;
936 clk_data->clks = kzalloc(clk_data->clk_num * sizeof(struct clk *),
937 GFP_KERNEL);
938
939 if (!clk_data->clks)
940 goto err;
941
942 if (of_property_read_string_index(np, "clock-output-names",
943 0, &clk_name))
944 goto err;
945
946 /*
947 * PLL0 HS (high speed) output
948 */
949 clk_data->clks[0] = clkgen_pll_register(parent_name,
950 (struct clkgen_pll_data *) &st_pll1600c65_ax,
951 reg + CLKGENAx_PLL0_OFFSET, 0, clk_name, NULL);
952
953 if (IS_ERR(clk_data->clks[0]))
954 goto err;
955
956 if (of_property_read_string_index(np, "clock-output-names",
957 1, &clk_name))
958 goto err;
959
960 /*
961 * PLL0 LS (low speed) output, which is a fixed divide by 2 of the
962 * high speed output.
963 */
964 clk_data->clks[1] = clkgen_c65_lsdiv_register(__clk_get_name
965 (clk_data->clks[0]),
966 clk_name);
967
968 if (IS_ERR(clk_data->clks[1]))
969 goto err;
970
971 if (of_property_read_string_index(np, "clock-output-names",
972 2, &clk_name))
973 goto err;
974
975 /*
976 * PLL1 output
977 */
978 clk_data->clks[2] = clkgen_pll_register(parent_name,
979 (struct clkgen_pll_data *) &st_pll800c65_ax,
980 reg + CLKGENAx_PLL1_OFFSET, 0, clk_name, NULL);
981
982 if (IS_ERR(clk_data->clks[2]))
983 goto err;
984
985 of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
986 return;
987
988err:
989 kfree(clk_data->clks);
990 kfree(clk_data);
991}
992CLK_OF_DECLARE(clkgena_c65_plls,
993 "st,clkgena-plls-c65", clkgena_c65_pll_setup);
994
995static struct clk * __init clkgen_odf_register(const char *parent_name, 655static struct clk * __init clkgen_odf_register(const char *parent_name,
996 void __iomem *reg, 656 void __iomem *reg,
997 struct clkgen_pll_data *pll_data, 657 struct clkgen_pll_data *pll_data,
@@ -1042,72 +702,17 @@ static struct clk * __init clkgen_odf_register(const char *parent_name,
1042 return clk; 702 return clk;
1043} 703}
1044 704
1045static const struct of_device_id c32_pll_of_match[] = {
1046 {
1047 .compatible = "st,plls-c32-a1x-0",
1048 .data = &st_pll3200c32_a1x_0,
1049 },
1050 {
1051 .compatible = "st,plls-c32-a1x-1",
1052 .data = &st_pll3200c32_a1x_1,
1053 },
1054 {
1055 .compatible = "st,stih415-plls-c32-a9",
1056 .data = &st_pll3200c32_a9_415,
1057 },
1058 {
1059 .compatible = "st,stih415-plls-c32-ddr",
1060 .data = &st_pll3200c32_ddr_415,
1061 },
1062 {
1063 .compatible = "st,stih416-plls-c32-a9",
1064 .data = &st_pll3200c32_a9_416,
1065 },
1066 {
1067 .compatible = "st,stih416-plls-c32-ddr",
1068 .data = &st_pll3200c32_ddr_416,
1069 },
1070 {
1071 .compatible = "st,stih407-plls-c32-a0",
1072 .data = &st_pll3200c32_407_a0,
1073 },
1074 {
1075 .compatible = "st,plls-c32-cx_0",
1076 .data = &st_pll3200c32_cx_0,
1077 },
1078 {
1079 .compatible = "st,plls-c32-cx_1",
1080 .data = &st_pll3200c32_cx_1,
1081 },
1082 {
1083 .compatible = "st,stih407-plls-c32-a9",
1084 .data = &st_pll3200c32_407_a9,
1085 },
1086 {
1087 .compatible = "st,stih418-plls-c28-a9",
1088 .data = &st_pll4600c28_418_a9,
1089 },
1090 {}
1091};
1092 705
1093static void __init clkgen_c32_pll_setup(struct device_node *np) 706static void __init clkgen_c32_pll_setup(struct device_node *np,
707 struct clkgen_pll_data *data)
1094{ 708{
1095 const struct of_device_id *match;
1096 struct clk *clk; 709 struct clk *clk;
1097 const char *parent_name, *pll_name; 710 const char *parent_name, *pll_name;
1098 void __iomem *pll_base; 711 void __iomem *pll_base;
1099 int num_odfs, odf; 712 int num_odfs, odf;
1100 struct clk_onecell_data *clk_data; 713 struct clk_onecell_data *clk_data;
1101 struct clkgen_pll_data *data;
1102 unsigned long pll_flags = 0; 714 unsigned long pll_flags = 0;
1103 715
1104 match = of_match_node(c32_pll_of_match, np);
1105 if (!match) {
1106 pr_err("%s: No matching data\n", __func__);
1107 return;
1108 }
1109
1110 data = (struct clkgen_pll_data *) match->data;
1111 716
1112 parent_name = of_clk_get_parent_name(np, 0); 717 parent_name = of_clk_get_parent_name(np, 0);
1113 if (!parent_name) 718 if (!parent_name)
@@ -1166,59 +771,30 @@ err:
1166 kfree(clk_data->clks); 771 kfree(clk_data->clks);
1167 kfree(clk_data); 772 kfree(clk_data);
1168} 773}
1169CLK_OF_DECLARE(clkgen_c32_pll, "st,clkgen-plls-c32", clkgen_c32_pll_setup); 774static void __init clkgen_c32_pll0_setup(struct device_node *np)
1170
1171static const struct of_device_id c32_gpu_pll_of_match[] = {
1172 {
1173 .compatible = "st,stih415-gpu-pll-c32",
1174 .data = &st_pll1200c32_gpu_415,
1175 },
1176 {
1177 .compatible = "st,stih416-gpu-pll-c32",
1178 .data = &st_pll1200c32_gpu_416,
1179 },
1180 {}
1181};
1182
1183static void __init clkgengpu_c32_pll_setup(struct device_node *np)
1184{ 775{
1185 const struct of_device_id *match; 776 clkgen_c32_pll_setup(np,
1186 struct clk *clk; 777 (struct clkgen_pll_data *) &st_pll3200c32_cx_0);
1187 const char *parent_name; 778}
1188 void __iomem *reg; 779CLK_OF_DECLARE(c32_pll0, "st,clkgen-pll0", clkgen_c32_pll0_setup);
1189 const char *clk_name;
1190 struct clkgen_pll_data *data;
1191
1192 match = of_match_node(c32_gpu_pll_of_match, np);
1193 if (!match) {
1194 pr_err("%s: No matching data\n", __func__);
1195 return;
1196 }
1197
1198 data = (struct clkgen_pll_data *)match->data;
1199
1200 parent_name = of_clk_get_parent_name(np, 0);
1201 if (!parent_name)
1202 return;
1203
1204 reg = clkgen_get_register_base(np);
1205 if (!reg)
1206 return;
1207
1208 if (of_property_read_string_index(np, "clock-output-names",
1209 0, &clk_name))
1210 return;
1211 780
1212 /* 781static void __init clkgen_c32_pll1_setup(struct device_node *np)
1213 * PLL 1200MHz output 782{
1214 */ 783 clkgen_c32_pll_setup(np,
1215 clk = clkgen_pll_register(parent_name, data, reg, 784 (struct clkgen_pll_data *) &st_pll3200c32_cx_1);
1216 0, clk_name, data->lock); 785}
786CLK_OF_DECLARE(c32_pll1, "st,clkgen-pll1", clkgen_c32_pll1_setup);
1217 787
1218 if (!IS_ERR(clk)) 788static void __init clkgen_c32_plla9_setup(struct device_node *np)
1219 of_clk_add_provider(np, of_clk_src_simple_get, clk); 789{
790 clkgen_c32_pll_setup(np,
791 (struct clkgen_pll_data *) &st_pll3200c32_407_a9);
792}
793CLK_OF_DECLARE(c32_plla9, "st,stih407-clkgen-plla9", clkgen_c32_plla9_setup);
1220 794
1221 return; 795static void __init clkgen_c28_plla9_setup(struct device_node *np)
796{
797 clkgen_c32_pll_setup(np,
798 (struct clkgen_pll_data *) &st_pll4600c28_418_a9);
1222} 799}
1223CLK_OF_DECLARE(clkgengpu_c32_pll, 800CLK_OF_DECLARE(c28_plla9, "st,stih418-clkgen-plla9", clkgen_c28_plla9_setup);
1224 "st,clkgengpu-pll-c32", clkgengpu_c32_pll_setup);
diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 2afcbd39e41e..254d9526c018 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -1,5 +1,6 @@
1config SUNXI_CCU 1config SUNXI_CCU
2 bool "Clock support for Allwinner SoCs" 2 bool "Clock support for Allwinner SoCs"
3 depends on ARCH_SUNXI || COMPILE_TEST
3 default ARCH_SUNXI 4 default ARCH_SUNXI
4 5
5if SUNXI_CCU 6if SUNXI_CCU
@@ -19,6 +20,10 @@ config SUNXI_CCU_GATE
19config SUNXI_CCU_MUX 20config SUNXI_CCU_MUX
20 bool 21 bool
21 22
23config SUNXI_CCU_MULT
24 bool
25 select SUNXI_CCU_MUX
26
22config SUNXI_CCU_PHASE 27config SUNXI_CCU_PHASE
23 bool 28 bool
24 29
@@ -51,6 +56,40 @@ config SUNXI_CCU_MP
51 56
52# SoC Drivers 57# SoC Drivers
53 58
59config SUN6I_A31_CCU
60 bool "Support for the Allwinner A31/A31s CCU"
61 select SUNXI_CCU_DIV
62 select SUNXI_CCU_NK
63 select SUNXI_CCU_NKM
64 select SUNXI_CCU_NM
65 select SUNXI_CCU_MP
66 select SUNXI_CCU_PHASE
67 default MACH_SUN6I
68
69config SUN8I_A23_CCU
70 bool "Support for the Allwinner A23 CCU"
71 select SUNXI_CCU_DIV
72 select SUNXI_CCU_MULT
73 select SUNXI_CCU_NK
74 select SUNXI_CCU_NKM
75 select SUNXI_CCU_NKMP
76 select SUNXI_CCU_NM
77 select SUNXI_CCU_MP
78 select SUNXI_CCU_PHASE
79 default MACH_SUN8I
80
81config SUN8I_A33_CCU
82 bool "Support for the Allwinner A33 CCU"
83 select SUNXI_CCU_DIV
84 select SUNXI_CCU_MULT
85 select SUNXI_CCU_NK
86 select SUNXI_CCU_NKM
87 select SUNXI_CCU_NKMP
88 select SUNXI_CCU_NM
89 select SUNXI_CCU_MP
90 select SUNXI_CCU_PHASE
91 default MACH_SUN8I
92
54config SUN8I_H3_CCU 93config SUN8I_H3_CCU
55 bool "Support for the Allwinner H3 CCU" 94 bool "Support for the Allwinner H3 CCU"
56 select SUNXI_CCU_DIV 95 select SUNXI_CCU_DIV
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 633ce642ffae..106cba27c331 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_SUNXI_CCU_DIV) += ccu_div.o
7obj-$(CONFIG_SUNXI_CCU_FRAC) += ccu_frac.o 7obj-$(CONFIG_SUNXI_CCU_FRAC) += ccu_frac.o
8obj-$(CONFIG_SUNXI_CCU_GATE) += ccu_gate.o 8obj-$(CONFIG_SUNXI_CCU_GATE) += ccu_gate.o
9obj-$(CONFIG_SUNXI_CCU_MUX) += ccu_mux.o 9obj-$(CONFIG_SUNXI_CCU_MUX) += ccu_mux.o
10obj-$(CONFIG_SUNXI_CCU_MULT) += ccu_mult.o
10obj-$(CONFIG_SUNXI_CCU_PHASE) += ccu_phase.o 11obj-$(CONFIG_SUNXI_CCU_PHASE) += ccu_phase.o
11 12
12# Multi-factor clocks 13# Multi-factor clocks
@@ -17,4 +18,7 @@ obj-$(CONFIG_SUNXI_CCU_NM) += ccu_nm.o
17obj-$(CONFIG_SUNXI_CCU_MP) += ccu_mp.o 18obj-$(CONFIG_SUNXI_CCU_MP) += ccu_mp.o
18 19
19# SoC support 20# SoC support
21obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o
22obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o
23obj-$(CONFIG_SUN8I_A33_CCU) += ccu-sun8i-a33.o
20obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o 24obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
new file mode 100644
index 000000000000..79596463e0d9
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
@@ -0,0 +1,1239 @@
1/*
2 * Copyright (c) 2016 Chen-Yu Tsai
3 *
4 * Chen-Yu Tsai <wens@csie.org>
5 *
6 * Based on ccu-sun8i-h3.c by Maxime Ripard.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/clk-provider.h>
19#include <linux/of_address.h>
20
21#include "ccu_common.h"
22#include "ccu_reset.h"
23
24#include "ccu_div.h"
25#include "ccu_gate.h"
26#include "ccu_mp.h"
27#include "ccu_mult.h"
28#include "ccu_mux.h"
29#include "ccu_nk.h"
30#include "ccu_nkm.h"
31#include "ccu_nkmp.h"
32#include "ccu_nm.h"
33#include "ccu_phase.h"
34
35#include "ccu-sun6i-a31.h"
36
37static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_cpu_clk, "pll-cpu",
38 "osc24M", 0x000,
39 8, 5, /* N */
40 4, 2, /* K */
41 0, 2, /* M */
42 BIT(31), /* gate */
43 BIT(28), /* lock */
44 0);
45
46/*
47 * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
48 * the base (2x, 4x and 8x), and one variable divider (the one true
49 * pll audio).
50 *
51 * We don't have any need for the variable divider for now, so we just
52 * hardcode it to match with the clock names
53 */
54#define SUN6I_A31_PLL_AUDIO_REG 0x008
55
56static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
57 "osc24M", 0x008,
58 8, 7, /* N */
59 0, 5, /* M */
60 BIT(31), /* gate */
61 BIT(28), /* lock */
62 CLK_SET_RATE_UNGATE);
63
64static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0",
65 "osc24M", 0x010,
66 8, 7, /* N */
67 0, 4, /* M */
68 BIT(24), /* frac enable */
69 BIT(25), /* frac select */
70 270000000, /* frac rate 0 */
71 297000000, /* frac rate 1 */
72 BIT(31), /* gate */
73 BIT(28), /* lock */
74 CLK_SET_RATE_UNGATE);
75
76static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
77 "osc24M", 0x018,
78 8, 7, /* N */
79 0, 4, /* M */
80 BIT(24), /* frac enable */
81 BIT(25), /* frac select */
82 270000000, /* frac rate 0 */
83 297000000, /* frac rate 1 */
84 BIT(31), /* gate */
85 BIT(28), /* lock */
86 CLK_SET_RATE_UNGATE);
87
88static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr",
89 "osc24M", 0x020,
90 8, 5, /* N */
91 4, 2, /* K */
92 0, 2, /* M */
93 BIT(31), /* gate */
94 BIT(28), /* lock */
95 CLK_SET_RATE_UNGATE);
96
97static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph_clk, "pll-periph",
98 "osc24M", 0x028,
99 8, 5, /* N */
100 4, 2, /* K */
101 BIT(31), /* gate */
102 BIT(28), /* lock */
103 2, /* post-div */
104 CLK_SET_RATE_UNGATE);
105
106static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1",
107 "osc24M", 0x030,
108 8, 7, /* N */
109 0, 4, /* M */
110 BIT(24), /* frac enable */
111 BIT(25), /* frac select */
112 270000000, /* frac rate 0 */
113 297000000, /* frac rate 1 */
114 BIT(31), /* gate */
115 BIT(28), /* lock */
116 CLK_SET_RATE_UNGATE);
117
118static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
119 "osc24M", 0x038,
120 8, 7, /* N */
121 0, 4, /* M */
122 BIT(24), /* frac enable */
123 BIT(25), /* frac select */
124 270000000, /* frac rate 0 */
125 297000000, /* frac rate 1 */
126 BIT(31), /* gate */
127 BIT(28), /* lock */
128 CLK_SET_RATE_UNGATE);
129
130/*
131 * The MIPI PLL has 2 modes: "MIPI" and "HDMI".
132 *
133 * The MIPI mode is a standard NKM-style clock. The HDMI mode is an
134 * integer / fractional clock with switchable multipliers and dividers.
135 * This is not supported here. We hardcode the PLL to MIPI mode.
136 */
137#define SUN6I_A31_PLL_MIPI_REG 0x040
138
139static const char * const pll_mipi_parents[] = { "pll-video0", "pll-video1" };
140static SUNXI_CCU_NKM_WITH_MUX_GATE_LOCK(pll_mipi_clk, "pll-mipi",
141 pll_mipi_parents, 0x040,
142 8, 4, /* N */
143 4, 2, /* K */
144 0, 4, /* M */
145 21, 0, /* mux */
146 BIT(31), /* gate */
147 BIT(28), /* lock */
148 CLK_SET_RATE_UNGATE);
149
150static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll9_clk, "pll9",
151 "osc24M", 0x044,
152 8, 7, /* N */
153 0, 4, /* M */
154 BIT(24), /* frac enable */
155 BIT(25), /* frac select */
156 270000000, /* frac rate 0 */
157 297000000, /* frac rate 1 */
158 BIT(31), /* gate */
159 BIT(28), /* lock */
160 CLK_SET_RATE_UNGATE);
161
162static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll10_clk, "pll10",
163 "osc24M", 0x048,
164 8, 7, /* N */
165 0, 4, /* M */
166 BIT(24), /* frac enable */
167 BIT(25), /* frac select */
168 270000000, /* frac rate 0 */
169 297000000, /* frac rate 1 */
170 BIT(31), /* gate */
171 BIT(28), /* lock */
172 CLK_SET_RATE_UNGATE);
173
174static const char * const cpux_parents[] = { "osc32k", "osc24M",
175 "pll-cpu", "pll-cpu" };
176static SUNXI_CCU_MUX(cpu_clk, "cpu", cpux_parents,
177 0x050, 16, 2, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
178
179static struct clk_div_table axi_div_table[] = {
180 { .val = 0, .div = 1 },
181 { .val = 1, .div = 2 },
182 { .val = 2, .div = 3 },
183 { .val = 3, .div = 4 },
184 { .val = 4, .div = 4 },
185 { .val = 5, .div = 4 },
186 { .val = 6, .div = 4 },
187 { .val = 7, .div = 4 },
188 { /* Sentinel */ },
189};
190
191static SUNXI_CCU_DIV_TABLE(axi_clk, "axi", "cpu",
192 0x050, 0, 3, axi_div_table, 0);
193
194static const char * const ahb1_parents[] = { "osc32k", "osc24M",
195 "axi", "pll-periph" };
196
197static struct ccu_div ahb1_clk = {
198 .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
199
200 .mux = {
201 .shift = 12,
202 .width = 2,
203
204 .variable_prediv = {
205 .index = 3,
206 .shift = 6,
207 .width = 2,
208 },
209 },
210
211 .common = {
212 .reg = 0x054,
213 .features = CCU_FEATURE_VARIABLE_PREDIV,
214 .hw.init = CLK_HW_INIT_PARENTS("ahb1",
215 ahb1_parents,
216 &ccu_div_ops,
217 0),
218 },
219};
220
221static struct clk_div_table apb1_div_table[] = {
222 { .val = 0, .div = 2 },
223 { .val = 1, .div = 2 },
224 { .val = 2, .div = 4 },
225 { .val = 3, .div = 8 },
226 { /* Sentinel */ },
227};
228
229static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1",
230 0x054, 8, 2, apb1_div_table, 0);
231
232static const char * const apb2_parents[] = { "osc32k", "osc24M",
233 "pll-periph", "pll-periph" };
234static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
235 0, 5, /* M */
236 16, 2, /* P */
237 24, 2, /* mux */
238 0);
239
240static SUNXI_CCU_GATE(ahb1_mipidsi_clk, "ahb1-mipidsi", "ahb1",
241 0x060, BIT(1), 0);
242static SUNXI_CCU_GATE(ahb1_ss_clk, "ahb1-ss", "ahb1",
243 0x060, BIT(5), 0);
244static SUNXI_CCU_GATE(ahb1_dma_clk, "ahb1-dma", "ahb1",
245 0x060, BIT(6), 0);
246static SUNXI_CCU_GATE(ahb1_mmc0_clk, "ahb1-mmc0", "ahb1",
247 0x060, BIT(8), 0);
248static SUNXI_CCU_GATE(ahb1_mmc1_clk, "ahb1-mmc1", "ahb1",
249 0x060, BIT(9), 0);
250static SUNXI_CCU_GATE(ahb1_mmc2_clk, "ahb1-mmc2", "ahb1",
251 0x060, BIT(10), 0);
252static SUNXI_CCU_GATE(ahb1_mmc3_clk, "ahb1-mmc3", "ahb1",
253 0x060, BIT(12), 0);
254static SUNXI_CCU_GATE(ahb1_nand1_clk, "ahb1-nand1", "ahb1",
255 0x060, BIT(13), 0);
256static SUNXI_CCU_GATE(ahb1_nand0_clk, "ahb1-nand0", "ahb1",
257 0x060, BIT(13), 0);
258static SUNXI_CCU_GATE(ahb1_sdram_clk, "ahb1-sdram", "ahb1",
259 0x060, BIT(14), 0);
260static SUNXI_CCU_GATE(ahb1_emac_clk, "ahb1-emac", "ahb1",
261 0x060, BIT(17), 0);
262static SUNXI_CCU_GATE(ahb1_ts_clk, "ahb1-ts", "ahb1",
263 0x060, BIT(18), 0);
264static SUNXI_CCU_GATE(ahb1_hstimer_clk, "ahb1-hstimer", "ahb1",
265 0x060, BIT(19), 0);
266static SUNXI_CCU_GATE(ahb1_spi0_clk, "ahb1-spi0", "ahb1",
267 0x060, BIT(20), 0);
268static SUNXI_CCU_GATE(ahb1_spi1_clk, "ahb1-spi1", "ahb1",
269 0x060, BIT(21), 0);
270static SUNXI_CCU_GATE(ahb1_spi2_clk, "ahb1-spi2", "ahb1",
271 0x060, BIT(22), 0);
272static SUNXI_CCU_GATE(ahb1_spi3_clk, "ahb1-spi3", "ahb1",
273 0x060, BIT(23), 0);
274static SUNXI_CCU_GATE(ahb1_otg_clk, "ahb1-otg", "ahb1",
275 0x060, BIT(24), 0);
276static SUNXI_CCU_GATE(ahb1_ehci0_clk, "ahb1-ehci0", "ahb1",
277 0x060, BIT(26), 0);
278static SUNXI_CCU_GATE(ahb1_ehci1_clk, "ahb1-ehci1", "ahb1",
279 0x060, BIT(27), 0);
280static SUNXI_CCU_GATE(ahb1_ohci0_clk, "ahb1-ohci0", "ahb1",
281 0x060, BIT(29), 0);
282static SUNXI_CCU_GATE(ahb1_ohci1_clk, "ahb1-ohci1", "ahb1",
283 0x060, BIT(30), 0);
284static SUNXI_CCU_GATE(ahb1_ohci2_clk, "ahb1-ohci2", "ahb1",
285 0x060, BIT(31), 0);
286
287static SUNXI_CCU_GATE(ahb1_ve_clk, "ahb1-ve", "ahb1",
288 0x064, BIT(0), 0);
289static SUNXI_CCU_GATE(ahb1_lcd0_clk, "ahb1-lcd0", "ahb1",
290 0x064, BIT(4), 0);
291static SUNXI_CCU_GATE(ahb1_lcd1_clk, "ahb1-lcd1", "ahb1",
292 0x064, BIT(5), 0);
293static SUNXI_CCU_GATE(ahb1_csi_clk, "ahb1-csi", "ahb1",
294 0x064, BIT(8), 0);
295static SUNXI_CCU_GATE(ahb1_hdmi_clk, "ahb1-hdmi", "ahb1",
296 0x064, BIT(11), 0);
297static SUNXI_CCU_GATE(ahb1_be0_clk, "ahb1-be0", "ahb1",
298 0x064, BIT(12), 0);
299static SUNXI_CCU_GATE(ahb1_be1_clk, "ahb1-be1", "ahb1",
300 0x064, BIT(13), 0);
301static SUNXI_CCU_GATE(ahb1_fe0_clk, "ahb1-fe0", "ahb1",
302 0x064, BIT(14), 0);
303static SUNXI_CCU_GATE(ahb1_fe1_clk, "ahb1-fe1", "ahb1",
304 0x064, BIT(15), 0);
305static SUNXI_CCU_GATE(ahb1_mp_clk, "ahb1-mp", "ahb1",
306 0x064, BIT(18), 0);
307static SUNXI_CCU_GATE(ahb1_gpu_clk, "ahb1-gpu", "ahb1",
308 0x064, BIT(20), 0);
309static SUNXI_CCU_GATE(ahb1_deu0_clk, "ahb1-deu0", "ahb1",
310 0x064, BIT(23), 0);
311static SUNXI_CCU_GATE(ahb1_deu1_clk, "ahb1-deu1", "ahb1",
312 0x064, BIT(24), 0);
313static SUNXI_CCU_GATE(ahb1_drc0_clk, "ahb1-drc0", "ahb1",
314 0x064, BIT(25), 0);
315static SUNXI_CCU_GATE(ahb1_drc1_clk, "ahb1-drc1", "ahb1",
316 0x064, BIT(26), 0);
317
318static SUNXI_CCU_GATE(apb1_codec_clk, "apb1-codec", "apb1",
319 0x068, BIT(0), 0);
320static SUNXI_CCU_GATE(apb1_spdif_clk, "apb1-spdif", "apb1",
321 0x068, BIT(1), 0);
322static SUNXI_CCU_GATE(apb1_digital_mic_clk, "apb1-digital-mic", "apb1",
323 0x068, BIT(4), 0);
324static SUNXI_CCU_GATE(apb1_pio_clk, "apb1-pio", "apb1",
325 0x068, BIT(5), 0);
326static SUNXI_CCU_GATE(apb1_daudio0_clk, "apb1-daudio0", "apb1",
327 0x068, BIT(12), 0);
328static SUNXI_CCU_GATE(apb1_daudio1_clk, "apb1-daudio1", "apb1",
329 0x068, BIT(13), 0);
330
331static SUNXI_CCU_GATE(apb2_i2c0_clk, "apb2-i2c0", "apb2",
332 0x06c, BIT(0), 0);
333static SUNXI_CCU_GATE(apb2_i2c1_clk, "apb2-i2c1", "apb2",
334 0x06c, BIT(1), 0);
335static SUNXI_CCU_GATE(apb2_i2c2_clk, "apb2-i2c2", "apb2",
336 0x06c, BIT(2), 0);
337static SUNXI_CCU_GATE(apb2_i2c3_clk, "apb2-i2c3", "apb2",
338 0x06c, BIT(3), 0);
339static SUNXI_CCU_GATE(apb2_uart0_clk, "apb2-uart0", "apb2",
340 0x06c, BIT(16), 0);
341static SUNXI_CCU_GATE(apb2_uart1_clk, "apb2-uart1", "apb2",
342 0x06c, BIT(17), 0);
343static SUNXI_CCU_GATE(apb2_uart2_clk, "apb2-uart2", "apb2",
344 0x06c, BIT(18), 0);
345static SUNXI_CCU_GATE(apb2_uart3_clk, "apb2-uart3", "apb2",
346 0x06c, BIT(19), 0);
347static SUNXI_CCU_GATE(apb2_uart4_clk, "apb2-uart4", "apb2",
348 0x06c, BIT(20), 0);
349static SUNXI_CCU_GATE(apb2_uart5_clk, "apb2-uart5", "apb2",
350 0x06c, BIT(21), 0);
351
352static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" };
353static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0", mod0_default_parents,
354 0x080,
355 0, 4, /* M */
356 16, 2, /* P */
357 24, 2, /* mux */
358 BIT(31), /* gate */
359 0);
360
361static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1", mod0_default_parents,
362 0x084,
363 0, 4, /* M */
364 16, 2, /* P */
365 24, 2, /* mux */
366 BIT(31), /* gate */
367 0);
368
369static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents,
370 0x088,
371 0, 4, /* M */
372 16, 2, /* P */
373 24, 2, /* mux */
374 BIT(31), /* gate */
375 0);
376
377static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
378 0x088, 20, 3, 0);
379static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
380 0x088, 8, 3, 0);
381
382static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents,
383 0x08c,
384 0, 4, /* M */
385 16, 2, /* P */
386 24, 2, /* mux */
387 BIT(31), /* gate */
388 0);
389
390static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
391 0x08c, 20, 3, 0);
392static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
393 0x08c, 8, 3, 0);
394
395static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents,
396 0x090,
397 0, 4, /* M */
398 16, 2, /* P */
399 24, 2, /* mux */
400 BIT(31), /* gate */
401 0);
402
403static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
404 0x090, 20, 3, 0);
405static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
406 0x090, 8, 3, 0);
407
408static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk, "mmc3", mod0_default_parents,
409 0x094,
410 0, 4, /* M */
411 16, 2, /* P */
412 24, 2, /* mux */
413 BIT(31), /* gate */
414 0);
415
416static SUNXI_CCU_PHASE(mmc3_sample_clk, "mmc3_sample", "mmc3",
417 0x094, 20, 3, 0);
418static SUNXI_CCU_PHASE(mmc3_output_clk, "mmc3_output", "mmc3",
419 0x094, 8, 3, 0);
420
421static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents, 0x098,
422 0, 4, /* M */
423 16, 2, /* P */
424 24, 2, /* mux */
425 BIT(31), /* gate */
426 0);
427
428static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c,
429 0, 4, /* M */
430 16, 2, /* P */
431 24, 2, /* mux */
432 BIT(31), /* gate */
433 0);
434
435static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
436 0, 4, /* M */
437 16, 2, /* P */
438 24, 2, /* mux */
439 BIT(31), /* gate */
440 0);
441
442static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
443 0, 4, /* M */
444 16, 2, /* P */
445 24, 2, /* mux */
446 BIT(31), /* gate */
447 0);
448static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8,
449 0, 4, /* M */
450 16, 2, /* P */
451 24, 2, /* mux */
452 BIT(31), /* gate */
453 0);
454
455static SUNXI_CCU_MP_WITH_MUX_GATE(spi3_clk, "spi3", mod0_default_parents, 0x0ac,
456 0, 4, /* M */
457 16, 2, /* P */
458 24, 2, /* mux */
459 BIT(31), /* gate */
460 0);
461
462static const char * const daudio_parents[] = { "pll-audio-8x", "pll-audio-4x",
463 "pll-audio-2x", "pll-audio" };
464static SUNXI_CCU_MUX_WITH_GATE(daudio0_clk, "daudio0", daudio_parents,
465 0x0b0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
466static SUNXI_CCU_MUX_WITH_GATE(daudio1_clk, "daudio1", daudio_parents,
467 0x0b4, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
468
469static SUNXI_CCU_M_WITH_GATE(spdif_clk, "spdif", "pll-audio",
470 0x0c0, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
471
472static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
473 0x0cc, BIT(8), 0);
474static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M",
475 0x0cc, BIT(9), 0);
476static SUNXI_CCU_GATE(usb_phy2_clk, "usb-phy2", "osc24M",
477 0x0cc, BIT(10), 0);
478static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc24M",
479 0x0cc, BIT(16), 0);
480static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc24M",
481 0x0cc, BIT(17), 0);
482static SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc24M",
483 0x0cc, BIT(18), 0);
484
485/* TODO emac clk not supported yet */
486
487static const char * const dram_parents[] = { "pll-ddr", "pll-periph" };
488static SUNXI_CCU_MP_WITH_MUX_GATE(mdfs_clk, "mdfs", dram_parents, 0x0f0,
489 0, 4, /* M */
490 16, 2, /* P */
491 24, 2, /* mux */
492 BIT(31), /* gate */
493 CLK_IS_CRITICAL);
494
495static SUNXI_CCU_M_WITH_MUX(sdram0_clk, "sdram0", dram_parents,
496 0x0f4, 0, 4, 4, 1, CLK_IS_CRITICAL);
497static SUNXI_CCU_M_WITH_MUX(sdram1_clk, "sdram1", dram_parents,
498 0x0f4, 8, 4, 12, 1, CLK_IS_CRITICAL);
499
500static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "mdfs",
501 0x100, BIT(0), 0);
502static SUNXI_CCU_GATE(dram_csi_isp_clk, "dram-csi-isp", "mdfs",
503 0x100, BIT(1), 0);
504static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "mdfs",
505 0x100, BIT(3), 0);
506static SUNXI_CCU_GATE(dram_drc0_clk, "dram-drc0", "mdfs",
507 0x100, BIT(16), 0);
508static SUNXI_CCU_GATE(dram_drc1_clk, "dram-drc1", "mdfs",
509 0x100, BIT(17), 0);
510static SUNXI_CCU_GATE(dram_deu0_clk, "dram-deu0", "mdfs",
511 0x100, BIT(18), 0);
512static SUNXI_CCU_GATE(dram_deu1_clk, "dram-deu1", "mdfs",
513 0x100, BIT(19), 0);
514static SUNXI_CCU_GATE(dram_fe0_clk, "dram-fe0", "mdfs",
515 0x100, BIT(24), 0);
516static SUNXI_CCU_GATE(dram_fe1_clk, "dram-fe1", "mdfs",
517 0x100, BIT(25), 0);
518static SUNXI_CCU_GATE(dram_be0_clk, "dram-be0", "mdfs",
519 0x100, BIT(26), 0);
520static SUNXI_CCU_GATE(dram_be1_clk, "dram-be1", "mdfs",
521 0x100, BIT(27), 0);
522static SUNXI_CCU_GATE(dram_mp_clk, "dram-mp", "mdfs",
523 0x100, BIT(28), 0);
524
525static const char * const de_parents[] = { "pll-video0", "pll-video1",
526 "pll-periph-2x", "pll-gpu",
527 "pll9", "pll10" };
528static SUNXI_CCU_M_WITH_MUX_GATE(be0_clk, "be0", de_parents,
529 0x104, 0, 4, 24, 3, BIT(31), 0);
530static SUNXI_CCU_M_WITH_MUX_GATE(be1_clk, "be1", de_parents,
531 0x108, 0, 4, 24, 3, BIT(31), 0);
532static SUNXI_CCU_M_WITH_MUX_GATE(fe0_clk, "fe0", de_parents,
533 0x10c, 0, 4, 24, 3, BIT(31), 0);
534static SUNXI_CCU_M_WITH_MUX_GATE(fe1_clk, "fe1", de_parents,
535 0x110, 0, 4, 24, 3, BIT(31), 0);
536
537static const char * const mp_parents[] = { "pll-video0", "pll-video1",
538 "pll9", "pll10" };
539static SUNXI_CCU_M_WITH_MUX_GATE(mp_clk, "mp", mp_parents,
540 0x114, 0, 4, 24, 3, BIT(31), 0);
541
542static const char * const lcd_ch0_parents[] = { "pll-video0", "pll-video1",
543 "pll-video0-2x",
544 "pll-video1-2x", "pll-mipi" };
545static SUNXI_CCU_MUX_WITH_GATE(lcd0_ch0_clk, "lcd0-ch0", lcd_ch0_parents,
546 0x118, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
547static SUNXI_CCU_MUX_WITH_GATE(lcd1_ch0_clk, "lcd1-ch0", lcd_ch0_parents,
548 0x11c, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
549
550static const char * const lcd_ch1_parents[] = { "pll-video0", "pll-video1",
551 "pll-video0-2x",
552 "pll-video1-2x" };
553static SUNXI_CCU_M_WITH_MUX_GATE(lcd0_ch1_clk, "lcd0-ch1", lcd_ch1_parents,
554 0x12c, 0, 4, 24, 3, BIT(31),
555 CLK_SET_RATE_PARENT);
556static SUNXI_CCU_M_WITH_MUX_GATE(lcd1_ch1_clk, "lcd1-ch1", lcd_ch1_parents,
557 0x12c, 0, 4, 24, 3, BIT(31),
558 CLK_SET_RATE_PARENT);
559
560static const char * const csi_sclk_parents[] = { "pll-video0", "pll-video1",
561 "pll9", "pll10", "pll-mipi",
562 "pll-ve" };
563static SUNXI_CCU_M_WITH_MUX_GATE(csi0_sclk_clk, "csi0-sclk", csi_sclk_parents,
564 0x134, 16, 4, 24, 3, BIT(31), 0);
565
566static const char * const csi_mclk_parents[] = { "pll-video0", "pll-video1",
567 "osc24M" };
568static const u8 csi_mclk_table[] = { 0, 1, 5 };
569static struct ccu_div csi0_mclk_clk = {
570 .enable = BIT(15),
571 .div = _SUNXI_CCU_DIV(0, 4),
572 .mux = _SUNXI_CCU_MUX_TABLE(8, 3, csi_mclk_table),
573 .common = {
574 .reg = 0x134,
575 .hw.init = CLK_HW_INIT_PARENTS("csi0-mclk",
576 csi_mclk_parents,
577 &ccu_div_ops,
578 0),
579 },
580};
581
582static struct ccu_div csi1_mclk_clk = {
583 .enable = BIT(15),
584 .div = _SUNXI_CCU_DIV(0, 4),
585 .mux = _SUNXI_CCU_MUX_TABLE(8, 3, csi_mclk_table),
586 .common = {
587 .reg = 0x138,
588 .hw.init = CLK_HW_INIT_PARENTS("csi1-mclk",
589 csi_mclk_parents,
590 &ccu_div_ops,
591 0),
592 },
593};
594
595static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
596 0x13c, 16, 3, BIT(31), 0);
597
598static SUNXI_CCU_GATE(codec_clk, "codec", "pll-audio",
599 0x140, BIT(31), CLK_SET_RATE_PARENT);
600static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M",
601 0x144, BIT(31), 0);
602static SUNXI_CCU_GATE(digital_mic_clk, "digital-mic", "pll-audio",
603 0x148, BIT(31), CLK_SET_RATE_PARENT);
604
605static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", lcd_ch1_parents,
606 0x150, 0, 4, 24, 2, BIT(31),
607 CLK_SET_RATE_PARENT);
608
609static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x150, BIT(31), 0);
610
611static SUNXI_CCU_GATE(ps_clk, "ps", "lcd1-ch1", 0x140, BIT(31), 0);
612
613static const char * const mbus_parents[] = { "osc24M", "pll-periph",
614 "pll-ddr" };
615static SUNXI_CCU_MP_WITH_MUX_GATE(mbus0_clk, "mbus0", mbus_parents, 0x15c,
616 0, 3, /* M */
617 16, 2, /* P */
618 24, 2, /* mux */
619 BIT(31), /* gate */
620 CLK_IS_CRITICAL);
621
622static SUNXI_CCU_MP_WITH_MUX_GATE(mbus1_clk, "mbus1", mbus_parents, 0x160,
623 0, 3, /* M */
624 16, 2, /* P */
625 24, 2, /* mux */
626 BIT(31), /* gate */
627 CLK_IS_CRITICAL);
628
629static SUNXI_CCU_M_WITH_MUX_GATE(mipi_dsi_clk, "mipi-dsi", lcd_ch1_parents,
630 0x168, 16, 3, 24, 2, BIT(31),
631 CLK_SET_RATE_PARENT);
632static SUNXI_CCU_M_WITH_MUX_GATE(mipi_dsi_dphy_clk, "mipi-dsi-dphy",
633 lcd_ch1_parents, 0x168, 0, 3, 8, 2,
634 BIT(15), CLK_SET_RATE_PARENT);
635static SUNXI_CCU_M_WITH_MUX_GATE(mipi_csi_dphy_clk, "mipi-csi-dphy",
636 lcd_ch1_parents, 0x16c, 0, 3, 8, 2,
637 BIT(15), 0);
638
639static SUNXI_CCU_M_WITH_MUX_GATE(iep_drc0_clk, "iep-drc0", de_parents,
640 0x180, 0, 3, 24, 2, BIT(31), 0);
641static SUNXI_CCU_M_WITH_MUX_GATE(iep_drc1_clk, "iep-drc1", de_parents,
642 0x184, 0, 3, 24, 2, BIT(31), 0);
643static SUNXI_CCU_M_WITH_MUX_GATE(iep_deu0_clk, "iep-deu0", de_parents,
644 0x188, 0, 3, 24, 2, BIT(31), 0);
645static SUNXI_CCU_M_WITH_MUX_GATE(iep_deu1_clk, "iep-deu1", de_parents,
646 0x18c, 0, 3, 24, 2, BIT(31), 0);
647
648static const char * const gpu_parents[] = { "pll-gpu", "pll-periph-2x",
649 "pll-video0", "pll-video1",
650 "pll9", "pll10" };
651static const struct ccu_mux_fixed_prediv gpu_predivs[] = {
652 { .index = 1, .div = 3, },
653};
654
655static struct ccu_div gpu_core_clk = {
656 .enable = BIT(31),
657 .div = _SUNXI_CCU_DIV(0, 3),
658 .mux = {
659 .shift = 24,
660 .width = 3,
661 .fixed_predivs = gpu_predivs,
662 .n_predivs = ARRAY_SIZE(gpu_predivs),
663 },
664 .common = {
665 .reg = 0x1a0,
666 .features = CCU_FEATURE_FIXED_PREDIV,
667 .hw.init = CLK_HW_INIT_PARENTS("gpu-core",
668 gpu_parents,
669 &ccu_div_ops,
670 0),
671 },
672};
673
674static struct ccu_div gpu_memory_clk = {
675 .enable = BIT(31),
676 .div = _SUNXI_CCU_DIV(0, 3),
677 .mux = {
678 .shift = 24,
679 .width = 3,
680 .fixed_predivs = gpu_predivs,
681 .n_predivs = ARRAY_SIZE(gpu_predivs),
682 },
683 .common = {
684 .reg = 0x1a4,
685 .features = CCU_FEATURE_FIXED_PREDIV,
686 .hw.init = CLK_HW_INIT_PARENTS("gpu-memory",
687 gpu_parents,
688 &ccu_div_ops,
689 0),
690 },
691};
692
693static struct ccu_div gpu_hyd_clk = {
694 .enable = BIT(31),
695 .div = _SUNXI_CCU_DIV(0, 3),
696 .mux = {
697 .shift = 24,
698 .width = 3,
699 .fixed_predivs = gpu_predivs,
700 .n_predivs = ARRAY_SIZE(gpu_predivs),
701 },
702 .common = {
703 .reg = 0x1a8,
704 .features = CCU_FEATURE_FIXED_PREDIV,
705 .hw.init = CLK_HW_INIT_PARENTS("gpu-hyd",
706 gpu_parents,
707 &ccu_div_ops,
708 0),
709 },
710};
711
712static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", mod0_default_parents, 0x1b0,
713 0, 3, /* M */
714 24, 2, /* mux */
715 BIT(31), /* gate */
716 0);
717
718static SUNXI_CCU_M_WITH_MUX_GATE(trace_clk, "trace", mod0_default_parents,
719 0x1b0,
720 0, 3, /* M */
721 24, 2, /* mux */
722 BIT(31), /* gate */
723 0);
724
725static const char * const clk_out_parents[] = { "osc24M", "osc32k", "osc24M",
726 "axi", "ahb1" };
727static const u8 clk_out_table[] = { 0, 1, 2, 11, 13 };
728
729static const struct ccu_mux_fixed_prediv clk_out_predivs[] = {
730 { .index = 0, .div = 750, },
731 { .index = 3, .div = 4, },
732 { .index = 4, .div = 4, },
733};
734
735static struct ccu_mp out_a_clk = {
736 .enable = BIT(31),
737 .m = _SUNXI_CCU_DIV(8, 5),
738 .p = _SUNXI_CCU_DIV(20, 2),
739 .mux = {
740 .shift = 24,
741 .width = 4,
742 .table = clk_out_table,
743 .fixed_predivs = clk_out_predivs,
744 .n_predivs = ARRAY_SIZE(clk_out_predivs),
745 },
746 .common = {
747 .reg = 0x300,
748 .features = CCU_FEATURE_FIXED_PREDIV,
749 .hw.init = CLK_HW_INIT_PARENTS("out-a",
750 clk_out_parents,
751 &ccu_div_ops,
752 0),
753 },
754};
755
756static struct ccu_mp out_b_clk = {
757 .enable = BIT(31),
758 .m = _SUNXI_CCU_DIV(8, 5),
759 .p = _SUNXI_CCU_DIV(20, 2),
760 .mux = {
761 .shift = 24,
762 .width = 4,
763 .table = clk_out_table,
764 .fixed_predivs = clk_out_predivs,
765 .n_predivs = ARRAY_SIZE(clk_out_predivs),
766 },
767 .common = {
768 .reg = 0x304,
769 .features = CCU_FEATURE_FIXED_PREDIV,
770 .hw.init = CLK_HW_INIT_PARENTS("out-b",
771 clk_out_parents,
772 &ccu_div_ops,
773 0),
774 },
775};
776
777static struct ccu_mp out_c_clk = {
778 .enable = BIT(31),
779 .m = _SUNXI_CCU_DIV(8, 5),
780 .p = _SUNXI_CCU_DIV(20, 2),
781 .mux = {
782 .shift = 24,
783 .width = 4,
784 .table = clk_out_table,
785 .fixed_predivs = clk_out_predivs,
786 .n_predivs = ARRAY_SIZE(clk_out_predivs),
787 },
788 .common = {
789 .reg = 0x308,
790 .features = CCU_FEATURE_FIXED_PREDIV,
791 .hw.init = CLK_HW_INIT_PARENTS("out-c",
792 clk_out_parents,
793 &ccu_div_ops,
794 0),
795 },
796};
797
798static struct ccu_common *sun6i_a31_ccu_clks[] = {
799 &pll_cpu_clk.common,
800 &pll_audio_base_clk.common,
801 &pll_video0_clk.common,
802 &pll_ve_clk.common,
803 &pll_ddr_clk.common,
804 &pll_periph_clk.common,
805 &pll_video1_clk.common,
806 &pll_gpu_clk.common,
807 &pll_mipi_clk.common,
808 &pll9_clk.common,
809 &pll10_clk.common,
810 &cpu_clk.common,
811 &axi_clk.common,
812 &ahb1_clk.common,
813 &apb1_clk.common,
814 &apb2_clk.common,
815 &ahb1_mipidsi_clk.common,
816 &ahb1_ss_clk.common,
817 &ahb1_dma_clk.common,
818 &ahb1_mmc0_clk.common,
819 &ahb1_mmc1_clk.common,
820 &ahb1_mmc2_clk.common,
821 &ahb1_mmc3_clk.common,
822 &ahb1_nand1_clk.common,
823 &ahb1_nand0_clk.common,
824 &ahb1_sdram_clk.common,
825 &ahb1_emac_clk.common,
826 &ahb1_ts_clk.common,
827 &ahb1_hstimer_clk.common,
828 &ahb1_spi0_clk.common,
829 &ahb1_spi1_clk.common,
830 &ahb1_spi2_clk.common,
831 &ahb1_spi3_clk.common,
832 &ahb1_otg_clk.common,
833 &ahb1_ehci0_clk.common,
834 &ahb1_ehci1_clk.common,
835 &ahb1_ohci0_clk.common,
836 &ahb1_ohci1_clk.common,
837 &ahb1_ohci2_clk.common,
838 &ahb1_ve_clk.common,
839 &ahb1_lcd0_clk.common,
840 &ahb1_lcd1_clk.common,
841 &ahb1_csi_clk.common,
842 &ahb1_hdmi_clk.common,
843 &ahb1_be0_clk.common,
844 &ahb1_be1_clk.common,
845 &ahb1_fe0_clk.common,
846 &ahb1_fe1_clk.common,
847 &ahb1_mp_clk.common,
848 &ahb1_gpu_clk.common,
849 &ahb1_deu0_clk.common,
850 &ahb1_deu1_clk.common,
851 &ahb1_drc0_clk.common,
852 &ahb1_drc1_clk.common,
853 &apb1_codec_clk.common,
854 &apb1_spdif_clk.common,
855 &apb1_digital_mic_clk.common,
856 &apb1_pio_clk.common,
857 &apb1_daudio0_clk.common,
858 &apb1_daudio1_clk.common,
859 &apb2_i2c0_clk.common,
860 &apb2_i2c1_clk.common,
861 &apb2_i2c2_clk.common,
862 &apb2_i2c3_clk.common,
863 &apb2_uart0_clk.common,
864 &apb2_uart1_clk.common,
865 &apb2_uart2_clk.common,
866 &apb2_uart3_clk.common,
867 &apb2_uart4_clk.common,
868 &apb2_uart5_clk.common,
869 &nand0_clk.common,
870 &nand1_clk.common,
871 &mmc0_clk.common,
872 &mmc0_sample_clk.common,
873 &mmc0_output_clk.common,
874 &mmc1_clk.common,
875 &mmc1_sample_clk.common,
876 &mmc1_output_clk.common,
877 &mmc2_clk.common,
878 &mmc2_sample_clk.common,
879 &mmc2_output_clk.common,
880 &mmc3_clk.common,
881 &mmc3_sample_clk.common,
882 &mmc3_output_clk.common,
883 &ts_clk.common,
884 &ss_clk.common,
885 &spi0_clk.common,
886 &spi1_clk.common,
887 &spi2_clk.common,
888 &spi3_clk.common,
889 &daudio0_clk.common,
890 &daudio1_clk.common,
891 &spdif_clk.common,
892 &usb_phy0_clk.common,
893 &usb_phy1_clk.common,
894 &usb_phy2_clk.common,
895 &usb_ohci0_clk.common,
896 &usb_ohci1_clk.common,
897 &usb_ohci2_clk.common,
898 &mdfs_clk.common,
899 &sdram0_clk.common,
900 &sdram1_clk.common,
901 &dram_ve_clk.common,
902 &dram_csi_isp_clk.common,
903 &dram_ts_clk.common,
904 &dram_drc0_clk.common,
905 &dram_drc1_clk.common,
906 &dram_deu0_clk.common,
907 &dram_deu1_clk.common,
908 &dram_fe0_clk.common,
909 &dram_fe1_clk.common,
910 &dram_be0_clk.common,
911 &dram_be1_clk.common,
912 &dram_mp_clk.common,
913 &be0_clk.common,
914 &be1_clk.common,
915 &fe0_clk.common,
916 &fe1_clk.common,
917 &mp_clk.common,
918 &lcd0_ch0_clk.common,
919 &lcd1_ch0_clk.common,
920 &lcd0_ch1_clk.common,
921 &lcd1_ch1_clk.common,
922 &csi0_sclk_clk.common,
923 &csi0_mclk_clk.common,
924 &csi1_mclk_clk.common,
925 &ve_clk.common,
926 &codec_clk.common,
927 &avs_clk.common,
928 &digital_mic_clk.common,
929 &hdmi_clk.common,
930 &hdmi_ddc_clk.common,
931 &ps_clk.common,
932 &mbus0_clk.common,
933 &mbus1_clk.common,
934 &mipi_dsi_clk.common,
935 &mipi_dsi_dphy_clk.common,
936 &mipi_csi_dphy_clk.common,
937 &iep_drc0_clk.common,
938 &iep_drc1_clk.common,
939 &iep_deu0_clk.common,
940 &iep_deu1_clk.common,
941 &gpu_core_clk.common,
942 &gpu_memory_clk.common,
943 &gpu_hyd_clk.common,
944 &ats_clk.common,
945 &trace_clk.common,
946 &out_a_clk.common,
947 &out_b_clk.common,
948 &out_c_clk.common,
949};
950
951/* We hardcode the divider to 4 for now */
952static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
953 "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
954static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
955 "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
956static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
957 "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
958static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
959 "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
960static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x",
961 "pll-periph", 1, 2, 0);
962static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x",
963 "pll-video0", 1, 2, CLK_SET_RATE_PARENT);
964static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x",
965 "pll-video1", 1, 2, CLK_SET_RATE_PARENT);
966
967static struct clk_hw_onecell_data sun6i_a31_hw_clks = {
968 .hws = {
969 [CLK_PLL_CPU] = &pll_cpu_clk.common.hw,
970 [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw,
971 [CLK_PLL_AUDIO] = &pll_audio_clk.hw,
972 [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw,
973 [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw,
974 [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw,
975 [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw,
976 [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw,
977 [CLK_PLL_VE] = &pll_ve_clk.common.hw,
978 [CLK_PLL_DDR] = &pll_ddr_clk.common.hw,
979 [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw,
980 [CLK_PLL_PERIPH_2X] = &pll_periph_2x_clk.hw,
981 [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw,
982 [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw,
983 [CLK_PLL_GPU] = &pll_gpu_clk.common.hw,
984 [CLK_PLL_MIPI] = &pll_mipi_clk.common.hw,
985 [CLK_PLL9] = &pll9_clk.common.hw,
986 [CLK_PLL10] = &pll10_clk.common.hw,
987 [CLK_CPU] = &cpu_clk.common.hw,
988 [CLK_AXI] = &axi_clk.common.hw,
989 [CLK_AHB1] = &ahb1_clk.common.hw,
990 [CLK_APB1] = &apb1_clk.common.hw,
991 [CLK_APB2] = &apb2_clk.common.hw,
992 [CLK_AHB1_MIPIDSI] = &ahb1_mipidsi_clk.common.hw,
993 [CLK_AHB1_SS] = &ahb1_ss_clk.common.hw,
994 [CLK_AHB1_DMA] = &ahb1_dma_clk.common.hw,
995 [CLK_AHB1_MMC0] = &ahb1_mmc0_clk.common.hw,
996 [CLK_AHB1_MMC1] = &ahb1_mmc1_clk.common.hw,
997 [CLK_AHB1_MMC2] = &ahb1_mmc2_clk.common.hw,
998 [CLK_AHB1_MMC3] = &ahb1_mmc3_clk.common.hw,
999 [CLK_AHB1_NAND1] = &ahb1_nand1_clk.common.hw,
1000 [CLK_AHB1_NAND0] = &ahb1_nand0_clk.common.hw,
1001 [CLK_AHB1_SDRAM] = &ahb1_sdram_clk.common.hw,
1002 [CLK_AHB1_EMAC] = &ahb1_emac_clk.common.hw,
1003 [CLK_AHB1_TS] = &ahb1_ts_clk.common.hw,
1004 [CLK_AHB1_HSTIMER] = &ahb1_hstimer_clk.common.hw,
1005 [CLK_AHB1_SPI0] = &ahb1_spi0_clk.common.hw,
1006 [CLK_AHB1_SPI1] = &ahb1_spi1_clk.common.hw,
1007 [CLK_AHB1_SPI2] = &ahb1_spi2_clk.common.hw,
1008 [CLK_AHB1_SPI3] = &ahb1_spi3_clk.common.hw,
1009 [CLK_AHB1_OTG] = &ahb1_otg_clk.common.hw,
1010 [CLK_AHB1_EHCI0] = &ahb1_ehci0_clk.common.hw,
1011 [CLK_AHB1_EHCI1] = &ahb1_ehci1_clk.common.hw,
1012 [CLK_AHB1_OHCI0] = &ahb1_ohci0_clk.common.hw,
1013 [CLK_AHB1_OHCI1] = &ahb1_ohci1_clk.common.hw,
1014 [CLK_AHB1_OHCI2] = &ahb1_ohci2_clk.common.hw,
1015 [CLK_AHB1_VE] = &ahb1_ve_clk.common.hw,
1016 [CLK_AHB1_LCD0] = &ahb1_lcd0_clk.common.hw,
1017 [CLK_AHB1_LCD1] = &ahb1_lcd1_clk.common.hw,
1018 [CLK_AHB1_CSI] = &ahb1_csi_clk.common.hw,
1019 [CLK_AHB1_HDMI] = &ahb1_hdmi_clk.common.hw,
1020 [CLK_AHB1_BE0] = &ahb1_be0_clk.common.hw,
1021 [CLK_AHB1_BE1] = &ahb1_be1_clk.common.hw,
1022 [CLK_AHB1_FE0] = &ahb1_fe0_clk.common.hw,
1023 [CLK_AHB1_FE1] = &ahb1_fe1_clk.common.hw,
1024 [CLK_AHB1_MP] = &ahb1_mp_clk.common.hw,
1025 [CLK_AHB1_GPU] = &ahb1_gpu_clk.common.hw,
1026 [CLK_AHB1_DEU0] = &ahb1_deu0_clk.common.hw,
1027 [CLK_AHB1_DEU1] = &ahb1_deu1_clk.common.hw,
1028 [CLK_AHB1_DRC0] = &ahb1_drc0_clk.common.hw,
1029 [CLK_AHB1_DRC1] = &ahb1_drc1_clk.common.hw,
1030 [CLK_APB1_CODEC] = &apb1_codec_clk.common.hw,
1031 [CLK_APB1_SPDIF] = &apb1_spdif_clk.common.hw,
1032 [CLK_APB1_DIGITAL_MIC] = &apb1_digital_mic_clk.common.hw,
1033 [CLK_APB1_PIO] = &apb1_pio_clk.common.hw,
1034 [CLK_APB1_DAUDIO0] = &apb1_daudio0_clk.common.hw,
1035 [CLK_APB1_DAUDIO1] = &apb1_daudio1_clk.common.hw,
1036 [CLK_APB2_I2C0] = &apb2_i2c0_clk.common.hw,
1037 [CLK_APB2_I2C1] = &apb2_i2c1_clk.common.hw,
1038 [CLK_APB2_I2C2] = &apb2_i2c2_clk.common.hw,
1039 [CLK_APB2_I2C3] = &apb2_i2c3_clk.common.hw,
1040 [CLK_APB2_UART0] = &apb2_uart0_clk.common.hw,
1041 [CLK_APB2_UART1] = &apb2_uart1_clk.common.hw,
1042 [CLK_APB2_UART2] = &apb2_uart2_clk.common.hw,
1043 [CLK_APB2_UART3] = &apb2_uart3_clk.common.hw,
1044 [CLK_APB2_UART4] = &apb2_uart4_clk.common.hw,
1045 [CLK_APB2_UART5] = &apb2_uart5_clk.common.hw,
1046 [CLK_NAND0] = &nand0_clk.common.hw,
1047 [CLK_NAND1] = &nand1_clk.common.hw,
1048 [CLK_MMC0] = &mmc0_clk.common.hw,
1049 [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw,
1050 [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw,
1051 [CLK_MMC1] = &mmc1_clk.common.hw,
1052 [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw,
1053 [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw,
1054 [CLK_MMC2] = &mmc2_clk.common.hw,
1055 [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw,
1056 [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw,
1057 [CLK_MMC3] = &mmc3_clk.common.hw,
1058 [CLK_MMC3_SAMPLE] = &mmc3_sample_clk.common.hw,
1059 [CLK_MMC3_OUTPUT] = &mmc3_output_clk.common.hw,
1060 [CLK_TS] = &ts_clk.common.hw,
1061 [CLK_SS] = &ss_clk.common.hw,
1062 [CLK_SPI0] = &spi0_clk.common.hw,
1063 [CLK_SPI1] = &spi1_clk.common.hw,
1064 [CLK_SPI2] = &spi2_clk.common.hw,
1065 [CLK_SPI3] = &spi3_clk.common.hw,
1066 [CLK_DAUDIO0] = &daudio0_clk.common.hw,
1067 [CLK_DAUDIO1] = &daudio1_clk.common.hw,
1068 [CLK_SPDIF] = &spdif_clk.common.hw,
1069 [CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
1070 [CLK_USB_PHY1] = &usb_phy1_clk.common.hw,
1071 [CLK_USB_PHY2] = &usb_phy2_clk.common.hw,
1072 [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw,
1073 [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw,
1074 [CLK_USB_OHCI2] = &usb_ohci2_clk.common.hw,
1075 [CLK_MDFS] = &mdfs_clk.common.hw,
1076 [CLK_SDRAM0] = &sdram0_clk.common.hw,
1077 [CLK_SDRAM1] = &sdram1_clk.common.hw,
1078 [CLK_DRAM_VE] = &dram_ve_clk.common.hw,
1079 [CLK_DRAM_CSI_ISP] = &dram_csi_isp_clk.common.hw,
1080 [CLK_DRAM_TS] = &dram_ts_clk.common.hw,
1081 [CLK_DRAM_DRC0] = &dram_drc0_clk.common.hw,
1082 [CLK_DRAM_DRC1] = &dram_drc1_clk.common.hw,
1083 [CLK_DRAM_DEU0] = &dram_deu0_clk.common.hw,
1084 [CLK_DRAM_DEU1] = &dram_deu1_clk.common.hw,
1085 [CLK_DRAM_FE0] = &dram_fe0_clk.common.hw,
1086 [CLK_DRAM_FE1] = &dram_fe1_clk.common.hw,
1087 [CLK_DRAM_BE0] = &dram_be0_clk.common.hw,
1088 [CLK_DRAM_BE1] = &dram_be1_clk.common.hw,
1089 [CLK_DRAM_MP] = &dram_mp_clk.common.hw,
1090 [CLK_BE0] = &be0_clk.common.hw,
1091 [CLK_BE1] = &be1_clk.common.hw,
1092 [CLK_FE0] = &fe0_clk.common.hw,
1093 [CLK_FE1] = &fe1_clk.common.hw,
1094 [CLK_MP] = &mp_clk.common.hw,
1095 [CLK_LCD0_CH0] = &lcd0_ch0_clk.common.hw,
1096 [CLK_LCD1_CH0] = &lcd1_ch0_clk.common.hw,
1097 [CLK_LCD0_CH1] = &lcd0_ch1_clk.common.hw,
1098 [CLK_LCD1_CH1] = &lcd1_ch1_clk.common.hw,
1099 [CLK_CSI0_SCLK] = &csi0_sclk_clk.common.hw,
1100 [CLK_CSI0_MCLK] = &csi0_mclk_clk.common.hw,
1101 [CLK_CSI1_MCLK] = &csi1_mclk_clk.common.hw,
1102 [CLK_VE] = &ve_clk.common.hw,
1103 [CLK_CODEC] = &codec_clk.common.hw,
1104 [CLK_AVS] = &avs_clk.common.hw,
1105 [CLK_DIGITAL_MIC] = &digital_mic_clk.common.hw,
1106 [CLK_HDMI] = &hdmi_clk.common.hw,
1107 [CLK_HDMI_DDC] = &hdmi_ddc_clk.common.hw,
1108 [CLK_PS] = &ps_clk.common.hw,
1109 [CLK_MBUS0] = &mbus0_clk.common.hw,
1110 [CLK_MBUS1] = &mbus1_clk.common.hw,
1111 [CLK_MIPI_DSI] = &mipi_dsi_clk.common.hw,
1112 [CLK_MIPI_DSI_DPHY] = &mipi_dsi_dphy_clk.common.hw,
1113 [CLK_MIPI_CSI_DPHY] = &mipi_csi_dphy_clk.common.hw,
1114 [CLK_IEP_DRC0] = &iep_drc0_clk.common.hw,
1115 [CLK_IEP_DRC1] = &iep_drc1_clk.common.hw,
1116 [CLK_IEP_DEU0] = &iep_deu0_clk.common.hw,
1117 [CLK_IEP_DEU1] = &iep_deu1_clk.common.hw,
1118 [CLK_GPU_CORE] = &gpu_core_clk.common.hw,
1119 [CLK_GPU_MEMORY] = &gpu_memory_clk.common.hw,
1120 [CLK_GPU_HYD] = &gpu_hyd_clk.common.hw,
1121 [CLK_ATS] = &ats_clk.common.hw,
1122 [CLK_TRACE] = &trace_clk.common.hw,
1123 [CLK_OUT_A] = &out_a_clk.common.hw,
1124 [CLK_OUT_B] = &out_b_clk.common.hw,
1125 [CLK_OUT_C] = &out_c_clk.common.hw,
1126 },
1127 .num = CLK_NUMBER,
1128};
1129
1130static struct ccu_reset_map sun6i_a31_ccu_resets[] = {
1131 [RST_USB_PHY0] = { 0x0cc, BIT(0) },
1132 [RST_USB_PHY1] = { 0x0cc, BIT(1) },
1133 [RST_USB_PHY2] = { 0x0cc, BIT(2) },
1134
1135 [RST_AHB1_MIPI_DSI] = { 0x2c0, BIT(1) },
1136 [RST_AHB1_SS] = { 0x2c0, BIT(5) },
1137 [RST_AHB1_DMA] = { 0x2c0, BIT(6) },
1138 [RST_AHB1_MMC0] = { 0x2c0, BIT(8) },
1139 [RST_AHB1_MMC1] = { 0x2c0, BIT(9) },
1140 [RST_AHB1_MMC2] = { 0x2c0, BIT(10) },
1141 [RST_AHB1_MMC3] = { 0x2c0, BIT(11) },
1142 [RST_AHB1_NAND1] = { 0x2c0, BIT(12) },
1143 [RST_AHB1_NAND0] = { 0x2c0, BIT(13) },
1144 [RST_AHB1_SDRAM] = { 0x2c0, BIT(14) },
1145 [RST_AHB1_EMAC] = { 0x2c0, BIT(17) },
1146 [RST_AHB1_TS] = { 0x2c0, BIT(18) },
1147 [RST_AHB1_HSTIMER] = { 0x2c0, BIT(19) },
1148 [RST_AHB1_SPI0] = { 0x2c0, BIT(20) },
1149 [RST_AHB1_SPI1] = { 0x2c0, BIT(21) },
1150 [RST_AHB1_SPI2] = { 0x2c0, BIT(22) },
1151 [RST_AHB1_SPI3] = { 0x2c0, BIT(23) },
1152 [RST_AHB1_OTG] = { 0x2c0, BIT(24) },
1153 [RST_AHB1_EHCI0] = { 0x2c0, BIT(26) },
1154 [RST_AHB1_EHCI1] = { 0x2c0, BIT(27) },
1155 [RST_AHB1_OHCI0] = { 0x2c0, BIT(29) },
1156 [RST_AHB1_OHCI1] = { 0x2c0, BIT(30) },
1157 [RST_AHB1_OHCI2] = { 0x2c0, BIT(31) },
1158
1159 [RST_AHB1_VE] = { 0x2c4, BIT(0) },
1160 [RST_AHB1_LCD0] = { 0x2c4, BIT(4) },
1161 [RST_AHB1_LCD1] = { 0x2c4, BIT(5) },
1162 [RST_AHB1_CSI] = { 0x2c4, BIT(8) },
1163 [RST_AHB1_HDMI] = { 0x2c4, BIT(11) },
1164 [RST_AHB1_BE0] = { 0x2c4, BIT(12) },
1165 [RST_AHB1_BE1] = { 0x2c4, BIT(13) },
1166 [RST_AHB1_FE0] = { 0x2c4, BIT(14) },
1167 [RST_AHB1_FE1] = { 0x2c4, BIT(15) },
1168 [RST_AHB1_MP] = { 0x2c4, BIT(18) },
1169 [RST_AHB1_GPU] = { 0x2c4, BIT(20) },
1170 [RST_AHB1_DEU0] = { 0x2c4, BIT(23) },
1171 [RST_AHB1_DEU1] = { 0x2c4, BIT(24) },
1172 [RST_AHB1_DRC0] = { 0x2c4, BIT(25) },
1173 [RST_AHB1_DRC1] = { 0x2c4, BIT(26) },
1174 [RST_AHB1_LVDS] = { 0x2c8, BIT(0) },
1175
1176 [RST_APB1_CODEC] = { 0x2d0, BIT(0) },
1177 [RST_APB1_SPDIF] = { 0x2d0, BIT(1) },
1178 [RST_APB1_DIGITAL_MIC] = { 0x2d0, BIT(4) },
1179 [RST_APB1_DAUDIO0] = { 0x2d0, BIT(12) },
1180 [RST_APB1_DAUDIO1] = { 0x2d0, BIT(13) },
1181
1182 [RST_APB2_I2C0] = { 0x2d8, BIT(0) },
1183 [RST_APB2_I2C1] = { 0x2d8, BIT(1) },
1184 [RST_APB2_I2C2] = { 0x2d8, BIT(2) },
1185 [RST_APB2_I2C3] = { 0x2d8, BIT(3) },
1186 [RST_APB2_UART0] = { 0x2d8, BIT(16) },
1187 [RST_APB2_UART1] = { 0x2d8, BIT(17) },
1188 [RST_APB2_UART2] = { 0x2d8, BIT(18) },
1189 [RST_APB2_UART3] = { 0x2d8, BIT(19) },
1190 [RST_APB2_UART4] = { 0x2d8, BIT(20) },
1191 [RST_APB2_UART5] = { 0x2d8, BIT(21) },
1192};
1193
1194static const struct sunxi_ccu_desc sun6i_a31_ccu_desc = {
1195 .ccu_clks = sun6i_a31_ccu_clks,
1196 .num_ccu_clks = ARRAY_SIZE(sun6i_a31_ccu_clks),
1197
1198 .hw_clks = &sun6i_a31_hw_clks,
1199
1200 .resets = sun6i_a31_ccu_resets,
1201 .num_resets = ARRAY_SIZE(sun6i_a31_ccu_resets),
1202};
1203
1204static struct ccu_mux_nb sun6i_a31_cpu_nb = {
1205 .common = &cpu_clk.common,
1206 .cm = &cpu_clk.mux,
1207 .delay_us = 1, /* > 8 clock cycles at 24 MHz */
1208 .bypass_index = 1, /* index of 24 MHz oscillator */
1209};
1210
1211static void __init sun6i_a31_ccu_setup(struct device_node *node)
1212{
1213 void __iomem *reg;
1214 u32 val;
1215
1216 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
1217 if (IS_ERR(reg)) {
1218 pr_err("%s: Could not map the clock registers\n",
1219 of_node_full_name(node));
1220 return;
1221 }
1222
1223 /* Force the PLL-Audio-1x divider to 4 */
1224 val = readl(reg + SUN6I_A31_PLL_AUDIO_REG);
1225 val &= ~GENMASK(19, 16);
1226 writel(val | (3 << 16), reg + SUN6I_A31_PLL_AUDIO_REG);
1227
1228 /* Force PLL-MIPI to MIPI mode */
1229 val = readl(reg + SUN6I_A31_PLL_MIPI_REG);
1230 val &= BIT(16);
1231 writel(val, reg + SUN6I_A31_PLL_MIPI_REG);
1232
1233 sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc);
1234
1235 ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk,
1236 &sun6i_a31_cpu_nb);
1237}
1238CLK_OF_DECLARE(sun6i_a31_ccu, "allwinner,sun6i-a31-ccu",
1239 sun6i_a31_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.h b/drivers/clk/sunxi-ng/ccu-sun6i-a31.h
new file mode 100644
index 000000000000..4e434011e9e7
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.h
@@ -0,0 +1,72 @@
1/*
2 * Copyright 2016 Chen-Yu Tsai
3 *
4 * Chen-Yu Tsai <wens@csie.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _CCU_SUN6I_A31_H_
18#define _CCU_SUN6I_A31_H_
19
20#include <dt-bindings/clock/sun6i-a31-ccu.h>
21#include <dt-bindings/reset/sun6i-a31-ccu.h>
22
23#define CLK_PLL_CPU 0
24#define CLK_PLL_AUDIO_BASE 1
25#define CLK_PLL_AUDIO 2
26#define CLK_PLL_AUDIO_2X 3
27#define CLK_PLL_AUDIO_4X 4
28#define CLK_PLL_AUDIO_8X 5
29#define CLK_PLL_VIDEO0 6
30#define CLK_PLL_VIDEO0_2X 7
31#define CLK_PLL_VE 8
32#define CLK_PLL_DDR 9
33
34/* The PLL_PERIPH clock is exported */
35
36#define CLK_PLL_PERIPH_2X 11
37#define CLK_PLL_VIDEO1 12
38#define CLK_PLL_VIDEO1_2X 13
39#define CLK_PLL_GPU 14
40#define CLK_PLL_MIPI 15
41#define CLK_PLL9 16
42#define CLK_PLL10 17
43
44/* The CPUX clock is exported */
45
46#define CLK_AXI 19
47#define CLK_AHB1 20
48#define CLK_APB1 21
49#define CLK_APB2 22
50
51/* All the bus gates are exported */
52
53/* The first bunch of module clocks are exported */
54
55/* EMAC clock is not implemented */
56
57#define CLK_MDFS 107
58#define CLK_SDRAM0 108
59#define CLK_SDRAM1 109
60
61/* All the DRAM gates are exported */
62
63/* Some more module clocks are exported */
64
65#define CLK_MBUS0 141
66#define CLK_MBUS1 142
67
68/* Some more module clocks and external clock outputs are exported */
69
70#define CLK_NUMBER (CLK_OUT_C + 1)
71
72#endif /* _CCU_SUN6I_A31_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h b/drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h
new file mode 100644
index 000000000000..62c0f8d49ef8
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright 2016 Maxime Ripard
3 *
4 * Maxime Ripard <maxime.ripard@free-electrons.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _CCU_SUN8I_A23_A33_H_
18#define _CCU_SUN8I_A23_A33_H_
19
20#include <dt-bindings/clock/sun8i-a23-a33-ccu.h>
21#include <dt-bindings/reset/sun8i-a23-a33-ccu.h>
22
23#define CLK_PLL_CPUX 0
24#define CLK_PLL_AUDIO_BASE 1
25#define CLK_PLL_AUDIO 2
26#define CLK_PLL_AUDIO_2X 3
27#define CLK_PLL_AUDIO_4X 4
28#define CLK_PLL_AUDIO_8X 5
29#define CLK_PLL_VIDEO 6
30#define CLK_PLL_VIDEO_2X 7
31#define CLK_PLL_VE 8
32#define CLK_PLL_DDR0 9
33#define CLK_PLL_PERIPH 10
34#define CLK_PLL_PERIPH_2X 11
35#define CLK_PLL_GPU 12
36#define CLK_PLL_MIPI 13
37#define CLK_PLL_HSIC 14
38#define CLK_PLL_DE 15
39#define CLK_PLL_DDR1 16
40#define CLK_PLL_DDR 17
41
42/* The CPUX clock is exported */
43
44#define CLK_AXI 19
45#define CLK_AHB1 20
46#define CLK_APB1 21
47#define CLK_APB2 22
48
49/* All the bus gates are exported */
50
51/* The first part of the mod clocks is exported */
52
53#define CLK_DRAM 79
54
55/* Some more module clocks are exported */
56
57#define CLK_MBUS 95
58
59/* And the last module clocks are exported */
60
61#define CLK_NUMBER (CLK_ATS + 1)
62
63#endif /* _CCU_SUN8I_A23_A33_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
new file mode 100644
index 000000000000..2646d980087b
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
@@ -0,0 +1,737 @@
1/*
2 * Copyright (c) 2016 Maxime Ripard. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/clk-provider.h>
15#include <linux/of_address.h>
16
17#include "ccu_common.h"
18#include "ccu_reset.h"
19
20#include "ccu_div.h"
21#include "ccu_gate.h"
22#include "ccu_mp.h"
23#include "ccu_mult.h"
24#include "ccu_nk.h"
25#include "ccu_nkm.h"
26#include "ccu_nkmp.h"
27#include "ccu_nm.h"
28#include "ccu_phase.h"
29
30#include "ccu-sun8i-a23-a33.h"
31
32
33static struct ccu_nkmp pll_cpux_clk = {
34 .enable = BIT(31),
35 .lock = BIT(28),
36
37 .n = _SUNXI_CCU_MULT(8, 5),
38 .k = _SUNXI_CCU_MULT(4, 2),
39 .m = _SUNXI_CCU_DIV(0, 2),
40 .p = _SUNXI_CCU_DIV_MAX(16, 2, 4),
41
42 .common = {
43 .reg = 0x000,
44 .hw.init = CLK_HW_INIT("pll-cpux", "osc24M",
45 &ccu_nkmp_ops,
46 0),
47 },
48};
49
50/*
51 * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
52 * the base (2x, 4x and 8x), and one variable divider (the one true
53 * pll audio).
54 *
55 * We don't have any need for the variable divider for now, so we just
56 * hardcode it to match with the clock names
57 */
58#define SUN8I_A23_PLL_AUDIO_REG 0x008
59
60static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
61 "osc24M", 0x008,
62 8, 7, /* N */
63 0, 5, /* M */
64 BIT(31), /* gate */
65 BIT(28), /* lock */
66 CLK_SET_RATE_UNGATE);
67
68static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
69 "osc24M", 0x010,
70 8, 7, /* N */
71 0, 4, /* M */
72 BIT(24), /* frac enable */
73 BIT(25), /* frac select */
74 270000000, /* frac rate 0 */
75 297000000, /* frac rate 1 */
76 BIT(31), /* gate */
77 BIT(28), /* lock */
78 CLK_SET_RATE_UNGATE);
79
80static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
81 "osc24M", 0x018,
82 8, 7, /* N */
83 0, 4, /* M */
84 BIT(24), /* frac enable */
85 BIT(25), /* frac select */
86 270000000, /* frac rate 0 */
87 297000000, /* frac rate 1 */
88 BIT(31), /* gate */
89 BIT(28), /* lock */
90 CLK_SET_RATE_UNGATE);
91
92static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr",
93 "osc24M", 0x020,
94 8, 5, /* N */
95 4, 2, /* K */
96 0, 2, /* M */
97 BIT(31), /* gate */
98 BIT(28), /* lock */
99 0);
100
101static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph_clk, "pll-periph",
102 "osc24M", 0x028,
103 8, 5, /* N */
104 4, 2, /* K */
105 BIT(31), /* gate */
106 BIT(28), /* lock */
107 2, /* post-div */
108 CLK_SET_RATE_UNGATE);
109
110static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
111 "osc24M", 0x038,
112 8, 7, /* N */
113 0, 4, /* M */
114 BIT(24), /* frac enable */
115 BIT(25), /* frac select */
116 270000000, /* frac rate 0 */
117 297000000, /* frac rate 1 */
118 BIT(31), /* gate */
119 BIT(28), /* lock */
120 CLK_SET_RATE_UNGATE);
121
122/*
123 * The MIPI PLL has 2 modes: "MIPI" and "HDMI".
124 *
125 * The MIPI mode is a standard NKM-style clock. The HDMI mode is an
126 * integer / fractional clock with switchable multipliers and dividers.
127 * This is not supported here. We hardcode the PLL to MIPI mode.
128 */
129#define SUN8I_A23_PLL_MIPI_REG 0x040
130static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_mipi_clk, "pll-mipi",
131 "pll-video", 0x040,
132 8, 4, /* N */
133 4, 2, /* K */
134 0, 4, /* M */
135 BIT(31), /* gate */
136 BIT(28), /* lock */
137 CLK_SET_RATE_UNGATE);
138
139static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_hsic_clk, "pll-hsic",
140 "osc24M", 0x044,
141 8, 7, /* N */
142 0, 4, /* M */
143 BIT(24), /* frac enable */
144 BIT(25), /* frac select */
145 270000000, /* frac rate 0 */
146 297000000, /* frac rate 1 */
147 BIT(31), /* gate */
148 BIT(28), /* lock */
149 CLK_SET_RATE_UNGATE);
150
151static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de",
152 "osc24M", 0x048,
153 8, 7, /* N */
154 0, 4, /* M */
155 BIT(24), /* frac enable */
156 BIT(25), /* frac select */
157 270000000, /* frac rate 0 */
158 297000000, /* frac rate 1 */
159 BIT(31), /* gate */
160 BIT(28), /* lock */
161 CLK_SET_RATE_UNGATE);
162
163static const char * const cpux_parents[] = { "osc32k", "osc24M",
164 "pll-cpux" , "pll-cpux" };
165static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
166 0x050, 16, 2, CLK_IS_CRITICAL);
167
168static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0);
169
170static const char * const ahb1_parents[] = { "osc32k", "osc24M",
171 "axi" , "pll-periph" };
172static struct ccu_div ahb1_clk = {
173 .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
174
175 .mux = {
176 .shift = 12,
177 .width = 2,
178
179 .variable_prediv = {
180 .index = 3,
181 .shift = 6,
182 .width = 2,
183 },
184 },
185
186 .common = {
187 .reg = 0x054,
188 .features = CCU_FEATURE_VARIABLE_PREDIV,
189 .hw.init = CLK_HW_INIT_PARENTS("ahb1",
190 ahb1_parents,
191 &ccu_div_ops,
192 0),
193 },
194};
195
196static struct clk_div_table apb1_div_table[] = {
197 { .val = 0, .div = 2 },
198 { .val = 1, .div = 2 },
199 { .val = 2, .div = 4 },
200 { .val = 3, .div = 8 },
201 { /* Sentinel */ },
202};
203static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1",
204 0x054, 8, 2, apb1_div_table, 0);
205
206static const char * const apb2_parents[] = { "osc32k", "osc24M",
207 "pll-periph" , "pll-periph" };
208static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
209 0, 5, /* M */
210 16, 2, /* P */
211 24, 2, /* mux */
212 0);
213
214static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb1",
215 0x060, BIT(1), 0);
216static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1",
217 0x060, BIT(6), 0);
218static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1",
219 0x060, BIT(8), 0);
220static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1",
221 0x060, BIT(9), 0);
222static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1",
223 0x060, BIT(10), 0);
224static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb1",
225 0x060, BIT(13), 0);
226static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1",
227 0x060, BIT(14), 0);
228static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1",
229 0x060, BIT(19), 0);
230static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1",
231 0x060, BIT(20), 0);
232static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb1",
233 0x060, BIT(21), 0);
234static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1",
235 0x060, BIT(24), 0);
236static SUNXI_CCU_GATE(bus_ehci_clk, "bus-ehci", "ahb1",
237 0x060, BIT(26), 0);
238static SUNXI_CCU_GATE(bus_ohci_clk, "bus-ohci", "ahb1",
239 0x060, BIT(29), 0);
240
241static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb1",
242 0x064, BIT(0), 0);
243static SUNXI_CCU_GATE(bus_lcd_clk, "bus-lcd", "ahb1",
244 0x064, BIT(4), 0);
245static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb1",
246 0x064, BIT(8), 0);
247static SUNXI_CCU_GATE(bus_de_be_clk, "bus-de-be", "ahb1",
248 0x064, BIT(12), 0);
249static SUNXI_CCU_GATE(bus_de_fe_clk, "bus-de-fe", "ahb1",
250 0x064, BIT(14), 0);
251static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "ahb1",
252 0x064, BIT(20), 0);
253static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb1",
254 0x064, BIT(21), 0);
255static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb1",
256 0x064, BIT(22), 0);
257static SUNXI_CCU_GATE(bus_drc_clk, "bus-drc", "ahb1",
258 0x064, BIT(25), 0);
259
260static SUNXI_CCU_GATE(bus_codec_clk, "bus-codec", "apb1",
261 0x068, BIT(0), 0);
262static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb1",
263 0x068, BIT(5), 0);
264static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1",
265 0x068, BIT(12), 0);
266static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1",
267 0x068, BIT(13), 0);
268
269static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2",
270 0x06c, BIT(0), 0);
271static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2",
272 0x06c, BIT(1), 0);
273static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2",
274 0x06c, BIT(2), 0);
275static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2",
276 0x06c, BIT(16), 0);
277static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2",
278 0x06c, BIT(17), 0);
279static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2",
280 0x06c, BIT(18), 0);
281static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2",
282 0x06c, BIT(19), 0);
283static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2",
284 0x06c, BIT(20), 0);
285
286static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" };
287static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
288 0, 4, /* M */
289 16, 2, /* P */
290 24, 2, /* mux */
291 BIT(31), /* gate */
292 0);
293
294static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
295 0, 4, /* M */
296 16, 2, /* P */
297 24, 2, /* mux */
298 BIT(31), /* gate */
299 0);
300
301static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
302 0x088, 20, 3, 0);
303static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
304 0x088, 8, 3, 0);
305
306static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
307 0, 4, /* M */
308 16, 2, /* P */
309 24, 2, /* mux */
310 BIT(31), /* gate */
311 0);
312
313static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
314 0x08c, 20, 3, 0);
315static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
316 0x08c, 8, 3, 0);
317
318static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
319 0, 4, /* M */
320 16, 2, /* P */
321 24, 2, /* mux */
322 BIT(31), /* gate */
323 0);
324
325static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
326 0x090, 20, 3, 0);
327static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
328 0x090, 8, 3, 0);
329
330static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
331 0, 4, /* M */
332 16, 2, /* P */
333 24, 2, /* mux */
334 BIT(31), /* gate */
335 0);
336
337static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
338 0, 4, /* M */
339 16, 2, /* P */
340 24, 2, /* mux */
341 BIT(31), /* gate */
342 0);
343
344static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
345 "pll-audio-2x", "pll-audio" };
346static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents,
347 0x0b0, 16, 2, BIT(31), 0);
348
349static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", i2s_parents,
350 0x0b4, 16, 2, BIT(31), 0);
351
352/* TODO: the parent for most of the USB clocks is not known */
353static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
354 0x0cc, BIT(8), 0);
355static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M",
356 0x0cc, BIT(9), 0);
357static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "pll-hsic",
358 0x0cc, BIT(10), 0);
359static SUNXI_CCU_GATE(usb_hsic_12M_clk, "usb-hsic-12M", "osc24M",
360 0x0cc, BIT(11), 0);
361static SUNXI_CCU_GATE(usb_ohci_clk, "usb-ohci", "osc24M",
362 0x0cc, BIT(16), 0);
363
364static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "pll-ddr",
365 0x100, BIT(0), 0);
366static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "pll-ddr",
367 0x100, BIT(1), 0);
368static SUNXI_CCU_GATE(dram_drc_clk, "dram-drc", "pll-ddr",
369 0x100, BIT(16), 0);
370static SUNXI_CCU_GATE(dram_de_fe_clk, "dram-de-fe", "pll-ddr",
371 0x100, BIT(24), 0);
372static SUNXI_CCU_GATE(dram_de_be_clk, "dram-de-be", "pll-ddr",
373 0x100, BIT(26), 0);
374
375static const char * const de_parents[] = { "pll-video", "pll-periph-2x",
376 "pll-gpu", "pll-de" };
377static const u8 de_table[] = { 0, 2, 3, 5 };
378static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_be_clk, "de-be",
379 de_parents, de_table,
380 0x104, 0, 4, 24, 3, BIT(31), 0);
381
382static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_fe_clk, "de-fe",
383 de_parents, de_table,
384 0x10c, 0, 4, 24, 3, BIT(31), 0);
385
386static const char * const lcd_ch0_parents[] = { "pll-video", "pll-video-2x",
387 "pll-mipi" };
388static const u8 lcd_ch0_table[] = { 0, 2, 4 };
389static SUNXI_CCU_MUX_TABLE_WITH_GATE(lcd_ch0_clk, "lcd-ch0",
390 lcd_ch0_parents, lcd_ch0_table,
391 0x118, 24, 3, BIT(31),
392 CLK_SET_RATE_PARENT);
393
394static const char * const lcd_ch1_parents[] = { "pll-video", "pll-video-2x" };
395static const u8 lcd_ch1_table[] = { 0, 2 };
396static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(lcd_ch1_clk, "lcd-ch1",
397 lcd_ch1_parents, lcd_ch1_table,
398 0x12c, 0, 4, 24, 2, BIT(31), 0);
399
400static const char * const csi_sclk_parents[] = { "pll-video", "pll-de",
401 "pll-mipi", "pll-ve" };
402static const u8 csi_sclk_table[] = { 0, 3, 4, 5 };
403static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_sclk_clk, "csi-sclk",
404 csi_sclk_parents, csi_sclk_table,
405 0x134, 16, 4, 24, 3, BIT(31), 0);
406
407static const char * const csi_mclk_parents[] = { "pll-video", "pll-de",
408 "osc24M" };
409static const u8 csi_mclk_table[] = { 0, 3, 5 };
410static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk",
411 csi_mclk_parents, csi_mclk_table,
412 0x134, 0, 5, 8, 3, BIT(15), 0);
413
414static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
415 0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT);
416
417static SUNXI_CCU_GATE(ac_dig_clk, "ac-dig", "pll-audio",
418 0x140, BIT(31), 0);
419static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M",
420 0x144, BIT(31), 0);
421
422static const char * const mbus_parents[] = { "osc24M", "pll-periph-2x",
423 "pll-ddr" };
424static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
425 0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL);
426
427static const char * const dsi_sclk_parents[] = { "pll-video", "pll-video-2x" };
428static const u8 dsi_sclk_table[] = { 0, 2 };
429static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_sclk_clk, "dsi-sclk",
430 dsi_sclk_parents, dsi_sclk_table,
431 0x168, 16, 4, 24, 2, BIT(31), 0);
432
433static const char * const dsi_dphy_parents[] = { "pll-video", "pll-periph" };
434static const u8 dsi_dphy_table[] = { 0, 2 };
435static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_dphy_clk, "dsi-dphy",
436 dsi_dphy_parents, dsi_dphy_table,
437 0x168, 0, 4, 8, 2, BIT(15), 0);
438
439static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(drc_clk, "drc",
440 de_parents, de_table,
441 0x180, 0, 4, 24, 3, BIT(31), 0);
442
443static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu",
444 0x1a0, 0, 3, BIT(31), 0);
445
446static const char * const ats_parents[] = { "osc24M", "pll-periph" };
447static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", ats_parents,
448 0x1b0, 0, 3, 24, 2, BIT(31), 0);
449
450static struct ccu_common *sun8i_a23_ccu_clks[] = {
451 &pll_cpux_clk.common,
452 &pll_audio_base_clk.common,
453 &pll_video_clk.common,
454 &pll_ve_clk.common,
455 &pll_ddr_clk.common,
456 &pll_periph_clk.common,
457 &pll_gpu_clk.common,
458 &pll_mipi_clk.common,
459 &pll_hsic_clk.common,
460 &pll_de_clk.common,
461 &cpux_clk.common,
462 &axi_clk.common,
463 &ahb1_clk.common,
464 &apb1_clk.common,
465 &apb2_clk.common,
466 &bus_mipi_dsi_clk.common,
467 &bus_dma_clk.common,
468 &bus_mmc0_clk.common,
469 &bus_mmc1_clk.common,
470 &bus_mmc2_clk.common,
471 &bus_nand_clk.common,
472 &bus_dram_clk.common,
473 &bus_hstimer_clk.common,
474 &bus_spi0_clk.common,
475 &bus_spi1_clk.common,
476 &bus_otg_clk.common,
477 &bus_ehci_clk.common,
478 &bus_ohci_clk.common,
479 &bus_ve_clk.common,
480 &bus_lcd_clk.common,
481 &bus_csi_clk.common,
482 &bus_de_fe_clk.common,
483 &bus_de_be_clk.common,
484 &bus_gpu_clk.common,
485 &bus_msgbox_clk.common,
486 &bus_spinlock_clk.common,
487 &bus_drc_clk.common,
488 &bus_codec_clk.common,
489 &bus_pio_clk.common,
490 &bus_i2s0_clk.common,
491 &bus_i2s1_clk.common,
492 &bus_i2c0_clk.common,
493 &bus_i2c1_clk.common,
494 &bus_i2c2_clk.common,
495 &bus_uart0_clk.common,
496 &bus_uart1_clk.common,
497 &bus_uart2_clk.common,
498 &bus_uart3_clk.common,
499 &bus_uart4_clk.common,
500 &nand_clk.common,
501 &mmc0_clk.common,
502 &mmc0_sample_clk.common,
503 &mmc0_output_clk.common,
504 &mmc1_clk.common,
505 &mmc1_sample_clk.common,
506 &mmc1_output_clk.common,
507 &mmc2_clk.common,
508 &mmc2_sample_clk.common,
509 &mmc2_output_clk.common,
510 &spi0_clk.common,
511 &spi1_clk.common,
512 &i2s0_clk.common,
513 &i2s1_clk.common,
514 &usb_phy0_clk.common,
515 &usb_phy1_clk.common,
516 &usb_hsic_clk.common,
517 &usb_hsic_12M_clk.common,
518 &usb_ohci_clk.common,
519 &dram_ve_clk.common,
520 &dram_csi_clk.common,
521 &dram_drc_clk.common,
522 &dram_de_fe_clk.common,
523 &dram_de_be_clk.common,
524 &de_be_clk.common,
525 &de_fe_clk.common,
526 &lcd_ch0_clk.common,
527 &lcd_ch1_clk.common,
528 &csi_sclk_clk.common,
529 &csi_mclk_clk.common,
530 &ve_clk.common,
531 &ac_dig_clk.common,
532 &avs_clk.common,
533 &mbus_clk.common,
534 &dsi_sclk_clk.common,
535 &dsi_dphy_clk.common,
536 &drc_clk.common,
537 &gpu_clk.common,
538 &ats_clk.common,
539};
540
541/* We hardcode the divider to 4 for now */
542static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
543 "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
544static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
545 "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
546static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
547 "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
548static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
549 "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
550static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x",
551 "pll-periph", 1, 2, 0);
552static CLK_FIXED_FACTOR(pll_video_2x_clk, "pll-video-2x",
553 "pll-video", 1, 2, 0);
554
555static struct clk_hw_onecell_data sun8i_a23_hw_clks = {
556 .hws = {
557 [CLK_PLL_CPUX] = &pll_cpux_clk.common.hw,
558 [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw,
559 [CLK_PLL_AUDIO] = &pll_audio_clk.hw,
560 [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw,
561 [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw,
562 [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw,
563 [CLK_PLL_VIDEO] = &pll_video_clk.common.hw,
564 [CLK_PLL_VIDEO_2X] = &pll_video_2x_clk.hw,
565 [CLK_PLL_VE] = &pll_ve_clk.common.hw,
566 [CLK_PLL_DDR0] = &pll_ddr_clk.common.hw,
567 [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw,
568 [CLK_PLL_PERIPH_2X] = &pll_periph_2x_clk.hw,
569 [CLK_PLL_GPU] = &pll_gpu_clk.common.hw,
570 [CLK_PLL_MIPI] = &pll_mipi_clk.common.hw,
571 [CLK_PLL_HSIC] = &pll_hsic_clk.common.hw,
572 [CLK_PLL_DE] = &pll_de_clk.common.hw,
573 [CLK_CPUX] = &cpux_clk.common.hw,
574 [CLK_AXI] = &axi_clk.common.hw,
575 [CLK_AHB1] = &ahb1_clk.common.hw,
576 [CLK_APB1] = &apb1_clk.common.hw,
577 [CLK_APB2] = &apb2_clk.common.hw,
578 [CLK_BUS_MIPI_DSI] = &bus_mipi_dsi_clk.common.hw,
579 [CLK_BUS_DMA] = &bus_dma_clk.common.hw,
580 [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw,
581 [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw,
582 [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw,
583 [CLK_BUS_NAND] = &bus_nand_clk.common.hw,
584 [CLK_BUS_DRAM] = &bus_dram_clk.common.hw,
585 [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw,
586 [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw,
587 [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw,
588 [CLK_BUS_OTG] = &bus_otg_clk.common.hw,
589 [CLK_BUS_EHCI] = &bus_ehci_clk.common.hw,
590 [CLK_BUS_OHCI] = &bus_ohci_clk.common.hw,
591 [CLK_BUS_VE] = &bus_ve_clk.common.hw,
592 [CLK_BUS_LCD] = &bus_lcd_clk.common.hw,
593 [CLK_BUS_CSI] = &bus_csi_clk.common.hw,
594 [CLK_BUS_DE_BE] = &bus_de_be_clk.common.hw,
595 [CLK_BUS_DE_FE] = &bus_de_fe_clk.common.hw,
596 [CLK_BUS_GPU] = &bus_gpu_clk.common.hw,
597 [CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw,
598 [CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw,
599 [CLK_BUS_DRC] = &bus_drc_clk.common.hw,
600 [CLK_BUS_CODEC] = &bus_codec_clk.common.hw,
601 [CLK_BUS_PIO] = &bus_pio_clk.common.hw,
602 [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw,
603 [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw,
604 [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw,
605 [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw,
606 [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw,
607 [CLK_BUS_UART0] = &bus_uart0_clk.common.hw,
608 [CLK_BUS_UART1] = &bus_uart1_clk.common.hw,
609 [CLK_BUS_UART2] = &bus_uart2_clk.common.hw,
610 [CLK_BUS_UART3] = &bus_uart3_clk.common.hw,
611 [CLK_BUS_UART4] = &bus_uart4_clk.common.hw,
612 [CLK_NAND] = &nand_clk.common.hw,
613 [CLK_MMC0] = &mmc0_clk.common.hw,
614 [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw,
615 [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw,
616 [CLK_MMC1] = &mmc1_clk.common.hw,
617 [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw,
618 [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw,
619 [CLK_MMC2] = &mmc2_clk.common.hw,
620 [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw,
621 [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw,
622 [CLK_SPI0] = &spi0_clk.common.hw,
623 [CLK_SPI1] = &spi1_clk.common.hw,
624 [CLK_I2S0] = &i2s0_clk.common.hw,
625 [CLK_I2S1] = &i2s1_clk.common.hw,
626 [CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
627 [CLK_USB_PHY1] = &usb_phy1_clk.common.hw,
628 [CLK_USB_HSIC] = &usb_hsic_clk.common.hw,
629 [CLK_USB_HSIC_12M] = &usb_hsic_12M_clk.common.hw,
630 [CLK_USB_OHCI] = &usb_ohci_clk.common.hw,
631 [CLK_DRAM_VE] = &dram_ve_clk.common.hw,
632 [CLK_DRAM_CSI] = &dram_csi_clk.common.hw,
633 [CLK_DRAM_DRC] = &dram_drc_clk.common.hw,
634 [CLK_DRAM_DE_FE] = &dram_de_fe_clk.common.hw,
635 [CLK_DRAM_DE_BE] = &dram_de_be_clk.common.hw,
636 [CLK_DE_BE] = &de_be_clk.common.hw,
637 [CLK_DE_FE] = &de_fe_clk.common.hw,
638 [CLK_LCD_CH0] = &lcd_ch0_clk.common.hw,
639 [CLK_LCD_CH1] = &lcd_ch1_clk.common.hw,
640 [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw,
641 [CLK_CSI_MCLK] = &csi_mclk_clk.common.hw,
642 [CLK_VE] = &ve_clk.common.hw,
643 [CLK_AC_DIG] = &ac_dig_clk.common.hw,
644 [CLK_AVS] = &avs_clk.common.hw,
645 [CLK_MBUS] = &mbus_clk.common.hw,
646 [CLK_DSI_SCLK] = &dsi_sclk_clk.common.hw,
647 [CLK_DSI_DPHY] = &dsi_dphy_clk.common.hw,
648 [CLK_DRC] = &drc_clk.common.hw,
649 [CLK_GPU] = &gpu_clk.common.hw,
650 [CLK_ATS] = &ats_clk.common.hw,
651 },
652 .num = CLK_NUMBER,
653};
654
655static struct ccu_reset_map sun8i_a23_ccu_resets[] = {
656 [RST_USB_PHY0] = { 0x0cc, BIT(0) },
657 [RST_USB_PHY1] = { 0x0cc, BIT(1) },
658 [RST_USB_HSIC] = { 0x0cc, BIT(2) },
659
660 [RST_MBUS] = { 0x0fc, BIT(31) },
661
662 [RST_BUS_MIPI_DSI] = { 0x2c0, BIT(1) },
663 [RST_BUS_DMA] = { 0x2c0, BIT(6) },
664 [RST_BUS_MMC0] = { 0x2c0, BIT(8) },
665 [RST_BUS_MMC1] = { 0x2c0, BIT(9) },
666 [RST_BUS_MMC2] = { 0x2c0, BIT(10) },
667 [RST_BUS_NAND] = { 0x2c0, BIT(13) },
668 [RST_BUS_DRAM] = { 0x2c0, BIT(14) },
669 [RST_BUS_HSTIMER] = { 0x2c0, BIT(19) },
670 [RST_BUS_SPI0] = { 0x2c0, BIT(20) },
671 [RST_BUS_SPI1] = { 0x2c0, BIT(21) },
672 [RST_BUS_OTG] = { 0x2c0, BIT(24) },
673 [RST_BUS_EHCI] = { 0x2c0, BIT(26) },
674 [RST_BUS_OHCI] = { 0x2c0, BIT(29) },
675
676 [RST_BUS_VE] = { 0x2c4, BIT(0) },
677 [RST_BUS_LCD] = { 0x2c4, BIT(4) },
678 [RST_BUS_CSI] = { 0x2c4, BIT(8) },
679 [RST_BUS_DE_BE] = { 0x2c4, BIT(12) },
680 [RST_BUS_DE_FE] = { 0x2c4, BIT(14) },
681 [RST_BUS_GPU] = { 0x2c4, BIT(20) },
682 [RST_BUS_MSGBOX] = { 0x2c4, BIT(21) },
683 [RST_BUS_SPINLOCK] = { 0x2c4, BIT(22) },
684 [RST_BUS_DRC] = { 0x2c4, BIT(25) },
685
686 [RST_BUS_LVDS] = { 0x2c8, BIT(0) },
687
688 [RST_BUS_CODEC] = { 0x2d0, BIT(0) },
689 [RST_BUS_I2S0] = { 0x2d0, BIT(12) },
690 [RST_BUS_I2S1] = { 0x2d0, BIT(13) },
691
692 [RST_BUS_I2C0] = { 0x2d8, BIT(0) },
693 [RST_BUS_I2C1] = { 0x2d8, BIT(1) },
694 [RST_BUS_I2C2] = { 0x2d8, BIT(2) },
695 [RST_BUS_UART0] = { 0x2d8, BIT(16) },
696 [RST_BUS_UART1] = { 0x2d8, BIT(17) },
697 [RST_BUS_UART2] = { 0x2d8, BIT(18) },
698 [RST_BUS_UART3] = { 0x2d8, BIT(19) },
699 [RST_BUS_UART4] = { 0x2d8, BIT(20) },
700};
701
702static const struct sunxi_ccu_desc sun8i_a23_ccu_desc = {
703 .ccu_clks = sun8i_a23_ccu_clks,
704 .num_ccu_clks = ARRAY_SIZE(sun8i_a23_ccu_clks),
705
706 .hw_clks = &sun8i_a23_hw_clks,
707
708 .resets = sun8i_a23_ccu_resets,
709 .num_resets = ARRAY_SIZE(sun8i_a23_ccu_resets),
710};
711
712static void __init sun8i_a23_ccu_setup(struct device_node *node)
713{
714 void __iomem *reg;
715 u32 val;
716
717 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
718 if (IS_ERR(reg)) {
719 pr_err("%s: Could not map the clock registers\n",
720 of_node_full_name(node));
721 return;
722 }
723
724 /* Force the PLL-Audio-1x divider to 4 */
725 val = readl(reg + SUN8I_A23_PLL_AUDIO_REG);
726 val &= ~GENMASK(19, 16);
727 writel(val | (3 << 16), reg + SUN8I_A23_PLL_AUDIO_REG);
728
729 /* Force PLL-MIPI to MIPI mode */
730 val = readl(reg + SUN8I_A23_PLL_MIPI_REG);
731 val &= ~BIT(16);
732 writel(val, reg + SUN8I_A23_PLL_MIPI_REG);
733
734 sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc);
735}
736CLK_OF_DECLARE(sun8i_a23_ccu, "allwinner,sun8i-a23-ccu",
737 sun8i_a23_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
new file mode 100644
index 000000000000..96b40ca57697
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
@@ -0,0 +1,780 @@
1/*
2 * Copyright (c) 2016 Maxime Ripard. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/clk-provider.h>
15#include <linux/of_address.h>
16
17#include "ccu_common.h"
18#include "ccu_reset.h"
19
20#include "ccu_div.h"
21#include "ccu_gate.h"
22#include "ccu_mp.h"
23#include "ccu_mult.h"
24#include "ccu_nk.h"
25#include "ccu_nkm.h"
26#include "ccu_nkmp.h"
27#include "ccu_nm.h"
28#include "ccu_phase.h"
29
30#include "ccu-sun8i-a23-a33.h"
31
32static struct ccu_nkmp pll_cpux_clk = {
33 .enable = BIT(31),
34 .lock = BIT(28),
35
36 .n = _SUNXI_CCU_MULT(8, 5),
37 .k = _SUNXI_CCU_MULT(4, 2),
38 .m = _SUNXI_CCU_DIV(0, 2),
39 .p = _SUNXI_CCU_DIV_MAX(16, 2, 4),
40
41 .common = {
42 .reg = 0x000,
43 .hw.init = CLK_HW_INIT("pll-cpux", "osc24M",
44 &ccu_nkmp_ops,
45 0),
46 },
47};
48
49/*
50 * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
51 * the base (2x, 4x and 8x), and one variable divider (the one true
52 * pll audio).
53 *
54 * We don't have any need for the variable divider for now, so we just
55 * hardcode it to match with the clock names
56 */
57#define SUN8I_A33_PLL_AUDIO_REG 0x008
58
59static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
60 "osc24M", 0x008,
61 8, 7, /* N */
62 0, 5, /* M */
63 BIT(31), /* gate */
64 BIT(28), /* lock */
65 CLK_SET_RATE_UNGATE);
66
67static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
68 "osc24M", 0x010,
69 8, 7, /* N */
70 0, 4, /* M */
71 BIT(24), /* frac enable */
72 BIT(25), /* frac select */
73 270000000, /* frac rate 0 */
74 297000000, /* frac rate 1 */
75 BIT(31), /* gate */
76 BIT(28), /* lock */
77 CLK_SET_RATE_UNGATE);
78
79static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
80 "osc24M", 0x018,
81 8, 7, /* N */
82 0, 4, /* M */
83 BIT(24), /* frac enable */
84 BIT(25), /* frac select */
85 270000000, /* frac rate 0 */
86 297000000, /* frac rate 1 */
87 BIT(31), /* gate */
88 BIT(28), /* lock */
89 CLK_SET_RATE_UNGATE);
90
91static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr0_clk, "pll-ddr0",
92 "osc24M", 0x020,
93 8, 5, /* N */
94 4, 2, /* K */
95 0, 2, /* M */
96 BIT(31), /* gate */
97 BIT(28), /* lock */
98 0);
99
100static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph_clk, "pll-periph",
101 "osc24M", 0x028,
102 8, 5, /* N */
103 4, 2, /* K */
104 BIT(31), /* gate */
105 BIT(28), /* lock */
106 2, /* post-div */
107 CLK_SET_RATE_UNGATE);
108
109static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
110 "osc24M", 0x038,
111 8, 7, /* N */
112 0, 4, /* M */
113 BIT(24), /* frac enable */
114 BIT(25), /* frac select */
115 270000000, /* frac rate 0 */
116 297000000, /* frac rate 1 */
117 BIT(31), /* gate */
118 BIT(28), /* lock */
119 CLK_SET_RATE_UNGATE);
120
121/*
122 * The MIPI PLL has 2 modes: "MIPI" and "HDMI".
123 *
124 * The MIPI mode is a standard NKM-style clock. The HDMI mode is an
125 * integer / fractional clock with switchable multipliers and dividers.
126 * This is not supported here. We hardcode the PLL to MIPI mode.
127 */
128#define SUN8I_A33_PLL_MIPI_REG 0x040
129static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_mipi_clk, "pll-mipi",
130 "pll-video", 0x040,
131 8, 4, /* N */
132 4, 2, /* K */
133 0, 4, /* M */
134 BIT(31), /* gate */
135 BIT(28), /* lock */
136 CLK_SET_RATE_UNGATE);
137
138static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_hsic_clk, "pll-hsic",
139 "osc24M", 0x044,
140 8, 7, /* N */
141 0, 4, /* M */
142 BIT(24), /* frac enable */
143 BIT(25), /* frac select */
144 270000000, /* frac rate 0 */
145 297000000, /* frac rate 1 */
146 BIT(31), /* gate */
147 BIT(28), /* lock */
148 CLK_SET_RATE_UNGATE);
149
150static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de",
151 "osc24M", 0x048,
152 8, 7, /* N */
153 0, 4, /* M */
154 BIT(24), /* frac enable */
155 BIT(25), /* frac select */
156 270000000, /* frac rate 0 */
157 297000000, /* frac rate 1 */
158 BIT(31), /* gate */
159 BIT(28), /* lock */
160 CLK_SET_RATE_UNGATE);
161
162/* TODO: Fix N */
163static SUNXI_CCU_N_WITH_GATE_LOCK(pll_ddr1_clk, "pll-ddr1",
164 "osc24M", 0x04c,
165 8, 6, /* N */
166 BIT(31), /* gate */
167 BIT(28), /* lock */
168 CLK_SET_RATE_UNGATE);
169
170static const char * const cpux_parents[] = { "osc32k", "osc24M",
171 "pll-cpux" , "pll-cpux" };
172static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
173 0x050, 16, 2, CLK_IS_CRITICAL);
174
175static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0);
176
177static const char * const ahb1_parents[] = { "osc32k", "osc24M",
178 "axi" , "pll-periph" };
179static struct ccu_div ahb1_clk = {
180 .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
181
182 .mux = {
183 .shift = 12,
184 .width = 2,
185
186 .variable_prediv = {
187 .index = 3,
188 .shift = 6,
189 .width = 2,
190 },
191 },
192
193 .common = {
194 .reg = 0x054,
195 .features = CCU_FEATURE_VARIABLE_PREDIV,
196 .hw.init = CLK_HW_INIT_PARENTS("ahb1",
197 ahb1_parents,
198 &ccu_div_ops,
199 0),
200 },
201};
202
203static struct clk_div_table apb1_div_table[] = {
204 { .val = 0, .div = 2 },
205 { .val = 1, .div = 2 },
206 { .val = 2, .div = 4 },
207 { .val = 3, .div = 8 },
208 { /* Sentinel */ },
209};
210static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1",
211 0x054, 8, 2, apb1_div_table, 0);
212
213static const char * const apb2_parents[] = { "osc32k", "osc24M",
214 "pll-periph" , "pll-periph" };
215static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
216 0, 5, /* M */
217 16, 2, /* P */
218 24, 2, /* mux */
219 0);
220
221static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb1",
222 0x060, BIT(1), 0);
223static SUNXI_CCU_GATE(bus_ss_clk, "bus-ss", "ahb1",
224 0x060, BIT(5), 0);
225static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1",
226 0x060, BIT(6), 0);
227static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1",
228 0x060, BIT(8), 0);
229static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1",
230 0x060, BIT(9), 0);
231static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1",
232 0x060, BIT(10), 0);
233static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb1",
234 0x060, BIT(13), 0);
235static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1",
236 0x060, BIT(14), 0);
237static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1",
238 0x060, BIT(19), 0);
239static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1",
240 0x060, BIT(20), 0);
241static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb1",
242 0x060, BIT(21), 0);
243static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1",
244 0x060, BIT(24), 0);
245static SUNXI_CCU_GATE(bus_ehci_clk, "bus-ehci", "ahb1",
246 0x060, BIT(26), 0);
247static SUNXI_CCU_GATE(bus_ohci_clk, "bus-ohci", "ahb1",
248 0x060, BIT(29), 0);
249
250static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb1",
251 0x064, BIT(0), 0);
252static SUNXI_CCU_GATE(bus_lcd_clk, "bus-lcd", "ahb1",
253 0x064, BIT(4), 0);
254static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb1",
255 0x064, BIT(8), 0);
256static SUNXI_CCU_GATE(bus_de_be_clk, "bus-de-be", "ahb1",
257 0x064, BIT(12), 0);
258static SUNXI_CCU_GATE(bus_de_fe_clk, "bus-de-fe", "ahb1",
259 0x064, BIT(14), 0);
260static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "ahb1",
261 0x064, BIT(20), 0);
262static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb1",
263 0x064, BIT(21), 0);
264static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb1",
265 0x064, BIT(22), 0);
266static SUNXI_CCU_GATE(bus_drc_clk, "bus-drc", "ahb1",
267 0x064, BIT(25), 0);
268static SUNXI_CCU_GATE(bus_sat_clk, "bus-sat", "ahb1",
269 0x064, BIT(26), 0);
270
271static SUNXI_CCU_GATE(bus_codec_clk, "bus-codec", "apb1",
272 0x068, BIT(0), 0);
273static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb1",
274 0x068, BIT(5), 0);
275static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1",
276 0x068, BIT(12), 0);
277static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1",
278 0x068, BIT(13), 0);
279
280static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2",
281 0x06c, BIT(0), 0);
282static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2",
283 0x06c, BIT(1), 0);
284static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2",
285 0x06c, BIT(2), 0);
286static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2",
287 0x06c, BIT(16), 0);
288static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2",
289 0x06c, BIT(17), 0);
290static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2",
291 0x06c, BIT(18), 0);
292static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2",
293 0x06c, BIT(19), 0);
294static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2",
295 0x06c, BIT(20), 0);
296
297static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" };
298static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
299 0, 4, /* M */
300 16, 2, /* P */
301 24, 2, /* mux */
302 BIT(31), /* gate */
303 0);
304
305static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
306 0, 4, /* M */
307 16, 2, /* P */
308 24, 2, /* mux */
309 BIT(31), /* gate */
310 0);
311
312static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
313 0x088, 20, 3, 0);
314static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
315 0x088, 8, 3, 0);
316
317static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
318 0, 4, /* M */
319 16, 2, /* P */
320 24, 2, /* mux */
321 BIT(31), /* gate */
322 0);
323
324static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
325 0x08c, 20, 3, 0);
326static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
327 0x08c, 8, 3, 0);
328
329static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
330 0, 4, /* M */
331 16, 2, /* P */
332 24, 2, /* mux */
333 BIT(31), /* gate */
334 0);
335
336static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
337 0x090, 20, 3, 0);
338static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
339 0x090, 8, 3, 0);
340
341static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c,
342 0, 4, /* M */
343 16, 2, /* P */
344 24, 2, /* mux */
345 BIT(31), /* gate */
346 0);
347
348static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
349 0, 4, /* M */
350 16, 2, /* P */
351 24, 2, /* mux */
352 BIT(31), /* gate */
353 0);
354
355static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
356 0, 4, /* M */
357 16, 2, /* P */
358 24, 2, /* mux */
359 BIT(31), /* gate */
360 0);
361
362static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
363 "pll-audio-2x", "pll-audio" };
364static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents,
365 0x0b0, 16, 2, BIT(31), 0);
366
367static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", i2s_parents,
368 0x0b4, 16, 2, BIT(31), 0);
369
370/* TODO: the parent for most of the USB clocks is not known */
371static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
372 0x0cc, BIT(8), 0);
373static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M",
374 0x0cc, BIT(9), 0);
375static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "pll-hsic",
376 0x0cc, BIT(10), 0);
377static SUNXI_CCU_GATE(usb_hsic_12M_clk, "usb-hsic-12M", "osc24M",
378 0x0cc, BIT(11), 0);
379static SUNXI_CCU_GATE(usb_ohci_clk, "usb-ohci", "osc24M",
380 0x0cc, BIT(16), 0);
381
382static SUNXI_CCU_M(dram_clk, "dram", "pll-ddr",
383 0x0f4, 0, 4, CLK_IS_CRITICAL);
384
385static const char * const pll_ddr_parents[] = { "pll-ddr0", "pll-ddr1" };
386static SUNXI_CCU_MUX(pll_ddr_clk, "pll-ddr", pll_ddr_parents,
387 0x0f8, 16, 1, 0);
388
389static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "dram",
390 0x100, BIT(0), 0);
391static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "dram",
392 0x100, BIT(1), 0);
393static SUNXI_CCU_GATE(dram_drc_clk, "dram-drc", "dram",
394 0x100, BIT(16), 0);
395static SUNXI_CCU_GATE(dram_de_fe_clk, "dram-de-fe", "dram",
396 0x100, BIT(24), 0);
397static SUNXI_CCU_GATE(dram_de_be_clk, "dram-de-be", "dram",
398 0x100, BIT(26), 0);
399
400static const char * const de_parents[] = { "pll-video", "pll-periph-2x",
401 "pll-gpu", "pll-de" };
402static const u8 de_table[] = { 0, 2, 3, 5 };
403static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_be_clk, "de-be",
404 de_parents, de_table,
405 0x104, 0, 4, 24, 3, BIT(31), 0);
406
407static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_fe_clk, "de-fe",
408 de_parents, de_table,
409 0x10c, 0, 4, 24, 3, BIT(31), 0);
410
411static const char * const lcd_ch0_parents[] = { "pll-video", "pll-video-2x",
412 "pll-mipi" };
413static const u8 lcd_ch0_table[] = { 0, 2, 4 };
414static SUNXI_CCU_MUX_TABLE_WITH_GATE(lcd_ch0_clk, "lcd-ch0",
415 lcd_ch0_parents, lcd_ch0_table,
416 0x118, 24, 3, BIT(31),
417 CLK_SET_RATE_PARENT);
418
419static const char * const lcd_ch1_parents[] = { "pll-video", "pll-video-2x" };
420static const u8 lcd_ch1_table[] = { 0, 2 };
421static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(lcd_ch1_clk, "lcd-ch1",
422 lcd_ch1_parents, lcd_ch1_table,
423 0x12c, 0, 4, 24, 2, BIT(31), 0);
424
425static const char * const csi_sclk_parents[] = { "pll-video", "pll-de",
426 "pll-mipi", "pll-ve" };
427static const u8 csi_sclk_table[] = { 0, 3, 4, 5 };
428static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_sclk_clk, "csi-sclk",
429 csi_sclk_parents, csi_sclk_table,
430 0x134, 16, 4, 24, 3, BIT(31), 0);
431
432static const char * const csi_mclk_parents[] = { "pll-video", "pll-de",
433 "osc24M" };
434static const u8 csi_mclk_table[] = { 0, 3, 5 };
435static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk",
436 csi_mclk_parents, csi_mclk_table,
437 0x134, 0, 5, 8, 3, BIT(15), 0);
438
439static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
440 0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT);
441
442static SUNXI_CCU_GATE(ac_dig_clk, "ac-dig", "pll-audio",
443 0x140, BIT(31), 0);
444static SUNXI_CCU_GATE(ac_dig_4x_clk, "ac-dig-4x", "pll-audio-4x",
445 0x140, BIT(30), 0);
446static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M",
447 0x144, BIT(31), 0);
448
449static const char * const mbus_parents[] = { "osc24M", "pll-periph-2x",
450 "pll-ddr0", "pll-ddr1" };
451static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
452 0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL);
453
454static const char * const dsi_sclk_parents[] = { "pll-video", "pll-video-2x" };
455static const u8 dsi_sclk_table[] = { 0, 2 };
456static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_sclk_clk, "dsi-sclk",
457 dsi_sclk_parents, dsi_sclk_table,
458 0x168, 16, 4, 24, 2, BIT(31), 0);
459
460static const char * const dsi_dphy_parents[] = { "pll-video", "pll-periph" };
461static const u8 dsi_dphy_table[] = { 0, 2 };
462static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_dphy_clk, "dsi-dphy",
463 dsi_dphy_parents, dsi_dphy_table,
464 0x168, 0, 4, 8, 2, BIT(15), 0);
465
466static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(drc_clk, "drc",
467 de_parents, de_table,
468 0x180, 0, 4, 24, 3, BIT(31), 0);
469
470static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu",
471 0x1a0, 0, 3, BIT(31), 0);
472
473static const char * const ats_parents[] = { "osc24M", "pll-periph" };
474static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", ats_parents,
475 0x1b0, 0, 3, 24, 2, BIT(31), 0);
476
477static struct ccu_common *sun8i_a33_ccu_clks[] = {
478 &pll_cpux_clk.common,
479 &pll_audio_base_clk.common,
480 &pll_video_clk.common,
481 &pll_ve_clk.common,
482 &pll_ddr0_clk.common,
483 &pll_periph_clk.common,
484 &pll_gpu_clk.common,
485 &pll_mipi_clk.common,
486 &pll_hsic_clk.common,
487 &pll_de_clk.common,
488 &pll_ddr1_clk.common,
489 &pll_ddr_clk.common,
490 &cpux_clk.common,
491 &axi_clk.common,
492 &ahb1_clk.common,
493 &apb1_clk.common,
494 &apb2_clk.common,
495 &bus_mipi_dsi_clk.common,
496 &bus_ss_clk.common,
497 &bus_dma_clk.common,
498 &bus_mmc0_clk.common,
499 &bus_mmc1_clk.common,
500 &bus_mmc2_clk.common,
501 &bus_nand_clk.common,
502 &bus_dram_clk.common,
503 &bus_hstimer_clk.common,
504 &bus_spi0_clk.common,
505 &bus_spi1_clk.common,
506 &bus_otg_clk.common,
507 &bus_ehci_clk.common,
508 &bus_ohci_clk.common,
509 &bus_ve_clk.common,
510 &bus_lcd_clk.common,
511 &bus_csi_clk.common,
512 &bus_de_fe_clk.common,
513 &bus_de_be_clk.common,
514 &bus_gpu_clk.common,
515 &bus_msgbox_clk.common,
516 &bus_spinlock_clk.common,
517 &bus_drc_clk.common,
518 &bus_sat_clk.common,
519 &bus_codec_clk.common,
520 &bus_pio_clk.common,
521 &bus_i2s0_clk.common,
522 &bus_i2s1_clk.common,
523 &bus_i2c0_clk.common,
524 &bus_i2c1_clk.common,
525 &bus_i2c2_clk.common,
526 &bus_uart0_clk.common,
527 &bus_uart1_clk.common,
528 &bus_uart2_clk.common,
529 &bus_uart3_clk.common,
530 &bus_uart4_clk.common,
531 &nand_clk.common,
532 &mmc0_clk.common,
533 &mmc0_sample_clk.common,
534 &mmc0_output_clk.common,
535 &mmc1_clk.common,
536 &mmc1_sample_clk.common,
537 &mmc1_output_clk.common,
538 &mmc2_clk.common,
539 &mmc2_sample_clk.common,
540 &mmc2_output_clk.common,
541 &ss_clk.common,
542 &spi0_clk.common,
543 &spi1_clk.common,
544 &i2s0_clk.common,
545 &i2s1_clk.common,
546 &usb_phy0_clk.common,
547 &usb_phy1_clk.common,
548 &usb_hsic_clk.common,
549 &usb_hsic_12M_clk.common,
550 &usb_ohci_clk.common,
551 &dram_clk.common,
552 &dram_ve_clk.common,
553 &dram_csi_clk.common,
554 &dram_drc_clk.common,
555 &dram_de_fe_clk.common,
556 &dram_de_be_clk.common,
557 &de_be_clk.common,
558 &de_fe_clk.common,
559 &lcd_ch0_clk.common,
560 &lcd_ch1_clk.common,
561 &csi_sclk_clk.common,
562 &csi_mclk_clk.common,
563 &ve_clk.common,
564 &ac_dig_clk.common,
565 &ac_dig_4x_clk.common,
566 &avs_clk.common,
567 &mbus_clk.common,
568 &dsi_sclk_clk.common,
569 &dsi_dphy_clk.common,
570 &drc_clk.common,
571 &gpu_clk.common,
572 &ats_clk.common,
573};
574
575/* We hardcode the divider to 4 for now */
576static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
577 "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
578static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
579 "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
580static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
581 "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
582static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
583 "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
584static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x",
585 "pll-periph", 1, 2, 0);
586static CLK_FIXED_FACTOR(pll_video_2x_clk, "pll-video-2x",
587 "pll-video", 1, 2, 0);
588
589static struct clk_hw_onecell_data sun8i_a33_hw_clks = {
590 .hws = {
591 [CLK_PLL_CPUX] = &pll_cpux_clk.common.hw,
592 [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw,
593 [CLK_PLL_AUDIO] = &pll_audio_clk.hw,
594 [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw,
595 [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw,
596 [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw,
597 [CLK_PLL_VIDEO] = &pll_video_clk.common.hw,
598 [CLK_PLL_VIDEO_2X] = &pll_video_2x_clk.hw,
599 [CLK_PLL_VE] = &pll_ve_clk.common.hw,
600 [CLK_PLL_DDR0] = &pll_ddr0_clk.common.hw,
601 [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw,
602 [CLK_PLL_PERIPH_2X] = &pll_periph_2x_clk.hw,
603 [CLK_PLL_GPU] = &pll_gpu_clk.common.hw,
604 [CLK_PLL_MIPI] = &pll_mipi_clk.common.hw,
605 [CLK_PLL_HSIC] = &pll_hsic_clk.common.hw,
606 [CLK_PLL_DE] = &pll_de_clk.common.hw,
607 [CLK_PLL_DDR1] = &pll_ddr1_clk.common.hw,
608 [CLK_PLL_DDR] = &pll_ddr_clk.common.hw,
609 [CLK_CPUX] = &cpux_clk.common.hw,
610 [CLK_AXI] = &axi_clk.common.hw,
611 [CLK_AHB1] = &ahb1_clk.common.hw,
612 [CLK_APB1] = &apb1_clk.common.hw,
613 [CLK_APB2] = &apb2_clk.common.hw,
614 [CLK_BUS_MIPI_DSI] = &bus_mipi_dsi_clk.common.hw,
615 [CLK_BUS_SS] = &bus_ss_clk.common.hw,
616 [CLK_BUS_DMA] = &bus_dma_clk.common.hw,
617 [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw,
618 [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw,
619 [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw,
620 [CLK_BUS_NAND] = &bus_nand_clk.common.hw,
621 [CLK_BUS_DRAM] = &bus_dram_clk.common.hw,
622 [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw,
623 [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw,
624 [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw,
625 [CLK_BUS_OTG] = &bus_otg_clk.common.hw,
626 [CLK_BUS_EHCI] = &bus_ehci_clk.common.hw,
627 [CLK_BUS_OHCI] = &bus_ohci_clk.common.hw,
628 [CLK_BUS_VE] = &bus_ve_clk.common.hw,
629 [CLK_BUS_LCD] = &bus_lcd_clk.common.hw,
630 [CLK_BUS_CSI] = &bus_csi_clk.common.hw,
631 [CLK_BUS_DE_BE] = &bus_de_be_clk.common.hw,
632 [CLK_BUS_DE_FE] = &bus_de_fe_clk.common.hw,
633 [CLK_BUS_GPU] = &bus_gpu_clk.common.hw,
634 [CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw,
635 [CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw,
636 [CLK_BUS_DRC] = &bus_drc_clk.common.hw,
637 [CLK_BUS_SAT] = &bus_sat_clk.common.hw,
638 [CLK_BUS_CODEC] = &bus_codec_clk.common.hw,
639 [CLK_BUS_PIO] = &bus_pio_clk.common.hw,
640 [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw,
641 [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw,
642 [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw,
643 [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw,
644 [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw,
645 [CLK_BUS_UART0] = &bus_uart0_clk.common.hw,
646 [CLK_BUS_UART1] = &bus_uart1_clk.common.hw,
647 [CLK_BUS_UART2] = &bus_uart2_clk.common.hw,
648 [CLK_BUS_UART3] = &bus_uart3_clk.common.hw,
649 [CLK_BUS_UART4] = &bus_uart4_clk.common.hw,
650 [CLK_NAND] = &nand_clk.common.hw,
651 [CLK_MMC0] = &mmc0_clk.common.hw,
652 [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw,
653 [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw,
654 [CLK_MMC1] = &mmc1_clk.common.hw,
655 [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw,
656 [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw,
657 [CLK_MMC2] = &mmc2_clk.common.hw,
658 [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw,
659 [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw,
660 [CLK_SS] = &ss_clk.common.hw,
661 [CLK_SPI0] = &spi0_clk.common.hw,
662 [CLK_SPI1] = &spi1_clk.common.hw,
663 [CLK_I2S0] = &i2s0_clk.common.hw,
664 [CLK_I2S1] = &i2s1_clk.common.hw,
665 [CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
666 [CLK_USB_PHY1] = &usb_phy1_clk.common.hw,
667 [CLK_USB_HSIC] = &usb_hsic_clk.common.hw,
668 [CLK_USB_HSIC_12M] = &usb_hsic_12M_clk.common.hw,
669 [CLK_USB_OHCI] = &usb_ohci_clk.common.hw,
670 [CLK_DRAM] = &dram_clk.common.hw,
671 [CLK_DRAM_VE] = &dram_ve_clk.common.hw,
672 [CLK_DRAM_CSI] = &dram_csi_clk.common.hw,
673 [CLK_DRAM_DRC] = &dram_drc_clk.common.hw,
674 [CLK_DRAM_DE_FE] = &dram_de_fe_clk.common.hw,
675 [CLK_DRAM_DE_BE] = &dram_de_be_clk.common.hw,
676 [CLK_DE_BE] = &de_be_clk.common.hw,
677 [CLK_DE_FE] = &de_fe_clk.common.hw,
678 [CLK_LCD_CH0] = &lcd_ch0_clk.common.hw,
679 [CLK_LCD_CH1] = &lcd_ch1_clk.common.hw,
680 [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw,
681 [CLK_CSI_MCLK] = &csi_mclk_clk.common.hw,
682 [CLK_VE] = &ve_clk.common.hw,
683 [CLK_AC_DIG] = &ac_dig_clk.common.hw,
684 [CLK_AC_DIG_4X] = &ac_dig_4x_clk.common.hw,
685 [CLK_AVS] = &avs_clk.common.hw,
686 [CLK_MBUS] = &mbus_clk.common.hw,
687 [CLK_DSI_SCLK] = &dsi_sclk_clk.common.hw,
688 [CLK_DSI_DPHY] = &dsi_dphy_clk.common.hw,
689 [CLK_DRC] = &drc_clk.common.hw,
690 [CLK_GPU] = &gpu_clk.common.hw,
691 [CLK_ATS] = &ats_clk.common.hw,
692 },
693 .num = CLK_NUMBER,
694};
695
696static struct ccu_reset_map sun8i_a33_ccu_resets[] = {
697 [RST_USB_PHY0] = { 0x0cc, BIT(0) },
698 [RST_USB_PHY1] = { 0x0cc, BIT(1) },
699 [RST_USB_HSIC] = { 0x0cc, BIT(2) },
700
701 [RST_MBUS] = { 0x0fc, BIT(31) },
702
703 [RST_BUS_MIPI_DSI] = { 0x2c0, BIT(1) },
704 [RST_BUS_SS] = { 0x2c0, BIT(5) },
705 [RST_BUS_DMA] = { 0x2c0, BIT(6) },
706 [RST_BUS_MMC0] = { 0x2c0, BIT(8) },
707 [RST_BUS_MMC1] = { 0x2c0, BIT(9) },
708 [RST_BUS_MMC2] = { 0x2c0, BIT(10) },
709 [RST_BUS_NAND] = { 0x2c0, BIT(13) },
710 [RST_BUS_DRAM] = { 0x2c0, BIT(14) },
711 [RST_BUS_HSTIMER] = { 0x2c0, BIT(19) },
712 [RST_BUS_SPI0] = { 0x2c0, BIT(20) },
713 [RST_BUS_SPI1] = { 0x2c0, BIT(21) },
714 [RST_BUS_OTG] = { 0x2c0, BIT(24) },
715 [RST_BUS_EHCI] = { 0x2c0, BIT(26) },
716 [RST_BUS_OHCI] = { 0x2c0, BIT(29) },
717
718 [RST_BUS_VE] = { 0x2c4, BIT(0) },
719 [RST_BUS_LCD] = { 0x2c4, BIT(4) },
720 [RST_BUS_CSI] = { 0x2c4, BIT(8) },
721 [RST_BUS_DE_BE] = { 0x2c4, BIT(12) },
722 [RST_BUS_DE_FE] = { 0x2c4, BIT(14) },
723 [RST_BUS_GPU] = { 0x2c4, BIT(20) },
724 [RST_BUS_MSGBOX] = { 0x2c4, BIT(21) },
725 [RST_BUS_SPINLOCK] = { 0x2c4, BIT(22) },
726 [RST_BUS_DRC] = { 0x2c4, BIT(25) },
727 [RST_BUS_SAT] = { 0x2c4, BIT(26) },
728
729 [RST_BUS_LVDS] = { 0x2c8, BIT(0) },
730
731 [RST_BUS_CODEC] = { 0x2d0, BIT(0) },
732 [RST_BUS_I2S0] = { 0x2d0, BIT(12) },
733 [RST_BUS_I2S1] = { 0x2d0, BIT(13) },
734
735 [RST_BUS_I2C0] = { 0x2d8, BIT(0) },
736 [RST_BUS_I2C1] = { 0x2d8, BIT(1) },
737 [RST_BUS_I2C2] = { 0x2d8, BIT(2) },
738 [RST_BUS_UART0] = { 0x2d8, BIT(16) },
739 [RST_BUS_UART1] = { 0x2d8, BIT(17) },
740 [RST_BUS_UART2] = { 0x2d8, BIT(18) },
741 [RST_BUS_UART3] = { 0x2d8, BIT(19) },
742 [RST_BUS_UART4] = { 0x2d8, BIT(20) },
743};
744
745static const struct sunxi_ccu_desc sun8i_a33_ccu_desc = {
746 .ccu_clks = sun8i_a33_ccu_clks,
747 .num_ccu_clks = ARRAY_SIZE(sun8i_a33_ccu_clks),
748
749 .hw_clks = &sun8i_a33_hw_clks,
750
751 .resets = sun8i_a33_ccu_resets,
752 .num_resets = ARRAY_SIZE(sun8i_a33_ccu_resets),
753};
754
755static void __init sun8i_a33_ccu_setup(struct device_node *node)
756{
757 void __iomem *reg;
758 u32 val;
759
760 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
761 if (IS_ERR(reg)) {
762 pr_err("%s: Could not map the clock registers\n",
763 of_node_full_name(node));
764 return;
765 }
766
767 /* Force the PLL-Audio-1x divider to 4 */
768 val = readl(reg + SUN8I_A33_PLL_AUDIO_REG);
769 val &= ~GENMASK(19, 16);
770 writel(val | (3 << 16), reg + SUN8I_A33_PLL_AUDIO_REG);
771
772 /* Force PLL-MIPI to MIPI mode */
773 val = readl(reg + SUN8I_A33_PLL_MIPI_REG);
774 val &= ~BIT(16);
775 writel(val, reg + SUN8I_A33_PLL_MIPI_REG);
776
777 sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc);
778}
779CLK_OF_DECLARE(sun8i_a33_ccu, "allwinner,sun8i-a33-ccu",
780 sun8i_a33_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
index 267f99523fbe..4d70590f05e3 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
@@ -184,15 +184,15 @@ static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
184 0); 184 0);
185 185
186static const char * const ahb2_parents[] = { "ahb1" , "pll-periph0" }; 186static const char * const ahb2_parents[] = { "ahb1" , "pll-periph0" };
187static const struct ccu_mux_fixed_prediv ahb2_fixed_predivs[] = {
188 { .index = 1, .div = 2 },
189};
187static struct ccu_mux ahb2_clk = { 190static struct ccu_mux ahb2_clk = {
188 .mux = { 191 .mux = {
189 .shift = 0, 192 .shift = 0,
190 .width = 1, 193 .width = 1,
191 194 .fixed_predivs = ahb2_fixed_predivs,
192 .fixed_prediv = { 195 .n_predivs = ARRAY_SIZE(ahb2_fixed_predivs),
193 .index = 1,
194 .div = 2,
195 },
196 }, 196 },
197 197
198 .common = { 198 .common = {
diff --git a/drivers/clk/sunxi-ng/ccu_div.h b/drivers/clk/sunxi-ng/ccu_div.h
index 653ade5769b3..34c338832c0d 100644
--- a/drivers/clk/sunxi-ng/ccu_div.h
+++ b/drivers/clk/sunxi-ng/ccu_div.h
@@ -19,10 +19,29 @@
19#include "ccu_common.h" 19#include "ccu_common.h"
20#include "ccu_mux.h" 20#include "ccu_mux.h"
21 21
22/**
23 * struct _ccu_div - Internal divider description
24 * @shift: Bit offset of the divider in its register
25 * @width: Width of the divider field in its register
26 * @max: Maximum value allowed for that divider. This is the
27 * arithmetic value, not the maximum value to be set in the
28 * register.
29 * @flags: clk_divider flags to apply on this divider
30 * @table: Divider table pointer (if applicable)
31 *
32 * That structure represents a single divider, and is meant to be
33 * embedded in other structures representing the various clock
34 * classes.
35 *
36 * It is basically a wrapper around the clk_divider functions
37 * arguments.
38 */
22struct _ccu_div { 39struct _ccu_div {
23 u8 shift; 40 u8 shift;
24 u8 width; 41 u8 width;
25 42
43 u32 max;
44
26 u32 flags; 45 u32 flags;
27 46
28 struct clk_div_table *table; 47 struct clk_div_table *table;
@@ -36,14 +55,25 @@ struct _ccu_div {
36 .table = _table, \ 55 .table = _table, \
37 } 56 }
38 57
39#define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags) \
40 _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, NULL, _flags)
41
42#define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table) \ 58#define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table) \
43 _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0) 59 _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0)
44 60
61#define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags) \
62 { \
63 .shift = _shift, \
64 .width = _width, \
65 .flags = _flags, \
66 .max = _max, \
67 }
68
69#define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags) \
70 _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags)
71
72#define _SUNXI_CCU_DIV_MAX(_shift, _width, _max) \
73 _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0)
74
45#define _SUNXI_CCU_DIV(_shift, _width) \ 75#define _SUNXI_CCU_DIV(_shift, _width) \
46 _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, NULL, 0) 76 _SUNXI_CCU_DIV_FLAGS(_shift, _width, 0)
47 77
48struct ccu_div { 78struct ccu_div {
49 u32 enable; 79 u32 enable;
@@ -77,13 +107,16 @@ struct ccu_div {
77 _shift, _width, _table, 0, \ 107 _shift, _width, _table, 0, \
78 _flags) 108 _flags)
79 109
80#define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ 110#define SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \
81 _mshift, _mwidth, _muxshift, _muxwidth, \ 111 _parents, _table, \
82 _gate, _flags) \ 112 _reg, \
113 _mshift, _mwidth, \
114 _muxshift, _muxwidth, \
115 _gate, _flags) \
83 struct ccu_div _struct = { \ 116 struct ccu_div _struct = { \
84 .enable = _gate, \ 117 .enable = _gate, \
85 .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \ 118 .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \
86 .mux = SUNXI_CLK_MUX(_muxshift, _muxwidth), \ 119 .mux = _SUNXI_CCU_MUX_TABLE(_muxshift, _muxwidth, _table), \
87 .common = { \ 120 .common = { \
88 .reg = _reg, \ 121 .reg = _reg, \
89 .hw.init = CLK_HW_INIT_PARENTS(_name, \ 122 .hw.init = CLK_HW_INIT_PARENTS(_name, \
@@ -93,12 +126,23 @@ struct ccu_div {
93 }, \ 126 }, \
94 } 127 }
95 128
129#define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
130 _mshift, _mwidth, _muxshift, _muxwidth, \
131 _gate, _flags) \
132 SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \
133 _parents, NULL, \
134 _reg, _mshift, _mwidth, \
135 _muxshift, _muxwidth, \
136 _gate, _flags)
137
96#define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg, \ 138#define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg, \
97 _mshift, _mwidth, _muxshift, _muxwidth, \ 139 _mshift, _mwidth, _muxshift, _muxwidth, \
98 _flags) \ 140 _flags) \
99 SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ 141 SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \
100 _mshift, _mwidth, _muxshift, _muxwidth, \ 142 _parents, NULL, \
101 0, _flags) 143 _reg, _mshift, _mwidth, \
144 _muxshift, _muxwidth, \
145 0, _flags)
102 146
103 147
104#define SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \ 148#define SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \
diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
index cbf33ef5faa9..ebb1b31568a5 100644
--- a/drivers/clk/sunxi-ng/ccu_mp.c
+++ b/drivers/clk/sunxi-ng/ccu_mp.c
@@ -21,9 +21,9 @@ static void ccu_mp_find_best(unsigned long parent, unsigned long rate,
21 unsigned int best_m = 0, best_p = 0; 21 unsigned int best_m = 0, best_p = 0;
22 unsigned int _m, _p; 22 unsigned int _m, _p;
23 23
24 for (_p = 0; _p <= max_p; _p++) { 24 for (_p = 1; _p <= max_p; _p <<= 1) {
25 for (_m = 1; _m <= max_m; _m++) { 25 for (_m = 1; _m <= max_m; _m++) {
26 unsigned long tmp_rate = (parent >> _p) / _m; 26 unsigned long tmp_rate = parent / _p / _m;
27 27
28 if (tmp_rate > rate) 28 if (tmp_rate > rate)
29 continue; 29 continue;
@@ -46,13 +46,15 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
46 void *data) 46 void *data)
47{ 47{
48 struct ccu_mp *cmp = data; 48 struct ccu_mp *cmp = data;
49 unsigned int max_m, max_p;
49 unsigned int m, p; 50 unsigned int m, p;
50 51
51 ccu_mp_find_best(parent_rate, rate, 52 max_m = cmp->m.max ?: 1 << cmp->m.width;
52 1 << cmp->m.width, (1 << cmp->p.width) - 1, 53 max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
53 &m, &p);
54 54
55 return (parent_rate >> p) / m; 55 ccu_mp_find_best(parent_rate, rate, max_m, max_p, &m, &p);
56
57 return parent_rate / p / m;
56} 58}
57 59
58static void ccu_mp_disable(struct clk_hw *hw) 60static void ccu_mp_disable(struct clk_hw *hw)
@@ -108,13 +110,14 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate,
108{ 110{
109 struct ccu_mp *cmp = hw_to_ccu_mp(hw); 111 struct ccu_mp *cmp = hw_to_ccu_mp(hw);
110 unsigned long flags; 112 unsigned long flags;
113 unsigned int max_m, max_p;
111 unsigned int m, p; 114 unsigned int m, p;
112 u32 reg; 115 u32 reg;
113 116
114 ccu_mp_find_best(parent_rate, rate, 117 max_m = cmp->m.max ?: 1 << cmp->m.width;
115 1 << cmp->m.width, (1 << cmp->p.width) - 1, 118 max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
116 &m, &p);
117 119
120 ccu_mp_find_best(parent_rate, rate, max_m, max_p, &m, &p);
118 121
119 spin_lock_irqsave(cmp->common.lock, flags); 122 spin_lock_irqsave(cmp->common.lock, flags);
120 123
@@ -122,7 +125,7 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate,
122 reg &= ~GENMASK(cmp->m.width + cmp->m.shift - 1, cmp->m.shift); 125 reg &= ~GENMASK(cmp->m.width + cmp->m.shift - 1, cmp->m.shift);
123 reg &= ~GENMASK(cmp->p.width + cmp->p.shift - 1, cmp->p.shift); 126 reg &= ~GENMASK(cmp->p.width + cmp->p.shift - 1, cmp->p.shift);
124 127
125 writel(reg | (p << cmp->p.shift) | ((m - 1) << cmp->m.shift), 128 writel(reg | (ilog2(p) << cmp->p.shift) | ((m - 1) << cmp->m.shift),
126 cmp->common.base + cmp->common.reg); 129 cmp->common.base + cmp->common.reg);
127 130
128 spin_unlock_irqrestore(cmp->common.lock, flags); 131 spin_unlock_irqrestore(cmp->common.lock, flags);
diff --git a/drivers/clk/sunxi-ng/ccu_mp.h b/drivers/clk/sunxi-ng/ccu_mp.h
index 3cf12bf95962..edf9215ea8cc 100644
--- a/drivers/clk/sunxi-ng/ccu_mp.h
+++ b/drivers/clk/sunxi-ng/ccu_mp.h
@@ -44,7 +44,7 @@ struct ccu_mp {
44 .enable = _gate, \ 44 .enable = _gate, \
45 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ 45 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
46 .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \ 46 .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \
47 .mux = SUNXI_CLK_MUX(_muxshift, _muxwidth), \ 47 .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
48 .common = { \ 48 .common = { \
49 .reg = _reg, \ 49 .reg = _reg, \
50 .hw.init = CLK_HW_INIT_PARENTS(_name, \ 50 .hw.init = CLK_HW_INIT_PARENTS(_name, \
diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c
new file mode 100644
index 000000000000..010e9424691d
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu_mult.c
@@ -0,0 +1,133 @@
1/*
2 * Copyright (C) 2016 Maxime Ripard
3 * Maxime Ripard <maxime.ripard@free-electrons.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 */
10
11#include <linux/clk-provider.h>
12
13#include "ccu_gate.h"
14#include "ccu_mult.h"
15
16static void ccu_mult_find_best(unsigned long parent, unsigned long rate,
17 unsigned int max_n, unsigned int *n)
18{
19 *n = rate / parent;
20}
21
22static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux,
23 unsigned long parent_rate,
24 unsigned long rate,
25 void *data)
26{
27 struct ccu_mult *cm = data;
28 unsigned int n;
29
30 ccu_mult_find_best(parent_rate, rate, 1 << cm->mult.width, &n);
31
32 return parent_rate * n;
33}
34
35static void ccu_mult_disable(struct clk_hw *hw)
36{
37 struct ccu_mult *cm = hw_to_ccu_mult(hw);
38
39 return ccu_gate_helper_disable(&cm->common, cm->enable);
40}
41
42static int ccu_mult_enable(struct clk_hw *hw)
43{
44 struct ccu_mult *cm = hw_to_ccu_mult(hw);
45
46 return ccu_gate_helper_enable(&cm->common, cm->enable);
47}
48
49static int ccu_mult_is_enabled(struct clk_hw *hw)
50{
51 struct ccu_mult *cm = hw_to_ccu_mult(hw);
52
53 return ccu_gate_helper_is_enabled(&cm->common, cm->enable);
54}
55
56static unsigned long ccu_mult_recalc_rate(struct clk_hw *hw,
57 unsigned long parent_rate)
58{
59 struct ccu_mult *cm = hw_to_ccu_mult(hw);
60 unsigned long val;
61 u32 reg;
62
63 reg = readl(cm->common.base + cm->common.reg);
64 val = reg >> cm->mult.shift;
65 val &= (1 << cm->mult.width) - 1;
66
67 ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1,
68 &parent_rate);
69
70 return parent_rate * (val + 1);
71}
72
73static int ccu_mult_determine_rate(struct clk_hw *hw,
74 struct clk_rate_request *req)
75{
76 struct ccu_mult *cm = hw_to_ccu_mult(hw);
77
78 return ccu_mux_helper_determine_rate(&cm->common, &cm->mux,
79 req, ccu_mult_round_rate, cm);
80}
81
82static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate,
83 unsigned long parent_rate)
84{
85 struct ccu_mult *cm = hw_to_ccu_mult(hw);
86 unsigned long flags;
87 unsigned int n;
88 u32 reg;
89
90 ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1,
91 &parent_rate);
92
93 ccu_mult_find_best(parent_rate, rate, 1 << cm->mult.width, &n);
94
95 spin_lock_irqsave(cm->common.lock, flags);
96
97 reg = readl(cm->common.base + cm->common.reg);
98 reg &= ~GENMASK(cm->mult.width + cm->mult.shift - 1, cm->mult.shift);
99
100 writel(reg | ((n - 1) << cm->mult.shift),
101 cm->common.base + cm->common.reg);
102
103 spin_unlock_irqrestore(cm->common.lock, flags);
104
105 return 0;
106}
107
108static u8 ccu_mult_get_parent(struct clk_hw *hw)
109{
110 struct ccu_mult *cm = hw_to_ccu_mult(hw);
111
112 return ccu_mux_helper_get_parent(&cm->common, &cm->mux);
113}
114
115static int ccu_mult_set_parent(struct clk_hw *hw, u8 index)
116{
117 struct ccu_mult *cm = hw_to_ccu_mult(hw);
118
119 return ccu_mux_helper_set_parent(&cm->common, &cm->mux, index);
120}
121
122const struct clk_ops ccu_mult_ops = {
123 .disable = ccu_mult_disable,
124 .enable = ccu_mult_enable,
125 .is_enabled = ccu_mult_is_enabled,
126
127 .get_parent = ccu_mult_get_parent,
128 .set_parent = ccu_mult_set_parent,
129
130 .determine_rate = ccu_mult_determine_rate,
131 .recalc_rate = ccu_mult_recalc_rate,
132 .set_rate = ccu_mult_set_rate,
133};
diff --git a/drivers/clk/sunxi-ng/ccu_mult.h b/drivers/clk/sunxi-ng/ccu_mult.h
index 609db6610880..5d2c8dc14073 100644
--- a/drivers/clk/sunxi-ng/ccu_mult.h
+++ b/drivers/clk/sunxi-ng/ccu_mult.h
@@ -1,6 +1,9 @@
1#ifndef _CCU_MULT_H_ 1#ifndef _CCU_MULT_H_
2#define _CCU_MULT_H_ 2#define _CCU_MULT_H_
3 3
4#include "ccu_common.h"
5#include "ccu_mux.h"
6
4struct _ccu_mult { 7struct _ccu_mult {
5 u8 shift; 8 u8 shift;
6 u8 width; 9 u8 width;
@@ -12,4 +15,36 @@ struct _ccu_mult {
12 .width = _width, \ 15 .width = _width, \
13 } 16 }
14 17
18struct ccu_mult {
19 u32 enable;
20
21 struct _ccu_mult mult;
22 struct ccu_mux_internal mux;
23 struct ccu_common common;
24};
25
26#define SUNXI_CCU_N_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \
27 _mshift, _mwidth, _gate, _lock, \
28 _flags) \
29 struct ccu_mult _struct = { \
30 .enable = _gate, \
31 .mult = _SUNXI_CCU_MULT(_mshift, _mwidth), \
32 .common = { \
33 .reg = _reg, \
34 .hw.init = CLK_HW_INIT(_name, \
35 _parent, \
36 &ccu_mult_ops, \
37 _flags), \
38 }, \
39 }
40
41static inline struct ccu_mult *hw_to_ccu_mult(struct clk_hw *hw)
42{
43 struct ccu_common *common = hw_to_ccu_common(hw);
44
45 return container_of(common, struct ccu_mult, common);
46}
47
48extern const struct clk_ops ccu_mult_ops;
49
15#endif /* _CCU_MULT_H_ */ 50#endif /* _CCU_MULT_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu_mux.c b/drivers/clk/sunxi-ng/ccu_mux.c
index 58fc36e7dcce..a43ad52a957d 100644
--- a/drivers/clk/sunxi-ng/ccu_mux.c
+++ b/drivers/clk/sunxi-ng/ccu_mux.c
@@ -8,7 +8,9 @@
8 * the License, or (at your option) any later version. 8 * the License, or (at your option) any later version.
9 */ 9 */
10 10
11#include <linux/clk.h>
11#include <linux/clk-provider.h> 12#include <linux/clk-provider.h>
13#include <linux/delay.h>
12 14
13#include "ccu_gate.h" 15#include "ccu_gate.h"
14#include "ccu_mux.h" 16#include "ccu_mux.h"
@@ -18,8 +20,9 @@ void ccu_mux_helper_adjust_parent_for_prediv(struct ccu_common *common,
18 int parent_index, 20 int parent_index,
19 unsigned long *parent_rate) 21 unsigned long *parent_rate)
20{ 22{
21 u8 prediv = 1; 23 u16 prediv = 1;
22 u32 reg; 24 u32 reg;
25 int i;
23 26
24 if (!((common->features & CCU_FEATURE_FIXED_PREDIV) || 27 if (!((common->features & CCU_FEATURE_FIXED_PREDIV) ||
25 (common->features & CCU_FEATURE_VARIABLE_PREDIV))) 28 (common->features & CCU_FEATURE_VARIABLE_PREDIV)))
@@ -32,8 +35,9 @@ void ccu_mux_helper_adjust_parent_for_prediv(struct ccu_common *common,
32 } 35 }
33 36
34 if (common->features & CCU_FEATURE_FIXED_PREDIV) 37 if (common->features & CCU_FEATURE_FIXED_PREDIV)
35 if (parent_index == cm->fixed_prediv.index) 38 for (i = 0; i < cm->n_predivs; i++)
36 prediv = cm->fixed_prediv.div; 39 if (parent_index == cm->fixed_predivs[i].index)
40 prediv = cm->fixed_predivs[i].div;
37 41
38 if (common->features & CCU_FEATURE_VARIABLE_PREDIV) 42 if (common->features & CCU_FEATURE_VARIABLE_PREDIV)
39 if (parent_index == cm->variable_prediv.index) { 43 if (parent_index == cm->variable_prediv.index) {
@@ -107,6 +111,15 @@ u8 ccu_mux_helper_get_parent(struct ccu_common *common,
107 parent = reg >> cm->shift; 111 parent = reg >> cm->shift;
108 parent &= (1 << cm->width) - 1; 112 parent &= (1 << cm->width) - 1;
109 113
114 if (cm->table) {
115 int num_parents = clk_hw_get_num_parents(&common->hw);
116 int i;
117
118 for (i = 0; i < num_parents; i++)
119 if (cm->table[i] == parent)
120 return i;
121 }
122
110 return parent; 123 return parent;
111} 124}
112 125
@@ -117,6 +130,9 @@ int ccu_mux_helper_set_parent(struct ccu_common *common,
117 unsigned long flags; 130 unsigned long flags;
118 u32 reg; 131 u32 reg;
119 132
133 if (cm->table)
134 index = cm->table[index];
135
120 spin_lock_irqsave(common->lock, flags); 136 spin_lock_irqsave(common->lock, flags);
121 137
122 reg = readl(common->base + common->reg); 138 reg = readl(common->base + common->reg);
@@ -185,3 +201,37 @@ const struct clk_ops ccu_mux_ops = {
185 .determine_rate = __clk_mux_determine_rate, 201 .determine_rate = __clk_mux_determine_rate,
186 .recalc_rate = ccu_mux_recalc_rate, 202 .recalc_rate = ccu_mux_recalc_rate,
187}; 203};
204
205/*
206 * This clock notifier is called when the frequency of the of the parent
207 * PLL clock is to be changed. The idea is to switch the parent to a
208 * stable clock, such as the main oscillator, while the PLL frequency
209 * stabilizes.
210 */
211static int ccu_mux_notifier_cb(struct notifier_block *nb,
212 unsigned long event, void *data)
213{
214 struct ccu_mux_nb *mux = to_ccu_mux_nb(nb);
215 int ret = 0;
216
217 if (event == PRE_RATE_CHANGE) {
218 mux->original_index = ccu_mux_helper_get_parent(mux->common,
219 mux->cm);
220 ret = ccu_mux_helper_set_parent(mux->common, mux->cm,
221 mux->bypass_index);
222 } else if (event == POST_RATE_CHANGE) {
223 ret = ccu_mux_helper_set_parent(mux->common, mux->cm,
224 mux->original_index);
225 }
226
227 udelay(mux->delay_us);
228
229 return notifier_from_errno(ret);
230}
231
232int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb)
233{
234 mux_nb->clk_nb.notifier_call = ccu_mux_notifier_cb;
235
236 return clk_notifier_register(clk, &mux_nb->clk_nb);
237}
diff --git a/drivers/clk/sunxi-ng/ccu_mux.h b/drivers/clk/sunxi-ng/ccu_mux.h
index 945082631e7d..47aba3a48245 100644
--- a/drivers/clk/sunxi-ng/ccu_mux.h
+++ b/drivers/clk/sunxi-ng/ccu_mux.h
@@ -5,14 +5,18 @@
5 5
6#include "ccu_common.h" 6#include "ccu_common.h"
7 7
8struct ccu_mux_fixed_prediv {
9 u8 index;
10 u16 div;
11};
12
8struct ccu_mux_internal { 13struct ccu_mux_internal {
9 u8 shift; 14 u8 shift;
10 u8 width; 15 u8 width;
16 const u8 *table;
11 17
12 struct { 18 const struct ccu_mux_fixed_prediv *fixed_predivs;
13 u8 index; 19 u8 n_predivs;
14 u8 div;
15 } fixed_prediv;
16 20
17 struct { 21 struct {
18 u8 index; 22 u8 index;
@@ -21,12 +25,16 @@ struct ccu_mux_internal {
21 } variable_prediv; 25 } variable_prediv;
22}; 26};
23 27
24#define SUNXI_CLK_MUX(_shift, _width) \ 28#define _SUNXI_CCU_MUX_TABLE(_shift, _width, _table) \
25 { \ 29 { \
26 .shift = _shift, \ 30 .shift = _shift, \
27 .width = _width, \ 31 .width = _width, \
32 .table = _table, \
28 } 33 }
29 34
35#define _SUNXI_CCU_MUX(_shift, _width) \
36 _SUNXI_CCU_MUX_TABLE(_shift, _width, NULL)
37
30struct ccu_mux { 38struct ccu_mux {
31 u16 reg; 39 u16 reg;
32 u32 enable; 40 u32 enable;
@@ -35,9 +43,12 @@ struct ccu_mux {
35 struct ccu_common common; 43 struct ccu_common common;
36}; 44};
37 45
38#define SUNXI_CCU_MUX(_struct, _name, _parents, _reg, _shift, _width, _flags) \ 46#define SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, _table, \
47 _reg, _shift, _width, _gate, \
48 _flags) \
39 struct ccu_mux _struct = { \ 49 struct ccu_mux _struct = { \
40 .mux = SUNXI_CLK_MUX(_shift, _width), \ 50 .enable = _gate, \
51 .mux = _SUNXI_CCU_MUX_TABLE(_shift, _width, _table), \
41 .common = { \ 52 .common = { \
42 .reg = _reg, \ 53 .reg = _reg, \
43 .hw.init = CLK_HW_INIT_PARENTS(_name, \ 54 .hw.init = CLK_HW_INIT_PARENTS(_name, \
@@ -49,17 +60,14 @@ struct ccu_mux {
49 60
50#define SUNXI_CCU_MUX_WITH_GATE(_struct, _name, _parents, _reg, \ 61#define SUNXI_CCU_MUX_WITH_GATE(_struct, _name, _parents, _reg, \
51 _shift, _width, _gate, _flags) \ 62 _shift, _width, _gate, _flags) \
52 struct ccu_mux _struct = { \ 63 SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL, \
53 .enable = _gate, \ 64 _reg, _shift, _width, _gate, \
54 .mux = SUNXI_CLK_MUX(_shift, _width), \ 65 _flags)
55 .common = { \ 66
56 .reg = _reg, \ 67#define SUNXI_CCU_MUX(_struct, _name, _parents, _reg, _shift, _width, \
57 .hw.init = CLK_HW_INIT_PARENTS(_name, \ 68 _flags) \
58 _parents, \ 69 SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL, \
59 &ccu_mux_ops, \ 70 _reg, _shift, _width, 0, _flags)
60 _flags), \
61 } \
62 }
63 71
64static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw) 72static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw)
65{ 73{
@@ -88,4 +96,18 @@ int ccu_mux_helper_set_parent(struct ccu_common *common,
88 struct ccu_mux_internal *cm, 96 struct ccu_mux_internal *cm,
89 u8 index); 97 u8 index);
90 98
99struct ccu_mux_nb {
100 struct notifier_block clk_nb;
101 struct ccu_common *common;
102 struct ccu_mux_internal *cm;
103
104 u32 delay_us; /* How many us to wait after reparenting */
105 u8 bypass_index; /* Which parent to temporarily use */
106 u8 original_index; /* This is set by the notifier callback */
107};
108
109#define to_ccu_mux_nb(_nb) container_of(_nb, struct ccu_mux_nb, clk_nb)
110
111int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb);
112
91#endif /* _CCU_MUX_H_ */ 113#endif /* _CCU_MUX_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
index 2071822b1e9c..059fdc3b4f96 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.c
+++ b/drivers/clk/sunxi-ng/ccu_nkm.c
@@ -93,19 +93,30 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
93 return parent_rate * (n + 1) * (k + 1) / (m + 1); 93 return parent_rate * (n + 1) * (k + 1) / (m + 1);
94} 94}
95 95
96static long ccu_nkm_round_rate(struct clk_hw *hw, unsigned long rate, 96static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
97 unsigned long *parent_rate) 97 unsigned long parent_rate,
98 unsigned long rate,
99 void *data)
98{ 100{
99 struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); 101 struct ccu_nkm *nkm = data;
100 struct _ccu_nkm _nkm; 102 struct _ccu_nkm _nkm;
101 103
102 _nkm.max_n = 1 << nkm->n.width; 104 _nkm.max_n = 1 << nkm->n.width;
103 _nkm.max_k = 1 << nkm->k.width; 105 _nkm.max_k = 1 << nkm->k.width;
104 _nkm.max_m = 1 << nkm->m.width; 106 _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
105 107
106 ccu_nkm_find_best(*parent_rate, rate, &_nkm); 108 ccu_nkm_find_best(parent_rate, rate, &_nkm);
107 109
108 return *parent_rate * _nkm.n * _nkm.k / _nkm.m; 110 return parent_rate * _nkm.n * _nkm.k / _nkm.m;
111}
112
113static int ccu_nkm_determine_rate(struct clk_hw *hw,
114 struct clk_rate_request *req)
115{
116 struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
117
118 return ccu_mux_helper_determine_rate(&nkm->common, &nkm->mux,
119 req, ccu_nkm_round_rate, nkm);
109} 120}
110 121
111static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate, 122static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -118,7 +129,7 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
118 129
119 _nkm.max_n = 1 << nkm->n.width; 130 _nkm.max_n = 1 << nkm->n.width;
120 _nkm.max_k = 1 << nkm->k.width; 131 _nkm.max_k = 1 << nkm->k.width;
121 _nkm.max_m = 1 << nkm->m.width; 132 _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
122 133
123 ccu_nkm_find_best(parent_rate, rate, &_nkm); 134 ccu_nkm_find_best(parent_rate, rate, &_nkm);
124 135
@@ -142,12 +153,29 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
142 return 0; 153 return 0;
143} 154}
144 155
156static u8 ccu_nkm_get_parent(struct clk_hw *hw)
157{
158 struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
159
160 return ccu_mux_helper_get_parent(&nkm->common, &nkm->mux);
161}
162
163static int ccu_nkm_set_parent(struct clk_hw *hw, u8 index)
164{
165 struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
166
167 return ccu_mux_helper_set_parent(&nkm->common, &nkm->mux, index);
168}
169
145const struct clk_ops ccu_nkm_ops = { 170const struct clk_ops ccu_nkm_ops = {
146 .disable = ccu_nkm_disable, 171 .disable = ccu_nkm_disable,
147 .enable = ccu_nkm_enable, 172 .enable = ccu_nkm_enable,
148 .is_enabled = ccu_nkm_is_enabled, 173 .is_enabled = ccu_nkm_is_enabled,
149 174
175 .get_parent = ccu_nkm_get_parent,
176 .set_parent = ccu_nkm_set_parent,
177
178 .determine_rate = ccu_nkm_determine_rate,
150 .recalc_rate = ccu_nkm_recalc_rate, 179 .recalc_rate = ccu_nkm_recalc_rate,
151 .round_rate = ccu_nkm_round_rate,
152 .set_rate = ccu_nkm_set_rate, 180 .set_rate = ccu_nkm_set_rate,
153}; 181};
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
index 1936ac1c6b37..35493fddd8ab 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.h
+++ b/drivers/clk/sunxi-ng/ccu_nkm.h
@@ -32,10 +32,33 @@ struct ccu_nkm {
32 struct _ccu_mult n; 32 struct _ccu_mult n;
33 struct _ccu_mult k; 33 struct _ccu_mult k;
34 struct _ccu_div m; 34 struct _ccu_div m;
35 struct ccu_mux_internal mux;
35 36
36 struct ccu_common common; 37 struct ccu_common common;
37}; 38};
38 39
40#define SUNXI_CCU_NKM_WITH_MUX_GATE_LOCK(_struct, _name, _parents, _reg, \
41 _nshift, _nwidth, \
42 _kshift, _kwidth, \
43 _mshift, _mwidth, \
44 _muxshift, _muxwidth, \
45 _gate, _lock, _flags) \
46 struct ccu_nkm _struct = { \
47 .enable = _gate, \
48 .lock = _lock, \
49 .k = _SUNXI_CCU_MULT(_kshift, _kwidth), \
50 .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \
51 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
52 .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
53 .common = { \
54 .reg = _reg, \
55 .hw.init = CLK_HW_INIT_PARENTS(_name, \
56 _parents, \
57 &ccu_nkm_ops, \
58 _flags), \
59 }, \
60 }
61
39#define SUNXI_CCU_NKM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ 62#define SUNXI_CCU_NKM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \
40 _nshift, _nwidth, \ 63 _nshift, _nwidth, \
41 _kshift, _kwidth, \ 64 _kshift, _kwidth, \
diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c
index 9f2b98e19dc9..9769dee99511 100644
--- a/drivers/clk/sunxi-ng/ccu_nkmp.c
+++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
@@ -29,14 +29,14 @@ static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate,
29 unsigned long _n, _k, _m, _p; 29 unsigned long _n, _k, _m, _p;
30 30
31 for (_k = 1; _k <= nkmp->max_k; _k++) { 31 for (_k = 1; _k <= nkmp->max_k; _k++) {
32 for (_p = 0; _p <= nkmp->max_p; _p++) { 32 for (_p = 1; _p <= nkmp->max_p; _p <<= 1) {
33 unsigned long tmp_rate; 33 unsigned long tmp_rate;
34 34
35 rational_best_approximation(rate / _k, parent >> _p, 35 rational_best_approximation(rate / _k, parent / _p,
36 nkmp->max_n, nkmp->max_m, 36 nkmp->max_n, nkmp->max_m,
37 &_n, &_m); 37 &_n, &_m);
38 38
39 tmp_rate = (parent * _n * _k >> _p) / _m; 39 tmp_rate = parent * _n * _k / (_m * _p);
40 40
41 if (tmp_rate > rate) 41 if (tmp_rate > rate)
42 continue; 42 continue;
@@ -110,13 +110,12 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
110 110
111 _nkmp.max_n = 1 << nkmp->n.width; 111 _nkmp.max_n = 1 << nkmp->n.width;
112 _nkmp.max_k = 1 << nkmp->k.width; 112 _nkmp.max_k = 1 << nkmp->k.width;
113 _nkmp.max_m = 1 << nkmp->m.width; 113 _nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width;
114 _nkmp.max_p = (1 << nkmp->p.width) - 1; 114 _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1);
115 115
116 ccu_nkmp_find_best(*parent_rate, rate, 116 ccu_nkmp_find_best(*parent_rate, rate, &_nkmp);
117 &_nkmp);
118 117
119 return (*parent_rate * _nkmp.n * _nkmp.k >> _nkmp.p) / _nkmp.m; 118 return *parent_rate * _nkmp.n * _nkmp.k / (_nkmp.m * _nkmp.p);
120} 119}
121 120
122static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, 121static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -129,8 +128,8 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
129 128
130 _nkmp.max_n = 1 << nkmp->n.width; 129 _nkmp.max_n = 1 << nkmp->n.width;
131 _nkmp.max_k = 1 << nkmp->k.width; 130 _nkmp.max_k = 1 << nkmp->k.width;
132 _nkmp.max_m = 1 << nkmp->m.width; 131 _nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width;
133 _nkmp.max_p = (1 << nkmp->p.width) - 1; 132 _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1);
134 133
135 ccu_nkmp_find_best(parent_rate, rate, &_nkmp); 134 ccu_nkmp_find_best(parent_rate, rate, &_nkmp);
136 135
@@ -145,7 +144,7 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
145 reg |= (_nkmp.n - 1) << nkmp->n.shift; 144 reg |= (_nkmp.n - 1) << nkmp->n.shift;
146 reg |= (_nkmp.k - 1) << nkmp->k.shift; 145 reg |= (_nkmp.k - 1) << nkmp->k.shift;
147 reg |= (_nkmp.m - 1) << nkmp->m.shift; 146 reg |= (_nkmp.m - 1) << nkmp->m.shift;
148 reg |= _nkmp.p << nkmp->p.shift; 147 reg |= ilog2(_nkmp.p) << nkmp->p.shift;
149 148
150 writel(reg, nkmp->common.base + nkmp->common.reg); 149 writel(reg, nkmp->common.base + nkmp->common.reg);
151 150
diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c
index e35ddd8eec8b..b61bdd8c7a7f 100644
--- a/drivers/clk/sunxi-ng/ccu_nm.c
+++ b/drivers/clk/sunxi-ng/ccu_nm.c
@@ -61,11 +61,13 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
61 unsigned long *parent_rate) 61 unsigned long *parent_rate)
62{ 62{
63 struct ccu_nm *nm = hw_to_ccu_nm(hw); 63 struct ccu_nm *nm = hw_to_ccu_nm(hw);
64 unsigned long max_n, max_m;
64 unsigned long n, m; 65 unsigned long n, m;
65 66
66 rational_best_approximation(rate, *parent_rate, 67 max_n = 1 << nm->n.width;
67 1 << nm->n.width, 1 << nm->m.width, 68 max_m = nm->m.max ?: 1 << nm->m.width;
68 &n, &m); 69
70 rational_best_approximation(rate, *parent_rate, max_n, max_m, &n, &m);
69 71
70 return *parent_rate * n / m; 72 return *parent_rate * n / m;
71} 73}
@@ -75,6 +77,7 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
75{ 77{
76 struct ccu_nm *nm = hw_to_ccu_nm(hw); 78 struct ccu_nm *nm = hw_to_ccu_nm(hw);
77 unsigned long flags; 79 unsigned long flags;
80 unsigned long max_n, max_m;
78 unsigned long n, m; 81 unsigned long n, m;
79 u32 reg; 82 u32 reg;
80 83
@@ -83,9 +86,10 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
83 else 86 else
84 ccu_frac_helper_disable(&nm->common, &nm->frac); 87 ccu_frac_helper_disable(&nm->common, &nm->frac);
85 88
86 rational_best_approximation(rate, parent_rate, 89 max_n = 1 << nm->n.width;
87 1 << nm->n.width, 1 << nm->m.width, 90 max_m = nm->m.max ?: 1 << nm->m.width;
88 &n, &m); 91
92 rational_best_approximation(rate, parent_rate, max_n, max_m, &n, &m);
89 93
90 spin_lock_irqsave(nm->common.lock, flags); 94 spin_lock_irqsave(nm->common.lock, flags);
91 95
diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c
index b38d71cec74c..e54266cc1c51 100644
--- a/drivers/clk/sunxi/clk-mod0.c
+++ b/drivers/clk/sunxi/clk-mod0.c
@@ -91,7 +91,8 @@ static void __init sun4i_a10_mod0_setup(struct device_node *node)
91 sunxi_factors_register(node, &sun4i_a10_mod0_data, 91 sunxi_factors_register(node, &sun4i_a10_mod0_data,
92 &sun4i_a10_mod0_lock, reg); 92 &sun4i_a10_mod0_lock, reg);
93} 93}
94CLK_OF_DECLARE(sun4i_a10_mod0, "allwinner,sun4i-a10-mod0-clk", sun4i_a10_mod0_setup); 94CLK_OF_DECLARE_DRIVER(sun4i_a10_mod0, "allwinner,sun4i-a10-mod0-clk",
95 sun4i_a10_mod0_setup);
95 96
96static int sun4i_a10_mod0_clk_probe(struct platform_device *pdev) 97static int sun4i_a10_mod0_clk_probe(struct platform_device *pdev)
97{ 98{
diff --git a/drivers/clk/sunxi/clk-sun8i-apb0.c b/drivers/clk/sunxi/clk-sun8i-apb0.c
index a5666e1d0ce7..ea1eed24778c 100644
--- a/drivers/clk/sunxi/clk-sun8i-apb0.c
+++ b/drivers/clk/sunxi/clk-sun8i-apb0.c
@@ -82,8 +82,8 @@ err_unmap:
82 of_address_to_resource(node, 0, &res); 82 of_address_to_resource(node, 0, &res);
83 release_mem_region(res.start, resource_size(&res)); 83 release_mem_region(res.start, resource_size(&res));
84} 84}
85CLK_OF_DECLARE(sun8i_a23_apb0, "allwinner,sun8i-a23-apb0-clk", 85CLK_OF_DECLARE_DRIVER(sun8i_a23_apb0, "allwinner,sun8i-a23-apb0-clk",
86 sun8i_a23_apb0_setup); 86 sun8i_a23_apb0_setup);
87 87
88static int sun8i_a23_apb0_clk_probe(struct platform_device *pdev) 88static int sun8i_a23_apb0_clk_probe(struct platform_device *pdev)
89{ 89{
diff --git a/drivers/clk/uniphier/Kconfig b/drivers/clk/uniphier/Kconfig
new file mode 100644
index 000000000000..5512377bd62b
--- /dev/null
+++ b/drivers/clk/uniphier/Kconfig
@@ -0,0 +1,9 @@
1config CLK_UNIPHIER
2 bool "Clock driver for UniPhier SoCs"
3 depends on ARCH_UNIPHIER || COMPILE_TEST
4 depends on OF && MFD_SYSCON
5 default ARCH_UNIPHIER
6 help
7 Support for clock controllers on UniPhier SoCs.
8 Say Y if you want to control clocks provided by System Control
9 block, Media I/O block, Peripheral Block.
diff --git a/drivers/clk/uniphier/Makefile b/drivers/clk/uniphier/Makefile
new file mode 100644
index 000000000000..f27b360329ca
--- /dev/null
+++ b/drivers/clk/uniphier/Makefile
@@ -0,0 +1,8 @@
1obj-y += clk-uniphier-core.o
2obj-y += clk-uniphier-fixed-factor.o
3obj-y += clk-uniphier-fixed-rate.o
4obj-y += clk-uniphier-gate.o
5obj-y += clk-uniphier-mux.o
6obj-y += clk-uniphier-sys.o
7obj-y += clk-uniphier-mio.o
8obj-y += clk-uniphier-peri.o
diff --git a/drivers/clk/uniphier/clk-uniphier-core.c b/drivers/clk/uniphier/clk-uniphier-core.c
new file mode 100644
index 000000000000..5ffb898d0839
--- /dev/null
+++ b/drivers/clk/uniphier/clk-uniphier-core.c
@@ -0,0 +1,214 @@
1/*
2 * Copyright (C) 2016 Socionext Inc.
3 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/clk-provider.h>
17#include <linux/init.h>
18#include <linux/mfd/syscon.h>
19#include <linux/of.h>
20#include <linux/of_device.h>
21#include <linux/platform_device.h>
22
23#include "clk-uniphier.h"
24
25static struct clk_hw *uniphier_clk_register(struct device *dev,
26 struct regmap *regmap,
27 const struct uniphier_clk_data *data)
28{
29 switch (data->type) {
30 case UNIPHIER_CLK_TYPE_FIXED_FACTOR:
31 return uniphier_clk_register_fixed_factor(dev, data->name,
32 &data->data.factor);
33 case UNIPHIER_CLK_TYPE_FIXED_RATE:
34 return uniphier_clk_register_fixed_rate(dev, data->name,
35 &data->data.rate);
36 case UNIPHIER_CLK_TYPE_GATE:
37 return uniphier_clk_register_gate(dev, regmap, data->name,
38 &data->data.gate);
39 case UNIPHIER_CLK_TYPE_MUX:
40 return uniphier_clk_register_mux(dev, regmap, data->name,
41 &data->data.mux);
42 default:
43 dev_err(dev, "unsupported clock type\n");
44 return ERR_PTR(-EINVAL);
45 }
46}
47
48static int uniphier_clk_probe(struct platform_device *pdev)
49{
50 struct device *dev = &pdev->dev;
51 struct clk_hw_onecell_data *hw_data;
52 const struct uniphier_clk_data *p, *data;
53 struct regmap *regmap;
54 struct device_node *parent;
55 int clk_num = 0;
56
57 data = of_device_get_match_data(dev);
58 if (WARN_ON(!data))
59 return -EINVAL;
60
61 parent = of_get_parent(dev->of_node); /* parent should be syscon node */
62 regmap = syscon_node_to_regmap(parent);
63 of_node_put(parent);
64 if (IS_ERR(regmap)) {
65 dev_err(dev, "failed to get regmap (error %ld)\n",
66 PTR_ERR(regmap));
67 return PTR_ERR(regmap);
68 }
69
70 for (p = data; p->name; p++)
71 clk_num = max(clk_num, p->idx + 1);
72
73 hw_data = devm_kzalloc(dev,
74 sizeof(*hw_data) + clk_num * sizeof(struct clk_hw *),
75 GFP_KERNEL);
76 if (!hw_data)
77 return -ENOMEM;
78
79 hw_data->num = clk_num;
80
81 /* avoid returning NULL for unused idx */
82 for (; clk_num >= 0; clk_num--)
83 hw_data->hws[clk_num] = ERR_PTR(-EINVAL);
84
85 for (p = data; p->name; p++) {
86 struct clk_hw *hw;
87
88 dev_dbg(dev, "register %s (index=%d)\n", p->name, p->idx);
89 hw = uniphier_clk_register(dev, regmap, p);
90 if (IS_ERR(hw)) {
91 dev_err(dev, "failed to register %s (error %ld)\n",
92 p->name, PTR_ERR(hw));
93 return PTR_ERR(hw);
94 }
95
96 if (p->idx >= 0)
97 hw_data->hws[p->idx] = hw;
98 }
99
100 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
101 hw_data);
102}
103
104static int uniphier_clk_remove(struct platform_device *pdev)
105{
106 of_clk_del_provider(pdev->dev.of_node);
107
108 return 0;
109}
110
111static const struct of_device_id uniphier_clk_match[] = {
112 /* System clock */
113 {
114 .compatible = "socionext,uniphier-ld4-clock",
115 .data = uniphier_ld4_sys_clk_data,
116 },
117 {
118 .compatible = "socionext,uniphier-pro4-clock",
119 .data = uniphier_pro4_sys_clk_data,
120 },
121 {
122 .compatible = "socionext,uniphier-sld8-clock",
123 .data = uniphier_sld8_sys_clk_data,
124 },
125 {
126 .compatible = "socionext,uniphier-pro5-clock",
127 .data = uniphier_pro5_sys_clk_data,
128 },
129 {
130 .compatible = "socionext,uniphier-pxs2-clock",
131 .data = uniphier_pxs2_sys_clk_data,
132 },
133 {
134 .compatible = "socionext,uniphier-ld11-clock",
135 .data = uniphier_ld11_sys_clk_data,
136 },
137 {
138 .compatible = "socionext,uniphier-ld20-clock",
139 .data = uniphier_ld20_sys_clk_data,
140 },
141 /* Media I/O clock */
142 {
143 .compatible = "socionext,uniphier-sld3-mio-clock",
144 .data = uniphier_sld3_mio_clk_data,
145 },
146 {
147 .compatible = "socionext,uniphier-ld4-mio-clock",
148 .data = uniphier_sld3_mio_clk_data,
149 },
150 {
151 .compatible = "socionext,uniphier-pro4-mio-clock",
152 .data = uniphier_sld3_mio_clk_data,
153 },
154 {
155 .compatible = "socionext,uniphier-sld8-mio-clock",
156 .data = uniphier_sld3_mio_clk_data,
157 },
158 {
159 .compatible = "socionext,uniphier-pro5-mio-clock",
160 .data = uniphier_pro5_mio_clk_data,
161 },
162 {
163 .compatible = "socionext,uniphier-pxs2-mio-clock",
164 .data = uniphier_pro5_mio_clk_data,
165 },
166 {
167 .compatible = "socionext,uniphier-ld11-mio-clock",
168 .data = uniphier_sld3_mio_clk_data,
169 },
170 {
171 .compatible = "socionext,uniphier-ld20-mio-clock",
172 .data = uniphier_pro5_mio_clk_data,
173 },
174 /* Peripheral clock */
175 {
176 .compatible = "socionext,uniphier-ld4-peri-clock",
177 .data = uniphier_ld4_peri_clk_data,
178 },
179 {
180 .compatible = "socionext,uniphier-pro4-peri-clock",
181 .data = uniphier_pro4_peri_clk_data,
182 },
183 {
184 .compatible = "socionext,uniphier-sld8-peri-clock",
185 .data = uniphier_ld4_peri_clk_data,
186 },
187 {
188 .compatible = "socionext,uniphier-pro5-peri-clock",
189 .data = uniphier_pro4_peri_clk_data,
190 },
191 {
192 .compatible = "socionext,uniphier-pxs2-peri-clock",
193 .data = uniphier_pro4_peri_clk_data,
194 },
195 {
196 .compatible = "socionext,uniphier-ld11-peri-clock",
197 .data = uniphier_pro4_peri_clk_data,
198 },
199 {
200 .compatible = "socionext,uniphier-ld20-peri-clock",
201 .data = uniphier_pro4_peri_clk_data,
202 },
203 { /* sentinel */ }
204};
205
206static struct platform_driver uniphier_clk_driver = {
207 .probe = uniphier_clk_probe,
208 .remove = uniphier_clk_remove,
209 .driver = {
210 .name = "uniphier-clk",
211 .of_match_table = uniphier_clk_match,
212 },
213};
214builtin_platform_driver(uniphier_clk_driver);
diff --git a/drivers/clk/uniphier/clk-uniphier-fixed-factor.c b/drivers/clk/uniphier/clk-uniphier-fixed-factor.c
new file mode 100644
index 000000000000..da2d9f47ef9f
--- /dev/null
+++ b/drivers/clk/uniphier/clk-uniphier-fixed-factor.c
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2016 Socionext Inc.
3 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/clk-provider.h>
17#include <linux/device.h>
18
19#include "clk-uniphier.h"
20
21struct clk_hw *uniphier_clk_register_fixed_factor(struct device *dev,
22 const char *name,
23 const struct uniphier_clk_fixed_factor_data *data)
24{
25 struct clk_fixed_factor *fix;
26 struct clk_init_data init;
27 int ret;
28
29 fix = devm_kzalloc(dev, sizeof(*fix), GFP_KERNEL);
30 if (!fix)
31 return ERR_PTR(-ENOMEM);
32
33 init.name = name;
34 init.ops = &clk_fixed_factor_ops;
35 init.flags = data->parent_name ? CLK_SET_RATE_PARENT : 0;
36 init.parent_names = data->parent_name ? &data->parent_name : NULL;
37 init.num_parents = data->parent_name ? 1 : 0;
38
39 fix->mult = data->mult;
40 fix->div = data->div;
41 fix->hw.init = &init;
42
43 ret = devm_clk_hw_register(dev, &fix->hw);
44 if (ret)
45 return ERR_PTR(ret);
46
47 return &fix->hw;
48}
diff --git a/drivers/clk/uniphier/clk-uniphier-fixed-rate.c b/drivers/clk/uniphier/clk-uniphier-fixed-rate.c
new file mode 100644
index 000000000000..0ad0d46173c0
--- /dev/null
+++ b/drivers/clk/uniphier/clk-uniphier-fixed-rate.c
@@ -0,0 +1,47 @@
1/*
2 * Copyright (C) 2016 Socionext Inc.
3 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/clk-provider.h>
17#include <linux/device.h>
18
19#include "clk-uniphier.h"
20
21struct clk_hw *uniphier_clk_register_fixed_rate(struct device *dev,
22 const char *name,
23 const struct uniphier_clk_fixed_rate_data *data)
24{
25 struct clk_fixed_rate *fixed;
26 struct clk_init_data init;
27 int ret;
28
29 /* allocate fixed-rate clock */
30 fixed = devm_kzalloc(dev, sizeof(*fixed), GFP_KERNEL);
31 if (!fixed)
32 return ERR_PTR(-ENOMEM);
33
34 init.name = name;
35 init.ops = &clk_fixed_rate_ops;
36 init.parent_names = NULL;
37 init.num_parents = 0;
38
39 fixed->fixed_rate = data->fixed_rate;
40 fixed->hw.init = &init;
41
42 ret = devm_clk_hw_register(dev, &fixed->hw);
43 if (ret)
44 return ERR_PTR(ret);
45
46 return &fixed->hw;
47}
diff --git a/drivers/clk/uniphier/clk-uniphier-gate.c b/drivers/clk/uniphier/clk-uniphier-gate.c
new file mode 100644
index 000000000000..49142d44446d
--- /dev/null
+++ b/drivers/clk/uniphier/clk-uniphier-gate.c
@@ -0,0 +1,97 @@
1/*
2 * Copyright (C) 2016 Socionext Inc.
3 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/clk-provider.h>
17#include <linux/device.h>
18#include <linux/regmap.h>
19
20#include "clk-uniphier.h"
21
22struct uniphier_clk_gate {
23 struct clk_hw hw;
24 struct regmap *regmap;
25 unsigned int reg;
26 unsigned int bit;
27};
28
29#define to_uniphier_clk_gate(_hw) \
30 container_of(_hw, struct uniphier_clk_gate, hw)
31
32static int uniphier_clk_gate_endisable(struct clk_hw *hw, int enable)
33{
34 struct uniphier_clk_gate *gate = to_uniphier_clk_gate(hw);
35
36 return regmap_write_bits(gate->regmap, gate->reg, BIT(gate->bit),
37 enable ? BIT(gate->bit) : 0);
38}
39
40static int uniphier_clk_gate_enable(struct clk_hw *hw)
41{
42 return uniphier_clk_gate_endisable(hw, 1);
43}
44
45static void uniphier_clk_gate_disable(struct clk_hw *hw)
46{
47 if (uniphier_clk_gate_endisable(hw, 0) < 0)
48 pr_warn("failed to disable clk\n");
49}
50
51static int uniphier_clk_gate_is_enabled(struct clk_hw *hw)
52{
53 struct uniphier_clk_gate *gate = to_uniphier_clk_gate(hw);
54 unsigned int val;
55
56 if (regmap_read(gate->regmap, gate->reg, &val) < 0)
57 pr_warn("is_enabled() may return wrong result\n");
58
59 return !!(val & BIT(gate->bit));
60}
61
62static const struct clk_ops uniphier_clk_gate_ops = {
63 .enable = uniphier_clk_gate_enable,
64 .disable = uniphier_clk_gate_disable,
65 .is_enabled = uniphier_clk_gate_is_enabled,
66};
67
68struct clk_hw *uniphier_clk_register_gate(struct device *dev,
69 struct regmap *regmap,
70 const char *name,
71 const struct uniphier_clk_gate_data *data)
72{
73 struct uniphier_clk_gate *gate;
74 struct clk_init_data init;
75 int ret;
76
77 gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
78 if (!gate)
79 return ERR_PTR(-ENOMEM);
80
81 init.name = name;
82 init.ops = &uniphier_clk_gate_ops;
83 init.flags = data->parent_name ? CLK_SET_RATE_PARENT : 0;
84 init.parent_names = data->parent_name ? &data->parent_name : NULL;
85 init.num_parents = data->parent_name ? 1 : 0;
86
87 gate->regmap = regmap;
88 gate->reg = data->reg;
89 gate->bit = data->bit;
90 gate->hw.init = &init;
91
92 ret = devm_clk_hw_register(dev, &gate->hw);
93 if (ret)
94 return ERR_PTR(ret);
95
96 return &gate->hw;
97}
diff --git a/drivers/clk/uniphier/clk-uniphier-mio.c b/drivers/clk/uniphier/clk-uniphier-mio.c
new file mode 100644
index 000000000000..6aa7ec768d0b
--- /dev/null
+++ b/drivers/clk/uniphier/clk-uniphier-mio.c
@@ -0,0 +1,101 @@
1/*
2 * Copyright (C) 2016 Socionext Inc.
3 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include "clk-uniphier.h"
17
18#define UNIPHIER_MIO_CLK_SD_FIXED \
19 UNIPHIER_CLK_FACTOR("sd-44m", -1, "sd-133m", 1, 3), \
20 UNIPHIER_CLK_FACTOR("sd-33m", -1, "sd-200m", 1, 6), \
21 UNIPHIER_CLK_FACTOR("sd-50m", -1, "sd-200m", 1, 4), \
22 UNIPHIER_CLK_FACTOR("sd-67m", -1, "sd-200m", 1, 3), \
23 UNIPHIER_CLK_FACTOR("sd-100m", -1, "sd-200m", 1, 2), \
24 UNIPHIER_CLK_FACTOR("sd-40m", -1, "sd-200m", 1, 5), \
25 UNIPHIER_CLK_FACTOR("sd-25m", -1, "sd-200m", 1, 8), \
26 UNIPHIER_CLK_FACTOR("sd-22m", -1, "sd-133m", 1, 6)
27
28#define UNIPHIER_MIO_CLK_SD(_idx, ch) \
29 { \
30 .name = "sd" #ch "-sel", \
31 .type = UNIPHIER_CLK_TYPE_MUX, \
32 .idx = -1, \
33 .data.mux = { \
34 .parent_names = { \
35 "sd-44m", \
36 "sd-33m", \
37 "sd-50m", \
38 "sd-67m", \
39 "sd-100m", \
40 "sd-40m", \
41 "sd-25m", \
42 "sd-22m", \
43 }, \
44 .num_parents = 8, \
45 .reg = 0x30 + 0x200 * (ch), \
46 .masks = { \
47 0x00031000, \
48 0x00031000, \
49 0x00031000, \
50 0x00031000, \
51 0x00001300, \
52 0x00001300, \
53 0x00001300, \
54 0x00001300, \
55 }, \
56 .vals = { \
57 0x00000000, \
58 0x00010000, \
59 0x00020000, \
60 0x00030000, \
61 0x00001000, \
62 0x00001100, \
63 0x00001200, \
64 0x00001300, \
65 }, \
66 }, \
67 }, \
68 UNIPHIER_CLK_GATE("sd" #ch, (_idx), "sd" #ch "-sel", 0x20 + 0x200 * (ch), 8)
69
70#define UNIPHIER_MIO_CLK_USB2(idx, ch) \
71 UNIPHIER_CLK_GATE("usb2" #ch, (idx), "usb2", 0x20 + 0x200 * (ch), 28)
72
73#define UNIPHIER_MIO_CLK_USB2_PHY(idx, ch) \
74 UNIPHIER_CLK_GATE("usb2" #ch "-phy", (idx), "usb2", 0x20 + 0x200 * (ch), 29)
75
76#define UNIPHIER_MIO_CLK_DMAC(idx) \
77 UNIPHIER_CLK_GATE("miodmac", (idx), "stdmac", 0x20, 25)
78
79const struct uniphier_clk_data uniphier_sld3_mio_clk_data[] = {
80 UNIPHIER_MIO_CLK_SD_FIXED,
81 UNIPHIER_MIO_CLK_SD(0, 0),
82 UNIPHIER_MIO_CLK_SD(1, 1),
83 UNIPHIER_MIO_CLK_SD(2, 2),
84 UNIPHIER_MIO_CLK_DMAC(7),
85 UNIPHIER_MIO_CLK_USB2(8, 0),
86 UNIPHIER_MIO_CLK_USB2(9, 1),
87 UNIPHIER_MIO_CLK_USB2(10, 2),
88 UNIPHIER_MIO_CLK_USB2(11, 3),
89 UNIPHIER_MIO_CLK_USB2_PHY(12, 0),
90 UNIPHIER_MIO_CLK_USB2_PHY(13, 1),
91 UNIPHIER_MIO_CLK_USB2_PHY(14, 2),
92 UNIPHIER_MIO_CLK_USB2_PHY(15, 3),
93 { /* sentinel */ }
94};
95
96const struct uniphier_clk_data uniphier_pro5_mio_clk_data[] = {
97 UNIPHIER_MIO_CLK_SD_FIXED,
98 UNIPHIER_MIO_CLK_SD(0, 0),
99 UNIPHIER_MIO_CLK_SD(1, 1),
100 { /* sentinel */ }
101};
diff --git a/drivers/clk/uniphier/clk-uniphier-mux.c b/drivers/clk/uniphier/clk-uniphier-mux.c
new file mode 100644
index 000000000000..15a2f2cbe0d9
--- /dev/null
+++ b/drivers/clk/uniphier/clk-uniphier-mux.c
@@ -0,0 +1,95 @@
1/*
2 * Copyright (C) 2016 Socionext Inc.
3 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/clk-provider.h>
17#include <linux/device.h>
18#include <linux/regmap.h>
19
20#include "clk-uniphier.h"
21
22struct uniphier_clk_mux {
23 struct clk_hw hw;
24 struct regmap *regmap;
25 unsigned int reg;
26 const unsigned int *masks;
27 const unsigned int *vals;
28};
29
30#define to_uniphier_clk_mux(_hw) container_of(_hw, struct uniphier_clk_mux, hw)
31
32static int uniphier_clk_mux_set_parent(struct clk_hw *hw, u8 index)
33{
34 struct uniphier_clk_mux *mux = to_uniphier_clk_mux(hw);
35
36 return regmap_write_bits(mux->regmap, mux->reg, mux->masks[index],
37 mux->vals[index]);
38}
39
40static u8 uniphier_clk_mux_get_parent(struct clk_hw *hw)
41{
42 struct uniphier_clk_mux *mux = to_uniphier_clk_mux(hw);
43 int num_parents = clk_hw_get_num_parents(hw);
44 int ret;
45 u32 val;
46 u8 i;
47
48 ret = regmap_read(mux->regmap, mux->reg, &val);
49 if (ret)
50 return ret;
51
52 for (i = 0; i < num_parents; i++)
53 if ((mux->masks[i] & val) == mux->vals[i])
54 return i;
55
56 return -EINVAL;
57}
58
59static const struct clk_ops uniphier_clk_mux_ops = {
60 .determine_rate = __clk_mux_determine_rate,
61 .set_parent = uniphier_clk_mux_set_parent,
62 .get_parent = uniphier_clk_mux_get_parent,
63};
64
65struct clk_hw *uniphier_clk_register_mux(struct device *dev,
66 struct regmap *regmap,
67 const char *name,
68 const struct uniphier_clk_mux_data *data)
69{
70 struct uniphier_clk_mux *mux;
71 struct clk_init_data init;
72 int ret;
73
74 mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
75 if (!mux)
76 return ERR_PTR(-ENOMEM);
77
78 init.name = name;
79 init.ops = &uniphier_clk_mux_ops;
80 init.flags = CLK_SET_RATE_PARENT;
81 init.parent_names = data->parent_names;
82 init.num_parents = data->num_parents,
83
84 mux->regmap = regmap;
85 mux->reg = data->reg;
86 mux->masks = data->masks;
87 mux->vals = data->vals;
88 mux->hw.init = &init;
89
90 ret = devm_clk_hw_register(dev, &mux->hw);
91 if (ret)
92 return ERR_PTR(ret);
93
94 return &mux->hw;
95}
diff --git a/drivers/clk/uniphier/clk-uniphier-peri.c b/drivers/clk/uniphier/clk-uniphier-peri.c
new file mode 100644
index 000000000000..521c80e9a06f
--- /dev/null
+++ b/drivers/clk/uniphier/clk-uniphier-peri.c
@@ -0,0 +1,57 @@
1/*
2 * Copyright (C) 2016 Socionext Inc.
3 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include "clk-uniphier.h"
17
18#define UNIPHIER_PERI_CLK_UART(idx, ch) \
19 UNIPHIER_CLK_GATE("uart" #ch, (idx), "uart", 0x24, 19 + (ch))
20
21#define UNIPHIER_PERI_CLK_I2C_COMMON \
22 UNIPHIER_CLK_GATE("i2c-common", -1, "i2c", 0x20, 1)
23
24#define UNIPHIER_PERI_CLK_I2C(idx, ch) \
25 UNIPHIER_CLK_GATE("i2c" #ch, (idx), "i2c-common", 0x24, 5 + (ch))
26
27#define UNIPHIER_PERI_CLK_FI2C(idx, ch) \
28 UNIPHIER_CLK_GATE("i2c" #ch, (idx), "i2c", 0x24, 24 + (ch))
29
30const struct uniphier_clk_data uniphier_ld4_peri_clk_data[] = {
31 UNIPHIER_PERI_CLK_UART(0, 0),
32 UNIPHIER_PERI_CLK_UART(1, 1),
33 UNIPHIER_PERI_CLK_UART(2, 2),
34 UNIPHIER_PERI_CLK_UART(3, 3),
35 UNIPHIER_PERI_CLK_I2C_COMMON,
36 UNIPHIER_PERI_CLK_I2C(4, 0),
37 UNIPHIER_PERI_CLK_I2C(5, 1),
38 UNIPHIER_PERI_CLK_I2C(6, 2),
39 UNIPHIER_PERI_CLK_I2C(7, 3),
40 UNIPHIER_PERI_CLK_I2C(8, 4),
41 { /* sentinel */ }
42};
43
44const struct uniphier_clk_data uniphier_pro4_peri_clk_data[] = {
45 UNIPHIER_PERI_CLK_UART(0, 0),
46 UNIPHIER_PERI_CLK_UART(1, 1),
47 UNIPHIER_PERI_CLK_UART(2, 2),
48 UNIPHIER_PERI_CLK_UART(3, 3),
49 UNIPHIER_PERI_CLK_FI2C(4, 0),
50 UNIPHIER_PERI_CLK_FI2C(5, 1),
51 UNIPHIER_PERI_CLK_FI2C(6, 2),
52 UNIPHIER_PERI_CLK_FI2C(7, 3),
53 UNIPHIER_PERI_CLK_FI2C(8, 4),
54 UNIPHIER_PERI_CLK_FI2C(9, 5),
55 UNIPHIER_PERI_CLK_FI2C(10, 6),
56 { /* sentinel */ }
57};
diff --git a/drivers/clk/uniphier/clk-uniphier-sys.c b/drivers/clk/uniphier/clk-uniphier-sys.c
new file mode 100644
index 000000000000..5d029991047d
--- /dev/null
+++ b/drivers/clk/uniphier/clk-uniphier-sys.c
@@ -0,0 +1,151 @@
1/*
2 * Copyright (C) 2016 Socionext Inc.
3 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/stddef.h>
17
18#include "clk-uniphier.h"
19
20#define UNIPHIER_SLD3_SYS_CLK_SD \
21 UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 8), \
22 UNIPHIER_CLK_FACTOR("sd-133m", -1, "vpll27a", 1, 2)
23
24#define UNIPHIER_PRO5_SYS_CLK_SD \
25 UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 12), \
26 UNIPHIER_CLK_FACTOR("sd-133m", -1, "spll", 1, 18)
27
28#define UNIPHIER_LD20_SYS_CLK_SD \
29 UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 10), \
30 UNIPHIER_CLK_FACTOR("sd-133m", -1, "spll", 1, 15)
31
32#define UNIPHIER_SLD3_SYS_CLK_STDMAC(idx) \
33 UNIPHIER_CLK_GATE("stdmac", (idx), NULL, 0x2104, 10)
34
35#define UNIPHIER_LD11_SYS_CLK_STDMAC(idx) \
36 UNIPHIER_CLK_GATE("stdmac", (idx), NULL, 0x210c, 8)
37
38#define UNIPHIER_PRO4_SYS_CLK_GIO(idx) \
39 UNIPHIER_CLK_GATE("gio", (idx), NULL, 0x2104, 6)
40
41#define UNIPHIER_PRO4_SYS_CLK_USB3(idx, ch) \
42 UNIPHIER_CLK_GATE("usb3" #ch, (idx), NULL, 0x2104, 16 + (ch))
43
44const struct uniphier_clk_data uniphier_sld3_sys_clk_data[] = {
45 UNIPHIER_CLK_FACTOR("spll", -1, "ref", 65, 1), /* 1597.44 MHz */
46 UNIPHIER_CLK_FACTOR("upll", -1, "ref", 6000, 512), /* 288 MHz */
47 UNIPHIER_CLK_FACTOR("a2pll", -1, "ref", 24, 1), /* 589.824 MHz */
48 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */
49 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16),
50 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16),
51 UNIPHIER_SLD3_SYS_CLK_SD,
52 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12),
53 UNIPHIER_SLD3_SYS_CLK_STDMAC(8),
54 { /* sentinel */ }
55};
56
57const struct uniphier_clk_data uniphier_ld4_sys_clk_data[] = {
58 UNIPHIER_CLK_FACTOR("spll", -1, "ref", 65, 1), /* 1597.44 MHz */
59 UNIPHIER_CLK_FACTOR("upll", -1, "ref", 6000, 512), /* 288 MHz */
60 UNIPHIER_CLK_FACTOR("a2pll", -1, "ref", 24, 1), /* 589.824 MHz */
61 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */
62 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16),
63 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16),
64 UNIPHIER_SLD3_SYS_CLK_SD,
65 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12),
66 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */
67 { /* sentinel */ }
68};
69
70const struct uniphier_clk_data uniphier_pro4_sys_clk_data[] = {
71 UNIPHIER_CLK_FACTOR("spll", -1, "ref", 64, 1), /* 1600 MHz */
72 UNIPHIER_CLK_FACTOR("upll", -1, "ref", 288, 25), /* 288 MHz */
73 UNIPHIER_CLK_FACTOR("a2pll", -1, "upll", 256, 125), /* 589.824 MHz */
74 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */
75 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 8),
76 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 32),
77 UNIPHIER_SLD3_SYS_CLK_SD,
78 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12),
79 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC, MIO, RLE */
80 UNIPHIER_PRO4_SYS_CLK_GIO(12), /* Ether, SATA, USB3 */
81 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0),
82 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1),
83 { /* sentinel */ }
84};
85
86const struct uniphier_clk_data uniphier_sld8_sys_clk_data[] = {
87 UNIPHIER_CLK_FACTOR("spll", -1, "ref", 64, 1), /* 1600 MHz */
88 UNIPHIER_CLK_FACTOR("upll", -1, "ref", 288, 25), /* 288 MHz */
89 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */
90 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 20),
91 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16),
92 UNIPHIER_SLD3_SYS_CLK_SD,
93 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12),
94 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */
95 { /* sentinel */ }
96};
97
98const struct uniphier_clk_data uniphier_pro5_sys_clk_data[] = {
99 UNIPHIER_CLK_FACTOR("spll", -1, "ref", 120, 1), /* 2400 MHz */
100 UNIPHIER_CLK_FACTOR("dapll1", -1, "ref", 128, 1), /* 2560 MHz */
101 UNIPHIER_CLK_FACTOR("dapll2", -1, "ref", 144, 125), /* 2949.12 MHz */
102 UNIPHIER_CLK_FACTOR("uart", 0, "dapll2", 1, 40),
103 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48),
104 UNIPHIER_PRO5_SYS_CLK_SD,
105 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC */
106 UNIPHIER_PRO4_SYS_CLK_GIO(12), /* PCIe, USB3 */
107 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0),
108 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1),
109 { /* sentinel */ }
110};
111
112const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] = {
113 UNIPHIER_CLK_FACTOR("spll", -1, "ref", 96, 1), /* 2400 MHz */
114 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 27),
115 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48),
116 UNIPHIER_PRO5_SYS_CLK_SD,
117 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC, RLE */
118 /* GIO is always clock-enabled: no function for 0x2104 bit6 */
119 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0),
120 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1),
121 /* The document mentions 0x2104 bit 18, but not functional */
122 UNIPHIER_CLK_GATE("usb30-phy", 16, NULL, 0x2104, 19),
123 UNIPHIER_CLK_GATE("usb31-phy", 20, NULL, 0x2104, 20),
124 { /* sentinel */ }
125};
126
127const struct uniphier_clk_data uniphier_ld11_sys_clk_data[] = {
128 UNIPHIER_CLK_FACTOR("spll", -1, "ref", 80, 1), /* 2000 MHz */
129 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34),
130 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40),
131 UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC, MIO */
132 UNIPHIER_CLK_FACTOR("usb2", -1, "ref", 24, 25),
133 { /* sentinel */ }
134};
135
136const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = {
137 UNIPHIER_CLK_FACTOR("spll", -1, "ref", 80, 1), /* 2000 MHz */
138 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34),
139 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40),
140 UNIPHIER_LD20_SYS_CLK_SD,
141 UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC */
142 /* GIO is always clock-enabled: no function for 0x210c bit5 */
143 /*
144 * clock for USB Link is enabled by the logic "OR" of bit 14 and bit 15.
145 * We do not use bit 15 here.
146 */
147 UNIPHIER_CLK_GATE("usb30", 14, NULL, 0x210c, 14),
148 UNIPHIER_CLK_GATE("usb30-phy0", 16, NULL, 0x210c, 12),
149 UNIPHIER_CLK_GATE("usb30-phy1", 17, NULL, 0x210c, 13),
150 { /* sentinel */ }
151};
diff --git a/drivers/clk/uniphier/clk-uniphier.h b/drivers/clk/uniphier/clk-uniphier.h
new file mode 100644
index 000000000000..3ae184062388
--- /dev/null
+++ b/drivers/clk/uniphier/clk-uniphier.h
@@ -0,0 +1,122 @@
1/*
2 * Copyright (C) 2016 Socionext Inc.
3 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef __CLK_UNIPHIER_H__
17#define __CLK_UNIPHIER_H__
18
19struct clk_hw;
20struct device;
21struct regmap;
22
23#define UNIPHIER_CLK_MUX_MAX_PARENTS 8
24
25enum uniphier_clk_type {
26 UNIPHIER_CLK_TYPE_FIXED_FACTOR,
27 UNIPHIER_CLK_TYPE_FIXED_RATE,
28 UNIPHIER_CLK_TYPE_GATE,
29 UNIPHIER_CLK_TYPE_MUX,
30};
31
32struct uniphier_clk_fixed_factor_data {
33 const char *parent_name;
34 unsigned int mult;
35 unsigned int div;
36};
37
38struct uniphier_clk_fixed_rate_data {
39 unsigned long fixed_rate;
40};
41
42struct uniphier_clk_gate_data {
43 const char *parent_name;
44 unsigned int reg;
45 unsigned int bit;
46};
47
48struct uniphier_clk_mux_data {
49 const char *parent_names[UNIPHIER_CLK_MUX_MAX_PARENTS];
50 unsigned int num_parents;
51 unsigned int reg;
52 unsigned int masks[UNIPHIER_CLK_MUX_MAX_PARENTS];
53 unsigned int vals[UNIPHIER_CLK_MUX_MAX_PARENTS];
54};
55
56struct uniphier_clk_data {
57 const char *name;
58 enum uniphier_clk_type type;
59 int idx;
60 union {
61 struct uniphier_clk_fixed_factor_data factor;
62 struct uniphier_clk_fixed_rate_data rate;
63 struct uniphier_clk_gate_data gate;
64 struct uniphier_clk_mux_data mux;
65 } data;
66};
67
68#define UNIPHIER_CLK_FACTOR(_name, _idx, _parent, _mult, _div) \
69 { \
70 .name = (_name), \
71 .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR, \
72 .idx = (_idx), \
73 .data.factor = { \
74 .parent_name = (_parent), \
75 .mult = (_mult), \
76 .div = (_div), \
77 }, \
78 }
79
80
81#define UNIPHIER_CLK_GATE(_name, _idx, _parent, _reg, _bit) \
82 { \
83 .name = (_name), \
84 .type = UNIPHIER_CLK_TYPE_GATE, \
85 .idx = (_idx), \
86 .data.gate = { \
87 .parent_name = (_parent), \
88 .reg = (_reg), \
89 .bit = (_bit), \
90 }, \
91 }
92
93
94struct clk_hw *uniphier_clk_register_fixed_factor(struct device *dev,
95 const char *name,
96 const struct uniphier_clk_fixed_factor_data *data);
97struct clk_hw *uniphier_clk_register_fixed_rate(struct device *dev,
98 const char *name,
99 const struct uniphier_clk_fixed_rate_data *data);
100struct clk_hw *uniphier_clk_register_gate(struct device *dev,
101 struct regmap *regmap,
102 const char *name,
103 const struct uniphier_clk_gate_data *data);
104struct clk_hw *uniphier_clk_register_mux(struct device *dev,
105 struct regmap *regmap,
106 const char *name,
107 const struct uniphier_clk_mux_data *data);
108
109extern const struct uniphier_clk_data uniphier_sld3_sys_clk_data[];
110extern const struct uniphier_clk_data uniphier_ld4_sys_clk_data[];
111extern const struct uniphier_clk_data uniphier_pro4_sys_clk_data[];
112extern const struct uniphier_clk_data uniphier_sld8_sys_clk_data[];
113extern const struct uniphier_clk_data uniphier_pro5_sys_clk_data[];
114extern const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[];
115extern const struct uniphier_clk_data uniphier_ld11_sys_clk_data[];
116extern const struct uniphier_clk_data uniphier_ld20_sys_clk_data[];
117extern const struct uniphier_clk_data uniphier_sld3_mio_clk_data[];
118extern const struct uniphier_clk_data uniphier_pro5_mio_clk_data[];
119extern const struct uniphier_clk_data uniphier_ld4_peri_clk_data[];
120extern const struct uniphier_clk_data uniphier_pro4_peri_clk_data[];
121
122#endif /* __CLK_UNIPHIER_H__ */
diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c
index 5e9b65278e4c..4faa94440779 100644
--- a/drivers/clk/versatile/clk-icst.c
+++ b/drivers/clk/versatile/clk-icst.c
@@ -27,6 +27,26 @@
27/* Magic unlocking token used on all Versatile boards */ 27/* Magic unlocking token used on all Versatile boards */
28#define VERSATILE_LOCK_VAL 0xA05F 28#define VERSATILE_LOCK_VAL 0xA05F
29 29
30#define VERSATILE_AUX_OSC_BITS 0x7FFFF
31#define INTEGRATOR_AP_CM_BITS 0xFF
32#define INTEGRATOR_AP_SYS_BITS 0xFF
33#define INTEGRATOR_CP_CM_CORE_BITS 0x7FF
34#define INTEGRATOR_CP_CM_MEM_BITS 0x7FF000
35
36#define INTEGRATOR_AP_PCI_25_33_MHZ BIT(8)
37
38/**
39 * enum icst_control_type - the type of ICST control register
40 */
41enum icst_control_type {
42 ICST_VERSATILE, /* The standard type, all control bits available */
43 ICST_INTEGRATOR_AP_CM, /* Only 8 bits of VDW available */
44 ICST_INTEGRATOR_AP_SYS, /* Only 8 bits of VDW available */
45 ICST_INTEGRATOR_AP_PCI, /* Odd bit pattern storage */
46 ICST_INTEGRATOR_CP_CM_CORE, /* Only 8 bits of VDW and 3 bits of OD */
47 ICST_INTEGRATOR_CP_CM_MEM, /* Only 8 bits of VDW and 3 bits of OD */
48};
49
30/** 50/**
31 * struct clk_icst - ICST VCO clock wrapper 51 * struct clk_icst - ICST VCO clock wrapper
32 * @hw: corresponding clock hardware entry 52 * @hw: corresponding clock hardware entry
@@ -34,6 +54,7 @@
34 * @lockreg: VCO lock register address 54 * @lockreg: VCO lock register address
35 * @params: parameters for this ICST instance 55 * @params: parameters for this ICST instance
36 * @rate: current rate 56 * @rate: current rate
57 * @ctype: the type of control register for the ICST
37 */ 58 */
38struct clk_icst { 59struct clk_icst {
39 struct clk_hw hw; 60 struct clk_hw hw;
@@ -42,6 +63,7 @@ struct clk_icst {
42 u32 lockreg_off; 63 u32 lockreg_off;
43 struct icst_params *params; 64 struct icst_params *params;
44 unsigned long rate; 65 unsigned long rate;
66 enum icst_control_type ctype;
45}; 67};
46 68
47#define to_icst(_hw) container_of(_hw, struct clk_icst, hw) 69#define to_icst(_hw) container_of(_hw, struct clk_icst, hw)
@@ -59,6 +81,76 @@ static int vco_get(struct clk_icst *icst, struct icst_vco *vco)
59 ret = regmap_read(icst->map, icst->vcoreg_off, &val); 81 ret = regmap_read(icst->map, icst->vcoreg_off, &val);
60 if (ret) 82 if (ret)
61 return ret; 83 return ret;
84
85 /*
86 * The Integrator/AP core clock can only access the low eight
87 * bits of the v PLL divider. Bit 8 is tied low and always zero,
88 * r is hardwired to 22 and output divider s is hardwired to 1
89 * (divide by 2) according to the document
90 * "Integrator CM926EJ-S, CM946E-S, CM966E-S, CM1026EJ-S and
91 * CM1136JF-S User Guide" ARM DUI 0138E, page 3-13 thru 3-14.
92 */
93 if (icst->ctype == ICST_INTEGRATOR_AP_CM) {
94 vco->v = val & INTEGRATOR_AP_CM_BITS;
95 vco->r = 22;
96 vco->s = 1;
97 return 0;
98 }
99
100 /*
101 * The Integrator/AP system clock on the base board can only
102 * access the low eight bits of the v PLL divider. Bit 8 is tied low
103 * and always zero, r is hardwired to 46, and the output divider is
104 * hardwired to 3 (divide by 4) according to the document
105 * "Integrator AP ASIC Development Motherboard" ARM DUI 0098B,
106 * page 3-16.
107 */
108 if (icst->ctype == ICST_INTEGRATOR_AP_SYS) {
109 vco->v = val & INTEGRATOR_AP_SYS_BITS;
110 vco->r = 46;
111 vco->s = 3;
112 return 0;
113 }
114
115 /*
116 * The Integrator/AP PCI clock is using an odd pattern to create
117 * the child clock, basically a single bit called DIVX/Y is used
118 * to select between two different hardwired values: setting the
119 * bit to 0 yields v = 17, r = 22 and OD = 1, whereas setting the
120 * bit to 1 yields v = 14, r = 14 and OD = 1 giving the frequencies
121 * 33 or 25 MHz respectively.
122 */
123 if (icst->ctype == ICST_INTEGRATOR_AP_PCI) {
124 bool divxy = !!(val & INTEGRATOR_AP_PCI_25_33_MHZ);
125
126 vco->v = divxy ? 17 : 14;
127 vco->r = divxy ? 22 : 14;
128 vco->s = 1;
129 return 0;
130 }
131
132 /*
133 * The Integrator/CP core clock can access the low eight bits
134 * of the v PLL divider. Bit 8 is tied low and always zero,
135 * r is hardwired to 22 and the output divider s is accessible
136 * in bits 8 thru 10 according to the document
137 * "Integrator/CM940T, CM920T, CM740T, and CM720T User Guide"
138 * ARM DUI 0157A, page 3-20 thru 3-23 and 4-10.
139 */
140 if (icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) {
141 vco->v = val & 0xFF;
142 vco->r = 22;
143 vco->s = (val >> 8) & 7;
144 return 0;
145 }
146
147 if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) {
148 vco->v = (val >> 12) & 0xFF;
149 vco->r = 22;
150 vco->s = (val >> 20) & 7;
151 return 0;
152 }
153
62 vco->v = val & 0x1ff; 154 vco->v = val & 0x1ff;
63 vco->r = (val >> 9) & 0x7f; 155 vco->r = (val >> 9) & 0x7f;
64 vco->s = (val >> 16) & 03; 156 vco->s = (val >> 16) & 03;
@@ -72,22 +164,62 @@ static int vco_get(struct clk_icst *icst, struct icst_vco *vco)
72 */ 164 */
73static int vco_set(struct clk_icst *icst, struct icst_vco vco) 165static int vco_set(struct clk_icst *icst, struct icst_vco vco)
74{ 166{
167 u32 mask;
75 u32 val; 168 u32 val;
76 int ret; 169 int ret;
77 170
78 ret = regmap_read(icst->map, icst->vcoreg_off, &val); 171 /* Mask the bits used by the VCO */
79 if (ret) 172 switch (icst->ctype) {
80 return ret; 173 case ICST_INTEGRATOR_AP_CM:
174 mask = INTEGRATOR_AP_CM_BITS;
175 val = vco.v & 0xFF;
176 if (vco.v & 0x100)
177 pr_err("ICST error: tried to set bit 8 of VDW\n");
178 if (vco.s != 1)
179 pr_err("ICST error: tried to use VOD != 1\n");
180 if (vco.r != 22)
181 pr_err("ICST error: tried to use RDW != 22\n");
182 break;
183 case ICST_INTEGRATOR_AP_SYS:
184 mask = INTEGRATOR_AP_SYS_BITS;
185 val = vco.v & 0xFF;
186 if (vco.v & 0x100)
187 pr_err("ICST error: tried to set bit 8 of VDW\n");
188 if (vco.s != 3)
189 pr_err("ICST error: tried to use VOD != 1\n");
190 if (vco.r != 46)
191 pr_err("ICST error: tried to use RDW != 22\n");
192 break;
193 case ICST_INTEGRATOR_CP_CM_CORE:
194 mask = INTEGRATOR_CP_CM_CORE_BITS; /* Uses 12 bits */
195 val = (vco.v & 0xFF) | vco.s << 8;
196 if (vco.v & 0x100)
197 pr_err("ICST error: tried to set bit 8 of VDW\n");
198 if (vco.r != 22)
199 pr_err("ICST error: tried to use RDW != 22\n");
200 break;
201 case ICST_INTEGRATOR_CP_CM_MEM:
202 mask = INTEGRATOR_CP_CM_MEM_BITS; /* Uses 12 bits */
203 val = ((vco.v & 0xFF) << 12) | (vco.s << 20);
204 if (vco.v & 0x100)
205 pr_err("ICST error: tried to set bit 8 of VDW\n");
206 if (vco.r != 22)
207 pr_err("ICST error: tried to use RDW != 22\n");
208 break;
209 default:
210 /* Regular auxilary oscillator */
211 mask = VERSATILE_AUX_OSC_BITS;
212 val = vco.v | (vco.r << 9) | (vco.s << 16);
213 break;
214 }
81 215
82 /* Mask the 18 bits used by the VCO */ 216 pr_debug("ICST: new val = 0x%08x\n", val);
83 val &= ~0x7ffff;
84 val |= vco.v | (vco.r << 9) | (vco.s << 16);
85 217
86 /* This magic unlocks the VCO so it can be controlled */ 218 /* This magic unlocks the VCO so it can be controlled */
87 ret = regmap_write(icst->map, icst->lockreg_off, VERSATILE_LOCK_VAL); 219 ret = regmap_write(icst->map, icst->lockreg_off, VERSATILE_LOCK_VAL);
88 if (ret) 220 if (ret)
89 return ret; 221 return ret;
90 ret = regmap_write(icst->map, icst->vcoreg_off, val); 222 ret = regmap_update_bits(icst->map, icst->vcoreg_off, mask, val);
91 if (ret) 223 if (ret)
92 return ret; 224 return ret;
93 /* This locks the VCO again */ 225 /* This locks the VCO again */
@@ -121,6 +253,46 @@ static long icst_round_rate(struct clk_hw *hw, unsigned long rate,
121 struct clk_icst *icst = to_icst(hw); 253 struct clk_icst *icst = to_icst(hw);
122 struct icst_vco vco; 254 struct icst_vco vco;
123 255
256 if (icst->ctype == ICST_INTEGRATOR_AP_CM ||
257 icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) {
258 if (rate <= 12000000)
259 return 12000000;
260 if (rate >= 160000000)
261 return 160000000;
262 /* Slam to closest megahertz */
263 return DIV_ROUND_CLOSEST(rate, 1000000) * 1000000;
264 }
265
266 if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) {
267 if (rate <= 6000000)
268 return 6000000;
269 if (rate >= 66000000)
270 return 66000000;
271 /* Slam to closest 0.5 megahertz */
272 return DIV_ROUND_CLOSEST(rate, 500000) * 500000;
273 }
274
275 if (icst->ctype == ICST_INTEGRATOR_AP_SYS) {
276 /* Divides between 3 and 50 MHz in steps of 0.25 MHz */
277 if (rate <= 3000000)
278 return 3000000;
279 if (rate >= 50000000)
280 return 5000000;
281 /* Slam to closest 0.25 MHz */
282 return DIV_ROUND_CLOSEST(rate, 250000) * 250000;
283 }
284
285 if (icst->ctype == ICST_INTEGRATOR_AP_PCI) {
286 /*
287 * If we're below or less than halfway from 25 to 33 MHz
288 * select 25 MHz
289 */
290 if (rate <= 25000000 || rate < 29000000)
291 return 25000000;
292 /* Else just return the default frequency */
293 return 33000000;
294 }
295
124 vco = icst_hz_to_vco(icst->params, rate); 296 vco = icst_hz_to_vco(icst->params, rate);
125 return icst_hz(icst->params, vco); 297 return icst_hz(icst->params, vco);
126} 298}
@@ -131,6 +303,36 @@ static int icst_set_rate(struct clk_hw *hw, unsigned long rate,
131 struct clk_icst *icst = to_icst(hw); 303 struct clk_icst *icst = to_icst(hw);
132 struct icst_vco vco; 304 struct icst_vco vco;
133 305
306 if (icst->ctype == ICST_INTEGRATOR_AP_PCI) {
307 /* This clock is especially primitive */
308 unsigned int val;
309 int ret;
310
311 if (rate == 25000000) {
312 val = 0;
313 } else if (rate == 33000000) {
314 val = INTEGRATOR_AP_PCI_25_33_MHZ;
315 } else {
316 pr_err("ICST: cannot set PCI frequency %lu\n",
317 rate);
318 return -EINVAL;
319 }
320 ret = regmap_write(icst->map, icst->lockreg_off,
321 VERSATILE_LOCK_VAL);
322 if (ret)
323 return ret;
324 ret = regmap_update_bits(icst->map, icst->vcoreg_off,
325 INTEGRATOR_AP_PCI_25_33_MHZ,
326 val);
327 if (ret)
328 return ret;
329 /* This locks the VCO again */
330 ret = regmap_write(icst->map, icst->lockreg_off, 0);
331 if (ret)
332 return ret;
333 return 0;
334 }
335
134 if (parent_rate) 336 if (parent_rate)
135 icst->params->ref = parent_rate; 337 icst->params->ref = parent_rate;
136 vco = icst_hz_to_vco(icst->params, rate); 338 vco = icst_hz_to_vco(icst->params, rate);
@@ -148,7 +350,8 @@ static struct clk *icst_clk_setup(struct device *dev,
148 const struct clk_icst_desc *desc, 350 const struct clk_icst_desc *desc,
149 const char *name, 351 const char *name,
150 const char *parent_name, 352 const char *parent_name,
151 struct regmap *map) 353 struct regmap *map,
354 enum icst_control_type ctype)
152{ 355{
153 struct clk *clk; 356 struct clk *clk;
154 struct clk_icst *icst; 357 struct clk_icst *icst;
@@ -178,6 +381,7 @@ static struct clk *icst_clk_setup(struct device *dev,
178 icst->params = pclone; 381 icst->params = pclone;
179 icst->vcoreg_off = desc->vco_offset; 382 icst->vcoreg_off = desc->vco_offset;
180 icst->lockreg_off = desc->lock_offset; 383 icst->lockreg_off = desc->lock_offset;
384 icst->ctype = ctype;
181 385
182 clk = clk_register(dev, &icst->hw); 386 clk = clk_register(dev, &icst->hw);
183 if (IS_ERR(clk)) { 387 if (IS_ERR(clk)) {
@@ -206,7 +410,8 @@ struct clk *icst_clk_register(struct device *dev,
206 pr_err("could not initialize ICST regmap\n"); 410 pr_err("could not initialize ICST regmap\n");
207 return ERR_CAST(map); 411 return ERR_CAST(map);
208 } 412 }
209 return icst_clk_setup(dev, desc, name, parent_name, map); 413 return icst_clk_setup(dev, desc, name, parent_name, map,
414 ICST_VERSATILE);
210} 415}
211EXPORT_SYMBOL_GPL(icst_clk_register); 416EXPORT_SYMBOL_GPL(icst_clk_register);
212 417
@@ -239,6 +444,56 @@ static const struct icst_params icst307_params = {
239 .idx2s = icst307_idx2s, 444 .idx2s = icst307_idx2s,
240}; 445};
241 446
447/**
448 * The core modules on the Integrator/AP and Integrator/CP have
449 * especially crippled ICST525 control.
450 */
451static const struct icst_params icst525_apcp_cm_params = {
452 .vco_max = ICST525_VCO_MAX_5V,
453 .vco_min = ICST525_VCO_MIN,
454 /* Minimum 12 MHz, VDW = 4 */
455 .vd_min = 12,
456 /*
457 * Maximum 160 MHz, VDW = 152 for all core modules, but
458 * CM926EJ-S, CM1026EJ-S and CM1136JF-S can actually
459 * go to 200 MHz (max VDW = 192).
460 */
461 .vd_max = 192,
462 /* r is hardcoded to 22 and this is the actual divisor, +2 */
463 .rd_min = 24,
464 .rd_max = 24,
465 .s2div = icst525_s2div,
466 .idx2s = icst525_idx2s,
467};
468
469static const struct icst_params icst525_ap_sys_params = {
470 .vco_max = ICST525_VCO_MAX_5V,
471 .vco_min = ICST525_VCO_MIN,
472 /* Minimum 3 MHz, VDW = 4 */
473 .vd_min = 3,
474 /* Maximum 50 MHz, VDW = 192 */
475 .vd_max = 50,
476 /* r is hardcoded to 46 and this is the actual divisor, +2 */
477 .rd_min = 48,
478 .rd_max = 48,
479 .s2div = icst525_s2div,
480 .idx2s = icst525_idx2s,
481};
482
483static const struct icst_params icst525_ap_pci_params = {
484 .vco_max = ICST525_VCO_MAX_5V,
485 .vco_min = ICST525_VCO_MIN,
486 /* Minimum 25 MHz */
487 .vd_min = 25,
488 /* Maximum 33 MHz */
489 .vd_max = 33,
490 /* r is hardcoded to 14 or 22 and this is the actual divisors +2 */
491 .rd_min = 16,
492 .rd_max = 24,
493 .s2div = icst525_s2div,
494 .idx2s = icst525_idx2s,
495};
496
242static void __init of_syscon_icst_setup(struct device_node *np) 497static void __init of_syscon_icst_setup(struct device_node *np)
243{ 498{
244 struct device_node *parent; 499 struct device_node *parent;
@@ -247,6 +502,7 @@ static void __init of_syscon_icst_setup(struct device_node *np)
247 const char *name = np->name; 502 const char *name = np->name;
248 const char *parent_name; 503 const char *parent_name;
249 struct clk *regclk; 504 struct clk *regclk;
505 enum icst_control_type ctype;
250 506
251 /* We do not release this reference, we are using it perpetually */ 507 /* We do not release this reference, we are using it perpetually */
252 parent = of_get_parent(np); 508 parent = of_get_parent(np);
@@ -269,11 +525,28 @@ static void __init of_syscon_icst_setup(struct device_node *np)
269 return; 525 return;
270 } 526 }
271 527
272 if (of_device_is_compatible(np, "arm,syscon-icst525")) 528 if (of_device_is_compatible(np, "arm,syscon-icst525")) {
273 icst_desc.params = &icst525_params; 529 icst_desc.params = &icst525_params;
274 else if (of_device_is_compatible(np, "arm,syscon-icst307")) 530 ctype = ICST_VERSATILE;
531 } else if (of_device_is_compatible(np, "arm,syscon-icst307")) {
275 icst_desc.params = &icst307_params; 532 icst_desc.params = &icst307_params;
276 else { 533 ctype = ICST_VERSATILE;
534 } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-cm")) {
535 icst_desc.params = &icst525_apcp_cm_params;
536 ctype = ICST_INTEGRATOR_AP_CM;
537 } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-sys")) {
538 icst_desc.params = &icst525_ap_sys_params;
539 ctype = ICST_INTEGRATOR_AP_SYS;
540 } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-pci")) {
541 icst_desc.params = &icst525_ap_pci_params;
542 ctype = ICST_INTEGRATOR_AP_PCI;
543 } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorcp-cm-core")) {
544 icst_desc.params = &icst525_apcp_cm_params;
545 ctype = ICST_INTEGRATOR_CP_CM_CORE;
546 } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorcp-cm-mem")) {
547 icst_desc.params = &icst525_apcp_cm_params;
548 ctype = ICST_INTEGRATOR_CP_CM_MEM;
549 } else {
277 pr_err("unknown ICST clock %s\n", name); 550 pr_err("unknown ICST clock %s\n", name);
278 return; 551 return;
279 } 552 }
@@ -281,7 +554,7 @@ static void __init of_syscon_icst_setup(struct device_node *np)
281 /* Parent clock name is not the same as node parent */ 554 /* Parent clock name is not the same as node parent */
282 parent_name = of_clk_get_parent_name(np, 0); 555 parent_name = of_clk_get_parent_name(np, 0);
283 556
284 regclk = icst_clk_setup(NULL, &icst_desc, name, parent_name, map); 557 regclk = icst_clk_setup(NULL, &icst_desc, name, parent_name, map, ctype);
285 if (IS_ERR(regclk)) { 558 if (IS_ERR(regclk)) {
286 pr_err("error setting up syscon ICST clock %s\n", name); 559 pr_err("error setting up syscon ICST clock %s\n", name);
287 return; 560 return;
@@ -294,5 +567,14 @@ CLK_OF_DECLARE(arm_syscon_icst525_clk,
294 "arm,syscon-icst525", of_syscon_icst_setup); 567 "arm,syscon-icst525", of_syscon_icst_setup);
295CLK_OF_DECLARE(arm_syscon_icst307_clk, 568CLK_OF_DECLARE(arm_syscon_icst307_clk,
296 "arm,syscon-icst307", of_syscon_icst_setup); 569 "arm,syscon-icst307", of_syscon_icst_setup);
297 570CLK_OF_DECLARE(arm_syscon_integratorap_cm_clk,
571 "arm,syscon-icst525-integratorap-cm", of_syscon_icst_setup);
572CLK_OF_DECLARE(arm_syscon_integratorap_sys_clk,
573 "arm,syscon-icst525-integratorap-sys", of_syscon_icst_setup);
574CLK_OF_DECLARE(arm_syscon_integratorap_pci_clk,
575 "arm,syscon-icst525-integratorap-pci", of_syscon_icst_setup);
576CLK_OF_DECLARE(arm_syscon_integratorcp_cm_core_clk,
577 "arm,syscon-icst525-integratorcp-cm-core", of_syscon_icst_setup);
578CLK_OF_DECLARE(arm_syscon_integratorcp_cm_mem_clk,
579 "arm,syscon-icst525-integratorcp-cm-mem", of_syscon_icst_setup);
298#endif 580#endif
diff --git a/drivers/clk/zte/Makefile b/drivers/clk/zte/Makefile
index 74005aa322a2..83374bfc4c07 100644
--- a/drivers/clk/zte/Makefile
+++ b/drivers/clk/zte/Makefile
@@ -1,2 +1,3 @@
1obj-y := clk.o 1obj-y := clk.o
2obj-$(CONFIG_SOC_ZX296702) += clk-zx296702.o 2obj-$(CONFIG_SOC_ZX296702) += clk-zx296702.o
3obj-$(CONFIG_ARCH_ZX) += clk-zx296718.o
diff --git a/drivers/clk/zte/clk-zx296718.c b/drivers/clk/zte/clk-zx296718.c
new file mode 100644
index 000000000000..707d62956e9b
--- /dev/null
+++ b/drivers/clk/zte/clk-zx296718.c
@@ -0,0 +1,924 @@
1/*
2 * Copyright (C) 2015 - 2016 ZTE Corporation.
3 * Copyright (C) 2016 Linaro Ltd.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#include <linux/clk-provider.h>
10#include <linux/device.h>
11#include <linux/kernel.h>
12#include <linux/of_address.h>
13#include <linux/of_device.h>
14#include <linux/platform_device.h>
15
16#include <dt-bindings/clock/zx296718-clock.h>
17#include "clk.h"
18
19/* TOP CRM */
20#define TOP_CLK_MUX0 0x04
21#define TOP_CLK_MUX1 0x08
22#define TOP_CLK_MUX2 0x0c
23#define TOP_CLK_MUX3 0x10
24#define TOP_CLK_MUX4 0x14
25#define TOP_CLK_MUX5 0x18
26#define TOP_CLK_MUX6 0x1c
27#define TOP_CLK_MUX7 0x20
28#define TOP_CLK_MUX9 0x28
29
30
31#define TOP_CLK_GATE0 0x34
32#define TOP_CLK_GATE1 0x38
33#define TOP_CLK_GATE2 0x3c
34#define TOP_CLK_GATE3 0x40
35#define TOP_CLK_GATE4 0x44
36#define TOP_CLK_GATE5 0x48
37#define TOP_CLK_GATE6 0x4c
38
39#define TOP_CLK_DIV0 0x58
40
41#define PLL_CPU_REG 0x80
42#define PLL_VGA_REG 0xb0
43#define PLL_DDR_REG 0xa0
44
45/* LSP0 CRM */
46#define LSP0_TIMER3_CLK 0x4
47#define LSP0_TIMER4_CLK 0x8
48#define LSP0_TIMER5_CLK 0xc
49#define LSP0_UART3_CLK 0x10
50#define LSP0_UART1_CLK 0x14
51#define LSP0_UART2_CLK 0x18
52#define LSP0_SPIFC0_CLK 0x1c
53#define LSP0_I2C4_CLK 0x20
54#define LSP0_I2C5_CLK 0x24
55#define LSP0_SSP0_CLK 0x28
56#define LSP0_SSP1_CLK 0x2c
57#define LSP0_USIM0_CLK 0x30
58#define LSP0_GPIO_CLK 0x34
59#define LSP0_I2C3_CLK 0x38
60
61/* LSP1 CRM */
62#define LSP1_UART4_CLK 0x08
63#define LSP1_UART5_CLK 0x0c
64#define LSP1_PWM_CLK 0x10
65#define LSP1_I2C2_CLK 0x14
66#define LSP1_SSP2_CLK 0x1c
67#define LSP1_SSP3_CLK 0x20
68#define LSP1_SSP4_CLK 0x24
69#define LSP1_USIM1_CLK 0x28
70
71/* audio lsp */
72#define AUDIO_I2S0_DIV_CFG1 0x10
73#define AUDIO_I2S0_DIV_CFG2 0x14
74#define AUDIO_I2S0_CLK 0x18
75#define AUDIO_I2S1_DIV_CFG1 0x20
76#define AUDIO_I2S1_DIV_CFG2 0x24
77#define AUDIO_I2S1_CLK 0x28
78#define AUDIO_I2S2_DIV_CFG1 0x30
79#define AUDIO_I2S2_DIV_CFG2 0x34
80#define AUDIO_I2S2_CLK 0x38
81#define AUDIO_I2S3_DIV_CFG1 0x40
82#define AUDIO_I2S3_DIV_CFG2 0x44
83#define AUDIO_I2S3_CLK 0x48
84#define AUDIO_I2C0_CLK 0x50
85#define AUDIO_SPDIF0_DIV_CFG1 0x60
86#define AUDIO_SPDIF0_DIV_CFG2 0x64
87#define AUDIO_SPDIF0_CLK 0x68
88#define AUDIO_SPDIF1_DIV_CFG1 0x70
89#define AUDIO_SPDIF1_DIV_CFG2 0x74
90#define AUDIO_SPDIF1_CLK 0x78
91#define AUDIO_TIMER_CLK 0x80
92#define AUDIO_TDM_CLK 0x90
93#define AUDIO_TS_CLK 0xa0
94
95static DEFINE_SPINLOCK(clk_lock);
96
97static struct zx_pll_config pll_cpu_table[] = {
98 PLL_RATE(1312000000, 0x00103621, 0x04aaaaaa),
99 PLL_RATE(1407000000, 0x00103a21, 0x04aaaaaa),
100 PLL_RATE(1503000000, 0x00103e21, 0x04aaaaaa),
101 PLL_RATE(1600000000, 0x00104221, 0x04aaaaaa),
102};
103
104PNAME(osc) = {
105 "osc24m",
106 "osc32k",
107};
108
109PNAME(dbg_wclk_p) = {
110 "clk334m",
111 "clk466m",
112 "clk396m",
113 "clk250m",
114};
115
116PNAME(a72_coreclk_p) = {
117 "osc24m",
118 "pll_mm0_1188m",
119 "pll_mm1_1296m",
120 "clk1000m",
121 "clk648m",
122 "clk1600m",
123 "pll_audio_1800m",
124 "pll_vga_1800m",
125};
126
127PNAME(cpu_periclk_p) = {
128 "osc24m",
129 "clk500m",
130 "clk594m",
131 "clk466m",
132 "clk294m",
133 "clk334m",
134 "clk250m",
135 "clk125m",
136};
137
138PNAME(a53_coreclk_p) = {
139 "osc24m",
140 "clk1000m",
141 "pll_mm0_1188m",
142 "clk648m",
143 "clk500m",
144 "clk800m",
145 "clk1600m",
146 "pll_audio_1800m",
147};
148
149PNAME(sec_wclk_p) = {
150 "osc24m",
151 "clk396m",
152 "clk334m",
153 "clk297m",
154 "clk250m",
155 "clk198m",
156 "clk148m5",
157 "clk99m",
158};
159
160PNAME(sd_nand_wclk_p) = {
161 "osc24m",
162 "clk49m5",
163 "clk99m",
164 "clk198m",
165 "clk167m",
166 "clk148m5",
167 "clk125m",
168 "clk216m",
169};
170
171PNAME(emmc_wclk_p) = {
172 "osc24m",
173 "clk198m",
174 "clk99m",
175 "clk396m",
176 "clk334m",
177 "clk297m",
178 "clk250m",
179 "clk148m5",
180};
181
182PNAME(clk32_p) = {
183 "osc32k",
184 "clk32k768",
185};
186
187PNAME(usb_ref24m_p) = {
188 "osc32k",
189 "clk32k768",
190};
191
192PNAME(sys_noc_alck_p) = {
193 "osc24m",
194 "clk250m",
195 "clk198m",
196 "clk148m5",
197 "clk108m",
198 "clk54m",
199 "clk216m",
200 "clk240m",
201};
202
203PNAME(vde_aclk_p) = {
204 "clk334m",
205 "clk594m",
206 "clk500m",
207 "clk432m",
208 "clk480m",
209 "clk297m",
210 "clk_vga", /*600MHz*/
211 "clk294m",
212};
213
214PNAME(vce_aclk_p) = {
215 "clk334m",
216 "clk594m",
217 "clk500m",
218 "clk432m",
219 "clk396m",
220 "clk297m",
221 "clk_vga", /*600MHz*/
222 "clk294m",
223};
224
225PNAME(hde_aclk_p) = {
226 "clk334m",
227 "clk594m",
228 "clk500m",
229 "clk432m",
230 "clk396m",
231 "clk297m",
232 "clk_vga", /*600MHz*/
233 "clk294m",
234};
235
236PNAME(gpu_aclk_p) = {
237 "clk334m",
238 "clk648m",
239 "clk594m",
240 "clk500m",
241 "clk396m",
242 "clk297m",
243 "clk_vga", /*600MHz*/
244 "clk294m",
245};
246
247PNAME(sappu_aclk_p) = {
248 "clk396m",
249 "clk500m",
250 "clk250m",
251 "clk148m5",
252};
253
254PNAME(sappu_wclk_p) = {
255 "clk198m",
256 "clk396m",
257 "clk334m",
258 "clk297m",
259 "clk250m",
260 "clk148m5",
261 "clk125m",
262 "clk99m",
263};
264
265PNAME(vou_aclk_p) = {
266 "clk334m",
267 "clk594m",
268 "clk500m",
269 "clk432m",
270 "clk396m",
271 "clk297m",
272 "clk_vga", /*600MHz*/
273 "clk294m",
274};
275
276PNAME(vou_main_wclk_p) = {
277 "clk108m",
278 "clk594m",
279 "clk297m",
280 "clk148m5",
281 "clk74m25",
282 "clk54m",
283 "clk27m",
284 "clk_vga",
285};
286
287PNAME(vou_aux_wclk_p) = {
288 "clk108m",
289 "clk148m5",
290 "clk74m25",
291 "clk54m",
292 "clk27m",
293 "clk_vga",
294 "clk54m_mm0",
295 "clk"
296};
297
298PNAME(vou_ppu_wclk_p) = {
299 "clk334m",
300 "clk432m",
301 "clk396m",
302 "clk297m",
303 "clk250m",
304 "clk125m",
305 "clk198m",
306 "clk99m",
307};
308
309PNAME(vga_i2c_wclk_p) = {
310 "osc24m",
311 "clk99m",
312};
313
314PNAME(viu_m0_aclk_p) = {
315 "clk334m",
316 "clk432m",
317 "clk396m",
318 "clk297m",
319 "clk250m",
320 "clk125m",
321 "clk198m",
322 "osc24m",
323};
324
325PNAME(viu_m1_aclk_p) = {
326 "clk198m",
327 "clk250m",
328 "clk297m",
329 "clk125m",
330 "clk396m",
331 "clk334m",
332 "clk148m5",
333 "osc24m",
334};
335
336PNAME(viu_clk_p) = {
337 "clk198m",
338 "clk334m",
339 "clk297m",
340 "clk250m",
341 "clk396m",
342 "clk125m",
343 "clk99m",
344 "clk148m5",
345};
346
347PNAME(viu_jpeg_clk_p) = {
348 "clk334m",
349 "clk480m",
350 "clk432m",
351 "clk396m",
352 "clk297m",
353 "clk250m",
354 "clk125m",
355 "clk198m",
356};
357
358PNAME(ts_sys_clk_p) = {
359 "clk192m",
360 "clk167m",
361 "clk125m",
362 "clk99m",
363};
364
365PNAME(wdt_ares_p) = {
366 "osc24m",
367 "clk32k"
368};
369
370static struct clk_zx_pll zx296718_pll_clk[] = {
371 ZX296718_PLL("pll_cpu", "osc24m", PLL_CPU_REG, pll_cpu_table),
372};
373
374static struct zx_clk_fixed_factor top_ffactor_clk[] = {
375 FFACTOR(0, "clk4m", "osc24m", 1, 6, 0),
376 FFACTOR(0, "clk2m", "osc24m", 1, 12, 0),
377 /* pll cpu */
378 FFACTOR(0, "clk1600m", "pll_cpu", 1, 1, CLK_SET_RATE_PARENT),
379 FFACTOR(0, "clk800m", "pll_cpu", 1, 2, CLK_SET_RATE_PARENT),
380 /* pll mac */
381 FFACTOR(0, "clk25m", "pll_mac", 1, 40, 0),
382 FFACTOR(0, "clk125m", "pll_mac", 1, 8, 0),
383 FFACTOR(0, "clk250m", "pll_mac", 1, 4, 0),
384 FFACTOR(0, "clk50m", "pll_mac", 1, 20, 0),
385 FFACTOR(0, "clk500m", "pll_mac", 1, 2, 0),
386 FFACTOR(0, "clk1000m", "pll_mac", 1, 1, 0),
387 FFACTOR(0, "clk334m", "pll_mac", 1, 3, 0),
388 FFACTOR(0, "clk167m", "pll_mac", 1, 6, 0),
389 /* pll mm */
390 FFACTOR(0, "clk54m_mm0", "pll_mm0", 1, 22, 0),
391 FFACTOR(0, "clk74m25", "pll_mm0", 1, 16, 0),
392 FFACTOR(0, "clk148m5", "pll_mm0", 1, 8, 0),
393 FFACTOR(0, "clk297m", "pll_mm0", 1, 4, 0),
394 FFACTOR(0, "clk594m", "pll_mm0", 1, 2, 0),
395 FFACTOR(0, "pll_mm0_1188m", "pll_mm0", 1, 1, 0),
396 FFACTOR(0, "clk396m", "pll_mm0", 1, 3, 0),
397 FFACTOR(0, "clk198m", "pll_mm0", 1, 6, 0),
398 FFACTOR(0, "clk99m", "pll_mm0", 1, 12, 0),
399 FFACTOR(0, "clk49m5", "pll_mm0", 1, 24, 0),
400 /* pll mm */
401 FFACTOR(0, "clk324m", "pll_mm1", 1, 4, 0),
402 FFACTOR(0, "clk648m", "pll_mm1", 1, 2, 0),
403 FFACTOR(0, "pll_mm1_1296m", "pll_mm1", 1, 1, 0),
404 FFACTOR(0, "clk216m", "pll_mm1", 1, 6, 0),
405 FFACTOR(0, "clk432m", "pll_mm1", 1, 3, 0),
406 FFACTOR(0, "clk108m", "pll_mm1", 1, 12, 0),
407 FFACTOR(0, "clk72m", "pll_mm1", 1, 18, 0),
408 FFACTOR(0, "clk27m", "pll_mm1", 1, 48, 0),
409 FFACTOR(0, "clk54m", "pll_mm1", 1, 24, 0),
410 /* vga */
411 FFACTOR(0, "pll_vga_1800m", "pll_vga", 1, 1, 0),
412 FFACTOR(0, "clk_vga", "pll_vga", 1, 2, 0),
413 /* pll ddr */
414 FFACTOR(0, "clk466m", "pll_ddr", 1, 2, 0),
415
416 /* pll audio */
417 FFACTOR(0, "pll_audio_1800m", "pll_audio", 1, 1, 0),
418 FFACTOR(0, "clk32k768", "pll_audio", 1, 27000, 0),
419 FFACTOR(0, "clk16m384", "pll_audio", 1, 54, 0),
420 FFACTOR(0, "clk294m", "pll_audio", 1, 3, 0),
421
422 /* pll hsic*/
423 FFACTOR(0, "clk240m", "pll_hsic", 1, 4, 0),
424 FFACTOR(0, "clk480m", "pll_hsic", 1, 2, 0),
425 FFACTOR(0, "clk192m", "pll_hsic", 1, 5, 0),
426 FFACTOR(0, "clk_pll_24m", "pll_hsic", 1, 40, 0),
427 FFACTOR(0, "emmc_mux_div2", "emmc_mux", 1, 2, CLK_SET_RATE_PARENT),
428};
429
430static struct clk_div_table noc_div_table[] = {
431 { .val = 1, .div = 2, },
432 { .val = 3, .div = 4, },
433};
434static struct zx_clk_div top_div_clk[] = {
435 DIV_T(0, "sys_noc_hclk", "sys_noc_aclk", TOP_CLK_DIV0, 0, 2, 0, noc_div_table),
436 DIV_T(0, "sys_noc_pclk", "sys_noc_aclk", TOP_CLK_DIV0, 4, 2, 0, noc_div_table),
437};
438
439static struct zx_clk_mux top_mux_clk[] = {
440 MUX(0, "dbg_mux", dbg_wclk_p, TOP_CLK_MUX0, 12, 2),
441 MUX(0, "a72_mux", a72_coreclk_p, TOP_CLK_MUX0, 8, 3),
442 MUX(0, "cpu_peri_mux", cpu_periclk_p, TOP_CLK_MUX0, 4, 3),
443 MUX_F(0, "a53_mux", a53_coreclk_p, TOP_CLK_MUX0, 0, 3, CLK_SET_RATE_PARENT, 0),
444 MUX(0, "sys_noc_aclk", sys_noc_alck_p, TOP_CLK_MUX1, 0, 3),
445 MUX(0, "sec_mux", sec_wclk_p, TOP_CLK_MUX2, 16, 3),
446 MUX(0, "sd1_mux", sd_nand_wclk_p, TOP_CLK_MUX2, 12, 3),
447 MUX(0, "sd0_mux", sd_nand_wclk_p, TOP_CLK_MUX2, 8, 3),
448 MUX(0, "emmc_mux", emmc_wclk_p, TOP_CLK_MUX2, 4, 3),
449 MUX(0, "nand_mux", sd_nand_wclk_p, TOP_CLK_MUX2, 0, 3),
450 MUX(0, "usb_ref24m_mux", usb_ref24m_p, TOP_CLK_MUX9, 16, 1),
451 MUX(0, "clk32k", clk32_p, TOP_CLK_MUX9, 12, 1),
452 MUX_F(0, "wdt_mux", wdt_ares_p, TOP_CLK_MUX9, 8, 1, CLK_SET_RATE_PARENT, 0),
453 MUX(0, "timer_mux", osc, TOP_CLK_MUX9, 4, 1),
454 MUX(0, "vde_mux", vde_aclk_p, TOP_CLK_MUX4, 0, 3),
455 MUX(0, "vce_mux", vce_aclk_p, TOP_CLK_MUX4, 4, 3),
456 MUX(0, "hde_mux", hde_aclk_p, TOP_CLK_MUX4, 8, 3),
457 MUX(0, "gpu_mux", gpu_aclk_p, TOP_CLK_MUX5, 0, 3),
458 MUX(0, "sappu_a_mux", sappu_aclk_p, TOP_CLK_MUX5, 4, 2),
459 MUX(0, "sappu_w_mux", sappu_wclk_p, TOP_CLK_MUX5, 8, 3),
460 MUX(0, "vou_a_mux", vou_aclk_p, TOP_CLK_MUX7, 0, 3),
461 MUX(0, "vou_main_w_mux", vou_main_wclk_p, TOP_CLK_MUX7, 4, 3),
462 MUX(0, "vou_aux_w_mux", vou_aux_wclk_p, TOP_CLK_MUX7, 8, 3),
463 MUX(0, "vou_ppu_w_mux", vou_ppu_wclk_p, TOP_CLK_MUX7, 12, 3),
464 MUX(0, "vga_i2c_mux", vga_i2c_wclk_p, TOP_CLK_MUX7, 16, 1),
465 MUX(0, "viu_m0_a_mux", viu_m0_aclk_p, TOP_CLK_MUX6, 0, 3),
466 MUX(0, "viu_m1_a_mux", viu_m1_aclk_p, TOP_CLK_MUX6, 4, 3),
467 MUX(0, "viu_w_mux", viu_clk_p, TOP_CLK_MUX6, 8, 3),
468 MUX(0, "viu_jpeg_w_mux", viu_jpeg_clk_p, TOP_CLK_MUX6, 12, 3),
469 MUX(0, "ts_sys_mux", ts_sys_clk_p, TOP_CLK_MUX6, 16, 2),
470};
471
472static struct zx_clk_gate top_gate_clk[] = {
473 GATE(CPU_DBG_GATE, "dbg_wclk", "dbg_mux", TOP_CLK_GATE0, 4, CLK_SET_RATE_PARENT, 0),
474 GATE(A72_GATE, "a72_coreclk", "a72_mux", TOP_CLK_GATE0, 3, CLK_SET_RATE_PARENT, 0),
475 GATE(CPU_PERI_GATE, "cpu_peri", "cpu_peri_mux", TOP_CLK_GATE0, 1, CLK_SET_RATE_PARENT, 0),
476 GATE(A53_GATE, "a53_coreclk", "a53_mux", TOP_CLK_GATE0, 0, CLK_SET_RATE_PARENT, 0),
477 GATE(SD1_WCLK, "sd1_wclk", "sd1_mux", TOP_CLK_GATE1, 13, CLK_SET_RATE_PARENT, 0),
478 GATE(SD0_WCLK, "sd0_wclk", "sd0_mux", TOP_CLK_GATE1, 9, CLK_SET_RATE_PARENT, 0),
479 GATE(EMMC_WCLK, "emmc_wclk", "emmc_mux_div2", TOP_CLK_GATE0, 5, CLK_SET_RATE_PARENT, 0),
480 GATE(EMMC_NAND_AXI, "emmc_nand_aclk", "sys_noc_aclk", TOP_CLK_GATE1, 4, CLK_SET_RATE_PARENT, 0),
481 GATE(NAND_WCLK, "nand_wclk", "nand_mux", TOP_CLK_GATE0, 1, CLK_SET_RATE_PARENT, 0),
482 GATE(EMMC_NAND_AHB, "emmc_nand_hclk", "sys_noc_hclk", TOP_CLK_GATE1, 0, CLK_SET_RATE_PARENT, 0),
483 GATE(0, "lsp1_pclk", "sys_noc_pclk", TOP_CLK_GATE2, 31, 0, 0),
484 GATE(LSP1_148M5, "lsp1_148m5", "clk148m5", TOP_CLK_GATE2, 30, 0, 0),
485 GATE(LSP1_99M, "lsp1_99m", "clk99m", TOP_CLK_GATE2, 29, 0, 0),
486 GATE(LSP1_24M, "lsp1_24m", "osc24m", TOP_CLK_GATE2, 28, 0, 0),
487 GATE(LSP0_74M25, "lsp0_74m25", "clk74m25", TOP_CLK_GATE2, 25, 0, 0),
488 GATE(0, "lsp0_pclk", "sys_noc_pclk", TOP_CLK_GATE2, 24, 0, 0),
489 GATE(LSP0_32K, "lsp0_32k", "osc32k", TOP_CLK_GATE2, 23, 0, 0),
490 GATE(LSP0_148M5, "lsp0_148m5", "clk148m5", TOP_CLK_GATE2, 22, 0, 0),
491 GATE(LSP0_99M, "lsp0_99m", "clk99m", TOP_CLK_GATE2, 21, 0, 0),
492 GATE(LSP0_24M, "lsp0_24m", "osc24m", TOP_CLK_GATE2, 20, 0, 0),
493 GATE(AUDIO_99M, "audio_99m", "clk99m", TOP_CLK_GATE5, 27, 0, 0),
494 GATE(AUDIO_24M, "audio_24m", "osc24m", TOP_CLK_GATE5, 28, 0, 0),
495 GATE(AUDIO_16M384, "audio_16m384", "clk16m384", TOP_CLK_GATE5, 29, 0, 0),
496 GATE(AUDIO_32K, "audio_32k", "clk32k", TOP_CLK_GATE5, 30, 0, 0),
497 GATE(WDT_WCLK, "wdt_wclk", "wdt_mux", TOP_CLK_GATE6, 9, CLK_SET_RATE_PARENT, 0),
498 GATE(TIMER_WCLK, "timer_wclk", "timer_mux", TOP_CLK_GATE6, 5, CLK_SET_RATE_PARENT, 0),
499 GATE(VDE_ACLK, "vde_aclk", "vde_mux", TOP_CLK_GATE3, 0, CLK_SET_RATE_PARENT, 0),
500 GATE(VCE_ACLK, "vce_aclk", "vce_mux", TOP_CLK_GATE3, 4, CLK_SET_RATE_PARENT, 0),
501 GATE(HDE_ACLK, "hde_aclk", "hde_mux", TOP_CLK_GATE3, 8, CLK_SET_RATE_PARENT, 0),
502 GATE(GPU_ACLK, "gpu_aclk", "gpu_mux", TOP_CLK_GATE3, 16, CLK_SET_RATE_PARENT, 0),
503 GATE(SAPPU_ACLK, "sappu_aclk", "sappu_a_mux", TOP_CLK_GATE3, 20, CLK_SET_RATE_PARENT, 0),
504 GATE(SAPPU_WCLK, "sappu_wclk", "sappu_w_mux", TOP_CLK_GATE3, 22, CLK_SET_RATE_PARENT, 0),
505 GATE(VOU_ACLK, "vou_aclk", "vou_a_mux", TOP_CLK_GATE4, 16, CLK_SET_RATE_PARENT, 0),
506 GATE(VOU_MAIN_WCLK, "vou_main_wclk", "vou_main_w_mux", TOP_CLK_GATE4, 18, CLK_SET_RATE_PARENT, 0),
507 GATE(VOU_AUX_WCLK, "vou_aux_wclk", "vou_aux_w_mux", TOP_CLK_GATE4, 19, CLK_SET_RATE_PARENT, 0),
508 GATE(VOU_PPU_WCLK, "vou_ppu_wclk", "vou_ppu_w_mux", TOP_CLK_GATE4, 20, CLK_SET_RATE_PARENT, 0),
509 GATE(MIPI_CFG_CLK, "mipi_cfg_clk", "osc24m", TOP_CLK_GATE4, 21, 0, 0),
510 GATE(VGA_I2C_WCLK, "vga_i2c_wclk", "vga_i2c_mux", TOP_CLK_GATE4, 23, CLK_SET_RATE_PARENT, 0),
511 GATE(MIPI_REF_CLK, "mipi_ref_clk", "clk27m", TOP_CLK_GATE4, 24, 0, 0),
512 GATE(HDMI_OSC_CEC, "hdmi_osc_cec", "clk2m", TOP_CLK_GATE4, 22, 0, 0),
513 GATE(HDMI_OSC_CLK, "hdmi_osc_clk", "clk240m", TOP_CLK_GATE4, 25, 0, 0),
514 GATE(HDMI_XCLK, "hdmi_xclk", "osc24m", TOP_CLK_GATE4, 26, 0, 0),
515 GATE(VIU_M0_ACLK, "viu_m0_aclk", "viu_m0_a_mux", TOP_CLK_GATE4, 0, CLK_SET_RATE_PARENT, 0),
516 GATE(VIU_M1_ACLK, "viu_m1_aclk", "viu_m1_a_mux", TOP_CLK_GATE4, 1, CLK_SET_RATE_PARENT, 0),
517 GATE(VIU_WCLK, "viu_wclk", "viu_w_mux", TOP_CLK_GATE4, 2, CLK_SET_RATE_PARENT, 0),
518 GATE(VIU_JPEG_WCLK, "viu_jpeg_wclk", "viu_jpeg_w_mux", TOP_CLK_GATE4, 3, CLK_SET_RATE_PARENT, 0),
519 GATE(VIU_CFG_CLK, "viu_cfg_clk", "osc24m", TOP_CLK_GATE4, 6, 0, 0),
520 GATE(TS_SYS_WCLK, "ts_sys_wclk", "ts_sys_mux", TOP_CLK_GATE5, 2, CLK_SET_RATE_PARENT, 0),
521 GATE(TS_SYS_108M, "ts_sys_108m", "clk108m", TOP_CLK_GATE5, 3, 0, 0),
522 GATE(USB20_HCLK, "usb20_hclk", "sys_noc_hclk", TOP_CLK_GATE2, 12, 0, 0),
523 GATE(USB20_PHY_CLK, "usb20_phy_clk", "usb_ref24m_mux", TOP_CLK_GATE2, 13, 0, 0),
524 GATE(USB21_HCLK, "usb21_hclk", "sys_noc_hclk", TOP_CLK_GATE2, 14, 0, 0),
525 GATE(USB21_PHY_CLK, "usb21_phy_clk", "usb_ref24m_mux", TOP_CLK_GATE2, 15, 0, 0),
526 GATE(GMAC_RMIICLK, "gmac_rmii_clk", "clk50m", TOP_CLK_GATE2, 3, 0, 0),
527 GATE(GMAC_PCLK, "gmac_pclk", "clk198m", TOP_CLK_GATE2, 1, 0, 0),
528 GATE(GMAC_ACLK, "gmac_aclk", "clk49m5", TOP_CLK_GATE2, 0, 0, 0),
529 GATE(GMAC_RFCLK, "gmac_refclk", "clk25m", TOP_CLK_GATE2, 4, 0, 0),
530 GATE(SD1_AHB, "sd1_hclk", "sys_noc_hclk", TOP_CLK_GATE1, 12, 0, 0),
531 GATE(SD0_AHB, "sd0_hclk", "sys_noc_hclk", TOP_CLK_GATE1, 8, 0, 0),
532 GATE(TEMPSENSOR_GATE, "tempsensor_gate", "clk4m", TOP_CLK_GATE5, 31, 0, 0),
533};
534
535static struct clk_hw_onecell_data top_hw_onecell_data = {
536 .num = TOP_NR_CLKS,
537 .hws = {
538 [TOP_NR_CLKS - 1] = NULL,
539 },
540};
541
542static int __init top_clocks_init(struct device_node *np)
543{
544 void __iomem *reg_base;
545 int i, ret;
546
547 reg_base = of_iomap(np, 0);
548 if (!reg_base) {
549 pr_err("%s: Unable to map clk base\n", __func__);
550 return -ENXIO;
551 }
552
553 for (i = 0; i < ARRAY_SIZE(zx296718_pll_clk); i++) {
554 zx296718_pll_clk[i].reg_base += (uintptr_t)reg_base;
555 ret = clk_hw_register(NULL, &zx296718_pll_clk[i].hw);
556 if (ret) {
557 pr_warn("top clk %s init error!\n",
558 zx296718_pll_clk[i].hw.init->name);
559 }
560 }
561
562 for (i = 0; i < ARRAY_SIZE(top_ffactor_clk); i++) {
563 if (top_ffactor_clk[i].id)
564 top_hw_onecell_data.hws[top_ffactor_clk[i].id] =
565 &top_ffactor_clk[i].factor.hw;
566
567 ret = clk_hw_register(NULL, &top_ffactor_clk[i].factor.hw);
568 if (ret) {
569 pr_warn("top clk %s init error!\n",
570 top_ffactor_clk[i].factor.hw.init->name);
571 }
572 }
573
574 for (i = 0; i < ARRAY_SIZE(top_mux_clk); i++) {
575 if (top_mux_clk[i].id)
576 top_hw_onecell_data.hws[top_mux_clk[i].id] =
577 &top_mux_clk[i].mux.hw;
578
579 top_mux_clk[i].mux.reg += (uintptr_t)reg_base;
580 ret = clk_hw_register(NULL, &top_mux_clk[i].mux.hw);
581 if (ret) {
582 pr_warn("top clk %s init error!\n",
583 top_mux_clk[i].mux.hw.init->name);
584 }
585 }
586
587 for (i = 0; i < ARRAY_SIZE(top_gate_clk); i++) {
588 if (top_gate_clk[i].id)
589 top_hw_onecell_data.hws[top_gate_clk[i].id] =
590 &top_gate_clk[i].gate.hw;
591
592 top_gate_clk[i].gate.reg += (uintptr_t)reg_base;
593 ret = clk_hw_register(NULL, &top_gate_clk[i].gate.hw);
594 if (ret) {
595 pr_warn("top clk %s init error!\n",
596 top_gate_clk[i].gate.hw.init->name);
597 }
598 }
599
600 for (i = 0; i < ARRAY_SIZE(top_div_clk); i++) {
601 if (top_div_clk[i].id)
602 top_hw_onecell_data.hws[top_div_clk[i].id] =
603 &top_div_clk[i].div.hw;
604
605 top_div_clk[i].div.reg += (uintptr_t)reg_base;
606 ret = clk_hw_register(NULL, &top_div_clk[i].div.hw);
607 if (ret) {
608 pr_warn("top clk %s init error!\n",
609 top_div_clk[i].div.hw.init->name);
610 }
611 }
612
613 if (of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &top_hw_onecell_data))
614 panic("could not register clk provider\n");
615 pr_info("top clk init over, nr:%d\n", TOP_NR_CLKS);
616
617 return 0;
618}
619
620static struct clk_div_table common_even_div_table[] = {
621 { .val = 0, .div = 1, },
622 { .val = 1, .div = 2, },
623 { .val = 3, .div = 4, },
624 { .val = 5, .div = 6, },
625 { .val = 7, .div = 8, },
626 { .val = 9, .div = 10, },
627 { .val = 11, .div = 12, },
628 { .val = 13, .div = 14, },
629 { .val = 15, .div = 16, },
630};
631
632static struct clk_div_table common_div_table[] = {
633 { .val = 0, .div = 1, },
634 { .val = 1, .div = 2, },
635 { .val = 2, .div = 3, },
636 { .val = 3, .div = 4, },
637 { .val = 4, .div = 5, },
638 { .val = 5, .div = 6, },
639 { .val = 6, .div = 7, },
640 { .val = 7, .div = 8, },
641 { .val = 8, .div = 9, },
642 { .val = 9, .div = 10, },
643 { .val = 10, .div = 11, },
644 { .val = 11, .div = 12, },
645 { .val = 12, .div = 13, },
646 { .val = 13, .div = 14, },
647 { .val = 14, .div = 15, },
648 { .val = 15, .div = 16, },
649};
650
651PNAME(lsp0_wclk_common_p) = {
652 "lsp0_24m",
653 "lsp0_99m",
654};
655
656PNAME(lsp0_wclk_timer3_p) = {
657 "timer3_div",
658 "lsp0_32k"
659};
660
661PNAME(lsp0_wclk_timer4_p) = {
662 "timer4_div",
663 "lsp0_32k"
664};
665
666PNAME(lsp0_wclk_timer5_p) = {
667 "timer5_div",
668 "lsp0_32k"
669};
670
671PNAME(lsp0_wclk_spifc0_p) = {
672 "lsp0_148m5",
673 "lsp0_24m",
674 "lsp0_99m",
675 "lsp0_74m25"
676};
677
678PNAME(lsp0_wclk_ssp_p) = {
679 "lsp0_148m5",
680 "lsp0_99m",
681 "lsp0_24m",
682};
683
684static struct zx_clk_mux lsp0_mux_clk[] = {
685 MUX(0, "timer3_wclk_mux", lsp0_wclk_timer3_p, LSP0_TIMER3_CLK, 4, 1),
686 MUX(0, "timer4_wclk_mux", lsp0_wclk_timer4_p, LSP0_TIMER4_CLK, 4, 1),
687 MUX(0, "timer5_wclk_mux", lsp0_wclk_timer5_p, LSP0_TIMER5_CLK, 4, 1),
688 MUX(0, "uart3_wclk_mux", lsp0_wclk_common_p, LSP0_UART3_CLK, 4, 1),
689 MUX(0, "uart1_wclk_mux", lsp0_wclk_common_p, LSP0_UART1_CLK, 4, 1),
690 MUX(0, "uart2_wclk_mux", lsp0_wclk_common_p, LSP0_UART2_CLK, 4, 1),
691 MUX(0, "spifc0_wclk_mux", lsp0_wclk_spifc0_p, LSP0_SPIFC0_CLK, 4, 2),
692 MUX(0, "i2c4_wclk_mux", lsp0_wclk_common_p, LSP0_I2C4_CLK, 4, 1),
693 MUX(0, "i2c5_wclk_mux", lsp0_wclk_common_p, LSP0_I2C5_CLK, 4, 1),
694 MUX(0, "ssp0_wclk_mux", lsp0_wclk_ssp_p, LSP0_SSP0_CLK, 4, 1),
695 MUX(0, "ssp1_wclk_mux", lsp0_wclk_ssp_p, LSP0_SSP1_CLK, 4, 1),
696 MUX(0, "i2c3_wclk_mux", lsp0_wclk_common_p, LSP0_I2C3_CLK, 4, 1),
697};
698
699static struct zx_clk_gate lsp0_gate_clk[] = {
700 GATE(LSP0_TIMER3_WCLK, "timer3_wclk", "timer3_wclk_mux", LSP0_TIMER3_CLK, 1, CLK_SET_RATE_PARENT, 0),
701 GATE(LSP0_TIMER4_WCLK, "timer4_wclk", "timer4_wclk_mux", LSP0_TIMER4_CLK, 1, CLK_SET_RATE_PARENT, 0),
702 GATE(LSP0_TIMER5_WCLK, "timer5_wclk", "timer5_wclk_mux", LSP0_TIMER5_CLK, 1, CLK_SET_RATE_PARENT, 0),
703 GATE(LSP0_UART3_WCLK, "uart3_wclk", "uart3_wclk_mux", LSP0_UART3_CLK, 1, CLK_SET_RATE_PARENT, 0),
704 GATE(LSP0_UART1_WCLK, "uart1_wclk", "uart1_wclk_mux", LSP0_UART1_CLK, 1, CLK_SET_RATE_PARENT, 0),
705 GATE(LSP0_UART2_WCLK, "uart2_wclk", "uart2_wclk_mux", LSP0_UART2_CLK, 1, CLK_SET_RATE_PARENT, 0),
706 GATE(LSP0_SPIFC0_WCLK, "spifc0_wclk", "spifc0_wclk_mux", LSP0_SPIFC0_CLK, 1, CLK_SET_RATE_PARENT, 0),
707 GATE(LSP0_I2C4_WCLK, "i2c4_wclk", "i2c4_wclk_mux", LSP0_I2C4_CLK, 1, CLK_SET_RATE_PARENT, 0),
708 GATE(LSP0_I2C5_WCLK, "i2c5_wclk", "i2c5_wclk_mux", LSP0_I2C5_CLK, 1, CLK_SET_RATE_PARENT, 0),
709 GATE(LSP0_SSP0_WCLK, "ssp0_wclk", "ssp0_div", LSP0_SSP0_CLK, 1, CLK_SET_RATE_PARENT, 0),
710 GATE(LSP0_SSP1_WCLK, "ssp1_wclk", "ssp1_div", LSP0_SSP1_CLK, 1, CLK_SET_RATE_PARENT, 0),
711 GATE(LSP0_I2C3_WCLK, "i2c3_wclk", "i2c3_wclk_mux", LSP0_I2C3_CLK, 1, CLK_SET_RATE_PARENT, 0),
712};
713
714static struct zx_clk_div lsp0_div_clk[] = {
715 DIV_T(0, "timer3_div", "lsp0_24m", LSP0_TIMER3_CLK, 12, 4, 0, common_even_div_table),
716 DIV_T(0, "timer4_div", "lsp0_24m", LSP0_TIMER4_CLK, 12, 4, 0, common_even_div_table),
717 DIV_T(0, "timer5_div", "lsp0_24m", LSP0_TIMER5_CLK, 12, 4, 0, common_even_div_table),
718 DIV_T(0, "ssp0_div", "ssp0_wclk_mux", LSP0_SSP0_CLK, 12, 4, 0, common_even_div_table),
719 DIV_T(0, "ssp1_div", "ssp1_wclk_mux", LSP0_SSP1_CLK, 12, 4, 0, common_even_div_table),
720};
721
722static struct clk_hw_onecell_data lsp0_hw_onecell_data = {
723 .num = LSP0_NR_CLKS,
724 .hws = {
725 [LSP0_NR_CLKS - 1] = NULL,
726 },
727};
728
729static int __init lsp0_clocks_init(struct device_node *np)
730{
731 void __iomem *reg_base;
732 int i, ret;
733
734 reg_base = of_iomap(np, 0);
735 if (!reg_base) {
736 pr_err("%s: Unable to map clk base\n", __func__);
737 return -ENXIO;
738 }
739
740 for (i = 0; i < ARRAY_SIZE(lsp0_mux_clk); i++) {
741 if (lsp0_mux_clk[i].id)
742 lsp0_hw_onecell_data.hws[lsp0_mux_clk[i].id] =
743 &lsp0_mux_clk[i].mux.hw;
744
745 lsp0_mux_clk[i].mux.reg += (uintptr_t)reg_base;
746 ret = clk_hw_register(NULL, &lsp0_mux_clk[i].mux.hw);
747 if (ret) {
748 pr_warn("lsp0 clk %s init error!\n",
749 lsp0_mux_clk[i].mux.hw.init->name);
750 }
751 }
752
753 for (i = 0; i < ARRAY_SIZE(lsp0_gate_clk); i++) {
754 if (lsp0_gate_clk[i].id)
755 lsp0_hw_onecell_data.hws[lsp0_gate_clk[i].id] =
756 &lsp0_gate_clk[i].gate.hw;
757
758 lsp0_gate_clk[i].gate.reg += (uintptr_t)reg_base;
759 ret = clk_hw_register(NULL, &lsp0_gate_clk[i].gate.hw);
760 if (ret) {
761 pr_warn("lsp0 clk %s init error!\n",
762 lsp0_gate_clk[i].gate.hw.init->name);
763 }
764 }
765
766 for (i = 0; i < ARRAY_SIZE(lsp0_div_clk); i++) {
767 if (lsp0_div_clk[i].id)
768 lsp0_hw_onecell_data.hws[lsp0_div_clk[i].id] =
769 &lsp0_div_clk[i].div.hw;
770
771 lsp0_div_clk[i].div.reg += (uintptr_t)reg_base;
772 ret = clk_hw_register(NULL, &lsp0_div_clk[i].div.hw);
773 if (ret) {
774 pr_warn("lsp0 clk %s init error!\n",
775 lsp0_div_clk[i].div.hw.init->name);
776 }
777 }
778
779 if (of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &lsp0_hw_onecell_data))
780 panic("could not register clk provider\n");
781 pr_info("lsp0-clk init over:%d\n", LSP0_NR_CLKS);
782
783 return 0;
784}
785
786PNAME(lsp1_wclk_common_p) = {
787 "lsp1_24m",
788 "lsp1_99m",
789};
790
791PNAME(lsp1_wclk_ssp_p) = {
792 "lsp1_148m5",
793 "lsp1_99m",
794 "lsp1_24m",
795};
796
797static struct zx_clk_mux lsp1_mux_clk[] = {
798 MUX(0, "uart4_wclk_mux", lsp1_wclk_common_p, LSP1_UART4_CLK, 4, 1),
799 MUX(0, "uart5_wclk_mux", lsp1_wclk_common_p, LSP1_UART5_CLK, 4, 1),
800 MUX(0, "pwm_wclk_mux", lsp1_wclk_common_p, LSP1_PWM_CLK, 4, 1),
801 MUX(0, "i2c2_wclk_mux", lsp1_wclk_common_p, LSP1_I2C2_CLK, 4, 1),
802 MUX(0, "ssp2_wclk_mux", lsp1_wclk_ssp_p, LSP1_SSP2_CLK, 4, 2),
803 MUX(0, "ssp3_wclk_mux", lsp1_wclk_ssp_p, LSP1_SSP3_CLK, 4, 2),
804 MUX(0, "ssp4_wclk_mux", lsp1_wclk_ssp_p, LSP1_SSP4_CLK, 4, 2),
805 MUX(0, "usim1_wclk_mux", lsp1_wclk_common_p, LSP1_USIM1_CLK, 4, 1),
806};
807
808static struct zx_clk_div lsp1_div_clk[] = {
809 DIV_T(0, "pwm_div", "pwm_wclk_mux", LSP1_PWM_CLK, 12, 4, CLK_SET_RATE_PARENT, common_div_table),
810 DIV_T(0, "ssp2_div", "ssp2_wclk_mux", LSP1_SSP2_CLK, 12, 4, CLK_SET_RATE_PARENT, common_even_div_table),
811 DIV_T(0, "ssp3_div", "ssp3_wclk_mux", LSP1_SSP3_CLK, 12, 4, CLK_SET_RATE_PARENT, common_even_div_table),
812 DIV_T(0, "ssp4_div", "ssp4_wclk_mux", LSP1_SSP4_CLK, 12, 4, CLK_SET_RATE_PARENT, common_even_div_table),
813};
814
815static struct zx_clk_gate lsp1_gate_clk[] = {
816 GATE(LSP1_UART4_WCLK, "lsp1_uart4_wclk", "uart4_wclk_mux", LSP1_UART4_CLK, 1, CLK_SET_RATE_PARENT, 0),
817 GATE(LSP1_UART5_WCLK, "lsp1_uart5_wclk", "uart5_wclk_mux", LSP1_UART5_CLK, 1, CLK_SET_RATE_PARENT, 0),
818 GATE(LSP1_PWM_WCLK, "lsp1_pwm_wclk", "pwm_div", LSP1_PWM_CLK, 1, CLK_SET_RATE_PARENT, 0),
819 GATE(LSP1_PWM_PCLK, "lsp1_pwm_pclk", "lsp1_pclk", LSP1_PWM_CLK, 0, 0, 0),
820 GATE(LSP1_I2C2_WCLK, "lsp1_i2c2_wclk", "i2c2_wclk_mux", LSP1_I2C2_CLK, 1, CLK_SET_RATE_PARENT, 0),
821 GATE(LSP1_SSP2_WCLK, "lsp1_ssp2_wclk", "ssp2_div", LSP1_SSP2_CLK, 1, CLK_SET_RATE_PARENT, 0),
822 GATE(LSP1_SSP3_WCLK, "lsp1_ssp3_wclk", "ssp3_div", LSP1_SSP3_CLK, 1, CLK_SET_RATE_PARENT, 0),
823 GATE(LSP1_SSP4_WCLK, "lsp1_ssp4_wclk", "ssp4_div", LSP1_SSP4_CLK, 1, CLK_SET_RATE_PARENT, 0),
824 GATE(LSP1_USIM1_WCLK, "lsp1_usim1_wclk", "usim1_wclk_mux", LSP1_USIM1_CLK, 1, CLK_SET_RATE_PARENT, 0),
825};
826
827static struct clk_hw_onecell_data lsp1_hw_onecell_data = {
828 .num = LSP1_NR_CLKS,
829 .hws = {
830 [LSP1_NR_CLKS - 1] = NULL,
831 },
832};
833
834static int __init lsp1_clocks_init(struct device_node *np)
835{
836 void __iomem *reg_base;
837 int i, ret;
838
839 reg_base = of_iomap(np, 0);
840 if (!reg_base) {
841 pr_err("%s: Unable to map clk base\n", __func__);
842 return -ENXIO;
843 }
844
845 for (i = 0; i < ARRAY_SIZE(lsp1_mux_clk); i++) {
846 if (lsp1_mux_clk[i].id)
847 lsp1_hw_onecell_data.hws[lsp1_mux_clk[i].id] =
848 &lsp0_mux_clk[i].mux.hw;
849
850 lsp1_mux_clk[i].mux.reg += (uintptr_t)reg_base;
851 ret = clk_hw_register(NULL, &lsp1_mux_clk[i].mux.hw);
852 if (ret) {
853 pr_warn("lsp1 clk %s init error!\n",
854 lsp1_mux_clk[i].mux.hw.init->name);
855 }
856 }
857
858 for (i = 0; i < ARRAY_SIZE(lsp1_gate_clk); i++) {
859 if (lsp1_gate_clk[i].id)
860 lsp1_hw_onecell_data.hws[lsp1_gate_clk[i].id] =
861 &lsp1_gate_clk[i].gate.hw;
862
863 lsp1_gate_clk[i].gate.reg += (uintptr_t)reg_base;
864 ret = clk_hw_register(NULL, &lsp1_gate_clk[i].gate.hw);
865 if (ret) {
866 pr_warn("lsp1 clk %s init error!\n",
867 lsp1_gate_clk[i].gate.hw.init->name);
868 }
869 }
870
871 for (i = 0; i < ARRAY_SIZE(lsp1_div_clk); i++) {
872 if (lsp1_div_clk[i].id)
873 lsp1_hw_onecell_data.hws[lsp1_div_clk[i].id] =
874 &lsp1_div_clk[i].div.hw;
875
876 lsp1_div_clk[i].div.reg += (uintptr_t)reg_base;
877 ret = clk_hw_register(NULL, &lsp1_div_clk[i].div.hw);
878 if (ret) {
879 pr_warn("lsp1 clk %s init error!\n",
880 lsp1_div_clk[i].div.hw.init->name);
881 }
882 }
883
884 if (of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &lsp1_hw_onecell_data))
885 panic("could not register clk provider\n");
886 pr_info("lsp1-clk init over, nr:%d\n", LSP1_NR_CLKS);
887
888 return 0;
889}
890
891static const struct of_device_id zx_clkc_match_table[] = {
892 { .compatible = "zte,zx296718-topcrm", .data = &top_clocks_init },
893 { .compatible = "zte,zx296718-lsp0crm", .data = &lsp0_clocks_init },
894 { .compatible = "zte,zx296718-lsp1crm", .data = &lsp1_clocks_init },
895 { }
896};
897
898static int zx_clkc_probe(struct platform_device *pdev)
899{
900 int (*init_fn)(struct device_node *np);
901 struct device_node *np = pdev->dev.of_node;
902
903 init_fn = of_device_get_match_data(&pdev->dev);
904 if (!init_fn) {
905 dev_err(&pdev->dev, "Error: No device match found\n");
906 return -ENODEV;
907 }
908
909 return init_fn(np);
910}
911
912static struct platform_driver zx_clk_driver = {
913 .probe = zx_clkc_probe,
914 .driver = {
915 .name = "zx296718-clkc",
916 .of_match_table = zx_clkc_match_table,
917 },
918};
919
920static int __init zx_clk_init(void)
921{
922 return platform_driver_register(&zx_clk_driver);
923}
924core_initcall(zx_clk_init);
diff --git a/drivers/clk/zte/clk.c b/drivers/clk/zte/clk.c
index 7c73c538c43d..c4c1251bc1e7 100644
--- a/drivers/clk/zte/clk.c
+++ b/drivers/clk/zte/clk.c
@@ -21,8 +21,8 @@
21#define to_clk_zx_audio(_hw) container_of(_hw, struct clk_zx_audio, hw) 21#define to_clk_zx_audio(_hw) container_of(_hw, struct clk_zx_audio, hw)
22 22
23#define CFG0_CFG1_OFFSET 4 23#define CFG0_CFG1_OFFSET 4
24#define LOCK_FLAG BIT(30) 24#define LOCK_FLAG 30
25#define POWER_DOWN BIT(31) 25#define POWER_DOWN 31
26 26
27static int rate_to_idx(struct clk_zx_pll *zx_pll, unsigned long rate) 27static int rate_to_idx(struct clk_zx_pll *zx_pll, unsigned long rate)
28{ 28{
@@ -50,8 +50,8 @@ static int hw_to_idx(struct clk_zx_pll *zx_pll)
50 hw_cfg1 = readl_relaxed(zx_pll->reg_base + CFG0_CFG1_OFFSET); 50 hw_cfg1 = readl_relaxed(zx_pll->reg_base + CFG0_CFG1_OFFSET);
51 51
52 /* For matching the value in lookup table */ 52 /* For matching the value in lookup table */
53 hw_cfg0 &= ~LOCK_FLAG; 53 hw_cfg0 &= ~BIT(zx_pll->lock_bit);
54 hw_cfg0 |= POWER_DOWN; 54 hw_cfg0 |= BIT(zx_pll->pd_bit);
55 55
56 for (i = 0; i < zx_pll->count; i++) { 56 for (i = 0; i < zx_pll->count; i++) {
57 if (hw_cfg0 == config[i].cfg0 && hw_cfg1 == config[i].cfg1) 57 if (hw_cfg0 == config[i].cfg0 && hw_cfg1 == config[i].cfg1)
@@ -108,10 +108,10 @@ static int zx_pll_enable(struct clk_hw *hw)
108 u32 reg; 108 u32 reg;
109 109
110 reg = readl_relaxed(zx_pll->reg_base); 110 reg = readl_relaxed(zx_pll->reg_base);
111 writel_relaxed(reg & ~POWER_DOWN, zx_pll->reg_base); 111 writel_relaxed(reg & ~BIT(zx_pll->pd_bit), zx_pll->reg_base);
112 112
113 return readl_relaxed_poll_timeout(zx_pll->reg_base, reg, 113 return readl_relaxed_poll_timeout(zx_pll->reg_base, reg,
114 reg & LOCK_FLAG, 0, 100); 114 reg & BIT(zx_pll->lock_bit), 0, 100);
115} 115}
116 116
117static void zx_pll_disable(struct clk_hw *hw) 117static void zx_pll_disable(struct clk_hw *hw)
@@ -120,7 +120,7 @@ static void zx_pll_disable(struct clk_hw *hw)
120 u32 reg; 120 u32 reg;
121 121
122 reg = readl_relaxed(zx_pll->reg_base); 122 reg = readl_relaxed(zx_pll->reg_base);
123 writel_relaxed(reg | POWER_DOWN, zx_pll->reg_base); 123 writel_relaxed(reg | BIT(zx_pll->pd_bit), zx_pll->reg_base);
124} 124}
125 125
126static int zx_pll_is_enabled(struct clk_hw *hw) 126static int zx_pll_is_enabled(struct clk_hw *hw)
@@ -130,10 +130,10 @@ static int zx_pll_is_enabled(struct clk_hw *hw)
130 130
131 reg = readl_relaxed(zx_pll->reg_base); 131 reg = readl_relaxed(zx_pll->reg_base);
132 132
133 return !(reg & POWER_DOWN); 133 return !(reg & BIT(zx_pll->pd_bit));
134} 134}
135 135
136static const struct clk_ops zx_pll_ops = { 136const struct clk_ops zx_pll_ops = {
137 .recalc_rate = zx_pll_recalc_rate, 137 .recalc_rate = zx_pll_recalc_rate,
138 .round_rate = zx_pll_round_rate, 138 .round_rate = zx_pll_round_rate,
139 .set_rate = zx_pll_set_rate, 139 .set_rate = zx_pll_set_rate,
@@ -141,6 +141,7 @@ static const struct clk_ops zx_pll_ops = {
141 .disable = zx_pll_disable, 141 .disable = zx_pll_disable,
142 .is_enabled = zx_pll_is_enabled, 142 .is_enabled = zx_pll_is_enabled,
143}; 143};
144EXPORT_SYMBOL(zx_pll_ops);
144 145
145struct clk *clk_register_zx_pll(const char *name, const char *parent_name, 146struct clk *clk_register_zx_pll(const char *name, const char *parent_name,
146 unsigned long flags, void __iomem *reg_base, 147 unsigned long flags, void __iomem *reg_base,
@@ -164,6 +165,8 @@ struct clk *clk_register_zx_pll(const char *name, const char *parent_name,
164 zx_pll->reg_base = reg_base; 165 zx_pll->reg_base = reg_base;
165 zx_pll->lookup_table = lookup_table; 166 zx_pll->lookup_table = lookup_table;
166 zx_pll->count = count; 167 zx_pll->count = count;
168 zx_pll->lock_bit = LOCK_FLAG;
169 zx_pll->pd_bit = POWER_DOWN;
167 zx_pll->lock = lock; 170 zx_pll->lock = lock;
168 zx_pll->hw.init = &init; 171 zx_pll->hw.init = &init;
169 172
diff --git a/drivers/clk/zte/clk.h b/drivers/clk/zte/clk.h
index 65ae08b818d3..0df3474b2cf3 100644
--- a/drivers/clk/zte/clk.h
+++ b/drivers/clk/zte/clk.h
@@ -12,6 +12,26 @@
12#include <linux/clk-provider.h> 12#include <linux/clk-provider.h>
13#include <linux/spinlock.h> 13#include <linux/spinlock.h>
14 14
15#define PNAME(x) static const char *x[]
16
17#define CLK_HW_INIT(_name, _parent, _ops, _flags) \
18 &(struct clk_init_data) { \
19 .flags = _flags, \
20 .name = _name, \
21 .parent_names = (const char *[]) { _parent }, \
22 .num_parents = 1, \
23 .ops = _ops, \
24 }
25
26#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \
27 &(struct clk_init_data) { \
28 .flags = _flags, \
29 .name = _name, \
30 .parent_names = _parents, \
31 .num_parents = ARRAY_SIZE(_parents), \
32 .ops = _ops, \
33 }
34
15struct zx_pll_config { 35struct zx_pll_config {
16 unsigned long rate; 36 unsigned long rate;
17 u32 cfg0; 37 u32 cfg0;
@@ -24,8 +44,115 @@ struct clk_zx_pll {
24 const struct zx_pll_config *lookup_table; /* order by rate asc */ 44 const struct zx_pll_config *lookup_table; /* order by rate asc */
25 int count; 45 int count;
26 spinlock_t *lock; 46 spinlock_t *lock;
47 u8 pd_bit; /* power down bit */
48 u8 lock_bit; /* pll lock flag bit */
49};
50
51#define PLL_RATE(_rate, _cfg0, _cfg1) \
52{ \
53 .rate = _rate, \
54 .cfg0 = _cfg0, \
55 .cfg1 = _cfg1, \
56}
57
58#define ZX_PLL(_name, _parent, _reg, _table, _pd, _lock) \
59{ \
60 .reg_base = (void __iomem *) _reg, \
61 .lookup_table = _table, \
62 .count = ARRAY_SIZE(_table), \
63 .pd_bit = _pd, \
64 .lock_bit = _lock, \
65 .hw.init = CLK_HW_INIT(_name, _parent, &zx_pll_ops, \
66 CLK_GET_RATE_NOCACHE), \
67}
68
69#define ZX296718_PLL(_name, _parent, _reg, _table) \
70ZX_PLL(_name, _parent, _reg, _table, 0, 30)
71
72struct zx_clk_gate {
73 struct clk_gate gate;
74 u16 id;
75};
76
77#define GATE(_id, _name, _parent, _reg, _bit, _flag, _gflags) \
78{ \
79 .gate = { \
80 .reg = (void __iomem *) _reg, \
81 .bit_idx = (_bit), \
82 .flags = _gflags, \
83 .lock = &clk_lock, \
84 .hw.init = CLK_HW_INIT(_name, \
85 _parent, \
86 &clk_gate_ops, \
87 _flag | CLK_IGNORE_UNUSED), \
88 }, \
89 .id = _id, \
90}
91
92struct zx_clk_fixed_factor {
93 struct clk_fixed_factor factor;
94 u16 id;
95};
96
97#define FFACTOR(_id, _name, _parent, _mult, _div, _flag) \
98{ \
99 .factor = { \
100 .div = _div, \
101 .mult = _mult, \
102 .hw.init = CLK_HW_INIT(_name, \
103 _parent, \
104 &clk_fixed_factor_ops, \
105 _flag), \
106 }, \
107 .id = _id, \
108}
109
110struct zx_clk_mux {
111 struct clk_mux mux;
112 u16 id;
113};
114
115#define MUX_F(_id, _name, _parent, _reg, _shift, _width, _flag, _mflag) \
116{ \
117 .mux = { \
118 .reg = (void __iomem *) _reg, \
119 .mask = BIT(_width) - 1, \
120 .shift = _shift, \
121 .flags = _mflag, \
122 .lock = &clk_lock, \
123 .hw.init = CLK_HW_INIT_PARENTS(_name, \
124 _parent, \
125 &clk_mux_ops, \
126 _flag), \
127 }, \
128 .id = _id, \
129}
130
131#define MUX(_id, _name, _parent, _reg, _shift, _width) \
132MUX_F(_id, _name, _parent, _reg, _shift, _width, 0, 0)
133
134struct zx_clk_div {
135 struct clk_divider div;
136 u16 id;
27}; 137};
28 138
139#define DIV_T(_id, _name, _parent, _reg, _shift, _width, _flag, _table) \
140{ \
141 .div = { \
142 .reg = (void __iomem *) _reg, \
143 .shift = _shift, \
144 .width = _width, \
145 .flags = 0, \
146 .table = _table, \
147 .lock = &clk_lock, \
148 .hw.init = CLK_HW_INIT(_name, \
149 _parent, \
150 &clk_divider_ops, \
151 _flag), \
152 }, \
153 .id = _id, \
154}
155
29struct clk *clk_register_zx_pll(const char *name, const char *parent_name, 156struct clk *clk_register_zx_pll(const char *name, const char *parent_name,
30 unsigned long flags, void __iomem *reg_base, 157 unsigned long flags, void __iomem *reg_base,
31 const struct zx_pll_config *lookup_table, int count, spinlock_t *lock); 158 const struct zx_pll_config *lookup_table, int count, spinlock_t *lock);
@@ -38,4 +165,6 @@ struct clk_zx_audio {
38struct clk *clk_register_zx_audio(const char *name, 165struct clk *clk_register_zx_audio(const char *name,
39 const char * const parent_name, 166 const char * const parent_name,
40 unsigned long flags, void __iomem *reg_base); 167 unsigned long flags, void __iomem *reg_base);
168
169extern const struct clk_ops zx_pll_ops;
41#endif 170#endif
diff --git a/include/dt-bindings/clock/exynos5410.h b/include/dt-bindings/clock/exynos5410.h
index 85b467b3a207..6cb4e90f81fc 100644
--- a/include/dt-bindings/clock/exynos5410.h
+++ b/include/dt-bindings/clock/exynos5410.h
@@ -19,6 +19,7 @@
19#define CLK_FOUT_MPLL 4 19#define CLK_FOUT_MPLL 4
20#define CLK_FOUT_BPLL 5 20#define CLK_FOUT_BPLL 5
21#define CLK_FOUT_KPLL 6 21#define CLK_FOUT_KPLL 6
22#define CLK_FOUT_EPLL 7
22 23
23/* gate for special clocks (sclk) */ 24/* gate for special clocks (sclk) */
24#define CLK_SCLK_UART0 128 25#define CLK_SCLK_UART0 128
@@ -55,6 +56,8 @@
55#define CLK_MMC0 351 56#define CLK_MMC0 351
56#define CLK_MMC1 352 57#define CLK_MMC1 352
57#define CLK_MMC2 353 58#define CLK_MMC2 353
59#define CLK_PDMA0 362
60#define CLK_PDMA1 363
58#define CLK_USBH20 365 61#define CLK_USBH20 365
59#define CLK_USBD300 366 62#define CLK_USBD300 366
60#define CLK_USBD301 367 63#define CLK_USBD301 367
diff --git a/include/dt-bindings/clock/exynos5420.h b/include/dt-bindings/clock/exynos5420.h
index 17ab8394bec7..6fd21c291416 100644
--- a/include/dt-bindings/clock/exynos5420.h
+++ b/include/dt-bindings/clock/exynos5420.h
@@ -214,6 +214,9 @@
214#define CLK_MOUT_SW_ACLK400 651 214#define CLK_MOUT_SW_ACLK400 651
215#define CLK_MOUT_USER_ACLK300_GSCL 652 215#define CLK_MOUT_USER_ACLK300_GSCL 652
216#define CLK_MOUT_SW_ACLK300_GSCL 653 216#define CLK_MOUT_SW_ACLK300_GSCL 653
217#define CLK_MOUT_MCLK_CDREX 654
218#define CLK_MOUT_BPLL 655
219#define CLK_MOUT_MX_MSPLL_CCORE 656
217 220
218/* divider clocks */ 221/* divider clocks */
219#define CLK_DOUT_PIXEL 768 222#define CLK_DOUT_PIXEL 768
@@ -239,8 +242,14 @@
239#define CLK_DOUT_ACLK300_DISP1 788 242#define CLK_DOUT_ACLK300_DISP1 788
240#define CLK_DOUT_ACLK300_GSCL 789 243#define CLK_DOUT_ACLK300_GSCL 789
241#define CLK_DOUT_ACLK400_DISP1 790 244#define CLK_DOUT_ACLK400_DISP1 790
245#define CLK_DOUT_PCLK_CDREX 791
246#define CLK_DOUT_SCLK_CDREX 792
247#define CLK_DOUT_ACLK_CDREX1 793
248#define CLK_DOUT_CCLK_DREX0 794
249#define CLK_DOUT_CLK2X_PHY0 795
250#define CLK_DOUT_PCLK_CORE_MEM 796
242 251
243/* must be greater than maximal clock id */ 252/* must be greater than maximal clock id */
244#define CLK_NR_CLKS 791 253#define CLK_NR_CLKS 797
245 254
246#endif /* _DT_BINDINGS_CLOCK_EXYNOS_5420_H */ 255#endif /* _DT_BINDINGS_CLOCK_EXYNOS_5420_H */
diff --git a/include/dt-bindings/clock/exynos5440.h b/include/dt-bindings/clock/exynos5440.h
index c66fc405a79a..842cdc0adff1 100644
--- a/include/dt-bindings/clock/exynos5440.h
+++ b/include/dt-bindings/clock/exynos5440.h
@@ -14,6 +14,8 @@
14 14
15#define CLK_XTAL 1 15#define CLK_XTAL 1
16#define CLK_ARM_CLK 2 16#define CLK_ARM_CLK 2
17#define CLK_CPLLA 3
18#define CLK_CPLLB 4
17#define CLK_SPI_BAUD 16 19#define CLK_SPI_BAUD 16
18#define CLK_PB0_250 17 20#define CLK_PB0_250 17
19#define CLK_PR0_250 18 21#define CLK_PR0_250 18
diff --git a/include/dt-bindings/clock/gxbb-aoclkc.h b/include/dt-bindings/clock/gxbb-aoclkc.h
new file mode 100644
index 000000000000..31751482d13c
--- /dev/null
+++ b/include/dt-bindings/clock/gxbb-aoclkc.h
@@ -0,0 +1,66 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright (c) 2016 BayLibre, SAS.
8 * Author: Neil Armstrong <narmstrong@baylibre.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 * The full GNU General Public License is included in this distribution
22 * in the file called COPYING.
23 *
24 * BSD LICENSE
25 *
26 * Copyright (c) 2016 BayLibre, SAS.
27 * Author: Neil Armstrong <narmstrong@baylibre.com>
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef DT_BINDINGS_CLOCK_AMLOGIC_MESON_GXBB_AOCLK
57#define DT_BINDINGS_CLOCK_AMLOGIC_MESON_GXBB_AOCLK
58
59#define CLKID_AO_REMOTE 0
60#define CLKID_AO_I2C_MASTER 1
61#define CLKID_AO_I2C_SLAVE 2
62#define CLKID_AO_UART1 3
63#define CLKID_AO_UART2 4
64#define CLKID_AO_IR_BLASTER 5
65
66#endif
diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h
index f889d80246cb..ce4ad637083d 100644
--- a/include/dt-bindings/clock/gxbb-clkc.h
+++ b/include/dt-bindings/clock/gxbb-clkc.h
@@ -6,7 +6,14 @@
6#define __GXBB_CLKC_H 6#define __GXBB_CLKC_H
7 7
8#define CLKID_CPUCLK 1 8#define CLKID_CPUCLK 1
9#define CLKID_HDMI_PLL 2
10#define CLKID_FCLK_DIV2 4
11#define CLKID_FCLK_DIV3 5
12#define CLKID_FCLK_DIV4 6
9#define CLKID_CLK81 12 13#define CLKID_CLK81 12
10#define CLKID_ETH 36 14#define CLKID_ETH 36
15#define CLKID_SD_EMMC_A 94
16#define CLKID_SD_EMMC_B 95
17#define CLKID_SD_EMMC_C 96
11 18
12#endif /* __GXBB_CLKC_H */ 19#endif /* __GXBB_CLKC_H */
diff --git a/include/dt-bindings/clock/imx5-clock.h b/include/dt-bindings/clock/imx5-clock.h
index f4b7478e23c8..d382fc71aa83 100644
--- a/include/dt-bindings/clock/imx5-clock.h
+++ b/include/dt-bindings/clock/imx5-clock.h
@@ -201,6 +201,19 @@
201#define IMX5_CLK_STEP_SEL 189 201#define IMX5_CLK_STEP_SEL 189
202#define IMX5_CLK_CPU_PODF_SEL 190 202#define IMX5_CLK_CPU_PODF_SEL 190
203#define IMX5_CLK_ARM 191 203#define IMX5_CLK_ARM 191
204#define IMX5_CLK_END 192 204#define IMX5_CLK_FIRI_PRED 192
205#define IMX5_CLK_FIRI_SEL 193
206#define IMX5_CLK_FIRI_PODF 194
207#define IMX5_CLK_FIRI_SERIAL_GATE 195
208#define IMX5_CLK_FIRI_IPG_GATE 196
209#define IMX5_CLK_CSI0_MCLK1_PRED 197
210#define IMX5_CLK_CSI0_MCLK1_SEL 198
211#define IMX5_CLK_CSI0_MCLK1_PODF 199
212#define IMX5_CLK_CSI0_MCLK1_GATE 200
213#define IMX5_CLK_IEEE1588_PRED 201
214#define IMX5_CLK_IEEE1588_SEL 202
215#define IMX5_CLK_IEEE1588_PODF 203
216#define IMX5_CLK_IEEE1588_GATE 204
217#define IMX5_CLK_END 205
205 218
206#endif /* __DT_BINDINGS_CLOCK_IMX5_H */ 219#endif /* __DT_BINDINGS_CLOCK_IMX5_H */
diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h
index 29050337d9d5..da59fd9cdb5e 100644
--- a/include/dt-bindings/clock/imx6qdl-clock.h
+++ b/include/dt-bindings/clock/imx6qdl-clock.h
@@ -269,6 +269,8 @@
269#define IMX6QDL_CLK_PRG0_APB 256 269#define IMX6QDL_CLK_PRG0_APB 256
270#define IMX6QDL_CLK_PRG1_APB 257 270#define IMX6QDL_CLK_PRG1_APB 257
271#define IMX6QDL_CLK_PRE_AXI 258 271#define IMX6QDL_CLK_PRE_AXI 258
272#define IMX6QDL_CLK_END 259 272#define IMX6QDL_CLK_MLB_SEL 259
273#define IMX6QDL_CLK_MLB_PODF 260
274#define IMX6QDL_CLK_END 261
273 275
274#endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */ 276#endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
diff --git a/include/dt-bindings/clock/maxim,max77620.h b/include/dt-bindings/clock/maxim,max77620.h
new file mode 100644
index 000000000000..82aba2849681
--- /dev/null
+++ b/include/dt-bindings/clock/maxim,max77620.h
@@ -0,0 +1,21 @@
1/*
2 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Device Tree binding constants clocks for the Maxim 77620 PMIC.
9 */
10
11#ifndef _DT_BINDINGS_CLOCK_MAXIM_MAX77620_CLOCK_H
12#define _DT_BINDINGS_CLOCK_MAXIM_MAX77620_CLOCK_H
13
14/* Fixed rate clocks. */
15
16#define MAX77620_CLK_32K_OUT0 0
17
18/* Total number of clocks. */
19#define MAX77620_CLKS_NUM (MAX77620_CLK_32K_OUT0 + 1)
20
21#endif /* _DT_BINDINGS_CLOCK_MAXIM_MAX77620_CLOCK_H */
diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h
index 595a58d0969a..a55ff8c9b30f 100644
--- a/include/dt-bindings/clock/meson8b-clkc.h
+++ b/include/dt-bindings/clock/meson8b-clkc.h
@@ -22,6 +22,4 @@
22#define CLKID_MPEG_SEL 14 22#define CLKID_MPEG_SEL 14
23#define CLKID_MPEG_DIV 15 23#define CLKID_MPEG_DIV 15
24 24
25#define CLK_NR_CLKS (CLKID_MPEG_DIV + 1)
26
27#endif /* __MESON8B_CLKC_H */ 25#endif /* __MESON8B_CLKC_H */
diff --git a/include/dt-bindings/clock/mt2701-clk.h b/include/dt-bindings/clock/mt2701-clk.h
new file mode 100644
index 000000000000..2062c67e2e51
--- /dev/null
+++ b/include/dt-bindings/clock/mt2701-clk.h
@@ -0,0 +1,486 @@
1/*
2 * Copyright (c) 2014 MediaTek Inc.
3 * Author: Shunli Wang <shunli.wang@mediatek.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#ifndef _DT_BINDINGS_CLK_MT2701_H
16#define _DT_BINDINGS_CLK_MT2701_H
17
18/* TOPCKGEN */
19#define CLK_TOP_SYSPLL 1
20#define CLK_TOP_SYSPLL_D2 2
21#define CLK_TOP_SYSPLL_D3 3
22#define CLK_TOP_SYSPLL_D5 4
23#define CLK_TOP_SYSPLL_D7 5
24#define CLK_TOP_SYSPLL1_D2 6
25#define CLK_TOP_SYSPLL1_D4 7
26#define CLK_TOP_SYSPLL1_D8 8
27#define CLK_TOP_SYSPLL1_D16 9
28#define CLK_TOP_SYSPLL2_D2 10
29#define CLK_TOP_SYSPLL2_D4 11
30#define CLK_TOP_SYSPLL2_D8 12
31#define CLK_TOP_SYSPLL3_D2 13
32#define CLK_TOP_SYSPLL3_D4 14
33#define CLK_TOP_SYSPLL4_D2 15
34#define CLK_TOP_SYSPLL4_D4 16
35#define CLK_TOP_UNIVPLL 17
36#define CLK_TOP_UNIVPLL_D2 18
37#define CLK_TOP_UNIVPLL_D3 19
38#define CLK_TOP_UNIVPLL_D5 20
39#define CLK_TOP_UNIVPLL_D7 21
40#define CLK_TOP_UNIVPLL_D26 22
41#define CLK_TOP_UNIVPLL_D52 23
42#define CLK_TOP_UNIVPLL_D108 24
43#define CLK_TOP_USB_PHY48M 25
44#define CLK_TOP_UNIVPLL1_D2 26
45#define CLK_TOP_UNIVPLL1_D4 27
46#define CLK_TOP_UNIVPLL1_D8 28
47#define CLK_TOP_UNIVPLL2_D2 29
48#define CLK_TOP_UNIVPLL2_D4 30
49#define CLK_TOP_UNIVPLL2_D8 31
50#define CLK_TOP_UNIVPLL2_D16 32
51#define CLK_TOP_UNIVPLL2_D32 33
52#define CLK_TOP_UNIVPLL3_D2 34
53#define CLK_TOP_UNIVPLL3_D4 35
54#define CLK_TOP_UNIVPLL3_D8 36
55#define CLK_TOP_MSDCPLL 37
56#define CLK_TOP_MSDCPLL_D2 38
57#define CLK_TOP_MSDCPLL_D4 39
58#define CLK_TOP_MSDCPLL_D8 40
59#define CLK_TOP_MMPLL 41
60#define CLK_TOP_MMPLL_D2 42
61#define CLK_TOP_DMPLL 43
62#define CLK_TOP_DMPLL_D2 44
63#define CLK_TOP_DMPLL_D4 45
64#define CLK_TOP_DMPLL_X2 46
65#define CLK_TOP_TVDPLL 47
66#define CLK_TOP_TVDPLL_D2 48
67#define CLK_TOP_TVDPLL_D4 49
68#define CLK_TOP_TVD2PLL 50
69#define CLK_TOP_TVD2PLL_D2 51
70#define CLK_TOP_HADDS2PLL_98M 52
71#define CLK_TOP_HADDS2PLL_294M 53
72#define CLK_TOP_HADDS2_FB 54
73#define CLK_TOP_MIPIPLL_D2 55
74#define CLK_TOP_MIPIPLL_D4 56
75#define CLK_TOP_HDMIPLL 57
76#define CLK_TOP_HDMIPLL_D2 58
77#define CLK_TOP_HDMIPLL_D3 59
78#define CLK_TOP_HDMI_SCL_RX 60
79#define CLK_TOP_HDMI_0_PIX340M 61
80#define CLK_TOP_HDMI_0_DEEP340M 62
81#define CLK_TOP_HDMI_0_PLL340M 63
82#define CLK_TOP_AUD1PLL_98M 64
83#define CLK_TOP_AUD2PLL_90M 65
84#define CLK_TOP_AUDPLL 66
85#define CLK_TOP_AUDPLL_D4 67
86#define CLK_TOP_AUDPLL_D8 68
87#define CLK_TOP_AUDPLL_D16 69
88#define CLK_TOP_AUDPLL_D24 70
89#define CLK_TOP_ETHPLL_500M 71
90#define CLK_TOP_VDECPLL 72
91#define CLK_TOP_VENCPLL 73
92#define CLK_TOP_MIPIPLL 74
93#define CLK_TOP_ARMPLL_1P3G 75
94
95#define CLK_TOP_MM_SEL 76
96#define CLK_TOP_DDRPHYCFG_SEL 77
97#define CLK_TOP_MEM_SEL 78
98#define CLK_TOP_AXI_SEL 79
99#define CLK_TOP_CAMTG_SEL 80
100#define CLK_TOP_MFG_SEL 81
101#define CLK_TOP_VDEC_SEL 82
102#define CLK_TOP_PWM_SEL 83
103#define CLK_TOP_MSDC30_0_SEL 84
104#define CLK_TOP_USB20_SEL 85
105#define CLK_TOP_SPI0_SEL 86
106#define CLK_TOP_UART_SEL 87
107#define CLK_TOP_AUDINTBUS_SEL 88
108#define CLK_TOP_AUDIO_SEL 89
109#define CLK_TOP_MSDC30_2_SEL 90
110#define CLK_TOP_MSDC30_1_SEL 91
111#define CLK_TOP_DPI1_SEL 92
112#define CLK_TOP_DPI0_SEL 93
113#define CLK_TOP_SCP_SEL 94
114#define CLK_TOP_PMICSPI_SEL 95
115#define CLK_TOP_APLL_SEL 96
116#define CLK_TOP_HDMI_SEL 97
117#define CLK_TOP_TVE_SEL 98
118#define CLK_TOP_EMMC_HCLK_SEL 99
119#define CLK_TOP_NFI2X_SEL 100
120#define CLK_TOP_RTC_SEL 101
121#define CLK_TOP_OSD_SEL 102
122#define CLK_TOP_NR_SEL 103
123#define CLK_TOP_DI_SEL 104
124#define CLK_TOP_FLASH_SEL 105
125#define CLK_TOP_ASM_M_SEL 106
126#define CLK_TOP_ASM_I_SEL 107
127#define CLK_TOP_INTDIR_SEL 108
128#define CLK_TOP_HDMIRX_BIST_SEL 109
129#define CLK_TOP_ETHIF_SEL 110
130#define CLK_TOP_MS_CARD_SEL 111
131#define CLK_TOP_ASM_H_SEL 112
132#define CLK_TOP_SPI1_SEL 113
133#define CLK_TOP_CMSYS_SEL 114
134#define CLK_TOP_MSDC30_3_SEL 115
135#define CLK_TOP_HDMIRX26_24_SEL 116
136#define CLK_TOP_AUD2DVD_SEL 117
137#define CLK_TOP_8BDAC_SEL 118
138#define CLK_TOP_SPI2_SEL 119
139#define CLK_TOP_AUD_MUX1_SEL 120
140#define CLK_TOP_AUD_MUX2_SEL 121
141#define CLK_TOP_AUDPLL_MUX_SEL 122
142#define CLK_TOP_AUD_K1_SRC_SEL 123
143#define CLK_TOP_AUD_K2_SRC_SEL 124
144#define CLK_TOP_AUD_K3_SRC_SEL 125
145#define CLK_TOP_AUD_K4_SRC_SEL 126
146#define CLK_TOP_AUD_K5_SRC_SEL 127
147#define CLK_TOP_AUD_K6_SRC_SEL 128
148#define CLK_TOP_PADMCLK_SEL 129
149#define CLK_TOP_AUD_EXTCK1_DIV 130
150#define CLK_TOP_AUD_EXTCK2_DIV 131
151#define CLK_TOP_AUD_MUX1_DIV 132
152#define CLK_TOP_AUD_MUX2_DIV 133
153#define CLK_TOP_AUD_K1_SRC_DIV 134
154#define CLK_TOP_AUD_K2_SRC_DIV 135
155#define CLK_TOP_AUD_K3_SRC_DIV 136
156#define CLK_TOP_AUD_K4_SRC_DIV 137
157#define CLK_TOP_AUD_K5_SRC_DIV 138
158#define CLK_TOP_AUD_K6_SRC_DIV 139
159#define CLK_TOP_AUD_I2S1_MCLK 140
160#define CLK_TOP_AUD_I2S2_MCLK 141
161#define CLK_TOP_AUD_I2S3_MCLK 142
162#define CLK_TOP_AUD_I2S4_MCLK 143
163#define CLK_TOP_AUD_I2S5_MCLK 144
164#define CLK_TOP_AUD_I2S6_MCLK 145
165#define CLK_TOP_AUD_48K_TIMING 146
166#define CLK_TOP_AUD_44K_TIMING 147
167
168#define CLK_TOP_32K_INTERNAL 148
169#define CLK_TOP_32K_EXTERNAL 149
170#define CLK_TOP_CLK26M_D8 150
171#define CLK_TOP_8BDAC 151
172#define CLK_TOP_WBG_DIG_416M 152
173#define CLK_TOP_DPI 153
174#define CLK_TOP_HDMITX_CLKDIG_CTS 154
175#define CLK_TOP_DSI0_LNTC_DSI 155
176#define CLK_TOP_AUD_EXT1 156
177#define CLK_TOP_AUD_EXT2 157
178#define CLK_TOP_NFI1X_PAD 158
179#define CLK_TOP_NR 159
180
181/* APMIXEDSYS */
182
183#define CLK_APMIXED_ARMPLL 1
184#define CLK_APMIXED_MAINPLL 2
185#define CLK_APMIXED_UNIVPLL 3
186#define CLK_APMIXED_MMPLL 4
187#define CLK_APMIXED_MSDCPLL 5
188#define CLK_APMIXED_TVDPLL 6
189#define CLK_APMIXED_AUD1PLL 7
190#define CLK_APMIXED_TRGPLL 8
191#define CLK_APMIXED_ETHPLL 9
192#define CLK_APMIXED_VDECPLL 10
193#define CLK_APMIXED_HADDS2PLL 11
194#define CLK_APMIXED_AUD2PLL 12
195#define CLK_APMIXED_TVD2PLL 13
196#define CLK_APMIXED_NR 14
197
198/* DDRPHY */
199
200#define CLK_DDRPHY_VENCPLL 1
201#define CLK_DDRPHY_NR 2
202
203/* INFRACFG */
204
205#define CLK_INFRA_DBG 1
206#define CLK_INFRA_SMI 2
207#define CLK_INFRA_QAXI_CM4 3
208#define CLK_INFRA_AUD_SPLIN_B 4
209#define CLK_INFRA_AUDIO 5
210#define CLK_INFRA_EFUSE 6
211#define CLK_INFRA_L2C_SRAM 7
212#define CLK_INFRA_M4U 8
213#define CLK_INFRA_CONNMCU 9
214#define CLK_INFRA_TRNG 10
215#define CLK_INFRA_RAMBUFIF 11
216#define CLK_INFRA_CPUM 12
217#define CLK_INFRA_KP 13
218#define CLK_INFRA_CEC 14
219#define CLK_INFRA_IRRX 15
220#define CLK_INFRA_PMICSPI 16
221#define CLK_INFRA_PMICWRAP 17
222#define CLK_INFRA_DDCCI 18
223#define CLK_INFRA_CLK_13M 19
224#define CLK_INFRA_NR 20
225
226/* PERICFG */
227
228#define CLK_PERI_NFI 1
229#define CLK_PERI_THERM 2
230#define CLK_PERI_PWM1 3
231#define CLK_PERI_PWM2 4
232#define CLK_PERI_PWM3 5
233#define CLK_PERI_PWM4 6
234#define CLK_PERI_PWM5 7
235#define CLK_PERI_PWM6 8
236#define CLK_PERI_PWM7 9
237#define CLK_PERI_PWM 10
238#define CLK_PERI_USB0 11
239#define CLK_PERI_USB1 12
240#define CLK_PERI_AP_DMA 13
241#define CLK_PERI_MSDC30_0 14
242#define CLK_PERI_MSDC30_1 15
243#define CLK_PERI_MSDC30_2 16
244#define CLK_PERI_MSDC30_3 17
245#define CLK_PERI_MSDC50_3 18
246#define CLK_PERI_NLI 19
247#define CLK_PERI_UART0 20
248#define CLK_PERI_UART1 21
249#define CLK_PERI_UART2 22
250#define CLK_PERI_UART3 23
251#define CLK_PERI_BTIF 24
252#define CLK_PERI_I2C0 25
253#define CLK_PERI_I2C1 26
254#define CLK_PERI_I2C2 27
255#define CLK_PERI_I2C3 28
256#define CLK_PERI_AUXADC 29
257#define CLK_PERI_SPI0 30
258#define CLK_PERI_ETH 31
259#define CLK_PERI_USB0_MCU 32
260
261#define CLK_PERI_USB1_MCU 33
262#define CLK_PERI_USB_SLV 34
263#define CLK_PERI_GCPU 35
264#define CLK_PERI_NFI_ECC 36
265#define CLK_PERI_NFI_PAD 37
266#define CLK_PERI_FLASH 38
267#define CLK_PERI_HOST89_INT 39
268#define CLK_PERI_HOST89_SPI 40
269#define CLK_PERI_HOST89_DVD 41
270#define CLK_PERI_SPI1 42
271#define CLK_PERI_SPI2 43
272#define CLK_PERI_FCI 44
273
274#define CLK_PERI_UART0_SEL 45
275#define CLK_PERI_UART1_SEL 46
276#define CLK_PERI_UART2_SEL 47
277#define CLK_PERI_UART3_SEL 48
278#define CLK_PERI_NR 49
279
280/* AUDIO */
281
282#define CLK_AUD_AFE 1
283#define CLK_AUD_LRCK_DETECT 2
284#define CLK_AUD_I2S 3
285#define CLK_AUD_APLL_TUNER 4
286#define CLK_AUD_HDMI 5
287#define CLK_AUD_SPDF 6
288#define CLK_AUD_SPDF2 7
289#define CLK_AUD_APLL 8
290#define CLK_AUD_TML 9
291#define CLK_AUD_AHB_IDLE_EXT 10
292#define CLK_AUD_AHB_IDLE_INT 11
293
294#define CLK_AUD_I2SIN1 12
295#define CLK_AUD_I2SIN2 13
296#define CLK_AUD_I2SIN3 14
297#define CLK_AUD_I2SIN4 15
298#define CLK_AUD_I2SIN5 16
299#define CLK_AUD_I2SIN6 17
300#define CLK_AUD_I2SO1 18
301#define CLK_AUD_I2SO2 19
302#define CLK_AUD_I2SO3 20
303#define CLK_AUD_I2SO4 21
304#define CLK_AUD_I2SO5 22
305#define CLK_AUD_I2SO6 23
306#define CLK_AUD_ASRCI1 24
307#define CLK_AUD_ASRCI2 25
308#define CLK_AUD_ASRCO1 26
309#define CLK_AUD_ASRCO2 27
310#define CLK_AUD_ASRC11 28
311#define CLK_AUD_ASRC12 29
312#define CLK_AUD_HDMIRX 30
313#define CLK_AUD_INTDIR 31
314#define CLK_AUD_A1SYS 32
315#define CLK_AUD_A2SYS 33
316#define CLK_AUD_AFE_CONN 34
317#define CLK_AUD_AFE_PCMIF 35
318#define CLK_AUD_AFE_MRGIF 36
319
320#define CLK_AUD_MMIF_UL1 37
321#define CLK_AUD_MMIF_UL2 38
322#define CLK_AUD_MMIF_UL3 39
323#define CLK_AUD_MMIF_UL4 40
324#define CLK_AUD_MMIF_UL5 41
325#define CLK_AUD_MMIF_UL6 42
326#define CLK_AUD_MMIF_DL1 43
327#define CLK_AUD_MMIF_DL2 44
328#define CLK_AUD_MMIF_DL3 45
329#define CLK_AUD_MMIF_DL4 46
330#define CLK_AUD_MMIF_DL5 47
331#define CLK_AUD_MMIF_DL6 48
332#define CLK_AUD_MMIF_DLMCH 49
333#define CLK_AUD_MMIF_ARB1 50
334#define CLK_AUD_MMIF_AWB1 51
335#define CLK_AUD_MMIF_AWB2 52
336#define CLK_AUD_MMIF_DAI 53
337
338#define CLK_AUD_DMIC1 54
339#define CLK_AUD_DMIC2 55
340#define CLK_AUD_ASRCI3 56
341#define CLK_AUD_ASRCI4 57
342#define CLK_AUD_ASRCI5 58
343#define CLK_AUD_ASRCI6 59
344#define CLK_AUD_ASRCO3 60
345#define CLK_AUD_ASRCO4 61
346#define CLK_AUD_ASRCO5 62
347#define CLK_AUD_ASRCO6 63
348#define CLK_AUD_MEM_ASRC1 64
349#define CLK_AUD_MEM_ASRC2 65
350#define CLK_AUD_MEM_ASRC3 66
351#define CLK_AUD_MEM_ASRC4 67
352#define CLK_AUD_MEM_ASRC5 68
353#define CLK_AUD_DSD_ENC 69
354#define CLK_AUD_ASRC_BRG 70
355#define CLK_AUD_NR 71
356
357/* MMSYS */
358
359#define CLK_MM_SMI_COMMON 1
360#define CLK_MM_SMI_LARB0 2
361#define CLK_MM_CMDQ 3
362#define CLK_MM_MUTEX 4
363#define CLK_MM_DISP_COLOR 5
364#define CLK_MM_DISP_BLS 6
365#define CLK_MM_DISP_WDMA 7
366#define CLK_MM_DISP_RDMA 8
367#define CLK_MM_DISP_OVL 9
368#define CLK_MM_MDP_TDSHP 10
369#define CLK_MM_MDP_WROT 11
370#define CLK_MM_MDP_WDMA 12
371#define CLK_MM_MDP_RSZ1 13
372#define CLK_MM_MDP_RSZ0 14
373#define CLK_MM_MDP_RDMA 15
374#define CLK_MM_MDP_BLS_26M 16
375#define CLK_MM_CAM_MDP 17
376#define CLK_MM_FAKE_ENG 18
377#define CLK_MM_MUTEX_32K 19
378#define CLK_MM_DISP_RDMA1 20
379#define CLK_MM_DISP_UFOE 21
380
381#define CLK_MM_DSI_ENGINE 22
382#define CLK_MM_DSI_DIG 23
383#define CLK_MM_DPI_DIGL 24
384#define CLK_MM_DPI_ENGINE 25
385#define CLK_MM_DPI1_DIGL 26
386#define CLK_MM_DPI1_ENGINE 27
387#define CLK_MM_TVE_OUTPUT 28
388#define CLK_MM_TVE_INPUT 29
389#define CLK_MM_HDMI_PIXEL 30
390#define CLK_MM_HDMI_PLL 31
391#define CLK_MM_HDMI_AUDIO 32
392#define CLK_MM_HDMI_SPDIF 33
393#define CLK_MM_TVE_FMM 34
394#define CLK_MM_NR 35
395
396/* IMGSYS */
397
398#define CLK_IMG_SMI_COMM 1
399#define CLK_IMG_RESZ 2
400#define CLK_IMG_JPGDEC_SMI 3
401#define CLK_IMG_JPGDEC 4
402#define CLK_IMG_VENC_LT 5
403#define CLK_IMG_VENC 6
404#define CLK_IMG_NR 7
405
406/* VDEC */
407
408#define CLK_VDEC_CKGEN 1
409#define CLK_VDEC_LARB 2
410#define CLK_VDEC_NR 3
411
412/* HIFSYS */
413
414#define CLK_HIFSYS_USB0PHY 1
415#define CLK_HIFSYS_USB1PHY 2
416#define CLK_HIFSYS_PCIE0 3
417#define CLK_HIFSYS_PCIE1 4
418#define CLK_HIFSYS_PCIE2 5
419#define CLK_HIFSYS_NR 6
420
421/* ETHSYS */
422#define CLK_ETHSYS_HSDMA 1
423#define CLK_ETHSYS_ESW 2
424#define CLK_ETHSYS_GP2 3
425#define CLK_ETHSYS_GP1 4
426#define CLK_ETHSYS_PCM 5
427#define CLK_ETHSYS_GDMA 6
428#define CLK_ETHSYS_I2S 7
429#define CLK_ETHSYS_CRYPTO 8
430#define CLK_ETHSYS_NR 9
431
432/* BDP */
433
434#define CLK_BDP_BRG_BA 1
435#define CLK_BDP_BRG_DRAM 2
436#define CLK_BDP_LARB_DRAM 3
437#define CLK_BDP_WR_VDI_PXL 4
438#define CLK_BDP_WR_VDI_DRAM 5
439#define CLK_BDP_WR_B 6
440#define CLK_BDP_DGI_IN 7
441#define CLK_BDP_DGI_OUT 8
442#define CLK_BDP_FMT_MAST_27 9
443#define CLK_BDP_FMT_B 10
444#define CLK_BDP_OSD_B 11
445#define CLK_BDP_OSD_DRAM 12
446#define CLK_BDP_OSD_AGENT 13
447#define CLK_BDP_OSD_PXL 14
448#define CLK_BDP_RLE_B 15
449#define CLK_BDP_RLE_AGENT 16
450#define CLK_BDP_RLE_DRAM 17
451#define CLK_BDP_F27M 18
452#define CLK_BDP_F27M_VDOUT 19
453#define CLK_BDP_F27_74_74 20
454#define CLK_BDP_F2FS 21
455#define CLK_BDP_F2FS74_148 22
456#define CLK_BDP_FB 23
457#define CLK_BDP_VDO_DRAM 24
458#define CLK_BDP_VDO_2FS 25
459#define CLK_BDP_VDO_B 26
460#define CLK_BDP_WR_DI_PXL 27
461#define CLK_BDP_WR_DI_DRAM 28
462#define CLK_BDP_WR_DI_B 29
463#define CLK_BDP_NR_PXL 30
464#define CLK_BDP_NR_DRAM 31
465#define CLK_BDP_NR_B 32
466
467#define CLK_BDP_RX_F 33
468#define CLK_BDP_RX_X 34
469#define CLK_BDP_RXPDT 35
470#define CLK_BDP_RX_CSCL_N 36
471#define CLK_BDP_RX_CSCL 37
472#define CLK_BDP_RX_DDCSCL_N 38
473#define CLK_BDP_RX_DDCSCL 39
474#define CLK_BDP_RX_VCO 40
475#define CLK_BDP_RX_DP 41
476#define CLK_BDP_RX_P 42
477#define CLK_BDP_RX_M 43
478#define CLK_BDP_RX_PLL 44
479#define CLK_BDP_BRG_RT_B 45
480#define CLK_BDP_BRG_RT_DRAM 46
481#define CLK_BDP_LARBRT_DRAM 47
482#define CLK_BDP_TMDS_SYN 48
483#define CLK_BDP_HDMI_MON 49
484#define CLK_BDP_NR 50
485
486#endif /* _DT_BINDINGS_CLK_MT2701_H */
diff --git a/include/dt-bindings/clock/qcom,gcc-mdm9615.h b/include/dt-bindings/clock/qcom,gcc-mdm9615.h
new file mode 100644
index 000000000000..9ab2c4087120
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,gcc-mdm9615.h
@@ -0,0 +1,327 @@
1/*
2 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
3 * Copyright (c) BayLibre, SAS.
4 * Author : Neil Armstrong <narmstrong@baylibre.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef _DT_BINDINGS_CLK_MDM_GCC_9615_H
17#define _DT_BINDINGS_CLK_MDM_GCC_9615_H
18
19#define AFAB_CLK_SRC 0
20#define AFAB_CORE_CLK 1
21#define SFAB_MSS_Q6_SW_A_CLK 2
22#define SFAB_MSS_Q6_FW_A_CLK 3
23#define QDSS_STM_CLK 4
24#define SCSS_A_CLK 5
25#define SCSS_H_CLK 6
26#define SCSS_XO_SRC_CLK 7
27#define AFAB_EBI1_CH0_A_CLK 8
28#define AFAB_EBI1_CH1_A_CLK 9
29#define AFAB_AXI_S0_FCLK 10
30#define AFAB_AXI_S1_FCLK 11
31#define AFAB_AXI_S2_FCLK 12
32#define AFAB_AXI_S3_FCLK 13
33#define AFAB_AXI_S4_FCLK 14
34#define SFAB_CORE_CLK 15
35#define SFAB_AXI_S0_FCLK 16
36#define SFAB_AXI_S1_FCLK 17
37#define SFAB_AXI_S2_FCLK 18
38#define SFAB_AXI_S3_FCLK 19
39#define SFAB_AXI_S4_FCLK 20
40#define SFAB_AHB_S0_FCLK 21
41#define SFAB_AHB_S1_FCLK 22
42#define SFAB_AHB_S2_FCLK 23
43#define SFAB_AHB_S3_FCLK 24
44#define SFAB_AHB_S4_FCLK 25
45#define SFAB_AHB_S5_FCLK 26
46#define SFAB_AHB_S6_FCLK 27
47#define SFAB_AHB_S7_FCLK 28
48#define QDSS_AT_CLK_SRC 29
49#define QDSS_AT_CLK 30
50#define QDSS_TRACECLKIN_CLK_SRC 31
51#define QDSS_TRACECLKIN_CLK 32
52#define QDSS_TSCTR_CLK_SRC 33
53#define QDSS_TSCTR_CLK 34
54#define SFAB_ADM0_M0_A_CLK 35
55#define SFAB_ADM0_M1_A_CLK 36
56#define SFAB_ADM0_M2_H_CLK 37
57#define ADM0_CLK 38
58#define ADM0_PBUS_CLK 39
59#define MSS_XPU_CLK 40
60#define IMEM0_A_CLK 41
61#define QDSS_H_CLK 42
62#define PCIE_A_CLK 43
63#define PCIE_AUX_CLK 44
64#define PCIE_PHY_REF_CLK 45
65#define PCIE_H_CLK 46
66#define SFAB_CLK_SRC 47
67#define MAHB0_CLK 48
68#define Q6SW_CLK_SRC 49
69#define Q6SW_CLK 50
70#define Q6FW_CLK_SRC 51
71#define Q6FW_CLK 52
72#define SFAB_MSS_M_A_CLK 53
73#define SFAB_USB3_M_A_CLK 54
74#define SFAB_LPASS_Q6_A_CLK 55
75#define SFAB_AFAB_M_A_CLK 56
76#define AFAB_SFAB_M0_A_CLK 57
77#define AFAB_SFAB_M1_A_CLK 58
78#define SFAB_SATA_S_H_CLK 59
79#define DFAB_CLK_SRC 60
80#define DFAB_CLK 61
81#define SFAB_DFAB_M_A_CLK 62
82#define DFAB_SFAB_M_A_CLK 63
83#define DFAB_SWAY0_H_CLK 64
84#define DFAB_SWAY1_H_CLK 65
85#define DFAB_ARB0_H_CLK 66
86#define DFAB_ARB1_H_CLK 67
87#define PPSS_H_CLK 68
88#define PPSS_PROC_CLK 69
89#define PPSS_TIMER0_CLK 70
90#define PPSS_TIMER1_CLK 71
91#define PMEM_A_CLK 72
92#define DMA_BAM_H_CLK 73
93#define SIC_H_CLK 74
94#define SPS_TIC_H_CLK 75
95#define SLIMBUS_H_CLK 76
96#define SLIMBUS_XO_SRC_CLK 77
97#define CFPB_2X_CLK_SRC 78
98#define CFPB_CLK 79
99#define CFPB0_H_CLK 80
100#define CFPB1_H_CLK 81
101#define CFPB2_H_CLK 82
102#define SFAB_CFPB_M_H_CLK 83
103#define CFPB_MASTER_H_CLK 84
104#define SFAB_CFPB_S_H_CLK 85
105#define CFPB_SPLITTER_H_CLK 86
106#define TSIF_H_CLK 87
107#define TSIF_INACTIVITY_TIMERS_CLK 88
108#define TSIF_REF_SRC 89
109#define TSIF_REF_CLK 90
110#define CE1_H_CLK 91
111#define CE1_CORE_CLK 92
112#define CE1_SLEEP_CLK 93
113#define CE2_H_CLK 94
114#define CE2_CORE_CLK 95
115#define SFPB_H_CLK_SRC 97
116#define SFPB_H_CLK 98
117#define SFAB_SFPB_M_H_CLK 99
118#define SFAB_SFPB_S_H_CLK 100
119#define RPM_PROC_CLK 101
120#define RPM_BUS_H_CLK 102
121#define RPM_SLEEP_CLK 103
122#define RPM_TIMER_CLK 104
123#define RPM_MSG_RAM_H_CLK 105
124#define PMIC_ARB0_H_CLK 106
125#define PMIC_ARB1_H_CLK 107
126#define PMIC_SSBI2_SRC 108
127#define PMIC_SSBI2_CLK 109
128#define SDC1_H_CLK 110
129#define SDC2_H_CLK 111
130#define SDC3_H_CLK 112
131#define SDC4_H_CLK 113
132#define SDC5_H_CLK 114
133#define SDC1_SRC 115
134#define SDC2_SRC 116
135#define SDC3_SRC 117
136#define SDC4_SRC 118
137#define SDC5_SRC 119
138#define SDC1_CLK 120
139#define SDC2_CLK 121
140#define SDC3_CLK 122
141#define SDC4_CLK 123
142#define SDC5_CLK 124
143#define DFAB_A2_H_CLK 125
144#define USB_HS1_H_CLK 126
145#define USB_HS1_XCVR_SRC 127
146#define USB_HS1_XCVR_CLK 128
147#define USB_HSIC_H_CLK 129
148#define USB_HSIC_XCVR_FS_SRC 130
149#define USB_HSIC_XCVR_FS_CLK 131
150#define USB_HSIC_SYSTEM_CLK_SRC 132
151#define USB_HSIC_SYSTEM_CLK 133
152#define CFPB0_C0_H_CLK 134
153#define CFPB0_C1_H_CLK 135
154#define CFPB0_D0_H_CLK 136
155#define CFPB0_D1_H_CLK 137
156#define USB_FS1_H_CLK 138
157#define USB_FS1_XCVR_FS_SRC 139
158#define USB_FS1_XCVR_FS_CLK 140
159#define USB_FS1_SYSTEM_CLK 141
160#define USB_FS2_H_CLK 142
161#define USB_FS2_XCVR_FS_SRC 143
162#define USB_FS2_XCVR_FS_CLK 144
163#define USB_FS2_SYSTEM_CLK 145
164#define GSBI_COMMON_SIM_SRC 146
165#define GSBI1_H_CLK 147
166#define GSBI2_H_CLK 148
167#define GSBI3_H_CLK 149
168#define GSBI4_H_CLK 150
169#define GSBI5_H_CLK 151
170#define GSBI6_H_CLK 152
171#define GSBI7_H_CLK 153
172#define GSBI8_H_CLK 154
173#define GSBI9_H_CLK 155
174#define GSBI10_H_CLK 156
175#define GSBI11_H_CLK 157
176#define GSBI12_H_CLK 158
177#define GSBI1_UART_SRC 159
178#define GSBI1_UART_CLK 160
179#define GSBI2_UART_SRC 161
180#define GSBI2_UART_CLK 162
181#define GSBI3_UART_SRC 163
182#define GSBI3_UART_CLK 164
183#define GSBI4_UART_SRC 165
184#define GSBI4_UART_CLK 166
185#define GSBI5_UART_SRC 167
186#define GSBI5_UART_CLK 168
187#define GSBI6_UART_SRC 169
188#define GSBI6_UART_CLK 170
189#define GSBI7_UART_SRC 171
190#define GSBI7_UART_CLK 172
191#define GSBI8_UART_SRC 173
192#define GSBI8_UART_CLK 174
193#define GSBI9_UART_SRC 175
194#define GSBI9_UART_CLK 176
195#define GSBI10_UART_SRC 177
196#define GSBI10_UART_CLK 178
197#define GSBI11_UART_SRC 179
198#define GSBI11_UART_CLK 180
199#define GSBI12_UART_SRC 181
200#define GSBI12_UART_CLK 182
201#define GSBI1_QUP_SRC 183
202#define GSBI1_QUP_CLK 184
203#define GSBI2_QUP_SRC 185
204#define GSBI2_QUP_CLK 186
205#define GSBI3_QUP_SRC 187
206#define GSBI3_QUP_CLK 188
207#define GSBI4_QUP_SRC 189
208#define GSBI4_QUP_CLK 190
209#define GSBI5_QUP_SRC 191
210#define GSBI5_QUP_CLK 192
211#define GSBI6_QUP_SRC 193
212#define GSBI6_QUP_CLK 194
213#define GSBI7_QUP_SRC 195
214#define GSBI7_QUP_CLK 196
215#define GSBI8_QUP_SRC 197
216#define GSBI8_QUP_CLK 198
217#define GSBI9_QUP_SRC 199
218#define GSBI9_QUP_CLK 200
219#define GSBI10_QUP_SRC 201
220#define GSBI10_QUP_CLK 202
221#define GSBI11_QUP_SRC 203
222#define GSBI11_QUP_CLK 204
223#define GSBI12_QUP_SRC 205
224#define GSBI12_QUP_CLK 206
225#define GSBI1_SIM_CLK 207
226#define GSBI2_SIM_CLK 208
227#define GSBI3_SIM_CLK 209
228#define GSBI4_SIM_CLK 210
229#define GSBI5_SIM_CLK 211
230#define GSBI6_SIM_CLK 212
231#define GSBI7_SIM_CLK 213
232#define GSBI8_SIM_CLK 214
233#define GSBI9_SIM_CLK 215
234#define GSBI10_SIM_CLK 216
235#define GSBI11_SIM_CLK 217
236#define GSBI12_SIM_CLK 218
237#define USB_HSIC_HSIC_CLK_SRC 219
238#define USB_HSIC_HSIC_CLK 220
239#define USB_HSIC_HSIO_CAL_CLK 221
240#define SPDM_CFG_H_CLK 222
241#define SPDM_MSTR_H_CLK 223
242#define SPDM_FF_CLK_SRC 224
243#define SPDM_FF_CLK 225
244#define SEC_CTRL_CLK 226
245#define SEC_CTRL_ACC_CLK_SRC 227
246#define SEC_CTRL_ACC_CLK 228
247#define TLMM_H_CLK 229
248#define TLMM_CLK 230
249#define SFAB_MSS_S_H_CLK 231
250#define MSS_SLP_CLK 232
251#define MSS_Q6SW_JTAG_CLK 233
252#define MSS_Q6FW_JTAG_CLK 234
253#define MSS_S_H_CLK 235
254#define MSS_CXO_SRC_CLK 236
255#define SATA_H_CLK 237
256#define SATA_CLK_SRC 238
257#define SATA_RXOOB_CLK 239
258#define SATA_PMALIVE_CLK 240
259#define SATA_PHY_REF_CLK 241
260#define TSSC_CLK_SRC 242
261#define TSSC_CLK 243
262#define PDM_SRC 244
263#define PDM_CLK 245
264#define GP0_SRC 246
265#define GP0_CLK 247
266#define GP1_SRC 248
267#define GP1_CLK 249
268#define GP2_SRC 250
269#define GP2_CLK 251
270#define MPM_CLK 252
271#define EBI1_CLK_SRC 253
272#define EBI1_CH0_CLK 254
273#define EBI1_CH1_CLK 255
274#define EBI1_2X_CLK 256
275#define EBI1_CH0_DQ_CLK 257
276#define EBI1_CH1_DQ_CLK 258
277#define EBI1_CH0_CA_CLK 259
278#define EBI1_CH1_CA_CLK 260
279#define EBI1_XO_CLK 261
280#define SFAB_SMPSS_S_H_CLK 262
281#define PRNG_SRC 263
282#define PRNG_CLK 264
283#define PXO_SRC 265
284#define LPASS_CXO_CLK 266
285#define LPASS_PXO_CLK 267
286#define SPDM_CY_PORT0_CLK 268
287#define SPDM_CY_PORT1_CLK 269
288#define SPDM_CY_PORT2_CLK 270
289#define SPDM_CY_PORT3_CLK 271
290#define SPDM_CY_PORT4_CLK 272
291#define SPDM_CY_PORT5_CLK 273
292#define SPDM_CY_PORT6_CLK 274
293#define SPDM_CY_PORT7_CLK 275
294#define PLL0 276
295#define PLL0_VOTE 277
296#define PLL3 278
297#define PLL3_VOTE 279
298#define PLL4_VOTE 280
299#define PLL5 281
300#define PLL5_VOTE 282
301#define PLL6 283
302#define PLL6_VOTE 284
303#define PLL7_VOTE 285
304#define PLL8 286
305#define PLL8_VOTE 287
306#define PLL9 288
307#define PLL10 289
308#define PLL11 290
309#define PLL12 291
310#define PLL13 292
311#define PLL14 293
312#define PLL14_VOTE 294
313#define USB_HS3_H_CLK 295
314#define USB_HS3_XCVR_SRC 296
315#define USB_HS3_XCVR_CLK 297
316#define USB_HS4_H_CLK 298
317#define USB_HS4_XCVR_SRC 299
318#define USB_HS4_XCVR_CLK 300
319#define SATA_PHY_CFG_CLK 301
320#define SATA_A_CLK 302
321#define CE3_SRC 303
322#define CE3_CORE_CLK 304
323#define CE3_H_CLK 305
324#define USB_HS1_SYSTEM_CLK_SRC 306
325#define USB_HS1_SYSTEM_CLK 307
326
327#endif
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8996.h b/include/dt-bindings/clock/qcom,gcc-msm8996.h
index 6f814db11c7e..1828723eb621 100644
--- a/include/dt-bindings/clock/qcom,gcc-msm8996.h
+++ b/include/dt-bindings/clock/qcom,gcc-msm8996.h
@@ -335,6 +335,11 @@
335#define GCC_MSMPU_BCR 98 335#define GCC_MSMPU_BCR 98
336#define GCC_MSS_Q6_BCR 99 336#define GCC_MSS_Q6_BCR 99
337#define GCC_QREFS_VBG_CAL_BCR 100 337#define GCC_QREFS_VBG_CAL_BCR 100
338#define GCC_PCIE_PHY_COM_BCR 101
339#define GCC_PCIE_PHY_COM_NOCSR_BCR 102
340#define GCC_USB3_PHY_BCR 103
341#define GCC_USB3PHY_PHY_BCR 104
342
338 343
339/* Indexes for GDSCs */ 344/* Indexes for GDSCs */
340#define AGGRE0_NOC_GDSC 0 345#define AGGRE0_NOC_GDSC 0
diff --git a/include/dt-bindings/clock/qcom,lcc-mdm9615.h b/include/dt-bindings/clock/qcom,lcc-mdm9615.h
new file mode 100644
index 000000000000..cac963a2fdcb
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,lcc-mdm9615.h
@@ -0,0 +1,52 @@
1/*
2 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
3 * Copyright (c) BayLibre, SAS.
4 * Author : Neil Armstrong <narmstrong@baylibre.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef _DT_BINDINGS_CLK_LCC_MDM9615_H
17#define _DT_BINDINGS_CLK_LCC_MDM9615_H
18
19#define PLL4 0
20#define MI2S_OSR_SRC 1
21#define MI2S_OSR_CLK 2
22#define MI2S_DIV_CLK 3
23#define MI2S_BIT_DIV_CLK 4
24#define MI2S_BIT_CLK 5
25#define PCM_SRC 6
26#define PCM_CLK_OUT 7
27#define PCM_CLK 8
28#define SLIMBUS_SRC 9
29#define AUDIO_SLIMBUS_CLK 10
30#define SPS_SLIMBUS_CLK 11
31#define CODEC_I2S_MIC_OSR_SRC 12
32#define CODEC_I2S_MIC_OSR_CLK 13
33#define CODEC_I2S_MIC_DIV_CLK 14
34#define CODEC_I2S_MIC_BIT_DIV_CLK 15
35#define CODEC_I2S_MIC_BIT_CLK 16
36#define SPARE_I2S_MIC_OSR_SRC 17
37#define SPARE_I2S_MIC_OSR_CLK 18
38#define SPARE_I2S_MIC_DIV_CLK 19
39#define SPARE_I2S_MIC_BIT_DIV_CLK 20
40#define SPARE_I2S_MIC_BIT_CLK 21
41#define CODEC_I2S_SPKR_OSR_SRC 22
42#define CODEC_I2S_SPKR_OSR_CLK 23
43#define CODEC_I2S_SPKR_DIV_CLK 24
44#define CODEC_I2S_SPKR_BIT_DIV_CLK 25
45#define CODEC_I2S_SPKR_BIT_CLK 26
46#define SPARE_I2S_SPKR_OSR_SRC 27
47#define SPARE_I2S_SPKR_OSR_CLK 28
48#define SPARE_I2S_SPKR_DIV_CLK 29
49#define SPARE_I2S_SPKR_BIT_DIV_CLK 30
50#define SPARE_I2S_SPKR_BIT_CLK 31
51
52#endif
diff --git a/include/dt-bindings/clock/qcom,mmcc-msm8996.h b/include/dt-bindings/clock/qcom,mmcc-msm8996.h
index 7d3a7fa1a1bd..5abc445ad815 100644
--- a/include/dt-bindings/clock/qcom,mmcc-msm8996.h
+++ b/include/dt-bindings/clock/qcom,mmcc-msm8996.h
@@ -298,5 +298,6 @@
298#define FD_GDSC 12 298#define FD_GDSC 12
299#define MDSS_GDSC 13 299#define MDSS_GDSC 13
300#define GPU_GX_GDSC 14 300#define GPU_GX_GDSC 14
301#define MMAGIC_BIMC_GDSC 15
301 302
302#endif 303#endif
diff --git a/include/dt-bindings/clock/rk3399-cru.h b/include/dt-bindings/clock/rk3399-cru.h
index 50a44cffb070..220a60f20d3b 100644
--- a/include/dt-bindings/clock/rk3399-cru.h
+++ b/include/dt-bindings/clock/rk3399-cru.h
@@ -131,12 +131,15 @@
131#define SCLK_DPHY_RX0_CFG 165 131#define SCLK_DPHY_RX0_CFG 165
132#define SCLK_RMII_SRC 166 132#define SCLK_RMII_SRC 166
133#define SCLK_PCIEPHY_REF100M 167 133#define SCLK_PCIEPHY_REF100M 167
134#define SCLK_DDRC 168
134 135
135#define DCLK_VOP0 180 136#define DCLK_VOP0 180
136#define DCLK_VOP1 181 137#define DCLK_VOP1 181
137#define DCLK_VOP0_DIV 182 138#define DCLK_VOP0_DIV 182
138#define DCLK_VOP1_DIV 183 139#define DCLK_VOP1_DIV 183
139#define DCLK_M0_PERILP 184 140#define DCLK_M0_PERILP 184
141#define DCLK_VOP0_FRAC 185
142#define DCLK_VOP1_FRAC 186
140 143
141#define FCLK_CM0S 190 144#define FCLK_CM0S 190
142 145
diff --git a/include/dt-bindings/clock/sun6i-a31-ccu.h b/include/dt-bindings/clock/sun6i-a31-ccu.h
new file mode 100644
index 000000000000..4482530fb6f5
--- /dev/null
+++ b/include/dt-bindings/clock/sun6i-a31-ccu.h
@@ -0,0 +1,187 @@
1/*
2 * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
3 *
4 * This file is dual-licensed: you can use it either under the terms
5 * of the GPL or the X11 license, at your option. Note that this dual
6 * licensing only applies to this file, and not this project as a
7 * whole.
8 *
9 * a) This file is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This file is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * Or, alternatively,
20 *
21 * b) Permission is hereby granted, free of charge, to any person
22 * obtaining a copy of this software and associated documentation
23 * files (the "Software"), to deal in the Software without
24 * restriction, including without limitation the rights to use,
25 * copy, modify, merge, publish, distribute, sublicense, and/or
26 * sell copies of the Software, and to permit persons to whom the
27 * Software is furnished to do so, subject to the following
28 * conditions:
29 *
30 * The above copyright notice and this permission notice shall be
31 * included in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
35 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
37 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
38 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40 * OTHER DEALINGS IN THE SOFTWARE.
41 */
42
43#ifndef _DT_BINDINGS_CLK_SUN6I_A31_H_
44#define _DT_BINDINGS_CLK_SUN6I_A31_H_
45
46#define CLK_PLL_PERIPH 10
47
48#define CLK_CPU 18
49
50#define CLK_AHB1_MIPIDSI 23
51#define CLK_AHB1_SS 24
52#define CLK_AHB1_DMA 25
53#define CLK_AHB1_MMC0 26
54#define CLK_AHB1_MMC1 27
55#define CLK_AHB1_MMC2 28
56#define CLK_AHB1_MMC3 29
57#define CLK_AHB1_NAND1 30
58#define CLK_AHB1_NAND0 31
59#define CLK_AHB1_SDRAM 32
60#define CLK_AHB1_EMAC 33
61#define CLK_AHB1_TS 34
62#define CLK_AHB1_HSTIMER 35
63#define CLK_AHB1_SPI0 36
64#define CLK_AHB1_SPI1 37
65#define CLK_AHB1_SPI2 38
66#define CLK_AHB1_SPI3 39
67#define CLK_AHB1_OTG 40
68#define CLK_AHB1_EHCI0 41
69#define CLK_AHB1_EHCI1 42
70#define CLK_AHB1_OHCI0 43
71#define CLK_AHB1_OHCI1 44
72#define CLK_AHB1_OHCI2 45
73#define CLK_AHB1_VE 46
74#define CLK_AHB1_LCD0 47
75#define CLK_AHB1_LCD1 48
76#define CLK_AHB1_CSI 49
77#define CLK_AHB1_HDMI 50
78#define CLK_AHB1_BE0 51
79#define CLK_AHB1_BE1 52
80#define CLK_AHB1_FE0 53
81#define CLK_AHB1_FE1 54
82#define CLK_AHB1_MP 55
83#define CLK_AHB1_GPU 56
84#define CLK_AHB1_DEU0 57
85#define CLK_AHB1_DEU1 58
86#define CLK_AHB1_DRC0 59
87#define CLK_AHB1_DRC1 60
88
89#define CLK_APB1_CODEC 61
90#define CLK_APB1_SPDIF 62
91#define CLK_APB1_DIGITAL_MIC 63
92#define CLK_APB1_PIO 64
93#define CLK_APB1_DAUDIO0 65
94#define CLK_APB1_DAUDIO1 66
95
96#define CLK_APB2_I2C0 67
97#define CLK_APB2_I2C1 68
98#define CLK_APB2_I2C2 69
99#define CLK_APB2_I2C3 70
100#define CLK_APB2_UART0 71
101#define CLK_APB2_UART1 72
102#define CLK_APB2_UART2 73
103#define CLK_APB2_UART3 74
104#define CLK_APB2_UART4 75
105#define CLK_APB2_UART5 76
106
107#define CLK_NAND0 77
108#define CLK_NAND1 78
109#define CLK_MMC0 79
110#define CLK_MMC0_SAMPLE 80
111#define CLK_MMC0_OUTPUT 81
112#define CLK_MMC1 82
113#define CLK_MMC1_SAMPLE 83
114#define CLK_MMC1_OUTPUT 84
115#define CLK_MMC2 85
116#define CLK_MMC2_SAMPLE 86
117#define CLK_MMC2_OUTPUT 87
118#define CLK_MMC3 88
119#define CLK_MMC3_SAMPLE 89
120#define CLK_MMC3_OUTPUT 90
121#define CLK_TS 91
122#define CLK_SS 92
123#define CLK_SPI0 93
124#define CLK_SPI1 94
125#define CLK_SPI2 95
126#define CLK_SPI3 96
127#define CLK_DAUDIO0 97
128#define CLK_DAUDIO1 98
129#define CLK_SPDIF 99
130#define CLK_USB_PHY0 100
131#define CLK_USB_PHY1 101
132#define CLK_USB_PHY2 102
133#define CLK_USB_OHCI0 103
134#define CLK_USB_OHCI1 104
135#define CLK_USB_OHCI2 105
136
137#define CLK_DRAM_VE 110
138#define CLK_DRAM_CSI_ISP 111
139#define CLK_DRAM_TS 112
140#define CLK_DRAM_DRC0 113
141#define CLK_DRAM_DRC1 114
142#define CLK_DRAM_DEU0 115
143#define CLK_DRAM_DEU1 116
144#define CLK_DRAM_FE0 117
145#define CLK_DRAM_FE1 118
146#define CLK_DRAM_BE0 119
147#define CLK_DRAM_BE1 120
148#define CLK_DRAM_MP 121
149
150#define CLK_BE0 122
151#define CLK_BE1 123
152#define CLK_FE0 124
153#define CLK_FE1 125
154#define CLK_MP 126
155#define CLK_LCD0_CH0 127
156#define CLK_LCD1_CH0 128
157#define CLK_LCD0_CH1 129
158#define CLK_LCD1_CH1 130
159#define CLK_CSI0_SCLK 131
160#define CLK_CSI0_MCLK 132
161#define CLK_CSI1_MCLK 133
162#define CLK_VE 134
163#define CLK_CODEC 135
164#define CLK_AVS 136
165#define CLK_DIGITAL_MIC 137
166#define CLK_HDMI 138
167#define CLK_HDMI_DDC 139
168#define CLK_PS 140
169
170#define CLK_MIPI_DSI 143
171#define CLK_MIPI_DSI_DPHY 144
172#define CLK_MIPI_CSI_DPHY 145
173#define CLK_IEP_DRC0 146
174#define CLK_IEP_DRC1 147
175#define CLK_IEP_DEU0 148
176#define CLK_IEP_DEU1 149
177#define CLK_GPU_CORE 150
178#define CLK_GPU_MEMORY 151
179#define CLK_GPU_HYD 152
180#define CLK_ATS 153
181#define CLK_TRACE 154
182
183#define CLK_OUT_A 155
184#define CLK_OUT_B 156
185#define CLK_OUT_C 157
186
187#endif /* _DT_BINDINGS_CLK_SUN6I_A31_H_ */
diff --git a/include/dt-bindings/clock/sun8i-a23-a33-ccu.h b/include/dt-bindings/clock/sun8i-a23-a33-ccu.h
new file mode 100644
index 000000000000..f8222b6b2cc3
--- /dev/null
+++ b/include/dt-bindings/clock/sun8i-a23-a33-ccu.h
@@ -0,0 +1,127 @@
1/*
2 * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
3 *
4 * This file is dual-licensed: you can use it either under the terms
5 * of the GPL or the X11 license, at your option. Note that this dual
6 * licensing only applies to this file, and not this project as a
7 * whole.
8 *
9 * a) This file is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This file is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * Or, alternatively,
20 *
21 * b) Permission is hereby granted, free of charge, to any person
22 * obtaining a copy of this software and associated documentation
23 * files (the "Software"), to deal in the Software without
24 * restriction, including without limitation the rights to use,
25 * copy, modify, merge, publish, distribute, sublicense, and/or
26 * sell copies of the Software, and to permit persons to whom the
27 * Software is furnished to do so, subject to the following
28 * conditions:
29 *
30 * The above copyright notice and this permission notice shall be
31 * included in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
35 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
37 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
38 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40 * OTHER DEALINGS IN THE SOFTWARE.
41 */
42
43#ifndef _DT_BINDINGS_CLK_SUN8I_A23_A33_H_
44#define _DT_BINDINGS_CLK_SUN8I_A23_A33_H_
45
46#define CLK_CPUX 18
47
48#define CLK_BUS_MIPI_DSI 23
49#define CLK_BUS_SS 24
50#define CLK_BUS_DMA 25
51#define CLK_BUS_MMC0 26
52#define CLK_BUS_MMC1 27
53#define CLK_BUS_MMC2 28
54#define CLK_BUS_NAND 29
55#define CLK_BUS_DRAM 30
56#define CLK_BUS_HSTIMER 31
57#define CLK_BUS_SPI0 32
58#define CLK_BUS_SPI1 33
59#define CLK_BUS_OTG 34
60#define CLK_BUS_EHCI 35
61#define CLK_BUS_OHCI 36
62#define CLK_BUS_VE 37
63#define CLK_BUS_LCD 38
64#define CLK_BUS_CSI 39
65#define CLK_BUS_DE_BE 40
66#define CLK_BUS_DE_FE 41
67#define CLK_BUS_GPU 42
68#define CLK_BUS_MSGBOX 43
69#define CLK_BUS_SPINLOCK 44
70#define CLK_BUS_DRC 45
71#define CLK_BUS_SAT 46
72#define CLK_BUS_CODEC 47
73#define CLK_BUS_PIO 48
74#define CLK_BUS_I2S0 49
75#define CLK_BUS_I2S1 50
76#define CLK_BUS_I2C0 51
77#define CLK_BUS_I2C1 52
78#define CLK_BUS_I2C2 53
79#define CLK_BUS_UART0 54
80#define CLK_BUS_UART1 55
81#define CLK_BUS_UART2 56
82#define CLK_BUS_UART3 57
83#define CLK_BUS_UART4 58
84#define CLK_NAND 59
85#define CLK_MMC0 60
86#define CLK_MMC0_SAMPLE 61
87#define CLK_MMC0_OUTPUT 62
88#define CLK_MMC1 63
89#define CLK_MMC1_SAMPLE 64
90#define CLK_MMC1_OUTPUT 65
91#define CLK_MMC2 66
92#define CLK_MMC2_SAMPLE 67
93#define CLK_MMC2_OUTPUT 68
94#define CLK_SS 69
95#define CLK_SPI0 70
96#define CLK_SPI1 71
97#define CLK_I2S0 72
98#define CLK_I2S1 73
99#define CLK_USB_PHY0 74
100#define CLK_USB_PHY1 75
101#define CLK_USB_HSIC 76
102#define CLK_USB_HSIC_12M 77
103#define CLK_USB_OHCI 78
104
105#define CLK_DRAM_VE 80
106#define CLK_DRAM_CSI 81
107#define CLK_DRAM_DRC 82
108#define CLK_DRAM_DE_FE 83
109#define CLK_DRAM_DE_BE 84
110#define CLK_DE_BE 85
111#define CLK_DE_FE 86
112#define CLK_LCD_CH0 87
113#define CLK_LCD_CH1 88
114#define CLK_CSI_SCLK 89
115#define CLK_CSI_MCLK 90
116#define CLK_VE 91
117#define CLK_AC_DIG 92
118#define CLK_AC_DIG_4X 93
119#define CLK_AVS 94
120
121#define CLK_DSI_SCLK 96
122#define CLK_DSI_DPHY 97
123#define CLK_DRC 98
124#define CLK_GPU 99
125#define CLK_ATS 100
126
127#endif /* _DT_BINDINGS_CLK_SUN8I_A23_A33_H_ */
diff --git a/include/dt-bindings/clock/zx296718-clock.h b/include/dt-bindings/clock/zx296718-clock.h
new file mode 100644
index 000000000000..822d52385080
--- /dev/null
+++ b/include/dt-bindings/clock/zx296718-clock.h
@@ -0,0 +1,163 @@
1/*
2 * Copyright (C) 2015 - 2016 ZTE Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#ifndef __DT_BINDINGS_CLOCK_ZX296718_H
9#define __DT_BINDINGS_CLOCK_ZX296718_H
10
11/* PLL */
12#define ZX296718_PLL_CPU 1
13#define ZX296718_PLL_MAC 2
14#define ZX296718_PLL_MM0 3
15#define ZX296718_PLL_MM1 4
16#define ZX296718_PLL_VGA 5
17#define ZX296718_PLL_DDR 6
18#define ZX296718_PLL_AUDIO 7
19#define ZX296718_PLL_HSIC 8
20#define CPU_DBG_GATE 9
21#define A72_GATE 10
22#define CPU_PERI_GATE 11
23#define A53_GATE 12
24#define DDR1_GATE 13
25#define DDR0_GATE 14
26#define SD1_WCLK 15
27#define SD1_AHB 16
28#define SD0_WCLK 17
29#define SD0_AHB 18
30#define EMMC_WCLK 19
31#define EMMC_NAND_AXI 20
32#define NAND_WCLK 21
33#define EMMC_NAND_AHB 22
34#define LSP1_148M5 23
35#define LSP1_99M 24
36#define LSP1_24M 25
37#define LSP0_74M25 26
38#define LSP0_32K 27
39#define LSP0_148M5 28
40#define LSP0_99M 29
41#define LSP0_24M 30
42#define DEMUX_AXI 31
43#define DEMUX_APB 32
44#define DEMUX_148M5 33
45#define DEMUX_108M 34
46#define AUDIO_APB 35
47#define AUDIO_99M 36
48#define AUDIO_24M 37
49#define AUDIO_16M384 38
50#define AUDIO_32K 39
51#define WDT_WCLK 40
52#define TIMER_WCLK 41
53#define VDE_ACLK 42
54#define VCE_ACLK 43
55#define HDE_ACLK 44
56#define GPU_ACLK 45
57#define SAPPU_ACLK 46
58#define SAPPU_WCLK 47
59#define VOU_ACLK 48
60#define VOU_MAIN_WCLK 49
61#define VOU_AUX_WCLK 50
62#define VOU_PPU_WCLK 51
63#define MIPI_CFG_CLK 52
64#define VGA_I2C_WCLK 53
65#define MIPI_REF_CLK 54
66#define HDMI_OSC_CEC 55
67#define HDMI_OSC_CLK 56
68#define HDMI_XCLK 57
69#define VIU_M0_ACLK 58
70#define VIU_M1_ACLK 59
71#define VIU_WCLK 60
72#define VIU_JPEG_WCLK 61
73#define VIU_CFG_CLK 62
74#define TS_SYS_WCLK 63
75#define TS_SYS_108M 64
76#define USB20_HCLK 65
77#define USB20_PHY_CLK 66
78#define USB21_HCLK 67
79#define USB21_PHY_CLK 68
80#define GMAC_RMIICLK 69
81#define GMAC_PCLK 70
82#define GMAC_ACLK 71
83#define GMAC_RFCLK 72
84#define TEMPSENSOR_GATE 73
85
86#define TOP_NR_CLKS 74
87
88
89#define LSP0_TIMER3_PCLK 1
90#define LSP0_TIMER3_WCLK 2
91#define LSP0_TIMER4_PCLK 3
92#define LSP0_TIMER4_WCLK 4
93#define LSP0_TIMER5_PCLK 5
94#define LSP0_TIMER5_WCLK 6
95#define LSP0_UART3_PCLK 7
96#define LSP0_UART3_WCLK 8
97#define LSP0_UART1_PCLK 9
98#define LSP0_UART1_WCLK 10
99#define LSP0_UART2_PCLK 11
100#define LSP0_UART2_WCLK 12
101#define LSP0_SPIFC0_PCLK 13
102#define LSP0_SPIFC0_WCLK 14
103#define LSP0_I2C4_PCLK 15
104#define LSP0_I2C4_WCLK 16
105#define LSP0_I2C5_PCLK 17
106#define LSP0_I2C5_WCLK 18
107#define LSP0_SSP0_PCLK 19
108#define LSP0_SSP0_WCLK 20
109#define LSP0_SSP1_PCLK 21
110#define LSP0_SSP1_WCLK 22
111#define LSP0_USIM_PCLK 23
112#define LSP0_USIM_WCLK 24
113#define LSP0_GPIO_PCLK 25
114#define LSP0_GPIO_WCLK 26
115#define LSP0_I2C3_PCLK 27
116#define LSP0_I2C3_WCLK 28
117
118#define LSP0_NR_CLKS 29
119
120
121#define LSP1_UART4_PCLK 1
122#define LSP1_UART4_WCLK 2
123#define LSP1_UART5_PCLK 3
124#define LSP1_UART5_WCLK 4
125#define LSP1_PWM_PCLK 5
126#define LSP1_PWM_WCLK 6
127#define LSP1_I2C2_PCLK 7
128#define LSP1_I2C2_WCLK 8
129#define LSP1_SSP2_PCLK 9
130#define LSP1_SSP2_WCLK 10
131#define LSP1_SSP3_PCLK 11
132#define LSP1_SSP3_WCLK 12
133#define LSP1_SSP4_PCLK 13
134#define LSP1_SSP4_WCLK 14
135#define LSP1_USIM1_PCLK 15
136#define LSP1_USIM1_WCLK 16
137
138#define LSP1_NR_CLKS 17
139
140
141#define AUDIO_I2S0_WCLK 1
142#define AUDIO_I2S0_PCLK 2
143#define AUDIO_I2S1_WCLK 3
144#define AUDIO_I2S1_PCLK 4
145#define AUDIO_I2S2_WCLK 5
146#define AUDIO_I2S2_PCLK 6
147#define AUDIO_I2S3_WCLK 7
148#define AUDIO_I2S3_PCLK 8
149#define AUDIO_I2C0_WCLK 9
150#define AUDIO_I2C0_PCLK 10
151#define AUDIO_SPDIF0_WCLK 11
152#define AUDIO_SPDIF0_PCLK 12
153#define AUDIO_SPDIF1_WCLK 13
154#define AUDIO_SPDIF1_PCLK 14
155#define AUDIO_TIMER_WCLK 15
156#define AUDIO_TIMER_PCLK 16
157#define AUDIO_TDM_WCLK 17
158#define AUDIO_TDM_PCLK 18
159#define AUDIO_TS_PCLK 19
160
161#define AUDIO_NR_CLKS 20
162
163#endif
diff --git a/include/dt-bindings/reset/gxbb-aoclkc.h b/include/dt-bindings/reset/gxbb-aoclkc.h
new file mode 100644
index 000000000000..9e3fd60c309c
--- /dev/null
+++ b/include/dt-bindings/reset/gxbb-aoclkc.h
@@ -0,0 +1,66 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright (c) 2016 BayLibre, SAS.
8 * Author: Neil Armstrong <narmstrong@baylibre.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 * The full GNU General Public License is included in this distribution
22 * in the file called COPYING.
23 *
24 * BSD LICENSE
25 *
26 * Copyright (c) 2016 BayLibre, SAS.
27 * Author: Neil Armstrong <narmstrong@baylibre.com>
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef DT_BINDINGS_RESET_AMLOGIC_MESON_GXBB_AOCLK
57#define DT_BINDINGS_RESET_AMLOGIC_MESON_GXBB_AOCLK
58
59#define RESET_AO_REMOTE 0
60#define RESET_AO_I2C_MASTER 1
61#define RESET_AO_I2C_SLAVE 2
62#define RESET_AO_UART1 3
63#define RESET_AO_UART2 4
64#define RESET_AO_IR_BLASTER 5
65
66#endif
diff --git a/include/dt-bindings/reset/mt2701-resets.h b/include/dt-bindings/reset/mt2701-resets.h
new file mode 100644
index 000000000000..aaf03057f755
--- /dev/null
+++ b/include/dt-bindings/reset/mt2701-resets.h
@@ -0,0 +1,83 @@
1/*
2 * Copyright (c) 2015 MediaTek, Shunli Wang <shunli.wang@mediatek.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT2701
15#define _DT_BINDINGS_RESET_CONTROLLER_MT2701
16
17/* INFRACFG resets */
18#define MT2701_INFRA_EMI_REG_RST 0
19#define MT2701_INFRA_DRAMC0_A0_RST 1
20#define MT2701_INFRA_FHCTL_RST 2
21#define MT2701_INFRA_APCIRQ_EINT_RST 3
22#define MT2701_INFRA_APXGPT_RST 4
23#define MT2701_INFRA_SCPSYS_RST 5
24#define MT2701_INFRA_KP_RST 6
25#define MT2701_INFRA_PMIC_WRAP_RST 7
26#define MT2701_INFRA_MIPI_RST 8
27#define MT2701_INFRA_IRRX_RST 9
28#define MT2701_INFRA_CEC_RST 10
29#define MT2701_INFRA_EMI_RST 32
30#define MT2701_INFRA_DRAMC0_RST 34
31#define MT2701_INFRA_TRNG_RST 37
32#define MT2701_INFRA_SYSIRQ_RST 38
33
34/* PERICFG resets */
35#define MT2701_PERI_UART0_SW_RST 0
36#define MT2701_PERI_UART1_SW_RST 1
37#define MT2701_PERI_UART2_SW_RST 2
38#define MT2701_PERI_UART3_SW_RST 3
39#define MT2701_PERI_GCPU_SW_RST 5
40#define MT2701_PERI_BTIF_SW_RST 6
41#define MT2701_PERI_PWM_SW_RST 8
42#define MT2701_PERI_AUXADC_SW_RST 10
43#define MT2701_PERI_DMA_SW_RST 11
44#define MT2701_PERI_NFI_SW_RST 14
45#define MT2701_PERI_NLI_SW_RST 15
46#define MT2701_PERI_THERM_SW_RST 16
47#define MT2701_PERI_MSDC2_SW_RST 17
48#define MT2701_PERI_MSDC0_SW_RST 19
49#define MT2701_PERI_MSDC1_SW_RST 20
50#define MT2701_PERI_I2C0_SW_RST 22
51#define MT2701_PERI_I2C1_SW_RST 23
52#define MT2701_PERI_I2C2_SW_RST 24
53#define MT2701_PERI_I2C3_SW_RST 25
54#define MT2701_PERI_USB_SW_RST 28
55#define MT2701_PERI_ETH_SW_RST 29
56#define MT2701_PERI_SPI0_SW_RST 33
57
58/* TOPRGU resets */
59#define MT2701_TOPRGU_INFRA_RST 0
60#define MT2701_TOPRGU_MM_RST 1
61#define MT2701_TOPRGU_MFG_RST 2
62#define MT2701_TOPRGU_ETHDMA_RST 3
63#define MT2701_TOPRGU_VDEC_RST 4
64#define MT2701_TOPRGU_VENC_IMG_RST 5
65#define MT2701_TOPRGU_DDRPHY_RST 6
66#define MT2701_TOPRGU_MD_RST 7
67#define MT2701_TOPRGU_INFRA_AO_RST 8
68#define MT2701_TOPRGU_CONN_RST 9
69#define MT2701_TOPRGU_APMIXED_RST 10
70#define MT2701_TOPRGU_HIFSYS_RST 11
71#define MT2701_TOPRGU_CONN_MCU_RST 12
72#define MT2701_TOPRGU_BDP_DISP_RST 13
73
74/* HIFSYS resets */
75#define MT2701_HIFSYS_UHOST0_RST 3
76#define MT2701_HIFSYS_UHOST1_RST 4
77#define MT2701_HIFSYS_UPHY0_RST 21
78#define MT2701_HIFSYS_UPHY1_RST 22
79#define MT2701_HIFSYS_PCIE0_RST 24
80#define MT2701_HIFSYS_PCIE1_RST 25
81#define MT2701_HIFSYS_PCIE2_RST 26
82
83#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT2701 */
diff --git a/include/dt-bindings/reset/qcom,gcc-mdm9615.h b/include/dt-bindings/reset/qcom,gcc-mdm9615.h
new file mode 100644
index 000000000000..7f86e9a59df4
--- /dev/null
+++ b/include/dt-bindings/reset/qcom,gcc-mdm9615.h
@@ -0,0 +1,136 @@
1/*
2 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
3 * Copyright (c) BayLibre, SAS.
4 * Author : Neil Armstrong <narmstrong@baylibre.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef _DT_BINDINGS_RESET_GCC_MDM9615_H
17#define _DT_BINDINGS_RESET_GCC_MDM9615_H
18
19#define SFAB_MSS_Q6_SW_RESET 0
20#define SFAB_MSS_Q6_FW_RESET 1
21#define QDSS_STM_RESET 2
22#define AFAB_SMPSS_S_RESET 3
23#define AFAB_SMPSS_M1_RESET 4
24#define AFAB_SMPSS_M0_RESET 5
25#define AFAB_EBI1_CH0_RESET 6
26#define AFAB_EBI1_CH1_RESET 7
27#define SFAB_ADM0_M0_RESET 8
28#define SFAB_ADM0_M1_RESET 9
29#define SFAB_ADM0_M2_RESET 10
30#define ADM0_C2_RESET 11
31#define ADM0_C1_RESET 12
32#define ADM0_C0_RESET 13
33#define ADM0_PBUS_RESET 14
34#define ADM0_RESET 15
35#define QDSS_CLKS_SW_RESET 16
36#define QDSS_POR_RESET 17
37#define QDSS_TSCTR_RESET 18
38#define QDSS_HRESET_RESET 19
39#define QDSS_AXI_RESET 20
40#define QDSS_DBG_RESET 21
41#define PCIE_A_RESET 22
42#define PCIE_AUX_RESET 23
43#define PCIE_H_RESET 24
44#define SFAB_PCIE_M_RESET 25
45#define SFAB_PCIE_S_RESET 26
46#define SFAB_MSS_M_RESET 27
47#define SFAB_USB3_M_RESET 28
48#define SFAB_RIVA_M_RESET 29
49#define SFAB_LPASS_RESET 30
50#define SFAB_AFAB_M_RESET 31
51#define AFAB_SFAB_M0_RESET 32
52#define AFAB_SFAB_M1_RESET 33
53#define SFAB_SATA_S_RESET 34
54#define SFAB_DFAB_M_RESET 35
55#define DFAB_SFAB_M_RESET 36
56#define DFAB_SWAY0_RESET 37
57#define DFAB_SWAY1_RESET 38
58#define DFAB_ARB0_RESET 39
59#define DFAB_ARB1_RESET 40
60#define PPSS_PROC_RESET 41
61#define PPSS_RESET 42
62#define DMA_BAM_RESET 43
63#define SPS_TIC_H_RESET 44
64#define SLIMBUS_H_RESET 45
65#define SFAB_CFPB_M_RESET 46
66#define SFAB_CFPB_S_RESET 47
67#define TSIF_H_RESET 48
68#define CE1_H_RESET 49
69#define CE1_CORE_RESET 50
70#define CE1_SLEEP_RESET 51
71#define CE2_H_RESET 52
72#define CE2_CORE_RESET 53
73#define SFAB_SFPB_M_RESET 54
74#define SFAB_SFPB_S_RESET 55
75#define RPM_PROC_RESET 56
76#define PMIC_SSBI2_RESET 57
77#define SDC1_RESET 58
78#define SDC2_RESET 59
79#define SDC3_RESET 60
80#define SDC4_RESET 61
81#define SDC5_RESET 62
82#define DFAB_A2_RESET 63
83#define USB_HS1_RESET 64
84#define USB_HSIC_RESET 65
85#define USB_FS1_XCVR_RESET 66
86#define USB_FS1_RESET 67
87#define USB_FS2_XCVR_RESET 68
88#define USB_FS2_RESET 69
89#define GSBI1_RESET 70
90#define GSBI2_RESET 71
91#define GSBI3_RESET 72
92#define GSBI4_RESET 73
93#define GSBI5_RESET 74
94#define GSBI6_RESET 75
95#define GSBI7_RESET 76
96#define GSBI8_RESET 77
97#define GSBI9_RESET 78
98#define GSBI10_RESET 79
99#define GSBI11_RESET 80
100#define GSBI12_RESET 81
101#define SPDM_RESET 82
102#define TLMM_H_RESET 83
103#define SFAB_MSS_S_RESET 84
104#define MSS_SLP_RESET 85
105#define MSS_Q6SW_JTAG_RESET 86
106#define MSS_Q6FW_JTAG_RESET 87
107#define MSS_RESET 88
108#define SATA_H_RESET 89
109#define SATA_RXOOB_RESE 90
110#define SATA_PMALIVE_RESET 91
111#define SATA_SFAB_M_RESET 92
112#define TSSC_RESET 93
113#define PDM_RESET 94
114#define MPM_H_RESET 95
115#define MPM_RESET 96
116#define SFAB_SMPSS_S_RESET 97
117#define PRNG_RESET 98
118#define RIVA_RESET 99
119#define USB_HS3_RESET 100
120#define USB_HS4_RESET 101
121#define CE3_RESET 102
122#define PCIE_EXT_PCI_RESET 103
123#define PCIE_PHY_RESET 104
124#define PCIE_PCI_RESET 105
125#define PCIE_POR_RESET 106
126#define PCIE_HCLK_RESET 107
127#define PCIE_ACLK_RESET 108
128#define CE3_H_RESET 109
129#define SFAB_CE3_M_RESET 110
130#define SFAB_CE3_S_RESET 111
131#define SATA_RESET 112
132#define CE3_SLEEP_RESET 113
133#define GSS_SLP_RESET 114
134#define GSS_RESET 115
135
136#endif
diff --git a/include/dt-bindings/reset/sun6i-a31-ccu.h b/include/dt-bindings/reset/sun6i-a31-ccu.h
new file mode 100644
index 000000000000..fbff365ed6e1
--- /dev/null
+++ b/include/dt-bindings/reset/sun6i-a31-ccu.h
@@ -0,0 +1,106 @@
1/*
2 * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
3 *
4 * This file is dual-licensed: you can use it either under the terms
5 * of the GPL or the X11 license, at your option. Note that this dual
6 * licensing only applies to this file, and not this project as a
7 * whole.
8 *
9 * a) This file is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This file is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * Or, alternatively,
20 *
21 * b) Permission is hereby granted, free of charge, to any person
22 * obtaining a copy of this software and associated documentation
23 * files (the "Software"), to deal in the Software without
24 * restriction, including without limitation the rights to use,
25 * copy, modify, merge, publish, distribute, sublicense, and/or
26 * sell copies of the Software, and to permit persons to whom the
27 * Software is furnished to do so, subject to the following
28 * conditions:
29 *
30 * The above copyright notice and this permission notice shall be
31 * included in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
35 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
37 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
38 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40 * OTHER DEALINGS IN THE SOFTWARE.
41 */
42
43#ifndef _DT_BINDINGS_RST_SUN6I_A31_H_
44#define _DT_BINDINGS_RST_SUN6I_A31_H_
45
46#define RST_USB_PHY0 0
47#define RST_USB_PHY1 1
48#define RST_USB_PHY2 2
49
50#define RST_AHB1_MIPI_DSI 3
51#define RST_AHB1_SS 4
52#define RST_AHB1_DMA 5
53#define RST_AHB1_MMC0 6
54#define RST_AHB1_MMC1 7
55#define RST_AHB1_MMC2 8
56#define RST_AHB1_MMC3 9
57#define RST_AHB1_NAND1 10
58#define RST_AHB1_NAND0 11
59#define RST_AHB1_SDRAM 12
60#define RST_AHB1_EMAC 13
61#define RST_AHB1_TS 14
62#define RST_AHB1_HSTIMER 15
63#define RST_AHB1_SPI0 16
64#define RST_AHB1_SPI1 17
65#define RST_AHB1_SPI2 18
66#define RST_AHB1_SPI3 19
67#define RST_AHB1_OTG 20
68#define RST_AHB1_EHCI0 21
69#define RST_AHB1_EHCI1 22
70#define RST_AHB1_OHCI0 23
71#define RST_AHB1_OHCI1 24
72#define RST_AHB1_OHCI2 25
73#define RST_AHB1_VE 26
74#define RST_AHB1_LCD0 27
75#define RST_AHB1_LCD1 28
76#define RST_AHB1_CSI 29
77#define RST_AHB1_HDMI 30
78#define RST_AHB1_BE0 31
79#define RST_AHB1_BE1 32
80#define RST_AHB1_FE0 33
81#define RST_AHB1_FE1 34
82#define RST_AHB1_MP 35
83#define RST_AHB1_GPU 36
84#define RST_AHB1_DEU0 37
85#define RST_AHB1_DEU1 38
86#define RST_AHB1_DRC0 39
87#define RST_AHB1_DRC1 40
88#define RST_AHB1_LVDS 41
89
90#define RST_APB1_CODEC 42
91#define RST_APB1_SPDIF 43
92#define RST_APB1_DIGITAL_MIC 44
93#define RST_APB1_DAUDIO0 45
94#define RST_APB1_DAUDIO1 46
95#define RST_APB2_I2C0 47
96#define RST_APB2_I2C1 48
97#define RST_APB2_I2C2 49
98#define RST_APB2_I2C3 50
99#define RST_APB2_UART0 51
100#define RST_APB2_UART1 52
101#define RST_APB2_UART2 53
102#define RST_APB2_UART3 54
103#define RST_APB2_UART4 55
104#define RST_APB2_UART5 56
105
106#endif /* _DT_BINDINGS_RST_SUN6I_A31_H_ */
diff --git a/include/dt-bindings/reset/sun8i-a23-a33-ccu.h b/include/dt-bindings/reset/sun8i-a23-a33-ccu.h
new file mode 100644
index 000000000000..6121f2b0cd0a
--- /dev/null
+++ b/include/dt-bindings/reset/sun8i-a23-a33-ccu.h
@@ -0,0 +1,87 @@
1/*
2 * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
3 *
4 * This file is dual-licensed: you can use it either under the terms
5 * of the GPL or the X11 license, at your option. Note that this dual
6 * licensing only applies to this file, and not this project as a
7 * whole.
8 *
9 * a) This file is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This file is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * Or, alternatively,
20 *
21 * b) Permission is hereby granted, free of charge, to any person
22 * obtaining a copy of this software and associated documentation
23 * files (the "Software"), to deal in the Software without
24 * restriction, including without limitation the rights to use,
25 * copy, modify, merge, publish, distribute, sublicense, and/or
26 * sell copies of the Software, and to permit persons to whom the
27 * Software is furnished to do so, subject to the following
28 * conditions:
29 *
30 * The above copyright notice and this permission notice shall be
31 * included in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
35 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
37 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
38 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40 * OTHER DEALINGS IN THE SOFTWARE.
41 */
42
43#ifndef _DT_BINDINGS_RST_SUN8I_A23_A33_H_
44#define _DT_BINDINGS_RST_SUN8I_A23_A33_H_
45
46#define RST_USB_PHY0 0
47#define RST_USB_PHY1 1
48#define RST_USB_HSIC 2
49#define RST_MBUS 3
50#define RST_BUS_MIPI_DSI 4
51#define RST_BUS_SS 5
52#define RST_BUS_DMA 6
53#define RST_BUS_MMC0 7
54#define RST_BUS_MMC1 8
55#define RST_BUS_MMC2 9
56#define RST_BUS_NAND 10
57#define RST_BUS_DRAM 11
58#define RST_BUS_HSTIMER 12
59#define RST_BUS_SPI0 13
60#define RST_BUS_SPI1 14
61#define RST_BUS_OTG 15
62#define RST_BUS_EHCI 16
63#define RST_BUS_OHCI 17
64#define RST_BUS_VE 18
65#define RST_BUS_LCD 19
66#define RST_BUS_CSI 20
67#define RST_BUS_DE_BE 21
68#define RST_BUS_DE_FE 22
69#define RST_BUS_GPU 23
70#define RST_BUS_MSGBOX 24
71#define RST_BUS_SPINLOCK 25
72#define RST_BUS_DRC 26
73#define RST_BUS_SAT 27
74#define RST_BUS_LVDS 28
75#define RST_BUS_CODEC 29
76#define RST_BUS_I2S0 30
77#define RST_BUS_I2S1 31
78#define RST_BUS_I2C0 32
79#define RST_BUS_I2C1 33
80#define RST_BUS_I2C2 34
81#define RST_BUS_UART0 35
82#define RST_BUS_UART1 36
83#define RST_BUS_UART2 37
84#define RST_BUS_UART3 38
85#define RST_BUS_UART4 39
86
87#endif /* _DT_BINDINGS_RST_SUN8I_A23_A33_H_ */
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index a39c0c530778..af596381fa0f 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -772,7 +772,7 @@ struct clk_onecell_data {
772}; 772};
773 773
774struct clk_hw_onecell_data { 774struct clk_hw_onecell_data {
775 size_t num; 775 unsigned int num;
776 struct clk_hw *hws[]; 776 struct clk_hw *hws[];
777}; 777};
778 778
@@ -780,6 +780,18 @@ extern struct of_device_id __clk_of_table;
780 780
781#define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn) 781#define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn)
782 782
783/*
784 * Use this macro when you have a driver that requires two initialization
785 * routines, one at of_clk_init(), and one at platform device probe
786 */
787#define CLK_OF_DECLARE_DRIVER(name, compat, fn) \
788 static void name##_of_clk_init_driver(struct device_node *np) \
789 { \
790 of_node_clear_flag(np, OF_POPULATED); \
791 fn(np); \
792 } \
793 OF_DECLARE_1(clk, name, compat, name##_of_clk_init_driver)
794
783#ifdef CONFIG_OF 795#ifdef CONFIG_OF
784int of_clk_add_provider(struct device_node *np, 796int of_clk_add_provider(struct device_node *np,
785 struct clk *(*clk_src_get)(struct of_phandle_args *args, 797 struct clk *(*clk_src_get)(struct of_phandle_args *args,
@@ -842,7 +854,7 @@ of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data)
842{ 854{
843 return ERR_PTR(-ENOENT); 855 return ERR_PTR(-ENOENT);
844} 856}
845static inline int of_clk_get_parent_count(struct device_node *np) 857static inline unsigned int of_clk_get_parent_count(struct device_node *np)
846{ 858{
847 return 0; 859 return 0;
848} 860}
diff --git a/include/soc/rockchip/rockchip_sip.h b/include/soc/rockchip/rockchip_sip.h
new file mode 100644
index 000000000000..7e28092c4d3d
--- /dev/null
+++ b/include/soc/rockchip/rockchip_sip.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
3 * Author: Lin Huang <hl@rock-chips.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14#ifndef __SOC_ROCKCHIP_SIP_H
15#define __SOC_ROCKCHIP_SIP_H
16
17#define ROCKCHIP_SIP_DRAM_FREQ 0x82000008
18#define ROCKCHIP_SIP_CONFIG_DRAM_INIT 0x00
19#define ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE 0x01
20#define ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE 0x02
21#define ROCKCHIP_SIP_CONFIG_DRAM_SET_AT_SR 0x03
22#define ROCKCHIP_SIP_CONFIG_DRAM_GET_BW 0x04
23#define ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE 0x05
24#define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ 0x06
25#define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM 0x07
26
27#endif