aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-09-13 14:04:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-13 14:04:14 -0400
commitf60a2abfdbf298a4722dfef331c38447fa18c4e3 (patch)
tree1ac56db32fb1909aedefc21b1c62d0bbe5a13e68
parent561a8eb3e1d219f415597c76dae44b530b7f961a (diff)
parent73c950da6ec523136090d6d4d6907a6ea8e8b67b (diff)
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk updates from Stephen Boyd: "The diff is dominated by the Allwinner A10/A20 SoCs getting converted to the sunxi-ng framework. Otherwise, the heavy hitters are various drivers for SoCs like AT91, Amlogic, Renesas, and Rockchip. There are some other new clk drivers in here too but overall this is just a bunch of clk drivers for various different pieces of hardware and a collection of non-critical fixes for clk drivers. New Drivers: - Allwinner R40 SoCs - Renesas R-Car Gen3 USB 2.0 clock selector PHY - Atmel AT91 audio PLL - Uniphier PXs3 SoCs - ARC HSDK Board PLLs - AXS10X Board PLLs - STMicroelectronics STM32H743 SoCs Removed Drivers: - Non-compiling mb86s7x support Updates: - Allwinner A10/A20 SoCs converted to sunxi-ng framework - Allwinner H3 CPU clk fixes - Renesas R-Car D3 SoC - Renesas V2H and M3-W modules - Samsung Exynos5420/5422/5800 audio fixes - Rockchip fractional clk approximation fixes - Rockchip rk3126 SoC support within the rk3128 driver - Amlogic gxbb CEC32 and sd_emmc clks - Amlogic meson8b reset controller support - IDT VersaClock 5P49V5925/5P49V6901 support - Qualcomm MSM8996 SMMU clks - Various 'const' applications for struct clk_ops - si5351 PLL reset bugfix - Uniphier audio on LD11/LD20 and ethernet support on LD11/LD20/Pro4/PXs2 - Assorted Tegra clk driver fixes" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (120 commits) clk: si5351: fix PLL reset ASoC: atmel-classd: remove aclk clock ASoC: atmel-classd: remove aclk clock from DT binding clk: at91: clk-generated: make gclk determine audio_pll rate clk: at91: clk-generated: create function to find best_diff clk: at91: add audio pll clock drivers dt-bindings: clk: at91: add audio plls to the compatible list clk: at91: clk-generated: remove useless divisor loop clk: mb86s7x: Drop non-building driver clk: ti: check for null return in strrchr to avoid null dereferencing clk: Don't write error code into divider register clk: uniphier: add video input subsystem clock clk: uniphier: add audio system clock clk: stm32h7: Add stm32h743 clock driver clk: gate: expose clk_gate_ops::is_enabled clk: nxp: clk-lpc32xx: rename clk_gate_is_enabled() clk: uniphier: add PXs3 clock data clk: hi6220: change watchdog clock source clk: Kconfig: Name RK805 in Kconfig for COMMON_CLK_RK808 clk: cs2000: Add cs2000_set_saved_rate ...
-rw-r--r--Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt22
-rw-r--r--Documentation/devicetree/bindings/clock/at91-clock.txt10
-rw-r--r--Documentation/devicetree/bindings/clock/idt,versaclock5.txt30
-rw-r--r--Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt3
-rw-r--r--Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt55
-rw-r--r--Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt8
-rw-r--r--Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt28
-rw-r--r--Documentation/devicetree/bindings/clock/snps,pll-clock.txt28
-rw-r--r--Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt71
-rw-r--r--Documentation/devicetree/bindings/clock/sunxi-ccu.txt6
-rw-r--r--Documentation/devicetree/bindings/clock/uniphier-clock.txt8
-rw-r--r--Documentation/devicetree/bindings/sound/atmel-classd.txt9
-rw-r--r--MAINTAINERS12
-rw-r--r--arch/arm/mach-at91/Kconfig4
-rw-r--r--drivers/clk/Kconfig17
-rw-r--r--drivers/clk/Makefile3
-rw-r--r--drivers/clk/at91/Makefile1
-rw-r--r--drivers/clk/at91/clk-audio-pll.c536
-rw-r--r--drivers/clk/at91/clk-generated.c101
-rw-r--r--drivers/clk/axs10x/Makefile1
-rw-r--r--drivers/clk/axs10x/pll_clock.c346
-rw-r--r--drivers/clk/berlin/bg2.c3
-rw-r--r--drivers/clk/berlin/bg2q.c7
-rw-r--r--drivers/clk/clk-asm9260.c4
-rw-r--r--drivers/clk/clk-conf.c16
-rw-r--r--drivers/clk/clk-cs2000-cp.c14
-rw-r--r--drivers/clk/clk-divider.c6
-rw-r--r--drivers/clk/clk-fractional-divider.c28
-rw-r--r--drivers/clk/clk-gate.c3
-rw-r--r--drivers/clk/clk-gemini.c7
-rw-r--r--drivers/clk/clk-hsdk-pll.c431
-rw-r--r--drivers/clk/clk-mb86s7x.c390
-rw-r--r--drivers/clk/clk-moxart.c16
-rw-r--r--drivers/clk/clk-qoriq.c26
-rw-r--r--drivers/clk/clk-si5351.c12
-rw-r--r--drivers/clk/clk-stm32f4.c4
-rw-r--r--drivers/clk/clk-stm32h7.c1410
-rw-r--r--drivers/clk/clk-versaclock5.c172
-rw-r--r--drivers/clk/clk-xgene.c15
-rw-r--r--drivers/clk/clk.c4
-rw-r--r--drivers/clk/clkdev.c4
-rw-r--r--drivers/clk/hisilicon/clk-hi6220.c6
-rw-r--r--drivers/clk/imx/clk-imx51-imx53.c8
-rw-r--r--drivers/clk/imx/clk-imx6sl.c6
-rw-r--r--drivers/clk/imx/clk-imx6sx.c6
-rw-r--r--drivers/clk/imx/clk-imx6ul.c6
-rw-r--r--drivers/clk/imx/clk-imx7d.c4
-rw-r--r--drivers/clk/imx/clk-vf610.c2
-rw-r--r--drivers/clk/mediatek/clk-cpumux.c6
-rw-r--r--drivers/clk/mediatek/clk-mtk.c2
-rw-r--r--drivers/clk/mediatek/reset.c2
-rw-r--r--drivers/clk/meson/Kconfig1
-rw-r--r--drivers/clk/meson/Makefile2
-rw-r--r--drivers/clk/meson/gxbb-aoclk-32k.c194
-rw-r--r--drivers/clk/meson/gxbb-aoclk-regmap.c46
-rw-r--r--drivers/clk/meson/gxbb-aoclk.c65
-rw-r--r--drivers/clk/meson/gxbb-aoclk.h42
-rw-r--r--drivers/clk/meson/gxbb.c187
-rw-r--r--drivers/clk/meson/meson8b.c159
-rw-r--r--drivers/clk/meson/meson8b.h9
-rw-r--r--drivers/clk/mmp/clk.c2
-rw-r--r--drivers/clk/nxp/clk-lpc32xx.c12
-rw-r--r--drivers/clk/qcom/clk-smd-rpm.c2
-rw-r--r--drivers/clk/qcom/gcc-msm8916.c2
-rw-r--r--drivers/clk/qcom/gcc-msm8996.c28
-rw-r--r--drivers/clk/renesas/Kconfig48
-rw-r--r--drivers/clk/renesas/Makefile2
-rw-r--r--drivers/clk/renesas/clk-div6.c3
-rw-r--r--drivers/clk/renesas/clk-mstp.c2
-rw-r--r--drivers/clk/renesas/clk-rcar-gen2.c3
-rw-r--r--drivers/clk/renesas/r8a7792-cpg-mssr.c7
-rw-r--r--drivers/clk/renesas/r8a7795-cpg-mssr.c34
-rw-r--r--drivers/clk/renesas/r8a7796-cpg-mssr.c35
-rw-r--r--drivers/clk/renesas/r8a77995-cpg-mssr.c236
-rw-r--r--drivers/clk/renesas/rcar-gen3-cpg.c69
-rw-r--r--drivers/clk/renesas/rcar-gen3-cpg.h15
-rw-r--r--drivers/clk/renesas/rcar-usb2-clock-sel.c188
-rw-r--r--drivers/clk/renesas/renesas-cpg-mssr.c6
-rw-r--r--drivers/clk/renesas/renesas-cpg-mssr.h1
-rw-r--r--drivers/clk/rockchip/clk-rk3128.c69
-rw-r--r--drivers/clk/rockchip/clk-rk3228.c2
-rw-r--r--drivers/clk/rockchip/clk-rv1108.c462
-rw-r--r--drivers/clk/rockchip/clk.c36
-rw-r--r--drivers/clk/samsung/clk-exynos-audss.c8
-rw-r--r--drivers/clk/samsung/clk-exynos5420.c23
-rw-r--r--drivers/clk/sunxi-ng/Kconfig18
-rw-r--r--drivers/clk/sunxi-ng/Makefile2
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun4i-a10.c1456
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun4i-a10.h61
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun5i.c3
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun6i-a31.c3
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-a23.c3
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-a33.c3
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-h3.c16
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-r.c3
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-r.h2
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-r40.c1290
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-r40.h69
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-v3s.c3
-rw-r--r--drivers/clk/sunxi-ng/ccu_div.c22
-rw-r--r--drivers/clk/sunxi-ng/ccu_div.h3
-rw-r--r--drivers/clk/sunxi-ng/ccu_frac.c14
-rw-r--r--drivers/clk/sunxi-ng/ccu_frac.h2
-rw-r--r--drivers/clk/sunxi-ng/ccu_mult.c10
-rw-r--r--drivers/clk/sunxi-ng/ccu_nkm.c22
-rw-r--r--drivers/clk/sunxi-ng/ccu_nkm.h2
-rw-r--r--drivers/clk/sunxi-ng/ccu_nm.c19
-rw-r--r--drivers/clk/sunxi/clk-sun8i-bus-gates.c4
-rw-r--r--drivers/clk/sunxi/clk-sunxi.c17
-rw-r--r--drivers/clk/tegra/clk-emc.c12
-rw-r--r--drivers/clk/tegra/clk-pll.c159
-rw-r--r--drivers/clk/tegra/clk-tegra-periph.c3
-rw-r--r--drivers/clk/tegra/clk-tegra-super-gen4.c11
-rw-r--r--drivers/clk/tegra/clk-tegra210.c32
-rw-r--r--drivers/clk/tegra/clk.h6
-rw-r--r--drivers/clk/ti/adpll.c4
-rw-r--r--drivers/clk/ti/apll.c2
-rw-r--r--drivers/clk/ti/clockdomain.c4
-rw-r--r--drivers/clk/ti/fapll.c4
-rw-r--r--drivers/clk/uniphier/clk-uniphier-core.c26
-rw-r--r--drivers/clk/uniphier/clk-uniphier-mio.c4
-rw-r--r--drivers/clk/uniphier/clk-uniphier-sys.c98
-rw-r--r--drivers/clk/uniphier/clk-uniphier.h4
-rw-r--r--drivers/clk/ux500/clk-prcc.c6
-rw-r--r--drivers/clk/ux500/clk-prcmu.c14
-rw-r--r--drivers/clk/ux500/clk-sysctrl.c8
-rw-r--r--drivers/clk/versatile/clk-vexpress-osc.c2
-rw-r--r--drivers/clk/zte/clk-zx296718.c6
-rw-r--r--include/dt-bindings/clock/qcom,gcc-msm8996.h2
-rw-r--r--include/dt-bindings/clock/r8a77995-cpg-mssr.h57
-rw-r--r--include/dt-bindings/clock/rk3228-cru.h1
-rw-r--r--include/dt-bindings/clock/rv1108-cru.h8
-rw-r--r--include/dt-bindings/clock/stm32h7-clks.h165
-rw-r--r--include/dt-bindings/clock/sun4i-a10-ccu.h200
-rw-r--r--include/dt-bindings/clock/sun7i-a20-ccu.h53
-rw-r--r--include/dt-bindings/clock/sun8i-r40-ccu.h187
-rw-r--r--include/dt-bindings/mfd/stm32h7-rcc.h136
-rw-r--r--include/dt-bindings/reset/sun4i-a10-ccu.h69
-rw-r--r--include/dt-bindings/reset/sun8i-r40-ccu.h130
-rw-r--r--include/linux/clk-provider.h4
-rw-r--r--include/linux/clk/at91_pmc.h25
-rw-r--r--sound/soc/atmel/atmel-classd.c47
142 files changed, 9354 insertions, 1101 deletions
diff --git a/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt
index faa6d8ac5834..786dc39ca904 100644
--- a/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt
+++ b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt
@@ -5,9 +5,11 @@ controllers within the Always-On part of the SoC.
5 5
6Required Properties: 6Required Properties:
7 7
8- compatible: should be "amlogic,gxbb-aoclkc" 8- compatible: value should be different for each SoC family as :
9- reg: physical base address of the clock controller and length of memory 9 - GXBB (S905) : "amlogic,meson-gxbb-aoclkc"
10 mapped region. 10 - GXL (S905X, S905D) : "amlogic,meson-gxl-aoclkc"
11 - GXM (S912) : "amlogic,meson-gxm-aoclkc"
12 followed by the common "amlogic,meson-gx-aoclkc"
11 13
12- #clock-cells: should be 1. 14- #clock-cells: should be 1.
13 15
@@ -23,14 +25,22 @@ to 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 25preprocessor macros in the dt-bindings/reset/gxbb-aoclkc.h header and can be
24used in device tree sources. 26used in device tree sources.
25 27
28Parent node should have the following properties :
29- compatible: "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd"
30- reg: base address and size of the AO system control register space.
31
26Example: AO Clock controller node: 32Example: AO Clock controller node:
27 33
28 clkc_AO: clock-controller@040 { 34ao_sysctrl: sys-ctrl@0 {
29 compatible = "amlogic,gxbb-aoclkc"; 35 compatible = "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd";
30 reg = <0x0 0x040 0x0 0x4>; 36 reg = <0x0 0x0 0x0 0x100>;
37
38 clkc_AO: clock-controller {
39 compatible = "amlogic,meson-gxbb-aoclkc", "amlogic,meson-gx-aoclkc";
31 #clock-cells = <1>; 40 #clock-cells = <1>;
32 #reset-cells = <1>; 41 #reset-cells = <1>;
33 }; 42 };
43};
34 44
35Example: UART controller node that consumes the clock and reset generated 45Example: UART controller node that consumes the clock and reset generated
36 by the clock controller: 46 by the clock controller:
diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt
index 5f3ad65daf69..51c259a92d02 100644
--- a/Documentation/devicetree/bindings/clock/at91-clock.txt
+++ b/Documentation/devicetree/bindings/clock/at91-clock.txt
@@ -81,6 +81,16 @@ Required properties:
81 "atmel,sama5d2-clk-generated": 81 "atmel,sama5d2-clk-generated":
82 at91 generated clock 82 at91 generated clock
83 83
84 "atmel,sama5d2-clk-audio-pll-frac":
85 at91 audio fractional pll
86
87 "atmel,sama5d2-clk-audio-pll-pad":
88 at91 audio pll CLK_AUDIO output pin
89
90 "atmel,sama5d2-clk-audio-pll-pmc"
91 at91 audio pll output on AUDIOPLLCLK that feeds the PMC
92 and can be used by peripheral clock or generic clock
93
84Required properties for SCKC node: 94Required properties for SCKC node:
85- reg : defines the IO memory reserved for the SCKC. 95- reg : defines the IO memory reserved for the SCKC.
86- #size-cells : shall be 0 (reg is used to encode clk id). 96- #size-cells : shall be 0 (reg is used to encode clk id).
diff --git a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt b/Documentation/devicetree/bindings/clock/idt,versaclock5.txt
index 53d7e50ed875..05a245c9df08 100644
--- a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt
+++ b/Documentation/devicetree/bindings/clock/idt,versaclock5.txt
@@ -1,24 +1,32 @@
1Binding for IDT VersaClock5 programmable i2c clock generator. 1Binding for IDT VersaClock 5,6 programmable i2c clock generators.
2 2
3The IDT VersaClock5 are programmable i2c clock generators providing 3The IDT VersaClock 5 and VersaClock 6 are programmable i2c clock
4from 3 to 12 output clocks. 4generators providing from 3 to 12 output clocks.
5 5
6==I2C device node== 6==I2C device node==
7 7
8Required properties: 8Required properties:
9- compatible: shall be one of "idt,5p49v5923" , "idt,5p49v5933" , 9- compatible: shall be one of
10 "idt,5p49v5935". 10 "idt,5p49v5923"
11 "idt,5p49v5925"
12 "idt,5p49v5933"
13 "idt,5p49v5935"
14 "idt,5p49v6901"
11- reg: i2c device address, shall be 0x68 or 0x6a. 15- reg: i2c device address, shall be 0x68 or 0x6a.
12- #clock-cells: from common clock binding; shall be set to 1. 16- #clock-cells: from common clock binding; shall be set to 1.
13- clocks: from common clock binding; list of parent clock handles, 17- clocks: from common clock binding; list of parent clock handles,
14 - 5p49v5923: (required) either or both of XTAL or CLKIN 18 - 5p49v5923 and
19 5p49v5925 and
20 5p49v6901: (required) either or both of XTAL or CLKIN
15 reference clock. 21 reference clock.
16 - 5p49v5933 and 22 - 5p49v5933 and
17 - 5p49v5935: (optional) property not present (internal 23 - 5p49v5935: (optional) property not present (internal
18 Xtal used) or CLKIN reference 24 Xtal used) or CLKIN reference
19 clock. 25 clock.
20- clock-names: from common clock binding; clock input names, can be 26- clock-names: from common clock binding; clock input names, can be
21 - 5p49v5923: (required) either or both of "xin", "clkin". 27 - 5p49v5923 and
28 5p49v5925 and
29 5p49v6901: (required) either or both of "xin", "clkin".
22 - 5p49v5933 and 30 - 5p49v5933 and
23 - 5p49v5935: (optional) property not present or "clkin". 31 - 5p49v5935: (optional) property not present or "clkin".
24 32
@@ -37,6 +45,7 @@ clock specifier, the following mapping applies:
37 1 -- OUT1 45 1 -- OUT1
38 2 -- OUT4 46 2 -- OUT4
39 47
485P49V5925 and
405P49V5935: 495P49V5935:
41 0 -- OUT0_SEL_I2CB 50 0 -- OUT0_SEL_I2CB
42 1 -- OUT1 51 1 -- OUT1
@@ -44,6 +53,13 @@ clock specifier, the following mapping applies:
44 3 -- OUT3 53 3 -- OUT3
45 4 -- OUT4 54 4 -- OUT4
46 55
565P49V6901:
57 0 -- OUT0_SEL_I2CB
58 1 -- OUT1
59 2 -- OUT2
60 3 -- OUT3
61 4 -- OUT4
62
47==Example== 63==Example==
48 64
49/* 25MHz reference crystal */ 65/* 25MHz reference crystal */
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
index 707a686d8d3e..316e13686568 100644
--- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
@@ -22,6 +22,7 @@ Required Properties:
22 - "renesas,r8a7794-cpg-mssr" for the r8a7794 SoC (R-Car E2) 22 - "renesas,r8a7794-cpg-mssr" for the r8a7794 SoC (R-Car E2)
23 - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3) 23 - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3)
24 - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W) 24 - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W)
25 - "renesas,r8a77995-cpg-mssr" for the r8a77995 SoC (R-Car D3)
25 26
26 - reg: Base address and length of the memory resource used by the CPG/MSSR 27 - reg: Base address and length of the memory resource used by the CPG/MSSR
27 block 28 block
@@ -30,7 +31,7 @@ Required Properties:
30 clock-names 31 clock-names
31 - clock-names: List of external parent clock names. Valid names are: 32 - clock-names: List of external parent clock names. Valid names are:
32 - "extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, 33 - "extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794,
33 r8a7795, r8a7796) 34 r8a7795, r8a7796, r8a77995)
34 - "extalr" (r8a7795, r8a7796) 35 - "extalr" (r8a7795, r8a7796)
35 - "usb_extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7793, r8a7794) 36 - "usb_extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7793, r8a7794)
36 37
diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt
new file mode 100644
index 000000000000..e96e085271c1
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt
@@ -0,0 +1,55 @@
1* Renesas R-Car USB 2.0 clock selector
2
3This file provides information on what the device node for the R-Car USB 2.0
4clock selector.
5
6If you connect an external clock to the USB_EXTAL pin only, you should set
7the clock rate to "usb_extal" node only.
8If you connect an oscillator to both the USB_XTAL and USB_EXTAL, this module
9is not needed because this is default setting. (Of course, you can set the
10clock rates to both "usb_extal" and "usb_xtal" nodes.
11
12Case 1: An external clock connects to R-Car SoC
13 +----------+ +--- R-Car ---------------------+
14 |External |---|USB_EXTAL ---> all usb channels|
15 |clock | |USB_XTAL |
16 +----------+ +-------------------------------+
17In this case, we need this driver with "usb_extal" clock.
18
19Case 2: An oscillator connects to R-Car SoC
20 +----------+ +--- R-Car ---------------------+
21 |Oscillator|---|USB_EXTAL -+-> all usb channels|
22 | |---|USB_XTAL --+ |
23 +----------+ +-------------------------------+
24In this case, we don't need this selector.
25
26Required properties:
27- compatible: "renesas,r8a7795-rcar-usb2-clock-sel" if the device is a part of
28 an R8A7795 SoC.
29 "renesas,r8a7796-rcar-usb2-clock-sel" if the device if a part of
30 an R8A7796 SoC.
31 "renesas,rcar-gen3-usb2-clock-sel" for a generic R-Car Gen3
32 compatible device.
33
34 When compatible with the generic version, nodes must list the
35 SoC-specific version corresponding to the platform first
36 followed by the generic version.
37
38- reg: offset and length of the USB 2.0 clock selector register block.
39- clocks: A list of phandles and specifier pairs.
40- clock-names: Name of the clocks.
41 - The functional clock must be "ehci_ohci"
42 - The USB_EXTAL clock pin must be "usb_extal"
43 - The USB_XTAL clock pin must be "usb_xtal"
44- #clock-cells: Must be 0
45
46Example (R-Car H3):
47
48 usb2_clksel: clock-controller@e6590630 {
49 compatible = "renesas,r8a77950-rcar-usb2-clock-sel",
50 "renesas,rcar-gen3-usb2-clock-sel";
51 reg = <0 0xe6590630 0 0x02>;
52 clocks = <&cpg CPG_MOD 703>, <&usb_extal>, <&usb_xtal>;
53 clock-names = "ehci_ohci", "usb_extal", "usb_xtal";
54 #clock-cells = <0>;
55 };
diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt
index 455a9a00a623..6f8744fd301b 100644
--- a/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt
@@ -1,12 +1,14 @@
1* Rockchip RK3128 Clock and Reset Unit 1* Rockchip RK3126/RK3128 Clock and Reset Unit
2 2
3The RK3128 clock controller generates and supplies clock to various 3The RK3126/RK3128 clock controller generates and supplies clock to various
4controllers within the SoC and also implements a reset controller for SoC 4controllers within the SoC and also implements a reset controller for SoC
5peripherals. 5peripherals.
6 6
7Required Properties: 7Required Properties:
8 8
9- compatible: should be "rockchip,rk3128-cru" 9- compatible: should be "rockchip,rk3126-cru" or "rockchip,rk3128-cru"
10 "rockchip,rk3126-cru" - controller compatible with RK3126 SoC.
11 "rockchip,rk3128-cru" - controller compatible with RK3128 SoC.
10- reg: physical base address of the controller and length of memory mapped 12- reg: physical base address of the controller and length of memory mapped
11 region. 13 region.
12- #clock-cells: should be 1. 14- #clock-cells: should be 1.
diff --git a/Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt b/Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt
new file mode 100644
index 000000000000..c56c7553c730
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt
@@ -0,0 +1,28 @@
1Binding for the HSDK Generic PLL clock
2
3This binding uses the common clock binding[1].
4
5[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
6
7Required properties:
8- compatible: should be "snps,hsdk-<name>-pll-clock"
9 "snps,hsdk-core-pll-clock"
10 "snps,hsdk-gp-pll-clock"
11 "snps,hsdk-hdmi-pll-clock"
12- reg : should contain base register location and length.
13- clocks: shall be the input parent clock phandle for the PLL.
14- #clock-cells: from common clock binding; Should always be set to 0.
15
16Example:
17 input_clk: input-clk {
18 clock-frequency = <33333333>;
19 compatible = "fixed-clock";
20 #clock-cells = <0>;
21 };
22
23 cpu_clk: cpu-clk@0 {
24 compatible = "snps,hsdk-core-pll-clock";
25 reg = <0x00 0x10>;
26 #clock-cells = <0>;
27 clocks = <&input_clk>;
28 };
diff --git a/Documentation/devicetree/bindings/clock/snps,pll-clock.txt b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt
new file mode 100644
index 000000000000..11fe4876612c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt
@@ -0,0 +1,28 @@
1Binding for the AXS10X Generic PLL clock
2
3This binding uses the common clock binding[1].
4
5[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
6
7Required properties:
8- compatible: should be "snps,axs10x-<name>-pll-clock"
9 "snps,axs10x-arc-pll-clock"
10 "snps,axs10x-pgu-pll-clock"
11- reg: should always contain 2 pairs address - length: first for PLL config
12registers and second for corresponding LOCK CGU register.
13- clocks: shall be the input parent clock phandle for the PLL.
14- #clock-cells: from common clock binding; Should always be set to 0.
15
16Example:
17 input-clk: input-clk {
18 clock-frequency = <33333333>;
19 compatible = "fixed-clock";
20 #clock-cells = <0>;
21 };
22
23 core-clk: core-clk@80 {
24 compatible = "snps,axs10x-arc-pll-clock";
25 reg = <0x80 0x10>, <0x100 0x10>;
26 #clock-cells = <0>;
27 clocks = <&input-clk>;
28 };
diff --git a/Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt b/Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt
new file mode 100644
index 000000000000..a135504c7d57
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt
@@ -0,0 +1,71 @@
1STMicroelectronics STM32H7 Reset and Clock Controller
2=====================================================
3
4The RCC IP is both a reset and a clock controller.
5
6Please refer to clock-bindings.txt for common clock controller binding usage.
7Please also refer to reset.txt for common reset controller binding usage.
8
9Required properties:
10- compatible: Should be:
11 "st,stm32h743-rcc"
12
13- reg: should be register base and length as documented in the
14 datasheet
15
16- #reset-cells: 1, see below
17
18- #clock-cells : from common clock binding; shall be set to 1
19
20- clocks: External oscillator clock phandle
21 - high speed external clock signal (HSE)
22 - low speed external clock signal (LSE)
23 - external I2S clock (I2S_CKIN)
24
25Optional properties:
26- st,syscfg: phandle for pwrcfg, mandatory to disable/enable backup domain
27 write protection (RTC clock).
28
29Example:
30
31 rcc: reset-clock-controller@58024400 {
32 compatible = "st,stm32h743-rcc", "st,stm32-rcc";
33 reg = <0x58024400 0x400>;
34 #reset-cells = <1>;
35 #clock-cells = <2>;
36 clocks = <&clk_hse>, <&clk_lse>, <&clk_i2s_ckin>;
37
38 st,syscfg = <&pwrcfg>;
39};
40
41The peripheral clock consumer should specify the desired clock by
42having the clock ID in its "clocks" phandle cell.
43
44Example:
45
46 timer5: timer@40000c00 {
47 compatible = "st,stm32-timer";
48 reg = <0x40000c00 0x400>;
49 interrupts = <50>;
50 clocks = <&rcc TIM5_CK>;
51 };
52
53Specifying softreset control of devices
54=======================================
55
56Device nodes should specify the reset channel required in their "resets"
57property, containing a phandle to the reset device node and an index specifying
58which channel to use.
59The index is the bit number within the RCC registers bank, starting from RCC
60base address.
61It is calculated as: index = register_offset / 4 * 32 + bit_offset.
62Where bit_offset is the bit offset within the register.
63
64For example, for CRC reset:
65 crc = AHB4RSTR_offset / 4 * 32 + CRCRST_bit_offset = 0x88 / 4 * 32 + 19 = 1107
66
67Example:
68
69 timer2 {
70 resets = <&rcc STM32H7_APB1L_RESET(TIM2)>;
71 };
diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
index df9fad58facd..7eda08eb8a1e 100644
--- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
@@ -3,18 +3,24 @@ Allwinner Clock Control Unit Binding
3 3
4Required properties : 4Required properties :
5- compatible: must contain one of the following compatibles: 5- compatible: must contain one of the following compatibles:
6 - "allwinner,sun4i-a10-ccu"
7 - "allwinner,sun5i-a10s-ccu"
8 - "allwinner,sun5i-a13-ccu"
6 - "allwinner,sun6i-a31-ccu" 9 - "allwinner,sun6i-a31-ccu"
10 - "allwinner,sun7i-a20-ccu"
7 - "allwinner,sun8i-a23-ccu" 11 - "allwinner,sun8i-a23-ccu"
8 - "allwinner,sun8i-a33-ccu" 12 - "allwinner,sun8i-a33-ccu"
9 - "allwinner,sun8i-a83t-ccu" 13 - "allwinner,sun8i-a83t-ccu"
10 - "allwinner,sun8i-a83t-r-ccu" 14 - "allwinner,sun8i-a83t-r-ccu"
11 - "allwinner,sun8i-h3-ccu" 15 - "allwinner,sun8i-h3-ccu"
12 - "allwinner,sun8i-h3-r-ccu" 16 - "allwinner,sun8i-h3-r-ccu"
17+ - "allwinner,sun8i-r40-ccu"
13 - "allwinner,sun8i-v3s-ccu" 18 - "allwinner,sun8i-v3s-ccu"
14 - "allwinner,sun9i-a80-ccu" 19 - "allwinner,sun9i-a80-ccu"
15 - "allwinner,sun50i-a64-ccu" 20 - "allwinner,sun50i-a64-ccu"
16 - "allwinner,sun50i-a64-r-ccu" 21 - "allwinner,sun50i-a64-r-ccu"
17 - "allwinner,sun50i-h5-ccu" 22 - "allwinner,sun50i-h5-ccu"
23 - "nextthing,gr8-ccu"
18 24
19- reg: Must contain the registers base address and length 25- reg: Must contain the registers base address and length
20- clocks: phandle to the oscillators feeding the CCU. Two are needed: 26- clocks: phandle to the oscillators feeding the CCU. Two are needed:
diff --git a/Documentation/devicetree/bindings/clock/uniphier-clock.txt b/Documentation/devicetree/bindings/clock/uniphier-clock.txt
index 812163060fa3..7b5f602765fe 100644
--- a/Documentation/devicetree/bindings/clock/uniphier-clock.txt
+++ b/Documentation/devicetree/bindings/clock/uniphier-clock.txt
@@ -6,7 +6,6 @@ System clock
6 6
7Required properties: 7Required properties:
8- compatible: should be one of the following: 8- compatible: should be one of the following:
9 "socionext,uniphier-sld3-clock" - for sLD3 SoC.
10 "socionext,uniphier-ld4-clock" - for LD4 SoC. 9 "socionext,uniphier-ld4-clock" - for LD4 SoC.
11 "socionext,uniphier-pro4-clock" - for Pro4 SoC. 10 "socionext,uniphier-pro4-clock" - for Pro4 SoC.
12 "socionext,uniphier-sld8-clock" - for sLD8 SoC. 11 "socionext,uniphier-sld8-clock" - for sLD8 SoC.
@@ -14,6 +13,7 @@ Required properties:
14 "socionext,uniphier-pxs2-clock" - for PXs2/LD6b SoC. 13 "socionext,uniphier-pxs2-clock" - for PXs2/LD6b SoC.
15 "socionext,uniphier-ld11-clock" - for LD11 SoC. 14 "socionext,uniphier-ld11-clock" - for LD11 SoC.
16 "socionext,uniphier-ld20-clock" - for LD20 SoC. 15 "socionext,uniphier-ld20-clock" - for LD20 SoC.
16 "socionext,uniphier-pxs3-clock" - for PXs3 SoC
17- #clock-cells: should be 1. 17- #clock-cells: should be 1.
18 18
19Example: 19Example:
@@ -48,7 +48,6 @@ Media I/O (MIO) clock, SD clock
48 48
49Required properties: 49Required properties:
50- compatible: should be one of the following: 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. 51 "socionext,uniphier-ld4-mio-clock" - for LD4 SoC.
53 "socionext,uniphier-pro4-mio-clock" - for Pro4 SoC. 52 "socionext,uniphier-pro4-mio-clock" - for Pro4 SoC.
54 "socionext,uniphier-sld8-mio-clock" - for sLD8 SoC. 53 "socionext,uniphier-sld8-mio-clock" - for sLD8 SoC.
@@ -56,6 +55,7 @@ Required properties:
56 "socionext,uniphier-pxs2-sd-clock" - for PXs2/LD6b SoC. 55 "socionext,uniphier-pxs2-sd-clock" - for PXs2/LD6b SoC.
57 "socionext,uniphier-ld11-mio-clock" - for LD11 SoC. 56 "socionext,uniphier-ld11-mio-clock" - for LD11 SoC.
58 "socionext,uniphier-ld20-sd-clock" - for LD20 SoC. 57 "socionext,uniphier-ld20-sd-clock" - for LD20 SoC.
58 "socionext,uniphier-pxs3-sd-clock" - for PXs3 SoC
59- #clock-cells: should be 1. 59- #clock-cells: should be 1.
60 60
61Example: 61Example:
@@ -82,11 +82,9 @@ Provided clocks:
82 8: USB2 ch0 host 82 8: USB2 ch0 host
83 9: USB2 ch1 host 83 9: USB2 ch1 host
8410: USB2 ch2 host 8410: USB2 ch2 host
8511: USB2 ch3 host
8612: USB2 ch0 PHY 8512: USB2 ch0 PHY
8713: USB2 ch1 PHY 8613: USB2 ch1 PHY
8814: USB2 ch2 PHY 8714: USB2 ch2 PHY
8915: USB2 ch3 PHY
90 88
91 89
92Peripheral clock 90Peripheral clock
@@ -94,7 +92,6 @@ Peripheral clock
94 92
95Required properties: 93Required properties:
96- compatible: should be one of the following: 94- 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. 95 "socionext,uniphier-ld4-peri-clock" - for LD4 SoC.
99 "socionext,uniphier-pro4-peri-clock" - for Pro4 SoC. 96 "socionext,uniphier-pro4-peri-clock" - for Pro4 SoC.
100 "socionext,uniphier-sld8-peri-clock" - for sLD8 SoC. 97 "socionext,uniphier-sld8-peri-clock" - for sLD8 SoC.
@@ -102,6 +99,7 @@ Required properties:
102 "socionext,uniphier-pxs2-peri-clock" - for PXs2/LD6b SoC. 99 "socionext,uniphier-pxs2-peri-clock" - for PXs2/LD6b SoC.
103 "socionext,uniphier-ld11-peri-clock" - for LD11 SoC. 100 "socionext,uniphier-ld11-peri-clock" - for LD11 SoC.
104 "socionext,uniphier-ld20-peri-clock" - for LD20 SoC. 101 "socionext,uniphier-ld20-peri-clock" - for LD20 SoC.
102 "socionext,uniphier-pxs3-peri-clock" - for PXs3 SoC
105- #clock-cells: should be 1. 103- #clock-cells: should be 1.
106 104
107Example: 105Example:
diff --git a/Documentation/devicetree/bindings/sound/atmel-classd.txt b/Documentation/devicetree/bindings/sound/atmel-classd.txt
index 549e701cb7a1..898551076382 100644
--- a/Documentation/devicetree/bindings/sound/atmel-classd.txt
+++ b/Documentation/devicetree/bindings/sound/atmel-classd.txt
@@ -13,13 +13,11 @@ Required properties:
13 Must be "tx". 13 Must be "tx".
14- clock-names 14- clock-names
15 Tuple listing input clock names. 15 Tuple listing input clock names.
16 Required elements: "pclk", "gclk" and "aclk". 16 Required elements: "pclk" and "gclk".
17- clocks 17- clocks
18 Please refer to clock-bindings.txt. 18 Please refer to clock-bindings.txt.
19- assigned-clocks 19- assigned-clocks
20 Should be <&classd_gclk>. 20 Should be <&classd_gclk>.
21- assigned-clock-parents
22 Should be <&audio_pll_pmc>.
23 21
24Optional properties: 22Optional properties:
25- pinctrl-names, pinctrl-0 23- pinctrl-names, pinctrl-0
@@ -45,10 +43,9 @@ classd: classd@fc048000 {
45 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) 43 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
46 | AT91_XDMAC_DT_PERID(47))>; 44 | AT91_XDMAC_DT_PERID(47))>;
47 dma-names = "tx"; 45 dma-names = "tx";
48 clocks = <&classd_clk>, <&classd_gclk>, <&audio_pll_pmc>; 46 clocks = <&classd_clk>, <&classd_gclk>;
49 clock-names = "pclk", "gclk", "aclk"; 47 clock-names = "pclk", "gclk";
50 assigned-clocks = <&classd_gclk>; 48 assigned-clocks = <&classd_gclk>;
51 assigned-clock-parents = <&audio_pll_pmc>;
52 49
53 pinctrl-names = "default"; 50 pinctrl-names = "default";
54 pinctrl-0 = <&pinctrl_classd_default>; 51 pinctrl-0 = <&pinctrl_classd_default>;
diff --git a/MAINTAINERS b/MAINTAINERS
index 048586a2a9be..7be4129ec951 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12842,6 +12842,18 @@ F: drivers/clocksource/arc_timer.c
12842F: drivers/tty/serial/arc_uart.c 12842F: drivers/tty/serial/arc_uart.c
12843T: git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git 12843T: git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git
12844 12844
12845SYNOPSYS ARC HSDK SDP pll clock driver
12846M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
12847S: Supported
12848F: drivers/clk/clk-hsdk-pll.c
12849F: Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt
12850
12851SYNOPSYS ARC SDP clock driver
12852M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
12853S: Supported
12854F: drivers/clk/axs10x/*
12855F: Documentation/devicetree/bindings/clock/snps,pll-clock.txt
12856
12845SYNOPSYS ARC SDP platform support 12857SYNOPSYS ARC SDP platform support
12846M: Alexey Brodkin <abrodkin@synopsys.com> 12858M: Alexey Brodkin <abrodkin@synopsys.com>
12847S: Supported 12859S: Supported
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 195da38cb9a2..6d870421a7a6 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -26,6 +26,7 @@ config SOC_SAMA5D2
26 select HAVE_AT91_USB_CLK 26 select HAVE_AT91_USB_CLK
27 select HAVE_AT91_H32MX 27 select HAVE_AT91_H32MX
28 select HAVE_AT91_GENERATED_CLK 28 select HAVE_AT91_GENERATED_CLK
29 select HAVE_AT91_AUDIO_PLL
29 select PINCTRL_AT91PIO4 30 select PINCTRL_AT91PIO4
30 help 31 help
31 Select this if ou are using one of Atmel's SAMA5D2 family SoC. 32 Select this if ou are using one of Atmel's SAMA5D2 family SoC.
@@ -125,6 +126,9 @@ config HAVE_AT91_H32MX
125config HAVE_AT91_GENERATED_CLK 126config HAVE_AT91_GENERATED_CLK
126 bool 127 bool
127 128
129config HAVE_AT91_AUDIO_PLL
130 bool
131
128config SOC_SAM_V4_V5 132config SOC_SAM_V4_V5
129 bool 133 bool
130 134
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 68ca2d9fcd73..1c4e1aa6767e 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -31,6 +31,13 @@ config COMMON_CLK_WM831X
31 31
32source "drivers/clk/versatile/Kconfig" 32source "drivers/clk/versatile/Kconfig"
33 33
34config CLK_HSDK
35 bool "PLL Driver for HSDK platform"
36 depends on OF || COMPILE_TEST
37 ---help---
38 This driver supports the HSDK core, system, ddr, tunnel and hdmi PLLs
39 control.
40
34config COMMON_CLK_MAX77686 41config COMMON_CLK_MAX77686
35 tristate "Clock driver for Maxim 77620/77686/77802 MFD" 42 tristate "Clock driver for Maxim 77620/77686/77802 MFD"
36 depends on MFD_MAX77686 || MFD_MAX77620 || COMPILE_TEST 43 depends on MFD_MAX77686 || MFD_MAX77620 || COMPILE_TEST
@@ -39,10 +46,10 @@ config COMMON_CLK_MAX77686
39 clock. 46 clock.
40 47
41config COMMON_CLK_RK808 48config COMMON_CLK_RK808
42 tristate "Clock driver for RK808/RK818" 49 tristate "Clock driver for RK805/RK808/RK818"
43 depends on MFD_RK808 50 depends on MFD_RK808
44 ---help--- 51 ---help---
45 This driver supports RK808 and RK818 crystal oscillator clock. These 52 This driver supports RK805, RK808 and RK818 crystal oscillator clock. These
46 multi-function devices have two fixed-rate oscillators, 53 multi-function devices have two fixed-rate oscillators,
47 clocked at 32KHz each. Clkout1 is always on, Clkout2 can off 54 clocked at 32KHz each. Clkout1 is always on, Clkout2 can off
48 by control register. 55 by control register.
@@ -210,14 +217,14 @@ config COMMON_CLK_OXNAS
210 Support for the OXNAS SoC Family clocks. 217 Support for the OXNAS SoC Family clocks.
211 218
212config COMMON_CLK_VC5 219config COMMON_CLK_VC5
213 tristate "Clock driver for IDT VersaClock5 devices" 220 tristate "Clock driver for IDT VersaClock 5,6 devices"
214 depends on I2C 221 depends on I2C
215 depends on OF 222 depends on OF
216 select REGMAP_I2C 223 select REGMAP_I2C
217 help 224 help
218 ---help--- 225 ---help---
219 This driver supports the IDT VersaClock5 programmable clock 226 This driver supports the IDT VersaClock 5 and VersaClock 6
220 generator. 227 programmable clock generators.
221 228
222source "drivers/clk/bcm/Kconfig" 229source "drivers/clk/bcm/Kconfig"
223source "drivers/clk/hisilicon/Kconfig" 230source "drivers/clk/hisilicon/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index cd376b3fb47a..c99f363826f0 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -27,8 +27,8 @@ obj-$(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_COMMON_CLK_GEMINI) += clk-gemini.o 28obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o
29obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o 29obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
30obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o
30obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o 31obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
31obj-$(CONFIG_ARCH_MB86S7X) += clk-mb86s7x.o
32obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o 32obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
33obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o 33obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
34obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o 34obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
@@ -44,6 +44,7 @@ obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
44obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o 44obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o
45obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o 45obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
46obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o 46obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o
47obj-$(CONFIG_ARCH_STM32) += clk-stm32h7.o
47obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o 48obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o
48obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o 49obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
49obj-$(CONFIG_ARCH_U300) += clk-u300.o 50obj-$(CONFIG_ARCH_U300) += clk-u300.o
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 13e67bd35cff..c68947b65a4c 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -6,6 +6,7 @@ obj-y += pmc.o sckc.o
6obj-y += clk-slow.o clk-main.o clk-pll.o clk-plldiv.o clk-master.o 6obj-y += clk-slow.o clk-main.o clk-pll.o clk-plldiv.o clk-master.o
7obj-y += clk-system.o clk-peripheral.o clk-programmable.o 7obj-y += clk-system.o clk-peripheral.o clk-programmable.o
8 8
9obj-$(CONFIG_HAVE_AT91_AUDIO_PLL) += clk-audio-pll.o
9obj-$(CONFIG_HAVE_AT91_UTMI) += clk-utmi.o 10obj-$(CONFIG_HAVE_AT91_UTMI) += clk-utmi.o
10obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o 11obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o
11obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o 12obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o
diff --git a/drivers/clk/at91/clk-audio-pll.c b/drivers/clk/at91/clk-audio-pll.c
new file mode 100644
index 000000000000..da7bafcfbe70
--- /dev/null
+++ b/drivers/clk/at91/clk-audio-pll.c
@@ -0,0 +1,536 @@
1/*
2 * Copyright (C) 2016 Atmel Corporation,
3 * Songjun Wu <songjun.wu@atmel.com>,
4 * Nicolas Ferre <nicolas.ferre@atmel.com>
5 * Copyright (C) 2017 Free Electrons,
6 * Quentin Schulz <quentin.schulz@free-electrons.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The Sama5d2 SoC has two audio PLLs (PMC and PAD) that shares the same parent
14 * (FRAC). FRAC can output between 620 and 700MHz and only multiply the rate of
15 * its own parent. PMC and PAD can then divide the FRAC rate to best match the
16 * asked rate.
17 *
18 * Traits of FRAC clock:
19 * enable - clk_enable writes nd, fracr parameters and enables PLL
20 * rate - rate is adjustable.
21 * clk->rate = parent->rate * ((nd + 1) + (fracr / 2^22))
22 * parent - fixed parent. No clk_set_parent support
23 *
24 * Traits of PMC clock:
25 * enable - clk_enable writes qdpmc, and enables PMC output
26 * rate - rate is adjustable.
27 * clk->rate = parent->rate / (qdpmc + 1)
28 * parent - fixed parent. No clk_set_parent support
29 *
30 * Traits of PAD clock:
31 * enable - clk_enable writes divisors and enables PAD output
32 * rate - rate is adjustable.
33 * clk->rate = parent->rate / (qdaudio * div))
34 * parent - fixed parent. No clk_set_parent support
35 *
36 */
37
38#include <linux/clk.h>
39#include <linux/clk-provider.h>
40#include <linux/clk/at91_pmc.h>
41#include <linux/of.h>
42#include <linux/mfd/syscon.h>
43#include <linux/regmap.h>
44#include <linux/slab.h>
45
46#define AUDIO_PLL_DIV_FRAC BIT(22)
47#define AUDIO_PLL_ND_MAX (AT91_PMC_AUDIO_PLL_ND_MASK >> \
48 AT91_PMC_AUDIO_PLL_ND_OFFSET)
49
50#define AUDIO_PLL_QDPAD(qd, div) ((AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV(qd) & \
51 AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MASK) | \
52 (AT91_PMC_AUDIO_PLL_QDPAD_DIV(div) & \
53 AT91_PMC_AUDIO_PLL_QDPAD_DIV_MASK))
54
55#define AUDIO_PLL_QDPMC_MAX (AT91_PMC_AUDIO_PLL_QDPMC_MASK >> \
56 AT91_PMC_AUDIO_PLL_QDPMC_OFFSET)
57
58#define AUDIO_PLL_FOUT_MIN 620000000UL
59#define AUDIO_PLL_FOUT_MAX 700000000UL
60
61struct clk_audio_frac {
62 struct clk_hw hw;
63 struct regmap *regmap;
64 u32 fracr;
65 u8 nd;
66};
67
68struct clk_audio_pad {
69 struct clk_hw hw;
70 struct regmap *regmap;
71 u8 qdaudio;
72 u8 div;
73};
74
75struct clk_audio_pmc {
76 struct clk_hw hw;
77 struct regmap *regmap;
78 u8 qdpmc;
79};
80
81#define to_clk_audio_frac(hw) container_of(hw, struct clk_audio_frac, hw)
82#define to_clk_audio_pad(hw) container_of(hw, struct clk_audio_pad, hw)
83#define to_clk_audio_pmc(hw) container_of(hw, struct clk_audio_pmc, hw)
84
85static int clk_audio_pll_frac_enable(struct clk_hw *hw)
86{
87 struct clk_audio_frac *frac = to_clk_audio_frac(hw);
88
89 regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0,
90 AT91_PMC_AUDIO_PLL_RESETN, 0);
91 regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0,
92 AT91_PMC_AUDIO_PLL_RESETN,
93 AT91_PMC_AUDIO_PLL_RESETN);
94 regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL1,
95 AT91_PMC_AUDIO_PLL_FRACR_MASK, frac->fracr);
96
97 /*
98 * reset and enable have to be done in 2 separated writes
99 * for AT91_PMC_AUDIO_PLL0
100 */
101 regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0,
102 AT91_PMC_AUDIO_PLL_PLLEN |
103 AT91_PMC_AUDIO_PLL_ND_MASK,
104 AT91_PMC_AUDIO_PLL_PLLEN |
105 AT91_PMC_AUDIO_PLL_ND(frac->nd));
106
107 return 0;
108}
109
110static int clk_audio_pll_pad_enable(struct clk_hw *hw)
111{
112 struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw);
113
114 regmap_update_bits(apad_ck->regmap, AT91_PMC_AUDIO_PLL1,
115 AT91_PMC_AUDIO_PLL_QDPAD_MASK,
116 AUDIO_PLL_QDPAD(apad_ck->qdaudio, apad_ck->div));
117 regmap_update_bits(apad_ck->regmap, AT91_PMC_AUDIO_PLL0,
118 AT91_PMC_AUDIO_PLL_PADEN, AT91_PMC_AUDIO_PLL_PADEN);
119
120 return 0;
121}
122
123static int clk_audio_pll_pmc_enable(struct clk_hw *hw)
124{
125 struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw);
126
127 regmap_update_bits(apmc_ck->regmap, AT91_PMC_AUDIO_PLL0,
128 AT91_PMC_AUDIO_PLL_PMCEN |
129 AT91_PMC_AUDIO_PLL_QDPMC_MASK,
130 AT91_PMC_AUDIO_PLL_PMCEN |
131 AT91_PMC_AUDIO_PLL_QDPMC(apmc_ck->qdpmc));
132 return 0;
133}
134
135static void clk_audio_pll_frac_disable(struct clk_hw *hw)
136{
137 struct clk_audio_frac *frac = to_clk_audio_frac(hw);
138
139 regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0,
140 AT91_PMC_AUDIO_PLL_PLLEN, 0);
141 /* do it in 2 separated writes */
142 regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0,
143 AT91_PMC_AUDIO_PLL_RESETN, 0);
144}
145
146static void clk_audio_pll_pad_disable(struct clk_hw *hw)
147{
148 struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw);
149
150 regmap_update_bits(apad_ck->regmap, AT91_PMC_AUDIO_PLL0,
151 AT91_PMC_AUDIO_PLL_PADEN, 0);
152}
153
154static void clk_audio_pll_pmc_disable(struct clk_hw *hw)
155{
156 struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw);
157
158 regmap_update_bits(apmc_ck->regmap, AT91_PMC_AUDIO_PLL0,
159 AT91_PMC_AUDIO_PLL_PMCEN, 0);
160}
161
162static unsigned long clk_audio_pll_fout(unsigned long parent_rate,
163 unsigned long nd, unsigned long fracr)
164{
165 unsigned long long fr = (unsigned long long)parent_rate * fracr;
166
167 pr_debug("A PLL: %s, fr = %llu\n", __func__, fr);
168
169 fr = DIV_ROUND_CLOSEST_ULL(fr, AUDIO_PLL_DIV_FRAC);
170
171 pr_debug("A PLL: %s, fr = %llu\n", __func__, fr);
172
173 return parent_rate * (nd + 1) + fr;
174}
175
176static unsigned long clk_audio_pll_frac_recalc_rate(struct clk_hw *hw,
177 unsigned long parent_rate)
178{
179 struct clk_audio_frac *frac = to_clk_audio_frac(hw);
180 unsigned long fout;
181
182 fout = clk_audio_pll_fout(parent_rate, frac->nd, frac->fracr);
183
184 pr_debug("A PLL: %s, fout = %lu (nd = %u, fracr = %lu)\n", __func__,
185 fout, frac->nd, (unsigned long)frac->fracr);
186
187 return fout;
188}
189
190static unsigned long clk_audio_pll_pad_recalc_rate(struct clk_hw *hw,
191 unsigned long parent_rate)
192{
193 struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw);
194 unsigned long apad_rate = 0;
195
196 if (apad_ck->qdaudio && apad_ck->div)
197 apad_rate = parent_rate / (apad_ck->qdaudio * apad_ck->div);
198
199 pr_debug("A PLL/PAD: %s, apad_rate = %lu (div = %u, qdaudio = %u)\n",
200 __func__, apad_rate, apad_ck->div, apad_ck->qdaudio);
201
202 return apad_rate;
203}
204
205static unsigned long clk_audio_pll_pmc_recalc_rate(struct clk_hw *hw,
206 unsigned long parent_rate)
207{
208 struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw);
209 unsigned long apmc_rate = 0;
210
211 apmc_rate = parent_rate / (apmc_ck->qdpmc + 1);
212
213 pr_debug("A PLL/PMC: %s, apmc_rate = %lu (qdpmc = %u)\n", __func__,
214 apmc_rate, apmc_ck->qdpmc);
215
216 return apmc_rate;
217}
218
219static int clk_audio_pll_frac_compute_frac(unsigned long rate,
220 unsigned long parent_rate,
221 unsigned long *nd,
222 unsigned long *fracr)
223{
224 unsigned long long tmp, rem;
225
226 if (!rate)
227 return -EINVAL;
228
229 tmp = rate;
230 rem = do_div(tmp, parent_rate);
231 if (!tmp || tmp >= AUDIO_PLL_ND_MAX)
232 return -EINVAL;
233
234 *nd = tmp - 1;
235
236 tmp = rem * AUDIO_PLL_DIV_FRAC;
237 tmp = DIV_ROUND_CLOSEST_ULL(tmp, parent_rate);
238 if (tmp > AT91_PMC_AUDIO_PLL_FRACR_MASK)
239 return -EINVAL;
240
241 /* we can cast here as we verified the bounds just above */
242 *fracr = (unsigned long)tmp;
243
244 return 0;
245}
246
247static int clk_audio_pll_frac_determine_rate(struct clk_hw *hw,
248 struct clk_rate_request *req)
249{
250 unsigned long fracr, nd;
251 int ret;
252
253 pr_debug("A PLL: %s, rate = %lu (parent_rate = %lu)\n", __func__,
254 req->rate, req->best_parent_rate);
255
256 req->rate = clamp(req->rate, AUDIO_PLL_FOUT_MIN, AUDIO_PLL_FOUT_MAX);
257
258 req->min_rate = max(req->min_rate, AUDIO_PLL_FOUT_MIN);
259 req->max_rate = min(req->max_rate, AUDIO_PLL_FOUT_MAX);
260
261 ret = clk_audio_pll_frac_compute_frac(req->rate, req->best_parent_rate,
262 &nd, &fracr);
263 if (ret)
264 return ret;
265
266 req->rate = clk_audio_pll_fout(req->best_parent_rate, nd, fracr);
267
268 req->best_parent_hw = clk_hw_get_parent(hw);
269
270 pr_debug("A PLL: %s, best_rate = %lu (nd = %lu, fracr = %lu)\n",
271 __func__, req->rate, nd, fracr);
272
273 return 0;
274}
275
276static long clk_audio_pll_pad_round_rate(struct clk_hw *hw, unsigned long rate,
277 unsigned long *parent_rate)
278{
279 struct clk_hw *pclk = clk_hw_get_parent(hw);
280 long best_rate = -EINVAL;
281 unsigned long best_parent_rate;
282 unsigned long tmp_qd;
283 u32 div;
284 long tmp_rate;
285 int tmp_diff;
286 int best_diff = -1;
287
288 pr_debug("A PLL/PAD: %s, rate = %lu (parent_rate = %lu)\n", __func__,
289 rate, *parent_rate);
290
291 /*
292 * Rate divisor is actually made of two different divisors, multiplied
293 * between themselves before dividing the rate.
294 * tmp_qd goes from 1 to 31 and div is either 2 or 3.
295 * In order to avoid testing twice the rate divisor (e.g. divisor 12 can
296 * be found with (tmp_qd, div) = (2, 6) or (3, 4)), we remove any loop
297 * for a rate divisor when div is 2 and tmp_qd is a multiple of 3.
298 * We cannot inverse it (condition div is 3 and tmp_qd is even) or we
299 * would miss some rate divisor that aren't reachable with div being 2
300 * (e.g. rate divisor 90 is made with div = 3 and tmp_qd = 30, thus
301 * tmp_qd is even so we skip it because we think div 2 could make this
302 * rate divisor which isn't possible since tmp_qd has to be <= 31).
303 */
304 for (tmp_qd = 1; tmp_qd < AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MAX; tmp_qd++)
305 for (div = 2; div <= 3; div++) {
306 if (div == 2 && tmp_qd % 3 == 0)
307 continue;
308
309 best_parent_rate = clk_hw_round_rate(pclk,
310 rate * tmp_qd * div);
311 tmp_rate = best_parent_rate / (div * tmp_qd);
312 tmp_diff = abs(rate - tmp_rate);
313
314 if (best_diff < 0 || best_diff > tmp_diff) {
315 *parent_rate = best_parent_rate;
316 best_rate = tmp_rate;
317 best_diff = tmp_diff;
318 }
319 }
320
321 pr_debug("A PLL/PAD: %s, best_rate = %ld, best_parent_rate = %lu\n",
322 __func__, best_rate, best_parent_rate);
323
324 return best_rate;
325}
326
327static long clk_audio_pll_pmc_round_rate(struct clk_hw *hw, unsigned long rate,
328 unsigned long *parent_rate)
329{
330 struct clk_hw *pclk = clk_hw_get_parent(hw);
331 long best_rate = -EINVAL;
332 unsigned long best_parent_rate = 0;
333 u32 tmp_qd = 0, div;
334 long tmp_rate;
335 int tmp_diff;
336 int best_diff = -1;
337
338 pr_debug("A PLL/PMC: %s, rate = %lu (parent_rate = %lu)\n", __func__,
339 rate, *parent_rate);
340
341 for (div = 1; div <= AUDIO_PLL_QDPMC_MAX; div++) {
342 best_parent_rate = clk_round_rate(pclk->clk, rate * div);
343 tmp_rate = best_parent_rate / div;
344 tmp_diff = abs(rate - tmp_rate);
345
346 if (best_diff < 0 || best_diff > tmp_diff) {
347 *parent_rate = best_parent_rate;
348 best_rate = tmp_rate;
349 best_diff = tmp_diff;
350 tmp_qd = div;
351 }
352 }
353
354 pr_debug("A PLL/PMC: %s, best_rate = %ld, best_parent_rate = %lu (qd = %d)\n",
355 __func__, best_rate, *parent_rate, tmp_qd - 1);
356
357 return best_rate;
358}
359
360static int clk_audio_pll_frac_set_rate(struct clk_hw *hw, unsigned long rate,
361 unsigned long parent_rate)
362{
363 struct clk_audio_frac *frac = to_clk_audio_frac(hw);
364 unsigned long fracr, nd;
365 int ret;
366
367 pr_debug("A PLL: %s, rate = %lu (parent_rate = %lu)\n", __func__, rate,
368 parent_rate);
369
370 if (rate < AUDIO_PLL_FOUT_MIN || rate > AUDIO_PLL_FOUT_MAX)
371 return -EINVAL;
372
373 ret = clk_audio_pll_frac_compute_frac(rate, parent_rate, &nd, &fracr);
374 if (ret)
375 return ret;
376
377 frac->nd = nd;
378 frac->fracr = fracr;
379
380 return 0;
381}
382
383static int clk_audio_pll_pad_set_rate(struct clk_hw *hw, unsigned long rate,
384 unsigned long parent_rate)
385{
386 struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw);
387 u8 tmp_div;
388
389 pr_debug("A PLL/PAD: %s, rate = %lu (parent_rate = %lu)\n", __func__,
390 rate, parent_rate);
391
392 if (!rate)
393 return -EINVAL;
394
395 tmp_div = parent_rate / rate;
396 if (tmp_div % 3 == 0) {
397 apad_ck->qdaudio = tmp_div / 3;
398 apad_ck->div = 3;
399 } else {
400 apad_ck->qdaudio = tmp_div / 2;
401 apad_ck->div = 2;
402 }
403
404 return 0;
405}
406
407static int clk_audio_pll_pmc_set_rate(struct clk_hw *hw, unsigned long rate,
408 unsigned long parent_rate)
409{
410 struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw);
411
412 if (!rate)
413 return -EINVAL;
414
415 pr_debug("A PLL/PMC: %s, rate = %lu (parent_rate = %lu)\n", __func__,
416 rate, parent_rate);
417
418 apmc_ck->qdpmc = parent_rate / rate - 1;
419
420 return 0;
421}
422
423static const struct clk_ops audio_pll_frac_ops = {
424 .enable = clk_audio_pll_frac_enable,
425 .disable = clk_audio_pll_frac_disable,
426 .recalc_rate = clk_audio_pll_frac_recalc_rate,
427 .determine_rate = clk_audio_pll_frac_determine_rate,
428 .set_rate = clk_audio_pll_frac_set_rate,
429};
430
431static const struct clk_ops audio_pll_pad_ops = {
432 .enable = clk_audio_pll_pad_enable,
433 .disable = clk_audio_pll_pad_disable,
434 .recalc_rate = clk_audio_pll_pad_recalc_rate,
435 .round_rate = clk_audio_pll_pad_round_rate,
436 .set_rate = clk_audio_pll_pad_set_rate,
437};
438
439static const struct clk_ops audio_pll_pmc_ops = {
440 .enable = clk_audio_pll_pmc_enable,
441 .disable = clk_audio_pll_pmc_disable,
442 .recalc_rate = clk_audio_pll_pmc_recalc_rate,
443 .round_rate = clk_audio_pll_pmc_round_rate,
444 .set_rate = clk_audio_pll_pmc_set_rate,
445};
446
447static int of_sama5d2_clk_audio_pll_setup(struct device_node *np,
448 struct clk_init_data *init,
449 struct clk_hw *hw,
450 struct regmap **clk_audio_regmap)
451{
452 struct regmap *regmap;
453 const char *parent_names[1];
454 int ret;
455
456 regmap = syscon_node_to_regmap(of_get_parent(np));
457 if (IS_ERR(regmap))
458 return PTR_ERR(regmap);
459
460 init->name = np->name;
461 of_clk_parent_fill(np, parent_names, 1);
462 init->parent_names = parent_names;
463 init->num_parents = 1;
464
465 hw->init = init;
466 *clk_audio_regmap = regmap;
467
468 ret = clk_hw_register(NULL, hw);
469 if (ret)
470 return ret;
471
472 return of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
473}
474
475static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np)
476{
477 struct clk_audio_frac *frac_ck;
478 struct clk_init_data init = {};
479
480 frac_ck = kzalloc(sizeof(*frac_ck), GFP_KERNEL);
481 if (!frac_ck)
482 return;
483
484 init.ops = &audio_pll_frac_ops;
485 init.flags = CLK_SET_RATE_GATE;
486
487 if (of_sama5d2_clk_audio_pll_setup(np, &init, &frac_ck->hw,
488 &frac_ck->regmap))
489 kfree(frac_ck);
490}
491
492static void __init of_sama5d2_clk_audio_pll_pad_setup(struct device_node *np)
493{
494 struct clk_audio_pad *apad_ck;
495 struct clk_init_data init = {};
496
497 apad_ck = kzalloc(sizeof(*apad_ck), GFP_KERNEL);
498 if (!apad_ck)
499 return;
500
501 init.ops = &audio_pll_pad_ops;
502 init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
503 CLK_SET_RATE_PARENT;
504
505 if (of_sama5d2_clk_audio_pll_setup(np, &init, &apad_ck->hw,
506 &apad_ck->regmap))
507 kfree(apad_ck);
508}
509
510static void __init of_sama5d2_clk_audio_pll_pmc_setup(struct device_node *np)
511{
512 struct clk_audio_pad *apmc_ck;
513 struct clk_init_data init = {};
514
515 apmc_ck = kzalloc(sizeof(*apmc_ck), GFP_KERNEL);
516 if (!apmc_ck)
517 return;
518
519 init.ops = &audio_pll_pmc_ops;
520 init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
521 CLK_SET_RATE_PARENT;
522
523 if (of_sama5d2_clk_audio_pll_setup(np, &init, &apmc_ck->hw,
524 &apmc_ck->regmap))
525 kfree(apmc_ck);
526}
527
528CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_frac_setup,
529 "atmel,sama5d2-clk-audio-pll-frac",
530 of_sama5d2_clk_audio_pll_frac_setup);
531CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pad_setup,
532 "atmel,sama5d2-clk-audio-pll-pad",
533 of_sama5d2_clk_audio_pll_pad_setup);
534CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pmc_setup,
535 "atmel,sama5d2-clk-audio-pll-pmc",
536 of_sama5d2_clk_audio_pll_pmc_setup);
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
index f0b7ae904ce2..33481368740e 100644
--- a/drivers/clk/at91/clk-generated.c
+++ b/drivers/clk/at91/clk-generated.c
@@ -26,6 +26,13 @@
26#define GENERATED_SOURCE_MAX 6 26#define GENERATED_SOURCE_MAX 6
27#define GENERATED_MAX_DIV 255 27#define GENERATED_MAX_DIV 255
28 28
29#define GCK_ID_SSC0 43
30#define GCK_ID_SSC1 44
31#define GCK_ID_I2S0 54
32#define GCK_ID_I2S1 55
33#define GCK_ID_CLASSD 59
34#define GCK_INDEX_DT_AUDIO_PLL 5
35
29struct clk_generated { 36struct clk_generated {
30 struct clk_hw hw; 37 struct clk_hw hw;
31 struct regmap *regmap; 38 struct regmap *regmap;
@@ -34,6 +41,7 @@ struct clk_generated {
34 u32 id; 41 u32 id;
35 u32 gckdiv; 42 u32 gckdiv;
36 u8 parent_id; 43 u8 parent_id;
44 bool audio_pll_allowed;
37}; 45};
38 46
39#define to_clk_generated(hw) \ 47#define to_clk_generated(hw) \
@@ -99,21 +107,41 @@ clk_generated_recalc_rate(struct clk_hw *hw,
99 return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1); 107 return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1);
100} 108}
101 109
110static void clk_generated_best_diff(struct clk_rate_request *req,
111 struct clk_hw *parent,
112 unsigned long parent_rate, u32 div,
113 int *best_diff, long *best_rate)
114{
115 unsigned long tmp_rate;
116 int tmp_diff;
117
118 if (!div)
119 tmp_rate = parent_rate;
120 else
121 tmp_rate = parent_rate / div;
122 tmp_diff = abs(req->rate - tmp_rate);
123
124 if (*best_diff < 0 || *best_diff > tmp_diff) {
125 *best_rate = tmp_rate;
126 *best_diff = tmp_diff;
127 req->best_parent_rate = parent_rate;
128 req->best_parent_hw = parent;
129 }
130}
131
102static int clk_generated_determine_rate(struct clk_hw *hw, 132static int clk_generated_determine_rate(struct clk_hw *hw,
103 struct clk_rate_request *req) 133 struct clk_rate_request *req)
104{ 134{
105 struct clk_generated *gck = to_clk_generated(hw); 135 struct clk_generated *gck = to_clk_generated(hw);
106 struct clk_hw *parent = NULL; 136 struct clk_hw *parent = NULL;
137 struct clk_rate_request req_parent = *req;
107 long best_rate = -EINVAL; 138 long best_rate = -EINVAL;
108 unsigned long tmp_rate, min_rate; 139 unsigned long min_rate, parent_rate;
109 int best_diff = -1; 140 int best_diff = -1;
110 int tmp_diff;
111 int i; 141 int i;
142 u32 div;
112 143
113 for (i = 0; i < clk_hw_get_num_parents(hw); i++) { 144 for (i = 0; i < clk_hw_get_num_parents(hw) - 1; i++) {
114 u32 div;
115 unsigned long parent_rate;
116
117 parent = clk_hw_get_parent_by_index(hw, i); 145 parent = clk_hw_get_parent_by_index(hw, i);
118 if (!parent) 146 if (!parent)
119 continue; 147 continue;
@@ -124,25 +152,43 @@ static int clk_generated_determine_rate(struct clk_hw *hw,
124 (gck->range.max && min_rate > gck->range.max)) 152 (gck->range.max && min_rate > gck->range.max))
125 continue; 153 continue;
126 154
127 for (div = 1; div < GENERATED_MAX_DIV + 2; div++) { 155 div = DIV_ROUND_CLOSEST(parent_rate, req->rate);
128 tmp_rate = DIV_ROUND_CLOSEST(parent_rate, div);
129 tmp_diff = abs(req->rate - tmp_rate);
130 156
131 if (best_diff < 0 || best_diff > tmp_diff) { 157 clk_generated_best_diff(req, parent, parent_rate, div,
132 best_rate = tmp_rate; 158 &best_diff, &best_rate);
133 best_diff = tmp_diff;
134 req->best_parent_rate = parent_rate;
135 req->best_parent_hw = parent;
136 }
137 159
138 if (!best_diff || tmp_rate < req->rate) 160 if (!best_diff)
139 break; 161 break;
140 } 162 }
163
164 /*
165 * The audio_pll rate can be modified, unlike the five others clocks
166 * that should never be altered.
167 * The audio_pll can technically be used by multiple consumers. However,
168 * with the rate locking, the first consumer to enable to clock will be
169 * the one definitely setting the rate of the clock.
170 * Since audio IPs are most likely to request the same rate, we enforce
171 * that the only clks able to modify gck rate are those of audio IPs.
172 */
173
174 if (!gck->audio_pll_allowed)
175 goto end;
176
177 parent = clk_hw_get_parent_by_index(hw, GCK_INDEX_DT_AUDIO_PLL);
178 if (!parent)
179 goto end;
180
181 for (div = 1; div < GENERATED_MAX_DIV + 2; div++) {
182 req_parent.rate = req->rate * div;
183 __clk_determine_rate(parent, &req_parent);
184 clk_generated_best_diff(req, parent, req_parent.rate, div,
185 &best_diff, &best_rate);
141 186
142 if (!best_diff) 187 if (!best_diff)
143 break; 188 break;
144 } 189 }
145 190
191end:
146 pr_debug("GCLK: %s, best_rate = %ld, parent clk: %s @ %ld\n", 192 pr_debug("GCLK: %s, best_rate = %ld, parent clk: %s @ %ld\n",
147 __func__, best_rate, 193 __func__, best_rate,
148 __clk_get_name((req->best_parent_hw)->clk), 194 __clk_get_name((req->best_parent_hw)->clk),
@@ -252,7 +298,8 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
252 init.ops = &generated_ops; 298 init.ops = &generated_ops;
253 init.parent_names = parent_names; 299 init.parent_names = parent_names;
254 init.num_parents = num_parents; 300 init.num_parents = num_parents;
255 init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; 301 init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
302 CLK_SET_RATE_PARENT;
256 303
257 gck->id = id; 304 gck->id = id;
258 gck->hw.init = &init; 305 gck->hw.init = &init;
@@ -284,6 +331,7 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
284 struct device_node *gcknp; 331 struct device_node *gcknp;
285 struct clk_range range = CLK_RANGE(0, 0); 332 struct clk_range range = CLK_RANGE(0, 0);
286 struct regmap *regmap; 333 struct regmap *regmap;
334 struct clk_generated *gck;
287 335
288 num_parents = of_clk_get_parent_count(np); 336 num_parents = of_clk_get_parent_count(np);
289 if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX) 337 if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX)
@@ -315,6 +363,21 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
315 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name, 363 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name,
316 parent_names, num_parents, 364 parent_names, num_parents,
317 id, &range); 365 id, &range);
366
367 gck = to_clk_generated(hw);
368
369 if (of_device_is_compatible(np,
370 "atmel,sama5d2-clk-generated")) {
371 if (gck->id == GCK_ID_SSC0 || gck->id == GCK_ID_SSC1 ||
372 gck->id == GCK_ID_I2S0 || gck->id == GCK_ID_I2S1 ||
373 gck->id == GCK_ID_CLASSD)
374 gck->audio_pll_allowed = true;
375 else
376 gck->audio_pll_allowed = false;
377 } else {
378 gck->audio_pll_allowed = false;
379 }
380
318 if (IS_ERR(hw)) 381 if (IS_ERR(hw))
319 continue; 382 continue;
320 383
diff --git a/drivers/clk/axs10x/Makefile b/drivers/clk/axs10x/Makefile
index 01996b871b06..d747deafbf1e 100644
--- a/drivers/clk/axs10x/Makefile
+++ b/drivers/clk/axs10x/Makefile
@@ -1 +1,2 @@
1obj-y += i2s_pll_clock.o 1obj-y += i2s_pll_clock.o
2obj-y += pll_clock.o
diff --git a/drivers/clk/axs10x/pll_clock.c b/drivers/clk/axs10x/pll_clock.c
new file mode 100644
index 000000000000..25d8c240ddfb
--- /dev/null
+++ b/drivers/clk/axs10x/pll_clock.c
@@ -0,0 +1,346 @@
1/*
2 * Synopsys AXS10X SDP Generic PLL clock driver
3 *
4 * Copyright (C) 2017 Synopsys
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <linux/platform_device.h>
12#include <linux/module.h>
13#include <linux/clk-provider.h>
14#include <linux/delay.h>
15#include <linux/err.h>
16#include <linux/device.h>
17#include <linux/of_address.h>
18#include <linux/of_device.h>
19#include <linux/slab.h>
20#include <linux/of.h>
21
22/* PLL registers addresses */
23#define PLL_REG_IDIV 0x0
24#define PLL_REG_FBDIV 0x4
25#define PLL_REG_ODIV 0x8
26
27/*
28 * Bit fields of the PLL IDIV/FBDIV/ODIV registers:
29 * ________________________________________________________________________
30 * |31 15| 14 | 13 | 12 |11 6|5 0|
31 * |-------RESRVED------|-NOUPDATE-|-BYPASS-|-EDGE-|--HIGHTIME--|--LOWTIME--|
32 * |____________________|__________|________|______|____________|___________|
33 *
34 * Following macros determine the way of access to these registers
35 * They should be set up only using the macros.
36 * reg should be an u32 variable.
37 */
38
39#define PLL_REG_GET_LOW(reg) \
40 (((reg) & (0x3F << 0)) >> 0)
41#define PLL_REG_GET_HIGH(reg) \
42 (((reg) & (0x3F << 6)) >> 6)
43#define PLL_REG_GET_EDGE(reg) \
44 (((reg) & (BIT(12))) ? 1 : 0)
45#define PLL_REG_GET_BYPASS(reg) \
46 (((reg) & (BIT(13))) ? 1 : 0)
47#define PLL_REG_GET_NOUPD(reg) \
48 (((reg) & (BIT(14))) ? 1 : 0)
49#define PLL_REG_GET_PAD(reg) \
50 (((reg) & (0x1FFFF << 15)) >> 15)
51
52#define PLL_REG_SET_LOW(reg, value) \
53 { reg |= (((value) & 0x3F) << 0); }
54#define PLL_REG_SET_HIGH(reg, value) \
55 { reg |= (((value) & 0x3F) << 6); }
56#define PLL_REG_SET_EDGE(reg, value) \
57 { reg |= (((value) & 0x01) << 12); }
58#define PLL_REG_SET_BYPASS(reg, value) \
59 { reg |= (((value) & 0x01) << 13); }
60#define PLL_REG_SET_NOUPD(reg, value) \
61 { reg |= (((value) & 0x01) << 14); }
62#define PLL_REG_SET_PAD(reg, value) \
63 { reg |= (((value) & 0x1FFFF) << 15); }
64
65#define PLL_LOCK BIT(0)
66#define PLL_ERROR BIT(1)
67#define PLL_MAX_LOCK_TIME 100 /* 100 us */
68
69struct axs10x_pll_cfg {
70 u32 rate;
71 u32 idiv;
72 u32 fbdiv;
73 u32 odiv;
74};
75
76static const struct axs10x_pll_cfg arc_pll_cfg[] = {
77 { 33333333, 1, 1, 1 },
78 { 50000000, 1, 30, 20 },
79 { 75000000, 2, 45, 10 },
80 { 90000000, 2, 54, 10 },
81 { 100000000, 1, 30, 10 },
82 { 125000000, 2, 45, 6 },
83 {}
84};
85
86static const struct axs10x_pll_cfg pgu_pll_cfg[] = {
87 { 25200000, 1, 84, 90 },
88 { 50000000, 1, 100, 54 },
89 { 74250000, 1, 44, 16 },
90 {}
91};
92
93struct axs10x_pll_clk {
94 struct clk_hw hw;
95 void __iomem *base;
96 void __iomem *lock;
97 const struct axs10x_pll_cfg *pll_cfg;
98 struct device *dev;
99};
100
101static inline void axs10x_pll_write(struct axs10x_pll_clk *clk, u32 reg,
102 u32 val)
103{
104 iowrite32(val, clk->base + reg);
105}
106
107static inline u32 axs10x_pll_read(struct axs10x_pll_clk *clk, u32 reg)
108{
109 return ioread32(clk->base + reg);
110}
111
112static inline struct axs10x_pll_clk *to_axs10x_pll_clk(struct clk_hw *hw)
113{
114 return container_of(hw, struct axs10x_pll_clk, hw);
115}
116
117static inline u32 axs10x_div_get_value(u32 reg)
118{
119 if (PLL_REG_GET_BYPASS(reg))
120 return 1;
121
122 return PLL_REG_GET_HIGH(reg) + PLL_REG_GET_LOW(reg);
123}
124
125static inline u32 axs10x_encode_div(unsigned int id, int upd)
126{
127 u32 div = 0;
128
129 PLL_REG_SET_LOW(div, (id % 2 == 0) ? id >> 1 : (id >> 1) + 1);
130 PLL_REG_SET_HIGH(div, id >> 1);
131 PLL_REG_SET_EDGE(div, id % 2);
132 PLL_REG_SET_BYPASS(div, id == 1 ? 1 : 0);
133 PLL_REG_SET_NOUPD(div, upd == 0 ? 1 : 0);
134
135 return div;
136}
137
138static unsigned long axs10x_pll_recalc_rate(struct clk_hw *hw,
139 unsigned long parent_rate)
140{
141 u64 rate;
142 u32 idiv, fbdiv, odiv;
143 struct axs10x_pll_clk *clk = to_axs10x_pll_clk(hw);
144
145 idiv = axs10x_div_get_value(axs10x_pll_read(clk, PLL_REG_IDIV));
146 fbdiv = axs10x_div_get_value(axs10x_pll_read(clk, PLL_REG_FBDIV));
147 odiv = axs10x_div_get_value(axs10x_pll_read(clk, PLL_REG_ODIV));
148
149 rate = (u64)parent_rate * fbdiv;
150 do_div(rate, idiv * odiv);
151
152 return rate;
153}
154
155static long axs10x_pll_round_rate(struct clk_hw *hw, unsigned long rate,
156 unsigned long *prate)
157{
158 int i;
159 long best_rate;
160 struct axs10x_pll_clk *clk = to_axs10x_pll_clk(hw);
161 const struct axs10x_pll_cfg *pll_cfg = clk->pll_cfg;
162
163 if (pll_cfg[0].rate == 0)
164 return -EINVAL;
165
166 best_rate = pll_cfg[0].rate;
167
168 for (i = 1; pll_cfg[i].rate != 0; i++) {
169 if (abs(rate - pll_cfg[i].rate) < abs(rate - best_rate))
170 best_rate = pll_cfg[i].rate;
171 }
172
173 return best_rate;
174}
175
176static int axs10x_pll_set_rate(struct clk_hw *hw, unsigned long rate,
177 unsigned long parent_rate)
178{
179 int i;
180 struct axs10x_pll_clk *clk = to_axs10x_pll_clk(hw);
181 const struct axs10x_pll_cfg *pll_cfg = clk->pll_cfg;
182
183 for (i = 0; pll_cfg[i].rate != 0; i++) {
184 if (pll_cfg[i].rate == rate) {
185 axs10x_pll_write(clk, PLL_REG_IDIV,
186 axs10x_encode_div(pll_cfg[i].idiv, 0));
187 axs10x_pll_write(clk, PLL_REG_FBDIV,
188 axs10x_encode_div(pll_cfg[i].fbdiv, 0));
189 axs10x_pll_write(clk, PLL_REG_ODIV,
190 axs10x_encode_div(pll_cfg[i].odiv, 1));
191
192 /*
193 * Wait until CGU relocks and check error status.
194 * If after timeout CGU is unlocked yet return error
195 */
196 udelay(PLL_MAX_LOCK_TIME);
197 if (!(ioread32(clk->lock) & PLL_LOCK))
198 return -ETIMEDOUT;
199
200 if (ioread32(clk->lock) & PLL_ERROR)
201 return -EINVAL;
202
203 return 0;
204 }
205 }
206
207 dev_err(clk->dev, "invalid rate=%ld, parent_rate=%ld\n", rate,
208 parent_rate);
209 return -EINVAL;
210}
211
212static const struct clk_ops axs10x_pll_ops = {
213 .recalc_rate = axs10x_pll_recalc_rate,
214 .round_rate = axs10x_pll_round_rate,
215 .set_rate = axs10x_pll_set_rate,
216};
217
218static int axs10x_pll_clk_probe(struct platform_device *pdev)
219{
220 struct device *dev = &pdev->dev;
221 const char *parent_name;
222 struct axs10x_pll_clk *pll_clk;
223 struct resource *mem;
224 struct clk_init_data init = { };
225 int ret;
226
227 pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL);
228 if (!pll_clk)
229 return -ENOMEM;
230
231 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
232 pll_clk->base = devm_ioremap_resource(dev, mem);
233 if (IS_ERR(pll_clk->base))
234 return PTR_ERR(pll_clk->base);
235
236 mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
237 pll_clk->lock = devm_ioremap_resource(dev, mem);
238 if (IS_ERR(pll_clk->lock))
239 return PTR_ERR(pll_clk->lock);
240
241 init.name = dev->of_node->name;
242 init.ops = &axs10x_pll_ops;
243 parent_name = of_clk_get_parent_name(dev->of_node, 0);
244 init.parent_names = &parent_name;
245 init.num_parents = 1;
246 pll_clk->hw.init = &init;
247 pll_clk->dev = dev;
248 pll_clk->pll_cfg = of_device_get_match_data(dev);
249
250 if (!pll_clk->pll_cfg) {
251 dev_err(dev, "No OF match data provided\n");
252 return -EINVAL;
253 }
254
255 ret = devm_clk_hw_register(dev, &pll_clk->hw);
256 if (ret) {
257 dev_err(dev, "failed to register %s clock\n", init.name);
258 return ret;
259 }
260
261 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get,
262 &pll_clk->hw);
263}
264
265static int axs10x_pll_clk_remove(struct platform_device *pdev)
266{
267 of_clk_del_provider(pdev->dev.of_node);
268 return 0;
269}
270
271static void __init of_axs10x_pll_clk_setup(struct device_node *node)
272{
273 const char *parent_name;
274 struct axs10x_pll_clk *pll_clk;
275 struct clk_init_data init = { };
276 int ret;
277
278 pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
279 if (!pll_clk)
280 return;
281
282 pll_clk->base = of_iomap(node, 0);
283 if (!pll_clk->base) {
284 pr_err("failed to map pll div registers\n");
285 goto err_free_pll_clk;
286 }
287
288 pll_clk->lock = of_iomap(node, 1);
289 if (!pll_clk->lock) {
290 pr_err("failed to map pll lock register\n");
291 goto err_unmap_base;
292 }
293
294 init.name = node->name;
295 init.ops = &axs10x_pll_ops;
296 parent_name = of_clk_get_parent_name(node, 0);
297 init.parent_names = &parent_name;
298 init.num_parents = parent_name ? 1 : 0;
299 pll_clk->hw.init = &init;
300 pll_clk->pll_cfg = arc_pll_cfg;
301
302 ret = clk_hw_register(NULL, &pll_clk->hw);
303 if (ret) {
304 pr_err("failed to register %s clock\n", node->name);
305 goto err_unmap_lock;
306 }
307
308 ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &pll_clk->hw);
309 if (ret) {
310 pr_err("failed to add hw provider for %s clock\n", node->name);
311 goto err_unregister_clk;
312 }
313
314 return;
315
316err_unregister_clk:
317 clk_hw_unregister(&pll_clk->hw);
318err_unmap_lock:
319 iounmap(pll_clk->lock);
320err_unmap_base:
321 iounmap(pll_clk->base);
322err_free_pll_clk:
323 kfree(pll_clk);
324}
325CLK_OF_DECLARE(axs10x_pll_clock, "snps,axs10x-arc-pll-clock",
326 of_axs10x_pll_clk_setup);
327
328static const struct of_device_id axs10x_pll_clk_id[] = {
329 { .compatible = "snps,axs10x-pgu-pll-clock", .data = &pgu_pll_cfg},
330 { }
331};
332MODULE_DEVICE_TABLE(of, axs10x_pll_clk_id);
333
334static struct platform_driver axs10x_pll_clk_driver = {
335 .driver = {
336 .name = "axs10x-pll-clock",
337 .of_match_table = axs10x_pll_clk_id,
338 },
339 .probe = axs10x_pll_clk_probe,
340 .remove = axs10x_pll_clk_remove,
341};
342builtin_platform_driver(axs10x_pll_clk_driver);
343
344MODULE_AUTHOR("Vlad Zakharov <vzakhar@synopsys.com>");
345MODULE_DESCRIPTION("Synopsys AXS10X SDP Generic PLL Clock Driver");
346MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c
index 1d99292e2039..e7331ace0337 100644
--- a/drivers/clk/berlin/bg2.c
+++ b/drivers/clk/berlin/bg2.c
@@ -679,8 +679,7 @@ static void __init berlin2_clock_setup(struct device_node *np)
679 if (!IS_ERR(hws[n])) 679 if (!IS_ERR(hws[n]))
680 continue; 680 continue;
681 681
682 pr_err("%s: Unable to register leaf clock %d\n", 682 pr_err("%pOF: Unable to register leaf clock %d\n", np, n);
683 np->full_name, n);
684 goto bg2_fail; 683 goto bg2_fail;
685 } 684 }
686 685
diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c
index 3b784b593afd..67c270b143f7 100644
--- a/drivers/clk/berlin/bg2q.c
+++ b/drivers/clk/berlin/bg2q.c
@@ -304,14 +304,14 @@ static void __init berlin2q_clock_setup(struct device_node *np)
304 304
305 gbase = of_iomap(parent_np, 0); 305 gbase = of_iomap(parent_np, 0);
306 if (!gbase) { 306 if (!gbase) {
307 pr_err("%s: Unable to map global base\n", np->full_name); 307 pr_err("%pOF: Unable to map global base\n", np);
308 return; 308 return;
309 } 309 }
310 310
311 /* BG2Q CPU PLL is not part of global registers */ 311 /* BG2Q CPU PLL is not part of global registers */
312 cpupll_base = of_iomap(parent_np, 1); 312 cpupll_base = of_iomap(parent_np, 1);
313 if (!cpupll_base) { 313 if (!cpupll_base) {
314 pr_err("%s: Unable to map cpupll base\n", np->full_name); 314 pr_err("%pOF: Unable to map cpupll base\n", np);
315 iounmap(gbase); 315 iounmap(gbase);
316 return; 316 return;
317 } 317 }
@@ -376,8 +376,7 @@ static void __init berlin2q_clock_setup(struct device_node *np)
376 if (!IS_ERR(hws[n])) 376 if (!IS_ERR(hws[n]))
377 continue; 377 continue;
378 378
379 pr_err("%s: Unable to register leaf clock %d\n", 379 pr_err("%pOF: Unable to register leaf clock %d\n", np, n);
380 np->full_name, n);
381 goto bg2q_fail; 380 goto bg2q_fail;
382 } 381 }
383 382
diff --git a/drivers/clk/clk-asm9260.c b/drivers/clk/clk-asm9260.c
index ea8568536193..bf0582cbbf38 100644
--- a/drivers/clk/clk-asm9260.c
+++ b/drivers/clk/clk-asm9260.c
@@ -338,8 +338,8 @@ static void __init asm9260_acc_init(struct device_node *np)
338 if (!IS_ERR(hws[n])) 338 if (!IS_ERR(hws[n]))
339 continue; 339 continue;
340 340
341 pr_err("%s: Unable to register leaf clock %d\n", 341 pr_err("%pOF: Unable to register leaf clock %d\n",
342 np->full_name, n); 342 np, n);
343 goto fail; 343 goto fail;
344 } 344 }
345 345
diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c
index 7ec36722f8ab..49819b546134 100644
--- a/drivers/clk/clk-conf.c
+++ b/drivers/clk/clk-conf.c
@@ -23,8 +23,8 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier)
23 num_parents = of_count_phandle_with_args(node, "assigned-clock-parents", 23 num_parents = of_count_phandle_with_args(node, "assigned-clock-parents",
24 "#clock-cells"); 24 "#clock-cells");
25 if (num_parents == -EINVAL) 25 if (num_parents == -EINVAL)
26 pr_err("clk: invalid value of clock-parents property at %s\n", 26 pr_err("clk: invalid value of clock-parents property at %pOF\n",
27 node->full_name); 27 node);
28 28
29 for (index = 0; index < num_parents; index++) { 29 for (index = 0; index < num_parents; index++) {
30 rc = of_parse_phandle_with_args(node, "assigned-clock-parents", 30 rc = of_parse_phandle_with_args(node, "assigned-clock-parents",
@@ -41,8 +41,8 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier)
41 pclk = of_clk_get_from_provider(&clkspec); 41 pclk = of_clk_get_from_provider(&clkspec);
42 if (IS_ERR(pclk)) { 42 if (IS_ERR(pclk)) {
43 if (PTR_ERR(pclk) != -EPROBE_DEFER) 43 if (PTR_ERR(pclk) != -EPROBE_DEFER)
44 pr_warn("clk: couldn't get parent clock %d for %s\n", 44 pr_warn("clk: couldn't get parent clock %d for %pOF\n",
45 index, node->full_name); 45 index, node);
46 return PTR_ERR(pclk); 46 return PTR_ERR(pclk);
47 } 47 }
48 48
@@ -57,8 +57,8 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier)
57 clk = of_clk_get_from_provider(&clkspec); 57 clk = of_clk_get_from_provider(&clkspec);
58 if (IS_ERR(clk)) { 58 if (IS_ERR(clk)) {
59 if (PTR_ERR(clk) != -EPROBE_DEFER) 59 if (PTR_ERR(clk) != -EPROBE_DEFER)
60 pr_warn("clk: couldn't get assigned clock %d for %s\n", 60 pr_warn("clk: couldn't get assigned clock %d for %pOF\n",
61 index, node->full_name); 61 index, node);
62 rc = PTR_ERR(clk); 62 rc = PTR_ERR(clk);
63 goto err; 63 goto err;
64 } 64 }
@@ -102,8 +102,8 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
102 clk = of_clk_get_from_provider(&clkspec); 102 clk = of_clk_get_from_provider(&clkspec);
103 if (IS_ERR(clk)) { 103 if (IS_ERR(clk)) {
104 if (PTR_ERR(clk) != -EPROBE_DEFER) 104 if (PTR_ERR(clk) != -EPROBE_DEFER)
105 pr_warn("clk: couldn't get clock %d for %s\n", 105 pr_warn("clk: couldn't get clock %d for %pOF\n",
106 index, node->full_name); 106 index, node);
107 return PTR_ERR(clk); 107 return PTR_ERR(clk);
108 } 108 }
109 109
diff --git a/drivers/clk/clk-cs2000-cp.c b/drivers/clk/clk-cs2000-cp.c
index c54baede4d68..e8ea81c30f0c 100644
--- a/drivers/clk/clk-cs2000-cp.c
+++ b/drivers/clk/clk-cs2000-cp.c
@@ -343,6 +343,15 @@ static int cs2000_set_rate(struct clk_hw *hw,
343 return __cs2000_set_rate(priv, ch, rate, parent_rate); 343 return __cs2000_set_rate(priv, ch, rate, parent_rate);
344} 344}
345 345
346static int cs2000_set_saved_rate(struct cs2000_priv *priv)
347{
348 int ch = 0; /* it uses ch0 only at this point */
349
350 return __cs2000_set_rate(priv, ch,
351 priv->saved_rate,
352 priv->saved_parent_rate);
353}
354
346static int cs2000_enable(struct clk_hw *hw) 355static int cs2000_enable(struct clk_hw *hw)
347{ 356{
348 struct cs2000_priv *priv = hw_to_priv(hw); 357 struct cs2000_priv *priv = hw_to_priv(hw);
@@ -535,11 +544,8 @@ probe_err:
535static int cs2000_resume(struct device *dev) 544static int cs2000_resume(struct device *dev)
536{ 545{
537 struct cs2000_priv *priv = dev_get_drvdata(dev); 546 struct cs2000_priv *priv = dev_get_drvdata(dev);
538 int ch = 0; /* it uses ch0 only at this point */
539 547
540 return __cs2000_set_rate(priv, ch, 548 return cs2000_set_saved_rate(priv);
541 priv->saved_rate,
542 priv->saved_parent_rate);
543} 549}
544 550
545static const struct dev_pm_ops cs2000_pm_ops = { 551static const struct dev_pm_ops cs2000_pm_ops = {
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 9bb472cccca6..4ed516cb7276 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -385,12 +385,14 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
385 unsigned long parent_rate) 385 unsigned long parent_rate)
386{ 386{
387 struct clk_divider *divider = to_clk_divider(hw); 387 struct clk_divider *divider = to_clk_divider(hw);
388 unsigned int value; 388 int value;
389 unsigned long flags = 0; 389 unsigned long flags = 0;
390 u32 val; 390 u32 val;
391 391
392 value = divider_get_val(rate, parent_rate, divider->table, 392 value = divider_get_val(rate, parent_rate, divider->table,
393 divider->width, divider->flags); 393 divider->width, divider->flags);
394 if (value < 0)
395 return value;
394 396
395 if (divider->lock) 397 if (divider->lock)
396 spin_lock_irqsave(divider->lock, flags); 398 spin_lock_irqsave(divider->lock, flags);
@@ -403,7 +405,7 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
403 val = clk_readl(divider->reg); 405 val = clk_readl(divider->reg);
404 val &= ~(div_mask(divider->width) << divider->shift); 406 val &= ~(div_mask(divider->width) << divider->shift);
405 } 407 }
406 val |= value << divider->shift; 408 val |= (u32)value << divider->shift;
407 clk_writel(val, divider->reg); 409 clk_writel(val, divider->reg);
408 410
409 if (divider->lock) 411 if (divider->lock)
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index aab904618eb6..fdf625fb10fa 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -49,16 +49,12 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
49 return ret; 49 return ret;
50} 50}
51 51
52static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate, 52static void clk_fd_general_approximation(struct clk_hw *hw, unsigned long rate,
53 unsigned long *parent_rate) 53 unsigned long *parent_rate,
54 unsigned long *m, unsigned long *n)
54{ 55{
55 struct clk_fractional_divider *fd = to_clk_fd(hw); 56 struct clk_fractional_divider *fd = to_clk_fd(hw);
56 unsigned long scale; 57 unsigned long scale;
57 unsigned long m, n;
58 u64 ret;
59
60 if (!rate || rate >= *parent_rate)
61 return *parent_rate;
62 58
63 /* 59 /*
64 * Get rate closer to *parent_rate to guarantee there is no overflow 60 * Get rate closer to *parent_rate to guarantee there is no overflow
@@ -71,7 +67,23 @@ static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
71 67
72 rational_best_approximation(rate, *parent_rate, 68 rational_best_approximation(rate, *parent_rate,
73 GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0), 69 GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
74 &m, &n); 70 m, n);
71}
72
73static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
74 unsigned long *parent_rate)
75{
76 struct clk_fractional_divider *fd = to_clk_fd(hw);
77 unsigned long m, n;
78 u64 ret;
79
80 if (!rate || rate >= *parent_rate)
81 return *parent_rate;
82
83 if (fd->approximation)
84 fd->approximation(hw, rate, parent_rate, &m, &n);
85 else
86 clk_fd_general_approximation(hw, rate, parent_rate, &m, &n);
75 87
76 ret = (u64)*parent_rate * m; 88 ret = (u64)*parent_rate * m;
77 do_div(ret, n); 89 do_div(ret, n);
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index 4e0c054a787c..dd82485e09a1 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -86,7 +86,7 @@ static void clk_gate_disable(struct clk_hw *hw)
86 clk_gate_endisable(hw, 0); 86 clk_gate_endisable(hw, 0);
87} 87}
88 88
89static int clk_gate_is_enabled(struct clk_hw *hw) 89int clk_gate_is_enabled(struct clk_hw *hw)
90{ 90{
91 u32 reg; 91 u32 reg;
92 struct clk_gate *gate = to_clk_gate(hw); 92 struct clk_gate *gate = to_clk_gate(hw);
@@ -101,6 +101,7 @@ static int clk_gate_is_enabled(struct clk_hw *hw)
101 101
102 return reg ? 1 : 0; 102 return reg ? 1 : 0;
103} 103}
104EXPORT_SYMBOL_GPL(clk_gate_is_enabled);
104 105
105const struct clk_ops clk_gate_ops = { 106const struct clk_ops clk_gate_ops = {
106 .enable = clk_gate_enable, 107 .enable = clk_gate_enable,
diff --git a/drivers/clk/clk-gemini.c b/drivers/clk/clk-gemini.c
index b4cf2f699a21..f940e5af845b 100644
--- a/drivers/clk/clk-gemini.c
+++ b/drivers/clk/clk-gemini.c
@@ -37,7 +37,6 @@ static DEFINE_SPINLOCK(gemini_clk_lock);
37 37
38#define GEMINI_GLOBAL_MISC_CONTROL 0x30 38#define GEMINI_GLOBAL_MISC_CONTROL 0x30
39#define PCI_CLK_66MHZ BIT(18) 39#define PCI_CLK_66MHZ BIT(18)
40#define PCI_CLK_OE BIT(17)
41 40
42#define GEMINI_GLOBAL_CLOCK_CONTROL 0x34 41#define GEMINI_GLOBAL_CLOCK_CONTROL 0x34
43#define PCI_CLKRUN_EN BIT(16) 42#define PCI_CLKRUN_EN BIT(16)
@@ -159,9 +158,6 @@ static int gemini_pci_enable(struct clk_hw *hw)
159 158
160 regmap_update_bits(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL, 159 regmap_update_bits(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL,
161 0, PCI_CLKRUN_EN); 160 0, PCI_CLKRUN_EN);
162 regmap_update_bits(pciclk->map,
163 GEMINI_GLOBAL_MISC_CONTROL,
164 0, PCI_CLK_OE);
165 return 0; 161 return 0;
166} 162}
167 163
@@ -169,9 +165,6 @@ static void gemini_pci_disable(struct clk_hw *hw)
169{ 165{
170 struct clk_gemini_pci *pciclk = to_pciclk(hw); 166 struct clk_gemini_pci *pciclk = to_pciclk(hw);
171 167
172 regmap_update_bits(pciclk->map,
173 GEMINI_GLOBAL_MISC_CONTROL,
174 PCI_CLK_OE, 0);
175 regmap_update_bits(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL, 168 regmap_update_bits(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL,
176 PCI_CLKRUN_EN, 0); 169 PCI_CLKRUN_EN, 0);
177} 170}
diff --git a/drivers/clk/clk-hsdk-pll.c b/drivers/clk/clk-hsdk-pll.c
new file mode 100644
index 000000000000..bbf237173b37
--- /dev/null
+++ b/drivers/clk/clk-hsdk-pll.c
@@ -0,0 +1,431 @@
1/*
2 * Synopsys HSDK SDP Generic PLL clock driver
3 *
4 * Copyright (C) 2017 Synopsys
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <linux/clk-provider.h>
12#include <linux/delay.h>
13#include <linux/device.h>
14#include <linux/err.h>
15#include <linux/of.h>
16#include <linux/of_address.h>
17#include <linux/of_device.h>
18#include <linux/platform_device.h>
19#include <linux/slab.h>
20
21#define CGU_PLL_CTRL 0x000 /* ARC PLL control register */
22#define CGU_PLL_STATUS 0x004 /* ARC PLL status register */
23#define CGU_PLL_FMEAS 0x008 /* ARC PLL frequency measurement register */
24#define CGU_PLL_MON 0x00C /* ARC PLL monitor register */
25
26#define CGU_PLL_CTRL_ODIV_SHIFT 2
27#define CGU_PLL_CTRL_IDIV_SHIFT 4
28#define CGU_PLL_CTRL_FBDIV_SHIFT 9
29#define CGU_PLL_CTRL_BAND_SHIFT 20
30
31#define CGU_PLL_CTRL_ODIV_MASK GENMASK(3, CGU_PLL_CTRL_ODIV_SHIFT)
32#define CGU_PLL_CTRL_IDIV_MASK GENMASK(8, CGU_PLL_CTRL_IDIV_SHIFT)
33#define CGU_PLL_CTRL_FBDIV_MASK GENMASK(15, CGU_PLL_CTRL_FBDIV_SHIFT)
34
35#define CGU_PLL_CTRL_PD BIT(0)
36#define CGU_PLL_CTRL_BYPASS BIT(1)
37
38#define CGU_PLL_STATUS_LOCK BIT(0)
39#define CGU_PLL_STATUS_ERR BIT(1)
40
41#define HSDK_PLL_MAX_LOCK_TIME 100 /* 100 us */
42
43#define CGU_PLL_SOURCE_MAX 1
44
45#define CORE_IF_CLK_THRESHOLD_HZ 500000000
46#define CREG_CORE_IF_CLK_DIV_1 0x0
47#define CREG_CORE_IF_CLK_DIV_2 0x1
48
49struct hsdk_pll_cfg {
50 u32 rate;
51 u32 idiv;
52 u32 fbdiv;
53 u32 odiv;
54 u32 band;
55};
56
57static const struct hsdk_pll_cfg asdt_pll_cfg[] = {
58 { 100000000, 0, 11, 3, 0 },
59 { 133000000, 0, 15, 3, 0 },
60 { 200000000, 1, 47, 3, 0 },
61 { 233000000, 1, 27, 2, 0 },
62 { 300000000, 1, 35, 2, 0 },
63 { 333000000, 1, 39, 2, 0 },
64 { 400000000, 1, 47, 2, 0 },
65 { 500000000, 0, 14, 1, 0 },
66 { 600000000, 0, 17, 1, 0 },
67 { 700000000, 0, 20, 1, 0 },
68 { 800000000, 0, 23, 1, 0 },
69 { 900000000, 1, 26, 0, 0 },
70 { 1000000000, 1, 29, 0, 0 },
71 { 1100000000, 1, 32, 0, 0 },
72 { 1200000000, 1, 35, 0, 0 },
73 { 1300000000, 1, 38, 0, 0 },
74 { 1400000000, 1, 41, 0, 0 },
75 { 1500000000, 1, 44, 0, 0 },
76 { 1600000000, 1, 47, 0, 0 },
77 {}
78};
79
80static const struct hsdk_pll_cfg hdmi_pll_cfg[] = {
81 { 297000000, 0, 21, 2, 0 },
82 { 540000000, 0, 19, 1, 0 },
83 { 594000000, 0, 21, 1, 0 },
84 {}
85};
86
87struct hsdk_pll_clk {
88 struct clk_hw hw;
89 void __iomem *regs;
90 void __iomem *spec_regs;
91 const struct hsdk_pll_devdata *pll_devdata;
92 struct device *dev;
93};
94
95struct hsdk_pll_devdata {
96 const struct hsdk_pll_cfg *pll_cfg;
97 int (*update_rate)(struct hsdk_pll_clk *clk, unsigned long rate,
98 const struct hsdk_pll_cfg *cfg);
99};
100
101static int hsdk_pll_core_update_rate(struct hsdk_pll_clk *, unsigned long,
102 const struct hsdk_pll_cfg *);
103static int hsdk_pll_comm_update_rate(struct hsdk_pll_clk *, unsigned long,
104 const struct hsdk_pll_cfg *);
105
106static const struct hsdk_pll_devdata core_pll_devdata = {
107 .pll_cfg = asdt_pll_cfg,
108 .update_rate = hsdk_pll_core_update_rate,
109};
110
111static const struct hsdk_pll_devdata sdt_pll_devdata = {
112 .pll_cfg = asdt_pll_cfg,
113 .update_rate = hsdk_pll_comm_update_rate,
114};
115
116static const struct hsdk_pll_devdata hdmi_pll_devdata = {
117 .pll_cfg = hdmi_pll_cfg,
118 .update_rate = hsdk_pll_comm_update_rate,
119};
120
121static inline void hsdk_pll_write(struct hsdk_pll_clk *clk, u32 reg, u32 val)
122{
123 iowrite32(val, clk->regs + reg);
124}
125
126static inline u32 hsdk_pll_read(struct hsdk_pll_clk *clk, u32 reg)
127{
128 return ioread32(clk->regs + reg);
129}
130
131static inline void hsdk_pll_set_cfg(struct hsdk_pll_clk *clk,
132 const struct hsdk_pll_cfg *cfg)
133{
134 u32 val = 0;
135
136 /* Powerdown and Bypass bits should be cleared */
137 val |= cfg->idiv << CGU_PLL_CTRL_IDIV_SHIFT;
138 val |= cfg->fbdiv << CGU_PLL_CTRL_FBDIV_SHIFT;
139 val |= cfg->odiv << CGU_PLL_CTRL_ODIV_SHIFT;
140 val |= cfg->band << CGU_PLL_CTRL_BAND_SHIFT;
141
142 dev_dbg(clk->dev, "write configurarion: %#x\n", val);
143
144 hsdk_pll_write(clk, CGU_PLL_CTRL, val);
145}
146
147static inline bool hsdk_pll_is_locked(struct hsdk_pll_clk *clk)
148{
149 return !!(hsdk_pll_read(clk, CGU_PLL_STATUS) & CGU_PLL_STATUS_LOCK);
150}
151
152static inline bool hsdk_pll_is_err(struct hsdk_pll_clk *clk)
153{
154 return !!(hsdk_pll_read(clk, CGU_PLL_STATUS) & CGU_PLL_STATUS_ERR);
155}
156
157static inline struct hsdk_pll_clk *to_hsdk_pll_clk(struct clk_hw *hw)
158{
159 return container_of(hw, struct hsdk_pll_clk, hw);
160}
161
162static unsigned long hsdk_pll_recalc_rate(struct clk_hw *hw,
163 unsigned long parent_rate)
164{
165 u32 val;
166 u64 rate;
167 u32 idiv, fbdiv, odiv;
168 struct hsdk_pll_clk *clk = to_hsdk_pll_clk(hw);
169
170 val = hsdk_pll_read(clk, CGU_PLL_CTRL);
171
172 dev_dbg(clk->dev, "current configurarion: %#x\n", val);
173
174 /* Check if PLL is disabled */
175 if (val & CGU_PLL_CTRL_PD)
176 return 0;
177
178 /* Check if PLL is bypassed */
179 if (val & CGU_PLL_CTRL_BYPASS)
180 return parent_rate;
181
182 /* input divider = reg.idiv + 1 */
183 idiv = 1 + ((val & CGU_PLL_CTRL_IDIV_MASK) >> CGU_PLL_CTRL_IDIV_SHIFT);
184 /* fb divider = 2*(reg.fbdiv + 1) */
185 fbdiv = 2 * (1 + ((val & CGU_PLL_CTRL_FBDIV_MASK) >> CGU_PLL_CTRL_FBDIV_SHIFT));
186 /* output divider = 2^(reg.odiv) */
187 odiv = 1 << ((val & CGU_PLL_CTRL_ODIV_MASK) >> CGU_PLL_CTRL_ODIV_SHIFT);
188
189 rate = (u64)parent_rate * fbdiv;
190 do_div(rate, idiv * odiv);
191
192 return rate;
193}
194
195static long hsdk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
196 unsigned long *prate)
197{
198 int i;
199 unsigned long best_rate;
200 struct hsdk_pll_clk *clk = to_hsdk_pll_clk(hw);
201 const struct hsdk_pll_cfg *pll_cfg = clk->pll_devdata->pll_cfg;
202
203 if (pll_cfg[0].rate == 0)
204 return -EINVAL;
205
206 best_rate = pll_cfg[0].rate;
207
208 for (i = 1; pll_cfg[i].rate != 0; i++) {
209 if (abs(rate - pll_cfg[i].rate) < abs(rate - best_rate))
210 best_rate = pll_cfg[i].rate;
211 }
212
213 dev_dbg(clk->dev, "chosen best rate: %lu\n", best_rate);
214
215 return best_rate;
216}
217
218static int hsdk_pll_comm_update_rate(struct hsdk_pll_clk *clk,
219 unsigned long rate,
220 const struct hsdk_pll_cfg *cfg)
221{
222 hsdk_pll_set_cfg(clk, cfg);
223
224 /*
225 * Wait until CGU relocks and check error status.
226 * If after timeout CGU is unlocked yet return error.
227 */
228 udelay(HSDK_PLL_MAX_LOCK_TIME);
229 if (!hsdk_pll_is_locked(clk))
230 return -ETIMEDOUT;
231
232 if (hsdk_pll_is_err(clk))
233 return -EINVAL;
234
235 return 0;
236}
237
238static int hsdk_pll_core_update_rate(struct hsdk_pll_clk *clk,
239 unsigned long rate,
240 const struct hsdk_pll_cfg *cfg)
241{
242 /*
243 * When core clock exceeds 500MHz, the divider for the interface
244 * clock must be programmed to div-by-2.
245 */
246 if (rate > CORE_IF_CLK_THRESHOLD_HZ)
247 iowrite32(CREG_CORE_IF_CLK_DIV_2, clk->spec_regs);
248
249 hsdk_pll_set_cfg(clk, cfg);
250
251 /*
252 * Wait until CGU relocks and check error status.
253 * If after timeout CGU is unlocked yet return error.
254 */
255 udelay(HSDK_PLL_MAX_LOCK_TIME);
256 if (!hsdk_pll_is_locked(clk))
257 return -ETIMEDOUT;
258
259 if (hsdk_pll_is_err(clk))
260 return -EINVAL;
261
262 /*
263 * Program divider to div-by-1 if we succesfuly set core clock below
264 * 500MHz threshold.
265 */
266 if (rate <= CORE_IF_CLK_THRESHOLD_HZ)
267 iowrite32(CREG_CORE_IF_CLK_DIV_1, clk->spec_regs);
268
269 return 0;
270}
271
272static int hsdk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
273 unsigned long parent_rate)
274{
275 int i;
276 struct hsdk_pll_clk *clk = to_hsdk_pll_clk(hw);
277 const struct hsdk_pll_cfg *pll_cfg = clk->pll_devdata->pll_cfg;
278
279 for (i = 0; pll_cfg[i].rate != 0; i++) {
280 if (pll_cfg[i].rate == rate) {
281 return clk->pll_devdata->update_rate(clk, rate,
282 &pll_cfg[i]);
283 }
284 }
285
286 dev_err(clk->dev, "invalid rate=%ld, parent_rate=%ld\n", rate,
287 parent_rate);
288
289 return -EINVAL;
290}
291
292static const struct clk_ops hsdk_pll_ops = {
293 .recalc_rate = hsdk_pll_recalc_rate,
294 .round_rate = hsdk_pll_round_rate,
295 .set_rate = hsdk_pll_set_rate,
296};
297
298static int hsdk_pll_clk_probe(struct platform_device *pdev)
299{
300 int ret;
301 struct resource *mem;
302 const char *parent_name;
303 unsigned int num_parents;
304 struct hsdk_pll_clk *pll_clk;
305 struct clk_init_data init = { };
306 struct device *dev = &pdev->dev;
307
308 pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL);
309 if (!pll_clk)
310 return -ENOMEM;
311
312 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
313 pll_clk->regs = devm_ioremap_resource(dev, mem);
314 if (IS_ERR(pll_clk->regs))
315 return PTR_ERR(pll_clk->regs);
316
317 init.name = dev->of_node->name;
318 init.ops = &hsdk_pll_ops;
319 parent_name = of_clk_get_parent_name(dev->of_node, 0);
320 init.parent_names = &parent_name;
321 num_parents = of_clk_get_parent_count(dev->of_node);
322 if (num_parents == 0 || num_parents > CGU_PLL_SOURCE_MAX) {
323 dev_err(dev, "wrong clock parents number: %u\n", num_parents);
324 return -EINVAL;
325 }
326 init.num_parents = num_parents;
327
328 pll_clk->hw.init = &init;
329 pll_clk->dev = dev;
330 pll_clk->pll_devdata = of_device_get_match_data(dev);
331
332 if (!pll_clk->pll_devdata) {
333 dev_err(dev, "No OF match data provided\n");
334 return -EINVAL;
335 }
336
337 ret = devm_clk_hw_register(dev, &pll_clk->hw);
338 if (ret) {
339 dev_err(dev, "failed to register %s clock\n", init.name);
340 return ret;
341 }
342
343 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get,
344 &pll_clk->hw);
345}
346
347static int hsdk_pll_clk_remove(struct platform_device *pdev)
348{
349 of_clk_del_provider(pdev->dev.of_node);
350 return 0;
351}
352
353static void __init of_hsdk_pll_clk_setup(struct device_node *node)
354{
355 int ret;
356 const char *parent_name;
357 unsigned int num_parents;
358 struct hsdk_pll_clk *pll_clk;
359 struct clk_init_data init = { };
360
361 pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
362 if (!pll_clk)
363 return;
364
365 pll_clk->regs = of_iomap(node, 0);
366 if (!pll_clk->regs) {
367 pr_err("failed to map pll registers\n");
368 goto err_free_pll_clk;
369 }
370
371 pll_clk->spec_regs = of_iomap(node, 1);
372 if (!pll_clk->spec_regs) {
373 pr_err("failed to map pll registers\n");
374 goto err_unmap_comm_regs;
375 }
376
377 init.name = node->name;
378 init.ops = &hsdk_pll_ops;
379 parent_name = of_clk_get_parent_name(node, 0);
380 init.parent_names = &parent_name;
381 num_parents = of_clk_get_parent_count(node);
382 if (num_parents > CGU_PLL_SOURCE_MAX) {
383 pr_err("too much clock parents: %u\n", num_parents);
384 goto err_unmap_spec_regs;
385 }
386 init.num_parents = num_parents;
387
388 pll_clk->hw.init = &init;
389 pll_clk->pll_devdata = &core_pll_devdata;
390
391 ret = clk_hw_register(NULL, &pll_clk->hw);
392 if (ret) {
393 pr_err("failed to register %s clock\n", node->name);
394 goto err_unmap_spec_regs;
395 }
396
397 ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &pll_clk->hw);
398 if (ret) {
399 pr_err("failed to add hw provider for %s clock\n", node->name);
400 goto err_unmap_spec_regs;
401 }
402
403 return;
404
405err_unmap_spec_regs:
406 iounmap(pll_clk->spec_regs);
407err_unmap_comm_regs:
408 iounmap(pll_clk->regs);
409err_free_pll_clk:
410 kfree(pll_clk);
411}
412
413/* Core PLL needed early for ARC cpus timers */
414CLK_OF_DECLARE(hsdk_pll_clock, "snps,hsdk-core-pll-clock",
415of_hsdk_pll_clk_setup);
416
417static const struct of_device_id hsdk_pll_clk_id[] = {
418 { .compatible = "snps,hsdk-gp-pll-clock", .data = &sdt_pll_devdata},
419 { .compatible = "snps,hsdk-hdmi-pll-clock", .data = &hdmi_pll_devdata},
420 { }
421};
422
423static struct platform_driver hsdk_pll_clk_driver = {
424 .driver = {
425 .name = "hsdk-gp-pll-clock",
426 .of_match_table = hsdk_pll_clk_id,
427 },
428 .probe = hsdk_pll_clk_probe,
429 .remove = hsdk_pll_clk_remove,
430};
431builtin_platform_driver(hsdk_pll_clk_driver);
diff --git a/drivers/clk/clk-mb86s7x.c b/drivers/clk/clk-mb86s7x.c
deleted file mode 100644
index 2a83a3ff1d09..000000000000
--- a/drivers/clk/clk-mb86s7x.c
+++ /dev/null
@@ -1,390 +0,0 @@
1/*
2 * Copyright (C) 2013-2015 FUJITSU SEMICONDUCTOR LIMITED
3 * Copyright (C) 2015 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 as published by
7 * the Free Software Foundation, version 2 of the License.
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#include <linux/clkdev.h>
16#include <linux/err.h>
17#include <linux/io.h>
18#include <linux/of.h>
19#include <linux/cpu.h>
20#include <linux/clk-provider.h>
21#include <linux/spinlock.h>
22#include <linux/module.h>
23#include <linux/topology.h>
24#include <linux/mailbox_client.h>
25#include <linux/platform_device.h>
26
27#include <soc/mb86s7x/scb_mhu.h>
28
29#define to_crg_clk(p) container_of(p, struct crg_clk, hw)
30#define to_clc_clk(p) container_of(p, struct cl_clk, hw)
31
32struct mb86s7x_peri_clk {
33 u32 payload_size;
34 u32 cntrlr;
35 u32 domain;
36 u32 port;
37 u32 en;
38 u64 frequency;
39} __packed __aligned(4);
40
41struct hack_rate {
42 unsigned clk_id;
43 unsigned long rate;
44 int gated;
45};
46
47struct crg_clk {
48 struct clk_hw hw;
49 u8 cntrlr, domain, port;
50};
51
52static int crg_gate_control(struct clk_hw *hw, int en)
53{
54 struct crg_clk *crgclk = to_crg_clk(hw);
55 struct mb86s7x_peri_clk cmd;
56 int ret;
57
58 cmd.payload_size = sizeof(cmd);
59 cmd.cntrlr = crgclk->cntrlr;
60 cmd.domain = crgclk->domain;
61 cmd.port = crgclk->port;
62 cmd.en = en;
63
64 /* Port is UngatedCLK */
65 if (cmd.port == 8)
66 return en ? 0 : -EINVAL;
67
68 pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u En-%u}\n",
69 __func__, __LINE__, cmd.cntrlr,
70 cmd.domain, cmd.port, cmd.en);
71
72 ret = mb86s7x_send_packet(CMD_PERI_CLOCK_GATE_SET_REQ,
73 &cmd, sizeof(cmd));
74 if (ret < 0) {
75 pr_err("%s:%d failed!\n", __func__, __LINE__);
76 return ret;
77 }
78
79 pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u En-%u}\n",
80 __func__, __LINE__, cmd.cntrlr,
81 cmd.domain, cmd.port, cmd.en);
82
83 /* If the request was rejected */
84 if (cmd.en != en)
85 ret = -EINVAL;
86 else
87 ret = 0;
88
89 return ret;
90}
91
92static int crg_port_prepare(struct clk_hw *hw)
93{
94 return crg_gate_control(hw, 1);
95}
96
97static void crg_port_unprepare(struct clk_hw *hw)
98{
99 crg_gate_control(hw, 0);
100}
101
102static int
103crg_rate_control(struct clk_hw *hw, int set, unsigned long *rate)
104{
105 struct crg_clk *crgclk = to_crg_clk(hw);
106 struct mb86s7x_peri_clk cmd;
107 int code, ret;
108
109 cmd.payload_size = sizeof(cmd);
110 cmd.cntrlr = crgclk->cntrlr;
111 cmd.domain = crgclk->domain;
112 cmd.port = crgclk->port;
113 cmd.frequency = *rate;
114
115 if (set) {
116 code = CMD_PERI_CLOCK_RATE_SET_REQ;
117 pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u Rate-SET %lluHz}\n",
118 __func__, __LINE__, cmd.cntrlr,
119 cmd.domain, cmd.port, cmd.frequency);
120 } else {
121 code = CMD_PERI_CLOCK_RATE_GET_REQ;
122 pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u Rate-GET}\n",
123 __func__, __LINE__, cmd.cntrlr,
124 cmd.domain, cmd.port);
125 }
126
127 ret = mb86s7x_send_packet(code, &cmd, sizeof(cmd));
128 if (ret < 0) {
129 pr_err("%s:%d failed!\n", __func__, __LINE__);
130 return ret;
131 }
132
133 if (set)
134 pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u Rate-SET %lluHz}\n",
135 __func__, __LINE__, cmd.cntrlr,
136 cmd.domain, cmd.port, cmd.frequency);
137 else
138 pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u Rate-GOT %lluHz}\n",
139 __func__, __LINE__, cmd.cntrlr,
140 cmd.domain, cmd.port, cmd.frequency);
141
142 *rate = cmd.frequency;
143 return 0;
144}
145
146static unsigned long
147crg_port_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
148{
149 unsigned long rate;
150
151 crg_rate_control(hw, 0, &rate);
152
153 return rate;
154}
155
156static long
157crg_port_round_rate(struct clk_hw *hw,
158 unsigned long rate, unsigned long *pr)
159{
160 return rate;
161}
162
163static int
164crg_port_set_rate(struct clk_hw *hw,
165 unsigned long rate, unsigned long parent_rate)
166{
167 return crg_rate_control(hw, 1, &rate);
168}
169
170const struct clk_ops crg_port_ops = {
171 .prepare = crg_port_prepare,
172 .unprepare = crg_port_unprepare,
173 .recalc_rate = crg_port_recalc_rate,
174 .round_rate = crg_port_round_rate,
175 .set_rate = crg_port_set_rate,
176};
177
178struct mb86s70_crg11 {
179 struct mutex lock; /* protects CLK populating and searching */
180};
181
182static struct clk *crg11_get(struct of_phandle_args *clkspec, void *data)
183{
184 struct mb86s70_crg11 *crg11 = data;
185 struct clk_init_data init;
186 u32 cntrlr, domain, port;
187 struct crg_clk *crgclk;
188 struct clk *clk;
189 char clkp[20];
190
191 if (clkspec->args_count != 3)
192 return ERR_PTR(-EINVAL);
193
194 cntrlr = clkspec->args[0];
195 domain = clkspec->args[1];
196 port = clkspec->args[2];
197
198 if (port > 7)
199 snprintf(clkp, 20, "UngatedCLK%d_%X", cntrlr, domain);
200 else
201 snprintf(clkp, 20, "CLK%d_%X_%d", cntrlr, domain, port);
202
203 mutex_lock(&crg11->lock);
204
205 clk = __clk_lookup(clkp);
206 if (clk) {
207 mutex_unlock(&crg11->lock);
208 return clk;
209 }
210
211 crgclk = kzalloc(sizeof(*crgclk), GFP_KERNEL);
212 if (!crgclk) {
213 mutex_unlock(&crg11->lock);
214 return ERR_PTR(-ENOMEM);
215 }
216
217 init.name = clkp;
218 init.num_parents = 0;
219 init.ops = &crg_port_ops;
220 init.flags = 0;
221 crgclk->hw.init = &init;
222 crgclk->cntrlr = cntrlr;
223 crgclk->domain = domain;
224 crgclk->port = port;
225 clk = clk_register(NULL, &crgclk->hw);
226 if (IS_ERR(clk))
227 pr_err("%s:%d Error!\n", __func__, __LINE__);
228 else
229 pr_debug("Registered %s\n", clkp);
230
231 clk_register_clkdev(clk, clkp, NULL);
232 mutex_unlock(&crg11->lock);
233 return clk;
234}
235
236static void __init crg_port_init(struct device_node *node)
237{
238 struct mb86s70_crg11 *crg11;
239
240 crg11 = kzalloc(sizeof(*crg11), GFP_KERNEL);
241 if (!crg11)
242 return;
243
244 mutex_init(&crg11->lock);
245
246 of_clk_add_provider(node, crg11_get, crg11);
247}
248CLK_OF_DECLARE(crg11_gate, "fujitsu,mb86s70-crg11", crg_port_init);
249
250struct cl_clk {
251 struct clk_hw hw;
252 int cluster;
253};
254
255struct mb86s7x_cpu_freq {
256 u32 payload_size;
257 u32 cluster_class;
258 u32 cluster_id;
259 u32 cpu_id;
260 u64 frequency;
261};
262
263static void mhu_cluster_rate(struct clk_hw *hw, unsigned long *rate, int get)
264{
265 struct cl_clk *clc = to_clc_clk(hw);
266 struct mb86s7x_cpu_freq cmd;
267 int code, ret;
268
269 cmd.payload_size = sizeof(cmd);
270 cmd.cluster_class = 0;
271 cmd.cluster_id = clc->cluster;
272 cmd.cpu_id = 0;
273 cmd.frequency = *rate;
274
275 if (get)
276 code = CMD_CPU_CLOCK_RATE_GET_REQ;
277 else
278 code = CMD_CPU_CLOCK_RATE_SET_REQ;
279
280 pr_debug("%s:%d CMD Cl_Class-%u CL_ID-%u CPU_ID-%u Freq-%llu}\n",
281 __func__, __LINE__, cmd.cluster_class,
282 cmd.cluster_id, cmd.cpu_id, cmd.frequency);
283
284 ret = mb86s7x_send_packet(code, &cmd, sizeof(cmd));
285 if (ret < 0) {
286 pr_err("%s:%d failed!\n", __func__, __LINE__);
287 return;
288 }
289
290 pr_debug("%s:%d REP Cl_Class-%u CL_ID-%u CPU_ID-%u Freq-%llu}\n",
291 __func__, __LINE__, cmd.cluster_class,
292 cmd.cluster_id, cmd.cpu_id, cmd.frequency);
293
294 *rate = cmd.frequency;
295}
296
297static unsigned long
298clc_recalc_rate(struct clk_hw *hw, unsigned long unused)
299{
300 unsigned long rate;
301
302 mhu_cluster_rate(hw, &rate, 1);
303 return rate;
304}
305
306static long
307clc_round_rate(struct clk_hw *hw, unsigned long rate,
308 unsigned long *unused)
309{
310 return rate;
311}
312
313static int
314clc_set_rate(struct clk_hw *hw, unsigned long rate,
315 unsigned long unused)
316{
317 unsigned long res = rate;
318
319 mhu_cluster_rate(hw, &res, 0);
320
321 return (res == rate) ? 0 : -EINVAL;
322}
323
324static struct clk_ops clk_clc_ops = {
325 .recalc_rate = clc_recalc_rate,
326 .round_rate = clc_round_rate,
327 .set_rate = clc_set_rate,
328};
329
330static struct clk_hw *mb86s7x_clclk_register(struct device *cpu_dev)
331{
332 struct clk_init_data init;
333 struct cl_clk *clc;
334 int ret;
335
336 clc = kzalloc(sizeof(*clc), GFP_KERNEL);
337 if (!clc)
338 return ERR_PTR(-ENOMEM);
339
340 clc->hw.init = &init;
341 clc->cluster = topology_physical_package_id(cpu_dev->id);
342
343 init.name = dev_name(cpu_dev);
344 init.ops = &clk_clc_ops;
345 init.flags = CLK_GET_RATE_NOCACHE;
346 init.num_parents = 0;
347
348 ret = devm_clk_hw_register(cpu_dev, &clc->hw);
349 if (ret)
350 return ERR_PTR(ret);
351 return &clc->hw;
352}
353
354static int mb86s7x_clclk_of_init(void)
355{
356 int cpu, ret = -ENODEV;
357 struct device_node *np;
358 struct clk_hw *hw;
359
360 np = of_find_compatible_node(NULL, NULL, "fujitsu,mb86s70-scb-1.0");
361 if (!np || !of_device_is_available(np))
362 goto exit;
363
364 for_each_possible_cpu(cpu) {
365 struct device *cpu_dev = get_cpu_device(cpu);
366
367 if (!cpu_dev) {
368 pr_err("failed to get cpu%d device\n", cpu);
369 continue;
370 }
371
372 hw = mb86s7x_clclk_register(cpu_dev);
373 if (IS_ERR(hw)) {
374 pr_err("failed to register cpu%d clock\n", cpu);
375 continue;
376 }
377 if (clk_hw_register_clkdev(hw, NULL, dev_name(cpu_dev))) {
378 pr_err("failed to register cpu%d clock lookup\n", cpu);
379 continue;
380 }
381 pr_debug("registered clk for %s\n", dev_name(cpu_dev));
382 }
383 ret = 0;
384
385 platform_device_register_simple("arm-bL-cpufreq-dt", -1, NULL, 0);
386exit:
387 of_node_put(np);
388 return ret;
389}
390module_init(mb86s7x_clclk_of_init);
diff --git a/drivers/clk/clk-moxart.c b/drivers/clk/clk-moxart.c
index b86dac851116..58428d0043fd 100644
--- a/drivers/clk/clk-moxart.c
+++ b/drivers/clk/clk-moxart.c
@@ -18,7 +18,7 @@
18 18
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 void __iomem *base;
22 struct clk_hw *hw; 22 struct clk_hw *hw;
23 struct clk *ref_clk; 23 struct clk *ref_clk;
24 unsigned int mul; 24 unsigned int mul;
@@ -30,7 +30,7 @@ static void __init moxart_of_pll_clk_init(struct device_node *node)
30 30
31 base = of_iomap(node, 0); 31 base = of_iomap(node, 0);
32 if (!base) { 32 if (!base) {
33 pr_err("%s: of_iomap failed\n", node->full_name); 33 pr_err("%pOF: of_iomap failed\n", node);
34 return; 34 return;
35 } 35 }
36 36
@@ -39,13 +39,13 @@ static void __init moxart_of_pll_clk_init(struct device_node *node)
39 39
40 ref_clk = of_clk_get(node, 0); 40 ref_clk = of_clk_get(node, 0);
41 if (IS_ERR(ref_clk)) { 41 if (IS_ERR(ref_clk)) {
42 pr_err("%s: of_clk_get failed\n", node->full_name); 42 pr_err("%pOF: of_clk_get failed\n", node);
43 return; 43 return;
44 } 44 }
45 45
46 hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mul, 1); 46 hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mul, 1);
47 if (IS_ERR(hw)) { 47 if (IS_ERR(hw)) {
48 pr_err("%s: failed to register clock\n", node->full_name); 48 pr_err("%pOF: failed to register clock\n", node);
49 return; 49 return;
50 } 50 }
51 51
@@ -57,7 +57,7 @@ CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock",
57 57
58static void __init moxart_of_apb_clk_init(struct device_node *node) 58static void __init moxart_of_apb_clk_init(struct device_node *node)
59{ 59{
60 static void __iomem *base; 60 void __iomem *base;
61 struct clk_hw *hw; 61 struct clk_hw *hw;
62 struct clk *pll_clk; 62 struct clk *pll_clk;
63 unsigned int div, val; 63 unsigned int div, val;
@@ -70,7 +70,7 @@ static void __init moxart_of_apb_clk_init(struct device_node *node)
70 70
71 base = of_iomap(node, 0); 71 base = of_iomap(node, 0);
72 if (!base) { 72 if (!base) {
73 pr_err("%s: of_iomap failed\n", node->full_name); 73 pr_err("%pOF: of_iomap failed\n", node);
74 return; 74 return;
75 } 75 }
76 76
@@ -83,13 +83,13 @@ static void __init moxart_of_apb_clk_init(struct device_node *node)
83 83
84 pll_clk = of_clk_get(node, 0); 84 pll_clk = of_clk_get(node, 0);
85 if (IS_ERR(pll_clk)) { 85 if (IS_ERR(pll_clk)) {
86 pr_err("%s: of_clk_get failed\n", node->full_name); 86 pr_err("%pOF: of_clk_get failed\n", node);
87 return; 87 return;
88 } 88 }
89 89
90 hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, 1, div); 90 hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, 1, div);
91 if (IS_ERR(hw)) { 91 if (IS_ERR(hw)) {
92 pr_err("%s: failed to register clock\n", node->full_name); 92 pr_err("%pOF: failed to register clock\n", node);
93 return; 93 return;
94 } 94 }
95 95
diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
index f3931e38fac0..b0ea753b8709 100644
--- a/drivers/clk/clk-qoriq.c
+++ b/drivers/clk/clk-qoriq.c
@@ -12,6 +12,7 @@
12 12
13#include <linux/clk.h> 13#include <linux/clk.h>
14#include <linux/clk-provider.h> 14#include <linux/clk-provider.h>
15#include <linux/clkdev.h>
15#include <linux/fsl/guts.h> 16#include <linux/fsl/guts.h>
16#include <linux/io.h> 17#include <linux/io.h>
17#include <linux/kernel.h> 18#include <linux/kernel.h>
@@ -537,6 +538,17 @@ static const struct clockgen_chipinfo chipinfo[] = {
537 .flags = CG_PLL_8BIT, 538 .flags = CG_PLL_8BIT,
538 }, 539 },
539 { 540 {
541 .compat = "fsl,ls1088a-clockgen",
542 .cmux_groups = {
543 &clockgen2_cmux_cga12
544 },
545 .cmux_to_group = {
546 0, 0, -1
547 },
548 .pll_mask = 0x07,
549 .flags = CG_VER3 | CG_LITTLE_ENDIAN,
550 },
551 {
540 .compat = "fsl,ls1012a-clockgen", 552 .compat = "fsl,ls1012a-clockgen",
541 .cmux_groups = { 553 .cmux_groups = {
542 &ls1012a_cmux 554 &ls1012a_cmux
@@ -1113,6 +1125,7 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
1113 1125
1114 for (i = 0; i < ARRAY_SIZE(pll->div); i++) { 1126 for (i = 0; i < ARRAY_SIZE(pll->div); i++) {
1115 struct clk *clk; 1127 struct clk *clk;
1128 int ret;
1116 1129
1117 snprintf(pll->div[i].name, sizeof(pll->div[i].name), 1130 snprintf(pll->div[i].name, sizeof(pll->div[i].name),
1118 "cg-pll%d-div%d", idx, i + 1); 1131 "cg-pll%d-div%d", idx, i + 1);
@@ -1126,6 +1139,11 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
1126 } 1139 }
1127 1140
1128 pll->div[i].clk = clk; 1141 pll->div[i].clk = clk;
1142 ret = clk_register_clkdev(clk, pll->div[i].name, NULL);
1143 if (ret != 0)
1144 pr_err("%s: %s: register to lookup table failed %ld\n",
1145 __func__, pll->div[i].name, PTR_ERR(clk));
1146
1129 } 1147 }
1130} 1148}
1131 1149
@@ -1348,8 +1366,7 @@ static void __init clockgen_init(struct device_node *np)
1348 } 1366 }
1349 1367
1350 if (i == ARRAY_SIZE(chipinfo)) { 1368 if (i == ARRAY_SIZE(chipinfo)) {
1351 pr_err("%s: unknown clockgen node %s\n", __func__, 1369 pr_err("%s: unknown clockgen node %pOF\n", __func__, np);
1352 np->full_name);
1353 goto err; 1370 goto err;
1354 } 1371 }
1355 clockgen.info = chipinfo[i]; 1372 clockgen.info = chipinfo[i];
@@ -1362,8 +1379,8 @@ static void __init clockgen_init(struct device_node *np)
1362 if (guts) { 1379 if (guts) {
1363 clockgen.guts = of_iomap(guts, 0); 1380 clockgen.guts = of_iomap(guts, 0);
1364 if (!clockgen.guts) { 1381 if (!clockgen.guts) {
1365 pr_err("%s: Couldn't map %s regs\n", __func__, 1382 pr_err("%s: Couldn't map %pOF regs\n", __func__,
1366 guts->full_name); 1383 guts);
1367 } 1384 }
1368 } 1385 }
1369 1386
@@ -1398,6 +1415,7 @@ CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init);
1398CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init); 1415CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init);
1399CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init); 1416CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init);
1400CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init); 1417CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init);
1418CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen", clockgen_init);
1401CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init); 1419CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init);
1402 1420
1403/* Legacy nodes */ 1421/* Legacy nodes */
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
index 2492442eea77..20d90769cced 100644
--- a/drivers/clk/clk-si5351.c
+++ b/drivers/clk/clk-si5351.c
@@ -519,6 +519,11 @@ static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate,
519 SI5351_CLK_INTEGER_MODE, 519 SI5351_CLK_INTEGER_MODE,
520 (hwdata->params.p2 == 0) ? SI5351_CLK_INTEGER_MODE : 0); 520 (hwdata->params.p2 == 0) ? SI5351_CLK_INTEGER_MODE : 0);
521 521
522 /* Do a pll soft reset on the affected pll */
523 si5351_reg_write(hwdata->drvdata, SI5351_PLL_RESET,
524 hwdata->num == 0 ? SI5351_PLL_RESET_A :
525 SI5351_PLL_RESET_B);
526
522 dev_dbg(&hwdata->drvdata->client->dev, 527 dev_dbg(&hwdata->drvdata->client->dev,
523 "%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n", 528 "%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n",
524 __func__, clk_hw_get_name(hw), 529 __func__, clk_hw_get_name(hw),
@@ -1091,13 +1096,6 @@ static int si5351_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
1091 si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num, 1096 si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
1092 SI5351_CLK_POWERDOWN, 0); 1097 SI5351_CLK_POWERDOWN, 0);
1093 1098
1094 /*
1095 * Do a pll soft reset on both plls, needed in some cases to get
1096 * all outputs running.
1097 */
1098 si5351_reg_write(hwdata->drvdata, SI5351_PLL_RESET,
1099 SI5351_PLL_RESET_A | SI5351_PLL_RESET_B);
1100
1101 dev_dbg(&hwdata->drvdata->client->dev, 1099 dev_dbg(&hwdata->drvdata->client->dev,
1102 "%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n", 1100 "%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
1103 __func__, clk_hw_get_name(hw), (1 << rdiv), 1101 __func__, clk_hw_get_name(hw), (1 << rdiv),
diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
index 68e2a4e499f1..96c6b6bc8f0e 100644
--- a/drivers/clk/clk-stm32f4.c
+++ b/drivers/clk/clk-stm32f4.c
@@ -1541,8 +1541,8 @@ static void __init stm32f4_rcc_init(struct device_node *np)
1541 base + gd->offset, gd->bit_idx, 0, &stm32f4_clk_lock); 1541 base + gd->offset, gd->bit_idx, 0, &stm32f4_clk_lock);
1542 1542
1543 if (IS_ERR(clks[idx])) { 1543 if (IS_ERR(clks[idx])) {
1544 pr_err("%s: Unable to register leaf clock %s\n", 1544 pr_err("%pOF: Unable to register leaf clock %s\n",
1545 np->full_name, gd->name); 1545 np, gd->name);
1546 goto fail; 1546 goto fail;
1547 } 1547 }
1548 } 1548 }
diff --git a/drivers/clk/clk-stm32h7.c b/drivers/clk/clk-stm32h7.c
new file mode 100644
index 000000000000..a94c3f56c590
--- /dev/null
+++ b/drivers/clk/clk-stm32h7.c
@@ -0,0 +1,1410 @@
1/*
2 * Copyright (C) Gabriel Fernandez 2017
3 * Author: Gabriel Fernandez <gabriel.fernandez@st.com>
4 *
5 * License terms: GPL V2.0.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/clk.h>
21#include <linux/clk-provider.h>
22#include <linux/err.h>
23#include <linux/io.h>
24#include <linux/mfd/syscon.h>
25#include <linux/of.h>
26#include <linux/of_address.h>
27#include <linux/slab.h>
28#include <linux/spinlock.h>
29#include <linux/regmap.h>
30
31#include <dt-bindings/clock/stm32h7-clks.h>
32
33/* Reset Clock Control Registers */
34#define RCC_CR 0x00
35#define RCC_CFGR 0x10
36#define RCC_D1CFGR 0x18
37#define RCC_D2CFGR 0x1C
38#define RCC_D3CFGR 0x20
39#define RCC_PLLCKSELR 0x28
40#define RCC_PLLCFGR 0x2C
41#define RCC_PLL1DIVR 0x30
42#define RCC_PLL1FRACR 0x34
43#define RCC_PLL2DIVR 0x38
44#define RCC_PLL2FRACR 0x3C
45#define RCC_PLL3DIVR 0x40
46#define RCC_PLL3FRACR 0x44
47#define RCC_D1CCIPR 0x4C
48#define RCC_D2CCIP1R 0x50
49#define RCC_D2CCIP2R 0x54
50#define RCC_D3CCIPR 0x58
51#define RCC_BDCR 0x70
52#define RCC_CSR 0x74
53#define RCC_AHB3ENR 0xD4
54#define RCC_AHB1ENR 0xD8
55#define RCC_AHB2ENR 0xDC
56#define RCC_AHB4ENR 0xE0
57#define RCC_APB3ENR 0xE4
58#define RCC_APB1LENR 0xE8
59#define RCC_APB1HENR 0xEC
60#define RCC_APB2ENR 0xF0
61#define RCC_APB4ENR 0xF4
62
63static DEFINE_SPINLOCK(stm32rcc_lock);
64
65static void __iomem *base;
66static struct clk_hw **hws;
67
68/* System clock parent */
69static const char * const sys_src[] = {
70 "hsi_ck", "csi_ck", "hse_ck", "pll1_p" };
71
72static const char * const tracein_src[] = {
73 "hsi_ck", "csi_ck", "hse_ck", "pll1_r" };
74
75static const char * const per_src[] = {
76 "hsi_ker", "csi_ker", "hse_ck", "disabled" };
77
78static const char * const pll_src[] = {
79 "hsi_ck", "csi_ck", "hse_ck", "no clock" };
80
81static const char * const sdmmc_src[] = { "pll1_q", "pll2_r" };
82
83static const char * const dsi_src[] = { "ck_dsi_phy", "pll2_q" };
84
85static const char * const qspi_src[] = {
86 "hclk", "pll1_q", "pll2_r", "per_ck" };
87
88static const char * const fmc_src[] = {
89 "hclk", "pll1_q", "pll2_r", "per_ck" };
90
91/* Kernel clock parent */
92static const char * const swp_src[] = { "pclk1", "hsi_ker" };
93
94static const char * const fdcan_src[] = { "hse_ck", "pll1_q", "pll2_q" };
95
96static const char * const dfsdm1_src[] = { "pclk2", "sys_ck" };
97
98static const char * const spdifrx_src[] = {
99 "pll1_q", "pll2_r", "pll3_r", "hsi_ker" };
100
101static const char *spi_src1[5] = {
102 "pll1_q", "pll2_p", "pll3_p", NULL, "per_ck" };
103
104static const char * const spi_src2[] = {
105 "pclk2", "pll2_q", "pll3_q", "hsi_ker", "csi_ker", "hse_ck" };
106
107static const char * const spi_src3[] = {
108 "pclk4", "pll2_q", "pll3_q", "hsi_ker", "csi_ker", "hse_ck" };
109
110static const char * const lptim_src1[] = {
111 "pclk1", "pll2_p", "pll3_r", "lse_ck", "lsi_ck", "per_ck" };
112
113static const char * const lptim_src2[] = {
114 "pclk4", "pll2_p", "pll3_r", "lse_ck", "lsi_ck", "per_ck" };
115
116static const char * const cec_src[] = {"lse_ck", "lsi_ck", "csi_ker_div122" };
117
118static const char * const usbotg_src[] = {"pll1_q", "pll3_q", "rc48_ck" };
119
120/* i2c 1,2,3 src */
121static const char * const i2c_src1[] = {
122 "pclk1", "pll3_r", "hsi_ker", "csi_ker" };
123
124static const char * const i2c_src2[] = {
125 "pclk4", "pll3_r", "hsi_ker", "csi_ker" };
126
127static const char * const rng_src[] = {
128 "rc48_ck", "pll1_q", "lse_ck", "lsi_ck" };
129
130/* usart 1,6 src */
131static const char * const usart_src1[] = {
132 "pclk2", "pll2_q", "pll3_q", "hsi_ker", "csi_ker", "lse_ck" };
133
134/* usart 2,3,4,5,7,8 src */
135static const char * const usart_src2[] = {
136 "pclk1", "pll2_q", "pll3_q", "hsi_ker", "csi_ker", "lse_ck" };
137
138static const char *sai_src[5] = {
139 "pll1_q", "pll2_p", "pll3_p", NULL, "per_ck" };
140
141static const char * const adc_src[] = { "pll2_p", "pll3_r", "per_ck" };
142
143/* lptim 2,3,4,5 src */
144static const char * const lpuart1_src[] = {
145 "pclk3", "pll2_q", "pll3_q", "csi_ker", "lse_ck" };
146
147static const char * const hrtim_src[] = { "tim2_ker", "d1cpre" };
148
149/* RTC clock parent */
150static const char * const rtc_src[] = { "off", "lse_ck", "lsi_ck", "hse_1M" };
151
152/* Micro-controller output clock parent */
153static const char * const mco_src1[] = {
154 "hsi_ck", "lse_ck", "hse_ck", "pll1_q", "rc48_ck" };
155
156static const char * const mco_src2[] = {
157 "sys_ck", "pll2_p", "hse_ck", "pll1_p", "csi_ck", "lsi_ck" };
158
159/* LCD clock */
160static const char * const ltdc_src[] = {"pll3_r"};
161
162/* Gate clock with ready bit and backup domain management */
163struct stm32_ready_gate {
164 struct clk_gate gate;
165 u8 bit_rdy;
166};
167
168#define to_ready_gate_clk(_rgate) container_of(_rgate, struct stm32_ready_gate,\
169 gate)
170
171#define RGATE_TIMEOUT 10000
172
173static int ready_gate_clk_enable(struct clk_hw *hw)
174{
175 struct clk_gate *gate = to_clk_gate(hw);
176 struct stm32_ready_gate *rgate = to_ready_gate_clk(gate);
177 int bit_status;
178 unsigned int timeout = RGATE_TIMEOUT;
179
180 if (clk_gate_ops.is_enabled(hw))
181 return 0;
182
183 clk_gate_ops.enable(hw);
184
185 /* We can't use readl_poll_timeout() because we can blocked if
186 * someone enables this clock before clocksource changes.
187 * Only jiffies counter is available. Jiffies are incremented by
188 * interruptions and enable op does not allow to be interrupted.
189 */
190 do {
191 bit_status = !(readl(gate->reg) & BIT(rgate->bit_rdy));
192
193 if (bit_status)
194 udelay(100);
195
196 } while (bit_status && --timeout);
197
198 return bit_status;
199}
200
201static void ready_gate_clk_disable(struct clk_hw *hw)
202{
203 struct clk_gate *gate = to_clk_gate(hw);
204 struct stm32_ready_gate *rgate = to_ready_gate_clk(gate);
205 int bit_status;
206 unsigned int timeout = RGATE_TIMEOUT;
207
208 if (!clk_gate_ops.is_enabled(hw))
209 return;
210
211 clk_gate_ops.disable(hw);
212
213 do {
214 bit_status = !!(readl(gate->reg) & BIT(rgate->bit_rdy));
215
216 if (bit_status)
217 udelay(100);
218
219 } while (bit_status && --timeout);
220}
221
222static const struct clk_ops ready_gate_clk_ops = {
223 .enable = ready_gate_clk_enable,
224 .disable = ready_gate_clk_disable,
225 .is_enabled = clk_gate_is_enabled,
226};
227
228static struct clk_hw *clk_register_ready_gate(struct device *dev,
229 const char *name, const char *parent_name,
230 void __iomem *reg, u8 bit_idx, u8 bit_rdy,
231 unsigned long flags, spinlock_t *lock)
232{
233 struct stm32_ready_gate *rgate;
234 struct clk_init_data init = { NULL };
235 struct clk_hw *hw;
236 int ret;
237
238 rgate = kzalloc(sizeof(*rgate), GFP_KERNEL);
239 if (!rgate)
240 return ERR_PTR(-ENOMEM);
241
242 init.name = name;
243 init.ops = &ready_gate_clk_ops;
244 init.flags = flags;
245 init.parent_names = &parent_name;
246 init.num_parents = 1;
247
248 rgate->bit_rdy = bit_rdy;
249 rgate->gate.lock = lock;
250 rgate->gate.reg = reg;
251 rgate->gate.bit_idx = bit_idx;
252 rgate->gate.hw.init = &init;
253
254 hw = &rgate->gate.hw;
255 ret = clk_hw_register(dev, hw);
256 if (ret) {
257 kfree(rgate);
258 hw = ERR_PTR(ret);
259 }
260
261 return hw;
262}
263
264struct gate_cfg {
265 u32 offset;
266 u8 bit_idx;
267};
268
269struct muxdiv_cfg {
270 u32 offset;
271 u8 shift;
272 u8 width;
273};
274
275struct composite_clk_cfg {
276 struct gate_cfg *gate;
277 struct muxdiv_cfg *mux;
278 struct muxdiv_cfg *div;
279 const char *name;
280 const char * const *parent_name;
281 int num_parents;
282 u32 flags;
283};
284
285struct composite_clk_gcfg_t {
286 u8 flags;
287 const struct clk_ops *ops;
288};
289
290/*
291 * General config definition of a composite clock (only clock diviser for rate)
292 */
293struct composite_clk_gcfg {
294 struct composite_clk_gcfg_t *mux;
295 struct composite_clk_gcfg_t *div;
296 struct composite_clk_gcfg_t *gate;
297};
298
299#define M_CFG_MUX(_mux_ops, _mux_flags)\
300 .mux = &(struct composite_clk_gcfg_t) { _mux_flags, _mux_ops}
301
302#define M_CFG_DIV(_rate_ops, _rate_flags)\
303 .div = &(struct composite_clk_gcfg_t) {_rate_flags, _rate_ops}
304
305#define M_CFG_GATE(_gate_ops, _gate_flags)\
306 .gate = &(struct composite_clk_gcfg_t) { _gate_flags, _gate_ops}
307
308static struct clk_mux *_get_cmux(void __iomem *reg, u8 shift, u8 width,
309 u32 flags, spinlock_t *lock)
310{
311 struct clk_mux *mux;
312
313 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
314 if (!mux)
315 return ERR_PTR(-ENOMEM);
316
317 mux->reg = reg;
318 mux->shift = shift;
319 mux->mask = (1 << width) - 1;
320 mux->flags = flags;
321 mux->lock = lock;
322
323 return mux;
324}
325
326static struct clk_divider *_get_cdiv(void __iomem *reg, u8 shift, u8 width,
327 u32 flags, spinlock_t *lock)
328{
329 struct clk_divider *div;
330
331 div = kzalloc(sizeof(*div), GFP_KERNEL);
332
333 if (!div)
334 return ERR_PTR(-ENOMEM);
335
336 div->reg = reg;
337 div->shift = shift;
338 div->width = width;
339 div->flags = flags;
340 div->lock = lock;
341
342 return div;
343}
344
345static struct clk_gate *_get_cgate(void __iomem *reg, u8 bit_idx, u32 flags,
346 spinlock_t *lock)
347{
348 struct clk_gate *gate;
349
350 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
351 if (!gate)
352 return ERR_PTR(-ENOMEM);
353
354 gate->reg = reg;
355 gate->bit_idx = bit_idx;
356 gate->flags = flags;
357 gate->lock = lock;
358
359 return gate;
360}
361
362struct composite_cfg {
363 struct clk_hw *mux_hw;
364 struct clk_hw *div_hw;
365 struct clk_hw *gate_hw;
366
367 const struct clk_ops *mux_ops;
368 const struct clk_ops *div_ops;
369 const struct clk_ops *gate_ops;
370};
371
372static void get_cfg_composite_div(const struct composite_clk_gcfg *gcfg,
373 const struct composite_clk_cfg *cfg,
374 struct composite_cfg *composite, spinlock_t *lock)
375{
376 struct clk_mux *mux = NULL;
377 struct clk_divider *div = NULL;
378 struct clk_gate *gate = NULL;
379 const struct clk_ops *mux_ops, *div_ops, *gate_ops;
380 struct clk_hw *mux_hw;
381 struct clk_hw *div_hw;
382 struct clk_hw *gate_hw;
383
384 mux_ops = div_ops = gate_ops = NULL;
385 mux_hw = div_hw = gate_hw = NULL;
386
387 if (gcfg->mux && gcfg->mux) {
388 mux = _get_cmux(base + cfg->mux->offset,
389 cfg->mux->shift,
390 cfg->mux->width,
391 gcfg->mux->flags, lock);
392
393 if (!IS_ERR(mux)) {
394 mux_hw = &mux->hw;
395 mux_ops = gcfg->mux->ops ?
396 gcfg->mux->ops : &clk_mux_ops;
397 }
398 }
399
400 if (gcfg->div && cfg->div) {
401 div = _get_cdiv(base + cfg->div->offset,
402 cfg->div->shift,
403 cfg->div->width,
404 gcfg->div->flags, lock);
405
406 if (!IS_ERR(div)) {
407 div_hw = &div->hw;
408 div_ops = gcfg->div->ops ?
409 gcfg->div->ops : &clk_divider_ops;
410 }
411 }
412
413 if (gcfg->gate && gcfg->gate) {
414 gate = _get_cgate(base + cfg->gate->offset,
415 cfg->gate->bit_idx,
416 gcfg->gate->flags, lock);
417
418 if (!IS_ERR(gate)) {
419 gate_hw = &gate->hw;
420 gate_ops = gcfg->gate->ops ?
421 gcfg->gate->ops : &clk_gate_ops;
422 }
423 }
424
425 composite->mux_hw = mux_hw;
426 composite->mux_ops = mux_ops;
427
428 composite->div_hw = div_hw;
429 composite->div_ops = div_ops;
430
431 composite->gate_hw = gate_hw;
432 composite->gate_ops = gate_ops;
433}
434
435/* Kernel Timer */
436struct timer_ker {
437 u8 dppre_shift;
438 struct clk_hw hw;
439 spinlock_t *lock;
440};
441
442#define to_timer_ker(_hw) container_of(_hw, struct timer_ker, hw)
443
444static unsigned long timer_ker_recalc_rate(struct clk_hw *hw,
445 unsigned long parent_rate)
446{
447 struct timer_ker *clk_elem = to_timer_ker(hw);
448 u32 timpre;
449 u32 dppre_shift = clk_elem->dppre_shift;
450 u32 prescaler;
451 u32 mul;
452
453 timpre = (readl(base + RCC_CFGR) >> 15) & 0x01;
454
455 prescaler = (readl(base + RCC_D2CFGR) >> dppre_shift) & 0x03;
456
457 mul = 2;
458
459 if (prescaler < 4)
460 mul = 1;
461
462 else if (timpre && prescaler > 4)
463 mul = 4;
464
465 return parent_rate * mul;
466}
467
468static const struct clk_ops timer_ker_ops = {
469 .recalc_rate = timer_ker_recalc_rate,
470};
471
472static struct clk_hw *clk_register_stm32_timer_ker(struct device *dev,
473 const char *name, const char *parent_name,
474 unsigned long flags,
475 u8 dppre_shift,
476 spinlock_t *lock)
477{
478 struct timer_ker *element;
479 struct clk_init_data init;
480 struct clk_hw *hw;
481 int err;
482
483 element = kzalloc(sizeof(*element), GFP_KERNEL);
484 if (!element)
485 return ERR_PTR(-ENOMEM);
486
487 init.name = name;
488 init.ops = &timer_ker_ops;
489 init.flags = flags;
490 init.parent_names = &parent_name;
491 init.num_parents = 1;
492
493 element->hw.init = &init;
494 element->lock = lock;
495 element->dppre_shift = dppre_shift;
496
497 hw = &element->hw;
498 err = clk_hw_register(dev, hw);
499
500 if (err) {
501 kfree(element);
502 return ERR_PTR(err);
503 }
504
505 return hw;
506}
507
508static const struct clk_div_table d1cpre_div_table[] = {
509 { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1},
510 { 4, 1 }, { 5, 1 }, { 6, 1 }, { 7, 1},
511 { 8, 2 }, { 9, 4 }, { 10, 8 }, { 11, 16 },
512 { 12, 64 }, { 13, 128 }, { 14, 256 },
513 { 15, 512 },
514 { 0 },
515};
516
517static const struct clk_div_table ppre_div_table[] = {
518 { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1},
519 { 4, 2 }, { 5, 4 }, { 6, 8 }, { 7, 16 },
520 { 0 },
521};
522
523static void register_core_and_bus_clocks(void)
524{
525 /* CORE AND BUS */
526 hws[SYS_D1CPRE] = clk_hw_register_divider_table(NULL, "d1cpre",
527 "sys_ck", CLK_IGNORE_UNUSED, base + RCC_D1CFGR, 8, 4, 0,
528 d1cpre_div_table, &stm32rcc_lock);
529
530 hws[HCLK] = clk_hw_register_divider_table(NULL, "hclk", "d1cpre",
531 CLK_IGNORE_UNUSED, base + RCC_D1CFGR, 0, 4, 0,
532 d1cpre_div_table, &stm32rcc_lock);
533
534 /* D1 DOMAIN */
535 /* * CPU Systick */
536 hws[CPU_SYSTICK] = clk_hw_register_fixed_factor(NULL, "systick",
537 "d1cpre", 0, 1, 8);
538
539 /* * APB3 peripheral */
540 hws[PCLK3] = clk_hw_register_divider_table(NULL, "pclk3", "hclk", 0,
541 base + RCC_D1CFGR, 4, 3, 0,
542 ppre_div_table, &stm32rcc_lock);
543
544 /* D2 DOMAIN */
545 /* * APB1 peripheral */
546 hws[PCLK1] = clk_hw_register_divider_table(NULL, "pclk1", "hclk", 0,
547 base + RCC_D2CFGR, 4, 3, 0,
548 ppre_div_table, &stm32rcc_lock);
549
550 /* Timers prescaler clocks */
551 clk_register_stm32_timer_ker(NULL, "tim1_ker", "pclk1", 0,
552 4, &stm32rcc_lock);
553
554 /* * APB2 peripheral */
555 hws[PCLK2] = clk_hw_register_divider_table(NULL, "pclk2", "hclk", 0,
556 base + RCC_D2CFGR, 8, 3, 0, ppre_div_table,
557 &stm32rcc_lock);
558
559 clk_register_stm32_timer_ker(NULL, "tim2_ker", "pclk2", 0, 8,
560 &stm32rcc_lock);
561
562 /* D3 DOMAIN */
563 /* * APB4 peripheral */
564 hws[PCLK4] = clk_hw_register_divider_table(NULL, "pclk4", "hclk", 0,
565 base + RCC_D3CFGR, 4, 3, 0,
566 ppre_div_table, &stm32rcc_lock);
567}
568
569/* MUX clock configuration */
570struct stm32_mux_clk {
571 const char *name;
572 const char * const *parents;
573 u8 num_parents;
574 u32 offset;
575 u8 shift;
576 u8 width;
577 u32 flags;
578};
579
580#define M_MCLOCF(_name, _parents, _mux_offset, _mux_shift, _mux_width, _flags)\
581{\
582 .name = _name,\
583 .parents = _parents,\
584 .num_parents = ARRAY_SIZE(_parents),\
585 .offset = _mux_offset,\
586 .shift = _mux_shift,\
587 .width = _mux_width,\
588 .flags = _flags,\
589}
590
591#define M_MCLOC(_name, _parents, _mux_offset, _mux_shift, _mux_width)\
592 M_MCLOCF(_name, _parents, _mux_offset, _mux_shift, _mux_width, 0)\
593
594static const struct stm32_mux_clk stm32_mclk[] __initconst = {
595 M_MCLOC("per_ck", per_src, RCC_D1CCIPR, 28, 3),
596 M_MCLOC("pllsrc", pll_src, RCC_PLLCKSELR, 0, 3),
597 M_MCLOC("sys_ck", sys_src, RCC_CFGR, 0, 3),
598 M_MCLOC("tracein_ck", tracein_src, RCC_CFGR, 0, 3),
599};
600
601/* Oscillary clock configuration */
602struct stm32_osc_clk {
603 const char *name;
604 const char *parent;
605 u32 gate_offset;
606 u8 bit_idx;
607 u8 bit_rdy;
608 u32 flags;
609};
610
611#define OSC_CLKF(_name, _parent, _gate_offset, _bit_idx, _bit_rdy, _flags)\
612{\
613 .name = _name,\
614 .parent = _parent,\
615 .gate_offset = _gate_offset,\
616 .bit_idx = _bit_idx,\
617 .bit_rdy = _bit_rdy,\
618 .flags = _flags,\
619}
620
621#define OSC_CLK(_name, _parent, _gate_offset, _bit_idx, _bit_rdy)\
622 OSC_CLKF(_name, _parent, _gate_offset, _bit_idx, _bit_rdy, 0)
623
624static const struct stm32_osc_clk stm32_oclk[] __initconst = {
625 OSC_CLKF("hsi_ck", "hsidiv", RCC_CR, 0, 2, CLK_IGNORE_UNUSED),
626 OSC_CLKF("hsi_ker", "hsidiv", RCC_CR, 1, 2, CLK_IGNORE_UNUSED),
627 OSC_CLKF("csi_ck", "clk-csi", RCC_CR, 7, 8, CLK_IGNORE_UNUSED),
628 OSC_CLKF("csi_ker", "clk-csi", RCC_CR, 9, 8, CLK_IGNORE_UNUSED),
629 OSC_CLKF("rc48_ck", "clk-rc48", RCC_CR, 12, 13, CLK_IGNORE_UNUSED),
630 OSC_CLKF("lsi_ck", "clk-lsi", RCC_CSR, 0, 1, CLK_IGNORE_UNUSED),
631};
632
633/* PLL configuration */
634struct st32h7_pll_cfg {
635 u8 bit_idx;
636 u32 offset_divr;
637 u8 bit_frac_en;
638 u32 offset_frac;
639 u8 divm;
640};
641
642struct stm32_pll_data {
643 const char *name;
644 const char *parent_name;
645 unsigned long flags;
646 const struct st32h7_pll_cfg *cfg;
647};
648
649static const struct st32h7_pll_cfg stm32h7_pll1 = {
650 .bit_idx = 24,
651 .offset_divr = RCC_PLL1DIVR,
652 .bit_frac_en = 0,
653 .offset_frac = RCC_PLL1FRACR,
654 .divm = 4,
655};
656
657static const struct st32h7_pll_cfg stm32h7_pll2 = {
658 .bit_idx = 26,
659 .offset_divr = RCC_PLL2DIVR,
660 .bit_frac_en = 4,
661 .offset_frac = RCC_PLL2FRACR,
662 .divm = 12,
663};
664
665static const struct st32h7_pll_cfg stm32h7_pll3 = {
666 .bit_idx = 28,
667 .offset_divr = RCC_PLL3DIVR,
668 .bit_frac_en = 8,
669 .offset_frac = RCC_PLL3FRACR,
670 .divm = 20,
671};
672
673static const struct stm32_pll_data stm32_pll[] = {
674 { "vco1", "pllsrc", CLK_IGNORE_UNUSED, &stm32h7_pll1 },
675 { "vco2", "pllsrc", 0, &stm32h7_pll2 },
676 { "vco3", "pllsrc", 0, &stm32h7_pll3 },
677};
678
679struct stm32_fractional_divider {
680 void __iomem *mreg;
681 u8 mshift;
682 u8 mwidth;
683 u32 mmask;
684
685 void __iomem *nreg;
686 u8 nshift;
687 u8 nwidth;
688
689 void __iomem *freg_status;
690 u8 freg_bit;
691 void __iomem *freg_value;
692 u8 fshift;
693 u8 fwidth;
694
695 u8 flags;
696 struct clk_hw hw;
697 spinlock_t *lock;
698};
699
700struct stm32_pll_obj {
701 spinlock_t *lock;
702 struct stm32_fractional_divider div;
703 struct stm32_ready_gate rgate;
704 struct clk_hw hw;
705};
706
707#define to_pll(_hw) container_of(_hw, struct stm32_pll_obj, hw)
708
709static int pll_is_enabled(struct clk_hw *hw)
710{
711 struct stm32_pll_obj *clk_elem = to_pll(hw);
712 struct clk_hw *_hw = &clk_elem->rgate.gate.hw;
713
714 __clk_hw_set_clk(_hw, hw);
715
716 return ready_gate_clk_ops.is_enabled(_hw);
717}
718
719static int pll_enable(struct clk_hw *hw)
720{
721 struct stm32_pll_obj *clk_elem = to_pll(hw);
722 struct clk_hw *_hw = &clk_elem->rgate.gate.hw;
723
724 __clk_hw_set_clk(_hw, hw);
725
726 return ready_gate_clk_ops.enable(_hw);
727}
728
729static void pll_disable(struct clk_hw *hw)
730{
731 struct stm32_pll_obj *clk_elem = to_pll(hw);
732 struct clk_hw *_hw = &clk_elem->rgate.gate.hw;
733
734 __clk_hw_set_clk(_hw, hw);
735
736 ready_gate_clk_ops.disable(_hw);
737}
738
739static int pll_frac_is_enabled(struct clk_hw *hw)
740{
741 struct stm32_pll_obj *clk_elem = to_pll(hw);
742 struct stm32_fractional_divider *fd = &clk_elem->div;
743
744 return (readl(fd->freg_status) >> fd->freg_bit) & 0x01;
745}
746
747static unsigned long pll_read_frac(struct clk_hw *hw)
748{
749 struct stm32_pll_obj *clk_elem = to_pll(hw);
750 struct stm32_fractional_divider *fd = &clk_elem->div;
751
752 return (readl(fd->freg_value) >> fd->fshift) &
753 GENMASK(fd->fwidth - 1, 0);
754}
755
756static unsigned long pll_fd_recalc_rate(struct clk_hw *hw,
757 unsigned long parent_rate)
758{
759 struct stm32_pll_obj *clk_elem = to_pll(hw);
760 struct stm32_fractional_divider *fd = &clk_elem->div;
761 unsigned long m, n;
762 u32 val, mask;
763 u64 rate, rate1 = 0;
764
765 val = readl(fd->mreg);
766 mask = GENMASK(fd->mwidth - 1, 0) << fd->mshift;
767 m = (val & mask) >> fd->mshift;
768
769 val = readl(fd->nreg);
770 mask = GENMASK(fd->nwidth - 1, 0) << fd->nshift;
771 n = ((val & mask) >> fd->nshift) + 1;
772
773 if (!n || !m)
774 return parent_rate;
775
776 rate = (u64)parent_rate * n;
777 do_div(rate, m);
778
779 if (pll_frac_is_enabled(hw)) {
780 val = pll_read_frac(hw);
781 rate1 = (u64)parent_rate * (u64)val;
782 do_div(rate1, (m * 8191));
783 }
784
785 return rate + rate1;
786}
787
788static const struct clk_ops pll_ops = {
789 .enable = pll_enable,
790 .disable = pll_disable,
791 .is_enabled = pll_is_enabled,
792 .recalc_rate = pll_fd_recalc_rate,
793};
794
795static struct clk_hw *clk_register_stm32_pll(struct device *dev,
796 const char *name,
797 const char *parent,
798 unsigned long flags,
799 const struct st32h7_pll_cfg *cfg,
800 spinlock_t *lock)
801{
802 struct stm32_pll_obj *pll;
803 struct clk_init_data init = { NULL };
804 struct clk_hw *hw;
805 int ret;
806 struct stm32_fractional_divider *div = NULL;
807 struct stm32_ready_gate *rgate;
808
809 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
810 if (!pll)
811 return ERR_PTR(-ENOMEM);
812
813 init.name = name;
814 init.ops = &pll_ops;
815 init.flags = flags;
816 init.parent_names = &parent;
817 init.num_parents = 1;
818 pll->hw.init = &init;
819
820 hw = &pll->hw;
821 rgate = &pll->rgate;
822
823 rgate->bit_rdy = cfg->bit_idx + 1;
824 rgate->gate.lock = lock;
825 rgate->gate.reg = base + RCC_CR;
826 rgate->gate.bit_idx = cfg->bit_idx;
827
828 div = &pll->div;
829 div->flags = 0;
830 div->mreg = base + RCC_PLLCKSELR;
831 div->mshift = cfg->divm;
832 div->mwidth = 6;
833 div->nreg = base + cfg->offset_divr;
834 div->nshift = 0;
835 div->nwidth = 9;
836
837 div->freg_status = base + RCC_PLLCFGR;
838 div->freg_bit = cfg->bit_frac_en;
839 div->freg_value = base + cfg->offset_frac;
840 div->fshift = 3;
841 div->fwidth = 13;
842
843 div->lock = lock;
844
845 ret = clk_hw_register(dev, hw);
846 if (ret) {
847 kfree(pll);
848 hw = ERR_PTR(ret);
849 }
850
851 return hw;
852}
853
854/* ODF CLOCKS */
855static unsigned long odf_divider_recalc_rate(struct clk_hw *hw,
856 unsigned long parent_rate)
857{
858 return clk_divider_ops.recalc_rate(hw, parent_rate);
859}
860
861static long odf_divider_round_rate(struct clk_hw *hw, unsigned long rate,
862 unsigned long *prate)
863{
864 return clk_divider_ops.round_rate(hw, rate, prate);
865}
866
867static int odf_divider_set_rate(struct clk_hw *hw, unsigned long rate,
868 unsigned long parent_rate)
869{
870 struct clk_hw *hwp;
871 int pll_status;
872 int ret;
873
874 hwp = clk_hw_get_parent(hw);
875
876 pll_status = pll_is_enabled(hwp);
877
878 if (pll_status)
879 pll_disable(hwp);
880
881 ret = clk_divider_ops.set_rate(hw, rate, parent_rate);
882
883 if (pll_status)
884 pll_enable(hwp);
885
886 return ret;
887}
888
889static const struct clk_ops odf_divider_ops = {
890 .recalc_rate = odf_divider_recalc_rate,
891 .round_rate = odf_divider_round_rate,
892 .set_rate = odf_divider_set_rate,
893};
894
895static int odf_gate_enable(struct clk_hw *hw)
896{
897 struct clk_hw *hwp;
898 int pll_status;
899 int ret;
900
901 if (clk_gate_ops.is_enabled(hw))
902 return 0;
903
904 hwp = clk_hw_get_parent(hw);
905
906 pll_status = pll_is_enabled(hwp);
907
908 if (pll_status)
909 pll_disable(hwp);
910
911 ret = clk_gate_ops.enable(hw);
912
913 if (pll_status)
914 pll_enable(hwp);
915
916 return ret;
917}
918
919static void odf_gate_disable(struct clk_hw *hw)
920{
921 struct clk_hw *hwp;
922 int pll_status;
923
924 if (!clk_gate_ops.is_enabled(hw))
925 return;
926
927 hwp = clk_hw_get_parent(hw);
928
929 pll_status = pll_is_enabled(hwp);
930
931 if (pll_status)
932 pll_disable(hwp);
933
934 clk_gate_ops.disable(hw);
935
936 if (pll_status)
937 pll_enable(hwp);
938}
939
940static const struct clk_ops odf_gate_ops = {
941 .enable = odf_gate_enable,
942 .disable = odf_gate_disable,
943 .is_enabled = clk_gate_is_enabled,
944};
945
946static struct composite_clk_gcfg odf_clk_gcfg = {
947 M_CFG_DIV(&odf_divider_ops, 0),
948 M_CFG_GATE(&odf_gate_ops, 0),
949};
950
951#define M_ODF_F(_name, _parent, _gate_offset, _bit_idx, _rate_offset,\
952 _rate_shift, _rate_width, _flags)\
953{\
954 .mux = NULL,\
955 .div = &(struct muxdiv_cfg) {_rate_offset, _rate_shift, _rate_width},\
956 .gate = &(struct gate_cfg) {_gate_offset, _bit_idx },\
957 .name = _name,\
958 .parent_name = &(const char *) {_parent},\
959 .num_parents = 1,\
960 .flags = _flags,\
961}
962
963#define M_ODF(_name, _parent, _gate_offset, _bit_idx, _rate_offset,\
964 _rate_shift, _rate_width)\
965M_ODF_F(_name, _parent, _gate_offset, _bit_idx, _rate_offset,\
966 _rate_shift, _rate_width, 0)\
967
968static const struct composite_clk_cfg stm32_odf[3][3] = {
969 {
970 M_ODF_F("pll1_p", "vco1", RCC_PLLCFGR, 16, RCC_PLL1DIVR, 9, 7,
971 CLK_IGNORE_UNUSED),
972 M_ODF_F("pll1_q", "vco1", RCC_PLLCFGR, 17, RCC_PLL1DIVR, 16, 7,
973 CLK_IGNORE_UNUSED),
974 M_ODF_F("pll1_r", "vco1", RCC_PLLCFGR, 18, RCC_PLL1DIVR, 24, 7,
975 CLK_IGNORE_UNUSED),
976 },
977
978 {
979 M_ODF("pll2_p", "vco2", RCC_PLLCFGR, 19, RCC_PLL2DIVR, 9, 7),
980 M_ODF("pll2_q", "vco2", RCC_PLLCFGR, 20, RCC_PLL2DIVR, 16, 7),
981 M_ODF("pll2_r", "vco2", RCC_PLLCFGR, 21, RCC_PLL2DIVR, 24, 7),
982 },
983 {
984 M_ODF("pll3_p", "vco3", RCC_PLLCFGR, 22, RCC_PLL3DIVR, 9, 7),
985 M_ODF("pll3_q", "vco3", RCC_PLLCFGR, 23, RCC_PLL3DIVR, 16, 7),
986 M_ODF("pll3_r", "vco3", RCC_PLLCFGR, 24, RCC_PLL3DIVR, 24, 7),
987 }
988};
989
990/* PERIF CLOCKS */
991struct pclk_t {
992 u32 gate_offset;
993 u8 bit_idx;
994 const char *name;
995 const char *parent;
996 u32 flags;
997};
998
999#define PER_CLKF(_gate_offset, _bit_idx, _name, _parent, _flags)\
1000{\
1001 .gate_offset = _gate_offset,\
1002 .bit_idx = _bit_idx,\
1003 .name = _name,\
1004 .parent = _parent,\
1005 .flags = _flags,\
1006}
1007
1008#define PER_CLK(_gate_offset, _bit_idx, _name, _parent)\
1009 PER_CLKF(_gate_offset, _bit_idx, _name, _parent, 0)
1010
1011static const struct pclk_t pclk[] = {
1012 PER_CLK(RCC_AHB3ENR, 31, "d1sram1", "hclk"),
1013 PER_CLK(RCC_AHB3ENR, 30, "itcm", "hclk"),
1014 PER_CLK(RCC_AHB3ENR, 29, "dtcm2", "hclk"),
1015 PER_CLK(RCC_AHB3ENR, 28, "dtcm1", "hclk"),
1016 PER_CLK(RCC_AHB3ENR, 8, "flitf", "hclk"),
1017 PER_CLK(RCC_AHB3ENR, 5, "jpgdec", "hclk"),
1018 PER_CLK(RCC_AHB3ENR, 4, "dma2d", "hclk"),
1019 PER_CLK(RCC_AHB3ENR, 0, "mdma", "hclk"),
1020 PER_CLK(RCC_AHB1ENR, 28, "usb2ulpi", "hclk"),
1021 PER_CLK(RCC_AHB1ENR, 26, "usb1ulpi", "hclk"),
1022 PER_CLK(RCC_AHB1ENR, 17, "eth1rx", "hclk"),
1023 PER_CLK(RCC_AHB1ENR, 16, "eth1tx", "hclk"),
1024 PER_CLK(RCC_AHB1ENR, 15, "eth1mac", "hclk"),
1025 PER_CLK(RCC_AHB1ENR, 14, "art", "hclk"),
1026 PER_CLK(RCC_AHB1ENR, 1, "dma2", "hclk"),
1027 PER_CLK(RCC_AHB1ENR, 0, "dma1", "hclk"),
1028 PER_CLK(RCC_AHB2ENR, 31, "d2sram3", "hclk"),
1029 PER_CLK(RCC_AHB2ENR, 30, "d2sram2", "hclk"),
1030 PER_CLK(RCC_AHB2ENR, 29, "d2sram1", "hclk"),
1031 PER_CLK(RCC_AHB2ENR, 5, "hash", "hclk"),
1032 PER_CLK(RCC_AHB2ENR, 4, "crypt", "hclk"),
1033 PER_CLK(RCC_AHB2ENR, 0, "camitf", "hclk"),
1034 PER_CLK(RCC_AHB4ENR, 28, "bkpram", "hclk"),
1035 PER_CLK(RCC_AHB4ENR, 25, "hsem", "hclk"),
1036 PER_CLK(RCC_AHB4ENR, 21, "bdma", "hclk"),
1037 PER_CLK(RCC_AHB4ENR, 19, "crc", "hclk"),
1038 PER_CLK(RCC_AHB4ENR, 10, "gpiok", "hclk"),
1039 PER_CLK(RCC_AHB4ENR, 9, "gpioj", "hclk"),
1040 PER_CLK(RCC_AHB4ENR, 8, "gpioi", "hclk"),
1041 PER_CLK(RCC_AHB4ENR, 7, "gpioh", "hclk"),
1042 PER_CLK(RCC_AHB4ENR, 6, "gpiog", "hclk"),
1043 PER_CLK(RCC_AHB4ENR, 5, "gpiof", "hclk"),
1044 PER_CLK(RCC_AHB4ENR, 4, "gpioe", "hclk"),
1045 PER_CLK(RCC_AHB4ENR, 3, "gpiod", "hclk"),
1046 PER_CLK(RCC_AHB4ENR, 2, "gpioc", "hclk"),
1047 PER_CLK(RCC_AHB4ENR, 1, "gpiob", "hclk"),
1048 PER_CLK(RCC_AHB4ENR, 0, "gpioa", "hclk"),
1049 PER_CLK(RCC_APB3ENR, 6, "wwdg1", "pclk3"),
1050 PER_CLK(RCC_APB1LENR, 29, "dac12", "pclk1"),
1051 PER_CLK(RCC_APB1LENR, 11, "wwdg2", "pclk1"),
1052 PER_CLK(RCC_APB1LENR, 8, "tim14", "tim1_ker"),
1053 PER_CLK(RCC_APB1LENR, 7, "tim13", "tim1_ker"),
1054 PER_CLK(RCC_APB1LENR, 6, "tim12", "tim1_ker"),
1055 PER_CLK(RCC_APB1LENR, 5, "tim7", "tim1_ker"),
1056 PER_CLK(RCC_APB1LENR, 4, "tim6", "tim1_ker"),
1057 PER_CLK(RCC_APB1LENR, 3, "tim5", "tim1_ker"),
1058 PER_CLK(RCC_APB1LENR, 2, "tim4", "tim1_ker"),
1059 PER_CLK(RCC_APB1LENR, 1, "tim3", "tim1_ker"),
1060 PER_CLK(RCC_APB1LENR, 0, "tim2", "tim1_ker"),
1061 PER_CLK(RCC_APB1HENR, 5, "mdios", "pclk1"),
1062 PER_CLK(RCC_APB1HENR, 4, "opamp", "pclk1"),
1063 PER_CLK(RCC_APB1HENR, 1, "crs", "pclk1"),
1064 PER_CLK(RCC_APB2ENR, 18, "tim17", "tim2_ker"),
1065 PER_CLK(RCC_APB2ENR, 17, "tim16", "tim2_ker"),
1066 PER_CLK(RCC_APB2ENR, 16, "tim15", "tim2_ker"),
1067 PER_CLK(RCC_APB2ENR, 1, "tim8", "tim2_ker"),
1068 PER_CLK(RCC_APB2ENR, 0, "tim1", "tim2_ker"),
1069 PER_CLK(RCC_APB4ENR, 26, "tmpsens", "pclk4"),
1070 PER_CLK(RCC_APB4ENR, 16, "rtcapb", "pclk4"),
1071 PER_CLK(RCC_APB4ENR, 15, "vref", "pclk4"),
1072 PER_CLK(RCC_APB4ENR, 14, "comp12", "pclk4"),
1073 PER_CLK(RCC_APB4ENR, 1, "syscfg", "pclk4"),
1074};
1075
1076/* KERNEL CLOCKS */
1077#define KER_CLKF(_gate_offset, _bit_idx,\
1078 _mux_offset, _mux_shift, _mux_width,\
1079 _name, _parent_name,\
1080 _flags) \
1081{ \
1082 .gate = &(struct gate_cfg) {_gate_offset, _bit_idx},\
1083 .mux = &(struct muxdiv_cfg) {_mux_offset, _mux_shift, _mux_width },\
1084 .name = _name, \
1085 .parent_name = _parent_name, \
1086 .num_parents = ARRAY_SIZE(_parent_name),\
1087 .flags = _flags,\
1088}
1089
1090#define KER_CLK(_gate_offset, _bit_idx, _mux_offset, _mux_shift, _mux_width,\
1091 _name, _parent_name) \
1092KER_CLKF(_gate_offset, _bit_idx, _mux_offset, _mux_shift, _mux_width,\
1093 _name, _parent_name, 0)\
1094
1095#define KER_CLKF_NOMUX(_gate_offset, _bit_idx,\
1096 _name, _parent_name,\
1097 _flags) \
1098{ \
1099 .gate = &(struct gate_cfg) {_gate_offset, _bit_idx},\
1100 .mux = NULL,\
1101 .name = _name, \
1102 .parent_name = _parent_name, \
1103 .num_parents = 1,\
1104 .flags = _flags,\
1105}
1106
1107static const struct composite_clk_cfg kclk[] = {
1108 KER_CLK(RCC_AHB3ENR, 16, RCC_D1CCIPR, 16, 1, "sdmmc1", sdmmc_src),
1109 KER_CLKF(RCC_AHB3ENR, 14, RCC_D1CCIPR, 4, 2, "quadspi", qspi_src,
1110 CLK_IGNORE_UNUSED),
1111 KER_CLKF(RCC_AHB3ENR, 12, RCC_D1CCIPR, 0, 2, "fmc", fmc_src,
1112 CLK_IGNORE_UNUSED),
1113 KER_CLK(RCC_AHB1ENR, 27, RCC_D2CCIP2R, 20, 2, "usb2otg", usbotg_src),
1114 KER_CLK(RCC_AHB1ENR, 25, RCC_D2CCIP2R, 20, 2, "usb1otg", usbotg_src),
1115 KER_CLK(RCC_AHB1ENR, 5, RCC_D3CCIPR, 16, 2, "adc12", adc_src),
1116 KER_CLK(RCC_AHB2ENR, 9, RCC_D1CCIPR, 16, 1, "sdmmc2", sdmmc_src),
1117 KER_CLK(RCC_AHB2ENR, 6, RCC_D2CCIP2R, 8, 2, "rng", rng_src),
1118 KER_CLK(RCC_AHB4ENR, 24, RCC_D3CCIPR, 16, 2, "adc3", adc_src),
1119 KER_CLKF(RCC_APB3ENR, 4, RCC_D1CCIPR, 8, 1, "dsi", dsi_src,
1120 CLK_SET_RATE_PARENT),
1121 KER_CLKF_NOMUX(RCC_APB3ENR, 3, "ltdc", ltdc_src, CLK_SET_RATE_PARENT),
1122 KER_CLK(RCC_APB1LENR, 31, RCC_D2CCIP2R, 0, 3, "usart8", usart_src2),
1123 KER_CLK(RCC_APB1LENR, 30, RCC_D2CCIP2R, 0, 3, "usart7", usart_src2),
1124 KER_CLK(RCC_APB1LENR, 27, RCC_D2CCIP2R, 22, 2, "hdmicec", cec_src),
1125 KER_CLK(RCC_APB1LENR, 23, RCC_D2CCIP2R, 12, 2, "i2c3", i2c_src1),
1126 KER_CLK(RCC_APB1LENR, 22, RCC_D2CCIP2R, 12, 2, "i2c2", i2c_src1),
1127 KER_CLK(RCC_APB1LENR, 21, RCC_D2CCIP2R, 12, 2, "i2c1", i2c_src1),
1128 KER_CLK(RCC_APB1LENR, 20, RCC_D2CCIP2R, 0, 3, "uart5", usart_src2),
1129 KER_CLK(RCC_APB1LENR, 19, RCC_D2CCIP2R, 0, 3, "uart4", usart_src2),
1130 KER_CLK(RCC_APB1LENR, 18, RCC_D2CCIP2R, 0, 3, "usart3", usart_src2),
1131 KER_CLK(RCC_APB1LENR, 17, RCC_D2CCIP2R, 0, 3, "usart2", usart_src2),
1132 KER_CLK(RCC_APB1LENR, 16, RCC_D2CCIP1R, 20, 2, "spdifrx", spdifrx_src),
1133 KER_CLK(RCC_APB1LENR, 15, RCC_D2CCIP1R, 16, 3, "spi3", spi_src1),
1134 KER_CLK(RCC_APB1LENR, 14, RCC_D2CCIP1R, 16, 3, "spi2", spi_src1),
1135 KER_CLK(RCC_APB1LENR, 9, RCC_D2CCIP2R, 28, 3, "lptim1", lptim_src1),
1136 KER_CLK(RCC_APB1HENR, 8, RCC_D2CCIP1R, 28, 2, "fdcan", fdcan_src),
1137 KER_CLK(RCC_APB1HENR, 2, RCC_D2CCIP1R, 31, 1, "swp", swp_src),
1138 KER_CLK(RCC_APB2ENR, 29, RCC_CFGR, 14, 1, "hrtim", hrtim_src),
1139 KER_CLK(RCC_APB2ENR, 28, RCC_D2CCIP1R, 24, 1, "dfsdm1", dfsdm1_src),
1140 KER_CLKF(RCC_APB2ENR, 24, RCC_D2CCIP1R, 6, 3, "sai3", sai_src,
1141 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
1142 KER_CLKF(RCC_APB2ENR, 23, RCC_D2CCIP1R, 6, 3, "sai2", sai_src,
1143 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
1144 KER_CLKF(RCC_APB2ENR, 22, RCC_D2CCIP1R, 0, 3, "sai1", sai_src,
1145 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
1146 KER_CLK(RCC_APB2ENR, 20, RCC_D2CCIP1R, 16, 3, "spi5", spi_src2),
1147 KER_CLK(RCC_APB2ENR, 13, RCC_D2CCIP1R, 16, 3, "spi4", spi_src2),
1148 KER_CLK(RCC_APB2ENR, 12, RCC_D2CCIP1R, 16, 3, "spi1", spi_src1),
1149 KER_CLK(RCC_APB2ENR, 5, RCC_D2CCIP2R, 3, 3, "usart6", usart_src1),
1150 KER_CLK(RCC_APB2ENR, 4, RCC_D2CCIP2R, 3, 3, "usart1", usart_src1),
1151 KER_CLK(RCC_APB4ENR, 21, RCC_D3CCIPR, 24, 3, "sai4b", sai_src),
1152 KER_CLK(RCC_APB4ENR, 21, RCC_D3CCIPR, 21, 3, "sai4a", sai_src),
1153 KER_CLK(RCC_APB4ENR, 12, RCC_D3CCIPR, 13, 3, "lptim5", lptim_src2),
1154 KER_CLK(RCC_APB4ENR, 11, RCC_D3CCIPR, 13, 3, "lptim4", lptim_src2),
1155 KER_CLK(RCC_APB4ENR, 10, RCC_D3CCIPR, 13, 3, "lptim3", lptim_src2),
1156 KER_CLK(RCC_APB4ENR, 9, RCC_D3CCIPR, 10, 3, "lptim2", lptim_src2),
1157 KER_CLK(RCC_APB4ENR, 7, RCC_D3CCIPR, 8, 2, "i2c4", i2c_src2),
1158 KER_CLK(RCC_APB4ENR, 5, RCC_D3CCIPR, 28, 3, "spi6", spi_src3),
1159 KER_CLK(RCC_APB4ENR, 3, RCC_D3CCIPR, 0, 3, "lpuart1", lpuart1_src),
1160};
1161
1162static struct composite_clk_gcfg kernel_clk_cfg = {
1163 M_CFG_MUX(NULL, 0),
1164 M_CFG_GATE(NULL, 0),
1165};
1166
1167/* RTC clock */
1168/*
1169 * RTC & LSE registers are protected against parasitic write access.
1170 * PWR_CR_DBP bit must be set to enable write access to RTC registers.
1171 */
1172/* STM32_PWR_CR */
1173#define PWR_CR 0x00
1174/* STM32_PWR_CR bit field */
1175#define PWR_CR_DBP BIT(8)
1176
1177static struct composite_clk_gcfg rtc_clk_cfg = {
1178 M_CFG_MUX(NULL, 0),
1179 M_CFG_GATE(NULL, 0),
1180};
1181
1182static const struct composite_clk_cfg rtc_clk =
1183 KER_CLK(RCC_BDCR, 15, RCC_BDCR, 8, 2, "rtc_ck", rtc_src);
1184
1185/* Micro-controller output clock */
1186static struct composite_clk_gcfg mco_clk_cfg = {
1187 M_CFG_MUX(NULL, 0),
1188 M_CFG_DIV(NULL, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
1189};
1190
1191#define M_MCO_F(_name, _parents, _mux_offset, _mux_shift, _mux_width,\
1192 _rate_offset, _rate_shift, _rate_width,\
1193 _flags)\
1194{\
1195 .mux = &(struct muxdiv_cfg) {_mux_offset, _mux_shift, _mux_width },\
1196 .div = &(struct muxdiv_cfg) {_rate_offset, _rate_shift, _rate_width},\
1197 .gate = NULL,\
1198 .name = _name,\
1199 .parent_name = _parents,\
1200 .num_parents = ARRAY_SIZE(_parents),\
1201 .flags = _flags,\
1202}
1203
1204static const struct composite_clk_cfg mco_clk[] = {
1205 M_MCO_F("mco1", mco_src1, RCC_CFGR, 22, 4, RCC_CFGR, 18, 4, 0),
1206 M_MCO_F("mco2", mco_src2, RCC_CFGR, 29, 3, RCC_CFGR, 25, 4, 0),
1207};
1208
1209static void __init stm32h7_rcc_init(struct device_node *np)
1210{
1211 struct clk_hw_onecell_data *clk_data;
1212 struct composite_cfg c_cfg;
1213 int n;
1214 const char *hse_clk, *lse_clk, *i2s_clk;
1215 struct regmap *pdrm;
1216
1217 clk_data = kzalloc(sizeof(*clk_data) +
1218 sizeof(*clk_data->hws) * STM32H7_MAX_CLKS,
1219 GFP_KERNEL);
1220 if (!clk_data)
1221 return;
1222
1223 clk_data->num = STM32H7_MAX_CLKS;
1224
1225 hws = clk_data->hws;
1226
1227 for (n = 0; n < STM32H7_MAX_CLKS; n++)
1228 hws[n] = ERR_PTR(-ENOENT);
1229
1230 /* get RCC base @ from DT */
1231 base = of_iomap(np, 0);
1232 if (!base) {
1233 pr_err("%s: unable to map resource", np->name);
1234 goto err_free_clks;
1235 }
1236
1237 pdrm = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
1238 if (IS_ERR(pdrm))
1239 pr_warn("%s: Unable to get syscfg\n", __func__);
1240 else
1241 /* In any case disable backup domain write protection
1242 * and will never be enabled.
1243 * Needed by LSE & RTC clocks.
1244 */
1245 regmap_update_bits(pdrm, PWR_CR, PWR_CR_DBP, PWR_CR_DBP);
1246
1247 /* Put parent names from DT */
1248 hse_clk = of_clk_get_parent_name(np, 0);
1249 lse_clk = of_clk_get_parent_name(np, 1);
1250 i2s_clk = of_clk_get_parent_name(np, 2);
1251
1252 sai_src[3] = i2s_clk;
1253 spi_src1[3] = i2s_clk;
1254
1255 /* Register Internal oscillators */
1256 clk_hw_register_fixed_rate(NULL, "clk-hsi", NULL, 0, 64000000);
1257 clk_hw_register_fixed_rate(NULL, "clk-csi", NULL, 0, 4000000);
1258 clk_hw_register_fixed_rate(NULL, "clk-lsi", NULL, 0, 32000);
1259 clk_hw_register_fixed_rate(NULL, "clk-rc48", NULL, 0, 48000);
1260
1261 /* This clock is coming from outside. Frequencies unknown */
1262 hws[CK_DSI_PHY] = clk_hw_register_fixed_rate(NULL, "ck_dsi_phy", NULL,
1263 0, 0);
1264
1265 hws[HSI_DIV] = clk_hw_register_divider(NULL, "hsidiv", "clk-hsi", 0,
1266 base + RCC_CR, 3, 2, CLK_DIVIDER_POWER_OF_TWO,
1267 &stm32rcc_lock);
1268
1269 hws[HSE_1M] = clk_hw_register_divider(NULL, "hse_1M", "hse_ck", 0,
1270 base + RCC_CFGR, 8, 6, CLK_DIVIDER_ONE_BASED |
1271 CLK_DIVIDER_ALLOW_ZERO,
1272 &stm32rcc_lock);
1273
1274 /* Mux system clocks */
1275 for (n = 0; n < ARRAY_SIZE(stm32_mclk); n++)
1276 hws[MCLK_BANK + n] = clk_hw_register_mux(NULL,
1277 stm32_mclk[n].name,
1278 stm32_mclk[n].parents,
1279 stm32_mclk[n].num_parents,
1280 stm32_mclk[n].flags,
1281 stm32_mclk[n].offset + base,
1282 stm32_mclk[n].shift,
1283 stm32_mclk[n].width,
1284 0,
1285 &stm32rcc_lock);
1286
1287 register_core_and_bus_clocks();
1288
1289 /* Oscillary clocks */
1290 for (n = 0; n < ARRAY_SIZE(stm32_oclk); n++)
1291 hws[OSC_BANK + n] = clk_register_ready_gate(NULL,
1292 stm32_oclk[n].name,
1293 stm32_oclk[n].parent,
1294 stm32_oclk[n].gate_offset + base,
1295 stm32_oclk[n].bit_idx,
1296 stm32_oclk[n].bit_rdy,
1297 stm32_oclk[n].flags,
1298 &stm32rcc_lock);
1299
1300 hws[HSE_CK] = clk_register_ready_gate(NULL,
1301 "hse_ck",
1302 hse_clk,
1303 RCC_CR + base,
1304 16, 17,
1305 0,
1306 &stm32rcc_lock);
1307
1308 hws[LSE_CK] = clk_register_ready_gate(NULL,
1309 "lse_ck",
1310 lse_clk,
1311 RCC_BDCR + base,
1312 0, 1,
1313 0,
1314 &stm32rcc_lock);
1315
1316 hws[CSI_KER_DIV122 + n] = clk_hw_register_fixed_factor(NULL,
1317 "csi_ker_div122", "csi_ker", 0, 1, 122);
1318
1319 /* PLLs */
1320 for (n = 0; n < ARRAY_SIZE(stm32_pll); n++) {
1321 int odf;
1322
1323 /* Register the VCO */
1324 clk_register_stm32_pll(NULL, stm32_pll[n].name,
1325 stm32_pll[n].parent_name, stm32_pll[n].flags,
1326 stm32_pll[n].cfg,
1327 &stm32rcc_lock);
1328
1329 /* Register the 3 output dividers */
1330 for (odf = 0; odf < 3; odf++) {
1331 int idx = n * 3 + odf;
1332
1333 get_cfg_composite_div(&odf_clk_gcfg, &stm32_odf[n][odf],
1334 &c_cfg, &stm32rcc_lock);
1335
1336 hws[ODF_BANK + idx] = clk_hw_register_composite(NULL,
1337 stm32_odf[n][odf].name,
1338 stm32_odf[n][odf].parent_name,
1339 stm32_odf[n][odf].num_parents,
1340 c_cfg.mux_hw, c_cfg.mux_ops,
1341 c_cfg.div_hw, c_cfg.div_ops,
1342 c_cfg.gate_hw, c_cfg.gate_ops,
1343 stm32_odf[n][odf].flags);
1344 }
1345 }
1346
1347 /* Peripheral clocks */
1348 for (n = 0; n < ARRAY_SIZE(pclk); n++)
1349 hws[PERIF_BANK + n] = clk_hw_register_gate(NULL, pclk[n].name,
1350 pclk[n].parent,
1351 pclk[n].flags, base + pclk[n].gate_offset,
1352 pclk[n].bit_idx, pclk[n].flags, &stm32rcc_lock);
1353
1354 /* Kernel clocks */
1355 for (n = 0; n < ARRAY_SIZE(kclk); n++) {
1356 get_cfg_composite_div(&kernel_clk_cfg, &kclk[n], &c_cfg,
1357 &stm32rcc_lock);
1358
1359 hws[KERN_BANK + n] = clk_hw_register_composite(NULL,
1360 kclk[n].name,
1361 kclk[n].parent_name,
1362 kclk[n].num_parents,
1363 c_cfg.mux_hw, c_cfg.mux_ops,
1364 c_cfg.div_hw, c_cfg.div_ops,
1365 c_cfg.gate_hw, c_cfg.gate_ops,
1366 kclk[n].flags);
1367 }
1368
1369 /* RTC clock (default state is off) */
1370 clk_hw_register_fixed_rate(NULL, "off", NULL, 0, 0);
1371
1372 get_cfg_composite_div(&rtc_clk_cfg, &rtc_clk, &c_cfg, &stm32rcc_lock);
1373
1374 hws[RTC_CK] = clk_hw_register_composite(NULL,
1375 rtc_clk.name,
1376 rtc_clk.parent_name,
1377 rtc_clk.num_parents,
1378 c_cfg.mux_hw, c_cfg.mux_ops,
1379 c_cfg.div_hw, c_cfg.div_ops,
1380 c_cfg.gate_hw, c_cfg.gate_ops,
1381 rtc_clk.flags);
1382
1383 /* Micro-controller clocks */
1384 for (n = 0; n < ARRAY_SIZE(mco_clk); n++) {
1385 get_cfg_composite_div(&mco_clk_cfg, &mco_clk[n], &c_cfg,
1386 &stm32rcc_lock);
1387
1388 hws[MCO_BANK + n] = clk_hw_register_composite(NULL,
1389 mco_clk[n].name,
1390 mco_clk[n].parent_name,
1391 mco_clk[n].num_parents,
1392 c_cfg.mux_hw, c_cfg.mux_ops,
1393 c_cfg.div_hw, c_cfg.div_ops,
1394 c_cfg.gate_hw, c_cfg.gate_ops,
1395 mco_clk[n].flags);
1396 }
1397
1398 of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
1399
1400 return;
1401
1402err_free_clks:
1403 kfree(clk_data);
1404}
1405
1406/* The RCC node is a clock and reset controller, and these
1407 * functionalities are supported by different drivers that
1408 * matches the same compatible strings.
1409 */
1410CLK_OF_DECLARE_DRIVER(stm32h7_rcc, "st,stm32h743-rcc", stm32h7_rcc_init);
diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
index ea7d552a2f2b..decffb3826ec 100644
--- a/drivers/clk/clk-versaclock5.c
+++ b/drivers/clk/clk-versaclock5.c
@@ -57,6 +57,7 @@
57#define VC5_PRIM_SRC_SHDN 0x10 57#define VC5_PRIM_SRC_SHDN 0x10
58#define VC5_PRIM_SRC_SHDN_EN_XTAL BIT(7) 58#define VC5_PRIM_SRC_SHDN_EN_XTAL BIT(7)
59#define VC5_PRIM_SRC_SHDN_EN_CLKIN BIT(6) 59#define VC5_PRIM_SRC_SHDN_EN_CLKIN BIT(6)
60#define VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ BIT(3)
60#define VC5_PRIM_SRC_SHDN_SP BIT(1) 61#define VC5_PRIM_SRC_SHDN_SP BIT(1)
61#define VC5_PRIM_SRC_SHDN_EN_GBL_SHDN BIT(0) 62#define VC5_PRIM_SRC_SHDN_EN_GBL_SHDN BIT(0)
62 63
@@ -122,12 +123,16 @@
122/* flags to describe chip features */ 123/* flags to describe chip features */
123/* chip has built-in oscilator */ 124/* chip has built-in oscilator */
124#define VC5_HAS_INTERNAL_XTAL BIT(0) 125#define VC5_HAS_INTERNAL_XTAL BIT(0)
126/* chip has PFD requency doubler */
127#define VC5_HAS_PFD_FREQ_DBL BIT(1)
125 128
126/* Supported IDT VC5 models. */ 129/* Supported IDT VC5 models. */
127enum vc5_model { 130enum vc5_model {
128 IDT_VC5_5P49V5923, 131 IDT_VC5_5P49V5923,
132 IDT_VC5_5P49V5925,
129 IDT_VC5_5P49V5933, 133 IDT_VC5_5P49V5933,
130 IDT_VC5_5P49V5935, 134 IDT_VC5_5P49V5935,
135 IDT_VC6_5P49V6901,
131}; 136};
132 137
133/* Structure to describe features of a particular VC5 model */ 138/* Structure to describe features of a particular VC5 model */
@@ -157,6 +162,8 @@ struct vc5_driver_data {
157 struct clk *pin_clkin; 162 struct clk *pin_clkin;
158 unsigned char clk_mux_ins; 163 unsigned char clk_mux_ins;
159 struct clk_hw clk_mux; 164 struct clk_hw clk_mux;
165 struct clk_hw clk_mul;
166 struct clk_hw clk_pfd;
160 struct vc5_hw_data clk_pll; 167 struct vc5_hw_data clk_pll;
161 struct vc5_hw_data clk_fod[VC5_MAX_FOD_NUM]; 168 struct vc5_hw_data clk_fod[VC5_MAX_FOD_NUM];
162 struct vc5_hw_data clk_out[VC5_MAX_CLK_OUT_NUM]; 169 struct vc5_hw_data clk_out[VC5_MAX_CLK_OUT_NUM];
@@ -166,6 +173,14 @@ static const char * const vc5_mux_names[] = {
166 "mux" 173 "mux"
167}; 174};
168 175
176static const char * const vc5_dbl_names[] = {
177 "dbl"
178};
179
180static const char * const vc5_pfd_names[] = {
181 "pfd"
182};
183
169static const char * const vc5_pll_names[] = { 184static const char * const vc5_pll_names[] = {
170 "pll" 185 "pll"
171}; 186};
@@ -254,11 +269,64 @@ static int vc5_mux_set_parent(struct clk_hw *hw, u8 index)
254 return regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, mask, src); 269 return regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, mask, src);
255} 270}
256 271
257static unsigned long vc5_mux_recalc_rate(struct clk_hw *hw, 272static const struct clk_ops vc5_mux_ops = {
273 .set_parent = vc5_mux_set_parent,
274 .get_parent = vc5_mux_get_parent,
275};
276
277static unsigned long vc5_dbl_recalc_rate(struct clk_hw *hw,
258 unsigned long parent_rate) 278 unsigned long parent_rate)
259{ 279{
260 struct vc5_driver_data *vc5 = 280 struct vc5_driver_data *vc5 =
261 container_of(hw, struct vc5_driver_data, clk_mux); 281 container_of(hw, struct vc5_driver_data, clk_mul);
282 unsigned int premul;
283
284 regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &premul);
285 if (premul & VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ)
286 parent_rate *= 2;
287
288 return parent_rate;
289}
290
291static long vc5_dbl_round_rate(struct clk_hw *hw, unsigned long rate,
292 unsigned long *parent_rate)
293{
294 if ((*parent_rate == rate) || ((*parent_rate * 2) == rate))
295 return rate;
296 else
297 return -EINVAL;
298}
299
300static int vc5_dbl_set_rate(struct clk_hw *hw, unsigned long rate,
301 unsigned long parent_rate)
302{
303 struct vc5_driver_data *vc5 =
304 container_of(hw, struct vc5_driver_data, clk_mul);
305 u32 mask;
306
307 if ((parent_rate * 2) == rate)
308 mask = VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ;
309 else
310 mask = 0;
311
312 regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN,
313 VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ,
314 mask);
315
316 return 0;
317}
318
319static const struct clk_ops vc5_dbl_ops = {
320 .recalc_rate = vc5_dbl_recalc_rate,
321 .round_rate = vc5_dbl_round_rate,
322 .set_rate = vc5_dbl_set_rate,
323};
324
325static unsigned long vc5_pfd_recalc_rate(struct clk_hw *hw,
326 unsigned long parent_rate)
327{
328 struct vc5_driver_data *vc5 =
329 container_of(hw, struct vc5_driver_data, clk_pfd);
262 unsigned int prediv, div; 330 unsigned int prediv, div;
263 331
264 regmap_read(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV, &prediv); 332 regmap_read(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV, &prediv);
@@ -276,7 +344,7 @@ static unsigned long vc5_mux_recalc_rate(struct clk_hw *hw,
276 return parent_rate / VC5_REF_DIVIDER_REF_DIV(div); 344 return parent_rate / VC5_REF_DIVIDER_REF_DIV(div);
277} 345}
278 346
279static long vc5_mux_round_rate(struct clk_hw *hw, unsigned long rate, 347static long vc5_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
280 unsigned long *parent_rate) 348 unsigned long *parent_rate)
281{ 349{
282 unsigned long idiv; 350 unsigned long idiv;
@@ -296,11 +364,11 @@ static long vc5_mux_round_rate(struct clk_hw *hw, unsigned long rate,
296 return *parent_rate / idiv; 364 return *parent_rate / idiv;
297} 365}
298 366
299static int vc5_mux_set_rate(struct clk_hw *hw, unsigned long rate, 367static int vc5_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
300 unsigned long parent_rate) 368 unsigned long parent_rate)
301{ 369{
302 struct vc5_driver_data *vc5 = 370 struct vc5_driver_data *vc5 =
303 container_of(hw, struct vc5_driver_data, clk_mux); 371 container_of(hw, struct vc5_driver_data, clk_pfd);
304 unsigned long idiv; 372 unsigned long idiv;
305 u8 div; 373 u8 div;
306 374
@@ -328,12 +396,10 @@ static int vc5_mux_set_rate(struct clk_hw *hw, unsigned long rate,
328 return 0; 396 return 0;
329} 397}
330 398
331static const struct clk_ops vc5_mux_ops = { 399static const struct clk_ops vc5_pfd_ops = {
332 .set_parent = vc5_mux_set_parent, 400 .recalc_rate = vc5_pfd_recalc_rate,
333 .get_parent = vc5_mux_get_parent, 401 .round_rate = vc5_pfd_round_rate,
334 .recalc_rate = vc5_mux_recalc_rate, 402 .set_rate = vc5_pfd_set_rate,
335 .round_rate = vc5_mux_round_rate,
336 .set_rate = vc5_mux_set_rate,
337}; 403};
338 404
339/* 405/*
@@ -426,6 +492,10 @@ static unsigned long vc5_fod_recalc_rate(struct clk_hw *hw,
426 div_frc = (od_frc[0] << 22) | (od_frc[1] << 14) | 492 div_frc = (od_frc[0] << 22) | (od_frc[1] << 14) |
427 (od_frc[2] << 6) | (od_frc[3] >> 2); 493 (od_frc[2] << 6) | (od_frc[3] >> 2);
428 494
495 /* Avoid division by zero if the output is not configured. */
496 if (div_int == 0 && div_frc == 0)
497 return 0;
498
429 /* The PLL divider has 12 integer bits and 30 fractional bits */ 499 /* The PLL divider has 12 integer bits and 30 fractional bits */
430 return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc); 500 return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc);
431} 501}
@@ -503,6 +573,25 @@ static int vc5_clk_out_prepare(struct clk_hw *hw)
503{ 573{
504 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw); 574 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
505 struct vc5_driver_data *vc5 = hwdata->vc5; 575 struct vc5_driver_data *vc5 = hwdata->vc5;
576 const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM |
577 VC5_OUT_DIV_CONTROL_SEL_EXT |
578 VC5_OUT_DIV_CONTROL_EN_FOD;
579 unsigned int src;
580 int ret;
581
582 /*
583 * If the input mux is disabled, enable it first and
584 * select source from matching FOD.
585 */
586 regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src);
587 if ((src & mask) == 0) {
588 src = VC5_OUT_DIV_CONTROL_RESET | VC5_OUT_DIV_CONTROL_EN_FOD;
589 ret = regmap_update_bits(vc5->regmap,
590 VC5_OUT_DIV_CONTROL(hwdata->num),
591 mask | VC5_OUT_DIV_CONTROL_RESET, src);
592 if (ret)
593 return ret;
594 }
506 595
507 /* Enable the clock buffer */ 596 /* Enable the clock buffer */
508 regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1), 597 regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
@@ -516,7 +605,7 @@ static void vc5_clk_out_unprepare(struct clk_hw *hw)
516 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw); 605 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
517 struct vc5_driver_data *vc5 = hwdata->vc5; 606 struct vc5_driver_data *vc5 = hwdata->vc5;
518 607
519 /* Enable the clock buffer */ 608 /* Disable the clock buffer */
520 regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1), 609 regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
521 VC5_CLK_OUTPUT_CFG1_EN_CLKBUF, 0); 610 VC5_CLK_OUTPUT_CFG1_EN_CLKBUF, 0);
522} 611}
@@ -537,6 +626,9 @@ static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw)
537 regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src); 626 regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src);
538 src &= mask; 627 src &= mask;
539 628
629 if (src == 0) /* Input mux set to DISABLED */
630 return 0;
631
540 if ((src & fodclkmask) == VC5_OUT_DIV_CONTROL_EN_FOD) 632 if ((src & fodclkmask) == VC5_OUT_DIV_CONTROL_EN_FOD)
541 return 0; 633 return 0;
542 634
@@ -595,7 +687,9 @@ static int vc5_map_index_to_output(const enum vc5_model model,
595 case IDT_VC5_5P49V5933: 687 case IDT_VC5_5P49V5933:
596 return (n == 0) ? 0 : 3; 688 return (n == 0) ? 0 : 3;
597 case IDT_VC5_5P49V5923: 689 case IDT_VC5_5P49V5923:
690 case IDT_VC5_5P49V5925:
598 case IDT_VC5_5P49V5935: 691 case IDT_VC5_5P49V5935:
692 case IDT_VC6_5P49V6901:
599 default: 693 default:
600 return n; 694 return n;
601 } 695 }
@@ -672,12 +766,46 @@ static int vc5_probe(struct i2c_client *client,
672 goto err_clk; 766 goto err_clk;
673 } 767 }
674 768
769 if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) {
770 /* Register frequency doubler */
771 memset(&init, 0, sizeof(init));
772 init.name = vc5_dbl_names[0];
773 init.ops = &vc5_dbl_ops;
774 init.flags = CLK_SET_RATE_PARENT;
775 init.parent_names = vc5_mux_names;
776 init.num_parents = 1;
777 vc5->clk_mul.init = &init;
778 ret = devm_clk_hw_register(&client->dev, &vc5->clk_mul);
779 if (ret) {
780 dev_err(&client->dev, "unable to register %s\n",
781 init.name);
782 goto err_clk;
783 }
784 }
785
786 /* Register PFD */
787 memset(&init, 0, sizeof(init));
788 init.name = vc5_pfd_names[0];
789 init.ops = &vc5_pfd_ops;
790 init.flags = CLK_SET_RATE_PARENT;
791 if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL)
792 init.parent_names = vc5_dbl_names;
793 else
794 init.parent_names = vc5_mux_names;
795 init.num_parents = 1;
796 vc5->clk_pfd.init = &init;
797 ret = devm_clk_hw_register(&client->dev, &vc5->clk_pfd);
798 if (ret) {
799 dev_err(&client->dev, "unable to register %s\n", init.name);
800 goto err_clk;
801 }
802
675 /* Register PLL */ 803 /* Register PLL */
676 memset(&init, 0, sizeof(init)); 804 memset(&init, 0, sizeof(init));
677 init.name = vc5_pll_names[0]; 805 init.name = vc5_pll_names[0];
678 init.ops = &vc5_pll_ops; 806 init.ops = &vc5_pll_ops;
679 init.flags = CLK_SET_RATE_PARENT; 807 init.flags = CLK_SET_RATE_PARENT;
680 init.parent_names = vc5_mux_names; 808 init.parent_names = vc5_pfd_names;
681 init.num_parents = 1; 809 init.num_parents = 1;
682 vc5->clk_pll.num = 0; 810 vc5->clk_pll.num = 0;
683 vc5->clk_pll.vc5 = vc5; 811 vc5->clk_pll.vc5 = vc5;
@@ -785,6 +913,13 @@ static const struct vc5_chip_info idt_5p49v5923_info = {
785 .flags = 0, 913 .flags = 0,
786}; 914};
787 915
916static const struct vc5_chip_info idt_5p49v5925_info = {
917 .model = IDT_VC5_5P49V5925,
918 .clk_fod_cnt = 4,
919 .clk_out_cnt = 5,
920 .flags = 0,
921};
922
788static const struct vc5_chip_info idt_5p49v5933_info = { 923static const struct vc5_chip_info idt_5p49v5933_info = {
789 .model = IDT_VC5_5P49V5933, 924 .model = IDT_VC5_5P49V5933,
790 .clk_fod_cnt = 2, 925 .clk_fod_cnt = 2,
@@ -799,18 +934,29 @@ static const struct vc5_chip_info idt_5p49v5935_info = {
799 .flags = VC5_HAS_INTERNAL_XTAL, 934 .flags = VC5_HAS_INTERNAL_XTAL,
800}; 935};
801 936
937static const struct vc5_chip_info idt_5p49v6901_info = {
938 .model = IDT_VC6_5P49V6901,
939 .clk_fod_cnt = 4,
940 .clk_out_cnt = 5,
941 .flags = VC5_HAS_PFD_FREQ_DBL,
942};
943
802static const struct i2c_device_id vc5_id[] = { 944static const struct i2c_device_id vc5_id[] = {
803 { "5p49v5923", .driver_data = IDT_VC5_5P49V5923 }, 945 { "5p49v5923", .driver_data = IDT_VC5_5P49V5923 },
946 { "5p49v5925", .driver_data = IDT_VC5_5P49V5925 },
804 { "5p49v5933", .driver_data = IDT_VC5_5P49V5933 }, 947 { "5p49v5933", .driver_data = IDT_VC5_5P49V5933 },
805 { "5p49v5935", .driver_data = IDT_VC5_5P49V5935 }, 948 { "5p49v5935", .driver_data = IDT_VC5_5P49V5935 },
949 { "5p49v6901", .driver_data = IDT_VC6_5P49V6901 },
806 { } 950 { }
807}; 951};
808MODULE_DEVICE_TABLE(i2c, vc5_id); 952MODULE_DEVICE_TABLE(i2c, vc5_id);
809 953
810static const struct of_device_id clk_vc5_of_match[] = { 954static const struct of_device_id clk_vc5_of_match[] = {
811 { .compatible = "idt,5p49v5923", .data = &idt_5p49v5923_info }, 955 { .compatible = "idt,5p49v5923", .data = &idt_5p49v5923_info },
956 { .compatible = "idt,5p49v5925", .data = &idt_5p49v5925_info },
812 { .compatible = "idt,5p49v5933", .data = &idt_5p49v5933_info }, 957 { .compatible = "idt,5p49v5933", .data = &idt_5p49v5933_info },
813 { .compatible = "idt,5p49v5935", .data = &idt_5p49v5935_info }, 958 { .compatible = "idt,5p49v5935", .data = &idt_5p49v5935_info },
959 { .compatible = "idt,5p49v6901", .data = &idt_5p49v6901_info },
814 { }, 960 { },
815}; 961};
816MODULE_DEVICE_TABLE(of, clk_vc5_of_match); 962MODULE_DEVICE_TABLE(of, clk_vc5_of_match);
diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c
index bc37030e38ba..4c75821a3933 100644
--- a/drivers/clk/clk-xgene.c
+++ b/drivers/clk/clk-xgene.c
@@ -192,7 +192,7 @@ static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_ty
192 192
193 reg = of_iomap(np, 0); 193 reg = of_iomap(np, 0);
194 if (reg == NULL) { 194 if (reg == NULL) {
195 pr_err("Unable to map CSR register for %s\n", np->full_name); 195 pr_err("Unable to map CSR register for %pOF\n", np);
196 return; 196 return;
197 } 197 }
198 of_property_read_string(np, "clock-output-names", &clk_name); 198 of_property_read_string(np, "clock-output-names", &clk_name);
@@ -409,12 +409,12 @@ static void xgene_pmdclk_init(struct device_node *np)
409 /* Parse the DTS register for resource */ 409 /* Parse the DTS register for resource */
410 rc = of_address_to_resource(np, 0, &res); 410 rc = of_address_to_resource(np, 0, &res);
411 if (rc != 0) { 411 if (rc != 0) {
412 pr_err("no DTS register for %s\n", np->full_name); 412 pr_err("no DTS register for %pOF\n", np);
413 return; 413 return;
414 } 414 }
415 csr_reg = of_iomap(np, 0); 415 csr_reg = of_iomap(np, 0);
416 if (!csr_reg) { 416 if (!csr_reg) {
417 pr_err("Unable to map resource for %s\n", np->full_name); 417 pr_err("Unable to map resource for %pOF\n", np);
418 return; 418 return;
419 } 419 }
420 of_property_read_string(np, "clock-output-names", &clk_name); 420 of_property_read_string(np, "clock-output-names", &clk_name);
@@ -703,16 +703,14 @@ static void __init xgene_devclk_init(struct device_node *np)
703 rc = of_address_to_resource(np, i, &res); 703 rc = of_address_to_resource(np, i, &res);
704 if (rc != 0) { 704 if (rc != 0) {
705 if (i == 0) { 705 if (i == 0) {
706 pr_err("no DTS register for %s\n", 706 pr_err("no DTS register for %pOF\n", np);
707 np->full_name);
708 return; 707 return;
709 } 708 }
710 break; 709 break;
711 } 710 }
712 map_res = of_iomap(np, i); 711 map_res = of_iomap(np, i);
713 if (map_res == NULL) { 712 if (map_res == NULL) {
714 pr_err("Unable to map resource %d for %s\n", 713 pr_err("Unable to map resource %d for %pOF\n", i, np);
715 i, np->full_name);
716 goto err; 714 goto err;
717 } 715 }
718 if (strcmp(res.name, "div-reg") == 0) 716 if (strcmp(res.name, "div-reg") == 0)
@@ -747,8 +745,7 @@ static void __init xgene_devclk_init(struct device_node *np)
747 pr_debug("Add %s clock\n", clk_name); 745 pr_debug("Add %s clock\n", clk_name);
748 rc = of_clk_add_provider(np, of_clk_src_simple_get, clk); 746 rc = of_clk_add_provider(np, of_clk_src_simple_get, clk);
749 if (rc != 0) 747 if (rc != 0)
750 pr_err("%s: could register provider clk %s\n", __func__, 748 pr_err("%s: could register provider clk %pOF\n", __func__, np);
751 np->full_name);
752 749
753 return; 750 return;
754 751
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index fc58c52a26b4..c8d83acda006 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -3132,7 +3132,7 @@ int of_clk_add_provider(struct device_node *np,
3132 mutex_lock(&of_clk_mutex); 3132 mutex_lock(&of_clk_mutex);
3133 list_add(&cp->link, &of_clk_providers); 3133 list_add(&cp->link, &of_clk_providers);
3134 mutex_unlock(&of_clk_mutex); 3134 mutex_unlock(&of_clk_mutex);
3135 pr_debug("Added clock from %s\n", np->full_name); 3135 pr_debug("Added clock from %pOF\n", np);
3136 3136
3137 ret = of_clk_set_defaults(np, true); 3137 ret = of_clk_set_defaults(np, true);
3138 if (ret < 0) 3138 if (ret < 0)
@@ -3167,7 +3167,7 @@ int of_clk_add_hw_provider(struct device_node *np,
3167 mutex_lock(&of_clk_mutex); 3167 mutex_lock(&of_clk_mutex);
3168 list_add(&cp->link, &of_clk_providers); 3168 list_add(&cp->link, &of_clk_providers);
3169 mutex_unlock(&of_clk_mutex); 3169 mutex_unlock(&of_clk_mutex);
3170 pr_debug("Added clk_hw provider from %s\n", np->full_name); 3170 pr_debug("Added clk_hw provider from %pOF\n", np);
3171 3171
3172 ret = of_clk_set_defaults(np, true); 3172 ret = of_clk_set_defaults(np, true);
3173 if (ret < 0) 3173 if (ret < 0)
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index bb8a77a5985f..6b2f29df3f70 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -77,8 +77,8 @@ static struct clk *__of_clk_get_by_name(struct device_node *np,
77 break; 77 break;
78 } else if (name && index >= 0) { 78 } else if (name && index >= 0) {
79 if (PTR_ERR(clk) != -EPROBE_DEFER) 79 if (PTR_ERR(clk) != -EPROBE_DEFER)
80 pr_err("ERROR: could not get clock %s:%s(%i)\n", 80 pr_err("ERROR: could not get clock %pOF:%s(%i)\n",
81 np->full_name, name ? name : "", index); 81 np, name ? name : "", index);
82 return clk; 82 return clk;
83 } 83 }
84 84
diff --git a/drivers/clk/hisilicon/clk-hi6220.c b/drivers/clk/hisilicon/clk-hi6220.c
index 4181b6808545..e786d717f75d 100644
--- a/drivers/clk/hisilicon/clk-hi6220.c
+++ b/drivers/clk/hisilicon/clk-hi6220.c
@@ -55,9 +55,9 @@ static struct hisi_fixed_factor_clock hi6220_fixed_factor_clks[] __initdata = {
55}; 55};
56 56
57static struct hisi_gate_clock hi6220_separated_gate_clks_ao[] __initdata = { 57static struct hisi_gate_clock hi6220_separated_gate_clks_ao[] __initdata = {
58 { HI6220_WDT0_PCLK, "wdt0_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 12, 0, }, 58 { HI6220_WDT0_PCLK, "wdt0_pclk", "ref32k", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 12, 0, },
59 { HI6220_WDT1_PCLK, "wdt1_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 13, 0, }, 59 { HI6220_WDT1_PCLK, "wdt1_pclk", "ref32k", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 13, 0, },
60 { HI6220_WDT2_PCLK, "wdt2_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 14, 0, }, 60 { HI6220_WDT2_PCLK, "wdt2_pclk", "ref32k", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 14, 0, },
61 { HI6220_TIMER0_PCLK, "timer0_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 15, 0, }, 61 { HI6220_TIMER0_PCLK, "timer0_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 15, 0, },
62 { HI6220_TIMER1_PCLK, "timer1_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 16, 0, }, 62 { HI6220_TIMER1_PCLK, "timer1_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 16, 0, },
63 { HI6220_TIMER2_PCLK, "timer2_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 17, 0, }, 63 { HI6220_TIMER2_PCLK, "timer2_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 17, 0, },
diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c
index 1e3c9ea5f9dc..7bcaf270db11 100644
--- a/drivers/clk/imx/clk-imx51-imx53.c
+++ b/drivers/clk/imx/clk-imx51-imx53.c
@@ -416,10 +416,10 @@ static void __init mx51_clocks_init(struct device_node *np)
416 416
417 clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1, 417 clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1,
418 lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); 418 lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
419 clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, 419 clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux_flags("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
420 mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel)); 420 mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel), CLK_SET_RATE_PARENT);
421 clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, 421 clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux_flags("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
422 mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel)); 422 mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel), CLK_SET_RATE_PARENT);
423 clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, 423 clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
424 mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT); 424 mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT);
425 clk[IMX5_CLK_TVE_SEL] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, 425 clk[IMX5_CLK_TVE_SEL] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1,
diff --git a/drivers/clk/imx/clk-imx6sl.c b/drivers/clk/imx/clk-imx6sl.c
index 5fd4ddac1bf1..9642cdf0fb88 100644
--- a/drivers/clk/imx/clk-imx6sl.c
+++ b/drivers/clk/imx/clk-imx6sl.c
@@ -71,7 +71,7 @@ static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
71static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; 71static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
72static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; 72static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
73 73
74static struct clk_div_table clk_enet_ref_table[] = { 74static const struct clk_div_table clk_enet_ref_table[] = {
75 { .val = 0, .div = 20, }, 75 { .val = 0, .div = 20, },
76 { .val = 1, .div = 10, }, 76 { .val = 1, .div = 10, },
77 { .val = 2, .div = 5, }, 77 { .val = 2, .div = 5, },
@@ -79,14 +79,14 @@ static struct clk_div_table clk_enet_ref_table[] = {
79 { } 79 { }
80}; 80};
81 81
82static struct clk_div_table post_div_table[] = { 82static const struct clk_div_table post_div_table[] = {
83 { .val = 2, .div = 1, }, 83 { .val = 2, .div = 1, },
84 { .val = 1, .div = 2, }, 84 { .val = 1, .div = 2, },
85 { .val = 0, .div = 4, }, 85 { .val = 0, .div = 4, },
86 { } 86 { }
87}; 87};
88 88
89static struct clk_div_table video_div_table[] = { 89static const struct clk_div_table video_div_table[] = {
90 { .val = 0, .div = 1, }, 90 { .val = 0, .div = 1, },
91 { .val = 1, .div = 2, }, 91 { .val = 1, .div = 2, },
92 { .val = 2, .div = 1, }, 92 { .val = 2, .div = 1, },
diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c
index b5c96de41ccf..e6d389e333d7 100644
--- a/drivers/clk/imx/clk-imx6sx.c
+++ b/drivers/clk/imx/clk-imx6sx.c
@@ -105,7 +105,7 @@ static int const clks_init_on[] __initconst = {
105 IMX6SX_CLK_EPIT2, 105 IMX6SX_CLK_EPIT2,
106}; 106};
107 107
108static struct clk_div_table clk_enet_ref_table[] = { 108static const struct clk_div_table clk_enet_ref_table[] = {
109 { .val = 0, .div = 20, }, 109 { .val = 0, .div = 20, },
110 { .val = 1, .div = 10, }, 110 { .val = 1, .div = 10, },
111 { .val = 2, .div = 5, }, 111 { .val = 2, .div = 5, },
@@ -113,14 +113,14 @@ static struct clk_div_table clk_enet_ref_table[] = {
113 { } 113 { }
114}; 114};
115 115
116static struct clk_div_table post_div_table[] = { 116static const struct clk_div_table post_div_table[] = {
117 { .val = 2, .div = 1, }, 117 { .val = 2, .div = 1, },
118 { .val = 1, .div = 2, }, 118 { .val = 1, .div = 2, },
119 { .val = 0, .div = 4, }, 119 { .val = 0, .div = 4, },
120 { } 120 { }
121}; 121};
122 122
123static struct clk_div_table video_div_table[] = { 123static const struct clk_div_table video_div_table[] = {
124 { .val = 0, .div = 1, }, 124 { .val = 0, .div = 1, },
125 { .val = 1, .div = 2, }, 125 { .val = 1, .div = 2, },
126 { .val = 2, .div = 1, }, 126 { .val = 2, .div = 1, },
diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index b4e0dff3c8c2..5e8c18afce9a 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -78,7 +78,7 @@ static int const clks_init_on[] __initconst = {
78 IMX6UL_CLK_MMDC_P0_FAST, IMX6UL_CLK_MMDC_P0_IPG, 78 IMX6UL_CLK_MMDC_P0_FAST, IMX6UL_CLK_MMDC_P0_IPG,
79}; 79};
80 80
81static struct clk_div_table clk_enet_ref_table[] = { 81static const struct clk_div_table clk_enet_ref_table[] = {
82 { .val = 0, .div = 20, }, 82 { .val = 0, .div = 20, },
83 { .val = 1, .div = 10, }, 83 { .val = 1, .div = 10, },
84 { .val = 2, .div = 5, }, 84 { .val = 2, .div = 5, },
@@ -86,14 +86,14 @@ static struct clk_div_table clk_enet_ref_table[] = {
86 { } 86 { }
87}; 87};
88 88
89static struct clk_div_table post_div_table[] = { 89static const struct clk_div_table post_div_table[] = {
90 { .val = 2, .div = 1, }, 90 { .val = 2, .div = 1, },
91 { .val = 1, .div = 2, }, 91 { .val = 1, .div = 2, },
92 { .val = 0, .div = 4, }, 92 { .val = 0, .div = 4, },
93 { } 93 { }
94}; 94};
95 95
96static struct clk_div_table video_div_table[] = { 96static const struct clk_div_table video_div_table[] = {
97 { .val = 0, .div = 1, }, 97 { .val = 0, .div = 1, },
98 { .val = 1, .div = 2, }, 98 { .val = 1, .div = 2, },
99 { .val = 2, .div = 1, }, 99 { .val = 2, .div = 1, },
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
index 3da121826b1b..2305699db467 100644
--- a/drivers/clk/imx/clk-imx7d.c
+++ b/drivers/clk/imx/clk-imx7d.c
@@ -27,7 +27,7 @@ static u32 share_count_sai2;
27static u32 share_count_sai3; 27static u32 share_count_sai3;
28static u32 share_count_nand; 28static u32 share_count_nand;
29 29
30static struct clk_div_table test_div_table[] = { 30static const struct clk_div_table test_div_table[] = {
31 { .val = 3, .div = 1, }, 31 { .val = 3, .div = 1, },
32 { .val = 2, .div = 1, }, 32 { .val = 2, .div = 1, },
33 { .val = 1, .div = 2, }, 33 { .val = 1, .div = 2, },
@@ -35,7 +35,7 @@ static struct clk_div_table test_div_table[] = {
35 { } 35 { }
36}; 36};
37 37
38static struct clk_div_table post_div_table[] = { 38static const struct clk_div_table post_div_table[] = {
39 { .val = 3, .div = 4, }, 39 { .val = 3, .div = 4, },
40 { .val = 2, .div = 1, }, 40 { .val = 2, .div = 1, },
41 { .val = 1, .div = 2, }, 41 { .val = 1, .div = 2, },
diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
index 59b1863deb88..6dae54325a91 100644
--- a/drivers/clk/imx/clk-vf610.c
+++ b/drivers/clk/imx/clk-vf610.c
@@ -102,7 +102,7 @@ static const char *ftm_ext_sels[] = {"sirc_128k", "sxosc", "fxosc_half", "audio_
102static const char *ftm_fix_sels[] = { "sxosc", "ipg_bus", }; 102static const char *ftm_fix_sels[] = { "sxosc", "ipg_bus", };
103 103
104 104
105static struct clk_div_table pll4_audio_div_table[] = { 105static const struct clk_div_table pll4_audio_div_table[] = {
106 { .val = 0, .div = 1 }, 106 { .val = 0, .div = 1 },
107 { .val = 1, .div = 2 }, 107 { .val = 1, .div = 2 },
108 { .val = 2, .div = 6 }, 108 { .val = 2, .div = 6 },
diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
index edd8e6918050..16e56772d280 100644
--- a/drivers/clk/mediatek/clk-cpumux.c
+++ b/drivers/clk/mediatek/clk-cpumux.c
@@ -27,7 +27,6 @@ static inline struct mtk_clk_cpumux *to_mtk_clk_cpumux(struct clk_hw *_hw)
27static u8 clk_cpumux_get_parent(struct clk_hw *hw) 27static u8 clk_cpumux_get_parent(struct clk_hw *hw)
28{ 28{
29 struct mtk_clk_cpumux *mux = to_mtk_clk_cpumux(hw); 29 struct mtk_clk_cpumux *mux = to_mtk_clk_cpumux(hw);
30 int num_parents = clk_hw_get_num_parents(hw);
31 unsigned int val; 30 unsigned int val;
32 31
33 regmap_read(mux->regmap, mux->reg, &val); 32 regmap_read(mux->regmap, mux->reg, &val);
@@ -35,9 +34,6 @@ static u8 clk_cpumux_get_parent(struct clk_hw *hw)
35 val >>= mux->shift; 34 val >>= mux->shift;
36 val &= mux->mask; 35 val &= mux->mask;
37 36
38 if (val >= num_parents)
39 return -EINVAL;
40
41 return val; 37 return val;
42} 38}
43 39
@@ -98,7 +94,7 @@ int __init mtk_clk_register_cpumuxes(struct device_node *node,
98 94
99 regmap = syscon_node_to_regmap(node); 95 regmap = syscon_node_to_regmap(node);
100 if (IS_ERR(regmap)) { 96 if (IS_ERR(regmap)) {
101 pr_err("Cannot find regmap for %s: %ld\n", node->full_name, 97 pr_err("Cannot find regmap for %pOF: %ld\n", node,
102 PTR_ERR(regmap)); 98 PTR_ERR(regmap));
103 return PTR_ERR(regmap); 99 return PTR_ERR(regmap);
104 } 100 }
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 0541df78141c..9c0ae4278a94 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -114,7 +114,7 @@ int mtk_clk_register_gates(struct device_node *node,
114 114
115 regmap = syscon_node_to_regmap(node); 115 regmap = syscon_node_to_regmap(node);
116 if (IS_ERR(regmap)) { 116 if (IS_ERR(regmap)) {
117 pr_err("Cannot find regmap for %s: %ld\n", node->full_name, 117 pr_err("Cannot find regmap for %pOF: %ld\n", node,
118 PTR_ERR(regmap)); 118 PTR_ERR(regmap));
119 return PTR_ERR(regmap); 119 return PTR_ERR(regmap);
120 } 120 }
diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c
index 309049d41f1b..d3551d5efef2 100644
--- a/drivers/clk/mediatek/reset.c
+++ b/drivers/clk/mediatek/reset.c
@@ -72,7 +72,7 @@ void mtk_register_reset_controller(struct device_node *np,
72 72
73 regmap = syscon_node_to_regmap(np); 73 regmap = syscon_node_to_regmap(np);
74 if (IS_ERR(regmap)) { 74 if (IS_ERR(regmap)) {
75 pr_err("Cannot find regmap for %s: %ld\n", np->full_name, 75 pr_err("Cannot find regmap for %pOF: %ld\n", np,
76 PTR_ERR(regmap)); 76 PTR_ERR(regmap));
77 return; 77 return;
78 } 78 }
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 5588f75a8414..d2d0174a6eca 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -6,6 +6,7 @@ config COMMON_CLK_AMLOGIC
6config COMMON_CLK_MESON8B 6config COMMON_CLK_MESON8B
7 bool 7 bool
8 depends on COMMON_CLK_AMLOGIC 8 depends on COMMON_CLK_AMLOGIC
9 select RESET_CONTROLLER
9 help 10 help
10 Support for the clock controller on AmLogic S802 (Meson8), 11 Support for the clock controller on AmLogic S802 (Meson8),
11 S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you 12 S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 83b6d9d65aa1..b139d41b25da 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -4,4 +4,4 @@
4 4
5obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o clk-audio-divider.o 5obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o clk-audio-divider.o
6obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o 6obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o
7obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o 7obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-regmap.o gxbb-aoclk-32k.o
diff --git a/drivers/clk/meson/gxbb-aoclk-32k.c b/drivers/clk/meson/gxbb-aoclk-32k.c
new file mode 100644
index 000000000000..491634dbc985
--- /dev/null
+++ b/drivers/clk/meson/gxbb-aoclk-32k.c
@@ -0,0 +1,194 @@
1/*
2 * Copyright (c) 2017 BayLibre, SAS.
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8#include <linux/clk-provider.h>
9#include <linux/bitfield.h>
10#include <linux/regmap.h>
11#include "gxbb-aoclk.h"
12
13/*
14 * The AO Domain embeds a dual/divider to generate a more precise
15 * 32,768KHz clock for low-power suspend mode and CEC.
16 * ______ ______
17 * | | | |
18 * ______ | Div1 |-| Cnt1 | ______
19 * | | /|______| |______|\ | |
20 * Xtal-->| Gate |---| ______ ______ X-X--| Gate |-->
21 * |______| | \| | | |/ | |______|
22 * | | Div2 |-| Cnt2 | |
23 * | |______| |______| |
24 * |_______________________|
25 *
26 * The dividing can be switched to single or dual, with a counter
27 * for each divider to set when the switching is done.
28 * The entire dividing mechanism can be also bypassed.
29 */
30
31#define CLK_CNTL0_N1_MASK GENMASK(11, 0)
32#define CLK_CNTL0_N2_MASK GENMASK(23, 12)
33#define CLK_CNTL0_DUALDIV_EN BIT(28)
34#define CLK_CNTL0_OUT_GATE_EN BIT(30)
35#define CLK_CNTL0_IN_GATE_EN BIT(31)
36
37#define CLK_CNTL1_M1_MASK GENMASK(11, 0)
38#define CLK_CNTL1_M2_MASK GENMASK(23, 12)
39#define CLK_CNTL1_BYPASS_EN BIT(24)
40#define CLK_CNTL1_SELECT_OSC BIT(27)
41
42#define PWR_CNTL_ALT_32K_SEL GENMASK(13, 10)
43
44struct cec_32k_freq_table {
45 unsigned long parent_rate;
46 unsigned long target_rate;
47 bool dualdiv;
48 unsigned int n1;
49 unsigned int n2;
50 unsigned int m1;
51 unsigned int m2;
52};
53
54static const struct cec_32k_freq_table aoclk_cec_32k_table[] = {
55 [0] = {
56 .parent_rate = 24000000,
57 .target_rate = 32768,
58 .dualdiv = true,
59 .n1 = 733,
60 .n2 = 732,
61 .m1 = 8,
62 .m2 = 11,
63 },
64};
65
66/*
67 * If CLK_CNTL0_DUALDIV_EN == 0
68 * - will use N1 divider only
69 * If CLK_CNTL0_DUALDIV_EN == 1
70 * - hold M1 cycles of N1 divider then changes to N2
71 * - hold M2 cycles of N2 divider then changes to N1
72 * Then we can get more accurate division.
73 */
74static unsigned long aoclk_cec_32k_recalc_rate(struct clk_hw *hw,
75 unsigned long parent_rate)
76{
77 struct aoclk_cec_32k *cec_32k = to_aoclk_cec_32k(hw);
78 unsigned long n1;
79 u32 reg0, reg1;
80
81 regmap_read(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0, &reg0);
82 regmap_read(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL1, &reg1);
83
84 if (reg1 & CLK_CNTL1_BYPASS_EN)
85 return parent_rate;
86
87 if (reg0 & CLK_CNTL0_DUALDIV_EN) {
88 unsigned long n2, m1, m2, f1, f2, p1, p2;
89
90 n1 = FIELD_GET(CLK_CNTL0_N1_MASK, reg0) + 1;
91 n2 = FIELD_GET(CLK_CNTL0_N2_MASK, reg0) + 1;
92
93 m1 = FIELD_GET(CLK_CNTL1_M1_MASK, reg1) + 1;
94 m2 = FIELD_GET(CLK_CNTL1_M2_MASK, reg1) + 1;
95
96 f1 = DIV_ROUND_CLOSEST(parent_rate, n1);
97 f2 = DIV_ROUND_CLOSEST(parent_rate, n2);
98
99 p1 = DIV_ROUND_CLOSEST(100000000 * m1, f1 * (m1 + m2));
100 p2 = DIV_ROUND_CLOSEST(100000000 * m2, f2 * (m1 + m2));
101
102 return DIV_ROUND_UP(100000000, p1 + p2);
103 }
104
105 n1 = FIELD_GET(CLK_CNTL0_N1_MASK, reg0) + 1;
106
107 return DIV_ROUND_CLOSEST(parent_rate, n1);
108}
109
110static const struct cec_32k_freq_table *find_cec_32k_freq(unsigned long rate,
111 unsigned long prate)
112{
113 int i;
114
115 for (i = 0 ; i < ARRAY_SIZE(aoclk_cec_32k_table) ; ++i)
116 if (aoclk_cec_32k_table[i].parent_rate == prate &&
117 aoclk_cec_32k_table[i].target_rate == rate)
118 return &aoclk_cec_32k_table[i];
119
120 return NULL;
121}
122
123static long aoclk_cec_32k_round_rate(struct clk_hw *hw, unsigned long rate,
124 unsigned long *prate)
125{
126 const struct cec_32k_freq_table *freq = find_cec_32k_freq(rate,
127 *prate);
128
129 /* If invalid return first one */
130 if (!freq)
131 return aoclk_cec_32k_table[0].target_rate;
132
133 return freq->target_rate;
134}
135
136/*
137 * From the Amlogic init procedure, the IN and OUT gates needs to be handled
138 * in the init procedure to avoid any glitches.
139 */
140
141static int aoclk_cec_32k_set_rate(struct clk_hw *hw, unsigned long rate,
142 unsigned long parent_rate)
143{
144 const struct cec_32k_freq_table *freq = find_cec_32k_freq(rate,
145 parent_rate);
146 struct aoclk_cec_32k *cec_32k = to_aoclk_cec_32k(hw);
147 u32 reg = 0;
148
149 if (!freq)
150 return -EINVAL;
151
152 /* Disable clock */
153 regmap_update_bits(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0,
154 CLK_CNTL0_IN_GATE_EN | CLK_CNTL0_OUT_GATE_EN, 0);
155
156 reg = FIELD_PREP(CLK_CNTL0_N1_MASK, freq->n1 - 1);
157 if (freq->dualdiv)
158 reg |= CLK_CNTL0_DUALDIV_EN |
159 FIELD_PREP(CLK_CNTL0_N2_MASK, freq->n2 - 1);
160
161 regmap_write(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0, reg);
162
163 reg = FIELD_PREP(CLK_CNTL1_M1_MASK, freq->m1 - 1);
164 if (freq->dualdiv)
165 reg |= FIELD_PREP(CLK_CNTL1_M2_MASK, freq->m2 - 1);
166
167 regmap_write(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL1, reg);
168
169 /* Enable clock */
170 regmap_update_bits(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0,
171 CLK_CNTL0_IN_GATE_EN, CLK_CNTL0_IN_GATE_EN);
172
173 udelay(200);
174
175 regmap_update_bits(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0,
176 CLK_CNTL0_OUT_GATE_EN, CLK_CNTL0_OUT_GATE_EN);
177
178 regmap_update_bits(cec_32k->regmap, AO_CRT_CLK_CNTL1,
179 CLK_CNTL1_SELECT_OSC, CLK_CNTL1_SELECT_OSC);
180
181 /* Select 32k from XTAL */
182 regmap_update_bits(cec_32k->regmap,
183 AO_RTI_PWR_CNTL_REG0,
184 PWR_CNTL_ALT_32K_SEL,
185 FIELD_PREP(PWR_CNTL_ALT_32K_SEL, 4));
186
187 return 0;
188}
189
190const struct clk_ops meson_aoclk_cec_32k_ops = {
191 .recalc_rate = aoclk_cec_32k_recalc_rate,
192 .round_rate = aoclk_cec_32k_round_rate,
193 .set_rate = aoclk_cec_32k_set_rate,
194};
diff --git a/drivers/clk/meson/gxbb-aoclk-regmap.c b/drivers/clk/meson/gxbb-aoclk-regmap.c
new file mode 100644
index 000000000000..2515fbfa0467
--- /dev/null
+++ b/drivers/clk/meson/gxbb-aoclk-regmap.c
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) 2017 BayLibre, SAS.
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8#include <linux/clk-provider.h>
9#include <linux/bitfield.h>
10#include <linux/regmap.h>
11#include "gxbb-aoclk.h"
12
13static int aoclk_gate_regmap_enable(struct clk_hw *hw)
14{
15 struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw);
16
17 return regmap_update_bits(gate->regmap, AO_RTI_GEN_CNTL_REG0,
18 BIT(gate->bit_idx), BIT(gate->bit_idx));
19}
20
21static void aoclk_gate_regmap_disable(struct clk_hw *hw)
22{
23 struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw);
24
25 regmap_update_bits(gate->regmap, AO_RTI_GEN_CNTL_REG0,
26 BIT(gate->bit_idx), 0);
27}
28
29static int aoclk_gate_regmap_is_enabled(struct clk_hw *hw)
30{
31 struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw);
32 unsigned int val;
33 int ret;
34
35 ret = regmap_read(gate->regmap, AO_RTI_GEN_CNTL_REG0, &val);
36 if (ret)
37 return ret;
38
39 return (val & BIT(gate->bit_idx)) != 0;
40}
41
42const struct clk_ops meson_aoclk_gate_regmap_ops = {
43 .enable = aoclk_gate_regmap_enable,
44 .disable = aoclk_gate_regmap_disable,
45 .is_enabled = aoclk_gate_regmap_is_enabled,
46};
diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c
index b45c5fba7e35..6c161e0a8e59 100644
--- a/drivers/clk/meson/gxbb-aoclk.c
+++ b/drivers/clk/meson/gxbb-aoclk.c
@@ -56,16 +56,20 @@
56#include <linux/of_address.h> 56#include <linux/of_address.h>
57#include <linux/platform_device.h> 57#include <linux/platform_device.h>
58#include <linux/reset-controller.h> 58#include <linux/reset-controller.h>
59#include <linux/mfd/syscon.h>
60#include <linux/regmap.h>
59#include <linux/init.h> 61#include <linux/init.h>
62#include <linux/delay.h>
60#include <dt-bindings/clock/gxbb-aoclkc.h> 63#include <dt-bindings/clock/gxbb-aoclkc.h>
61#include <dt-bindings/reset/gxbb-aoclkc.h> 64#include <dt-bindings/reset/gxbb-aoclkc.h>
65#include "gxbb-aoclk.h"
62 66
63static DEFINE_SPINLOCK(gxbb_aoclk_lock); 67static DEFINE_SPINLOCK(gxbb_aoclk_lock);
64 68
65struct gxbb_aoclk_reset_controller { 69struct gxbb_aoclk_reset_controller {
66 struct reset_controller_dev reset; 70 struct reset_controller_dev reset;
67 unsigned int *data; 71 unsigned int *data;
68 void __iomem *base; 72 struct regmap *regmap;
69}; 73};
70 74
71static int gxbb_aoclk_do_reset(struct reset_controller_dev *rcdev, 75static int gxbb_aoclk_do_reset(struct reset_controller_dev *rcdev,
@@ -74,9 +78,8 @@ static int gxbb_aoclk_do_reset(struct reset_controller_dev *rcdev,
74 struct gxbb_aoclk_reset_controller *reset = 78 struct gxbb_aoclk_reset_controller *reset =
75 container_of(rcdev, struct gxbb_aoclk_reset_controller, reset); 79 container_of(rcdev, struct gxbb_aoclk_reset_controller, reset);
76 80
77 writel(BIT(reset->data[id]), reset->base); 81 return regmap_write(reset->regmap, AO_RTI_GEN_CNTL_REG0,
78 82 BIT(reset->data[id]));
79 return 0;
80} 83}
81 84
82static const struct reset_control_ops gxbb_aoclk_reset_ops = { 85static const struct reset_control_ops gxbb_aoclk_reset_ops = {
@@ -84,13 +87,12 @@ static const struct reset_control_ops gxbb_aoclk_reset_ops = {
84}; 87};
85 88
86#define GXBB_AO_GATE(_name, _bit) \ 89#define GXBB_AO_GATE(_name, _bit) \
87static struct clk_gate _name##_ao = { \ 90static struct aoclk_gate_regmap _name##_ao = { \
88 .reg = (void __iomem *)0, \
89 .bit_idx = (_bit), \ 91 .bit_idx = (_bit), \
90 .lock = &gxbb_aoclk_lock, \ 92 .lock = &gxbb_aoclk_lock, \
91 .hw.init = &(struct clk_init_data) { \ 93 .hw.init = &(struct clk_init_data) { \
92 .name = #_name "_ao", \ 94 .name = #_name "_ao", \
93 .ops = &clk_gate_ops, \ 95 .ops = &meson_aoclk_gate_regmap_ops, \
94 .parent_names = (const char *[]){ "clk81" }, \ 96 .parent_names = (const char *[]){ "clk81" }, \
95 .num_parents = 1, \ 97 .num_parents = 1, \
96 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ 98 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
@@ -104,6 +106,17 @@ GXBB_AO_GATE(uart1, 3);
104GXBB_AO_GATE(uart2, 5); 106GXBB_AO_GATE(uart2, 5);
105GXBB_AO_GATE(ir_blaster, 6); 107GXBB_AO_GATE(ir_blaster, 6);
106 108
109static struct aoclk_cec_32k cec_32k_ao = {
110 .lock = &gxbb_aoclk_lock,
111 .hw.init = &(struct clk_init_data) {
112 .name = "cec_32k_ao",
113 .ops = &meson_aoclk_cec_32k_ops,
114 .parent_names = (const char *[]){ "xtal" },
115 .num_parents = 1,
116 .flags = CLK_IGNORE_UNUSED,
117 },
118};
119
107static unsigned int gxbb_aoclk_reset[] = { 120static unsigned int gxbb_aoclk_reset[] = {
108 [RESET_AO_REMOTE] = 16, 121 [RESET_AO_REMOTE] = 16,
109 [RESET_AO_I2C_MASTER] = 18, 122 [RESET_AO_I2C_MASTER] = 18,
@@ -113,7 +126,7 @@ static unsigned int gxbb_aoclk_reset[] = {
113 [RESET_AO_IR_BLASTER] = 23, 126 [RESET_AO_IR_BLASTER] = 23,
114}; 127};
115 128
116static struct clk_gate *gxbb_aoclk_gate[] = { 129static struct aoclk_gate_regmap *gxbb_aoclk_gate[] = {
117 [CLKID_AO_REMOTE] = &remote_ao, 130 [CLKID_AO_REMOTE] = &remote_ao,
118 [CLKID_AO_I2C_MASTER] = &i2c_master_ao, 131 [CLKID_AO_I2C_MASTER] = &i2c_master_ao,
119 [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao, 132 [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao,
@@ -130,30 +143,30 @@ static struct clk_hw_onecell_data gxbb_aoclk_onecell_data = {
130 [CLKID_AO_UART1] = &uart1_ao.hw, 143 [CLKID_AO_UART1] = &uart1_ao.hw,
131 [CLKID_AO_UART2] = &uart2_ao.hw, 144 [CLKID_AO_UART2] = &uart2_ao.hw,
132 [CLKID_AO_IR_BLASTER] = &ir_blaster_ao.hw, 145 [CLKID_AO_IR_BLASTER] = &ir_blaster_ao.hw,
146 [CLKID_AO_CEC_32K] = &cec_32k_ao.hw,
133 }, 147 },
134 .num = ARRAY_SIZE(gxbb_aoclk_gate), 148 .num = 7,
135}; 149};
136 150
137static int gxbb_aoclkc_probe(struct platform_device *pdev) 151static int gxbb_aoclkc_probe(struct platform_device *pdev)
138{ 152{
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; 153 struct gxbb_aoclk_reset_controller *rstc;
154 struct device *dev = &pdev->dev;
155 struct regmap *regmap;
156 int ret, clkid;
144 157
145 rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL); 158 rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL);
146 if (!rstc) 159 if (!rstc)
147 return -ENOMEM; 160 return -ENOMEM;
148 161
149 /* Generic clocks */ 162 regmap = syscon_node_to_regmap(of_get_parent(dev->of_node));
150 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 163 if (IS_ERR(regmap)) {
151 base = devm_ioremap_resource(dev, res); 164 dev_err(dev, "failed to get regmap\n");
152 if (IS_ERR(base)) 165 return -ENODEV;
153 return PTR_ERR(base); 166 }
154 167
155 /* Reset Controller */ 168 /* Reset Controller */
156 rstc->base = base; 169 rstc->regmap = regmap;
157 rstc->data = gxbb_aoclk_reset; 170 rstc->data = gxbb_aoclk_reset;
158 rstc->reset.ops = &gxbb_aoclk_reset_ops; 171 rstc->reset.ops = &gxbb_aoclk_reset_ops;
159 rstc->reset.nr_resets = ARRAY_SIZE(gxbb_aoclk_reset); 172 rstc->reset.nr_resets = ARRAY_SIZE(gxbb_aoclk_reset);
@@ -161,10 +174,10 @@ static int gxbb_aoclkc_probe(struct platform_device *pdev)
161 ret = devm_reset_controller_register(dev, &rstc->reset); 174 ret = devm_reset_controller_register(dev, &rstc->reset);
162 175
163 /* 176 /*
164 * Populate base address and register all clks 177 * Populate regmap and register all clks
165 */ 178 */
166 for (clkid = 0; clkid < gxbb_aoclk_onecell_data.num; clkid++) { 179 for (clkid = 0; clkid < ARRAY_SIZE(gxbb_aoclk_gate); clkid++) {
167 gxbb_aoclk_gate[clkid]->reg = base; 180 gxbb_aoclk_gate[clkid]->regmap = regmap;
168 181
169 ret = devm_clk_hw_register(dev, 182 ret = devm_clk_hw_register(dev,
170 gxbb_aoclk_onecell_data.hws[clkid]); 183 gxbb_aoclk_onecell_data.hws[clkid]);
@@ -172,12 +185,18 @@ static int gxbb_aoclkc_probe(struct platform_device *pdev)
172 return ret; 185 return ret;
173 } 186 }
174 187
188 /* Specific clocks */
189 cec_32k_ao.regmap = regmap;
190 ret = devm_clk_hw_register(dev, &cec_32k_ao.hw);
191 if (ret)
192 return ret;
193
175 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, 194 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
176 &gxbb_aoclk_onecell_data); 195 &gxbb_aoclk_onecell_data);
177} 196}
178 197
179static const struct of_device_id gxbb_aoclkc_match_table[] = { 198static const struct of_device_id gxbb_aoclkc_match_table[] = {
180 { .compatible = "amlogic,gxbb-aoclkc" }, 199 { .compatible = "amlogic,meson-gx-aoclkc" },
181 { } 200 { }
182}; 201};
183 202
diff --git a/drivers/clk/meson/gxbb-aoclk.h b/drivers/clk/meson/gxbb-aoclk.h
new file mode 100644
index 000000000000..e8604c8f7eee
--- /dev/null
+++ b/drivers/clk/meson/gxbb-aoclk.h
@@ -0,0 +1,42 @@
1/*
2 * Copyright (c) 2017 BayLibre, SAS
3 * Author: Neil Armstrong <narmstrong@baylibre.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8#ifndef __GXBB_AOCLKC_H
9#define __GXBB_AOCLKC_H
10
11/* AO Configuration Clock registers offsets */
12#define AO_RTI_PWR_CNTL_REG1 0x0c
13#define AO_RTI_PWR_CNTL_REG0 0x10
14#define AO_RTI_GEN_CNTL_REG0 0x40
15#define AO_OSCIN_CNTL 0x58
16#define AO_CRT_CLK_CNTL1 0x68
17#define AO_RTC_ALT_CLK_CNTL0 0x94
18#define AO_RTC_ALT_CLK_CNTL1 0x98
19
20struct aoclk_gate_regmap {
21 struct clk_hw hw;
22 unsigned bit_idx;
23 struct regmap *regmap;
24 spinlock_t *lock;
25};
26
27#define to_aoclk_gate_regmap(_hw) \
28 container_of(_hw, struct aoclk_gate_regmap, hw)
29
30extern const struct clk_ops meson_aoclk_gate_regmap_ops;
31
32struct aoclk_cec_32k {
33 struct clk_hw hw;
34 struct regmap *regmap;
35 spinlock_t *lock;
36};
37
38#define to_aoclk_cec_32k(_hw) container_of(_hw, struct aoclk_cec_32k, hw)
39
40extern const struct clk_ops meson_aoclk_cec_32k_ops;
41
42#endif /* __GXBB_AOCLKC_H */
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 964489b39f6a..b2d1e8ed7152 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -850,13 +850,14 @@ static struct meson_clk_audio_divider gxbb_cts_amclk_div = {
850 .shift = 0, 850 .shift = 0,
851 .width = 8, 851 .width = 8,
852 }, 852 },
853 .flags = CLK_DIVIDER_ROUND_CLOSEST,
853 .lock = &clk_lock, 854 .lock = &clk_lock,
854 .hw.init = &(struct clk_init_data){ 855 .hw.init = &(struct clk_init_data){
855 .name = "cts_amclk_div", 856 .name = "cts_amclk_div",
856 .ops = &meson_clk_audio_divider_ops, 857 .ops = &meson_clk_audio_divider_ops,
857 .parent_names = (const char *[]){ "cts_amclk_sel" }, 858 .parent_names = (const char *[]){ "cts_amclk_sel" },
858 .num_parents = 1, 859 .num_parents = 1,
859 .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST, 860 .flags = CLK_SET_RATE_PARENT,
860 }, 861 },
861}; 862};
862 863
@@ -880,7 +881,7 @@ static struct clk_mux gxbb_cts_mclk_i958_sel = {
880 /* Default parent unknown (register reset value: 0) */ 881 /* Default parent unknown (register reset value: 0) */
881 .table = (u32[]){ 1, 2, 3 }, 882 .table = (u32[]){ 1, 2, 3 },
882 .lock = &clk_lock, 883 .lock = &clk_lock,
883 .hw.init = &(struct clk_init_data){ 884 .hw.init = &(struct clk_init_data) {
884 .name = "cts_mclk_i958_sel", 885 .name = "cts_mclk_i958_sel",
885 .ops = &clk_mux_ops, 886 .ops = &clk_mux_ops,
886 .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, 887 .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" },
@@ -894,12 +895,13 @@ static struct clk_divider gxbb_cts_mclk_i958_div = {
894 .shift = 16, 895 .shift = 16,
895 .width = 8, 896 .width = 8,
896 .lock = &clk_lock, 897 .lock = &clk_lock,
897 .hw.init = &(struct clk_init_data){ 898 .flags = CLK_DIVIDER_ROUND_CLOSEST,
899 .hw.init = &(struct clk_init_data) {
898 .name = "cts_mclk_i958_div", 900 .name = "cts_mclk_i958_div",
899 .ops = &clk_divider_ops, 901 .ops = &clk_divider_ops,
900 .parent_names = (const char *[]){ "cts_mclk_i958_sel" }, 902 .parent_names = (const char *[]){ "cts_mclk_i958_sel" },
901 .num_parents = 1, 903 .num_parents = 1,
902 .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST, 904 .flags = CLK_SET_RATE_PARENT,
903 }, 905 },
904}; 906};
905 907
@@ -979,6 +981,156 @@ static struct clk_mux gxbb_32k_clk_sel = {
979 }, 981 },
980}; 982};
981 983
984static const char * const gxbb_sd_emmc_clk0_parent_names[] = {
985 "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
986
987 /*
988 * Following these parent clocks, we should also have had mpll2, mpll3
989 * and gp0_pll but these clocks are too precious to be used here. All
990 * the necessary rates for MMC and NAND operation can be acheived using
991 * xtal or fclk_div clocks
992 */
993};
994
995/* SDIO clock */
996static struct clk_mux gxbb_sd_emmc_a_clk0_sel = {
997 .reg = (void *)HHI_SD_EMMC_CLK_CNTL,
998 .mask = 0x7,
999 .shift = 9,
1000 .lock = &clk_lock,
1001 .hw.init = &(struct clk_init_data) {
1002 .name = "sd_emmc_a_clk0_sel",
1003 .ops = &clk_mux_ops,
1004 .parent_names = gxbb_sd_emmc_clk0_parent_names,
1005 .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
1006 .flags = CLK_SET_RATE_PARENT,
1007 },
1008};
1009
1010static struct clk_divider gxbb_sd_emmc_a_clk0_div = {
1011 .reg = (void *)HHI_SD_EMMC_CLK_CNTL,
1012 .shift = 0,
1013 .width = 7,
1014 .lock = &clk_lock,
1015 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1016 .hw.init = &(struct clk_init_data) {
1017 .name = "sd_emmc_a_clk0_div",
1018 .ops = &clk_divider_ops,
1019 .parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" },
1020 .num_parents = 1,
1021 .flags = CLK_SET_RATE_PARENT,
1022 },
1023};
1024
1025static struct clk_gate gxbb_sd_emmc_a_clk0 = {
1026 .reg = (void *)HHI_SD_EMMC_CLK_CNTL,
1027 .bit_idx = 7,
1028 .lock = &clk_lock,
1029 .hw.init = &(struct clk_init_data){
1030 .name = "sd_emmc_a_clk0",
1031 .ops = &clk_gate_ops,
1032 .parent_names = (const char *[]){ "sd_emmc_a_clk0_div" },
1033 .num_parents = 1,
1034
1035 /*
1036 * FIXME:
1037 * We need CLK_IGNORE_UNUSED because mmc DT node point to xtal
1038 * instead of this clock. CCF would gate this on boot, killing
1039 * the mmc controller. Please remove this flag once DT properly
1040 * point to this clock instead of xtal
1041 *
1042 * Same goes for emmc B and C clocks
1043 */
1044 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1045 },
1046};
1047
1048/* SDcard clock */
1049static struct clk_mux gxbb_sd_emmc_b_clk0_sel = {
1050 .reg = (void *)HHI_SD_EMMC_CLK_CNTL,
1051 .mask = 0x7,
1052 .shift = 25,
1053 .lock = &clk_lock,
1054 .hw.init = &(struct clk_init_data) {
1055 .name = "sd_emmc_b_clk0_sel",
1056 .ops = &clk_mux_ops,
1057 .parent_names = gxbb_sd_emmc_clk0_parent_names,
1058 .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
1059 .flags = CLK_SET_RATE_PARENT,
1060 },
1061};
1062
1063static struct clk_divider gxbb_sd_emmc_b_clk0_div = {
1064 .reg = (void *)HHI_SD_EMMC_CLK_CNTL,
1065 .shift = 16,
1066 .width = 7,
1067 .lock = &clk_lock,
1068 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1069 .hw.init = &(struct clk_init_data) {
1070 .name = "sd_emmc_b_clk0_div",
1071 .ops = &clk_divider_ops,
1072 .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
1073 .num_parents = 1,
1074 .flags = CLK_SET_RATE_PARENT,
1075 },
1076};
1077
1078static struct clk_gate gxbb_sd_emmc_b_clk0 = {
1079 .reg = (void *)HHI_SD_EMMC_CLK_CNTL,
1080 .bit_idx = 23,
1081 .lock = &clk_lock,
1082 .hw.init = &(struct clk_init_data){
1083 .name = "sd_emmc_b_clk0",
1084 .ops = &clk_gate_ops,
1085 .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
1086 .num_parents = 1,
1087 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1088 },
1089};
1090
1091/* EMMC/NAND clock */
1092static struct clk_mux gxbb_sd_emmc_c_clk0_sel = {
1093 .reg = (void *)HHI_NAND_CLK_CNTL,
1094 .mask = 0x7,
1095 .shift = 9,
1096 .lock = &clk_lock,
1097 .hw.init = &(struct clk_init_data) {
1098 .name = "sd_emmc_c_clk0_sel",
1099 .ops = &clk_mux_ops,
1100 .parent_names = gxbb_sd_emmc_clk0_parent_names,
1101 .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
1102 .flags = CLK_SET_RATE_PARENT,
1103 },
1104};
1105
1106static struct clk_divider gxbb_sd_emmc_c_clk0_div = {
1107 .reg = (void *)HHI_NAND_CLK_CNTL,
1108 .shift = 0,
1109 .width = 7,
1110 .lock = &clk_lock,
1111 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1112 .hw.init = &(struct clk_init_data) {
1113 .name = "sd_emmc_c_clk0_div",
1114 .ops = &clk_divider_ops,
1115 .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
1116 .num_parents = 1,
1117 .flags = CLK_SET_RATE_PARENT,
1118 },
1119};
1120
1121static struct clk_gate gxbb_sd_emmc_c_clk0 = {
1122 .reg = (void *)HHI_NAND_CLK_CNTL,
1123 .bit_idx = 7,
1124 .lock = &clk_lock,
1125 .hw.init = &(struct clk_init_data){
1126 .name = "sd_emmc_c_clk0",
1127 .ops = &clk_gate_ops,
1128 .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
1129 .num_parents = 1,
1130 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1131 },
1132};
1133
982/* Everything Else (EE) domain gates */ 1134/* Everything Else (EE) domain gates */
983static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0); 1135static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0);
984static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1); 1136static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1);
@@ -1188,6 +1340,15 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
1188 [CLKID_32K_CLK] = &gxbb_32k_clk.hw, 1340 [CLKID_32K_CLK] = &gxbb_32k_clk.hw,
1189 [CLKID_32K_CLK_SEL] = &gxbb_32k_clk_sel.hw, 1341 [CLKID_32K_CLK_SEL] = &gxbb_32k_clk_sel.hw,
1190 [CLKID_32K_CLK_DIV] = &gxbb_32k_clk_div.hw, 1342 [CLKID_32K_CLK_DIV] = &gxbb_32k_clk_div.hw,
1343 [CLKID_SD_EMMC_A_CLK0_SEL] = &gxbb_sd_emmc_a_clk0_sel.hw,
1344 [CLKID_SD_EMMC_A_CLK0_DIV] = &gxbb_sd_emmc_a_clk0_div.hw,
1345 [CLKID_SD_EMMC_A_CLK0] = &gxbb_sd_emmc_a_clk0.hw,
1346 [CLKID_SD_EMMC_B_CLK0_SEL] = &gxbb_sd_emmc_b_clk0_sel.hw,
1347 [CLKID_SD_EMMC_B_CLK0_DIV] = &gxbb_sd_emmc_b_clk0_div.hw,
1348 [CLKID_SD_EMMC_B_CLK0] = &gxbb_sd_emmc_b_clk0.hw,
1349 [CLKID_SD_EMMC_C_CLK0_SEL] = &gxbb_sd_emmc_c_clk0_sel.hw,
1350 [CLKID_SD_EMMC_C_CLK0_DIV] = &gxbb_sd_emmc_c_clk0_div.hw,
1351 [CLKID_SD_EMMC_C_CLK0] = &gxbb_sd_emmc_c_clk0.hw,
1191 [NR_CLKS] = NULL, 1352 [NR_CLKS] = NULL,
1192 }, 1353 },
1193 .num = NR_CLKS, 1354 .num = NR_CLKS,
@@ -1311,6 +1472,15 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
1311 [CLKID_32K_CLK] = &gxbb_32k_clk.hw, 1472 [CLKID_32K_CLK] = &gxbb_32k_clk.hw,
1312 [CLKID_32K_CLK_SEL] = &gxbb_32k_clk_sel.hw, 1473 [CLKID_32K_CLK_SEL] = &gxbb_32k_clk_sel.hw,
1313 [CLKID_32K_CLK_DIV] = &gxbb_32k_clk_div.hw, 1474 [CLKID_32K_CLK_DIV] = &gxbb_32k_clk_div.hw,
1475 [CLKID_SD_EMMC_A_CLK0_SEL] = &gxbb_sd_emmc_a_clk0_sel.hw,
1476 [CLKID_SD_EMMC_A_CLK0_DIV] = &gxbb_sd_emmc_a_clk0_div.hw,
1477 [CLKID_SD_EMMC_A_CLK0] = &gxbb_sd_emmc_a_clk0.hw,
1478 [CLKID_SD_EMMC_B_CLK0_SEL] = &gxbb_sd_emmc_b_clk0_sel.hw,
1479 [CLKID_SD_EMMC_B_CLK0_DIV] = &gxbb_sd_emmc_b_clk0_div.hw,
1480 [CLKID_SD_EMMC_B_CLK0] = &gxbb_sd_emmc_b_clk0.hw,
1481 [CLKID_SD_EMMC_C_CLK0_SEL] = &gxbb_sd_emmc_c_clk0_sel.hw,
1482 [CLKID_SD_EMMC_C_CLK0_DIV] = &gxbb_sd_emmc_c_clk0_div.hw,
1483 [CLKID_SD_EMMC_C_CLK0] = &gxbb_sd_emmc_c_clk0.hw,
1314 [NR_CLKS] = NULL, 1484 [NR_CLKS] = NULL,
1315 }, 1485 },
1316 .num = NR_CLKS, 1486 .num = NR_CLKS,
@@ -1427,6 +1597,9 @@ static struct clk_gate *const gxbb_clk_gates[] = {
1427 &gxbb_cts_amclk, 1597 &gxbb_cts_amclk,
1428 &gxbb_cts_mclk_i958, 1598 &gxbb_cts_mclk_i958,
1429 &gxbb_32k_clk, 1599 &gxbb_32k_clk,
1600 &gxbb_sd_emmc_a_clk0,
1601 &gxbb_sd_emmc_b_clk0,
1602 &gxbb_sd_emmc_c_clk0,
1430}; 1603};
1431 1604
1432static struct clk_mux *const gxbb_clk_muxes[] = { 1605static struct clk_mux *const gxbb_clk_muxes[] = {
@@ -1439,6 +1612,9 @@ static struct clk_mux *const gxbb_clk_muxes[] = {
1439 &gxbb_cts_mclk_i958_sel, 1612 &gxbb_cts_mclk_i958_sel,
1440 &gxbb_cts_i958, 1613 &gxbb_cts_i958,
1441 &gxbb_32k_clk_sel, 1614 &gxbb_32k_clk_sel,
1615 &gxbb_sd_emmc_a_clk0_sel,
1616 &gxbb_sd_emmc_b_clk0_sel,
1617 &gxbb_sd_emmc_c_clk0_sel,
1442}; 1618};
1443 1619
1444static struct clk_divider *const gxbb_clk_dividers[] = { 1620static struct clk_divider *const gxbb_clk_dividers[] = {
@@ -1448,6 +1624,9 @@ static struct clk_divider *const gxbb_clk_dividers[] = {
1448 &gxbb_mali_1_div, 1624 &gxbb_mali_1_div,
1449 &gxbb_cts_mclk_i958_div, 1625 &gxbb_cts_mclk_i958_div,
1450 &gxbb_32k_clk_div, 1626 &gxbb_32k_clk_div,
1627 &gxbb_sd_emmc_a_clk0_div,
1628 &gxbb_sd_emmc_b_clk0_div,
1629 &gxbb_sd_emmc_c_clk0_div,
1451}; 1630};
1452 1631
1453static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = { 1632static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = {
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index cb60a516ca82..20ab7190d328 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -25,6 +25,8 @@
25#include <linux/clk-provider.h> 25#include <linux/clk-provider.h>
26#include <linux/of_address.h> 26#include <linux/of_address.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/reset-controller.h>
29#include <linux/slab.h>
28#include <linux/init.h> 30#include <linux/init.h>
29 31
30#include "clkc.h" 32#include "clkc.h"
@@ -32,6 +34,13 @@
32 34
33static DEFINE_SPINLOCK(clk_lock); 35static DEFINE_SPINLOCK(clk_lock);
34 36
37static void __iomem *clk_base;
38
39struct meson8b_clk_reset {
40 struct reset_controller_dev reset;
41 void __iomem *base;
42};
43
35static const struct pll_rate_table sys_pll_rate_table[] = { 44static const struct pll_rate_table sys_pll_rate_table[] = {
36 PLL_RATE(312000000, 52, 1, 2), 45 PLL_RATE(312000000, 52, 1, 2),
37 PLL_RATE(336000000, 56, 1, 2), 46 PLL_RATE(336000000, 56, 1, 2),
@@ -696,20 +705,114 @@ static struct clk_divider *const meson8b_clk_dividers[] = {
696 &meson8b_mpeg_clk_div, 705 &meson8b_mpeg_clk_div,
697}; 706};
698 707
708static const struct meson8b_clk_reset_line {
709 u32 reg;
710 u8 bit_idx;
711} meson8b_clk_reset_bits[] = {
712 [CLKC_RESET_L2_CACHE_SOFT_RESET] = {
713 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 30
714 },
715 [CLKC_RESET_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET] = {
716 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 29
717 },
718 [CLKC_RESET_SCU_SOFT_RESET] = {
719 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 28
720 },
721 [CLKC_RESET_CPU3_SOFT_RESET] = {
722 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 27
723 },
724 [CLKC_RESET_CPU2_SOFT_RESET] = {
725 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 26
726 },
727 [CLKC_RESET_CPU1_SOFT_RESET] = {
728 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 25
729 },
730 [CLKC_RESET_CPU0_SOFT_RESET] = {
731 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 24
732 },
733 [CLKC_RESET_A5_GLOBAL_RESET] = {
734 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 18
735 },
736 [CLKC_RESET_A5_AXI_SOFT_RESET] = {
737 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 17
738 },
739 [CLKC_RESET_A5_ABP_SOFT_RESET] = {
740 .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 16
741 },
742 [CLKC_RESET_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET] = {
743 .reg = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 30
744 },
745 [CLKC_RESET_VID_CLK_CNTL_SOFT_RESET] = {
746 .reg = HHI_VID_CLK_CNTL, .bit_idx = 15
747 },
748 [CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST] = {
749 .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 7
750 },
751 [CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE] = {
752 .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 3
753 },
754 [CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST] = {
755 .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 1
756 },
757 [CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE] = {
758 .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 0
759 },
760};
761
762static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev,
763 unsigned long id, bool assert)
764{
765 struct meson8b_clk_reset *meson8b_clk_reset =
766 container_of(rcdev, struct meson8b_clk_reset, reset);
767 unsigned long flags;
768 const struct meson8b_clk_reset_line *reset;
769 u32 val;
770
771 if (id >= ARRAY_SIZE(meson8b_clk_reset_bits))
772 return -EINVAL;
773
774 reset = &meson8b_clk_reset_bits[id];
775
776 spin_lock_irqsave(&clk_lock, flags);
777
778 val = readl(meson8b_clk_reset->base + reset->reg);
779 if (assert)
780 val |= BIT(reset->bit_idx);
781 else
782 val &= ~BIT(reset->bit_idx);
783 writel(val, meson8b_clk_reset->base + reset->reg);
784
785 spin_unlock_irqrestore(&clk_lock, flags);
786
787 return 0;
788}
789
790static int meson8b_clk_reset_assert(struct reset_controller_dev *rcdev,
791 unsigned long id)
792{
793 return meson8b_clk_reset_update(rcdev, id, true);
794}
795
796static int meson8b_clk_reset_deassert(struct reset_controller_dev *rcdev,
797 unsigned long id)
798{
799 return meson8b_clk_reset_update(rcdev, id, false);
800}
801
802static const struct reset_control_ops meson8b_clk_reset_ops = {
803 .assert = meson8b_clk_reset_assert,
804 .deassert = meson8b_clk_reset_deassert,
805};
806
699static int meson8b_clkc_probe(struct platform_device *pdev) 807static int meson8b_clkc_probe(struct platform_device *pdev)
700{ 808{
701 void __iomem *clk_base;
702 int ret, clkid, i; 809 int ret, clkid, i;
703 struct clk_hw *parent_hw; 810 struct clk_hw *parent_hw;
704 struct clk *parent_clk; 811 struct clk *parent_clk;
705 struct device *dev = &pdev->dev; 812 struct device *dev = &pdev->dev;
706 813
707 /* Generic clocks and PLLs */ 814 if (!clk_base)
708 clk_base = of_iomap(dev->of_node, 1);
709 if (!clk_base) {
710 pr_err("%s: Unable to map clk base\n", __func__);
711 return -ENXIO; 815 return -ENXIO;
712 }
713 816
714 /* Populate base address for PLLs */ 817 /* Populate base address for PLLs */
715 for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++) 818 for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
@@ -749,7 +852,7 @@ static int meson8b_clkc_probe(struct platform_device *pdev)
749 /* FIXME convert to devm_clk_register */ 852 /* FIXME convert to devm_clk_register */
750 ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[clkid]); 853 ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[clkid]);
751 if (ret) 854 if (ret)
752 goto iounmap; 855 return ret;
753 } 856 }
754 857
755 /* 858 /*
@@ -772,15 +875,11 @@ static int meson8b_clkc_probe(struct platform_device *pdev)
772 if (ret) { 875 if (ret) {
773 pr_err("%s: failed to register clock notifier for cpu_clk\n", 876 pr_err("%s: failed to register clock notifier for cpu_clk\n",
774 __func__); 877 __func__);
775 goto iounmap; 878 return ret;
776 } 879 }
777 880
778 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, 881 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
779 &meson8b_hw_onecell_data); 882 &meson8b_hw_onecell_data);
780
781iounmap:
782 iounmap(clk_base);
783 return ret;
784} 883}
785 884
786static const struct of_device_id meson8b_clkc_match_table[] = { 885static const struct of_device_id meson8b_clkc_match_table[] = {
@@ -799,3 +898,39 @@ static struct platform_driver meson8b_driver = {
799}; 898};
800 899
801builtin_platform_driver(meson8b_driver); 900builtin_platform_driver(meson8b_driver);
901
902static void __init meson8b_clkc_reset_init(struct device_node *np)
903{
904 struct meson8b_clk_reset *rstc;
905 int ret;
906
907 /* Generic clocks, PLLs and some of the reset-bits */
908 clk_base = of_iomap(np, 1);
909 if (!clk_base) {
910 pr_err("%s: Unable to map clk base\n", __func__);
911 return;
912 }
913
914 rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
915 if (!rstc)
916 return;
917
918 /* Reset Controller */
919 rstc->base = clk_base;
920 rstc->reset.ops = &meson8b_clk_reset_ops;
921 rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits);
922 rstc->reset.of_node = np;
923 ret = reset_controller_register(&rstc->reset);
924 if (ret) {
925 pr_err("%s: Failed to register clkc reset controller: %d\n",
926 __func__, ret);
927 return;
928 }
929}
930
931CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc",
932 meson8b_clkc_reset_init);
933CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc",
934 meson8b_clkc_reset_init);
935CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc",
936 meson8b_clkc_reset_init);
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
index c139bb3273ca..2eaf8a52e7dd 100644
--- a/drivers/clk/meson/meson8b.h
+++ b/drivers/clk/meson/meson8b.h
@@ -37,6 +37,9 @@
37#define HHI_GCLK_AO 0x154 /* 0x55 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 */ 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 */ 39#define HHI_MPEG_CLK_CNTL 0x174 /* 0x5d offset in data sheet */
40#define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */
41#define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */
42#define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */
40#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */ 43#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */
41#define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */ 44#define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */
42#define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */ 45#define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
@@ -68,7 +71,11 @@
68 71
69#define CLK_NR_CLKS 96 72#define CLK_NR_CLKS 96
70 73
71/* include the CLKIDs that have been made part of the stable DT binding */ 74/*
75 * include the CLKID and RESETID that have
76 * been made part of the stable DT binding
77 */
72#include <dt-bindings/clock/meson8b-clkc.h> 78#include <dt-bindings/clock/meson8b-clkc.h>
79#include <dt-bindings/reset/amlogic,meson8b-clkc-reset.h>
73 80
74#endif /* __MESON8B_H */ 81#endif /* __MESON8B_H */
diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c
index 61893fe73251..089927e4cda2 100644
--- a/drivers/clk/mmp/clk.c
+++ b/drivers/clk/mmp/clk.c
@@ -9,7 +9,7 @@
9void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit, 9void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
10 int nr_clks) 10 int nr_clks)
11{ 11{
12 static struct clk **clk_table; 12 struct clk **clk_table;
13 13
14 clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); 14 clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
15 if (!clk_table) 15 if (!clk_table)
diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c
index 5b98ff9076f3..7b359afd620e 100644
--- a/drivers/clk/nxp/clk-lpc32xx.c
+++ b/drivers/clk/nxp/clk-lpc32xx.c
@@ -885,7 +885,7 @@ static const struct clk_ops clk_usb_i2c_ops = {
885 .recalc_rate = clk_usb_i2c_recalc_rate, 885 .recalc_rate = clk_usb_i2c_recalc_rate,
886}; 886};
887 887
888static int clk_gate_enable(struct clk_hw *hw) 888static int lpc32xx_clk_gate_enable(struct clk_hw *hw)
889{ 889{
890 struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw); 890 struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw);
891 u32 mask = BIT(clk->bit_idx); 891 u32 mask = BIT(clk->bit_idx);
@@ -894,7 +894,7 @@ static int clk_gate_enable(struct clk_hw *hw)
894 return regmap_update_bits(clk_regmap, clk->reg, mask, val); 894 return regmap_update_bits(clk_regmap, clk->reg, mask, val);
895} 895}
896 896
897static void clk_gate_disable(struct clk_hw *hw) 897static void lpc32xx_clk_gate_disable(struct clk_hw *hw)
898{ 898{
899 struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw); 899 struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw);
900 u32 mask = BIT(clk->bit_idx); 900 u32 mask = BIT(clk->bit_idx);
@@ -903,7 +903,7 @@ static void clk_gate_disable(struct clk_hw *hw)
903 regmap_update_bits(clk_regmap, clk->reg, mask, val); 903 regmap_update_bits(clk_regmap, clk->reg, mask, val);
904} 904}
905 905
906static int clk_gate_is_enabled(struct clk_hw *hw) 906static int lpc32xx_clk_gate_is_enabled(struct clk_hw *hw)
907{ 907{
908 struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw); 908 struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw);
909 u32 val; 909 u32 val;
@@ -916,9 +916,9 @@ static int clk_gate_is_enabled(struct clk_hw *hw)
916} 916}
917 917
918static const struct clk_ops lpc32xx_clk_gate_ops = { 918static const struct clk_ops lpc32xx_clk_gate_ops = {
919 .enable = clk_gate_enable, 919 .enable = lpc32xx_clk_gate_enable,
920 .disable = clk_gate_disable, 920 .disable = lpc32xx_clk_gate_disable,
921 .is_enabled = clk_gate_is_enabled, 921 .is_enabled = lpc32xx_clk_gate_is_enabled,
922}; 922};
923 923
924#define div_mask(width) ((1 << (width)) - 1) 924#define div_mask(width) ((1 << (width)) - 1)
diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c
index d990fe44aef3..cc03d5508627 100644
--- a/drivers/clk/qcom/clk-smd-rpm.c
+++ b/drivers/clk/qcom/clk-smd-rpm.c
@@ -412,8 +412,6 @@ static const struct clk_ops clk_smd_rpm_ops = {
412static const struct clk_ops clk_smd_rpm_branch_ops = { 412static const struct clk_ops clk_smd_rpm_branch_ops = {
413 .prepare = clk_smd_rpm_prepare, 413 .prepare = clk_smd_rpm_prepare,
414 .unprepare = clk_smd_rpm_unprepare, 414 .unprepare = clk_smd_rpm_unprepare,
415 .round_rate = clk_smd_rpm_round_rate,
416 .recalc_rate = clk_smd_rpm_recalc_rate,
417}; 415};
418 416
419/* msm8916 */ 417/* msm8916 */
diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c
index 2cfe7000fc60..3410ee68d4bc 100644
--- a/drivers/clk/qcom/gcc-msm8916.c
+++ b/drivers/clk/qcom/gcc-msm8916.c
@@ -1176,7 +1176,7 @@ static struct clk_rcg2 bimc_gpu_clk_src = {
1176 .parent_names = gcc_xo_gpll0_bimc, 1176 .parent_names = gcc_xo_gpll0_bimc,
1177 .num_parents = 3, 1177 .num_parents = 3,
1178 .flags = CLK_GET_RATE_NOCACHE, 1178 .flags = CLK_GET_RATE_NOCACHE,
1179 .ops = &clk_rcg2_shared_ops, 1179 .ops = &clk_rcg2_ops,
1180 }, 1180 },
1181}; 1181};
1182 1182
diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
index 8abc200d4fd3..7ddec886fcd3 100644
--- a/drivers/clk/qcom/gcc-msm8996.c
+++ b/drivers/clk/qcom/gcc-msm8996.c
@@ -2730,6 +2730,32 @@ static struct clk_fixed_factor ufs_rx_cfg_clk_src = {
2730 }, 2730 },
2731}; 2731};
2732 2732
2733static struct clk_branch gcc_hlos1_vote_lpass_core_smmu_clk = {
2734 .halt_reg = 0x7d010,
2735 .halt_check = BRANCH_HALT_VOTED,
2736 .clkr = {
2737 .enable_reg = 0x7d010,
2738 .enable_mask = BIT(0),
2739 .hw.init = &(struct clk_init_data){
2740 .name = "hlos1_vote_lpass_core_smmu_clk",
2741 .ops = &clk_branch2_ops,
2742 },
2743 },
2744};
2745
2746static struct clk_branch gcc_hlos1_vote_lpass_adsp_smmu_clk = {
2747 .halt_reg = 0x7d014,
2748 .halt_check = BRANCH_HALT_VOTED,
2749 .clkr = {
2750 .enable_reg = 0x7d014,
2751 .enable_mask = BIT(0),
2752 .hw.init = &(struct clk_init_data){
2753 .name = "hlos1_vote_lpass_adsp_smmu_clk",
2754 .ops = &clk_branch2_ops,
2755 },
2756 },
2757};
2758
2733static struct clk_branch gcc_ufs_rx_cfg_clk = { 2759static struct clk_branch gcc_ufs_rx_cfg_clk = {
2734 .halt_reg = 0x75014, 2760 .halt_reg = 0x75014,
2735 .clkr = { 2761 .clkr = {
@@ -3307,6 +3333,8 @@ static struct clk_regmap *gcc_msm8996_clocks[] = {
3307 [GCC_UFS_AHB_CLK] = &gcc_ufs_ahb_clk.clkr, 3333 [GCC_UFS_AHB_CLK] = &gcc_ufs_ahb_clk.clkr,
3308 [GCC_UFS_TX_CFG_CLK] = &gcc_ufs_tx_cfg_clk.clkr, 3334 [GCC_UFS_TX_CFG_CLK] = &gcc_ufs_tx_cfg_clk.clkr,
3309 [GCC_UFS_RX_CFG_CLK] = &gcc_ufs_rx_cfg_clk.clkr, 3335 [GCC_UFS_RX_CFG_CLK] = &gcc_ufs_rx_cfg_clk.clkr,
3336 [GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK] = &gcc_hlos1_vote_lpass_core_smmu_clk.clkr,
3337 [GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK] = &gcc_hlos1_vote_lpass_adsp_smmu_clk.clkr,
3310 [GCC_UFS_TX_SYMBOL_0_CLK] = &gcc_ufs_tx_symbol_0_clk.clkr, 3338 [GCC_UFS_TX_SYMBOL_0_CLK] = &gcc_ufs_tx_symbol_0_clk.clkr,
3311 [GCC_UFS_RX_SYMBOL_0_CLK] = &gcc_ufs_rx_symbol_0_clk.clkr, 3339 [GCC_UFS_RX_SYMBOL_0_CLK] = &gcc_ufs_rx_symbol_0_clk.clkr,
3312 [GCC_UFS_RX_SYMBOL_1_CLK] = &gcc_ufs_rx_symbol_1_clk.clkr, 3340 [GCC_UFS_RX_SYMBOL_1_CLK] = &gcc_ufs_rx_symbol_1_clk.clkr,
diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index 78d1df9112ba..acbb38151ba1 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -15,6 +15,7 @@ config CLK_RENESAS
15 select CLK_R8A7794 if ARCH_R8A7794 15 select CLK_R8A7794 if ARCH_R8A7794
16 select CLK_R8A7795 if ARCH_R8A7795 16 select CLK_R8A7795 if ARCH_R8A7795
17 select CLK_R8A7796 if ARCH_R8A7796 17 select CLK_R8A7796 if ARCH_R8A7796
18 select CLK_R8A77995 if ARCH_R8A77995
18 select CLK_SH73A0 if ARCH_SH73A0 19 select CLK_SH73A0 if ARCH_SH73A0
19 20
20if CLK_RENESAS 21if CLK_RENESAS
@@ -34,94 +35,103 @@ config CLK_EMEV2
34 bool "Emma Mobile EV2 clock support" if COMPILE_TEST 35 bool "Emma Mobile EV2 clock support" if COMPILE_TEST
35 36
36config CLK_RZA1 37config CLK_RZA1
37 bool 38 bool "RZ/A1H clock support" if COMPILE_TEST
38 select CLK_RENESAS_CPG_MSTP 39 select CLK_RENESAS_CPG_MSTP
39 40
40config CLK_R8A73A4 41config CLK_R8A73A4
41 bool 42 bool "R-Mobile APE6 clock support" if COMPILE_TEST
42 select CLK_RENESAS_CPG_MSTP 43 select CLK_RENESAS_CPG_MSTP
43 select CLK_RENESAS_DIV6 44 select CLK_RENESAS_DIV6
44 45
45config CLK_R8A7740 46config CLK_R8A7740
46 bool 47 bool "R-Mobile A1 clock support" if COMPILE_TEST
47 select CLK_RENESAS_CPG_MSTP 48 select CLK_RENESAS_CPG_MSTP
48 select CLK_RENESAS_DIV6 49 select CLK_RENESAS_DIV6
49 50
50config CLK_R8A7743 51config CLK_R8A7743
51 bool 52 bool "RZ/G1M clock support" if COMPILE_TEST
52 select CLK_RCAR_GEN2_CPG 53 select CLK_RCAR_GEN2_CPG
53 54
54config CLK_R8A7745 55config CLK_R8A7745
55 bool 56 bool "RZ/G1E clock support" if COMPILE_TEST
56 select CLK_RCAR_GEN2_CPG 57 select CLK_RCAR_GEN2_CPG
57 58
58config CLK_R8A7778 59config CLK_R8A7778
59 bool 60 bool "R-Car M1A clock support" if COMPILE_TEST
60 select CLK_RENESAS_CPG_MSTP 61 select CLK_RENESAS_CPG_MSTP
61 62
62config CLK_R8A7779 63config CLK_R8A7779
63 bool 64 bool "R-Car H1 clock support" if COMPILE_TEST
64 select CLK_RENESAS_CPG_MSTP 65 select CLK_RENESAS_CPG_MSTP
65 66
66config CLK_R8A7790 67config CLK_R8A7790
67 bool 68 bool "R-Car H2 clock support" if COMPILE_TEST
68 select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY 69 select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY
69 select CLK_RCAR_GEN2_CPG 70 select CLK_RCAR_GEN2_CPG
70 select CLK_RENESAS_DIV6 71 select CLK_RENESAS_DIV6
71 72
72config CLK_R8A7791 73config CLK_R8A7791
73 bool 74 bool "R-Car M2-W/N clock support" if COMPILE_TEST
74 select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY 75 select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY
75 select CLK_RCAR_GEN2_CPG 76 select CLK_RCAR_GEN2_CPG
76 select CLK_RENESAS_DIV6 77 select CLK_RENESAS_DIV6
77 78
78config CLK_R8A7792 79config CLK_R8A7792
79 bool 80 bool "R-Car V2H clock support" if COMPILE_TEST
80 select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY 81 select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY
81 select CLK_RCAR_GEN2_CPG 82 select CLK_RCAR_GEN2_CPG
82 83
83config CLK_R8A7794 84config CLK_R8A7794
84 bool 85 bool "R-Car E2 clock support" if COMPILE_TEST
85 select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY 86 select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY
86 select CLK_RCAR_GEN2_CPG 87 select CLK_RCAR_GEN2_CPG
87 select CLK_RENESAS_DIV6 88 select CLK_RENESAS_DIV6
88 89
89config CLK_R8A7795 90config CLK_R8A7795
90 bool 91 bool "R-Car H3 clock support" if COMPILE_TEST
91 select CLK_RCAR_GEN3_CPG 92 select CLK_RCAR_GEN3_CPG
92 93
93config CLK_R8A7796 94config CLK_R8A7796
94 bool 95 bool "R-Car M3-W clock support" if COMPILE_TEST
96 select CLK_RCAR_GEN3_CPG
97
98config CLK_R8A77995
99 bool "R-Car D3 clock support" if COMPILE_TEST
95 select CLK_RCAR_GEN3_CPG 100 select CLK_RCAR_GEN3_CPG
96 101
97config CLK_SH73A0 102config CLK_SH73A0
98 bool 103 bool "SH-Mobile AG5 clock support" if COMPILE_TEST
99 select CLK_RENESAS_CPG_MSTP 104 select CLK_RENESAS_CPG_MSTP
100 select CLK_RENESAS_DIV6 105 select CLK_RENESAS_DIV6
101 106
102 107
103# Family 108# Family
104config CLK_RCAR_GEN2 109config CLK_RCAR_GEN2
105 bool 110 bool "R-Car Gen2 legacy clock support" if COMPILE_TEST
106 select CLK_RENESAS_CPG_MSTP 111 select CLK_RENESAS_CPG_MSTP
107 select CLK_RENESAS_DIV6 112 select CLK_RENESAS_DIV6
108 113
109config CLK_RCAR_GEN2_CPG 114config CLK_RCAR_GEN2_CPG
110 bool 115 bool "R-Car Gen2 CPG clock support" if COMPILE_TEST
111 select CLK_RENESAS_CPG_MSSR 116 select CLK_RENESAS_CPG_MSSR
112 117
113config CLK_RCAR_GEN3_CPG 118config CLK_RCAR_GEN3_CPG
114 bool 119 bool "R-Car Gen3 CPG clock support" if COMPILE_TEST
115 select CLK_RENESAS_CPG_MSSR 120 select CLK_RENESAS_CPG_MSSR
116 121
122config CLK_RCAR_USB2_CLOCK_SEL
123 bool "Renesas R-Car USB2 clock selector support"
124 depends on ARCH_RENESAS || COMPILE_TEST
125 help
126 This is a driver for R-Car USB2 clock selector
117 127
118# Generic 128# Generic
119config CLK_RENESAS_CPG_MSSR 129config CLK_RENESAS_CPG_MSSR
120 bool 130 bool "CPG/MSSR clock support" if COMPILE_TEST
121 select CLK_RENESAS_DIV6 131 select CLK_RENESAS_DIV6
122 132
123config CLK_RENESAS_CPG_MSTP 133config CLK_RENESAS_CPG_MSTP
124 bool 134 bool "MSTP clock support" if COMPILE_TEST
125 135
126config CLK_RENESAS_DIV6 136config CLK_RENESAS_DIV6
127 bool "DIV6 clock support" if COMPILE_TEST 137 bool "DIV6 clock support" if COMPILE_TEST
diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile
index 02d04124371f..9bda3ec5b199 100644
--- a/drivers/clk/renesas/Makefile
+++ b/drivers/clk/renesas/Makefile
@@ -13,12 +13,14 @@ obj-$(CONFIG_CLK_R8A7792) += r8a7792-cpg-mssr.o
13obj-$(CONFIG_CLK_R8A7794) += r8a7794-cpg-mssr.o 13obj-$(CONFIG_CLK_R8A7794) += r8a7794-cpg-mssr.o
14obj-$(CONFIG_CLK_R8A7795) += r8a7795-cpg-mssr.o 14obj-$(CONFIG_CLK_R8A7795) += r8a7795-cpg-mssr.o
15obj-$(CONFIG_CLK_R8A7796) += r8a7796-cpg-mssr.o 15obj-$(CONFIG_CLK_R8A7796) += r8a7796-cpg-mssr.o
16obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o
16obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o 17obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o
17 18
18# Family 19# Family
19obj-$(CONFIG_CLK_RCAR_GEN2) += clk-rcar-gen2.o 20obj-$(CONFIG_CLK_RCAR_GEN2) += clk-rcar-gen2.o
20obj-$(CONFIG_CLK_RCAR_GEN2_CPG) += rcar-gen2-cpg.o 21obj-$(CONFIG_CLK_RCAR_GEN2_CPG) += rcar-gen2-cpg.o
21obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o 22obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o
23obj-$(CONFIG_CLK_RCAR_USB2_CLOCK_SEL) += rcar-usb2-clock-sel.o
22 24
23# Generic 25# Generic
24obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o 26obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o
diff --git a/drivers/clk/renesas/clk-div6.c b/drivers/clk/renesas/clk-div6.c
index 0627860233cb..3e0040c0ac87 100644
--- a/drivers/clk/renesas/clk-div6.c
+++ b/drivers/clk/renesas/clk-div6.c
@@ -29,6 +29,9 @@
29 * @hw: handle between common and hardware-specific interfaces 29 * @hw: handle between common and hardware-specific interfaces
30 * @reg: IO-remapped register 30 * @reg: IO-remapped register
31 * @div: divisor value (1-64) 31 * @div: divisor value (1-64)
32 * @src_shift: Shift to access the register bits to select the parent clock
33 * @src_width: Number of register bits to select the parent clock (may be 0)
34 * @parents: Array to map from valid parent clocks indices to hardware indices
32 */ 35 */
33struct div6_clock { 36struct div6_clock {
34 struct clk_hw hw; 37 struct clk_hw hw;
diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c
index f1617dd044cb..500a9e4e03c4 100644
--- a/drivers/clk/renesas/clk-mstp.c
+++ b/drivers/clk/renesas/clk-mstp.c
@@ -335,7 +335,7 @@ void __init cpg_mstp_add_clk_domain(struct device_node *np)
335 u32 ncells; 335 u32 ncells;
336 336
337 if (of_property_read_u32(np, "#power-domain-cells", &ncells)) { 337 if (of_property_read_u32(np, "#power-domain-cells", &ncells)) {
338 pr_warn("%s lacks #power-domain-cells\n", np->full_name); 338 pr_warn("%pOF lacks #power-domain-cells\n", np);
339 return; 339 return;
340 } 340 }
341 341
diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c
index 51a2479ed5d7..0b2e56d0d94b 100644
--- a/drivers/clk/renesas/clk-rcar-gen2.c
+++ b/drivers/clk/renesas/clk-rcar-gen2.c
@@ -407,8 +407,7 @@ static void __init rcar_gen2_cpg_clocks_init(struct device_node *np)
407 407
408 if (rcar_rst_read_mode_pins(&cpg_mode)) { 408 if (rcar_rst_read_mode_pins(&cpg_mode)) {
409 /* Backward-compatibility with old DT */ 409 /* Backward-compatibility with old DT */
410 pr_warn("%s: failed to obtain mode pins from RST\n", 410 pr_warn("%pOF: failed to obtain mode pins from RST\n", np);
411 np->full_name);
412 cpg_mode = rcar_gen2_read_mode_pins(); 411 cpg_mode = rcar_gen2_read_mode_pins();
413 } 412 }
414 413
diff --git a/drivers/clk/renesas/r8a7792-cpg-mssr.c b/drivers/clk/renesas/r8a7792-cpg-mssr.c
index a832b9b6f7b0..7f85bbf20bf7 100644
--- a/drivers/clk/renesas/r8a7792-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7792-cpg-mssr.c
@@ -118,6 +118,13 @@ static const struct mssr_mod_clk r8a7792_mod_clks[] __initconst = {
118 DEF_MOD("vin1", 810, R8A7792_CLK_ZG), 118 DEF_MOD("vin1", 810, R8A7792_CLK_ZG),
119 DEF_MOD("vin0", 811, R8A7792_CLK_ZG), 119 DEF_MOD("vin0", 811, R8A7792_CLK_ZG),
120 DEF_MOD("etheravb", 812, R8A7792_CLK_HP), 120 DEF_MOD("etheravb", 812, R8A7792_CLK_HP),
121 DEF_MOD("imr-lx3", 821, R8A7792_CLK_ZG),
122 DEF_MOD("imr-lsx3-1", 822, R8A7792_CLK_ZG),
123 DEF_MOD("imr-lsx3-0", 823, R8A7792_CLK_ZG),
124 DEF_MOD("imr-lsx3-5", 825, R8A7792_CLK_ZG),
125 DEF_MOD("imr-lsx3-4", 826, R8A7792_CLK_ZG),
126 DEF_MOD("imr-lsx3-3", 827, R8A7792_CLK_ZG),
127 DEF_MOD("imr-lsx3-2", 828, R8A7792_CLK_ZG),
121 DEF_MOD("gyro-adc", 901, R8A7792_CLK_P), 128 DEF_MOD("gyro-adc", 901, R8A7792_CLK_P),
122 DEF_MOD("gpio7", 904, R8A7792_CLK_CP), 129 DEF_MOD("gpio7", 904, R8A7792_CLK_CP),
123 DEF_MOD("gpio6", 905, R8A7792_CLK_CP), 130 DEF_MOD("gpio6", 905, R8A7792_CLK_CP),
diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c
index c091a8e024b8..762b2f8824f1 100644
--- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
@@ -305,23 +305,23 @@ static const unsigned int r8a7795_crit_mod_clks[] __initconst = {
305 (((md) & BIT(17)) >> 17)) 305 (((md) & BIT(17)) >> 17))
306 306
307static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { 307static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = {
308 /* EXTAL div PLL1 mult PLL3 mult */ 308 /* EXTAL div PLL1 mult/div PLL3 mult/div */
309 { 1, 192, 192, }, 309 { 1, 192, 1, 192, 1, },
310 { 1, 192, 128, }, 310 { 1, 192, 1, 128, 1, },
311 { 0, /* Prohibited setting */ }, 311 { 0, /* Prohibited setting */ },
312 { 1, 192, 192, }, 312 { 1, 192, 1, 192, 1, },
313 { 1, 160, 160, }, 313 { 1, 160, 1, 160, 1, },
314 { 1, 160, 106, }, 314 { 1, 160, 1, 106, 1, },
315 { 0, /* Prohibited setting */ }, 315 { 0, /* Prohibited setting */ },
316 { 1, 160, 160, }, 316 { 1, 160, 1, 160, 1, },
317 { 1, 128, 128, }, 317 { 1, 128, 1, 128, 1, },
318 { 1, 128, 84, }, 318 { 1, 128, 1, 84, 1, },
319 { 0, /* Prohibited setting */ }, 319 { 0, /* Prohibited setting */ },
320 { 1, 128, 128, }, 320 { 1, 128, 1, 128, 1, },
321 { 2, 192, 192, }, 321 { 2, 192, 1, 192, 1, },
322 { 2, 192, 128, }, 322 { 2, 192, 1, 128, 1, },
323 { 0, /* Prohibited setting */ }, 323 { 0, /* Prohibited setting */ },
324 { 2, 192, 192, }, 324 { 2, 192, 1, 192, 1, },
325}; 325};
326 326
327static const struct soc_device_attribute r8a7795es1[] __initconst = { 327static const struct soc_device_attribute r8a7795es1[] __initconst = {
diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c
index acc6d0f153e1..e5e7fb212288 100644
--- a/drivers/clk/renesas/r8a7796-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c
@@ -138,6 +138,7 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = {
138 DEF_MOD("sdif0", 314, R8A7796_CLK_SD0), 138 DEF_MOD("sdif0", 314, R8A7796_CLK_SD0),
139 DEF_MOD("pcie1", 318, R8A7796_CLK_S3D1), 139 DEF_MOD("pcie1", 318, R8A7796_CLK_S3D1),
140 DEF_MOD("pcie0", 319, R8A7796_CLK_S3D1), 140 DEF_MOD("pcie0", 319, R8A7796_CLK_S3D1),
141 DEF_MOD("usb3-if0", 328, R8A7796_CLK_S3D1),
141 DEF_MOD("usb-dmac0", 330, R8A7796_CLK_S3D1), 142 DEF_MOD("usb-dmac0", 330, R8A7796_CLK_S3D1),
142 DEF_MOD("usb-dmac1", 331, R8A7796_CLK_S3D1), 143 DEF_MOD("usb-dmac1", 331, R8A7796_CLK_S3D1),
143 DEF_MOD("rwdt", 402, R8A7796_CLK_R), 144 DEF_MOD("rwdt", 402, R8A7796_CLK_R),
@@ -277,23 +278,23 @@ static const unsigned int r8a7796_crit_mod_clks[] __initconst = {
277 (((md) & BIT(17)) >> 17)) 278 (((md) & BIT(17)) >> 17))
278 279
279static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { 280static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = {
280 /* EXTAL div PLL1 mult PLL3 mult */ 281 /* EXTAL div PLL1 mult/div PLL3 mult/div */
281 { 1, 192, 192, }, 282 { 1, 192, 1, 192, 1, },
282 { 1, 192, 128, }, 283 { 1, 192, 1, 128, 1, },
283 { 0, /* Prohibited setting */ }, 284 { 0, /* Prohibited setting */ },
284 { 1, 192, 192, }, 285 { 1, 192, 1, 192, 1, },
285 { 1, 160, 160, }, 286 { 1, 160, 1, 160, 1, },
286 { 1, 160, 106, }, 287 { 1, 160, 1, 106, 1, },
287 { 0, /* Prohibited setting */ }, 288 { 0, /* Prohibited setting */ },
288 { 1, 160, 160, }, 289 { 1, 160, 1, 160, 1, },
289 { 1, 128, 128, }, 290 { 1, 128, 1, 128, 1, },
290 { 1, 128, 84, }, 291 { 1, 128, 1, 84, 1, },
291 { 0, /* Prohibited setting */ }, 292 { 0, /* Prohibited setting */ },
292 { 1, 128, 128, }, 293 { 1, 128, 1, 128, 1, },
293 { 2, 192, 192, }, 294 { 2, 192, 1, 192, 1, },
294 { 2, 192, 128, }, 295 { 2, 192, 1, 128, 1, },
295 { 0, /* Prohibited setting */ }, 296 { 0, /* Prohibited setting */ },
296 { 2, 192, 192, }, 297 { 2, 192, 1, 192, 1, },
297}; 298};
298 299
299static int __init r8a7796_cpg_mssr_init(struct device *dev) 300static int __init r8a7796_cpg_mssr_init(struct device *dev)
diff --git a/drivers/clk/renesas/r8a77995-cpg-mssr.c b/drivers/clk/renesas/r8a77995-cpg-mssr.c
new file mode 100644
index 000000000000..e594cf8ee63b
--- /dev/null
+++ b/drivers/clk/renesas/r8a77995-cpg-mssr.c
@@ -0,0 +1,236 @@
1/*
2 * r8a77995 Clock Pulse Generator / Module Standby and Software Reset
3 *
4 * Copyright (C) 2017 Glider bvba
5 *
6 * Based on r8a7795-cpg-mssr.c
7 *
8 * Copyright (C) 2015 Glider bvba
9 * Copyright (C) 2015 Renesas Electronics Corp.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2 of the License.
14 */
15
16#include <linux/device.h>
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/soc/renesas/rcar-rst.h>
20
21#include <dt-bindings/clock/r8a77995-cpg-mssr.h>
22
23#include "renesas-cpg-mssr.h"
24#include "rcar-gen3-cpg.h"
25
26enum clk_ids {
27 /* Core Clock Outputs exported to DT */
28 LAST_DT_CORE_CLK = R8A77995_CLK_CP,
29
30 /* External Input Clocks */
31 CLK_EXTAL,
32
33 /* Internal Core Clocks */
34 CLK_MAIN,
35 CLK_PLL0,
36 CLK_PLL1,
37 CLK_PLL3,
38 CLK_PLL0D2,
39 CLK_PLL0D3,
40 CLK_PLL0D5,
41 CLK_PLL1D2,
42 CLK_PE,
43 CLK_S0,
44 CLK_S1,
45 CLK_S2,
46 CLK_S3,
47 CLK_SDSRC,
48 CLK_SSPSRC,
49
50 /* Module Clocks */
51 MOD_CLK_BASE
52};
53
54static const struct cpg_core_clk r8a77995_core_clks[] __initconst = {
55 /* External Clock Inputs */
56 DEF_INPUT("extal", CLK_EXTAL),
57
58 /* Internal Core Clocks */
59 DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL),
60 DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN),
61 DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN),
62
63 DEF_FIXED(".pll0", CLK_PLL0, CLK_MAIN, 4, 250),
64 DEF_FIXED(".pll0d2", CLK_PLL0D2, CLK_PLL0, 2, 1),
65 DEF_FIXED(".pll0d3", CLK_PLL0D3, CLK_PLL0, 3, 1),
66 DEF_FIXED(".pll0d5", CLK_PLL0D5, CLK_PLL0, 5, 1),
67 DEF_FIXED(".pll1d2", CLK_PLL1D2, CLK_PLL1, 2, 1),
68 DEF_FIXED(".pe", CLK_PE, CLK_PLL0D3, 4, 1),
69 DEF_FIXED(".s0", CLK_S0, CLK_PLL1, 2, 1),
70 DEF_FIXED(".s1", CLK_S1, CLK_PLL1, 3, 1),
71 DEF_FIXED(".s2", CLK_S2, CLK_PLL1, 4, 1),
72 DEF_FIXED(".s3", CLK_S3, CLK_PLL1, 6, 1),
73 DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1, 2, 1),
74
75 /* Core Clock Outputs */
76 DEF_FIXED("z2", R8A77995_CLK_Z2, CLK_PLL0D3, 1, 1),
77 DEF_FIXED("ztr", R8A77995_CLK_ZTR, CLK_PLL1, 6, 1),
78 DEF_FIXED("zt", R8A77995_CLK_ZT, CLK_PLL1, 4, 1),
79 DEF_FIXED("zx", R8A77995_CLK_ZX, CLK_PLL1, 3, 1),
80 DEF_FIXED("s0d1", R8A77995_CLK_S0D1, CLK_S0, 1, 1),
81 DEF_FIXED("s1d1", R8A77995_CLK_S1D1, CLK_S1, 1, 1),
82 DEF_FIXED("s1d2", R8A77995_CLK_S1D2, CLK_S1, 2, 1),
83 DEF_FIXED("s1d4", R8A77995_CLK_S1D4, CLK_S1, 4, 1),
84 DEF_FIXED("s2d1", R8A77995_CLK_S2D1, CLK_S2, 1, 1),
85 DEF_FIXED("s2d2", R8A77995_CLK_S2D2, CLK_S2, 2, 1),
86 DEF_FIXED("s2d4", R8A77995_CLK_S2D4, CLK_S2, 4, 1),
87 DEF_FIXED("s3d1", R8A77995_CLK_S3D1, CLK_S3, 1, 1),
88 DEF_FIXED("s3d2", R8A77995_CLK_S3D2, CLK_S3, 2, 1),
89 DEF_FIXED("s3d4", R8A77995_CLK_S3D4, CLK_S3, 4, 1),
90
91 DEF_FIXED("cl", R8A77995_CLK_CL, CLK_PLL1, 48, 1),
92 DEF_FIXED("cp", R8A77995_CLK_CP, CLK_EXTAL, 2, 1),
93 DEF_FIXED("osc", R8A77995_CLK_OSC, CLK_EXTAL, 384, 1),
94 DEF_FIXED("r", R8A77995_CLK_R, CLK_EXTAL, 1536, 1),
95
96 DEF_GEN3_PE("s1d4c", R8A77995_CLK_S1D4C, CLK_S1, 4, CLK_PE, 2),
97 DEF_GEN3_PE("s3d1c", R8A77995_CLK_S3D1C, CLK_S3, 1, CLK_PE, 1),
98 DEF_GEN3_PE("s3d2c", R8A77995_CLK_S3D2C, CLK_S3, 2, CLK_PE, 2),
99 DEF_GEN3_PE("s3d4c", R8A77995_CLK_S3D4C, CLK_S3, 4, CLK_PE, 4),
100
101 DEF_GEN3_SD("sd0", R8A77995_CLK_SD0, CLK_SDSRC, 0x268),
102
103 DEF_DIV6P1("canfd", R8A77995_CLK_CANFD, CLK_PLL0D3, 0x244),
104 DEF_DIV6P1("mso", R8A77995_CLK_MSO, CLK_PLL1D2, 0x014),
105};
106
107static const struct mssr_mod_clk r8a77995_mod_clks[] __initconst = {
108 DEF_MOD("scif5", 202, R8A77995_CLK_S3D4C),
109 DEF_MOD("scif4", 203, R8A77995_CLK_S3D4C),
110 DEF_MOD("scif3", 204, R8A77995_CLK_S3D4C),
111 DEF_MOD("scif1", 206, R8A77995_CLK_S3D4C),
112 DEF_MOD("scif0", 207, R8A77995_CLK_S3D4C),
113 DEF_MOD("msiof3", 208, R8A77995_CLK_MSO),
114 DEF_MOD("msiof2", 209, R8A77995_CLK_MSO),
115 DEF_MOD("msiof1", 210, R8A77995_CLK_MSO),
116 DEF_MOD("msiof0", 211, R8A77995_CLK_MSO),
117 DEF_MOD("sys-dmac2", 217, R8A77995_CLK_S3D1),
118 DEF_MOD("sys-dmac1", 218, R8A77995_CLK_S3D1),
119 DEF_MOD("sys-dmac0", 219, R8A77995_CLK_S3D1),
120 DEF_MOD("cmt3", 300, R8A77995_CLK_R),
121 DEF_MOD("cmt2", 301, R8A77995_CLK_R),
122 DEF_MOD("cmt1", 302, R8A77995_CLK_R),
123 DEF_MOD("cmt0", 303, R8A77995_CLK_R),
124 DEF_MOD("scif2", 310, R8A77995_CLK_S3D4C),
125 DEF_MOD("emmc0", 312, R8A77995_CLK_SD0),
126 DEF_MOD("usb-dmac0", 330, R8A77995_CLK_S3D1),
127 DEF_MOD("usb-dmac1", 331, R8A77995_CLK_S3D1),
128 DEF_MOD("rwdt", 402, R8A77995_CLK_R),
129 DEF_MOD("intc-ex", 407, R8A77995_CLK_CP),
130 DEF_MOD("intc-ap", 408, R8A77995_CLK_S3D1),
131 DEF_MOD("audmac0", 502, R8A77995_CLK_S3D1),
132 DEF_MOD("hscif3", 517, R8A77995_CLK_S3D1C),
133 DEF_MOD("hscif0", 520, R8A77995_CLK_S3D1C),
134 DEF_MOD("thermal", 522, R8A77995_CLK_CP),
135 DEF_MOD("pwm", 523, R8A77995_CLK_S3D4C),
136 DEF_MOD("fcpvd1", 602, R8A77995_CLK_S1D2),
137 DEF_MOD("fcpvd0", 603, R8A77995_CLK_S1D2),
138 DEF_MOD("fcpvbs", 607, R8A77995_CLK_S0D1),
139 DEF_MOD("vspd1", 622, R8A77995_CLK_S1D2),
140 DEF_MOD("vspd0", 623, R8A77995_CLK_S1D2),
141 DEF_MOD("vspbs", 627, R8A77995_CLK_S0D1),
142 DEF_MOD("ehci0", 703, R8A77995_CLK_S3D2),
143 DEF_MOD("hsusb", 704, R8A77995_CLK_S3D2),
144 DEF_MOD("du1", 723, R8A77995_CLK_S2D1),
145 DEF_MOD("du0", 724, R8A77995_CLK_S2D1),
146 DEF_MOD("lvds", 727, R8A77995_CLK_S2D1),
147 DEF_MOD("vin7", 804, R8A77995_CLK_S1D2),
148 DEF_MOD("vin6", 805, R8A77995_CLK_S1D2),
149 DEF_MOD("vin5", 806, R8A77995_CLK_S1D2),
150 DEF_MOD("vin4", 807, R8A77995_CLK_S1D2),
151 DEF_MOD("etheravb", 812, R8A77995_CLK_S3D2),
152 DEF_MOD("imr0", 823, R8A77995_CLK_S1D2),
153 DEF_MOD("gpio6", 906, R8A77995_CLK_S3D4),
154 DEF_MOD("gpio5", 907, R8A77995_CLK_S3D4),
155 DEF_MOD("gpio4", 908, R8A77995_CLK_S3D4),
156 DEF_MOD("gpio3", 909, R8A77995_CLK_S3D4),
157 DEF_MOD("gpio2", 910, R8A77995_CLK_S3D4),
158 DEF_MOD("gpio1", 911, R8A77995_CLK_S3D4),
159 DEF_MOD("gpio0", 912, R8A77995_CLK_S3D4),
160 DEF_MOD("can-fd", 914, R8A77995_CLK_S3D2),
161 DEF_MOD("can-if1", 915, R8A77995_CLK_S3D4),
162 DEF_MOD("can-if0", 916, R8A77995_CLK_S3D4),
163 DEF_MOD("i2c3", 928, R8A77995_CLK_S3D2),
164 DEF_MOD("i2c2", 929, R8A77995_CLK_S3D2),
165 DEF_MOD("i2c1", 930, R8A77995_CLK_S3D2),
166 DEF_MOD("i2c0", 931, R8A77995_CLK_S3D2),
167 DEF_MOD("ssi-all", 1005, R8A77995_CLK_S3D4),
168 DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)),
169 DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)),
170 DEF_MOD("scu-all", 1017, R8A77995_CLK_S3D4),
171 DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)),
172 DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)),
173 DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)),
174 DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)),
175 DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)),
176 DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)),
177};
178
179static const unsigned int r8a77995_crit_mod_clks[] __initconst = {
180 MOD_CLK_ID(408), /* INTC-AP (GIC) */
181};
182
183
184/*
185 * CPG Clock Data
186 */
187
188/*
189 * MD19 EXTAL (MHz) PLL0 PLL1 PLL3
190 *--------------------------------------------------------------------
191 * 0 48 x 1 x250/4 x100/3 x100/3
192 * 1 48 x 1 x250/4 x100/3 x116/6
193 */
194#define CPG_PLL_CONFIG_INDEX(md) (((md) & BIT(19)) >> 19)
195
196static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[2] __initconst = {
197 /* EXTAL div PLL1 mult/div PLL3 mult/div */
198 { 1, 100, 3, 100, 3, },
199 { 1, 100, 3, 116, 6, },
200};
201
202static int __init r8a77995_cpg_mssr_init(struct device *dev)
203{
204 const struct rcar_gen3_cpg_pll_config *cpg_pll_config;
205 u32 cpg_mode;
206 int error;
207
208 error = rcar_rst_read_mode_pins(&cpg_mode);
209 if (error)
210 return error;
211
212 cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
213
214 return rcar_gen3_cpg_init(cpg_pll_config, 0, cpg_mode);
215}
216
217const struct cpg_mssr_info r8a77995_cpg_mssr_info __initconst = {
218 /* Core Clocks */
219 .core_clks = r8a77995_core_clks,
220 .num_core_clks = ARRAY_SIZE(r8a77995_core_clks),
221 .last_dt_core_clk = LAST_DT_CORE_CLK,
222 .num_total_core_clks = MOD_CLK_BASE,
223
224 /* Module Clocks */
225 .mod_clks = r8a77995_mod_clks,
226 .num_mod_clks = ARRAY_SIZE(r8a77995_mod_clks),
227 .num_hw_mod_clks = 12 * 32,
228
229 /* Critical Module Clocks */
230 .crit_mod_clks = r8a77995_crit_mod_clks,
231 .num_crit_mod_clks = ARRAY_SIZE(r8a77995_crit_mod_clks),
232
233 /* Callbacks */
234 .init = r8a77995_cpg_mssr_init,
235 .cpg_clk_register = rcar_gen3_cpg_clk_register,
236};
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
index 3dee900522b7..951105816547 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.c
+++ b/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -60,6 +60,7 @@ struct sd_clock {
60 unsigned int div_num; 60 unsigned int div_num;
61 unsigned int div_min; 61 unsigned int div_min;
62 unsigned int div_max; 62 unsigned int div_max;
63 unsigned int cur_div_idx;
63}; 64};
64 65
65/* SDn divider 66/* SDn divider
@@ -96,21 +97,10 @@ static const struct sd_div_table cpg_sd_div_table[] = {
96static int cpg_sd_clock_enable(struct clk_hw *hw) 97static int cpg_sd_clock_enable(struct clk_hw *hw)
97{ 98{
98 struct sd_clock *clock = to_sd_clock(hw); 99 struct sd_clock *clock = to_sd_clock(hw);
99 u32 val, sd_fc; 100 u32 val = readl(clock->reg);
100 unsigned int i;
101
102 val = readl(clock->reg);
103
104 sd_fc = val & CPG_SD_FC_MASK;
105 for (i = 0; i < clock->div_num; i++)
106 if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK))
107 break;
108
109 if (i >= clock->div_num)
110 return -EINVAL;
111 101
112 val &= ~(CPG_SD_STP_MASK); 102 val &= ~(CPG_SD_STP_MASK);
113 val |= clock->div_table[i].val & CPG_SD_STP_MASK; 103 val |= clock->div_table[clock->cur_div_idx].val & CPG_SD_STP_MASK;
114 104
115 writel(val, clock->reg); 105 writel(val, clock->reg);
116 106
@@ -135,21 +125,9 @@ static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw,
135 unsigned long parent_rate) 125 unsigned long parent_rate)
136{ 126{
137 struct sd_clock *clock = to_sd_clock(hw); 127 struct sd_clock *clock = to_sd_clock(hw);
138 unsigned long rate = parent_rate;
139 u32 val, sd_fc;
140 unsigned int i;
141 128
142 val = readl(clock->reg); 129 return DIV_ROUND_CLOSEST(parent_rate,
143 130 clock->div_table[clock->cur_div_idx].div);
144 sd_fc = val & CPG_SD_FC_MASK;
145 for (i = 0; i < clock->div_num; i++)
146 if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK))
147 break;
148
149 if (i >= clock->div_num)
150 return -EINVAL;
151
152 return DIV_ROUND_CLOSEST(rate, clock->div_table[i].div);
153} 131}
154 132
155static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, 133static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock,
@@ -190,6 +168,8 @@ static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate,
190 if (i >= clock->div_num) 168 if (i >= clock->div_num)
191 return -EINVAL; 169 return -EINVAL;
192 170
171 clock->cur_div_idx = i;
172
193 val = readl(clock->reg); 173 val = readl(clock->reg);
194 val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK); 174 val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK);
195 val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK); 175 val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK);
@@ -215,6 +195,7 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core,
215 struct sd_clock *clock; 195 struct sd_clock *clock;
216 struct clk *clk; 196 struct clk *clk;
217 unsigned int i; 197 unsigned int i;
198 u32 sd_fc;
218 199
219 clock = kzalloc(sizeof(*clock), GFP_KERNEL); 200 clock = kzalloc(sizeof(*clock), GFP_KERNEL);
220 if (!clock) 201 if (!clock)
@@ -231,6 +212,18 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core,
231 clock->div_table = cpg_sd_div_table; 212 clock->div_table = cpg_sd_div_table;
232 clock->div_num = ARRAY_SIZE(cpg_sd_div_table); 213 clock->div_num = ARRAY_SIZE(cpg_sd_div_table);
233 214
215 sd_fc = readl(clock->reg) & CPG_SD_FC_MASK;
216 for (i = 0; i < clock->div_num; i++)
217 if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK))
218 break;
219
220 if (WARN_ON(i >= clock->div_num)) {
221 kfree(clock);
222 return ERR_PTR(-EINVAL);
223 }
224
225 clock->cur_div_idx = i;
226
234 clock->div_max = clock->div_table[0].div; 227 clock->div_max = clock->div_table[0].div;
235 clock->div_min = clock->div_max; 228 clock->div_min = clock->div_max;
236 for (i = 1; i < clock->div_num; i++) { 229 for (i = 1; i < clock->div_num; i++) {
@@ -279,7 +272,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
279 unsigned int div = 1; 272 unsigned int div = 1;
280 u32 value; 273 u32 value;
281 274
282 parent = clks[core->parent]; 275 parent = clks[core->parent & 0xffff]; /* CLK_TYPE_PE uses high bits */
283 if (IS_ERR(parent)) 276 if (IS_ERR(parent))
284 return ERR_CAST(parent); 277 return ERR_CAST(parent);
285 278
@@ -303,6 +296,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
303 296
304 case CLK_TYPE_GEN3_PLL1: 297 case CLK_TYPE_GEN3_PLL1:
305 mult = cpg_pll_config->pll1_mult; 298 mult = cpg_pll_config->pll1_mult;
299 div = cpg_pll_config->pll1_div;
306 break; 300 break;
307 301
308 case CLK_TYPE_GEN3_PLL2: 302 case CLK_TYPE_GEN3_PLL2:
@@ -320,6 +314,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
320 314
321 case CLK_TYPE_GEN3_PLL3: 315 case CLK_TYPE_GEN3_PLL3:
322 mult = cpg_pll_config->pll3_mult; 316 mult = cpg_pll_config->pll3_mult;
317 div = cpg_pll_config->pll3_div;
323 break; 318 break;
324 319
325 case CLK_TYPE_GEN3_PLL4: 320 case CLK_TYPE_GEN3_PLL4:
@@ -360,6 +355,24 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
360 parent = clks[cpg_clk_extalr]; 355 parent = clks[cpg_clk_extalr];
361 break; 356 break;
362 357
358 case CLK_TYPE_GEN3_PE:
359 /*
360 * Peripheral clock with a fixed divider, selectable between
361 * clean and spread spectrum parents using MD12
362 */
363 if (cpg_mode & BIT(12)) {
364 /* Clean */
365 div = core->div & 0xffff;
366 } else {
367 /* SCCG */
368 parent = clks[core->parent >> 16];
369 if (IS_ERR(parent))
370 return ERR_CAST(parent);
371 div = core->div >> 16;
372 }
373 mult = 1;
374 break;
375
363 default: 376 default:
364 return ERR_PTR(-EINVAL); 377 return ERR_PTR(-EINVAL);
365 } 378 }
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h
index 073be54b5d03..d756ef8b78eb 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.h
+++ b/drivers/clk/renesas/rcar-gen3-cpg.h
@@ -20,15 +20,24 @@ enum rcar_gen3_clk_types {
20 CLK_TYPE_GEN3_PLL4, 20 CLK_TYPE_GEN3_PLL4,
21 CLK_TYPE_GEN3_SD, 21 CLK_TYPE_GEN3_SD,
22 CLK_TYPE_GEN3_R, 22 CLK_TYPE_GEN3_R,
23 CLK_TYPE_GEN3_PE,
23}; 24};
24 25
25#define DEF_GEN3_SD(_name, _id, _parent, _offset) \ 26#define DEF_GEN3_SD(_name, _id, _parent, _offset) \
26 DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset) 27 DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset)
27 28
29#define DEF_GEN3_PE(_name, _id, _parent_sscg, _div_sscg, _parent_clean, \
30 _div_clean) \
31 DEF_BASE(_name, _id, CLK_TYPE_GEN3_PE, \
32 (_parent_sscg) << 16 | (_parent_clean), \
33 .div = (_div_sscg) << 16 | (_div_clean))
34
28struct rcar_gen3_cpg_pll_config { 35struct rcar_gen3_cpg_pll_config {
29 unsigned int extal_div; 36 u8 extal_div;
30 unsigned int pll1_mult; 37 u8 pll1_mult;
31 unsigned int pll3_mult; 38 u8 pll1_div;
39 u8 pll3_mult;
40 u8 pll3_div;
32}; 41};
33 42
34#define CPG_RCKCR 0x240 43#define CPG_RCKCR 0x240
diff --git a/drivers/clk/renesas/rcar-usb2-clock-sel.c b/drivers/clk/renesas/rcar-usb2-clock-sel.c
new file mode 100644
index 000000000000..6cd030a58964
--- /dev/null
+++ b/drivers/clk/renesas/rcar-usb2-clock-sel.c
@@ -0,0 +1,188 @@
1/*
2 * Renesas R-Car USB2.0 clock selector
3 *
4 * Copyright (C) 2017 Renesas Electronics Corp.
5 *
6 * Based on renesas-cpg-mssr.c
7 *
8 * Copyright (C) 2015 Glider bvba
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
13 */
14
15#include <linux/clk.h>
16#include <linux/clk-provider.h>
17#include <linux/device.h>
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/of_device.h>
21#include <linux/platform_device.h>
22#include <linux/pm.h>
23#include <linux/pm_runtime.h>
24#include <linux/slab.h>
25
26#define USB20_CLKSET0 0x00
27#define CLKSET0_INTCLK_EN BIT(11)
28#define CLKSET0_PRIVATE BIT(0)
29#define CLKSET0_EXTAL_ONLY (CLKSET0_INTCLK_EN | CLKSET0_PRIVATE)
30
31struct usb2_clock_sel_priv {
32 void __iomem *base;
33 struct clk_hw hw;
34 bool extal;
35 bool xtal;
36};
37#define to_priv(_hw) container_of(_hw, struct usb2_clock_sel_priv, hw)
38
39static void usb2_clock_sel_enable_extal_only(struct usb2_clock_sel_priv *priv)
40{
41 u16 val = readw(priv->base + USB20_CLKSET0);
42
43 pr_debug("%s: enter %d %d %x\n", __func__,
44 priv->extal, priv->xtal, val);
45
46 if (priv->extal && !priv->xtal && val != CLKSET0_EXTAL_ONLY)
47 writew(CLKSET0_EXTAL_ONLY, priv->base + USB20_CLKSET0);
48}
49
50static void usb2_clock_sel_disable_extal_only(struct usb2_clock_sel_priv *priv)
51{
52 if (priv->extal && !priv->xtal)
53 writew(CLKSET0_PRIVATE, priv->base + USB20_CLKSET0);
54}
55
56static int usb2_clock_sel_enable(struct clk_hw *hw)
57{
58 usb2_clock_sel_enable_extal_only(to_priv(hw));
59
60 return 0;
61}
62
63static void usb2_clock_sel_disable(struct clk_hw *hw)
64{
65 usb2_clock_sel_disable_extal_only(to_priv(hw));
66}
67
68/*
69 * This module seems a mux, but this driver assumes a gate because
70 * ehci/ohci platform drivers don't support clk_set_parent() for now.
71 * If this driver acts as a gate, ehci/ohci-platform drivers don't need
72 * any modification.
73 */
74static const struct clk_ops usb2_clock_sel_clock_ops = {
75 .enable = usb2_clock_sel_enable,
76 .disable = usb2_clock_sel_disable,
77};
78
79static const struct of_device_id rcar_usb2_clock_sel_match[] = {
80 { .compatible = "renesas,rcar-gen3-usb2-clock-sel" },
81 { }
82};
83
84static int rcar_usb2_clock_sel_suspend(struct device *dev)
85{
86 struct usb2_clock_sel_priv *priv = dev_get_drvdata(dev);
87
88 usb2_clock_sel_disable_extal_only(priv);
89 pm_runtime_put(dev);
90
91 return 0;
92}
93
94static int rcar_usb2_clock_sel_resume(struct device *dev)
95{
96 struct usb2_clock_sel_priv *priv = dev_get_drvdata(dev);
97
98 pm_runtime_get_sync(dev);
99 usb2_clock_sel_enable_extal_only(priv);
100
101 return 0;
102}
103
104static int rcar_usb2_clock_sel_remove(struct platform_device *pdev)
105{
106 struct device *dev = &pdev->dev;
107 struct usb2_clock_sel_priv *priv = platform_get_drvdata(pdev);
108
109 of_clk_del_provider(dev->of_node);
110 clk_hw_unregister(&priv->hw);
111 pm_runtime_put(dev);
112 pm_runtime_disable(dev);
113
114 return 0;
115}
116
117static int rcar_usb2_clock_sel_probe(struct platform_device *pdev)
118{
119 struct device *dev = &pdev->dev;
120 struct device_node *np = dev->of_node;
121 struct usb2_clock_sel_priv *priv;
122 struct resource *res;
123 struct clk *clk;
124 struct clk_init_data init;
125
126 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
127 if (!priv)
128 return -ENOMEM;
129
130 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
131 priv->base = devm_ioremap_resource(dev, res);
132 if (IS_ERR(priv->base))
133 return PTR_ERR(priv->base);
134
135 pm_runtime_enable(dev);
136 pm_runtime_get_sync(dev);
137
138 clk = devm_clk_get(dev, "usb_extal");
139 if (!IS_ERR(clk) && !clk_prepare_enable(clk)) {
140 priv->extal = !!clk_get_rate(clk);
141 clk_disable_unprepare(clk);
142 }
143 clk = devm_clk_get(dev, "usb_xtal");
144 if (!IS_ERR(clk) && !clk_prepare_enable(clk)) {
145 priv->xtal = !!clk_get_rate(clk);
146 clk_disable_unprepare(clk);
147 }
148
149 if (!priv->extal && !priv->xtal) {
150 dev_err(dev, "This driver needs usb_extal or usb_xtal\n");
151 return -ENOENT;
152 }
153
154 platform_set_drvdata(pdev, priv);
155 dev_set_drvdata(dev, priv);
156
157 init.name = "rcar_usb2_clock_sel";
158 init.ops = &usb2_clock_sel_clock_ops;
159 init.flags = 0;
160 init.parent_names = NULL;
161 init.num_parents = 0;
162 priv->hw.init = &init;
163
164 clk = clk_register(NULL, &priv->hw);
165 if (IS_ERR(clk))
166 return PTR_ERR(clk);
167
168 return of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw);
169}
170
171static const struct dev_pm_ops rcar_usb2_clock_sel_pm_ops = {
172 .suspend = rcar_usb2_clock_sel_suspend,
173 .resume = rcar_usb2_clock_sel_resume,
174};
175
176static struct platform_driver rcar_usb2_clock_sel_driver = {
177 .driver = {
178 .name = "rcar-usb2-clock-sel",
179 .of_match_table = rcar_usb2_clock_sel_match,
180 .pm = &rcar_usb2_clock_sel_pm_ops,
181 },
182 .probe = rcar_usb2_clock_sel_probe,
183 .remove = rcar_usb2_clock_sel_remove,
184};
185builtin_platform_driver(rcar_usb2_clock_sel_driver);
186
187MODULE_DESCRIPTION("Renesas R-Car USB2 clock selector Driver");
188MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
index 1f607c806f9b..e580a5e6346c 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -680,6 +680,12 @@ static const struct of_device_id cpg_mssr_match[] = {
680 .data = &r8a7796_cpg_mssr_info, 680 .data = &r8a7796_cpg_mssr_info,
681 }, 681 },
682#endif 682#endif
683#ifdef CONFIG_CLK_R8A77995
684 {
685 .compatible = "renesas,r8a77995-cpg-mssr",
686 .data = &r8a77995_cpg_mssr_info,
687 },
688#endif
683 { /* sentinel */ } 689 { /* sentinel */ }
684}; 690};
685 691
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h
index 43d7c7f6832d..94b9071d1061 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.h
+++ b/drivers/clk/renesas/renesas-cpg-mssr.h
@@ -138,6 +138,7 @@ extern const struct cpg_mssr_info r8a7792_cpg_mssr_info;
138extern const struct cpg_mssr_info r8a7794_cpg_mssr_info; 138extern const struct cpg_mssr_info r8a7794_cpg_mssr_info;
139extern const struct cpg_mssr_info r8a7795_cpg_mssr_info; 139extern const struct cpg_mssr_info r8a7795_cpg_mssr_info;
140extern const struct cpg_mssr_info r8a7796_cpg_mssr_info; 140extern const struct cpg_mssr_info r8a7796_cpg_mssr_info;
141extern const struct cpg_mssr_info r8a77995_cpg_mssr_info;
141 142
142 143
143 /* 144 /*
diff --git a/drivers/clk/rockchip/clk-rk3128.c b/drivers/clk/rockchip/clk-rk3128.c
index e243f2eae68f..62d7854e4b87 100644
--- a/drivers/clk/rockchip/clk-rk3128.c
+++ b/drivers/clk/rockchip/clk-rk3128.c
@@ -201,7 +201,7 @@ static struct rockchip_clk_branch rk3128_uart2_fracmux __initdata =
201 MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT, 201 MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
202 RK2928_CLKSEL_CON(15), 8, 2, MFLAGS); 202 RK2928_CLKSEL_CON(15), 8, 2, MFLAGS);
203 203
204static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = { 204static struct rockchip_clk_branch common_clk_branches[] __initdata = {
205 /* 205 /*
206 * Clock-Architecture Diagram 1 206 * Clock-Architecture Diagram 1
207 */ 207 */
@@ -459,10 +459,6 @@ static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = {
459 RK2928_CLKSEL_CON(2), 14, 2, MFLAGS, 8, 5, DFLAGS, 459 RK2928_CLKSEL_CON(2), 14, 2, MFLAGS, 8, 5, DFLAGS,
460 RK2928_CLKGATE_CON(10), 15, GFLAGS), 460 RK2928_CLKGATE_CON(10), 15, GFLAGS),
461 461
462 COMPOSITE(SCLK_SFC, "sclk_sfc", mux_sclk_sfc_src_p, 0,
463 RK2928_CLKSEL_CON(11), 14, 2, MFLAGS, 8, 5, DFLAGS,
464 RK2928_CLKGATE_CON(3), 15, GFLAGS),
465
466 COMPOSITE_NOMUX(PCLK_PMU_PRE, "pclk_pmu_pre", "cpll", 0, 462 COMPOSITE_NOMUX(PCLK_PMU_PRE, "pclk_pmu_pre", "cpll", 0,
467 RK2928_CLKSEL_CON(29), 8, 6, DFLAGS, 463 RK2928_CLKSEL_CON(29), 8, 6, DFLAGS,
468 RK2928_CLKGATE_CON(1), 0, GFLAGS), 464 RK2928_CLKGATE_CON(1), 0, GFLAGS),
@@ -495,7 +491,6 @@ static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = {
495 GATE(ACLK_DMAC, "aclk_dmac", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS), 491 GATE(ACLK_DMAC, "aclk_dmac", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS),
496 GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 15, GFLAGS), 492 GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 15, GFLAGS),
497 GATE(0, "aclk_cpu_to_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS), 493 GATE(0, "aclk_cpu_to_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS),
498 GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS),
499 494
500 GATE(HCLK_I2S_8CH, "hclk_i2s_8ch", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), 495 GATE(HCLK_I2S_8CH, "hclk_i2s_8ch", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
501 GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS), 496 GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS),
@@ -541,7 +536,6 @@ static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = {
541 GATE(0, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 6, GFLAGS), 536 GATE(0, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 6, GFLAGS),
542 GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS), 537 GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS),
543 538
544 GATE(PCLK_HDMI, "pclk_hdmi", "pclk_cpu", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS),
545 GATE(PCLK_ACODEC, "pclk_acodec", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS), 539 GATE(PCLK_ACODEC, "pclk_acodec", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS),
546 GATE(0, "pclk_ddrupctl", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 7, GFLAGS), 540 GATE(0, "pclk_ddrupctl", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 7, GFLAGS),
547 GATE(0, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS), 541 GATE(0, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS),
@@ -561,6 +555,21 @@ static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = {
561 MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 0), 555 MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 0),
562}; 556};
563 557
558static struct rockchip_clk_branch rk3126_clk_branches[] __initdata = {
559 GATE(0, "pclk_stimer", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 15, GFLAGS),
560 GATE(0, "pclk_s_efuse", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 14, GFLAGS),
561 GATE(0, "pclk_sgrf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 8, GFLAGS),
562};
563
564static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = {
565 COMPOSITE(SCLK_SFC, "sclk_sfc", mux_sclk_sfc_src_p, 0,
566 RK2928_CLKSEL_CON(11), 14, 2, MFLAGS, 8, 5, DFLAGS,
567 RK2928_CLKGATE_CON(3), 15, GFLAGS),
568
569 GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS),
570 GATE(PCLK_HDMI, "pclk_hdmi", "pclk_cpu", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS),
571};
572
564static const char *const rk3128_critical_clocks[] __initconst = { 573static const char *const rk3128_critical_clocks[] __initconst = {
565 "aclk_cpu", 574 "aclk_cpu",
566 "hclk_cpu", 575 "hclk_cpu",
@@ -570,7 +579,7 @@ static const char *const rk3128_critical_clocks[] __initconst = {
570 "pclk_peri", 579 "pclk_peri",
571}; 580};
572 581
573static void __init rk3128_clk_init(struct device_node *np) 582static struct rockchip_clk_provider *__init rk3128_common_clk_init(struct device_node *np)
574{ 583{
575 struct rockchip_clk_provider *ctx; 584 struct rockchip_clk_provider *ctx;
576 void __iomem *reg_base; 585 void __iomem *reg_base;
@@ -578,23 +587,21 @@ static void __init rk3128_clk_init(struct device_node *np)
578 reg_base = of_iomap(np, 0); 587 reg_base = of_iomap(np, 0);
579 if (!reg_base) { 588 if (!reg_base) {
580 pr_err("%s: could not map cru region\n", __func__); 589 pr_err("%s: could not map cru region\n", __func__);
581 return; 590 return ERR_PTR(-ENOMEM);
582 } 591 }
583 592
584 ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 593 ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
585 if (IS_ERR(ctx)) { 594 if (IS_ERR(ctx)) {
586 pr_err("%s: rockchip clk init failed\n", __func__); 595 pr_err("%s: rockchip clk init failed\n", __func__);
587 iounmap(reg_base); 596 iounmap(reg_base);
588 return; 597 return ERR_PTR(-ENOMEM);
589 } 598 }
590 599
591 rockchip_clk_register_plls(ctx, rk3128_pll_clks, 600 rockchip_clk_register_plls(ctx, rk3128_pll_clks,
592 ARRAY_SIZE(rk3128_pll_clks), 601 ARRAY_SIZE(rk3128_pll_clks),
593 RK3128_GRF_SOC_STATUS0); 602 RK3128_GRF_SOC_STATUS0);
594 rockchip_clk_register_branches(ctx, rk3128_clk_branches, 603 rockchip_clk_register_branches(ctx, common_clk_branches,
595 ARRAY_SIZE(rk3128_clk_branches)); 604 ARRAY_SIZE(common_clk_branches));
596 rockchip_clk_protect_critical(rk3128_critical_clocks,
597 ARRAY_SIZE(rk3128_critical_clocks));
598 605
599 rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", 606 rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
600 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 607 mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
@@ -606,6 +613,40 @@ static void __init rk3128_clk_init(struct device_node *np)
606 613
607 rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL); 614 rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL);
608 615
616 return ctx;
617}
618
619static void __init rk3126_clk_init(struct device_node *np)
620{
621 struct rockchip_clk_provider *ctx;
622
623 ctx = rk3128_common_clk_init(np);
624 if (IS_ERR(ctx))
625 return;
626
627 rockchip_clk_register_branches(ctx, rk3126_clk_branches,
628 ARRAY_SIZE(rk3126_clk_branches));
629 rockchip_clk_protect_critical(rk3128_critical_clocks,
630 ARRAY_SIZE(rk3128_critical_clocks));
631
632 rockchip_clk_of_add_provider(np, ctx);
633}
634
635CLK_OF_DECLARE(rk3126_cru, "rockchip,rk3126-cru", rk3126_clk_init);
636
637static void __init rk3128_clk_init(struct device_node *np)
638{
639 struct rockchip_clk_provider *ctx;
640
641 ctx = rk3128_common_clk_init(np);
642 if (IS_ERR(ctx))
643 return;
644
645 rockchip_clk_register_branches(ctx, rk3128_clk_branches,
646 ARRAY_SIZE(rk3128_clk_branches));
647 rockchip_clk_protect_critical(rk3128_critical_clocks,
648 ARRAY_SIZE(rk3128_critical_clocks));
649
609 rockchip_clk_of_add_provider(np, ctx); 650 rockchip_clk_of_add_provider(np, ctx);
610} 651}
611 652
diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c
index bb405d9044a3..11e7f2d1c054 100644
--- a/drivers/clk/rockchip/clk-rk3228.c
+++ b/drivers/clk/rockchip/clk-rk3228.c
@@ -391,7 +391,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
391 RK2928_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 8, DFLAGS, 391 RK2928_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 8, DFLAGS,
392 RK2928_CLKGATE_CON(2), 11, GFLAGS), 392 RK2928_CLKGATE_CON(2), 11, GFLAGS),
393 393
394 COMPOSITE_NODIV(0, "sclk_sdio_src", mux_mmc_src_p, 0, 394 COMPOSITE_NODIV(SCLK_SDIO_SRC, "sclk_sdio_src", mux_mmc_src_p, 0,
395 RK2928_CLKSEL_CON(11), 10, 2, MFLAGS, 395 RK2928_CLKSEL_CON(11), 10, 2, MFLAGS,
396 RK2928_CLKGATE_CON(2), 13, GFLAGS), 396 RK2928_CLKGATE_CON(2), 13, GFLAGS),
397 DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0, 397 DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0,
diff --git a/drivers/clk/rockchip/clk-rv1108.c b/drivers/clk/rockchip/clk-rv1108.c
index 7c05ab366348..089cb17925e5 100644
--- a/drivers/clk/rockchip/clk-rv1108.c
+++ b/drivers/clk/rockchip/clk-rv1108.c
@@ -93,9 +93,24 @@ static struct rockchip_pll_rate_table rv1108_pll_rates[] = {
93 } 93 }
94 94
95static struct rockchip_cpuclk_rate_table rv1108_cpuclk_rates[] __initdata = { 95static struct rockchip_cpuclk_rate_table rv1108_cpuclk_rates[] __initdata = {
96 RV1108_CPUCLK_RATE(816000000, 4), 96 RV1108_CPUCLK_RATE(1608000000, 7),
97 RV1108_CPUCLK_RATE(600000000, 4), 97 RV1108_CPUCLK_RATE(1512000000, 7),
98 RV1108_CPUCLK_RATE(312000000, 4), 98 RV1108_CPUCLK_RATE(1488000000, 5),
99 RV1108_CPUCLK_RATE(1416000000, 5),
100 RV1108_CPUCLK_RATE(1392000000, 5),
101 RV1108_CPUCLK_RATE(1296000000, 5),
102 RV1108_CPUCLK_RATE(1200000000, 5),
103 RV1108_CPUCLK_RATE(1104000000, 5),
104 RV1108_CPUCLK_RATE(1008000000, 5),
105 RV1108_CPUCLK_RATE(912000000, 5),
106 RV1108_CPUCLK_RATE(816000000, 3),
107 RV1108_CPUCLK_RATE(696000000, 3),
108 RV1108_CPUCLK_RATE(600000000, 3),
109 RV1108_CPUCLK_RATE(500000000, 3),
110 RV1108_CPUCLK_RATE(408000000, 1),
111 RV1108_CPUCLK_RATE(312000000, 1),
112 RV1108_CPUCLK_RATE(216000000, 1),
113 RV1108_CPUCLK_RATE(96000000, 1),
99}; 114};
100 115
101static const struct rockchip_cpuclk_reg_data rv1108_cpuclk_data = { 116static const struct rockchip_cpuclk_reg_data rv1108_cpuclk_data = {
@@ -105,7 +120,7 @@ static const struct rockchip_cpuclk_reg_data rv1108_cpuclk_data = {
105 .mux_core_alt = 1, 120 .mux_core_alt = 1,
106 .mux_core_main = 0, 121 .mux_core_main = 0,
107 .mux_core_shift = 8, 122 .mux_core_shift = 8,
108 .mux_core_mask = 0x1, 123 .mux_core_mask = 0x3,
109}; 124};
110 125
111PNAME(mux_pll_p) = { "xin24m", "xin24m"}; 126PNAME(mux_pll_p) = { "xin24m", "xin24m"};
@@ -114,30 +129,42 @@ PNAME(mux_armclk_p) = { "apll_core", "gpll_core", "dpll_core" };
114PNAME(mux_usb480m_pre_p) = { "usbphy", "xin24m" }; 129PNAME(mux_usb480m_pre_p) = { "usbphy", "xin24m" };
115PNAME(mux_hdmiphy_phy_p) = { "hdmiphy", "xin24m" }; 130PNAME(mux_hdmiphy_phy_p) = { "hdmiphy", "xin24m" };
116PNAME(mux_dclk_hdmiphy_pre_p) = { "dclk_hdmiphy_src_gpll", "dclk_hdmiphy_src_dpll" }; 131PNAME(mux_dclk_hdmiphy_pre_p) = { "dclk_hdmiphy_src_gpll", "dclk_hdmiphy_src_dpll" };
117PNAME(mux_pll_src_4plls_p) = { "dpll", "hdmiphy", "gpll", "usb480m" }; 132PNAME(mux_pll_src_4plls_p) = { "dpll", "gpll", "hdmiphy", "usb480m" };
118PNAME(mux_pll_src_3plls_p) = { "apll", "gpll", "dpll" }; 133PNAME(mux_pll_src_3plls_p) = { "apll", "gpll", "dpll" };
119PNAME(mux_pll_src_2plls_p) = { "dpll", "gpll" }; 134PNAME(mux_pll_src_2plls_p) = { "dpll", "gpll" };
120PNAME(mux_pll_src_apll_gpll_p) = { "apll", "gpll" }; 135PNAME(mux_pll_src_apll_gpll_p) = { "apll", "gpll" };
121PNAME(mux_aclk_peri_src_p) = { "aclk_peri_src_dpll", "aclk_peri_src_gpll" }; 136PNAME(mux_aclk_peri_src_p) = { "aclk_peri_src_gpll", "aclk_peri_src_dpll" };
122PNAME(mux_aclk_bus_src_p) = { "aclk_bus_src_gpll", "aclk_bus_src_apll", "aclk_bus_src_dpll" }; 137PNAME(mux_aclk_bus_src_p) = { "aclk_bus_src_gpll", "aclk_bus_src_apll", "aclk_bus_src_dpll" };
123PNAME(mux_mmc_src_p) = { "dpll", "gpll", "xin24m", "usb480m" }; 138PNAME(mux_mmc_src_p) = { "dpll", "gpll", "xin24m", "usb480m" };
124PNAME(mux_pll_src_dpll_gpll_usb480m_p) = { "dpll", "gpll", "usb480m" }; 139PNAME(mux_pll_src_dpll_gpll_usb480m_p) = { "dpll", "gpll", "usb480m" };
125PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" }; 140PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" };
126PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" }; 141PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" };
127PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" }; 142PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" };
128PNAME(mux_sclk_macphy_p) = { "sclk_macphy_pre", "ext_gmac" }; 143PNAME(mux_sclk_mac_p) = { "sclk_mac_pre", "ext_gmac" };
129PNAME(mux_i2s0_pre_p) = { "i2s0_src", "i2s0_frac", "ext_i2s", "xin12m" }; 144PNAME(mux_i2s0_pre_p) = { "i2s0_src", "i2s0_frac", "ext_i2s", "xin12m" };
130PNAME(mux_i2s_out_p) = { "i2s0_pre", "xin12m" }; 145PNAME(mux_i2s_out_p) = { "i2s0_pre", "xin12m" };
131PNAME(mux_i2s1_p) = { "i2s1_src", "i2s1_frac", "xin12m" }; 146PNAME(mux_i2s1_p) = { "i2s1_src", "i2s1_frac", "dummy", "xin12m" };
132PNAME(mux_i2s2_p) = { "i2s2_src", "i2s2_frac", "xin12m" }; 147PNAME(mux_i2s2_p) = { "i2s2_src", "i2s2_frac", "dummy", "xin12m" };
148PNAME(mux_wifi_src_p) = { "gpll", "xin24m" };
149PNAME(mux_cifout_src_p) = { "hdmiphy", "gpll" };
150PNAME(mux_cifout_p) = { "sclk_cifout_src", "xin24m" };
151PNAME(mux_sclk_cif0_src_p) = { "pclk_vip", "clk_cif0_chn_out", "pclkin_cvbs2cif" };
152PNAME(mux_sclk_cif1_src_p) = { "pclk_vip", "clk_cif1_chn_out", "pclkin_cvbs2cif" };
153PNAME(mux_sclk_cif2_src_p) = { "pclk_vip", "clk_cif2_chn_out", "pclkin_cvbs2cif" };
154PNAME(mux_sclk_cif3_src_p) = { "pclk_vip", "clk_cif3_chn_out", "pclkin_cvbs2cif" };
155PNAME(mux_dsp_src_p) = { "dpll", "gpll", "apll", "usb480m" };
156PNAME(mux_dclk_hdmiphy_p) = { "hdmiphy", "xin24m" };
157PNAME(mux_dclk_vop_p) = { "dclk_hdmiphy", "dclk_vop_src" };
158PNAME(mux_hdmi_cec_src_p) = { "dpll", "gpll", "xin24m" };
159PNAME(mux_cvbs_src_p) = { "apll", "io_cvbs_clkin", "hdmiphy", "gpll" };
133 160
134static struct rockchip_pll_clock rv1108_pll_clks[] __initdata = { 161static struct rockchip_pll_clock rv1108_pll_clks[] __initdata = {
135 [apll] = PLL(pll_rk3399, PLL_APLL, "apll", mux_pll_p, 0, RV1108_PLL_CON(0), 162 [apll] = PLL(pll_rk3399, PLL_APLL, "apll", mux_pll_p, 0, RV1108_PLL_CON(0),
136 RV1108_PLL_CON(3), 8, 31, 0, rv1108_pll_rates), 163 RV1108_PLL_CON(3), 8, 0, 0, rv1108_pll_rates),
137 [dpll] = PLL(pll_rk3399, PLL_DPLL, "dpll", mux_pll_p, 0, RV1108_PLL_CON(8), 164 [dpll] = PLL(pll_rk3399, PLL_DPLL, "dpll", mux_pll_p, 0, RV1108_PLL_CON(8),
138 RV1108_PLL_CON(11), 8, 31, 0, NULL), 165 RV1108_PLL_CON(11), 8, 1, 0, NULL),
139 [gpll] = PLL(pll_rk3399, PLL_GPLL, "gpll", mux_pll_p, 0, RV1108_PLL_CON(16), 166 [gpll] = PLL(pll_rk3399, PLL_GPLL, "gpll", mux_pll_p, 0, RV1108_PLL_CON(16),
140 RV1108_PLL_CON(19), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rv1108_pll_rates), 167 RV1108_PLL_CON(19), 8, 2, 0, rv1108_pll_rates),
141}; 168};
142 169
143#define MFLAGS CLK_MUX_HIWORD_MASK 170#define MFLAGS CLK_MUX_HIWORD_MASK
@@ -170,10 +197,10 @@ static struct rockchip_clk_branch rv1108_i2s2_fracmux __initdata =
170 RV1108_CLKSEL_CON(7), 12, 2, MFLAGS); 197 RV1108_CLKSEL_CON(7), 12, 2, MFLAGS);
171 198
172static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { 199static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = {
173 MUX(0, "hdmi_phy", mux_hdmiphy_phy_p, CLK_SET_RATE_PARENT, 200 MUX(0, "hdmiphy", mux_hdmiphy_phy_p, CLK_SET_RATE_PARENT,
174 RV1108_MISC_CON, 13, 2, MFLAGS), 201 RV1108_MISC_CON, 13, 1, MFLAGS),
175 MUX(0, "usb480m", mux_usb480m_pre_p, CLK_SET_RATE_PARENT, 202 MUX(0, "usb480m", mux_usb480m_pre_p, CLK_SET_RATE_PARENT,
176 RV1108_MISC_CON, 15, 2, MFLAGS), 203 RV1108_MISC_CON, 15, 1, MFLAGS),
177 /* 204 /*
178 * Clock-Architecture Diagram 2 205 * Clock-Architecture Diagram 2
179 */ 206 */
@@ -197,50 +224,212 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = {
197 RV1108_CLKGATE_CON(11), 1, GFLAGS), 224 RV1108_CLKGATE_CON(11), 1, GFLAGS),
198 225
199 /* PD_RKVENC */ 226 /* PD_RKVENC */
227 COMPOSITE(0, "aclk_rkvenc_pre", mux_pll_src_4plls_p, 0,
228 RV1108_CLKSEL_CON(37), 6, 2, MFLAGS, 0, 5, DFLAGS,
229 RV1108_CLKGATE_CON(8), 8, GFLAGS),
230 FACTOR_GATE(0, "hclk_rkvenc_pre", "aclk_rkvenc_pre", 0, 1, 4,
231 RV1108_CLKGATE_CON(8), 10, GFLAGS),
232 COMPOSITE(SCLK_VENC_CORE, "clk_venc_core", mux_pll_src_4plls_p, 0,
233 RV1108_CLKSEL_CON(37), 14, 2, MFLAGS, 8, 5, DFLAGS,
234 RV1108_CLKGATE_CON(8), 9, GFLAGS),
235 GATE(ACLK_RKVENC, "aclk_rkvenc", "aclk_rkvenc_pre", 0,
236 RV1108_CLKGATE_CON(19), 8, GFLAGS),
237 GATE(HCLK_RKVENC, "hclk_rkvenc", "hclk_rkvenc_pre", 0,
238 RV1108_CLKGATE_CON(19), 9, GFLAGS),
239 GATE(0, "aclk_rkvenc_niu", "aclk_rkvenc_pre", CLK_IGNORE_UNUSED,
240 RV1108_CLKGATE_CON(19), 11, GFLAGS),
241 GATE(0, "hclk_rkvenc_niu", "hclk_rkvenc_pre", CLK_IGNORE_UNUSED,
242 RV1108_CLKGATE_CON(19), 10, GFLAGS),
200 243
201 /* PD_RKVDEC */ 244 /* PD_RKVDEC */
245 COMPOSITE(SCLK_HEVC_CORE, "sclk_hevc_core", mux_pll_src_4plls_p, 0,
246 RV1108_CLKSEL_CON(36), 6, 2, MFLAGS, 0, 5, DFLAGS,
247 RV1108_CLKGATE_CON(8), 2, GFLAGS),
248 FACTOR_GATE(0, "hclk_rkvdec_pre", "sclk_hevc_core", 0, 1, 4,
249 RV1108_CLKGATE_CON(8), 10, GFLAGS),
250 COMPOSITE(SCLK_HEVC_CABAC, "clk_hevc_cabac", mux_pll_src_4plls_p, 0,
251 RV1108_CLKSEL_CON(35), 14, 2, MFLAGS, 8, 5, DFLAGS,
252 RV1108_CLKGATE_CON(8), 1, GFLAGS),
253
254 COMPOSITE(0, "aclk_rkvdec_pre", mux_pll_src_4plls_p, 0,
255 RV1108_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS,
256 RV1108_CLKGATE_CON(8), 0, GFLAGS),
257 COMPOSITE(0, "aclk_vpu_pre", mux_pll_src_4plls_p, 0,
258 RV1108_CLKSEL_CON(36), 14, 2, MFLAGS, 8, 5, DFLAGS,
259 RV1108_CLKGATE_CON(8), 3, GFLAGS),
260 GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_pre", 0,
261 RV1108_CLKGATE_CON(19), 0, GFLAGS),
262 GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", 0,
263 RV1108_CLKGATE_CON(19), 1, GFLAGS),
264 GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", 0,
265 RV1108_CLKGATE_CON(19), 2, GFLAGS),
266 GATE(HCLK_VPU, "hclk_vpu", "hclk_rkvdec_pre", 0,
267 RV1108_CLKGATE_CON(19), 3, GFLAGS),
268 GATE(0, "aclk_rkvdec_niu", "aclk_rkvdec_pre", CLK_IGNORE_UNUSED,
269 RV1108_CLKGATE_CON(19), 4, GFLAGS),
270 GATE(0, "hclk_rkvdec_niu", "hclk_rkvdec_pre", CLK_IGNORE_UNUSED,
271 RV1108_CLKGATE_CON(19), 5, GFLAGS),
272 GATE(0, "aclk_vpu_niu", "aclk_vpu_pre", CLK_IGNORE_UNUSED,
273 RV1108_CLKGATE_CON(19), 6, GFLAGS),
202 274
203 /* PD_PMU_wrapper */ 275 /* PD_PMU_wrapper */
204 COMPOSITE_NOMUX(0, "pmu_24m_ena", "gpll", CLK_IGNORE_UNUSED, 276 COMPOSITE_NOMUX(0, "pmu_24m_ena", "gpll", CLK_IGNORE_UNUSED,
205 RV1108_CLKSEL_CON(38), 0, 5, DFLAGS, 277 RV1108_CLKSEL_CON(38), 0, 5, DFLAGS,
206 RV1108_CLKGATE_CON(8), 12, GFLAGS), 278 RV1108_CLKGATE_CON(8), 12, GFLAGS),
207 GATE(0, "pmu", "pmu_24m_ena", CLK_IGNORE_UNUSED, 279 GATE(0, "pclk_pmu", "pmu_24m_ena", CLK_IGNORE_UNUSED,
208 RV1108_CLKGATE_CON(10), 0, GFLAGS), 280 RV1108_CLKGATE_CON(10), 0, GFLAGS),
209 GATE(0, "intmem1", "pmu_24m_ena", CLK_IGNORE_UNUSED, 281 GATE(0, "pclk_intmem1", "pmu_24m_ena", CLK_IGNORE_UNUSED,
210 RV1108_CLKGATE_CON(10), 1, GFLAGS), 282 RV1108_CLKGATE_CON(10), 1, GFLAGS),
211 GATE(0, "gpio0_pmu", "pmu_24m_ena", CLK_IGNORE_UNUSED, 283 GATE(PCLK_GPIO0_PMU, "pclk_gpio0_pmu", "pmu_24m_ena", 0,
212 RV1108_CLKGATE_CON(10), 2, GFLAGS), 284 RV1108_CLKGATE_CON(10), 2, GFLAGS),
213 GATE(0, "pmugrf", "pmu_24m_ena", CLK_IGNORE_UNUSED, 285 GATE(0, "pclk_pmugrf", "pmu_24m_ena", CLK_IGNORE_UNUSED,
214 RV1108_CLKGATE_CON(10), 3, GFLAGS), 286 RV1108_CLKGATE_CON(10), 3, GFLAGS),
215 GATE(0, "pmu_noc", "pmu_24m_ena", CLK_IGNORE_UNUSED, 287 GATE(0, "pclk_pmu_niu", "pmu_24m_ena", CLK_IGNORE_UNUSED,
216 RV1108_CLKGATE_CON(10), 4, GFLAGS), 288 RV1108_CLKGATE_CON(10), 4, GFLAGS),
217 GATE(0, "i2c0_pmu_pclk", "pmu_24m_ena", CLK_IGNORE_UNUSED, 289 GATE(PCLK_I2C0_PMU, "pclk_i2c0_pmu", "pmu_24m_ena", 0,
218 RV1108_CLKGATE_CON(10), 5, GFLAGS), 290 RV1108_CLKGATE_CON(10), 5, GFLAGS),
219 GATE(0, "pwm0_pmu_pclk", "pmu_24m_ena", CLK_IGNORE_UNUSED, 291 GATE(PCLK_PWM0_PMU, "pclk_pwm0_pmu", "pmu_24m_ena", 0,
220 RV1108_CLKGATE_CON(10), 6, GFLAGS), 292 RV1108_CLKGATE_CON(10), 6, GFLAGS),
221 COMPOSITE(0, "pwm0_pmu_clk", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, 293 COMPOSITE(SCLK_PWM0_PMU, "sclk_pwm0_pmu", mux_pll_src_2plls_p, 0,
222 RV1108_CLKSEL_CON(12), 7, 1, MFLAGS, 0, 7, DFLAGS, 294 RV1108_CLKSEL_CON(12), 7, 1, MFLAGS, 0, 7, DFLAGS,
223 RV1108_CLKGATE_CON(8), 15, GFLAGS), 295 RV1108_CLKGATE_CON(8), 15, GFLAGS),
224 COMPOSITE(0, "i2c0_pmu_clk", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, 296 COMPOSITE(SCLK_I2C0_PMU, "sclk_i2c0_pmu", mux_pll_src_2plls_p, 0,
225 RV1108_CLKSEL_CON(19), 7, 1, MFLAGS, 0, 7, DFLAGS, 297 RV1108_CLKSEL_CON(19), 7, 1, MFLAGS, 0, 7, DFLAGS,
226 RV1108_CLKGATE_CON(8), 14, GFLAGS), 298 RV1108_CLKGATE_CON(8), 14, GFLAGS),
227 GATE(0, "pvtm_pmu", "xin24m", CLK_IGNORE_UNUSED, 299 GATE(0, "pvtm_pmu", "xin24m", CLK_IGNORE_UNUSED,
228 RV1108_CLKGATE_CON(8), 13, GFLAGS), 300 RV1108_CLKGATE_CON(8), 13, GFLAGS),
229 301
230 /* 302 /*
303 * Clock-Architecture Diagram 3
304 */
305 COMPOSITE(SCLK_WIFI, "sclk_wifi", mux_wifi_src_p, 0,
306 RV1108_CLKSEL_CON(28), 15, 1, MFLAGS, 8, 6, DFLAGS,
307 RV1108_CLKGATE_CON(9), 8, GFLAGS),
308 COMPOSITE_NODIV(0, "sclk_cifout_src", mux_cifout_src_p, 0,
309 RV1108_CLKSEL_CON(40), 8, 1, MFLAGS,
310 RV1108_CLKGATE_CON(9), 11, GFLAGS),
311 COMPOSITE_NOGATE(SCLK_CIFOUT, "sclk_cifout", mux_cifout_p, 0,
312 RV1108_CLKSEL_CON(40), 12, 1, MFLAGS, 0, 5, DFLAGS),
313 COMPOSITE_NOMUX(SCLK_MIPI_CSI_OUT, "sclk_mipi_csi_out", "xin24m", 0,
314 RV1108_CLKSEL_CON(41), 0, 5, DFLAGS,
315 RV1108_CLKGATE_CON(9), 12, GFLAGS),
316
317 GATE(0, "pclk_acodecphy", "pclk_top_pre", CLK_IGNORE_UNUSED,
318 RV1108_CLKGATE_CON(14), 6, GFLAGS),
319 GATE(0, "pclk_usbgrf", "pclk_top_pre", CLK_IGNORE_UNUSED,
320 RV1108_CLKGATE_CON(14), 14, GFLAGS),
321
322 GATE(ACLK_CIF0, "aclk_cif0", "aclk_vio1_pre", 0,
323 RV1108_CLKGATE_CON(18), 10, GFLAGS),
324 GATE(HCLK_CIF0, "hclk_cif0", "hclk_vio_pre", 0,
325 RV1108_CLKGATE_CON(18), 10, GFLAGS),
326 COMPOSITE_NODIV(SCLK_CIF0, "sclk_cif0", mux_sclk_cif0_src_p, 0,
327 RV1108_CLKSEL_CON(31), 0, 2, MFLAGS,
328 RV1108_CLKGATE_CON(7), 9, GFLAGS),
329 GATE(ACLK_CIF1, "aclk_cif1", "aclk_vio1_pre", 0,
330 RV1108_CLKGATE_CON(17), 6, GFLAGS),
331 GATE(HCLK_CIF1, "hclk_cif1", "hclk_vio_pre", 0,
332 RV1108_CLKGATE_CON(17), 7, GFLAGS),
333 COMPOSITE_NODIV(SCLK_CIF1, "sclk_cif1", mux_sclk_cif1_src_p, 0,
334 RV1108_CLKSEL_CON(31), 2, 2, MFLAGS,
335 RV1108_CLKGATE_CON(7), 10, GFLAGS),
336 GATE(ACLK_CIF2, "aclk_cif2", "aclk_vio1_pre", 0,
337 RV1108_CLKGATE_CON(17), 8, GFLAGS),
338 GATE(HCLK_CIF2, "hclk_cif2", "hclk_vio_pre", 0,
339 RV1108_CLKGATE_CON(17), 9, GFLAGS),
340 COMPOSITE_NODIV(SCLK_CIF2, "sclk_cif2", mux_sclk_cif2_src_p, 0,
341 RV1108_CLKSEL_CON(31), 4, 2, MFLAGS,
342 RV1108_CLKGATE_CON(7), 11, GFLAGS),
343 GATE(ACLK_CIF3, "aclk_cif3", "aclk_vio1_pre", 0,
344 RV1108_CLKGATE_CON(17), 10, GFLAGS),
345 GATE(HCLK_CIF3, "hclk_cif3", "hclk_vio_pre", 0,
346 RV1108_CLKGATE_CON(17), 11, GFLAGS),
347 COMPOSITE_NODIV(SCLK_CIF3, "sclk_cif3", mux_sclk_cif3_src_p, 0,
348 RV1108_CLKSEL_CON(31), 6, 2, MFLAGS,
349 RV1108_CLKGATE_CON(7), 12, GFLAGS),
350 GATE(0, "pclk_cif1to4", "pclk_vip", CLK_IGNORE_UNUSED,
351 RV1108_CLKGATE_CON(7), 8, GFLAGS),
352
353 /* PD_DSP_wrapper */
354 COMPOSITE(SCLK_DSP, "sclk_dsp", mux_dsp_src_p, 0,
355 RV1108_CLKSEL_CON(42), 8, 2, MFLAGS, 0, 5, DFLAGS,
356 RV1108_CLKGATE_CON(9), 0, GFLAGS),
357 GATE(0, "clk_dsp_sys_wd", "sclk_dsp", CLK_IGNORE_UNUSED,
358 RV1108_CLKGATE_CON(16), 0, GFLAGS),
359 GATE(0, "clk_dsp_epp_wd", "sclk_dsp", CLK_IGNORE_UNUSED,
360 RV1108_CLKGATE_CON(16), 1, GFLAGS),
361 GATE(0, "clk_dsp_edp_wd", "sclk_dsp", CLK_IGNORE_UNUSED,
362 RV1108_CLKGATE_CON(16), 2, GFLAGS),
363 GATE(0, "clk_dsp_iop_wd", "sclk_dsp", CLK_IGNORE_UNUSED,
364 RV1108_CLKGATE_CON(16), 3, GFLAGS),
365 GATE(0, "clk_dsp_free", "sclk_dsp", CLK_IGNORE_UNUSED,
366 RV1108_CLKGATE_CON(16), 13, GFLAGS),
367 COMPOSITE_NOMUX(SCLK_DSP_IOP, "sclk_dsp_iop", "sclk_dsp", 0,
368 RV1108_CLKSEL_CON(44), 0, 5, DFLAGS,
369 RV1108_CLKGATE_CON(9), 1, GFLAGS),
370 COMPOSITE_NOMUX(SCLK_DSP_EPP, "sclk_dsp_epp", "sclk_dsp", 0,
371 RV1108_CLKSEL_CON(44), 8, 5, DFLAGS,
372 RV1108_CLKGATE_CON(9), 2, GFLAGS),
373 COMPOSITE_NOMUX(SCLK_DSP_EDP, "sclk_dsp_edp", "sclk_dsp", 0,
374 RV1108_CLKSEL_CON(45), 0, 5, DFLAGS,
375 RV1108_CLKGATE_CON(9), 3, GFLAGS),
376 COMPOSITE_NOMUX(SCLK_DSP_EDAP, "sclk_dsp_edap", "sclk_dsp", 0,
377 RV1108_CLKSEL_CON(45), 8, 5, DFLAGS,
378 RV1108_CLKGATE_CON(9), 4, GFLAGS),
379 GATE(0, "pclk_dsp_iop_niu", "sclk_dsp_iop", CLK_IGNORE_UNUSED,
380 RV1108_CLKGATE_CON(16), 4, GFLAGS),
381 GATE(0, "aclk_dsp_epp_niu", "sclk_dsp_epp", CLK_IGNORE_UNUSED,
382 RV1108_CLKGATE_CON(16), 5, GFLAGS),
383 GATE(0, "aclk_dsp_edp_niu", "sclk_dsp_edp", CLK_IGNORE_UNUSED,
384 RV1108_CLKGATE_CON(16), 6, GFLAGS),
385 GATE(0, "pclk_dsp_dbg_niu", "sclk_dsp", CLK_IGNORE_UNUSED,
386 RV1108_CLKGATE_CON(16), 7, GFLAGS),
387 GATE(0, "aclk_dsp_edap_niu", "sclk_dsp_edap", CLK_IGNORE_UNUSED,
388 RV1108_CLKGATE_CON(16), 14, GFLAGS),
389 COMPOSITE_NOMUX(SCLK_DSP_PFM, "sclk_dsp_pfm", "sclk_dsp", 0,
390 RV1108_CLKSEL_CON(43), 0, 5, DFLAGS,
391 RV1108_CLKGATE_CON(9), 5, GFLAGS),
392 COMPOSITE_NOMUX(PCLK_DSP_CFG, "pclk_dsp_cfg", "sclk_dsp", 0,
393 RV1108_CLKSEL_CON(43), 8, 5, DFLAGS,
394 RV1108_CLKGATE_CON(9), 6, GFLAGS),
395 GATE(0, "pclk_dsp_cfg_niu", "pclk_dsp_cfg", CLK_IGNORE_UNUSED,
396 RV1108_CLKGATE_CON(16), 8, GFLAGS),
397 GATE(0, "pclk_dsp_pfm_mon", "pclk_dsp_cfg", CLK_IGNORE_UNUSED,
398 RV1108_CLKGATE_CON(16), 9, GFLAGS),
399 GATE(0, "pclk_intc", "pclk_dsp_cfg", CLK_IGNORE_UNUSED,
400 RV1108_CLKGATE_CON(16), 10, GFLAGS),
401 GATE(0, "pclk_dsp_grf", "pclk_dsp_cfg", CLK_IGNORE_UNUSED,
402 RV1108_CLKGATE_CON(16), 11, GFLAGS),
403 GATE(0, "pclk_mailbox", "pclk_dsp_cfg", CLK_IGNORE_UNUSED,
404 RV1108_CLKGATE_CON(16), 12, GFLAGS),
405 GATE(0, "aclk_dsp_epp_perf", "sclk_dsp_epp", CLK_IGNORE_UNUSED,
406 RV1108_CLKGATE_CON(16), 15, GFLAGS),
407 GATE(0, "aclk_dsp_edp_perf", "sclk_dsp_edp", CLK_IGNORE_UNUSED,
408 RV1108_CLKGATE_CON(11), 8, GFLAGS),
409
410 /*
231 * Clock-Architecture Diagram 4 411 * Clock-Architecture Diagram 4
232 */ 412 */
233 COMPOSITE(0, "aclk_vio0_2wrap_occ", mux_pll_src_4plls_p, CLK_IGNORE_UNUSED, 413 COMPOSITE(0, "aclk_vio0_pre", mux_pll_src_4plls_p, CLK_IGNORE_UNUSED,
234 RV1108_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS, 414 RV1108_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS,
235 RV1108_CLKGATE_CON(6), 0, GFLAGS), 415 RV1108_CLKGATE_CON(6), 0, GFLAGS),
236 GATE(0, "aclk_vio0_pre", "aclk_vio0_2wrap_occ", CLK_IGNORE_UNUSED, 416 GATE(ACLK_VIO0, "aclk_vio0", "aclk_vio0_pre", 0,
237 RV1108_CLKGATE_CON(17), 0, GFLAGS), 417 RV1108_CLKGATE_CON(17), 0, GFLAGS),
238 COMPOSITE_NOMUX(0, "hclk_vio_pre", "aclk_vio0_pre", 0, 418 COMPOSITE_NOMUX(0, "hclk_vio_pre", "aclk_vio0_pre", 0,
239 RV1108_CLKSEL_CON(29), 0, 5, DFLAGS, 419 RV1108_CLKSEL_CON(29), 0, 5, DFLAGS,
240 RV1108_CLKGATE_CON(7), 2, GFLAGS), 420 RV1108_CLKGATE_CON(7), 2, GFLAGS),
421 GATE(HCLK_VIO, "hclk_vio", "hclk_vio_pre", 0,
422 RV1108_CLKGATE_CON(17), 2, GFLAGS),
241 COMPOSITE_NOMUX(0, "pclk_vio_pre", "aclk_vio0_pre", 0, 423 COMPOSITE_NOMUX(0, "pclk_vio_pre", "aclk_vio0_pre", 0,
242 RV1108_CLKSEL_CON(29), 8, 5, DFLAGS, 424 RV1108_CLKSEL_CON(29), 8, 5, DFLAGS,
243 RV1108_CLKGATE_CON(7), 3, GFLAGS), 425 RV1108_CLKGATE_CON(7), 3, GFLAGS),
426 GATE(PCLK_VIO, "pclk_vio", "pclk_vio_pre", 0,
427 RV1108_CLKGATE_CON(17), 3, GFLAGS),
428 COMPOSITE(0, "aclk_vio1_pre", mux_pll_src_4plls_p, CLK_IGNORE_UNUSED,
429 RV1108_CLKSEL_CON(28), 14, 2, MFLAGS, 8, 5, DFLAGS,
430 RV1108_CLKGATE_CON(6), 1, GFLAGS),
431 GATE(ACLK_VIO1, "aclk_vio1", "aclk_vio1_pre", 0,
432 RV1108_CLKGATE_CON(17), 1, GFLAGS),
244 433
245 INVERTER(0, "pclk_vip", "ext_vip", 434 INVERTER(0, "pclk_vip", "ext_vip",
246 RV1108_CLKSEL_CON(31), 8, IFLAGS), 435 RV1108_CLKSEL_CON(31), 8, IFLAGS),
@@ -252,8 +441,63 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = {
252 RV1108_CLKGATE_CON(6), 5, GFLAGS), 441 RV1108_CLKGATE_CON(6), 5, GFLAGS),
253 GATE(0, "dclk_hdmiphy_src_dpll", "dpll", CLK_IGNORE_UNUSED, 442 GATE(0, "dclk_hdmiphy_src_dpll", "dpll", CLK_IGNORE_UNUSED,
254 RV1108_CLKGATE_CON(6), 4, GFLAGS), 443 RV1108_CLKGATE_CON(6), 4, GFLAGS),
255 COMPOSITE_NOGATE(0, "dclk_hdmiphy", mux_dclk_hdmiphy_pre_p, 0, 444 COMPOSITE_NOGATE(0, "dclk_hdmiphy_pre", mux_dclk_hdmiphy_pre_p, 0,
256 RV1108_CLKSEL_CON(32), 6, 2, MFLAGS, 8, 6, DFLAGS), 445 RV1108_CLKSEL_CON(32), 6, 1, MFLAGS, 8, 6, DFLAGS),
446 COMPOSITE_NOGATE(DCLK_VOP_SRC, "dclk_vop_src", mux_dclk_hdmiphy_pre_p, 0,
447 RV1108_CLKSEL_CON(32), 6, 1, MFLAGS, 0, 6, DFLAGS),
448 MUX(DCLK_HDMIPHY, "dclk_hdmiphy", mux_dclk_hdmiphy_p, CLK_SET_RATE_PARENT,
449 RV1108_CLKSEL_CON(32), 15, 1, MFLAGS),
450 MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, CLK_SET_RATE_PARENT,
451 RV1108_CLKSEL_CON(32), 7, 1, MFLAGS),
452 GATE(ACLK_VOP, "aclk_vop", "aclk_vio0_pre", 0,
453 RV1108_CLKGATE_CON(18), 0, GFLAGS),
454 GATE(HCLK_VOP, "hclk_vop", "hclk_vio_pre", 0,
455 RV1108_CLKGATE_CON(18), 1, GFLAGS),
456 GATE(ACLK_IEP, "aclk_iep", "aclk_vio0_pre", 0,
457 RV1108_CLKGATE_CON(18), 2, GFLAGS),
458 GATE(HCLK_IEP, "hclk_iep", "hclk_vio_pre", 0,
459 RV1108_CLKGATE_CON(18), 3, GFLAGS),
460
461 GATE(ACLK_RGA, "aclk_rga", "aclk_vio1_pre", 0,
462 RV1108_CLKGATE_CON(18), 4, GFLAGS),
463 GATE(HCLK_RGA, "hclk_rga", "hclk_vio_pre", 0,
464 RV1108_CLKGATE_CON(18), 5, GFLAGS),
465 COMPOSITE(SCLK_RGA, "sclk_rga", mux_pll_src_4plls_p, 0,
466 RV1108_CLKSEL_CON(33), 6, 2, MFLAGS, 0, 5, DFLAGS,
467 RV1108_CLKGATE_CON(6), 6, GFLAGS),
468
469 COMPOSITE(SCLK_CVBS_HOST, "sclk_cvbs_host", mux_cvbs_src_p, 0,
470 RV1108_CLKSEL_CON(33), 13, 2, MFLAGS, 8, 5, DFLAGS,
471 RV1108_CLKGATE_CON(6), 7, GFLAGS),
472 FACTOR(0, "sclk_cvbs_27m", "sclk_cvbs_host", 0, 1, 2),
473
474 GATE(SCLK_HDMI_SFR, "sclk_hdmi_sfr", "xin24m", 0,
475 RV1108_CLKGATE_CON(6), 8, GFLAGS),
476
477 COMPOSITE(SCLK_HDMI_CEC, "sclk_hdmi_cec", mux_hdmi_cec_src_p, 0,
478 RV1108_CLKSEL_CON(34), 14, 2, MFLAGS, 0, 14, DFLAGS,
479 RV1108_CLKGATE_CON(6), 9, GFLAGS),
480 GATE(PCLK_MIPI_DSI, "pclk_mipi_dsi", "pclk_vio_pre", 0,
481 RV1108_CLKGATE_CON(18), 8, GFLAGS),
482 GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "pclk_vio_pre", 0,
483 RV1108_CLKGATE_CON(18), 9, GFLAGS),
484
485 GATE(ACLK_ISP, "aclk_isp", "aclk_vio1_pre", 0,
486 RV1108_CLKGATE_CON(18), 12, GFLAGS),
487 GATE(HCLK_ISP, "hclk_isp", "hclk_vio_pre", 0,
488 RV1108_CLKGATE_CON(18), 11, GFLAGS),
489 COMPOSITE(SCLK_ISP, "sclk_isp", mux_pll_src_4plls_p, 0,
490 RV1108_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS,
491 RV1108_CLKGATE_CON(6), 3, GFLAGS),
492
493 GATE(0, "clk_dsiphy24m", "xin24m", CLK_IGNORE_UNUSED,
494 RV1108_CLKGATE_CON(9), 10, GFLAGS),
495 GATE(0, "pclk_vdacphy", "pclk_top_pre", CLK_IGNORE_UNUSED,
496 RV1108_CLKGATE_CON(14), 9, GFLAGS),
497 GATE(0, "pclk_mipi_dsiphy", "pclk_top_pre", CLK_IGNORE_UNUSED,
498 RV1108_CLKGATE_CON(14), 11, GFLAGS),
499 GATE(0, "pclk_mipi_csiphy", "pclk_top_pre", CLK_IGNORE_UNUSED,
500 RV1108_CLKGATE_CON(14), 12, GFLAGS),
257 501
258 /* 502 /*
259 * Clock-Architecture Diagram 5 503 * Clock-Architecture Diagram 5
@@ -261,10 +505,11 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = {
261 505
262 FACTOR(0, "xin12m", "xin24m", 0, 1, 2), 506 FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
263 507
264 COMPOSITE(0, "i2s0_src", mux_pll_src_2plls_p, 0, 508
509 COMPOSITE(SCLK_I2S0_SRC, "i2s0_src", mux_pll_src_2plls_p, 0,
265 RV1108_CLKSEL_CON(5), 8, 1, MFLAGS, 0, 7, DFLAGS, 510 RV1108_CLKSEL_CON(5), 8, 1, MFLAGS, 0, 7, DFLAGS,
266 RV1108_CLKGATE_CON(2), 0, GFLAGS), 511 RV1108_CLKGATE_CON(2), 0, GFLAGS),
267 COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_src", CLK_SET_RATE_PARENT, 512 COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_src", CLK_SET_RATE_PARENT,
268 RV1108_CLKSEL_CON(8), 0, 513 RV1108_CLKSEL_CON(8), 0,
269 RV1108_CLKGATE_CON(2), 1, GFLAGS, 514 RV1108_CLKGATE_CON(2), 1, GFLAGS,
270 &rv1108_i2s0_fracmux), 515 &rv1108_i2s0_fracmux),
@@ -274,7 +519,7 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = {
274 RV1108_CLKSEL_CON(5), 15, 1, MFLAGS, 519 RV1108_CLKSEL_CON(5), 15, 1, MFLAGS,
275 RV1108_CLKGATE_CON(2), 3, GFLAGS), 520 RV1108_CLKGATE_CON(2), 3, GFLAGS),
276 521
277 COMPOSITE(0, "i2s1_src", mux_pll_src_2plls_p, 0, 522 COMPOSITE(SCLK_I2S1_SRC, "i2s1_src", mux_pll_src_2plls_p, 0,
278 RV1108_CLKSEL_CON(6), 8, 1, MFLAGS, 0, 7, DFLAGS, 523 RV1108_CLKSEL_CON(6), 8, 1, MFLAGS, 0, 7, DFLAGS,
279 RV1108_CLKGATE_CON(2), 4, GFLAGS), 524 RV1108_CLKGATE_CON(2), 4, GFLAGS),
280 COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_src", CLK_SET_RATE_PARENT, 525 COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_src", CLK_SET_RATE_PARENT,
@@ -284,7 +529,7 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = {
284 GATE(SCLK_I2S1, "sclk_i2s1", "i2s1_pre", CLK_SET_RATE_PARENT, 529 GATE(SCLK_I2S1, "sclk_i2s1", "i2s1_pre", CLK_SET_RATE_PARENT,
285 RV1108_CLKGATE_CON(2), 6, GFLAGS), 530 RV1108_CLKGATE_CON(2), 6, GFLAGS),
286 531
287 COMPOSITE(0, "i2s2_src", mux_pll_src_2plls_p, 0, 532 COMPOSITE(SCLK_I2S2_SRC, "i2s2_src", mux_pll_src_2plls_p, 0,
288 RV1108_CLKSEL_CON(7), 8, 1, MFLAGS, 0, 7, DFLAGS, 533 RV1108_CLKSEL_CON(7), 8, 1, MFLAGS, 0, 7, DFLAGS,
289 RV1108_CLKGATE_CON(3), 8, GFLAGS), 534 RV1108_CLKGATE_CON(3), 8, GFLAGS),
290 COMPOSITE_FRACMUX(0, "i2s2_frac", "i2s2_src", CLK_SET_RATE_PARENT, 535 COMPOSITE_FRACMUX(0, "i2s2_frac", "i2s2_src", CLK_SET_RATE_PARENT,
@@ -303,32 +548,53 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = {
303 RV1108_CLKGATE_CON(1), 2, GFLAGS), 548 RV1108_CLKGATE_CON(1), 2, GFLAGS),
304 COMPOSITE_NOGATE(ACLK_PRE, "aclk_bus_pre", mux_aclk_bus_src_p, 0, 549 COMPOSITE_NOGATE(ACLK_PRE, "aclk_bus_pre", mux_aclk_bus_src_p, 0,
305 RV1108_CLKSEL_CON(2), 8, 2, MFLAGS, 0, 5, DFLAGS), 550 RV1108_CLKSEL_CON(2), 8, 2, MFLAGS, 0, 5, DFLAGS),
306 COMPOSITE_NOMUX(0, "hclk_bus_pre", "aclk_bus_2wrap_occ", 0, 551 COMPOSITE_NOMUX(HCLK_BUS, "hclk_bus_pre", "aclk_bus_pre", 0,
307 RV1108_CLKSEL_CON(3), 0, 5, DFLAGS, 552 RV1108_CLKSEL_CON(3), 0, 5, DFLAGS,
308 RV1108_CLKGATE_CON(1), 4, GFLAGS), 553 RV1108_CLKGATE_CON(1), 4, GFLAGS),
309 COMPOSITE_NOMUX(0, "pclken_bus", "aclk_bus_2wrap_occ", 0, 554 COMPOSITE_NOMUX(0, "pclk_bus_pre", "aclk_bus_pre", 0,
310 RV1108_CLKSEL_CON(3), 8, 5, DFLAGS, 555 RV1108_CLKSEL_CON(3), 8, 5, DFLAGS,
311 RV1108_CLKGATE_CON(1), 5, GFLAGS), 556 RV1108_CLKGATE_CON(1), 5, GFLAGS),
312 GATE(0, "pclk_bus_pre", "pclken_bus", CLK_IGNORE_UNUSED, 557 GATE(PCLK_BUS, "pclk_bus", "pclk_bus_pre", 0,
313 RV1108_CLKGATE_CON(1), 6, GFLAGS), 558 RV1108_CLKGATE_CON(1), 6, GFLAGS),
314 GATE(0, "pclk_top_pre", "pclken_bus", CLK_IGNORE_UNUSED, 559 GATE(0, "pclk_top_pre", "pclk_bus_pre", CLK_IGNORE_UNUSED,
315 RV1108_CLKGATE_CON(1), 7, GFLAGS), 560 RV1108_CLKGATE_CON(1), 7, GFLAGS),
316 GATE(0, "pclk_ddr_pre", "pclken_bus", CLK_IGNORE_UNUSED, 561 GATE(0, "pclk_ddr_pre", "pclk_bus_pre", CLK_IGNORE_UNUSED,
317 RV1108_CLKGATE_CON(1), 8, GFLAGS), 562 RV1108_CLKGATE_CON(1), 8, GFLAGS),
318 GATE(0, "clk_timer0", "mux_pll_p", CLK_IGNORE_UNUSED, 563 GATE(SCLK_TIMER0, "clk_timer0", "xin24m", 0,
319 RV1108_CLKGATE_CON(1), 9, GFLAGS), 564 RV1108_CLKGATE_CON(1), 9, GFLAGS),
320 GATE(0, "clk_timer1", "mux_pll_p", CLK_IGNORE_UNUSED, 565 GATE(SCLK_TIMER1, "clk_timer1", "xin24m", CLK_IGNORE_UNUSED,
321 RV1108_CLKGATE_CON(1), 10, GFLAGS), 566 RV1108_CLKGATE_CON(1), 10, GFLAGS),
322 GATE(0, "pclk_timer", "pclk_bus_pre", CLK_IGNORE_UNUSED, 567 GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_pre", CLK_IGNORE_UNUSED,
323 RV1108_CLKGATE_CON(13), 4, GFLAGS), 568 RV1108_CLKGATE_CON(13), 4, GFLAGS),
324 569
325 COMPOSITE(0, "uart0_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, 570 GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_bus_pre", 0,
571 RV1108_CLKGATE_CON(12), 7, GFLAGS),
572 GATE(HCLK_I2S1_2CH, "hclk_i2s1_2ch", "hclk_bus_pre", 0,
573 RV1108_CLKGATE_CON(12), 8, GFLAGS),
574 GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_bus_pre", 0,
575 RV1108_CLKGATE_CON(12), 9, GFLAGS),
576
577 GATE(HCLK_CRYPTO_MST, "hclk_crypto_mst", "hclk_bus_pre", 0,
578 RV1108_CLKGATE_CON(12), 10, GFLAGS),
579 GATE(HCLK_CRYPTO_SLV, "hclk_crypto_slv", "hclk_bus_pre", 0,
580 RV1108_CLKGATE_CON(12), 11, GFLAGS),
581 COMPOSITE(SCLK_CRYPTO, "sclk_crypto", mux_pll_src_2plls_p, 0,
582 RV1108_CLKSEL_CON(11), 7, 1, MFLAGS, 0, 5, DFLAGS,
583 RV1108_CLKGATE_CON(2), 12, GFLAGS),
584
585 COMPOSITE(SCLK_SPI, "sclk_spi", mux_pll_src_2plls_p, 0,
586 RV1108_CLKSEL_CON(11), 15, 1, MFLAGS, 8, 5, DFLAGS,
587 RV1108_CLKGATE_CON(3), 0, GFLAGS),
588 GATE(PCLK_SPI, "pclk_spi", "pclk_bus_pre", 0,
589 RV1108_CLKGATE_CON(13), 5, GFLAGS),
590
591 COMPOSITE(SCLK_UART0_SRC, "uart0_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
326 RV1108_CLKSEL_CON(13), 12, 2, MFLAGS, 0, 7, DFLAGS, 592 RV1108_CLKSEL_CON(13), 12, 2, MFLAGS, 0, 7, DFLAGS,
327 RV1108_CLKGATE_CON(3), 1, GFLAGS), 593 RV1108_CLKGATE_CON(3), 1, GFLAGS),
328 COMPOSITE(0, "uart1_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, 594 COMPOSITE(SCLK_UART1_SRC, "uart1_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
329 RV1108_CLKSEL_CON(14), 12, 2, MFLAGS, 0, 7, DFLAGS, 595 RV1108_CLKSEL_CON(14), 12, 2, MFLAGS, 0, 7, DFLAGS,
330 RV1108_CLKGATE_CON(3), 3, GFLAGS), 596 RV1108_CLKGATE_CON(3), 3, GFLAGS),
331 COMPOSITE(0, "uart21_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, 597 COMPOSITE(SCLK_UART2_SRC, "uart2_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
332 RV1108_CLKSEL_CON(15), 12, 2, MFLAGS, 0, 7, DFLAGS, 598 RV1108_CLKSEL_CON(15), 12, 2, MFLAGS, 0, 7, DFLAGS,
333 RV1108_CLKGATE_CON(3), 5, GFLAGS), 599 RV1108_CLKGATE_CON(3), 5, GFLAGS),
334 600
@@ -344,44 +610,58 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = {
344 RV1108_CLKSEL_CON(18), 0, 610 RV1108_CLKSEL_CON(18), 0,
345 RV1108_CLKGATE_CON(3), 6, GFLAGS, 611 RV1108_CLKGATE_CON(3), 6, GFLAGS,
346 &rv1108_uart2_fracmux), 612 &rv1108_uart2_fracmux),
347 GATE(PCLK_UART0, "pclk_uart0", "pclk_bus_pre", CLK_IGNORE_UNUSED, 613 GATE(PCLK_UART0, "pclk_uart0", "pclk_bus_pre", 0,
348 RV1108_CLKGATE_CON(13), 10, GFLAGS), 614 RV1108_CLKGATE_CON(13), 10, GFLAGS),
349 GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_pre", CLK_IGNORE_UNUSED, 615 GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_pre", 0,
350 RV1108_CLKGATE_CON(13), 11, GFLAGS), 616 RV1108_CLKGATE_CON(13), 11, GFLAGS),
351 GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_pre", CLK_IGNORE_UNUSED, 617 GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_pre", 0,
352 RV1108_CLKGATE_CON(13), 12, GFLAGS), 618 RV1108_CLKGATE_CON(13), 12, GFLAGS),
353 619
354 COMPOSITE(0, "clk_i2c1", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, 620 COMPOSITE(SCLK_I2C1, "clk_i2c1", mux_pll_src_2plls_p, 0,
355 RV1108_CLKSEL_CON(19), 15, 2, MFLAGS, 8, 7, DFLAGS, 621 RV1108_CLKSEL_CON(19), 15, 1, MFLAGS, 8, 7, DFLAGS,
356 RV1108_CLKGATE_CON(3), 7, GFLAGS), 622 RV1108_CLKGATE_CON(3), 7, GFLAGS),
357 COMPOSITE(0, "clk_i2c2", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, 623 COMPOSITE(SCLK_I2C2, "clk_i2c2", mux_pll_src_2plls_p, 0,
358 RV1108_CLKSEL_CON(20), 7, 2, MFLAGS, 0, 7, DFLAGS, 624 RV1108_CLKSEL_CON(20), 7, 1, MFLAGS, 0, 7, DFLAGS,
359 RV1108_CLKGATE_CON(3), 8, GFLAGS), 625 RV1108_CLKGATE_CON(3), 8, GFLAGS),
360 COMPOSITE(0, "clk_i2c3", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, 626 COMPOSITE(SCLK_I2C3, "clk_i2c3", mux_pll_src_2plls_p, 0,
361 RV1108_CLKSEL_CON(20), 15, 2, MFLAGS, 8, 7, DFLAGS, 627 RV1108_CLKSEL_CON(20), 15, 1, MFLAGS, 8, 7, DFLAGS,
362 RV1108_CLKGATE_CON(3), 9, GFLAGS), 628 RV1108_CLKGATE_CON(3), 9, GFLAGS),
363 GATE(0, "pclk_i2c1", "pclk_bus_pre", CLK_IGNORE_UNUSED, 629 GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus_pre", 0,
364 RV1108_CLKGATE_CON(13), 0, GFLAGS), 630 RV1108_CLKGATE_CON(13), 0, GFLAGS),
365 GATE(0, "pclk_i2c2", "pclk_bus_pre", CLK_IGNORE_UNUSED, 631 GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus_pre", 0,
366 RV1108_CLKGATE_CON(13), 1, GFLAGS), 632 RV1108_CLKGATE_CON(13), 1, GFLAGS),
367 GATE(0, "pclk_i2c3", "pclk_bus_pre", CLK_IGNORE_UNUSED, 633 GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus_pre", 0,
368 RV1108_CLKGATE_CON(13), 2, GFLAGS), 634 RV1108_CLKGATE_CON(13), 2, GFLAGS),
369 COMPOSITE(0, "clk_pwm1", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, 635 COMPOSITE(SCLK_PWM, "clk_pwm", mux_pll_src_2plls_p, 0,
370 RV1108_CLKSEL_CON(12), 15, 2, MFLAGS, 8, 7, DFLAGS, 636 RV1108_CLKSEL_CON(12), 15, 2, MFLAGS, 8, 7, DFLAGS,
371 RV1108_CLKGATE_CON(3), 10, GFLAGS), 637 RV1108_CLKGATE_CON(3), 10, GFLAGS),
372 GATE(0, "pclk_pwm1", "pclk_bus_pre", CLK_IGNORE_UNUSED, 638 GATE(PCLK_PWM, "pclk_pwm", "pclk_bus_pre", 0,
373 RV1108_CLKGATE_CON(13), 6, GFLAGS), 639 RV1108_CLKGATE_CON(13), 6, GFLAGS),
374 GATE(0, "pclk_wdt", "pclk_bus_pre", CLK_IGNORE_UNUSED, 640 GATE(PCLK_WDT, "pclk_wdt", "pclk_bus_pre", 0,
375 RV1108_CLKGATE_CON(13), 3, GFLAGS), 641 RV1108_CLKGATE_CON(13), 3, GFLAGS),
376 GATE(0, "pclk_gpio1", "pclk_bus_pre", CLK_IGNORE_UNUSED, 642 GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus_pre", 0,
377 RV1108_CLKGATE_CON(13), 7, GFLAGS), 643 RV1108_CLKGATE_CON(13), 7, GFLAGS),
378 GATE(0, "pclk_gpio2", "pclk_bus_pre", CLK_IGNORE_UNUSED, 644 GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus_pre", 0,
379 RV1108_CLKGATE_CON(13), 8, GFLAGS), 645 RV1108_CLKGATE_CON(13), 8, GFLAGS),
380 GATE(0, "pclk_gpio3", "pclk_bus_pre", CLK_IGNORE_UNUSED, 646 GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus_pre", 0,
381 RV1108_CLKGATE_CON(13), 9, GFLAGS), 647 RV1108_CLKGATE_CON(13), 9, GFLAGS),
382 648
383 GATE(0, "pclk_grf", "pclk_bus_pre", CLK_IGNORE_UNUSED, 649 GATE(0, "pclk_grf", "pclk_bus_pre", CLK_IGNORE_UNUSED,
384 RV1108_CLKGATE_CON(14), 0, GFLAGS), 650 RV1108_CLKGATE_CON(14), 0, GFLAGS),
651 GATE(PCLK_EFUSE0, "pclk_efuse0", "pclk_bus_pre", 0,
652 RV1108_CLKGATE_CON(12), 12, GFLAGS),
653 GATE(PCLK_EFUSE1, "pclk_efuse1", "pclk_bus_pre", 0,
654 RV1108_CLKGATE_CON(12), 13, GFLAGS),
655 GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus_pre", 0,
656 RV1108_CLKGATE_CON(13), 13, GFLAGS),
657 COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin24m", 0,
658 RV1108_CLKSEL_CON(21), 0, 10, DFLAGS,
659 RV1108_CLKGATE_CON(3), 11, GFLAGS),
660 GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus_pre", 0,
661 RV1108_CLKGATE_CON(13), 14, GFLAGS),
662 COMPOSITE_NOMUX(SCLK_SARADC, "sclk_saradc", "xin24m", 0,
663 RV1108_CLKSEL_CON(22), 0, 10, DFLAGS,
664 RV1108_CLKGATE_CON(3), 12, GFLAGS),
385 665
386 GATE(ACLK_DMAC, "aclk_dmac", "aclk_bus_pre", 0, 666 GATE(ACLK_DMAC, "aclk_dmac", "aclk_bus_pre", 0,
387 RV1108_CLKGATE_CON(12), 2, GFLAGS), 667 RV1108_CLKGATE_CON(12), 2, GFLAGS),
@@ -397,18 +677,24 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = {
397 RV1108_CLKGATE_CON(0), 9, GFLAGS), 677 RV1108_CLKGATE_CON(0), 9, GFLAGS),
398 GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED, 678 GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED,
399 RV1108_CLKGATE_CON(0), 10, GFLAGS), 679 RV1108_CLKGATE_CON(0), 10, GFLAGS),
400 COMPOSITE(0, "ddrphy4x", mux_ddrphy_p, CLK_IGNORE_UNUSED, 680 COMPOSITE_NOGATE(0, "clk_ddrphy_src", mux_ddrphy_p, CLK_IGNORE_UNUSED,
401 RV1108_CLKSEL_CON(4), 8, 2, MFLAGS, 0, 3, 681 RV1108_CLKSEL_CON(4), 8, 2, MFLAGS, 0, 3,
402 DFLAGS | CLK_DIVIDER_POWER_OF_TWO, 682 DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
683 FACTOR(0, "clk_ddr", "clk_ddrphy_src", 0, 1, 2),
684 GATE(0, "clk_ddrphy4x", "clk_ddr", CLK_IGNORE_UNUSED,
403 RV1108_CLKGATE_CON(10), 9, GFLAGS), 685 RV1108_CLKGATE_CON(10), 9, GFLAGS),
404 GATE(0, "ddrupctl", "ddrphy_pre", CLK_IGNORE_UNUSED, 686 GATE(0, "pclk_ddrupctl", "pclk_ddr_pre", CLK_IGNORE_UNUSED,
405 RV1108_CLKGATE_CON(12), 4, GFLAGS), 687 RV1108_CLKGATE_CON(12), 4, GFLAGS),
406 GATE(0, "ddrc", "ddrphy", CLK_IGNORE_UNUSED, 688 GATE(0, "nclk_ddrupctl", "clk_ddr", CLK_IGNORE_UNUSED,
407 RV1108_CLKGATE_CON(12), 5, GFLAGS), 689 RV1108_CLKGATE_CON(12), 5, GFLAGS),
408 GATE(0, "ddrmon", "ddrphy_pre", CLK_IGNORE_UNUSED, 690 GATE(0, "pclk_ddrmon", "pclk_ddr_pre", CLK_IGNORE_UNUSED,
409 RV1108_CLKGATE_CON(12), 6, GFLAGS), 691 RV1108_CLKGATE_CON(12), 6, GFLAGS),
410 GATE(0, "timer_clk", "xin24m", CLK_IGNORE_UNUSED, 692 GATE(0, "timer_clk", "xin24m", CLK_IGNORE_UNUSED,
411 RV1108_CLKGATE_CON(0), 11, GFLAGS), 693 RV1108_CLKGATE_CON(0), 11, GFLAGS),
694 GATE(0, "pclk_mschniu", "pclk_ddr_pre", CLK_IGNORE_UNUSED,
695 RV1108_CLKGATE_CON(14), 2, GFLAGS),
696 GATE(0, "pclk_ddrphy", "pclk_ddr_pre", CLK_IGNORE_UNUSED,
697 RV1108_CLKGATE_CON(14), 4, GFLAGS),
412 698
413 /* 699 /*
414 * Clock-Architecture Diagram 6 700 * Clock-Architecture Diagram 6
@@ -418,23 +704,23 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = {
418 COMPOSITE_NOMUX(0, "pclk_periph_pre", "gpll", 0, 704 COMPOSITE_NOMUX(0, "pclk_periph_pre", "gpll", 0,
419 RV1108_CLKSEL_CON(23), 10, 5, DFLAGS, 705 RV1108_CLKSEL_CON(23), 10, 5, DFLAGS,
420 RV1108_CLKGATE_CON(4), 5, GFLAGS), 706 RV1108_CLKGATE_CON(4), 5, GFLAGS),
421 GATE(0, "pclk_periph", "pclk_periph_pre", CLK_IGNORE_UNUSED, 707 GATE(PCLK_PERI, "pclk_periph", "pclk_periph_pre", CLK_IGNORE_UNUSED,
422 RV1108_CLKGATE_CON(15), 13, GFLAGS), 708 RV1108_CLKGATE_CON(15), 13, GFLAGS),
423 COMPOSITE_NOMUX(0, "hclk_periph_pre", "gpll", 0, 709 COMPOSITE_NOMUX(0, "hclk_periph_pre", "gpll", 0,
424 RV1108_CLKSEL_CON(23), 5, 5, DFLAGS, 710 RV1108_CLKSEL_CON(23), 5, 5, DFLAGS,
425 RV1108_CLKGATE_CON(4), 4, GFLAGS), 711 RV1108_CLKGATE_CON(4), 4, GFLAGS),
426 GATE(0, "hclk_periph", "hclk_periph_pre", CLK_IGNORE_UNUSED, 712 GATE(HCLK_PERI, "hclk_periph", "hclk_periph_pre", CLK_IGNORE_UNUSED,
427 RV1108_CLKGATE_CON(15), 12, GFLAGS), 713 RV1108_CLKGATE_CON(15), 12, GFLAGS),
428 714
429 GATE(0, "aclk_peri_src_dpll", "dpll", CLK_IGNORE_UNUSED, 715 GATE(0, "aclk_peri_src_dpll", "dpll", CLK_IGNORE_UNUSED,
430 RV1108_CLKGATE_CON(4), 1, GFLAGS), 716 RV1108_CLKGATE_CON(4), 1, GFLAGS),
431 GATE(0, "aclk_peri_src_gpll", "gpll", CLK_IGNORE_UNUSED, 717 GATE(0, "aclk_peri_src_gpll", "gpll", CLK_IGNORE_UNUSED,
432 RV1108_CLKGATE_CON(4), 2, GFLAGS), 718 RV1108_CLKGATE_CON(4), 2, GFLAGS),
433 COMPOSITE(0, "aclk_periph", mux_aclk_peri_src_p, CLK_IGNORE_UNUSED, 719 COMPOSITE(ACLK_PERI, "aclk_periph", mux_aclk_peri_src_p, 0,
434 RV1108_CLKSEL_CON(23), 15, 2, MFLAGS, 0, 5, DFLAGS, 720 RV1108_CLKSEL_CON(23), 15, 1, MFLAGS, 0, 5, DFLAGS,
435 RV1108_CLKGATE_CON(15), 11, GFLAGS), 721 RV1108_CLKGATE_CON(15), 11, GFLAGS),
436 722
437 COMPOSITE(SCLK_SDMMC, "sclk_sdmmc0", mux_mmc_src_p, 0, 723 COMPOSITE(SCLK_SDMMC, "sclk_sdmmc", mux_mmc_src_p, 0,
438 RV1108_CLKSEL_CON(25), 8, 2, MFLAGS, 0, 8, DFLAGS, 724 RV1108_CLKSEL_CON(25), 8, 2, MFLAGS, 0, 8, DFLAGS,
439 RV1108_CLKGATE_CON(5), 0, GFLAGS), 725 RV1108_CLKGATE_CON(5), 0, GFLAGS),
440 726
@@ -454,23 +740,31 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = {
454 GATE(HCLK_EMMC, "hclk_emmc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 2, GFLAGS), 740 GATE(HCLK_EMMC, "hclk_emmc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 2, GFLAGS),
455 741
456 COMPOSITE(SCLK_NANDC, "sclk_nandc", mux_pll_src_2plls_p, 0, 742 COMPOSITE(SCLK_NANDC, "sclk_nandc", mux_pll_src_2plls_p, 0,
457 RV1108_CLKSEL_CON(27), 14, 2, MFLAGS, 8, 5, DFLAGS, 743 RV1108_CLKSEL_CON(27), 14, 1, MFLAGS, 8, 5, DFLAGS,
458 RV1108_CLKGATE_CON(5), 3, GFLAGS), 744 RV1108_CLKGATE_CON(5), 3, GFLAGS),
459 GATE(HCLK_NANDC, "hclk_nandc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 3, GFLAGS), 745 GATE(HCLK_NANDC, "hclk_nandc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 3, GFLAGS),
460 746
747 GATE(HCLK_HOST0, "hclk_host0", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 6, GFLAGS),
748 GATE(0, "hclk_host0_arb", "hclk_periph", CLK_IGNORE_UNUSED, RV1108_CLKGATE_CON(15), 7, GFLAGS),
749 GATE(HCLK_OTG, "hclk_otg", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 8, GFLAGS),
750 GATE(0, "hclk_otg_pmu", "hclk_periph", CLK_IGNORE_UNUSED, RV1108_CLKGATE_CON(15), 9, GFLAGS),
751 GATE(SCLK_USBPHY, "clk_usbphy", "xin24m", CLK_IGNORE_UNUSED, RV1108_CLKGATE_CON(5), 5, GFLAGS),
752
461 COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_2plls_p, 0, 753 COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_2plls_p, 0,
462 RV1108_CLKSEL_CON(27), 7, 2, MFLAGS, 0, 7, DFLAGS, 754 RV1108_CLKSEL_CON(27), 7, 1, MFLAGS, 0, 7, DFLAGS,
463 RV1108_CLKGATE_CON(5), 4, GFLAGS), 755 RV1108_CLKGATE_CON(5), 4, GFLAGS),
464 GATE(HCLK_SFC, "hclk_sfc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 10, GFLAGS), 756 GATE(HCLK_SFC, "hclk_sfc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 10, GFLAGS),
465 757
466 COMPOSITE(0, "sclk_macphy_pre", mux_pll_src_apll_gpll_p, 0, 758 COMPOSITE(SCLK_MAC_PRE, "sclk_mac_pre", mux_pll_src_apll_gpll_p, 0,
467 RV1108_CLKSEL_CON(24), 12, 2, MFLAGS, 0, 5, DFLAGS, 759 RV1108_CLKSEL_CON(24), 12, 1, MFLAGS, 0, 5, DFLAGS,
468 RV1108_CLKGATE_CON(4), 10, GFLAGS), 760 RV1108_CLKGATE_CON(4), 10, GFLAGS),
469 MUX(0, "sclk_macphy", mux_sclk_macphy_p, CLK_SET_RATE_PARENT, 761 MUX(SCLK_MAC, "sclk_mac", mux_sclk_mac_p, CLK_SET_RATE_PARENT,
470 RV1108_CLKSEL_CON(24), 8, 2, MFLAGS), 762 RV1108_CLKSEL_CON(24), 8, 1, MFLAGS),
471 GATE(0, "sclk_macphy_rx", "sclk_macphy", 0, RV1108_CLKGATE_CON(4), 8, GFLAGS), 763 GATE(SCLK_MAC_RX, "sclk_mac_rx", "sclk_mac", 0, RV1108_CLKGATE_CON(4), 8, GFLAGS),
472 GATE(0, "sclk_mac_ref", "sclk_macphy", 0, RV1108_CLKGATE_CON(4), 6, GFLAGS), 764 GATE(SCLK_MAC_REF, "sclk_mac_ref", "sclk_mac", 0, RV1108_CLKGATE_CON(4), 6, GFLAGS),
473 GATE(0, "sclk_mac_refout", "sclk_macphy", 0, RV1108_CLKGATE_CON(4), 7, GFLAGS), 765 GATE(SCLK_MAC_REFOUT, "sclk_mac_refout", "sclk_mac", 0, RV1108_CLKGATE_CON(4), 7, GFLAGS),
766 GATE(ACLK_GMAC, "aclk_gmac", "aclk_periph", 0, RV1108_CLKGATE_CON(15), 4, GFLAGS),
767 GATE(PCLK_GMAC, "pclk_gmac", "pclk_periph", 0, RV1108_CLKGATE_CON(15), 5, GFLAGS),
474 768
475 MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RV1108_SDMMC_CON0, 1), 769 MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RV1108_SDMMC_CON0, 1),
476 MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RV1108_SDMMC_CON1, 1), 770 MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RV1108_SDMMC_CON1, 1),
@@ -484,10 +778,16 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = {
484 778
485static const char *const rv1108_critical_clocks[] __initconst = { 779static const char *const rv1108_critical_clocks[] __initconst = {
486 "aclk_core", 780 "aclk_core",
487 "aclk_bus_src_gpll", 781 "aclk_bus",
782 "hclk_bus",
783 "pclk_bus",
488 "aclk_periph", 784 "aclk_periph",
489 "hclk_periph", 785 "hclk_periph",
490 "pclk_periph", 786 "pclk_periph",
787 "nclk_ddrupctl",
788 "pclk_ddrmon",
789 "pclk_acodecphy",
790 "pclk_pmu",
491}; 791};
492 792
493static void __init rv1108_clk_init(struct device_node *np) 793static void __init rv1108_clk_init(struct device_node *np)
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index fe1d393cf678..35dbd63c2f49 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -29,6 +29,7 @@
29#include <linux/mfd/syscon.h> 29#include <linux/mfd/syscon.h>
30#include <linux/regmap.h> 30#include <linux/regmap.h>
31#include <linux/reboot.h> 31#include <linux/reboot.h>
32#include <linux/rational.h>
32#include "clk.h" 33#include "clk.h"
33 34
34/** 35/**
@@ -164,6 +165,40 @@ static int rockchip_clk_frac_notifier_cb(struct notifier_block *nb,
164 return notifier_from_errno(ret); 165 return notifier_from_errno(ret);
165} 166}
166 167
168/**
169 * fractional divider must set that denominator is 20 times larger than
170 * numerator to generate precise clock frequency.
171 */
172static void rockchip_fractional_approximation(struct clk_hw *hw,
173 unsigned long rate, unsigned long *parent_rate,
174 unsigned long *m, unsigned long *n)
175{
176 struct clk_fractional_divider *fd = to_clk_fd(hw);
177 unsigned long p_rate, p_parent_rate;
178 struct clk_hw *p_parent;
179 unsigned long scale;
180
181 p_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
182 if ((rate * 20 > p_rate) && (p_rate % rate != 0)) {
183 p_parent = clk_hw_get_parent(clk_hw_get_parent(hw));
184 p_parent_rate = clk_hw_get_rate(p_parent);
185 *parent_rate = p_parent_rate;
186 }
187
188 /*
189 * Get rate closer to *parent_rate to guarantee there is no overflow
190 * for m and n. In the result it will be the nearest rate left shifted
191 * by (scale - fd->nwidth) bits.
192 */
193 scale = fls_long(*parent_rate / rate - 1);
194 if (scale > fd->nwidth)
195 rate <<= scale - fd->nwidth;
196
197 rational_best_approximation(rate, *parent_rate,
198 GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
199 m, n);
200}
201
167static struct clk *rockchip_clk_register_frac_branch( 202static struct clk *rockchip_clk_register_frac_branch(
168 struct rockchip_clk_provider *ctx, const char *name, 203 struct rockchip_clk_provider *ctx, const char *name,
169 const char *const *parent_names, u8 num_parents, 204 const char *const *parent_names, u8 num_parents,
@@ -210,6 +245,7 @@ static struct clk *rockchip_clk_register_frac_branch(
210 div->nwidth = 16; 245 div->nwidth = 16;
211 div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift; 246 div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift;
212 div->lock = lock; 247 div->lock = lock;
248 div->approximation = rockchip_fractional_approximation;
213 div_ops = &clk_fractional_divider_ops; 249 div_ops = &clk_fractional_divider_ops;
214 250
215 clk = clk_register_composite(NULL, name, parent_names, num_parents, 251 clk = clk_register_composite(NULL, name, parent_names, num_parents,
diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c
index 1fab56f396d4..b117783ed404 100644
--- a/drivers/clk/samsung/clk-exynos-audss.c
+++ b/drivers/clk/samsung/clk-exynos-audss.c
@@ -180,7 +180,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
180 } 180 }
181 clk_table[EXYNOS_MOUT_AUDSS] = clk_hw_register_mux(NULL, "mout_audss", 181 clk_table[EXYNOS_MOUT_AUDSS] = clk_hw_register_mux(NULL, "mout_audss",
182 mout_audss_p, ARRAY_SIZE(mout_audss_p), 182 mout_audss_p, ARRAY_SIZE(mout_audss_p),
183 CLK_SET_RATE_NO_REPARENT, 183 CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
184 reg_base + ASS_CLK_SRC, 0, 1, 0, &lock); 184 reg_base + ASS_CLK_SRC, 0, 1, 0, &lock);
185 185
186 cdclk = devm_clk_get(&pdev->dev, "cdclk"); 186 cdclk = devm_clk_get(&pdev->dev, "cdclk");
@@ -195,11 +195,11 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
195 reg_base + ASS_CLK_SRC, 2, 2, 0, &lock); 195 reg_base + ASS_CLK_SRC, 2, 2, 0, &lock);
196 196
197 clk_table[EXYNOS_DOUT_SRP] = clk_hw_register_divider(NULL, "dout_srp", 197 clk_table[EXYNOS_DOUT_SRP] = clk_hw_register_divider(NULL, "dout_srp",
198 "mout_audss", 0, reg_base + ASS_CLK_DIV, 0, 4, 198 "mout_audss", CLK_SET_RATE_PARENT,
199 0, &lock); 199 reg_base + ASS_CLK_DIV, 0, 4, 0, &lock);
200 200
201 clk_table[EXYNOS_DOUT_AUD_BUS] = clk_hw_register_divider(NULL, 201 clk_table[EXYNOS_DOUT_AUD_BUS] = clk_hw_register_divider(NULL,
202 "dout_aud_bus", "dout_srp", 0, 202 "dout_aud_bus", "dout_srp", CLK_SET_RATE_PARENT,
203 reg_base + ASS_CLK_DIV, 4, 4, 0, &lock); 203 reg_base + ASS_CLK_DIV, 4, 4, 0, &lock);
204 204
205 clk_table[EXYNOS_DOUT_I2S] = clk_hw_register_divider(NULL, "dout_i2s", 205 clk_table[EXYNOS_DOUT_I2S] = clk_hw_register_divider(NULL, "dout_i2s",
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 9a6476aa7d81..25601967d1cd 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -537,8 +537,8 @@ static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = {
537 537
538 MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore", 538 MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore",
539 mout_mx_mspll_ccore_p, SRC_TOP7, 16, 2), 539 mout_mx_mspll_ccore_p, SRC_TOP7, 16, 2),
540 MUX(CLK_MOUT_MAU_EPLL, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p, 540 MUX_F(CLK_MOUT_MAU_EPLL, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p,
541 SRC_TOP7, 20, 2), 541 SRC_TOP7, 20, 2, CLK_SET_RATE_PARENT, 0),
542 MUX(0, "sclk_bpll", mout_bpll_p, SRC_TOP7, 24, 1), 542 MUX(0, "sclk_bpll", mout_bpll_p, SRC_TOP7, 24, 1),
543 MUX(0, "mout_epll2", mout_epll2_5800_p, SRC_TOP7, 28, 1), 543 MUX(0, "mout_epll2", mout_epll2_5800_p, SRC_TOP7, 28, 1),
544 544
@@ -547,8 +547,8 @@ static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = {
547 MUX(0, "mout_aclk432_cam", mout_group6_5800_p, SRC_TOP8, 24, 2), 547 MUX(0, "mout_aclk432_cam", mout_group6_5800_p, SRC_TOP8, 24, 2),
548 MUX(0, "mout_aclk432_scaler", mout_group6_5800_p, SRC_TOP8, 28, 2), 548 MUX(0, "mout_aclk432_scaler", mout_group6_5800_p, SRC_TOP8, 28, 2),
549 549
550 MUX(CLK_MOUT_USER_MAU_EPLL, "mout_user_mau_epll", mout_group16_5800_p, 550 MUX_F(CLK_MOUT_USER_MAU_EPLL, "mout_user_mau_epll", mout_group16_5800_p,
551 SRC_TOP9, 8, 1), 551 SRC_TOP9, 8, 1, CLK_SET_RATE_PARENT, 0),
552 MUX(0, "mout_user_aclk550_cam", mout_group15_5800_p, 552 MUX(0, "mout_user_aclk550_cam", mout_group15_5800_p,
553 SRC_TOP9, 16, 1), 553 SRC_TOP9, 16, 1),
554 MUX(0, "mout_user_aclkfl1_550_cam", mout_group13_5800_p, 554 MUX(0, "mout_user_aclkfl1_550_cam", mout_group13_5800_p,
@@ -590,6 +590,8 @@ static const struct samsung_gate_clock exynos5800_gate_clks[] __initconst = {
590 GATE_BUS_TOP, 24, 0, 0), 590 GATE_BUS_TOP, 24, 0, 0),
591 GATE(CLK_ACLK432_SCALER, "aclk432_scaler", "mout_user_aclk432_scaler", 591 GATE(CLK_ACLK432_SCALER, "aclk432_scaler", "mout_user_aclk432_scaler",
592 GATE_BUS_TOP, 27, CLK_IS_CRITICAL, 0), 592 GATE_BUS_TOP, 27, CLK_IS_CRITICAL, 0),
593 GATE(CLK_MAU_EPLL, "mau_epll", "mout_user_mau_epll",
594 SRC_MASK_TOP7, 20, CLK_SET_RATE_PARENT, 0),
593}; 595};
594 596
595static const struct samsung_mux_clock exynos5420_mux_clks[] __initconst = { 597static const struct samsung_mux_clock exynos5420_mux_clks[] __initconst = {
@@ -629,6 +631,11 @@ static const struct samsung_div_clock exynos5420_div_clks[] __initconst = {
629 "mout_aclk400_wcore_bpll", DIV_TOP0, 16, 3), 631 "mout_aclk400_wcore_bpll", DIV_TOP0, 16, 3),
630}; 632};
631 633
634static const struct samsung_gate_clock exynos5420_gate_clks[] __initconst = {
635 GATE(CLK_MAU_EPLL, "mau_epll", "mout_mau_epll_clk",
636 SRC_MASK_TOP7, 20, CLK_SET_RATE_PARENT, 0),
637};
638
632static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { 639static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = {
633 MUX(0, "mout_user_pclk66_gpio", mout_user_pclk66_gpio_p, 640 MUX(0, "mout_user_pclk66_gpio", mout_user_pclk66_gpio_p,
634 SRC_TOP7, 4, 1), 641 SRC_TOP7, 4, 1),
@@ -706,7 +713,8 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = {
706 MUX(0, "mout_sclk_spll", mout_spll_p, SRC_TOP6, 8, 1), 713 MUX(0, "mout_sclk_spll", mout_spll_p, SRC_TOP6, 8, 1),
707 MUX(0, "mout_sclk_ipll", mout_ipll_p, SRC_TOP6, 12, 1), 714 MUX(0, "mout_sclk_ipll", mout_ipll_p, SRC_TOP6, 12, 1),
708 MUX(0, "mout_sclk_rpll", mout_rpll_p, SRC_TOP6, 16, 1), 715 MUX(0, "mout_sclk_rpll", mout_rpll_p, SRC_TOP6, 16, 1),
709 MUX(CLK_MOUT_EPLL, "mout_sclk_epll", mout_epll_p, SRC_TOP6, 20, 1), 716 MUX_F(CLK_MOUT_EPLL, "mout_sclk_epll", mout_epll_p, SRC_TOP6, 20, 1,
717 CLK_SET_RATE_PARENT, 0),
710 MUX(0, "mout_sclk_dpll", mout_dpll_p, SRC_TOP6, 24, 1), 718 MUX(0, "mout_sclk_dpll", mout_dpll_p, SRC_TOP6, 24, 1),
711 MUX(0, "mout_sclk_cpll", mout_cpll_p, SRC_TOP6, 28, 1), 719 MUX(0, "mout_sclk_cpll", mout_cpll_p, SRC_TOP6, 28, 1),
712 720
@@ -1001,9 +1009,6 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
1001 GATE(0, "aclk300_disp1", "mout_user_aclk300_disp1", 1009 GATE(0, "aclk300_disp1", "mout_user_aclk300_disp1",
1002 SRC_MASK_TOP2, 24, CLK_IS_CRITICAL, 0), 1010 SRC_MASK_TOP2, 24, CLK_IS_CRITICAL, 0),
1003 1011
1004 GATE(CLK_MAU_EPLL, "mau_epll", "mout_mau_epll_clk",
1005 SRC_MASK_TOP7, 20, 0, 0),
1006
1007 /* sclk */ 1012 /* sclk */
1008 GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_uart0", 1013 GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_uart0",
1009 GATE_TOP_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0), 1014 GATE_TOP_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0),
@@ -1440,6 +1445,8 @@ static void __init exynos5x_clk_init(struct device_node *np,
1440 ARRAY_SIZE(exynos5420_mux_clks)); 1445 ARRAY_SIZE(exynos5420_mux_clks));
1441 samsung_clk_register_div(ctx, exynos5420_div_clks, 1446 samsung_clk_register_div(ctx, exynos5420_div_clks,
1442 ARRAY_SIZE(exynos5420_div_clks)); 1447 ARRAY_SIZE(exynos5420_div_clks));
1448 samsung_clk_register_gate(ctx, exynos5420_gate_clks,
1449 ARRAY_SIZE(exynos5420_gate_clks));
1443 } else { 1450 } else {
1444 samsung_clk_register_fixed_factor( 1451 samsung_clk_register_fixed_factor(
1445 ctx, exynos5800_fixed_factor_clks, 1452 ctx, exynos5800_fixed_factor_clks,
diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 7342928c35cd..6427d0ebe2de 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -11,6 +11,19 @@ config SUN50I_A64_CCU
11 default ARM64 && ARCH_SUNXI 11 default ARM64 && ARCH_SUNXI
12 depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST 12 depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
13 13
14config SUN4I_A10_CCU
15 bool "Support for the Allwinner A10/A20 CCU"
16 select SUNXI_CCU_DIV
17 select SUNXI_CCU_MULT
18 select SUNXI_CCU_NK
19 select SUNXI_CCU_NKM
20 select SUNXI_CCU_NM
21 select SUNXI_CCU_MP
22 select SUNXI_CCU_PHASE
23 default MACH_SUN4I
24 default MACH_SUN7I
25 depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST
26
14config SUN5I_CCU 27config SUN5I_CCU
15 bool "Support for the Allwinner sun5i family CCM" 28 bool "Support for the Allwinner sun5i family CCM"
16 default MACH_SUN5I 29 default MACH_SUN5I
@@ -48,6 +61,11 @@ config SUN8I_V3S_CCU
48config SUN8I_DE2_CCU 61config SUN8I_DE2_CCU
49 bool "Support for the Allwinner SoCs DE2 CCU" 62 bool "Support for the Allwinner SoCs DE2 CCU"
50 63
64config SUN8I_R40_CCU
65 bool "Support for the Allwinner R40 CCU"
66 default MACH_SUN8I
67 depends on MACH_SUN8I || COMPILE_TEST
68
51config SUN9I_A80_CCU 69config SUN9I_A80_CCU
52 bool "Support for the Allwinner A80 CCU" 70 bool "Support for the Allwinner A80 CCU"
53 default MACH_SUN9I 71 default MACH_SUN9I
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 45a5910379a5..85a0633c1eac 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -20,6 +20,7 @@ lib-$(CONFIG_SUNXI_CCU) += ccu_mp.o
20 20
21# SoC support 21# SoC support
22obj-$(CONFIG_SUN50I_A64_CCU) += ccu-sun50i-a64.o 22obj-$(CONFIG_SUN50I_A64_CCU) += ccu-sun50i-a64.o
23obj-$(CONFIG_SUN4I_A10_CCU) += ccu-sun4i-a10.o
23obj-$(CONFIG_SUN5I_CCU) += ccu-sun5i.o 24obj-$(CONFIG_SUN5I_CCU) += ccu-sun5i.o
24obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o 25obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o
25obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o 26obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o
@@ -29,6 +30,7 @@ obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o
29obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o 30obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o
30obj-$(CONFIG_SUN8I_DE2_CCU) += ccu-sun8i-de2.o 31obj-$(CONFIG_SUN8I_DE2_CCU) += ccu-sun8i-de2.o
31obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o 32obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o
33obj-$(CONFIG_SUN8I_R40_CCU) += ccu-sun8i-r40.o
32obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o 34obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o
33obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o 35obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o
34obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o 36obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
new file mode 100644
index 000000000000..286b0049b7b6
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
@@ -0,0 +1,1456 @@
1/*
2 * Copyright (c) 2017 Priit Laes <plaes@plaes.org>.
3 * Copyright (c) 2017 Maxime Ripard.
4 * Copyright (c) 2017 Jonathan Liu.
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/clk-provider.h>
17#include <linux/of_address.h>
18
19#include "ccu_common.h"
20#include "ccu_reset.h"
21
22#include "ccu_div.h"
23#include "ccu_gate.h"
24#include "ccu_mp.h"
25#include "ccu_mult.h"
26#include "ccu_nk.h"
27#include "ccu_nkm.h"
28#include "ccu_nkmp.h"
29#include "ccu_nm.h"
30#include "ccu_phase.h"
31
32#include "ccu-sun4i-a10.h"
33
34static struct ccu_nkmp pll_core_clk = {
35 .enable = BIT(31),
36 .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
37 .k = _SUNXI_CCU_MULT(4, 2),
38 .m = _SUNXI_CCU_DIV(0, 2),
39 .p = _SUNXI_CCU_DIV(16, 2),
40 .common = {
41 .reg = 0x000,
42 .hw.init = CLK_HW_INIT("pll-core",
43 "hosc",
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 SUN4I_PLL_AUDIO_REG 0x008
58static struct ccu_nm pll_audio_base_clk = {
59 .enable = BIT(31),
60 .n = _SUNXI_CCU_MULT_OFFSET(8, 7, 0),
61 .m = _SUNXI_CCU_DIV_OFFSET(0, 5, 0),
62 .common = {
63 .reg = 0x008,
64 .hw.init = CLK_HW_INIT("pll-audio-base",
65 "hosc",
66 &ccu_nm_ops,
67 0),
68 },
69
70};
71
72static struct ccu_mult pll_video0_clk = {
73 .enable = BIT(31),
74 .mult = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
75 .frac = _SUNXI_CCU_FRAC(BIT(15), BIT(14),
76 270000000, 297000000),
77 .common = {
78 .reg = 0x010,
79 .features = (CCU_FEATURE_FRACTIONAL |
80 CCU_FEATURE_ALL_PREDIV),
81 .prediv = 8,
82 .hw.init = CLK_HW_INIT("pll-video0",
83 "hosc",
84 &ccu_mult_ops,
85 0),
86 },
87};
88
89static struct ccu_nkmp pll_ve_sun4i_clk = {
90 .enable = BIT(31),
91 .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
92 .k = _SUNXI_CCU_MULT(4, 2),
93 .m = _SUNXI_CCU_DIV(0, 2),
94 .p = _SUNXI_CCU_DIV(16, 2),
95 .common = {
96 .reg = 0x018,
97 .hw.init = CLK_HW_INIT("pll-ve",
98 "hosc",
99 &ccu_nkmp_ops,
100 0),
101 },
102};
103
104static struct ccu_nk pll_ve_sun7i_clk = {
105 .enable = BIT(31),
106 .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
107 .k = _SUNXI_CCU_MULT(4, 2),
108 .common = {
109 .reg = 0x018,
110 .hw.init = CLK_HW_INIT("pll-ve",
111 "hosc",
112 &ccu_nk_ops,
113 0),
114 },
115};
116
117static struct ccu_nk pll_ddr_base_clk = {
118 .enable = BIT(31),
119 .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
120 .k = _SUNXI_CCU_MULT(4, 2),
121 .common = {
122 .reg = 0x020,
123 .hw.init = CLK_HW_INIT("pll-ddr-base",
124 "hosc",
125 &ccu_nk_ops,
126 0),
127 },
128};
129
130static SUNXI_CCU_M(pll_ddr_clk, "pll-ddr", "pll-ddr-base", 0x020, 0, 2,
131 CLK_IS_CRITICAL);
132
133static struct ccu_div pll_ddr_other_clk = {
134 .div = _SUNXI_CCU_DIV_FLAGS(16, 2, CLK_DIVIDER_POWER_OF_TWO),
135 .common = {
136 .reg = 0x020,
137 .hw.init = CLK_HW_INIT("pll-ddr-other", "pll-ddr-base",
138 &ccu_div_ops,
139 0),
140 },
141};
142
143static struct ccu_nk pll_periph_base_clk = {
144 .enable = BIT(31),
145 .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
146 .k = _SUNXI_CCU_MULT(4, 2),
147 .common = {
148 .reg = 0x028,
149 .hw.init = CLK_HW_INIT("pll-periph-base",
150 "hosc",
151 &ccu_nk_ops,
152 0),
153 },
154};
155
156static CLK_FIXED_FACTOR(pll_periph_clk, "pll-periph", "pll-periph-base",
157 2, 1, CLK_SET_RATE_PARENT);
158
159/* Not documented on A10 */
160static struct ccu_div pll_periph_sata_clk = {
161 .enable = BIT(14),
162 .div = _SUNXI_CCU_DIV(0, 2),
163 .fixed_post_div = 6,
164 .common = {
165 .reg = 0x028,
166 .features = CCU_FEATURE_FIXED_POSTDIV,
167 .hw.init = CLK_HW_INIT("pll-periph-sata",
168 "pll-periph-base",
169 &ccu_div_ops, 0),
170 },
171};
172
173static struct ccu_mult pll_video1_clk = {
174 .enable = BIT(31),
175 .mult = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
176 .frac = _SUNXI_CCU_FRAC(BIT(15), BIT(14),
177 270000000, 297000000),
178 .common = {
179 .reg = 0x030,
180 .features = (CCU_FEATURE_FRACTIONAL |
181 CCU_FEATURE_ALL_PREDIV),
182 .prediv = 8,
183 .hw.init = CLK_HW_INIT("pll-video1",
184 "hosc",
185 &ccu_mult_ops,
186 0),
187 },
188};
189
190/* Not present on A10 */
191static struct ccu_nk pll_gpu_clk = {
192 .enable = BIT(31),
193 .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
194 .k = _SUNXI_CCU_MULT(4, 2),
195 .common = {
196 .reg = 0x040,
197 .hw.init = CLK_HW_INIT("pll-gpu",
198 "hosc",
199 &ccu_nk_ops,
200 0),
201 },
202};
203
204static SUNXI_CCU_GATE(hosc_clk, "hosc", "osc24M", 0x050, BIT(0), 0);
205
206static const char *const cpu_parents[] = { "osc32k", "hosc",
207 "pll-core", "pll-periph" };
208static const struct ccu_mux_fixed_prediv cpu_predivs[] = {
209 { .index = 3, .div = 3, },
210};
211
212#define SUN4I_AHB_REG 0x054
213static struct ccu_mux cpu_clk = {
214 .mux = {
215 .shift = 16,
216 .width = 2,
217 .fixed_predivs = cpu_predivs,
218 .n_predivs = ARRAY_SIZE(cpu_predivs),
219 },
220 .common = {
221 .reg = 0x054,
222 .features = CCU_FEATURE_FIXED_PREDIV,
223 .hw.init = CLK_HW_INIT_PARENTS("cpu",
224 cpu_parents,
225 &ccu_mux_ops,
226 CLK_IS_CRITICAL),
227 }
228};
229
230static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x054, 0, 2, 0);
231
232static struct ccu_div ahb_sun4i_clk = {
233 .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
234 .common = {
235 .reg = 0x054,
236 .hw.init = CLK_HW_INIT("ahb", "axi", &ccu_div_ops, 0),
237 },
238};
239
240static const char *const ahb_sun7i_parents[] = { "axi", "pll-periph",
241 "pll-periph" };
242static const struct ccu_mux_fixed_prediv ahb_sun7i_predivs[] = {
243 { .index = 1, .div = 2, },
244 { /* Sentinel */ },
245};
246static struct ccu_div ahb_sun7i_clk = {
247 .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
248 .mux = {
249 .shift = 6,
250 .width = 2,
251 .fixed_predivs = ahb_sun7i_predivs,
252 .n_predivs = ARRAY_SIZE(ahb_sun7i_predivs),
253 },
254
255 .common = {
256 .reg = 0x054,
257 .hw.init = CLK_HW_INIT_PARENTS("ahb",
258 ahb_sun7i_parents,
259 &ccu_div_ops,
260 0),
261 },
262};
263
264static struct clk_div_table apb0_div_table[] = {
265 { .val = 0, .div = 2 },
266 { .val = 1, .div = 2 },
267 { .val = 2, .div = 4 },
268 { .val = 3, .div = 8 },
269 { /* Sentinel */ },
270};
271static SUNXI_CCU_DIV_TABLE(apb0_clk, "apb0", "ahb",
272 0x054, 8, 2, apb0_div_table, 0);
273
274static const char *const apb1_parents[] = { "hosc", "pll-periph", "osc32k" };
275static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb1_parents, 0x058,
276 0, 5, /* M */
277 16, 2, /* P */
278 24, 2, /* mux */
279 0);
280
281/* Not present on A20 */
282static SUNXI_CCU_GATE(axi_dram_clk, "axi-dram", "ahb",
283 0x05c, BIT(31), 0);
284
285static SUNXI_CCU_GATE(ahb_otg_clk, "ahb-otg", "ahb",
286 0x060, BIT(0), 0);
287static SUNXI_CCU_GATE(ahb_ehci0_clk, "ahb-ehci0", "ahb",
288 0x060, BIT(1), 0);
289static SUNXI_CCU_GATE(ahb_ohci0_clk, "ahb-ohci0", "ahb",
290 0x060, BIT(2), 0);
291static SUNXI_CCU_GATE(ahb_ehci1_clk, "ahb-ehci1", "ahb",
292 0x060, BIT(3), 0);
293static SUNXI_CCU_GATE(ahb_ohci1_clk, "ahb-ohci1", "ahb",
294 0x060, BIT(4), 0);
295static SUNXI_CCU_GATE(ahb_ss_clk, "ahb-ss", "ahb",
296 0x060, BIT(5), 0);
297static SUNXI_CCU_GATE(ahb_dma_clk, "ahb-dma", "ahb",
298 0x060, BIT(6), 0);
299static SUNXI_CCU_GATE(ahb_bist_clk, "ahb-bist", "ahb",
300 0x060, BIT(7), 0);
301static SUNXI_CCU_GATE(ahb_mmc0_clk, "ahb-mmc0", "ahb",
302 0x060, BIT(8), 0);
303static SUNXI_CCU_GATE(ahb_mmc1_clk, "ahb-mmc1", "ahb",
304 0x060, BIT(9), 0);
305static SUNXI_CCU_GATE(ahb_mmc2_clk, "ahb-mmc2", "ahb",
306 0x060, BIT(10), 0);
307static SUNXI_CCU_GATE(ahb_mmc3_clk, "ahb-mmc3", "ahb",
308 0x060, BIT(11), 0);
309static SUNXI_CCU_GATE(ahb_ms_clk, "ahb-ms", "ahb",
310 0x060, BIT(12), 0);
311static SUNXI_CCU_GATE(ahb_nand_clk, "ahb-nand", "ahb",
312 0x060, BIT(13), 0);
313static SUNXI_CCU_GATE(ahb_sdram_clk, "ahb-sdram", "ahb",
314 0x060, BIT(14), CLK_IS_CRITICAL);
315
316static SUNXI_CCU_GATE(ahb_ace_clk, "ahb-ace", "ahb",
317 0x060, BIT(16), 0);
318static SUNXI_CCU_GATE(ahb_emac_clk, "ahb-emac", "ahb",
319 0x060, BIT(17), 0);
320static SUNXI_CCU_GATE(ahb_ts_clk, "ahb-ts", "ahb",
321 0x060, BIT(18), 0);
322static SUNXI_CCU_GATE(ahb_spi0_clk, "ahb-spi0", "ahb",
323 0x060, BIT(20), 0);
324static SUNXI_CCU_GATE(ahb_spi1_clk, "ahb-spi1", "ahb",
325 0x060, BIT(21), 0);
326static SUNXI_CCU_GATE(ahb_spi2_clk, "ahb-spi2", "ahb",
327 0x060, BIT(22), 0);
328static SUNXI_CCU_GATE(ahb_spi3_clk, "ahb-spi3", "ahb",
329 0x060, BIT(23), 0);
330static SUNXI_CCU_GATE(ahb_pata_clk, "ahb-pata", "ahb",
331 0x060, BIT(24), 0);
332/* Not documented on A20 */
333static SUNXI_CCU_GATE(ahb_sata_clk, "ahb-sata", "ahb",
334 0x060, BIT(25), 0);
335/* Not present on A20 */
336static SUNXI_CCU_GATE(ahb_gps_clk, "ahb-gps", "ahb",
337 0x060, BIT(26), 0);
338/* Not present on A10 */
339static SUNXI_CCU_GATE(ahb_hstimer_clk, "ahb-hstimer", "ahb",
340 0x060, BIT(28), 0);
341
342static SUNXI_CCU_GATE(ahb_ve_clk, "ahb-ve", "ahb",
343 0x064, BIT(0), 0);
344static SUNXI_CCU_GATE(ahb_tvd_clk, "ahb-tvd", "ahb",
345 0x064, BIT(1), 0);
346static SUNXI_CCU_GATE(ahb_tve0_clk, "ahb-tve0", "ahb",
347 0x064, BIT(2), 0);
348static SUNXI_CCU_GATE(ahb_tve1_clk, "ahb-tve1", "ahb",
349 0x064, BIT(3), 0);
350static SUNXI_CCU_GATE(ahb_lcd0_clk, "ahb-lcd0", "ahb",
351 0x064, BIT(4), 0);
352static SUNXI_CCU_GATE(ahb_lcd1_clk, "ahb-lcd1", "ahb",
353 0x064, BIT(5), 0);
354static SUNXI_CCU_GATE(ahb_csi0_clk, "ahb-csi0", "ahb",
355 0x064, BIT(8), 0);
356static SUNXI_CCU_GATE(ahb_csi1_clk, "ahb-csi1", "ahb",
357 0x064, BIT(9), 0);
358/* Not present on A10 */
359static SUNXI_CCU_GATE(ahb_hdmi1_clk, "ahb-hdmi1", "ahb",
360 0x064, BIT(10), 0);
361static SUNXI_CCU_GATE(ahb_hdmi0_clk, "ahb-hdmi0", "ahb",
362 0x064, BIT(11), 0);
363static SUNXI_CCU_GATE(ahb_de_be0_clk, "ahb-de-be0", "ahb",
364 0x064, BIT(12), 0);
365static SUNXI_CCU_GATE(ahb_de_be1_clk, "ahb-de-be1", "ahb",
366 0x064, BIT(13), 0);
367static SUNXI_CCU_GATE(ahb_de_fe0_clk, "ahb-de-fe0", "ahb",
368 0x064, BIT(14), 0);
369static SUNXI_CCU_GATE(ahb_de_fe1_clk, "ahb-de-fe1", "ahb",
370 0x064, BIT(15), 0);
371/* Not present on A10 */
372static SUNXI_CCU_GATE(ahb_gmac_clk, "ahb-gmac", "ahb",
373 0x064, BIT(17), 0);
374static SUNXI_CCU_GATE(ahb_mp_clk, "ahb-mp", "ahb",
375 0x064, BIT(18), 0);
376static SUNXI_CCU_GATE(ahb_gpu_clk, "ahb-gpu", "ahb",
377 0x064, BIT(20), 0);
378
379static SUNXI_CCU_GATE(apb0_codec_clk, "apb0-codec", "apb0",
380 0x068, BIT(0), 0);
381static SUNXI_CCU_GATE(apb0_spdif_clk, "apb0-spdif", "apb0",
382 0x068, BIT(1), 0);
383static SUNXI_CCU_GATE(apb0_ac97_clk, "apb0-ac97", "apb0",
384 0x068, BIT(2), 0);
385static SUNXI_CCU_GATE(apb0_i2s0_clk, "apb0-i2s0", "apb0",
386 0x068, BIT(3), 0);
387/* Not present on A10 */
388static SUNXI_CCU_GATE(apb0_i2s1_clk, "apb0-i2s1", "apb0",
389 0x068, BIT(4), 0);
390static SUNXI_CCU_GATE(apb0_pio_clk, "apb0-pio", "apb0",
391 0x068, BIT(5), 0);
392static SUNXI_CCU_GATE(apb0_ir0_clk, "apb0-ir0", "apb0",
393 0x068, BIT(6), 0);
394static SUNXI_CCU_GATE(apb0_ir1_clk, "apb0-ir1", "apb0",
395 0x068, BIT(7), 0);
396/* Not present on A10 */
397static SUNXI_CCU_GATE(apb0_i2s2_clk, "apb0-i2s2", "apb0",
398 0x068, BIT(8), 0);
399static SUNXI_CCU_GATE(apb0_keypad_clk, "apb0-keypad", "apb0",
400 0x068, BIT(10), 0);
401
402static SUNXI_CCU_GATE(apb1_i2c0_clk, "apb1-i2c0", "apb1",
403 0x06c, BIT(0), 0);
404static SUNXI_CCU_GATE(apb1_i2c1_clk, "apb1-i2c1", "apb1",
405 0x06c, BIT(1), 0);
406static SUNXI_CCU_GATE(apb1_i2c2_clk, "apb1-i2c2", "apb1",
407 0x06c, BIT(2), 0);
408/* Not present on A10 */
409static SUNXI_CCU_GATE(apb1_i2c3_clk, "apb1-i2c3", "apb1",
410 0x06c, BIT(3), 0);
411static SUNXI_CCU_GATE(apb1_can_clk, "apb1-can", "apb1",
412 0x06c, BIT(4), 0);
413static SUNXI_CCU_GATE(apb1_scr_clk, "apb1-scr", "apb1",
414 0x06c, BIT(5), 0);
415static SUNXI_CCU_GATE(apb1_ps20_clk, "apb1-ps20", "apb1",
416 0x06c, BIT(6), 0);
417static SUNXI_CCU_GATE(apb1_ps21_clk, "apb1-ps21", "apb1",
418 0x06c, BIT(7), 0);
419/* Not present on A10 */
420static SUNXI_CCU_GATE(apb1_i2c4_clk, "apb1-i2c4", "apb1",
421 0x06c, BIT(15), 0);
422static SUNXI_CCU_GATE(apb1_uart0_clk, "apb1-uart0", "apb1",
423 0x06c, BIT(16), 0);
424static SUNXI_CCU_GATE(apb1_uart1_clk, "apb1-uart1", "apb1",
425 0x06c, BIT(17), 0);
426static SUNXI_CCU_GATE(apb1_uart2_clk, "apb1-uart2", "apb1",
427 0x06c, BIT(18), 0);
428static SUNXI_CCU_GATE(apb1_uart3_clk, "apb1-uart3", "apb1",
429 0x06c, BIT(19), 0);
430static SUNXI_CCU_GATE(apb1_uart4_clk, "apb1-uart4", "apb1",
431 0x06c, BIT(20), 0);
432static SUNXI_CCU_GATE(apb1_uart5_clk, "apb1-uart5", "apb1",
433 0x06c, BIT(21), 0);
434static SUNXI_CCU_GATE(apb1_uart6_clk, "apb1-uart6", "apb1",
435 0x06c, BIT(22), 0);
436static SUNXI_CCU_GATE(apb1_uart7_clk, "apb1-uart7", "apb1",
437 0x06c, BIT(23), 0);
438
439static const char *const mod0_default_parents[] = { "hosc", "pll-periph",
440 "pll-ddr-other" };
441static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
442 0, 4, /* M */
443 16, 2, /* P */
444 24, 2, /* mux */
445 BIT(31), /* gate */
446 0);
447
448/* Undocumented on A10 */
449static SUNXI_CCU_MP_WITH_MUX_GATE(ms_clk, "ms", mod0_default_parents, 0x084,
450 0, 4, /* M */
451 16, 2, /* P */
452 24, 2, /* mux */
453 BIT(31), /* gate */
454 0);
455
456static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
457 0, 4, /* M */
458 16, 2, /* P */
459 24, 2, /* mux */
460 BIT(31), /* gate */
461 0);
462
463/* MMC output and sample clocks are not present on A10 */
464static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
465 0x088, 8, 3, 0);
466static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
467 0x088, 20, 3, 0);
468
469static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
470 0, 4, /* M */
471 16, 2, /* P */
472 24, 2, /* mux */
473 BIT(31), /* gate */
474 0);
475
476/* MMC output and sample clocks are not present on A10 */
477static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
478 0x08c, 8, 3, 0);
479static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
480 0x08c, 20, 3, 0);
481
482static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
483 0, 4, /* M */
484 16, 2, /* P */
485 24, 2, /* mux */
486 BIT(31), /* gate */
487 0);
488
489/* MMC output and sample clocks are not present on A10 */
490static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
491 0x090, 8, 3, 0);
492static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
493 0x090, 20, 3, 0);
494
495static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk, "mmc3", mod0_default_parents, 0x094,
496 0, 4, /* M */
497 16, 2, /* P */
498 24, 2, /* mux */
499 BIT(31), /* gate */
500 0);
501
502/* MMC output and sample clocks are not present on A10 */
503static SUNXI_CCU_PHASE(mmc3_output_clk, "mmc3_output", "mmc3",
504 0x094, 8, 3, 0);
505static SUNXI_CCU_PHASE(mmc3_sample_clk, "mmc3_sample", "mmc3",
506 0x094, 20, 3, 0);
507
508static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents, 0x098,
509 0, 4, /* M */
510 16, 2, /* P */
511 24, 2, /* mux */
512 BIT(31), /* gate */
513 0);
514
515static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c,
516 0, 4, /* M */
517 16, 2, /* P */
518 24, 2, /* mux */
519 BIT(31), /* gate */
520 0);
521
522static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
523 0, 4, /* M */
524 16, 2, /* P */
525 24, 2, /* mux */
526 BIT(31), /* gate */
527 0);
528
529static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
530 0, 4, /* M */
531 16, 2, /* P */
532 24, 2, /* mux */
533 BIT(31), /* gate */
534 0);
535
536static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8,
537 0, 4, /* M */
538 16, 2, /* P */
539 24, 2, /* mux */
540 BIT(31), /* gate */
541 0);
542
543/* Undocumented on A10 */
544static SUNXI_CCU_MP_WITH_MUX_GATE(pata_clk, "pata", mod0_default_parents, 0x0ac,
545 0, 4, /* M */
546 16, 2, /* P */
547 24, 2, /* mux */
548 BIT(31), /* gate */
549 0);
550
551/* TODO: Check whether A10 actually supports osc32k as 4th parent? */
552static const char *const ir_parents_sun4i[] = { "hosc", "pll-periph",
553 "pll-ddr-other" };
554static SUNXI_CCU_MP_WITH_MUX_GATE(ir0_sun4i_clk, "ir0", ir_parents_sun4i, 0x0b0,
555 0, 4, /* M */
556 16, 2, /* P */
557 24, 2, /* mux */
558 BIT(31), /* gate */
559 0);
560
561static SUNXI_CCU_MP_WITH_MUX_GATE(ir1_sun4i_clk, "ir1", ir_parents_sun4i, 0x0b4,
562 0, 4, /* M */
563 16, 2, /* P */
564 24, 2, /* mux */
565 BIT(31), /* gate */
566 0);
567static const char *const ir_parents_sun7i[] = { "hosc", "pll-periph",
568 "pll-ddr-other", "osc32k" };
569static SUNXI_CCU_MP_WITH_MUX_GATE(ir0_sun7i_clk, "ir0", ir_parents_sun7i, 0x0b0,
570 0, 4, /* M */
571 16, 2, /* P */
572 24, 2, /* mux */
573 BIT(31), /* gate */
574 0);
575
576static SUNXI_CCU_MP_WITH_MUX_GATE(ir1_sun7i_clk, "ir1", ir_parents_sun7i, 0x0b4,
577 0, 4, /* M */
578 16, 2, /* P */
579 24, 2, /* mux */
580 BIT(31), /* gate */
581 0);
582
583static const char *const audio_parents[] = { "pll-audio-8x", "pll-audio-4x",
584 "pll-audio-2x", "pll-audio" };
585static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", audio_parents,
586 0x0b8, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
587
588static SUNXI_CCU_MUX_WITH_GATE(ac97_clk, "ac97", audio_parents,
589 0x0bc, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
590
591/* Undocumented on A10 */
592static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", audio_parents,
593 0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
594
595static const char *const keypad_parents[] = { "hosc", "losc"};
596static const u8 keypad_table[] = { 0, 2 };
597static struct ccu_mp keypad_clk = {
598 .enable = BIT(31),
599 .m = _SUNXI_CCU_DIV(0, 5),
600 .p = _SUNXI_CCU_DIV(16, 2),
601 .mux = _SUNXI_CCU_MUX_TABLE(24, 2, keypad_table),
602 .common = {
603 .reg = 0x0c4,
604 .hw.init = CLK_HW_INIT_PARENTS("keypad",
605 keypad_parents,
606 &ccu_mp_ops,
607 0),
608 },
609};
610
611/*
612 * SATA supports external clock as parent via BIT(24) and is probably an
613 * optional crystal or oscillator that can be connected to the
614 * SATA-CLKM / SATA-CLKP pins.
615 */
616static const char *const sata_parents[] = {"pll-periph-sata", "sata-ext"};
617static SUNXI_CCU_MUX_WITH_GATE(sata_clk, "sata", sata_parents,
618 0x0c8, 24, 1, BIT(31), CLK_SET_RATE_PARENT);
619
620
621static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "pll-periph",
622 0x0cc, BIT(6), 0);
623static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "pll-periph",
624 0x0cc, BIT(7), 0);
625static SUNXI_CCU_GATE(usb_phy_clk, "usb-phy", "pll-periph",
626 0x0cc, BIT(8), 0);
627
628/* TODO: GPS CLK 0x0d0 */
629
630static SUNXI_CCU_MP_WITH_MUX_GATE(spi3_clk, "spi3", mod0_default_parents, 0x0d4,
631 0, 4, /* M */
632 16, 2, /* P */
633 24, 2, /* mux */
634 BIT(31), /* gate */
635 0);
636
637/* Not present on A10 */
638static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", audio_parents,
639 0x0d8, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
640
641/* Not present on A10 */
642static SUNXI_CCU_MUX_WITH_GATE(i2s2_clk, "i2s2", audio_parents,
643 0x0dc, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
644
645static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "pll-ddr",
646 0x100, BIT(0), 0);
647static SUNXI_CCU_GATE(dram_csi0_clk, "dram-csi0", "pll-ddr",
648 0x100, BIT(1), 0);
649static SUNXI_CCU_GATE(dram_csi1_clk, "dram-csi1", "pll-ddr",
650 0x100, BIT(2), 0);
651static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "pll-ddr",
652 0x100, BIT(3), 0);
653static SUNXI_CCU_GATE(dram_tvd_clk, "dram-tvd", "pll-ddr",
654 0x100, BIT(4), 0);
655static SUNXI_CCU_GATE(dram_tve0_clk, "dram-tve0", "pll-ddr",
656 0x100, BIT(5), 0);
657static SUNXI_CCU_GATE(dram_tve1_clk, "dram-tve1", "pll-ddr",
658 0x100, BIT(6), 0);
659
660/* Clock seems to be critical only on sun4i */
661static SUNXI_CCU_GATE(dram_out_clk, "dram-out", "pll-ddr",
662 0x100, BIT(15), CLK_IS_CRITICAL);
663static SUNXI_CCU_GATE(dram_de_fe1_clk, "dram-de-fe1", "pll-ddr",
664 0x100, BIT(24), 0);
665static SUNXI_CCU_GATE(dram_de_fe0_clk, "dram-de-fe0", "pll-ddr",
666 0x100, BIT(25), 0);
667static SUNXI_CCU_GATE(dram_de_be0_clk, "dram-de-be0", "pll-ddr",
668 0x100, BIT(26), 0);
669static SUNXI_CCU_GATE(dram_de_be1_clk, "dram-de-be1", "pll-ddr",
670 0x100, BIT(27), 0);
671static SUNXI_CCU_GATE(dram_mp_clk, "dram-mp", "pll-ddr",
672 0x100, BIT(28), 0);
673static SUNXI_CCU_GATE(dram_ace_clk, "dram-ace", "pll-ddr",
674 0x100, BIT(29), 0);
675
676static const char *const de_parents[] = { "pll-video0", "pll-video1",
677 "pll-ddr-other" };
678static SUNXI_CCU_M_WITH_MUX_GATE(de_be0_clk, "de-be0", de_parents,
679 0x104, 0, 4, 24, 2, BIT(31), 0);
680
681static SUNXI_CCU_M_WITH_MUX_GATE(de_be1_clk, "de-be1", de_parents,
682 0x108, 0, 4, 24, 2, BIT(31), 0);
683
684static SUNXI_CCU_M_WITH_MUX_GATE(de_fe0_clk, "de-fe0", de_parents,
685 0x10c, 0, 4, 24, 2, BIT(31), 0);
686
687static SUNXI_CCU_M_WITH_MUX_GATE(de_fe1_clk, "de-fe1", de_parents,
688 0x110, 0, 4, 24, 2, BIT(31), 0);
689
690/* Undocumented on A10 */
691static SUNXI_CCU_M_WITH_MUX_GATE(de_mp_clk, "de-mp", de_parents,
692 0x114, 0, 4, 24, 2, BIT(31), 0);
693
694static const char *const disp_parents[] = { "pll-video0", "pll-video1",
695 "pll-video0-2x", "pll-video1-2x" };
696static SUNXI_CCU_MUX_WITH_GATE(tcon0_ch0_clk, "tcon0-ch0-sclk", disp_parents,
697 0x118, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
698static SUNXI_CCU_MUX_WITH_GATE(tcon1_ch0_clk, "tcon1-ch0-sclk", disp_parents,
699 0x11c, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
700
701static const char *const csi_sclk_parents[] = { "pll-video0", "pll-ve",
702 "pll-ddr-other", "pll-periph" };
703
704static SUNXI_CCU_M_WITH_MUX_GATE(csi_sclk_clk, "csi-sclk",
705 csi_sclk_parents,
706 0x120, 0, 4, 24, 2, BIT(31), 0);
707
708/* TVD clock setup for A10 */
709static const char *const tvd_parents[] = { "pll-video0", "pll-video1" };
710static SUNXI_CCU_MUX_WITH_GATE(tvd_sun4i_clk, "tvd", tvd_parents,
711 0x128, 24, 1, BIT(31), 0);
712
713/* TVD clock setup for A20 */
714static SUNXI_CCU_MP_WITH_MUX_GATE(tvd_sclk2_sun7i_clk,
715 "tvd-sclk2", tvd_parents,
716 0x128,
717 0, 4, /* M */
718 16, 4, /* P */
719 8, 1, /* mux */
720 BIT(15), /* gate */
721 0);
722
723static SUNXI_CCU_M_WITH_GATE(tvd_sclk1_sun7i_clk, "tvd-sclk1", "tvd-sclk2",
724 0x128, 0, 4, BIT(31), 0);
725
726static SUNXI_CCU_M_WITH_MUX_GATE(tcon0_ch1_sclk2_clk, "tcon0-ch1-sclk2",
727 disp_parents,
728 0x12c, 0, 4, 24, 2, BIT(31),
729 CLK_SET_RATE_PARENT);
730
731static SUNXI_CCU_M_WITH_GATE(tcon0_ch1_clk,
732 "tcon0-ch1-sclk1", "tcon0-ch1-sclk2",
733 0x12c, 11, 1, BIT(15),
734 CLK_SET_RATE_PARENT);
735
736static SUNXI_CCU_M_WITH_MUX_GATE(tcon1_ch1_sclk2_clk, "tcon1-ch1-sclk2",
737 disp_parents,
738 0x130, 0, 4, 24, 2, BIT(31),
739 CLK_SET_RATE_PARENT);
740
741static SUNXI_CCU_M_WITH_GATE(tcon1_ch1_clk,
742 "tcon1-ch1-sclk1", "tcon1-ch1-sclk2",
743 0x130, 11, 1, BIT(15),
744 CLK_SET_RATE_PARENT);
745
746static const char *const csi_parents[] = { "hosc", "pll-video0", "pll-video1",
747 "pll-video0-2x", "pll-video1-2x"};
748static const u8 csi_table[] = { 0, 1, 2, 5, 6};
749static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi0_clk, "csi0",
750 csi_parents, csi_table,
751 0x134, 0, 5, 24, 3, BIT(31), 0);
752
753static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi1_clk, "csi1",
754 csi_parents, csi_table,
755 0x138, 0, 5, 24, 3, BIT(31), 0);
756
757static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", 0x13c, 16, 8, BIT(31), 0);
758
759static SUNXI_CCU_GATE(codec_clk, "codec", "pll-audio",
760 0x140, BIT(31), CLK_SET_RATE_PARENT);
761
762static SUNXI_CCU_GATE(avs_clk, "avs", "hosc", 0x144, BIT(31), 0);
763
764static const char *const ace_parents[] = { "pll-ve", "pll-ddr-other" };
765static SUNXI_CCU_M_WITH_MUX_GATE(ace_clk, "ace", ace_parents,
766 0x148, 0, 4, 24, 1, BIT(31), 0);
767
768static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", disp_parents,
769 0x150, 0, 4, 24, 2, BIT(31),
770 CLK_SET_RATE_PARENT);
771
772static const char *const gpu_parents_sun4i[] = { "pll-video0", "pll-ve",
773 "pll-ddr-other",
774 "pll-video1" };
775static SUNXI_CCU_M_WITH_MUX_GATE(gpu_sun4i_clk, "gpu", gpu_parents_sun4i,
776 0x154, 0, 4, 24, 2, BIT(31),
777 CLK_SET_RATE_PARENT);
778
779static const char *const gpu_parents_sun7i[] = { "pll-video0", "pll-ve",
780 "pll-ddr-other", "pll-video1",
781 "pll-gpu" };
782static const u8 gpu_table_sun7i[] = { 0, 1, 2, 3, 4 };
783static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(gpu_sun7i_clk, "gpu",
784 gpu_parents_sun7i, gpu_table_sun7i,
785 0x154, 0, 4, 24, 3, BIT(31),
786 CLK_SET_RATE_PARENT);
787
788static const char *const mbus_sun4i_parents[] = { "hosc", "pll-periph",
789 "pll-ddr-other" };
790static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_sun4i_clk, "mbus", mbus_sun4i_parents,
791 0x15c, 0, 4, 16, 2, 24, 2, BIT(31),
792 0);
793static const char *const mbus_sun7i_parents[] = { "hosc", "pll-periph-base",
794 "pll-ddr-other" };
795static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_sun7i_clk, "mbus", mbus_sun7i_parents,
796 0x15c, 0, 4, 16, 2, 24, 2, BIT(31),
797 CLK_IS_CRITICAL);
798
799static SUNXI_CCU_GATE(hdmi1_slow_clk, "hdmi1-slow", "hosc", 0x178, BIT(31), 0);
800
801static const char *const hdmi1_parents[] = { "pll-video0", "pll-video1" };
802static const u8 hdmi1_table[] = { 0, 1};
803static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(hdmi1_clk, "hdmi1",
804 hdmi1_parents, hdmi1_table,
805 0x17c, 0, 4, 24, 2, BIT(31),
806 CLK_SET_RATE_PARENT);
807
808static const char *const out_parents[] = { "hosc", "osc32k", "hosc" };
809static const struct ccu_mux_fixed_prediv clk_out_predivs[] = {
810 { .index = 0, .div = 750, },
811};
812
813static struct ccu_mp out_a_clk = {
814 .enable = BIT(31),
815 .m = _SUNXI_CCU_DIV(8, 5),
816 .p = _SUNXI_CCU_DIV(20, 2),
817 .mux = {
818 .shift = 24,
819 .width = 2,
820 .fixed_predivs = clk_out_predivs,
821 .n_predivs = ARRAY_SIZE(clk_out_predivs),
822 },
823 .common = {
824 .reg = 0x1f0,
825 .features = CCU_FEATURE_FIXED_PREDIV,
826 .hw.init = CLK_HW_INIT_PARENTS("out-a",
827 out_parents,
828 &ccu_mp_ops,
829 0),
830 },
831};
832static struct ccu_mp out_b_clk = {
833 .enable = BIT(31),
834 .m = _SUNXI_CCU_DIV(8, 5),
835 .p = _SUNXI_CCU_DIV(20, 2),
836 .mux = {
837 .shift = 24,
838 .width = 2,
839 .fixed_predivs = clk_out_predivs,
840 .n_predivs = ARRAY_SIZE(clk_out_predivs),
841 },
842 .common = {
843 .reg = 0x1f4,
844 .features = CCU_FEATURE_FIXED_PREDIV,
845 .hw.init = CLK_HW_INIT_PARENTS("out-b",
846 out_parents,
847 &ccu_mp_ops,
848 0),
849 },
850};
851
852static struct ccu_common *sun4i_sun7i_ccu_clks[] = {
853 &hosc_clk.common,
854 &pll_core_clk.common,
855 &pll_audio_base_clk.common,
856 &pll_video0_clk.common,
857 &pll_ve_sun4i_clk.common,
858 &pll_ve_sun7i_clk.common,
859 &pll_ddr_base_clk.common,
860 &pll_ddr_clk.common,
861 &pll_ddr_other_clk.common,
862 &pll_periph_base_clk.common,
863 &pll_periph_sata_clk.common,
864 &pll_video1_clk.common,
865 &pll_gpu_clk.common,
866 &cpu_clk.common,
867 &axi_clk.common,
868 &axi_dram_clk.common,
869 &ahb_sun4i_clk.common,
870 &ahb_sun7i_clk.common,
871 &apb0_clk.common,
872 &apb1_clk.common,
873 &ahb_otg_clk.common,
874 &ahb_ehci0_clk.common,
875 &ahb_ohci0_clk.common,
876 &ahb_ehci1_clk.common,
877 &ahb_ohci1_clk.common,
878 &ahb_ss_clk.common,
879 &ahb_dma_clk.common,
880 &ahb_bist_clk.common,
881 &ahb_mmc0_clk.common,
882 &ahb_mmc1_clk.common,
883 &ahb_mmc2_clk.common,
884 &ahb_mmc3_clk.common,
885 &ahb_ms_clk.common,
886 &ahb_nand_clk.common,
887 &ahb_sdram_clk.common,
888 &ahb_ace_clk.common,
889 &ahb_emac_clk.common,
890 &ahb_ts_clk.common,
891 &ahb_spi0_clk.common,
892 &ahb_spi1_clk.common,
893 &ahb_spi2_clk.common,
894 &ahb_spi3_clk.common,
895 &ahb_pata_clk.common,
896 &ahb_sata_clk.common,
897 &ahb_gps_clk.common,
898 &ahb_hstimer_clk.common,
899 &ahb_ve_clk.common,
900 &ahb_tvd_clk.common,
901 &ahb_tve0_clk.common,
902 &ahb_tve1_clk.common,
903 &ahb_lcd0_clk.common,
904 &ahb_lcd1_clk.common,
905 &ahb_csi0_clk.common,
906 &ahb_csi1_clk.common,
907 &ahb_hdmi1_clk.common,
908 &ahb_hdmi0_clk.common,
909 &ahb_de_be0_clk.common,
910 &ahb_de_be1_clk.common,
911 &ahb_de_fe0_clk.common,
912 &ahb_de_fe1_clk.common,
913 &ahb_gmac_clk.common,
914 &ahb_mp_clk.common,
915 &ahb_gpu_clk.common,
916 &apb0_codec_clk.common,
917 &apb0_spdif_clk.common,
918 &apb0_ac97_clk.common,
919 &apb0_i2s0_clk.common,
920 &apb0_i2s1_clk.common,
921 &apb0_pio_clk.common,
922 &apb0_ir0_clk.common,
923 &apb0_ir1_clk.common,
924 &apb0_i2s2_clk.common,
925 &apb0_keypad_clk.common,
926 &apb1_i2c0_clk.common,
927 &apb1_i2c1_clk.common,
928 &apb1_i2c2_clk.common,
929 &apb1_i2c3_clk.common,
930 &apb1_can_clk.common,
931 &apb1_scr_clk.common,
932 &apb1_ps20_clk.common,
933 &apb1_ps21_clk.common,
934 &apb1_i2c4_clk.common,
935 &apb1_uart0_clk.common,
936 &apb1_uart1_clk.common,
937 &apb1_uart2_clk.common,
938 &apb1_uart3_clk.common,
939 &apb1_uart4_clk.common,
940 &apb1_uart5_clk.common,
941 &apb1_uart6_clk.common,
942 &apb1_uart7_clk.common,
943 &nand_clk.common,
944 &ms_clk.common,
945 &mmc0_clk.common,
946 &mmc0_output_clk.common,
947 &mmc0_sample_clk.common,
948 &mmc1_clk.common,
949 &mmc1_output_clk.common,
950 &mmc1_sample_clk.common,
951 &mmc2_clk.common,
952 &mmc2_output_clk.common,
953 &mmc2_sample_clk.common,
954 &mmc3_clk.common,
955 &mmc3_output_clk.common,
956 &mmc3_sample_clk.common,
957 &ts_clk.common,
958 &ss_clk.common,
959 &spi0_clk.common,
960 &spi1_clk.common,
961 &spi2_clk.common,
962 &pata_clk.common,
963 &ir0_sun4i_clk.common,
964 &ir1_sun4i_clk.common,
965 &ir0_sun7i_clk.common,
966 &ir1_sun7i_clk.common,
967 &i2s0_clk.common,
968 &ac97_clk.common,
969 &spdif_clk.common,
970 &keypad_clk.common,
971 &sata_clk.common,
972 &usb_ohci0_clk.common,
973 &usb_ohci1_clk.common,
974 &usb_phy_clk.common,
975 &spi3_clk.common,
976 &i2s1_clk.common,
977 &i2s2_clk.common,
978 &dram_ve_clk.common,
979 &dram_csi0_clk.common,
980 &dram_csi1_clk.common,
981 &dram_ts_clk.common,
982 &dram_tvd_clk.common,
983 &dram_tve0_clk.common,
984 &dram_tve1_clk.common,
985 &dram_out_clk.common,
986 &dram_de_fe1_clk.common,
987 &dram_de_fe0_clk.common,
988 &dram_de_be0_clk.common,
989 &dram_de_be1_clk.common,
990 &dram_mp_clk.common,
991 &dram_ace_clk.common,
992 &de_be0_clk.common,
993 &de_be1_clk.common,
994 &de_fe0_clk.common,
995 &de_fe1_clk.common,
996 &de_mp_clk.common,
997 &tcon0_ch0_clk.common,
998 &tcon1_ch0_clk.common,
999 &csi_sclk_clk.common,
1000 &tvd_sun4i_clk.common,
1001 &tvd_sclk1_sun7i_clk.common,
1002 &tvd_sclk2_sun7i_clk.common,
1003 &tcon0_ch1_sclk2_clk.common,
1004 &tcon0_ch1_clk.common,
1005 &tcon1_ch1_sclk2_clk.common,
1006 &tcon1_ch1_clk.common,
1007 &csi0_clk.common,
1008 &csi1_clk.common,
1009 &ve_clk.common,
1010 &codec_clk.common,
1011 &avs_clk.common,
1012 &ace_clk.common,
1013 &hdmi_clk.common,
1014 &gpu_sun4i_clk.common,
1015 &gpu_sun7i_clk.common,
1016 &mbus_sun4i_clk.common,
1017 &mbus_sun7i_clk.common,
1018 &hdmi1_slow_clk.common,
1019 &hdmi1_clk.common,
1020 &out_a_clk.common,
1021 &out_b_clk.common
1022};
1023
1024/* Post-divider for pll-audio is hardcoded to 4 */
1025static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
1026 "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
1027static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
1028 "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
1029static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
1030 "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
1031static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
1032 "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
1033static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x",
1034 "pll-video0", 1, 2, CLK_SET_RATE_PARENT);
1035static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x",
1036 "pll-video1", 1, 2, CLK_SET_RATE_PARENT);
1037
1038
1039static struct clk_hw_onecell_data sun4i_a10_hw_clks = {
1040 .hws = {
1041 [CLK_HOSC] = &hosc_clk.common.hw,
1042 [CLK_PLL_CORE] = &pll_core_clk.common.hw,
1043 [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw,
1044 [CLK_PLL_AUDIO] = &pll_audio_clk.hw,
1045 [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw,
1046 [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw,
1047 [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw,
1048 [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw,
1049 [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw,
1050 [CLK_PLL_VE] = &pll_ve_sun4i_clk.common.hw,
1051 [CLK_PLL_DDR_BASE] = &pll_ddr_base_clk.common.hw,
1052 [CLK_PLL_DDR] = &pll_ddr_clk.common.hw,
1053 [CLK_PLL_DDR_OTHER] = &pll_ddr_other_clk.common.hw,
1054 [CLK_PLL_PERIPH_BASE] = &pll_periph_base_clk.common.hw,
1055 [CLK_PLL_PERIPH] = &pll_periph_clk.hw,
1056 [CLK_PLL_PERIPH_SATA] = &pll_periph_sata_clk.common.hw,
1057 [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw,
1058 [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw,
1059 [CLK_CPU] = &cpu_clk.common.hw,
1060 [CLK_AXI] = &axi_clk.common.hw,
1061 [CLK_AXI_DRAM] = &axi_dram_clk.common.hw,
1062 [CLK_AHB] = &ahb_sun4i_clk.common.hw,
1063 [CLK_APB0] = &apb0_clk.common.hw,
1064 [CLK_APB1] = &apb1_clk.common.hw,
1065 [CLK_AHB_OTG] = &ahb_otg_clk.common.hw,
1066 [CLK_AHB_EHCI0] = &ahb_ehci0_clk.common.hw,
1067 [CLK_AHB_OHCI0] = &ahb_ohci0_clk.common.hw,
1068 [CLK_AHB_EHCI1] = &ahb_ehci1_clk.common.hw,
1069 [CLK_AHB_OHCI1] = &ahb_ohci1_clk.common.hw,
1070 [CLK_AHB_SS] = &ahb_ss_clk.common.hw,
1071 [CLK_AHB_DMA] = &ahb_dma_clk.common.hw,
1072 [CLK_AHB_BIST] = &ahb_bist_clk.common.hw,
1073 [CLK_AHB_MMC0] = &ahb_mmc0_clk.common.hw,
1074 [CLK_AHB_MMC1] = &ahb_mmc1_clk.common.hw,
1075 [CLK_AHB_MMC2] = &ahb_mmc2_clk.common.hw,
1076 [CLK_AHB_MMC3] = &ahb_mmc3_clk.common.hw,
1077 [CLK_AHB_MS] = &ahb_ms_clk.common.hw,
1078 [CLK_AHB_NAND] = &ahb_nand_clk.common.hw,
1079 [CLK_AHB_SDRAM] = &ahb_sdram_clk.common.hw,
1080 [CLK_AHB_ACE] = &ahb_ace_clk.common.hw,
1081 [CLK_AHB_EMAC] = &ahb_emac_clk.common.hw,
1082 [CLK_AHB_TS] = &ahb_ts_clk.common.hw,
1083 [CLK_AHB_SPI0] = &ahb_spi0_clk.common.hw,
1084 [CLK_AHB_SPI1] = &ahb_spi1_clk.common.hw,
1085 [CLK_AHB_SPI2] = &ahb_spi2_clk.common.hw,
1086 [CLK_AHB_SPI3] = &ahb_spi3_clk.common.hw,
1087 [CLK_AHB_PATA] = &ahb_pata_clk.common.hw,
1088 [CLK_AHB_SATA] = &ahb_sata_clk.common.hw,
1089 [CLK_AHB_GPS] = &ahb_gps_clk.common.hw,
1090 [CLK_AHB_VE] = &ahb_ve_clk.common.hw,
1091 [CLK_AHB_TVD] = &ahb_tvd_clk.common.hw,
1092 [CLK_AHB_TVE0] = &ahb_tve0_clk.common.hw,
1093 [CLK_AHB_TVE1] = &ahb_tve1_clk.common.hw,
1094 [CLK_AHB_LCD0] = &ahb_lcd0_clk.common.hw,
1095 [CLK_AHB_LCD1] = &ahb_lcd1_clk.common.hw,
1096 [CLK_AHB_CSI0] = &ahb_csi0_clk.common.hw,
1097 [CLK_AHB_CSI1] = &ahb_csi1_clk.common.hw,
1098 [CLK_AHB_HDMI0] = &ahb_hdmi0_clk.common.hw,
1099 [CLK_AHB_DE_BE0] = &ahb_de_be0_clk.common.hw,
1100 [CLK_AHB_DE_BE1] = &ahb_de_be1_clk.common.hw,
1101 [CLK_AHB_DE_FE0] = &ahb_de_fe0_clk.common.hw,
1102 [CLK_AHB_DE_FE1] = &ahb_de_fe1_clk.common.hw,
1103 [CLK_AHB_MP] = &ahb_mp_clk.common.hw,
1104 [CLK_AHB_GPU] = &ahb_gpu_clk.common.hw,
1105 [CLK_APB0_CODEC] = &apb0_codec_clk.common.hw,
1106 [CLK_APB0_SPDIF] = &apb0_spdif_clk.common.hw,
1107 [CLK_APB0_AC97] = &apb0_ac97_clk.common.hw,
1108 [CLK_APB0_I2S0] = &apb0_i2s0_clk.common.hw,
1109 [CLK_APB0_PIO] = &apb0_pio_clk.common.hw,
1110 [CLK_APB0_IR0] = &apb0_ir0_clk.common.hw,
1111 [CLK_APB0_IR1] = &apb0_ir1_clk.common.hw,
1112 [CLK_APB0_KEYPAD] = &apb0_keypad_clk.common.hw,
1113 [CLK_APB1_I2C0] = &apb1_i2c0_clk.common.hw,
1114 [CLK_APB1_I2C1] = &apb1_i2c1_clk.common.hw,
1115 [CLK_APB1_I2C2] = &apb1_i2c2_clk.common.hw,
1116 [CLK_APB1_CAN] = &apb1_can_clk.common.hw,
1117 [CLK_APB1_SCR] = &apb1_scr_clk.common.hw,
1118 [CLK_APB1_PS20] = &apb1_ps20_clk.common.hw,
1119 [CLK_APB1_PS21] = &apb1_ps21_clk.common.hw,
1120 [CLK_APB1_UART0] = &apb1_uart0_clk.common.hw,
1121 [CLK_APB1_UART1] = &apb1_uart1_clk.common.hw,
1122 [CLK_APB1_UART2] = &apb1_uart2_clk.common.hw,
1123 [CLK_APB1_UART3] = &apb1_uart3_clk.common.hw,
1124 [CLK_APB1_UART4] = &apb1_uart4_clk.common.hw,
1125 [CLK_APB1_UART5] = &apb1_uart5_clk.common.hw,
1126 [CLK_APB1_UART6] = &apb1_uart6_clk.common.hw,
1127 [CLK_APB1_UART7] = &apb1_uart7_clk.common.hw,
1128 [CLK_NAND] = &nand_clk.common.hw,
1129 [CLK_MS] = &ms_clk.common.hw,
1130 [CLK_MMC0] = &mmc0_clk.common.hw,
1131 [CLK_MMC1] = &mmc1_clk.common.hw,
1132 [CLK_MMC2] = &mmc2_clk.common.hw,
1133 [CLK_MMC3] = &mmc3_clk.common.hw,
1134 [CLK_TS] = &ts_clk.common.hw,
1135 [CLK_SS] = &ss_clk.common.hw,
1136 [CLK_SPI0] = &spi0_clk.common.hw,
1137 [CLK_SPI1] = &spi1_clk.common.hw,
1138 [CLK_SPI2] = &spi2_clk.common.hw,
1139 [CLK_PATA] = &pata_clk.common.hw,
1140 [CLK_IR0] = &ir0_sun4i_clk.common.hw,
1141 [CLK_IR1] = &ir1_sun4i_clk.common.hw,
1142 [CLK_I2S0] = &i2s0_clk.common.hw,
1143 [CLK_AC97] = &ac97_clk.common.hw,
1144 [CLK_SPDIF] = &spdif_clk.common.hw,
1145 [CLK_KEYPAD] = &keypad_clk.common.hw,
1146 [CLK_SATA] = &sata_clk.common.hw,
1147 [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw,
1148 [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw,
1149 [CLK_USB_PHY] = &usb_phy_clk.common.hw,
1150 /* CLK_GPS is unimplemented */
1151 [CLK_SPI3] = &spi3_clk.common.hw,
1152 [CLK_DRAM_VE] = &dram_ve_clk.common.hw,
1153 [CLK_DRAM_CSI0] = &dram_csi0_clk.common.hw,
1154 [CLK_DRAM_CSI1] = &dram_csi1_clk.common.hw,
1155 [CLK_DRAM_TS] = &dram_ts_clk.common.hw,
1156 [CLK_DRAM_TVD] = &dram_tvd_clk.common.hw,
1157 [CLK_DRAM_TVE0] = &dram_tve0_clk.common.hw,
1158 [CLK_DRAM_TVE1] = &dram_tve1_clk.common.hw,
1159 [CLK_DRAM_OUT] = &dram_out_clk.common.hw,
1160 [CLK_DRAM_DE_FE1] = &dram_de_fe1_clk.common.hw,
1161 [CLK_DRAM_DE_FE0] = &dram_de_fe0_clk.common.hw,
1162 [CLK_DRAM_DE_BE0] = &dram_de_be0_clk.common.hw,
1163 [CLK_DRAM_DE_BE1] = &dram_de_be1_clk.common.hw,
1164 [CLK_DRAM_MP] = &dram_mp_clk.common.hw,
1165 [CLK_DRAM_ACE] = &dram_ace_clk.common.hw,
1166 [CLK_DE_BE0] = &de_be0_clk.common.hw,
1167 [CLK_DE_BE1] = &de_be1_clk.common.hw,
1168 [CLK_DE_FE0] = &de_fe0_clk.common.hw,
1169 [CLK_DE_FE1] = &de_fe1_clk.common.hw,
1170 [CLK_DE_MP] = &de_mp_clk.common.hw,
1171 [CLK_TCON0_CH0] = &tcon0_ch0_clk.common.hw,
1172 [CLK_TCON1_CH0] = &tcon1_ch0_clk.common.hw,
1173 [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw,
1174 [CLK_TVD] = &tvd_sun4i_clk.common.hw,
1175 [CLK_TCON0_CH1_SCLK2] = &tcon0_ch1_sclk2_clk.common.hw,
1176 [CLK_TCON0_CH1] = &tcon0_ch1_clk.common.hw,
1177 [CLK_TCON1_CH1_SCLK2] = &tcon1_ch1_sclk2_clk.common.hw,
1178 [CLK_TCON1_CH1] = &tcon1_ch1_clk.common.hw,
1179 [CLK_CSI0] = &csi0_clk.common.hw,
1180 [CLK_CSI1] = &csi1_clk.common.hw,
1181 [CLK_VE] = &ve_clk.common.hw,
1182 [CLK_CODEC] = &codec_clk.common.hw,
1183 [CLK_AVS] = &avs_clk.common.hw,
1184 [CLK_ACE] = &ace_clk.common.hw,
1185 [CLK_HDMI] = &hdmi_clk.common.hw,
1186 [CLK_GPU] = &gpu_sun7i_clk.common.hw,
1187 [CLK_MBUS] = &mbus_sun4i_clk.common.hw,
1188 },
1189 .num = CLK_NUMBER_SUN4I,
1190};
1191static struct clk_hw_onecell_data sun7i_a20_hw_clks = {
1192 .hws = {
1193 [CLK_HOSC] = &hosc_clk.common.hw,
1194 [CLK_PLL_CORE] = &pll_core_clk.common.hw,
1195 [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw,
1196 [CLK_PLL_AUDIO] = &pll_audio_clk.hw,
1197 [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw,
1198 [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw,
1199 [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw,
1200 [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw,
1201 [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw,
1202 [CLK_PLL_VE] = &pll_ve_sun7i_clk.common.hw,
1203 [CLK_PLL_DDR_BASE] = &pll_ddr_base_clk.common.hw,
1204 [CLK_PLL_DDR] = &pll_ddr_clk.common.hw,
1205 [CLK_PLL_DDR_OTHER] = &pll_ddr_other_clk.common.hw,
1206 [CLK_PLL_PERIPH_BASE] = &pll_periph_base_clk.common.hw,
1207 [CLK_PLL_PERIPH] = &pll_periph_clk.hw,
1208 [CLK_PLL_PERIPH_SATA] = &pll_periph_sata_clk.common.hw,
1209 [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw,
1210 [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw,
1211 [CLK_PLL_GPU] = &pll_gpu_clk.common.hw,
1212 [CLK_CPU] = &cpu_clk.common.hw,
1213 [CLK_AXI] = &axi_clk.common.hw,
1214 [CLK_AHB] = &ahb_sun7i_clk.common.hw,
1215 [CLK_APB0] = &apb0_clk.common.hw,
1216 [CLK_APB1] = &apb1_clk.common.hw,
1217 [CLK_AHB_OTG] = &ahb_otg_clk.common.hw,
1218 [CLK_AHB_EHCI0] = &ahb_ehci0_clk.common.hw,
1219 [CLK_AHB_OHCI0] = &ahb_ohci0_clk.common.hw,
1220 [CLK_AHB_EHCI1] = &ahb_ehci1_clk.common.hw,
1221 [CLK_AHB_OHCI1] = &ahb_ohci1_clk.common.hw,
1222 [CLK_AHB_SS] = &ahb_ss_clk.common.hw,
1223 [CLK_AHB_DMA] = &ahb_dma_clk.common.hw,
1224 [CLK_AHB_BIST] = &ahb_bist_clk.common.hw,
1225 [CLK_AHB_MMC0] = &ahb_mmc0_clk.common.hw,
1226 [CLK_AHB_MMC1] = &ahb_mmc1_clk.common.hw,
1227 [CLK_AHB_MMC2] = &ahb_mmc2_clk.common.hw,
1228 [CLK_AHB_MMC3] = &ahb_mmc3_clk.common.hw,
1229 [CLK_AHB_MS] = &ahb_ms_clk.common.hw,
1230 [CLK_AHB_NAND] = &ahb_nand_clk.common.hw,
1231 [CLK_AHB_SDRAM] = &ahb_sdram_clk.common.hw,
1232 [CLK_AHB_ACE] = &ahb_ace_clk.common.hw,
1233 [CLK_AHB_EMAC] = &ahb_emac_clk.common.hw,
1234 [CLK_AHB_TS] = &ahb_ts_clk.common.hw,
1235 [CLK_AHB_SPI0] = &ahb_spi0_clk.common.hw,
1236 [CLK_AHB_SPI1] = &ahb_spi1_clk.common.hw,
1237 [CLK_AHB_SPI2] = &ahb_spi2_clk.common.hw,
1238 [CLK_AHB_SPI3] = &ahb_spi3_clk.common.hw,
1239 [CLK_AHB_PATA] = &ahb_pata_clk.common.hw,
1240 [CLK_AHB_SATA] = &ahb_sata_clk.common.hw,
1241 [CLK_AHB_HSTIMER] = &ahb_hstimer_clk.common.hw,
1242 [CLK_AHB_VE] = &ahb_ve_clk.common.hw,
1243 [CLK_AHB_TVD] = &ahb_tvd_clk.common.hw,
1244 [CLK_AHB_TVE0] = &ahb_tve0_clk.common.hw,
1245 [CLK_AHB_TVE1] = &ahb_tve1_clk.common.hw,
1246 [CLK_AHB_LCD0] = &ahb_lcd0_clk.common.hw,
1247 [CLK_AHB_LCD1] = &ahb_lcd1_clk.common.hw,
1248 [CLK_AHB_CSI0] = &ahb_csi0_clk.common.hw,
1249 [CLK_AHB_CSI1] = &ahb_csi1_clk.common.hw,
1250 [CLK_AHB_HDMI1] = &ahb_hdmi1_clk.common.hw,
1251 [CLK_AHB_HDMI0] = &ahb_hdmi0_clk.common.hw,
1252 [CLK_AHB_DE_BE0] = &ahb_de_be0_clk.common.hw,
1253 [CLK_AHB_DE_BE1] = &ahb_de_be1_clk.common.hw,
1254 [CLK_AHB_DE_FE0] = &ahb_de_fe0_clk.common.hw,
1255 [CLK_AHB_DE_FE1] = &ahb_de_fe1_clk.common.hw,
1256 [CLK_AHB_GMAC] = &ahb_gmac_clk.common.hw,
1257 [CLK_AHB_MP] = &ahb_mp_clk.common.hw,
1258 [CLK_AHB_GPU] = &ahb_gpu_clk.common.hw,
1259 [CLK_APB0_CODEC] = &apb0_codec_clk.common.hw,
1260 [CLK_APB0_SPDIF] = &apb0_spdif_clk.common.hw,
1261 [CLK_APB0_AC97] = &apb0_ac97_clk.common.hw,
1262 [CLK_APB0_I2S0] = &apb0_i2s0_clk.common.hw,
1263 [CLK_APB0_I2S1] = &apb0_i2s1_clk.common.hw,
1264 [CLK_APB0_PIO] = &apb0_pio_clk.common.hw,
1265 [CLK_APB0_IR0] = &apb0_ir0_clk.common.hw,
1266 [CLK_APB0_IR1] = &apb0_ir1_clk.common.hw,
1267 [CLK_APB0_I2S2] = &apb0_i2s2_clk.common.hw,
1268 [CLK_APB0_KEYPAD] = &apb0_keypad_clk.common.hw,
1269 [CLK_APB1_I2C0] = &apb1_i2c0_clk.common.hw,
1270 [CLK_APB1_I2C1] = &apb1_i2c1_clk.common.hw,
1271 [CLK_APB1_I2C2] = &apb1_i2c2_clk.common.hw,
1272 [CLK_APB1_I2C3] = &apb1_i2c3_clk.common.hw,
1273 [CLK_APB1_CAN] = &apb1_can_clk.common.hw,
1274 [CLK_APB1_SCR] = &apb1_scr_clk.common.hw,
1275 [CLK_APB1_PS20] = &apb1_ps20_clk.common.hw,
1276 [CLK_APB1_PS21] = &apb1_ps21_clk.common.hw,
1277 [CLK_APB1_I2C4] = &apb1_i2c4_clk.common.hw,
1278 [CLK_APB1_UART0] = &apb1_uart0_clk.common.hw,
1279 [CLK_APB1_UART1] = &apb1_uart1_clk.common.hw,
1280 [CLK_APB1_UART2] = &apb1_uart2_clk.common.hw,
1281 [CLK_APB1_UART3] = &apb1_uart3_clk.common.hw,
1282 [CLK_APB1_UART4] = &apb1_uart4_clk.common.hw,
1283 [CLK_APB1_UART5] = &apb1_uart5_clk.common.hw,
1284 [CLK_APB1_UART6] = &apb1_uart6_clk.common.hw,
1285 [CLK_APB1_UART7] = &apb1_uart7_clk.common.hw,
1286 [CLK_NAND] = &nand_clk.common.hw,
1287 [CLK_MS] = &ms_clk.common.hw,
1288 [CLK_MMC0] = &mmc0_clk.common.hw,
1289 [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw,
1290 [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw,
1291 [CLK_MMC1] = &mmc1_clk.common.hw,
1292 [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw,
1293 [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw,
1294 [CLK_MMC2] = &mmc2_clk.common.hw,
1295 [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw,
1296 [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw,
1297 [CLK_MMC3] = &mmc3_clk.common.hw,
1298 [CLK_MMC3_OUTPUT] = &mmc3_output_clk.common.hw,
1299 [CLK_MMC3_SAMPLE] = &mmc3_sample_clk.common.hw,
1300 [CLK_TS] = &ts_clk.common.hw,
1301 [CLK_SS] = &ss_clk.common.hw,
1302 [CLK_SPI0] = &spi0_clk.common.hw,
1303 [CLK_SPI1] = &spi1_clk.common.hw,
1304 [CLK_SPI2] = &spi2_clk.common.hw,
1305 [CLK_PATA] = &pata_clk.common.hw,
1306 [CLK_IR0] = &ir0_sun7i_clk.common.hw,
1307 [CLK_IR1] = &ir1_sun7i_clk.common.hw,
1308 [CLK_I2S0] = &i2s0_clk.common.hw,
1309 [CLK_AC97] = &ac97_clk.common.hw,
1310 [CLK_SPDIF] = &spdif_clk.common.hw,
1311 [CLK_KEYPAD] = &keypad_clk.common.hw,
1312 [CLK_SATA] = &sata_clk.common.hw,
1313 [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw,
1314 [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw,
1315 [CLK_USB_PHY] = &usb_phy_clk.common.hw,
1316 /* CLK_GPS is unimplemented */
1317 [CLK_SPI3] = &spi3_clk.common.hw,
1318 [CLK_I2S1] = &i2s1_clk.common.hw,
1319 [CLK_I2S2] = &i2s2_clk.common.hw,
1320 [CLK_DRAM_VE] = &dram_ve_clk.common.hw,
1321 [CLK_DRAM_CSI0] = &dram_csi0_clk.common.hw,
1322 [CLK_DRAM_CSI1] = &dram_csi1_clk.common.hw,
1323 [CLK_DRAM_TS] = &dram_ts_clk.common.hw,
1324 [CLK_DRAM_TVD] = &dram_tvd_clk.common.hw,
1325 [CLK_DRAM_TVE0] = &dram_tve0_clk.common.hw,
1326 [CLK_DRAM_TVE1] = &dram_tve1_clk.common.hw,
1327 [CLK_DRAM_OUT] = &dram_out_clk.common.hw,
1328 [CLK_DRAM_DE_FE1] = &dram_de_fe1_clk.common.hw,
1329 [CLK_DRAM_DE_FE0] = &dram_de_fe0_clk.common.hw,
1330 [CLK_DRAM_DE_BE0] = &dram_de_be0_clk.common.hw,
1331 [CLK_DRAM_DE_BE1] = &dram_de_be1_clk.common.hw,
1332 [CLK_DRAM_MP] = &dram_mp_clk.common.hw,
1333 [CLK_DRAM_ACE] = &dram_ace_clk.common.hw,
1334 [CLK_DE_BE0] = &de_be0_clk.common.hw,
1335 [CLK_DE_BE1] = &de_be1_clk.common.hw,
1336 [CLK_DE_FE0] = &de_fe0_clk.common.hw,
1337 [CLK_DE_FE1] = &de_fe1_clk.common.hw,
1338 [CLK_DE_MP] = &de_mp_clk.common.hw,
1339 [CLK_TCON0_CH0] = &tcon0_ch0_clk.common.hw,
1340 [CLK_TCON1_CH0] = &tcon1_ch0_clk.common.hw,
1341 [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw,
1342 [CLK_TVD_SCLK2] = &tvd_sclk2_sun7i_clk.common.hw,
1343 [CLK_TVD] = &tvd_sclk1_sun7i_clk.common.hw,
1344 [CLK_TCON0_CH1_SCLK2] = &tcon0_ch1_sclk2_clk.common.hw,
1345 [CLK_TCON0_CH1] = &tcon0_ch1_clk.common.hw,
1346 [CLK_TCON1_CH1_SCLK2] = &tcon1_ch1_sclk2_clk.common.hw,
1347 [CLK_TCON1_CH1] = &tcon1_ch1_clk.common.hw,
1348 [CLK_CSI0] = &csi0_clk.common.hw,
1349 [CLK_CSI1] = &csi1_clk.common.hw,
1350 [CLK_VE] = &ve_clk.common.hw,
1351 [CLK_CODEC] = &codec_clk.common.hw,
1352 [CLK_AVS] = &avs_clk.common.hw,
1353 [CLK_ACE] = &ace_clk.common.hw,
1354 [CLK_HDMI] = &hdmi_clk.common.hw,
1355 [CLK_GPU] = &gpu_sun7i_clk.common.hw,
1356 [CLK_MBUS] = &mbus_sun7i_clk.common.hw,
1357 [CLK_HDMI1_SLOW] = &hdmi1_slow_clk.common.hw,
1358 [CLK_HDMI1] = &hdmi1_clk.common.hw,
1359 [CLK_OUT_A] = &out_a_clk.common.hw,
1360 [CLK_OUT_B] = &out_b_clk.common.hw,
1361 },
1362 .num = CLK_NUMBER_SUN7I,
1363};
1364
1365static struct ccu_reset_map sunxi_a10_a20_ccu_resets[] = {
1366 [RST_USB_PHY0] = { 0x0cc, BIT(0) },
1367 [RST_USB_PHY1] = { 0x0cc, BIT(1) },
1368 [RST_USB_PHY2] = { 0x0cc, BIT(2) },
1369 [RST_GPS] = { 0x0d0, BIT(0) },
1370 [RST_DE_BE0] = { 0x104, BIT(30) },
1371 [RST_DE_BE1] = { 0x108, BIT(30) },
1372 [RST_DE_FE0] = { 0x10c, BIT(30) },
1373 [RST_DE_FE1] = { 0x110, BIT(30) },
1374 [RST_DE_MP] = { 0x114, BIT(30) },
1375 [RST_TVE0] = { 0x118, BIT(29) },
1376 [RST_TCON0] = { 0x118, BIT(30) },
1377 [RST_TVE1] = { 0x11c, BIT(29) },
1378 [RST_TCON1] = { 0x11c, BIT(30) },
1379 [RST_CSI0] = { 0x134, BIT(30) },
1380 [RST_CSI1] = { 0x138, BIT(30) },
1381 [RST_VE] = { 0x13c, BIT(0) },
1382 [RST_ACE] = { 0x148, BIT(16) },
1383 [RST_LVDS] = { 0x14c, BIT(0) },
1384 [RST_GPU] = { 0x154, BIT(30) },
1385 [RST_HDMI_H] = { 0x170, BIT(0) },
1386 [RST_HDMI_SYS] = { 0x170, BIT(1) },
1387 [RST_HDMI_AUDIO_DMA] = { 0x170, BIT(2) },
1388};
1389
1390static const struct sunxi_ccu_desc sun4i_a10_ccu_desc = {
1391 .ccu_clks = sun4i_sun7i_ccu_clks,
1392 .num_ccu_clks = ARRAY_SIZE(sun4i_sun7i_ccu_clks),
1393
1394 .hw_clks = &sun4i_a10_hw_clks,
1395
1396 .resets = sunxi_a10_a20_ccu_resets,
1397 .num_resets = ARRAY_SIZE(sunxi_a10_a20_ccu_resets),
1398};
1399
1400static const struct sunxi_ccu_desc sun7i_a20_ccu_desc = {
1401 .ccu_clks = sun4i_sun7i_ccu_clks,
1402 .num_ccu_clks = ARRAY_SIZE(sun4i_sun7i_ccu_clks),
1403
1404 .hw_clks = &sun7i_a20_hw_clks,
1405
1406 .resets = sunxi_a10_a20_ccu_resets,
1407 .num_resets = ARRAY_SIZE(sunxi_a10_a20_ccu_resets),
1408};
1409
1410static void __init sun4i_ccu_init(struct device_node *node,
1411 const struct sunxi_ccu_desc *desc)
1412{
1413 void __iomem *reg;
1414 u32 val;
1415
1416 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
1417 if (IS_ERR(reg)) {
1418 pr_err("%s: Could not map the clock registers\n",
1419 of_node_full_name(node));
1420 return;
1421 }
1422
1423 /* Force the PLL-Audio-1x divider to 4 */
1424 val = readl(reg + SUN4I_PLL_AUDIO_REG);
1425 val &= ~GENMASK(29, 26);
1426 writel(val | (4 << 26), reg + SUN4I_PLL_AUDIO_REG);
1427
1428 /*
1429 * Use the peripheral PLL6 as the AHB parent, instead of CPU /
1430 * AXI which have rate changes due to cpufreq.
1431 *
1432 * This is especially a big deal for the HS timer whose parent
1433 * clock is AHB.
1434 *
1435 * NB! These bits are undocumented in A10 manual.
1436 */
1437 val = readl(reg + SUN4I_AHB_REG);
1438 val &= ~GENMASK(7, 6);
1439 writel(val | (2 << 6), reg + SUN4I_AHB_REG);
1440
1441 sunxi_ccu_probe(node, reg, desc);
1442}
1443
1444static void __init sun4i_a10_ccu_setup(struct device_node *node)
1445{
1446 sun4i_ccu_init(node, &sun4i_a10_ccu_desc);
1447}
1448CLK_OF_DECLARE(sun4i_a10_ccu, "allwinner,sun4i-a10-ccu",
1449 sun4i_a10_ccu_setup);
1450
1451static void __init sun7i_a20_ccu_setup(struct device_node *node)
1452{
1453 sun4i_ccu_init(node, &sun7i_a20_ccu_desc);
1454}
1455CLK_OF_DECLARE(sun7i_a20_ccu, "allwinner,sun7i-a20-ccu",
1456 sun7i_a20_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.h b/drivers/clk/sunxi-ng/ccu-sun4i-a10.h
new file mode 100644
index 000000000000..c5947c7c050e
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun4i-a10.h
@@ -0,0 +1,61 @@
1/*
2 * Copyright 2017 Priit Laes
3 *
4 * Priit Laes <plaes@plaes.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_SUN4I_A10_H_
18#define _CCU_SUN4I_A10_H_
19
20#include <dt-bindings/clock/sun4i-a10-ccu.h>
21#include <dt-bindings/clock/sun7i-a20-ccu.h>
22#include <dt-bindings/reset/sun4i-a10-ccu.h>
23
24/* The HOSC is exported */
25#define CLK_PLL_CORE 2
26#define CLK_PLL_AUDIO_BASE 3
27#define CLK_PLL_AUDIO 4
28#define CLK_PLL_AUDIO_2X 5
29#define CLK_PLL_AUDIO_4X 6
30#define CLK_PLL_AUDIO_8X 7
31#define CLK_PLL_VIDEO0 8
32#define CLK_PLL_VIDEO0_2X 9
33#define CLK_PLL_VE 10
34#define CLK_PLL_DDR_BASE 11
35#define CLK_PLL_DDR 12
36#define CLK_PLL_DDR_OTHER 13
37#define CLK_PLL_PERIPH_BASE 14
38#define CLK_PLL_PERIPH 15
39#define CLK_PLL_PERIPH_SATA 16
40#define CLK_PLL_VIDEO1 17
41#define CLK_PLL_VIDEO1_2X 18
42#define CLK_PLL_GPU 19
43
44/* The CPU clock is exported */
45#define CLK_AXI 21
46#define CLK_AXI_DRAM 22
47#define CLK_AHB 23
48#define CLK_APB0 24
49#define CLK_APB1 25
50
51/* AHB gates are exported (23..68) */
52/* APB0 gates are exported (69..78) */
53/* APB1 gates are exported (79..95) */
54/* IP module clocks are exported (96..128) */
55/* DRAM gates are exported (129..142)*/
56/* Media (display engine clocks & etc) are exported (143..169) */
57
58#define CLK_NUMBER_SUN4I (CLK_MBUS + 1)
59#define CLK_NUMBER_SUN7I (CLK_OUT_B + 1)
60
61#endif /* _CCU_SUN4I_A10_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.c b/drivers/clk/sunxi-ng/ccu-sun5i.c
index 31d7ffda9aab..ab9e850b3707 100644
--- a/drivers/clk/sunxi-ng/ccu-sun5i.c
+++ b/drivers/clk/sunxi-ng/ccu-sun5i.c
@@ -976,8 +976,7 @@ static void __init sun5i_ccu_init(struct device_node *node,
976 976
977 reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 977 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
978 if (IS_ERR(reg)) { 978 if (IS_ERR(reg)) {
979 pr_err("%s: Could not map the clock registers\n", 979 pr_err("%pOF: Could not map the clock registers\n", node);
980 of_node_full_name(node));
981 return; 980 return;
982 } 981 }
983 982
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
index 4d6078fca9ac..8af434815fba 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
@@ -1217,8 +1217,7 @@ static void __init sun6i_a31_ccu_setup(struct device_node *node)
1217 1217
1218 reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 1218 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
1219 if (IS_ERR(reg)) { 1219 if (IS_ERR(reg)) {
1220 pr_err("%s: Could not map the clock registers\n", 1220 pr_err("%pOF: Could not map the clock registers\n", node);
1221 of_node_full_name(node));
1222 return; 1221 return;
1223 } 1222 }
1224 1223
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
index 8a753ed0426d..d93b452f0df9 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
@@ -716,8 +716,7 @@ static void __init sun8i_a23_ccu_setup(struct device_node *node)
716 716
717 reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 717 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
718 if (IS_ERR(reg)) { 718 if (IS_ERR(reg)) {
719 pr_err("%s: Could not map the clock registers\n", 719 pr_err("%pOF: Could not map the clock registers\n", node);
720 of_node_full_name(node));
721 return; 720 return;
722 } 721 }
723 722
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
index 10b38dc46f75..13eb5b23c5e7 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
@@ -777,8 +777,7 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node)
777 777
778 reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 778 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
779 if (IS_ERR(reg)) { 779 if (IS_ERR(reg)) {
780 pr_err("%s: Could not map the clock registers\n", 780 pr_err("%pOF: Could not map the clock registers\n", node);
781 of_node_full_name(node));
782 return; 781 return;
783 } 782 }
784 783
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
index 62e4f0d2b2fc..1729ff6a5aae 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
@@ -135,7 +135,7 @@ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de",
135static const char * const cpux_parents[] = { "osc32k", "osc24M", 135static const char * const cpux_parents[] = { "osc32k", "osc24M",
136 "pll-cpux" , "pll-cpux" }; 136 "pll-cpux" , "pll-cpux" };
137static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents, 137static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
138 0x050, 16, 2, CLK_IS_CRITICAL); 138 0x050, 16, 2, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT);
139 139
140static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0); 140static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0);
141 141
@@ -1103,6 +1103,13 @@ static const struct sunxi_ccu_desc sun50i_h5_ccu_desc = {
1103 .num_resets = ARRAY_SIZE(sun50i_h5_ccu_resets), 1103 .num_resets = ARRAY_SIZE(sun50i_h5_ccu_resets),
1104}; 1104};
1105 1105
1106static struct ccu_pll_nb sun8i_h3_pll_cpu_nb = {
1107 .common = &pll_cpux_clk.common,
1108 /* copy from pll_cpux_clk */
1109 .enable = BIT(31),
1110 .lock = BIT(28),
1111};
1112
1106static struct ccu_mux_nb sun8i_h3_cpu_nb = { 1113static struct ccu_mux_nb sun8i_h3_cpu_nb = {
1107 .common = &cpux_clk.common, 1114 .common = &cpux_clk.common,
1108 .cm = &cpux_clk.mux, 1115 .cm = &cpux_clk.mux,
@@ -1118,8 +1125,7 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node,
1118 1125
1119 reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 1126 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
1120 if (IS_ERR(reg)) { 1127 if (IS_ERR(reg)) {
1121 pr_err("%s: Could not map the clock registers\n", 1128 pr_err("%pOF: Could not map the clock registers\n", node);
1122 of_node_full_name(node));
1123 return; 1129 return;
1124 } 1130 }
1125 1131
@@ -1130,6 +1136,10 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node,
1130 1136
1131 sunxi_ccu_probe(node, reg, desc); 1137 sunxi_ccu_probe(node, reg, desc);
1132 1138
1139 /* Gate then ungate PLL CPU after any rate changes */
1140 ccu_pll_notifier_register(&sun8i_h3_pll_cpu_nb);
1141
1142 /* Reparent CPU during PLL CPU rate changes */
1133 ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, 1143 ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
1134 &sun8i_h3_cpu_nb); 1144 &sun8i_h3_cpu_nb);
1135} 1145}
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
index e54816ec1dbe..71feb7b24e8a 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-r.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
@@ -290,8 +290,7 @@ static void __init sunxi_r_ccu_init(struct device_node *node,
290 290
291 reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 291 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
292 if (IS_ERR(reg)) { 292 if (IS_ERR(reg)) {
293 pr_err("%s: Could not map the clock registers\n", 293 pr_err("%pOF: Could not map the clock registers\n", node);
294 of_node_full_name(node));
295 return; 294 return;
296 } 295 }
297 296
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.h b/drivers/clk/sunxi-ng/ccu-sun8i-r.h
index a7a407f12b56..fb01bffb929d 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-r.h
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.h
@@ -13,7 +13,7 @@
13 */ 13 */
14 14
15#ifndef _CCU_SUN8I_R_H 15#ifndef _CCU_SUN8I_R_H
16#define _CCU_SUN8I_R_H_ 16#define _CCU_SUN8I_R_H
17 17
18#include <dt-bindings/clock/sun8i-r-ccu.h> 18#include <dt-bindings/clock/sun8i-r-ccu.h>
19#include <dt-bindings/reset/sun8i-r-ccu.h> 19#include <dt-bindings/reset/sun8i-r-ccu.h>
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
new file mode 100644
index 000000000000..933f2e68f42a
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
@@ -0,0 +1,1290 @@
1/*
2 * Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.io>
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-r40.h"
31
32/* TODO: The result of N*K is required to be in [10, 88] range. */
33static struct ccu_nkmp pll_cpu_clk = {
34 .enable = BIT(31),
35 .lock = BIT(28),
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 .common = {
41 .reg = 0x000,
42 .hw.init = CLK_HW_INIT("pll-cpu",
43 "osc24M",
44 &ccu_nkmp_ops,
45 CLK_SET_RATE_UNGATE),
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_R40_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
67/* TODO: The result of N/M is required to be in [8, 25] range. */
68static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0",
69 "osc24M", 0x0010,
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
80/* TODO: The result of N/M is required to be in [8, 25] range. */
81static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
82 "osc24M", 0x0018,
83 8, 7, /* N */
84 0, 4, /* M */
85 BIT(24), /* frac enable */
86 BIT(25), /* frac select */
87 270000000, /* frac rate 0 */
88 297000000, /* frac rate 1 */
89 BIT(31), /* gate */
90 BIT(28), /* lock */
91 CLK_SET_RATE_UNGATE);
92
93/* TODO: The result of N*K is required to be in [10, 77] range. */
94static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr0_clk, "pll-ddr0",
95 "osc24M", 0x020,
96 8, 5, /* N */
97 4, 2, /* K */
98 0, 2, /* M */
99 BIT(31), /* gate */
100 BIT(28), /* lock */
101 CLK_SET_RATE_UNGATE);
102
103/* TODO: The result of N*K is required to be in [21, 58] range. */
104static struct ccu_nk pll_periph0_clk = {
105 .enable = BIT(31),
106 .lock = BIT(28),
107 .n = _SUNXI_CCU_MULT(8, 5),
108 .k = _SUNXI_CCU_MULT(4, 2),
109 .fixed_post_div = 2,
110 .common = {
111 .reg = 0x028,
112 .features = CCU_FEATURE_FIXED_POSTDIV,
113 .hw.init = CLK_HW_INIT("pll-periph0", "osc24M",
114 &ccu_nk_ops,
115 CLK_SET_RATE_UNGATE),
116 },
117};
118
119static struct ccu_div pll_periph0_sata_clk = {
120 .enable = BIT(24),
121 .div = _SUNXI_CCU_DIV(0, 2),
122 /*
123 * The formula of pll-periph0 (1x) is 24MHz*N*K/2, and the formula
124 * of pll-periph0-sata is 24MHz*N*K/M/6, so the postdiv here is
125 * 6/2 = 3.
126 */
127 .fixed_post_div = 3,
128 .common = {
129 .reg = 0x028,
130 .features = CCU_FEATURE_FIXED_POSTDIV,
131 .hw.init = CLK_HW_INIT("pll-periph0-sata",
132 "pll-periph0",
133 &ccu_div_ops, 0),
134 },
135};
136
137/* TODO: The result of N*K is required to be in [21, 58] range. */
138static struct ccu_nk pll_periph1_clk = {
139 .enable = BIT(31),
140 .lock = BIT(28),
141 .n = _SUNXI_CCU_MULT(8, 5),
142 .k = _SUNXI_CCU_MULT(4, 2),
143 .fixed_post_div = 2,
144 .common = {
145 .reg = 0x02c,
146 .features = CCU_FEATURE_FIXED_POSTDIV,
147 .hw.init = CLK_HW_INIT("pll-periph1", "osc24M",
148 &ccu_nk_ops,
149 CLK_SET_RATE_UNGATE),
150 },
151};
152
153/* TODO: The result of N/M is required to be in [8, 25] range. */
154static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1",
155 "osc24M", 0x030,
156 8, 7, /* N */
157 0, 4, /* M */
158 BIT(24), /* frac enable */
159 BIT(25), /* frac select */
160 270000000, /* frac rate 0 */
161 297000000, /* frac rate 1 */
162 BIT(31), /* gate */
163 BIT(28), /* lock */
164 CLK_SET_RATE_UNGATE);
165
166static struct ccu_nkm pll_sata_clk = {
167 .enable = BIT(31),
168 .lock = BIT(28),
169 .n = _SUNXI_CCU_MULT(8, 5),
170 .k = _SUNXI_CCU_MULT(4, 2),
171 .m = _SUNXI_CCU_DIV(0, 2),
172 .fixed_post_div = 6,
173 .common = {
174 .reg = 0x034,
175 .features = CCU_FEATURE_FIXED_POSTDIV,
176 .hw.init = CLK_HW_INIT("pll-sata", "osc24M",
177 &ccu_nkm_ops,
178 CLK_SET_RATE_UNGATE),
179 },
180};
181
182static const char * const pll_sata_out_parents[] = { "pll-sata",
183 "pll-periph0-sata" };
184static SUNXI_CCU_MUX_WITH_GATE(pll_sata_out_clk, "pll-sata-out",
185 pll_sata_out_parents, 0x034,
186 30, 1, /* mux */
187 BIT(14), /* gate */
188 CLK_SET_RATE_PARENT);
189
190/* TODO: The result of N/M is required to be in [8, 25] range. */
191static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
192 "osc24M", 0x038,
193 8, 7, /* N */
194 0, 4, /* M */
195 BIT(24), /* frac enable */
196 BIT(25), /* frac select */
197 270000000, /* frac rate 0 */
198 297000000, /* frac rate 1 */
199 BIT(31), /* gate */
200 BIT(28), /* lock */
201 CLK_SET_RATE_UNGATE);
202
203/*
204 * The MIPI PLL has 2 modes: "MIPI" and "HDMI".
205 *
206 * The MIPI mode is a standard NKM-style clock. The HDMI mode is an
207 * integer / fractional clock with switchable multipliers and dividers.
208 * This is not supported here. We hardcode the PLL to MIPI mode.
209 *
210 * TODO: In the MIPI mode, M/N is required to be equal or lesser than 3,
211 * which cannot be implemented now.
212 */
213#define SUN8I_R40_PLL_MIPI_REG 0x040
214
215static const char * const pll_mipi_parents[] = { "pll-video0" };
216static struct ccu_nkm pll_mipi_clk = {
217 .enable = BIT(31) | BIT(23) | BIT(22),
218 .lock = BIT(28),
219 .n = _SUNXI_CCU_MULT(8, 4),
220 .k = _SUNXI_CCU_MULT_MIN(4, 2, 2),
221 .m = _SUNXI_CCU_DIV(0, 4),
222 .mux = _SUNXI_CCU_MUX(21, 1),
223 .common = {
224 .reg = 0x040,
225 .hw.init = CLK_HW_INIT_PARENTS("pll-mipi",
226 pll_mipi_parents,
227 &ccu_nkm_ops,
228 CLK_SET_RATE_UNGATE)
229 },
230};
231
232/* TODO: The result of N/M is required to be in [8, 25] range. */
233static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de",
234 "osc24M", 0x048,
235 8, 7, /* N */
236 0, 4, /* M */
237 BIT(24), /* frac enable */
238 BIT(25), /* frac select */
239 270000000, /* frac rate 0 */
240 297000000, /* frac rate 1 */
241 BIT(31), /* gate */
242 BIT(28), /* lock */
243 CLK_SET_RATE_UNGATE);
244
245/* TODO: The N factor is required to be in [16, 75] range. */
246static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_ddr1_clk, "pll-ddr1",
247 "osc24M", 0x04c,
248 8, 7, /* N */
249 0, 2, /* M */
250 BIT(31), /* gate */
251 BIT(28), /* lock */
252 CLK_SET_RATE_UNGATE);
253
254static const char * const cpu_parents[] = { "osc32k", "osc24M",
255 "pll-cpu", "pll-cpu" };
256static SUNXI_CCU_MUX(cpu_clk, "cpu", cpu_parents,
257 0x050, 16, 2, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT);
258
259static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x050, 0, 2, 0);
260
261static const char * const ahb1_parents[] = { "osc32k", "osc24M",
262 "axi", "pll-periph0" };
263static const struct ccu_mux_var_prediv ahb1_predivs[] = {
264 { .index = 3, .shift = 6, .width = 2 },
265};
266static struct ccu_div ahb1_clk = {
267 .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
268
269 .mux = {
270 .shift = 12,
271 .width = 2,
272
273 .var_predivs = ahb1_predivs,
274 .n_var_predivs = ARRAY_SIZE(ahb1_predivs),
275 },
276
277 .common = {
278 .reg = 0x054,
279 .features = CCU_FEATURE_VARIABLE_PREDIV,
280 .hw.init = CLK_HW_INIT_PARENTS("ahb1",
281 ahb1_parents,
282 &ccu_div_ops,
283 0),
284 },
285};
286
287static struct clk_div_table apb1_div_table[] = {
288 { .val = 0, .div = 2 },
289 { .val = 1, .div = 2 },
290 { .val = 2, .div = 4 },
291 { .val = 3, .div = 8 },
292 { /* Sentinel */ },
293};
294static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1",
295 0x054, 8, 2, apb1_div_table, 0);
296
297static const char * const apb2_parents[] = { "osc32k", "osc24M",
298 "pll-periph0-2x",
299 "pll-periph0-2x" };
300static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
301 0, 5, /* M */
302 16, 2, /* P */
303 24, 2, /* mux */
304 0);
305
306static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb1",
307 0x060, BIT(1), 0);
308static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "ahb1",
309 0x060, BIT(5), 0);
310static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1",
311 0x060, BIT(6), 0);
312static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1",
313 0x060, BIT(8), 0);
314static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1",
315 0x060, BIT(9), 0);
316static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1",
317 0x060, BIT(10), 0);
318static SUNXI_CCU_GATE(bus_mmc3_clk, "bus-mmc3", "ahb1",
319 0x060, BIT(11), 0);
320static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb1",
321 0x060, BIT(13), 0);
322static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1",
323 0x060, BIT(14), 0);
324static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb1",
325 0x060, BIT(17), 0);
326static SUNXI_CCU_GATE(bus_ts_clk, "bus-ts", "ahb1",
327 0x060, BIT(18), 0);
328static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1",
329 0x060, BIT(19), 0);
330static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1",
331 0x060, BIT(20), 0);
332static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb1",
333 0x060, BIT(21), 0);
334static SUNXI_CCU_GATE(bus_spi2_clk, "bus-spi2", "ahb1",
335 0x060, BIT(22), 0);
336static SUNXI_CCU_GATE(bus_spi3_clk, "bus-spi3", "ahb1",
337 0x060, BIT(23), 0);
338static SUNXI_CCU_GATE(bus_sata_clk, "bus-sata", "ahb1",
339 0x060, BIT(24), 0);
340static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1",
341 0x060, BIT(25), 0);
342static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb1",
343 0x060, BIT(26), 0);
344static SUNXI_CCU_GATE(bus_ehci1_clk, "bus-ehci1", "ahb1",
345 0x060, BIT(27), 0);
346static SUNXI_CCU_GATE(bus_ehci2_clk, "bus-ehci2", "ahb1",
347 0x060, BIT(28), 0);
348static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb1",
349 0x060, BIT(29), 0);
350static SUNXI_CCU_GATE(bus_ohci1_clk, "bus-ohci1", "ahb1",
351 0x060, BIT(30), 0);
352static SUNXI_CCU_GATE(bus_ohci2_clk, "bus-ohci2", "ahb1",
353 0x060, BIT(31), 0);
354
355static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb1",
356 0x064, BIT(0), 0);
357static SUNXI_CCU_GATE(bus_mp_clk, "bus-mp", "ahb1",
358 0x064, BIT(2), 0);
359static SUNXI_CCU_GATE(bus_deinterlace_clk, "bus-deinterlace", "ahb1",
360 0x064, BIT(5), 0);
361static SUNXI_CCU_GATE(bus_csi0_clk, "bus-csi0", "ahb1",
362 0x064, BIT(8), 0);
363static SUNXI_CCU_GATE(bus_csi1_clk, "bus-csi1", "ahb1",
364 0x064, BIT(9), 0);
365static SUNXI_CCU_GATE(bus_hdmi0_clk, "bus-hdmi0", "ahb1",
366 0x064, BIT(10), 0);
367static SUNXI_CCU_GATE(bus_hdmi1_clk, "bus-hdmi1", "ahb1",
368 0x064, BIT(11), 0);
369static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "ahb1",
370 0x064, BIT(12), 0);
371static SUNXI_CCU_GATE(bus_tve0_clk, "bus-tve0", "ahb1",
372 0x064, BIT(13), 0);
373static SUNXI_CCU_GATE(bus_tve1_clk, "bus-tve1", "ahb1",
374 0x064, BIT(14), 0);
375static SUNXI_CCU_GATE(bus_tve_top_clk, "bus-tve-top", "ahb1",
376 0x064, BIT(15), 0);
377static SUNXI_CCU_GATE(bus_gmac_clk, "bus-gmac", "ahb1",
378 0x064, BIT(17), 0);
379static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "ahb1",
380 0x064, BIT(20), 0);
381static SUNXI_CCU_GATE(bus_tvd0_clk, "bus-tvd0", "ahb1",
382 0x064, BIT(21), 0);
383static SUNXI_CCU_GATE(bus_tvd1_clk, "bus-tvd1", "ahb1",
384 0x064, BIT(22), 0);
385static SUNXI_CCU_GATE(bus_tvd2_clk, "bus-tvd2", "ahb1",
386 0x064, BIT(23), 0);
387static SUNXI_CCU_GATE(bus_tvd3_clk, "bus-tvd3", "ahb1",
388 0x064, BIT(24), 0);
389static SUNXI_CCU_GATE(bus_tvd_top_clk, "bus-tvd-top", "ahb1",
390 0x064, BIT(25), 0);
391static SUNXI_CCU_GATE(bus_tcon_lcd0_clk, "bus-tcon-lcd0", "ahb1",
392 0x064, BIT(26), 0);
393static SUNXI_CCU_GATE(bus_tcon_lcd1_clk, "bus-tcon-lcd1", "ahb1",
394 0x064, BIT(27), 0);
395static SUNXI_CCU_GATE(bus_tcon_tv0_clk, "bus-tcon-tv0", "ahb1",
396 0x064, BIT(28), 0);
397static SUNXI_CCU_GATE(bus_tcon_tv1_clk, "bus-tcon-tv1", "ahb1",
398 0x064, BIT(29), 0);
399static SUNXI_CCU_GATE(bus_tcon_top_clk, "bus-tcon-top", "ahb1",
400 0x064, BIT(30), 0);
401
402static SUNXI_CCU_GATE(bus_codec_clk, "bus-codec", "apb1",
403 0x068, BIT(0), 0);
404static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1",
405 0x068, BIT(1), 0);
406static SUNXI_CCU_GATE(bus_ac97_clk, "bus-ac97", "apb1",
407 0x068, BIT(2), 0);
408static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb1",
409 0x068, BIT(5), 0);
410static SUNXI_CCU_GATE(bus_ir0_clk, "bus-ir0", "apb1",
411 0x068, BIT(6), 0);
412static SUNXI_CCU_GATE(bus_ir1_clk, "bus-ir1", "apb1",
413 0x068, BIT(7), 0);
414static SUNXI_CCU_GATE(bus_ths_clk, "bus-ths", "apb1",
415 0x068, BIT(8), 0);
416static SUNXI_CCU_GATE(bus_keypad_clk, "bus-keypad", "apb1",
417 0x068, BIT(10), 0);
418static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1",
419 0x068, BIT(12), 0);
420static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1",
421 0x068, BIT(13), 0);
422static SUNXI_CCU_GATE(bus_i2s2_clk, "bus-i2s2", "apb1",
423 0x068, BIT(14), 0);
424
425static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2",
426 0x06c, BIT(0), 0);
427static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2",
428 0x06c, BIT(1), 0);
429static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2",
430 0x06c, BIT(2), 0);
431static SUNXI_CCU_GATE(bus_i2c3_clk, "bus-i2c3", "apb2",
432 0x06c, BIT(3), 0);
433/*
434 * In datasheet here's "Reserved", however the gate exists in BSP soucre
435 * code.
436 */
437static SUNXI_CCU_GATE(bus_can_clk, "bus-can", "apb2",
438 0x06c, BIT(4), 0);
439static SUNXI_CCU_GATE(bus_scr_clk, "bus-scr", "apb2",
440 0x06c, BIT(5), 0);
441static SUNXI_CCU_GATE(bus_ps20_clk, "bus-ps20", "apb2",
442 0x06c, BIT(6), 0);
443static SUNXI_CCU_GATE(bus_ps21_clk, "bus-ps21", "apb2",
444 0x06c, BIT(7), 0);
445static SUNXI_CCU_GATE(bus_i2c4_clk, "bus-i2c4", "apb2",
446 0x06c, BIT(15), 0);
447static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2",
448 0x06c, BIT(16), 0);
449static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2",
450 0x06c, BIT(17), 0);
451static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2",
452 0x06c, BIT(18), 0);
453static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2",
454 0x06c, BIT(19), 0);
455static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2",
456 0x06c, BIT(20), 0);
457static SUNXI_CCU_GATE(bus_uart5_clk, "bus-uart5", "apb2",
458 0x06c, BIT(21), 0);
459static SUNXI_CCU_GATE(bus_uart6_clk, "bus-uart6", "apb2",
460 0x06c, BIT(22), 0);
461static SUNXI_CCU_GATE(bus_uart7_clk, "bus-uart7", "apb2",
462 0x06c, BIT(23), 0);
463
464static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "ahb1",
465 0x070, BIT(7), 0);
466
467static const char * const ths_parents[] = { "osc24M" };
468static struct ccu_div ths_clk = {
469 .enable = BIT(31),
470 .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
471 .mux = _SUNXI_CCU_MUX(24, 2),
472 .common = {
473 .reg = 0x074,
474 .hw.init = CLK_HW_INIT_PARENTS("ths",
475 ths_parents,
476 &ccu_div_ops,
477 0),
478 },
479};
480
481static const char * const mod0_default_parents[] = { "osc24M", "pll-periph0",
482 "pll-periph1" };
483static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
484 0, 4, /* M */
485 16, 2, /* P */
486 24, 2, /* mux */
487 BIT(31), /* gate */
488 0);
489
490static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
491 0, 4, /* M */
492 16, 2, /* P */
493 24, 2, /* mux */
494 BIT(31), /* gate */
495 0);
496
497static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
498 0, 4, /* M */
499 16, 2, /* P */
500 24, 2, /* mux */
501 BIT(31), /* gate */
502 0);
503
504static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
505 0, 4, /* M */
506 16, 2, /* P */
507 24, 2, /* mux */
508 BIT(31), /* gate */
509 0);
510
511static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk, "mmc3", mod0_default_parents, 0x094,
512 0, 4, /* M */
513 16, 2, /* P */
514 24, 2, /* mux */
515 BIT(31), /* gate */
516 0);
517
518static const char * const ts_parents[] = { "osc24M", "pll-periph0", };
519static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", ts_parents, 0x098,
520 0, 4, /* M */
521 16, 2, /* P */
522 24, 4, /* mux */
523 BIT(31), /* gate */
524 0);
525
526static const char * const ce_parents[] = { "osc24M", "pll-periph0-2x",
527 "pll-periph1-2x" };
528static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x09c,
529 0, 4, /* M */
530 16, 2, /* P */
531 24, 2, /* mux */
532 BIT(31), /* gate */
533 0);
534
535static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
536 0, 4, /* M */
537 16, 2, /* P */
538 24, 2, /* mux */
539 BIT(31), /* gate */
540 0);
541
542static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
543 0, 4, /* M */
544 16, 2, /* P */
545 24, 2, /* mux */
546 BIT(31), /* gate */
547 0);
548
549static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8,
550 0, 4, /* M */
551 16, 2, /* P */
552 24, 2, /* mux */
553 BIT(31), /* gate */
554 0);
555
556static SUNXI_CCU_MP_WITH_MUX_GATE(spi3_clk, "spi3", mod0_default_parents, 0x0ac,
557 0, 4, /* M */
558 16, 2, /* P */
559 24, 2, /* mux */
560 BIT(31), /* gate */
561 0);
562
563static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
564 "pll-audio-2x", "pll-audio" };
565static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents,
566 0x0b0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
567
568static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", i2s_parents,
569 0x0b4, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
570
571static SUNXI_CCU_MUX_WITH_GATE(i2s2_clk, "i2s2", i2s_parents,
572 0x0b8, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
573
574static SUNXI_CCU_MUX_WITH_GATE(ac97_clk, "ac97", i2s_parents,
575 0x0bc, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
576
577static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", i2s_parents,
578 0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
579
580static const char * const keypad_parents[] = { "osc24M", "osc32k" };
581static const u8 keypad_table[] = { 0, 2 };
582static struct ccu_mp keypad_clk = {
583 .enable = BIT(31),
584 .m = _SUNXI_CCU_DIV(0, 5),
585 .p = _SUNXI_CCU_DIV(16, 2),
586 .mux = _SUNXI_CCU_MUX_TABLE(24, 2, keypad_table),
587 .common = {
588 .reg = 0x0c4,
589 .hw.init = CLK_HW_INIT_PARENTS("keypad",
590 keypad_parents,
591 &ccu_mp_ops,
592 0),
593 }
594};
595
596static const char * const sata_parents[] = { "pll-sata-out", "sata-ext" };
597static SUNXI_CCU_MUX_WITH_GATE(sata_clk, "sata", sata_parents,
598 0x0c8, 24, 1, BIT(31), CLK_SET_RATE_PARENT);
599
600/*
601 * There are 3 OHCI 12M clock source selection bits in this register.
602 * We will force them to 0 (12M divided from 48M).
603 */
604#define SUN8I_R40_USB_CLK_REG 0x0cc
605
606static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
607 0x0cc, BIT(8), 0);
608static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M",
609 0x0cc, BIT(9), 0);
610static SUNXI_CCU_GATE(usb_phy2_clk, "usb-phy2", "osc24M",
611 0x0cc, BIT(10), 0);
612static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc12M",
613 0x0cc, BIT(16), 0);
614static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc12M",
615 0x0cc, BIT(17), 0);
616static SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc12M",
617 0x0cc, BIT(18), 0);
618
619static const char * const ir_parents[] = { "osc24M", "pll-periph0",
620 "pll-periph1", "osc32k" };
621static SUNXI_CCU_MP_WITH_MUX_GATE(ir0_clk, "ir0", ir_parents, 0x0d0,
622 0, 4, /* M */
623 16, 2, /* P */
624 24, 2, /* mux */
625 BIT(31), /* gate */
626 0);
627
628static SUNXI_CCU_MP_WITH_MUX_GATE(ir1_clk, "ir1", ir_parents, 0x0d4,
629 0, 4, /* M */
630 16, 2, /* P */
631 24, 2, /* mux */
632 BIT(31), /* gate */
633 0);
634
635static const char * const dram_parents[] = { "pll-ddr0", "pll-ddr1" };
636static SUNXI_CCU_M_WITH_MUX(dram_clk, "dram", dram_parents,
637 0x0f4, 0, 2, 20, 2, CLK_IS_CRITICAL);
638
639static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "dram",
640 0x100, BIT(0), 0);
641static SUNXI_CCU_GATE(dram_csi0_clk, "dram-csi0", "dram",
642 0x100, BIT(1), 0);
643static SUNXI_CCU_GATE(dram_csi1_clk, "dram-csi1", "dram",
644 0x100, BIT(2), 0);
645static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "dram",
646 0x100, BIT(3), 0);
647static SUNXI_CCU_GATE(dram_tvd_clk, "dram-tvd", "dram",
648 0x100, BIT(4), 0);
649static SUNXI_CCU_GATE(dram_mp_clk, "dram-mp", "dram",
650 0x100, BIT(5), 0);
651static SUNXI_CCU_GATE(dram_deinterlace_clk, "dram-deinterlace", "dram",
652 0x100, BIT(6), 0);
653
654static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" };
655static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
656 0x104, 0, 4, 24, 3, BIT(31), 0);
657static SUNXI_CCU_M_WITH_MUX_GATE(mp_clk, "mp", de_parents,
658 0x108, 0, 4, 24, 3, BIT(31), 0);
659
660static const char * const tcon_parents[] = { "pll-video0", "pll-video1",
661 "pll-video0-2x", "pll-video1-2x",
662 "pll-mipi" };
663static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd0_clk, "tcon-lcd0", tcon_parents,
664 0x110, 24, 3, BIT(31), CLK_SET_RATE_PARENT);
665static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd1_clk, "tcon-lcd1", tcon_parents,
666 0x114, 24, 3, BIT(31), CLK_SET_RATE_PARENT);
667static SUNXI_CCU_M_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0", tcon_parents,
668 0x118, 0, 4, 24, 3, BIT(31), 0);
669static SUNXI_CCU_M_WITH_MUX_GATE(tcon_tv1_clk, "tcon-tv1", tcon_parents,
670 0x11c, 0, 4, 24, 3, BIT(31), 0);
671
672static const char * const deinterlace_parents[] = { "pll-periph0",
673 "pll-periph1" };
674static SUNXI_CCU_M_WITH_MUX_GATE(deinterlace_clk, "deinterlace",
675 deinterlace_parents, 0x124, 0, 4, 24, 3,
676 BIT(31), 0);
677
678static const char * const csi_mclk_parents[] = { "osc24M", "pll-video1",
679 "pll-periph1" };
680static SUNXI_CCU_M_WITH_MUX_GATE(csi1_mclk_clk, "csi1-mclk", csi_mclk_parents,
681 0x130, 0, 5, 8, 3, BIT(15), 0);
682
683static const char * const csi_sclk_parents[] = { "pll-periph0", "pll-periph1" };
684static SUNXI_CCU_M_WITH_MUX_GATE(csi_sclk_clk, "csi-sclk", csi_sclk_parents,
685 0x134, 16, 4, 24, 3, BIT(31), 0);
686
687static SUNXI_CCU_M_WITH_MUX_GATE(csi0_mclk_clk, "csi0-mclk", csi_mclk_parents,
688 0x134, 0, 5, 8, 3, BIT(15), 0);
689
690static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
691 0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT);
692
693static SUNXI_CCU_GATE(codec_clk, "codec", "pll-audio",
694 0x140, BIT(31), CLK_SET_RATE_PARENT);
695static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M",
696 0x144, BIT(31), 0);
697
698static const char * const hdmi_parents[] = { "pll-video0", "pll-video1" };
699static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents,
700 0x150, 0, 4, 24, 2, BIT(31), 0);
701
702static SUNXI_CCU_GATE(hdmi_slow_clk, "hdmi-slow", "osc24M",
703 0x154, BIT(31), 0);
704
705/*
706 * In the SoC's user manual, the P factor is mentioned, but not used in
707 * the frequency formula.
708 *
709 * Here the factor is included, according to the BSP kernel source,
710 * which contains the P factor of this clock.
711 */
712static const char * const mbus_parents[] = { "osc24M", "pll-periph0-2x",
713 "pll-ddr0" };
714static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents, 0x15c,
715 0, 4, /* M */
716 16, 2, /* P */
717 24, 2, /* mux */
718 BIT(31), /* gate */
719 CLK_IS_CRITICAL);
720
721static const char * const dsi_dphy_parents[] = { "pll-video0", "pll-video1",
722 "pll-periph0" };
723static SUNXI_CCU_M_WITH_MUX_GATE(dsi_dphy_clk, "dsi-dphy", dsi_dphy_parents,
724 0x168, 0, 4, 8, 2, BIT(15), 0);
725
726static SUNXI_CCU_M_WITH_MUX_GATE(tve0_clk, "tve0", tcon_parents,
727 0x180, 0, 4, 24, 3, BIT(31), 0);
728static SUNXI_CCU_M_WITH_MUX_GATE(tve1_clk, "tve1", tcon_parents,
729 0x184, 0, 4, 24, 3, BIT(31), 0);
730
731static const char * const tvd_parents[] = { "pll-video0", "pll-video1",
732 "pll-video0-2x", "pll-video1-2x" };
733static SUNXI_CCU_M_WITH_MUX_GATE(tvd0_clk, "tvd0", tvd_parents,
734 0x188, 0, 4, 24, 3, BIT(31), 0);
735static SUNXI_CCU_M_WITH_MUX_GATE(tvd1_clk, "tvd1", tvd_parents,
736 0x18c, 0, 4, 24, 3, BIT(31), 0);
737static SUNXI_CCU_M_WITH_MUX_GATE(tvd2_clk, "tvd2", tvd_parents,
738 0x190, 0, 4, 24, 3, BIT(31), 0);
739static SUNXI_CCU_M_WITH_MUX_GATE(tvd3_clk, "tvd3", tvd_parents,
740 0x194, 0, 4, 24, 3, BIT(31), 0);
741
742static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu",
743 0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT);
744
745static const char * const out_parents[] = { "osc24M", "osc32k", "osc24M" };
746static const struct ccu_mux_fixed_prediv out_predivs[] = {
747 { .index = 0, .div = 750, },
748};
749
750static struct ccu_mp outa_clk = {
751 .enable = BIT(31),
752 .m = _SUNXI_CCU_DIV(8, 5),
753 .p = _SUNXI_CCU_DIV(20, 2),
754 .mux = {
755 .shift = 24,
756 .width = 2,
757 .fixed_predivs = out_predivs,
758 .n_predivs = ARRAY_SIZE(out_predivs),
759 },
760 .common = {
761 .reg = 0x1f0,
762 .features = CCU_FEATURE_FIXED_PREDIV,
763 .hw.init = CLK_HW_INIT_PARENTS("outa", out_parents,
764 &ccu_mp_ops, 0),
765 }
766};
767
768static struct ccu_mp outb_clk = {
769 .enable = BIT(31),
770 .m = _SUNXI_CCU_DIV(8, 5),
771 .p = _SUNXI_CCU_DIV(20, 2),
772 .mux = {
773 .shift = 24,
774 .width = 2,
775 .fixed_predivs = out_predivs,
776 .n_predivs = ARRAY_SIZE(out_predivs),
777 },
778 .common = {
779 .reg = 0x1f4,
780 .features = CCU_FEATURE_FIXED_PREDIV,
781 .hw.init = CLK_HW_INIT_PARENTS("outb", out_parents,
782 &ccu_mp_ops, 0),
783 }
784};
785
786static struct ccu_common *sun8i_r40_ccu_clks[] = {
787 &pll_cpu_clk.common,
788 &pll_audio_base_clk.common,
789 &pll_video0_clk.common,
790 &pll_ve_clk.common,
791 &pll_ddr0_clk.common,
792 &pll_periph0_clk.common,
793 &pll_periph0_sata_clk.common,
794 &pll_periph1_clk.common,
795 &pll_video1_clk.common,
796 &pll_sata_clk.common,
797 &pll_sata_out_clk.common,
798 &pll_gpu_clk.common,
799 &pll_mipi_clk.common,
800 &pll_de_clk.common,
801 &pll_ddr1_clk.common,
802 &cpu_clk.common,
803 &axi_clk.common,
804 &ahb1_clk.common,
805 &apb1_clk.common,
806 &apb2_clk.common,
807 &bus_mipi_dsi_clk.common,
808 &bus_ce_clk.common,
809 &bus_dma_clk.common,
810 &bus_mmc0_clk.common,
811 &bus_mmc1_clk.common,
812 &bus_mmc2_clk.common,
813 &bus_mmc3_clk.common,
814 &bus_nand_clk.common,
815 &bus_dram_clk.common,
816 &bus_emac_clk.common,
817 &bus_ts_clk.common,
818 &bus_hstimer_clk.common,
819 &bus_spi0_clk.common,
820 &bus_spi1_clk.common,
821 &bus_spi2_clk.common,
822 &bus_spi3_clk.common,
823 &bus_sata_clk.common,
824 &bus_otg_clk.common,
825 &bus_ehci0_clk.common,
826 &bus_ehci1_clk.common,
827 &bus_ehci2_clk.common,
828 &bus_ohci0_clk.common,
829 &bus_ohci1_clk.common,
830 &bus_ohci2_clk.common,
831 &bus_ve_clk.common,
832 &bus_mp_clk.common,
833 &bus_deinterlace_clk.common,
834 &bus_csi0_clk.common,
835 &bus_csi1_clk.common,
836 &bus_hdmi0_clk.common,
837 &bus_hdmi1_clk.common,
838 &bus_de_clk.common,
839 &bus_tve0_clk.common,
840 &bus_tve1_clk.common,
841 &bus_tve_top_clk.common,
842 &bus_gmac_clk.common,
843 &bus_gpu_clk.common,
844 &bus_tvd0_clk.common,
845 &bus_tvd1_clk.common,
846 &bus_tvd2_clk.common,
847 &bus_tvd3_clk.common,
848 &bus_tvd_top_clk.common,
849 &bus_tcon_lcd0_clk.common,
850 &bus_tcon_lcd1_clk.common,
851 &bus_tcon_tv0_clk.common,
852 &bus_tcon_tv1_clk.common,
853 &bus_tcon_top_clk.common,
854 &bus_codec_clk.common,
855 &bus_spdif_clk.common,
856 &bus_ac97_clk.common,
857 &bus_pio_clk.common,
858 &bus_ir0_clk.common,
859 &bus_ir1_clk.common,
860 &bus_ths_clk.common,
861 &bus_keypad_clk.common,
862 &bus_i2s0_clk.common,
863 &bus_i2s1_clk.common,
864 &bus_i2s2_clk.common,
865 &bus_i2c0_clk.common,
866 &bus_i2c1_clk.common,
867 &bus_i2c2_clk.common,
868 &bus_i2c3_clk.common,
869 &bus_can_clk.common,
870 &bus_scr_clk.common,
871 &bus_ps20_clk.common,
872 &bus_ps21_clk.common,
873 &bus_i2c4_clk.common,
874 &bus_uart0_clk.common,
875 &bus_uart1_clk.common,
876 &bus_uart2_clk.common,
877 &bus_uart3_clk.common,
878 &bus_uart4_clk.common,
879 &bus_uart5_clk.common,
880 &bus_uart6_clk.common,
881 &bus_uart7_clk.common,
882 &bus_dbg_clk.common,
883 &ths_clk.common,
884 &nand_clk.common,
885 &mmc0_clk.common,
886 &mmc1_clk.common,
887 &mmc2_clk.common,
888 &mmc3_clk.common,
889 &ts_clk.common,
890 &ce_clk.common,
891 &spi0_clk.common,
892 &spi1_clk.common,
893 &spi2_clk.common,
894 &spi3_clk.common,
895 &i2s0_clk.common,
896 &i2s1_clk.common,
897 &i2s2_clk.common,
898 &ac97_clk.common,
899 &spdif_clk.common,
900 &keypad_clk.common,
901 &sata_clk.common,
902 &usb_phy0_clk.common,
903 &usb_phy1_clk.common,
904 &usb_phy2_clk.common,
905 &usb_ohci0_clk.common,
906 &usb_ohci1_clk.common,
907 &usb_ohci2_clk.common,
908 &ir0_clk.common,
909 &ir1_clk.common,
910 &dram_clk.common,
911 &dram_ve_clk.common,
912 &dram_csi0_clk.common,
913 &dram_csi1_clk.common,
914 &dram_ts_clk.common,
915 &dram_tvd_clk.common,
916 &dram_mp_clk.common,
917 &dram_deinterlace_clk.common,
918 &de_clk.common,
919 &mp_clk.common,
920 &tcon_lcd0_clk.common,
921 &tcon_lcd1_clk.common,
922 &tcon_tv0_clk.common,
923 &tcon_tv1_clk.common,
924 &deinterlace_clk.common,
925 &csi1_mclk_clk.common,
926 &csi_sclk_clk.common,
927 &csi0_mclk_clk.common,
928 &ve_clk.common,
929 &codec_clk.common,
930 &avs_clk.common,
931 &hdmi_clk.common,
932 &hdmi_slow_clk.common,
933 &mbus_clk.common,
934 &dsi_dphy_clk.common,
935 &tve0_clk.common,
936 &tve1_clk.common,
937 &tvd0_clk.common,
938 &tvd1_clk.common,
939 &tvd2_clk.common,
940 &tvd3_clk.common,
941 &gpu_clk.common,
942 &outa_clk.common,
943 &outb_clk.common,
944};
945
946/* Fixed Factor clocks */
947static CLK_FIXED_FACTOR(osc12M_clk, "osc12M", "osc24M", 2, 1, 0);
948
949/* We hardcode the divider to 4 for now */
950static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
951 "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
952static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
953 "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
954static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
955 "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
956static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
957 "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
958static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x",
959 "pll-periph0", 1, 2, 0);
960static CLK_FIXED_FACTOR(pll_periph1_2x_clk, "pll-periph1-2x",
961 "pll-periph1", 1, 2, 0);
962static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x",
963 "pll-video0", 1, 2, 0);
964static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x",
965 "pll-video1", 1, 2, 0);
966
967static struct clk_hw_onecell_data sun8i_r40_hw_clks = {
968 .hws = {
969 [CLK_OSC_12M] = &osc12M_clk.hw,
970 [CLK_PLL_CPU] = &pll_cpu_clk.common.hw,
971 [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw,
972 [CLK_PLL_AUDIO] = &pll_audio_clk.hw,
973 [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw,
974 [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw,
975 [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw,
976 [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw,
977 [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw,
978 [CLK_PLL_VE] = &pll_ve_clk.common.hw,
979 [CLK_PLL_DDR0] = &pll_ddr0_clk.common.hw,
980 [CLK_PLL_PERIPH0] = &pll_periph0_clk.common.hw,
981 [CLK_PLL_PERIPH0_SATA] = &pll_periph0_sata_clk.common.hw,
982 [CLK_PLL_PERIPH0_2X] = &pll_periph0_2x_clk.hw,
983 [CLK_PLL_PERIPH1] = &pll_periph1_clk.common.hw,
984 [CLK_PLL_PERIPH1_2X] = &pll_periph1_2x_clk.hw,
985 [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw,
986 [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw,
987 [CLK_PLL_SATA] = &pll_sata_clk.common.hw,
988 [CLK_PLL_SATA_OUT] = &pll_sata_out_clk.common.hw,
989 [CLK_PLL_GPU] = &pll_gpu_clk.common.hw,
990 [CLK_PLL_MIPI] = &pll_mipi_clk.common.hw,
991 [CLK_PLL_DE] = &pll_de_clk.common.hw,
992 [CLK_PLL_DDR1] = &pll_ddr1_clk.common.hw,
993 [CLK_CPU] = &cpu_clk.common.hw,
994 [CLK_AXI] = &axi_clk.common.hw,
995 [CLK_AHB1] = &ahb1_clk.common.hw,
996 [CLK_APB1] = &apb1_clk.common.hw,
997 [CLK_APB2] = &apb2_clk.common.hw,
998 [CLK_BUS_MIPI_DSI] = &bus_mipi_dsi_clk.common.hw,
999 [CLK_BUS_CE] = &bus_ce_clk.common.hw,
1000 [CLK_BUS_DMA] = &bus_dma_clk.common.hw,
1001 [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw,
1002 [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw,
1003 [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw,
1004 [CLK_BUS_MMC3] = &bus_mmc3_clk.common.hw,
1005 [CLK_BUS_NAND] = &bus_nand_clk.common.hw,
1006 [CLK_BUS_DRAM] = &bus_dram_clk.common.hw,
1007 [CLK_BUS_EMAC] = &bus_emac_clk.common.hw,
1008 [CLK_BUS_TS] = &bus_ts_clk.common.hw,
1009 [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw,
1010 [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw,
1011 [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw,
1012 [CLK_BUS_SPI2] = &bus_spi2_clk.common.hw,
1013 [CLK_BUS_SPI3] = &bus_spi3_clk.common.hw,
1014 [CLK_BUS_SATA] = &bus_sata_clk.common.hw,
1015 [CLK_BUS_OTG] = &bus_otg_clk.common.hw,
1016 [CLK_BUS_EHCI0] = &bus_ehci0_clk.common.hw,
1017 [CLK_BUS_EHCI1] = &bus_ehci1_clk.common.hw,
1018 [CLK_BUS_EHCI2] = &bus_ehci2_clk.common.hw,
1019 [CLK_BUS_OHCI0] = &bus_ohci0_clk.common.hw,
1020 [CLK_BUS_OHCI1] = &bus_ohci1_clk.common.hw,
1021 [CLK_BUS_OHCI2] = &bus_ohci2_clk.common.hw,
1022 [CLK_BUS_VE] = &bus_ve_clk.common.hw,
1023 [CLK_BUS_MP] = &bus_mp_clk.common.hw,
1024 [CLK_BUS_DEINTERLACE] = &bus_deinterlace_clk.common.hw,
1025 [CLK_BUS_CSI0] = &bus_csi0_clk.common.hw,
1026 [CLK_BUS_CSI1] = &bus_csi1_clk.common.hw,
1027 [CLK_BUS_HDMI0] = &bus_hdmi0_clk.common.hw,
1028 [CLK_BUS_HDMI1] = &bus_hdmi1_clk.common.hw,
1029 [CLK_BUS_DE] = &bus_de_clk.common.hw,
1030 [CLK_BUS_TVE0] = &bus_tve0_clk.common.hw,
1031 [CLK_BUS_TVE1] = &bus_tve1_clk.common.hw,
1032 [CLK_BUS_TVE_TOP] = &bus_tve_top_clk.common.hw,
1033 [CLK_BUS_GMAC] = &bus_gmac_clk.common.hw,
1034 [CLK_BUS_GPU] = &bus_gpu_clk.common.hw,
1035 [CLK_BUS_TVD0] = &bus_tvd0_clk.common.hw,
1036 [CLK_BUS_TVD1] = &bus_tvd1_clk.common.hw,
1037 [CLK_BUS_TVD2] = &bus_tvd2_clk.common.hw,
1038 [CLK_BUS_TVD3] = &bus_tvd3_clk.common.hw,
1039 [CLK_BUS_TVD_TOP] = &bus_tvd_top_clk.common.hw,
1040 [CLK_BUS_TCON_LCD0] = &bus_tcon_lcd0_clk.common.hw,
1041 [CLK_BUS_TCON_LCD1] = &bus_tcon_lcd1_clk.common.hw,
1042 [CLK_BUS_TCON_TV0] = &bus_tcon_tv0_clk.common.hw,
1043 [CLK_BUS_TCON_TV1] = &bus_tcon_tv1_clk.common.hw,
1044 [CLK_BUS_TCON_TOP] = &bus_tcon_top_clk.common.hw,
1045 [CLK_BUS_CODEC] = &bus_codec_clk.common.hw,
1046 [CLK_BUS_SPDIF] = &bus_spdif_clk.common.hw,
1047 [CLK_BUS_AC97] = &bus_ac97_clk.common.hw,
1048 [CLK_BUS_PIO] = &bus_pio_clk.common.hw,
1049 [CLK_BUS_IR0] = &bus_ir0_clk.common.hw,
1050 [CLK_BUS_IR1] = &bus_ir1_clk.common.hw,
1051 [CLK_BUS_THS] = &bus_ths_clk.common.hw,
1052 [CLK_BUS_KEYPAD] = &bus_keypad_clk.common.hw,
1053 [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw,
1054 [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw,
1055 [CLK_BUS_I2S2] = &bus_i2s2_clk.common.hw,
1056 [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw,
1057 [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw,
1058 [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw,
1059 [CLK_BUS_I2C3] = &bus_i2c3_clk.common.hw,
1060 [CLK_BUS_CAN] = &bus_can_clk.common.hw,
1061 [CLK_BUS_SCR] = &bus_scr_clk.common.hw,
1062 [CLK_BUS_PS20] = &bus_ps20_clk.common.hw,
1063 [CLK_BUS_PS21] = &bus_ps21_clk.common.hw,
1064 [CLK_BUS_I2C4] = &bus_i2c4_clk.common.hw,
1065 [CLK_BUS_UART0] = &bus_uart0_clk.common.hw,
1066 [CLK_BUS_UART1] = &bus_uart1_clk.common.hw,
1067 [CLK_BUS_UART2] = &bus_uart2_clk.common.hw,
1068 [CLK_BUS_UART3] = &bus_uart3_clk.common.hw,
1069 [CLK_BUS_UART4] = &bus_uart4_clk.common.hw,
1070 [CLK_BUS_UART5] = &bus_uart5_clk.common.hw,
1071 [CLK_BUS_UART6] = &bus_uart6_clk.common.hw,
1072 [CLK_BUS_UART7] = &bus_uart7_clk.common.hw,
1073 [CLK_BUS_DBG] = &bus_dbg_clk.common.hw,
1074 [CLK_THS] = &ths_clk.common.hw,
1075 [CLK_NAND] = &nand_clk.common.hw,
1076 [CLK_MMC0] = &mmc0_clk.common.hw,
1077 [CLK_MMC1] = &mmc1_clk.common.hw,
1078 [CLK_MMC2] = &mmc2_clk.common.hw,
1079 [CLK_MMC3] = &mmc3_clk.common.hw,
1080 [CLK_TS] = &ts_clk.common.hw,
1081 [CLK_CE] = &ce_clk.common.hw,
1082 [CLK_SPI0] = &spi0_clk.common.hw,
1083 [CLK_SPI1] = &spi1_clk.common.hw,
1084 [CLK_SPI2] = &spi2_clk.common.hw,
1085 [CLK_SPI3] = &spi3_clk.common.hw,
1086 [CLK_I2S0] = &i2s0_clk.common.hw,
1087 [CLK_I2S1] = &i2s1_clk.common.hw,
1088 [CLK_I2S2] = &i2s2_clk.common.hw,
1089 [CLK_AC97] = &ac97_clk.common.hw,
1090 [CLK_SPDIF] = &spdif_clk.common.hw,
1091 [CLK_KEYPAD] = &keypad_clk.common.hw,
1092 [CLK_SATA] = &sata_clk.common.hw,
1093 [CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
1094 [CLK_USB_PHY1] = &usb_phy1_clk.common.hw,
1095 [CLK_USB_PHY2] = &usb_phy2_clk.common.hw,
1096 [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw,
1097 [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw,
1098 [CLK_USB_OHCI2] = &usb_ohci2_clk.common.hw,
1099 [CLK_IR0] = &ir0_clk.common.hw,
1100 [CLK_IR1] = &ir1_clk.common.hw,
1101 [CLK_DRAM] = &dram_clk.common.hw,
1102 [CLK_DRAM_VE] = &dram_ve_clk.common.hw,
1103 [CLK_DRAM_CSI0] = &dram_csi0_clk.common.hw,
1104 [CLK_DRAM_CSI1] = &dram_csi1_clk.common.hw,
1105 [CLK_DRAM_TS] = &dram_ts_clk.common.hw,
1106 [CLK_DRAM_TVD] = &dram_tvd_clk.common.hw,
1107 [CLK_DRAM_MP] = &dram_mp_clk.common.hw,
1108 [CLK_DRAM_DEINTERLACE] = &dram_deinterlace_clk.common.hw,
1109 [CLK_DE] = &de_clk.common.hw,
1110 [CLK_MP] = &mp_clk.common.hw,
1111 [CLK_TCON_LCD0] = &tcon_lcd0_clk.common.hw,
1112 [CLK_TCON_LCD1] = &tcon_lcd1_clk.common.hw,
1113 [CLK_TCON_TV0] = &tcon_tv0_clk.common.hw,
1114 [CLK_TCON_TV1] = &tcon_tv1_clk.common.hw,
1115 [CLK_DEINTERLACE] = &deinterlace_clk.common.hw,
1116 [CLK_CSI1_MCLK] = &csi1_mclk_clk.common.hw,
1117 [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw,
1118 [CLK_CSI0_MCLK] = &csi0_mclk_clk.common.hw,
1119 [CLK_VE] = &ve_clk.common.hw,
1120 [CLK_CODEC] = &codec_clk.common.hw,
1121 [CLK_AVS] = &avs_clk.common.hw,
1122 [CLK_HDMI] = &hdmi_clk.common.hw,
1123 [CLK_HDMI_SLOW] = &hdmi_slow_clk.common.hw,
1124 [CLK_MBUS] = &mbus_clk.common.hw,
1125 [CLK_DSI_DPHY] = &dsi_dphy_clk.common.hw,
1126 [CLK_TVE0] = &tve0_clk.common.hw,
1127 [CLK_TVE1] = &tve1_clk.common.hw,
1128 [CLK_TVD0] = &tvd0_clk.common.hw,
1129 [CLK_TVD1] = &tvd1_clk.common.hw,
1130 [CLK_TVD2] = &tvd2_clk.common.hw,
1131 [CLK_TVD3] = &tvd3_clk.common.hw,
1132 [CLK_GPU] = &gpu_clk.common.hw,
1133 [CLK_OUTA] = &outa_clk.common.hw,
1134 [CLK_OUTB] = &outb_clk.common.hw,
1135 },
1136 .num = CLK_NUMBER,
1137};
1138
1139static struct ccu_reset_map sun8i_r40_ccu_resets[] = {
1140 [RST_USB_PHY0] = { 0x0cc, BIT(0) },
1141 [RST_USB_PHY1] = { 0x0cc, BIT(1) },
1142 [RST_USB_PHY2] = { 0x0cc, BIT(2) },
1143
1144 [RST_DRAM] = { 0x0f4, BIT(31) },
1145 [RST_MBUS] = { 0x0fc, BIT(31) },
1146
1147 [RST_BUS_MIPI_DSI] = { 0x2c0, BIT(1) },
1148 [RST_BUS_CE] = { 0x2c0, BIT(5) },
1149 [RST_BUS_DMA] = { 0x2c0, BIT(6) },
1150 [RST_BUS_MMC0] = { 0x2c0, BIT(8) },
1151 [RST_BUS_MMC1] = { 0x2c0, BIT(9) },
1152 [RST_BUS_MMC2] = { 0x2c0, BIT(10) },
1153 [RST_BUS_MMC3] = { 0x2c0, BIT(11) },
1154 [RST_BUS_NAND] = { 0x2c0, BIT(13) },
1155 [RST_BUS_DRAM] = { 0x2c0, BIT(14) },
1156 [RST_BUS_EMAC] = { 0x2c0, BIT(17) },
1157 [RST_BUS_TS] = { 0x2c0, BIT(18) },
1158 [RST_BUS_HSTIMER] = { 0x2c0, BIT(19) },
1159 [RST_BUS_SPI0] = { 0x2c0, BIT(20) },
1160 [RST_BUS_SPI1] = { 0x2c0, BIT(21) },
1161 [RST_BUS_SPI2] = { 0x2c0, BIT(22) },
1162 [RST_BUS_SPI3] = { 0x2c0, BIT(23) },
1163 [RST_BUS_SATA] = { 0x2c0, BIT(24) },
1164 [RST_BUS_OTG] = { 0x2c0, BIT(25) },
1165 [RST_BUS_EHCI0] = { 0x2c0, BIT(26) },
1166 [RST_BUS_EHCI1] = { 0x2c0, BIT(27) },
1167 [RST_BUS_EHCI2] = { 0x2c0, BIT(28) },
1168 [RST_BUS_OHCI0] = { 0x2c0, BIT(29) },
1169 [RST_BUS_OHCI1] = { 0x2c0, BIT(30) },
1170 [RST_BUS_OHCI2] = { 0x2c0, BIT(31) },
1171
1172 [RST_BUS_VE] = { 0x2c4, BIT(0) },
1173 [RST_BUS_MP] = { 0x2c4, BIT(2) },
1174 [RST_BUS_DEINTERLACE] = { 0x2c4, BIT(5) },
1175 [RST_BUS_CSI0] = { 0x2c4, BIT(8) },
1176 [RST_BUS_CSI1] = { 0x2c4, BIT(9) },
1177 [RST_BUS_HDMI0] = { 0x2c4, BIT(10) },
1178 [RST_BUS_HDMI1] = { 0x2c4, BIT(11) },
1179 [RST_BUS_DE] = { 0x2c4, BIT(12) },
1180 [RST_BUS_TVE0] = { 0x2c4, BIT(13) },
1181 [RST_BUS_TVE1] = { 0x2c4, BIT(14) },
1182 [RST_BUS_TVE_TOP] = { 0x2c4, BIT(15) },
1183 [RST_BUS_GMAC] = { 0x2c4, BIT(17) },
1184 [RST_BUS_GPU] = { 0x2c4, BIT(20) },
1185 [RST_BUS_TVD0] = { 0x2c4, BIT(21) },
1186 [RST_BUS_TVD1] = { 0x2c4, BIT(22) },
1187 [RST_BUS_TVD2] = { 0x2c4, BIT(23) },
1188 [RST_BUS_TVD3] = { 0x2c4, BIT(24) },
1189 [RST_BUS_TVD_TOP] = { 0x2c4, BIT(25) },
1190 [RST_BUS_TCON_LCD0] = { 0x2c4, BIT(26) },
1191 [RST_BUS_TCON_LCD1] = { 0x2c4, BIT(27) },
1192 [RST_BUS_TCON_TV0] = { 0x2c4, BIT(28) },
1193 [RST_BUS_TCON_TV1] = { 0x2c4, BIT(29) },
1194 [RST_BUS_TCON_TOP] = { 0x2c4, BIT(30) },
1195 [RST_BUS_DBG] = { 0x2c4, BIT(31) },
1196
1197 [RST_BUS_LVDS] = { 0x2c8, BIT(0) },
1198
1199 [RST_BUS_CODEC] = { 0x2d0, BIT(0) },
1200 [RST_BUS_SPDIF] = { 0x2d0, BIT(1) },
1201 [RST_BUS_AC97] = { 0x2d0, BIT(2) },
1202 [RST_BUS_IR0] = { 0x2d0, BIT(6) },
1203 [RST_BUS_IR1] = { 0x2d0, BIT(7) },
1204 [RST_BUS_THS] = { 0x2d0, BIT(8) },
1205 [RST_BUS_KEYPAD] = { 0x2d0, BIT(10) },
1206 [RST_BUS_I2S0] = { 0x2d0, BIT(12) },
1207 [RST_BUS_I2S1] = { 0x2d0, BIT(13) },
1208 [RST_BUS_I2S2] = { 0x2d0, BIT(14) },
1209
1210 [RST_BUS_I2C0] = { 0x2d8, BIT(0) },
1211 [RST_BUS_I2C1] = { 0x2d8, BIT(1) },
1212 [RST_BUS_I2C2] = { 0x2d8, BIT(2) },
1213 [RST_BUS_I2C3] = { 0x2d8, BIT(3) },
1214 [RST_BUS_CAN] = { 0x2d8, BIT(4) },
1215 [RST_BUS_SCR] = { 0x2d8, BIT(5) },
1216 [RST_BUS_PS20] = { 0x2d8, BIT(6) },
1217 [RST_BUS_PS21] = { 0x2d8, BIT(7) },
1218 [RST_BUS_I2C4] = { 0x2d8, BIT(15) },
1219 [RST_BUS_UART0] = { 0x2d8, BIT(16) },
1220 [RST_BUS_UART1] = { 0x2d8, BIT(17) },
1221 [RST_BUS_UART2] = { 0x2d8, BIT(18) },
1222 [RST_BUS_UART3] = { 0x2d8, BIT(19) },
1223 [RST_BUS_UART4] = { 0x2d8, BIT(20) },
1224 [RST_BUS_UART5] = { 0x2d8, BIT(21) },
1225 [RST_BUS_UART6] = { 0x2d8, BIT(22) },
1226 [RST_BUS_UART7] = { 0x2d8, BIT(23) },
1227};
1228
1229static const struct sunxi_ccu_desc sun8i_r40_ccu_desc = {
1230 .ccu_clks = sun8i_r40_ccu_clks,
1231 .num_ccu_clks = ARRAY_SIZE(sun8i_r40_ccu_clks),
1232
1233 .hw_clks = &sun8i_r40_hw_clks,
1234
1235 .resets = sun8i_r40_ccu_resets,
1236 .num_resets = ARRAY_SIZE(sun8i_r40_ccu_resets),
1237};
1238
1239static struct ccu_pll_nb sun8i_r40_pll_cpu_nb = {
1240 .common = &pll_cpu_clk.common,
1241 /* copy from pll_cpu_clk */
1242 .enable = BIT(31),
1243 .lock = BIT(28),
1244};
1245
1246static struct ccu_mux_nb sun8i_r40_cpu_nb = {
1247 .common = &cpu_clk.common,
1248 .cm = &cpu_clk.mux,
1249 .delay_us = 1, /* > 8 clock cycles at 24 MHz */
1250 .bypass_index = 1, /* index of 24 MHz oscillator */
1251};
1252
1253static void __init sun8i_r40_ccu_setup(struct device_node *node)
1254{
1255 void __iomem *reg;
1256 u32 val;
1257
1258 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
1259 if (IS_ERR(reg)) {
1260 pr_err("%s: Could not map the clock registers\n",
1261 of_node_full_name(node));
1262 return;
1263 }
1264
1265 /* Force the PLL-Audio-1x divider to 4 */
1266 val = readl(reg + SUN8I_R40_PLL_AUDIO_REG);
1267 val &= ~GENMASK(19, 16);
1268 writel(val | (3 << 16), reg + SUN8I_R40_PLL_AUDIO_REG);
1269
1270 /* Force PLL-MIPI to MIPI mode */
1271 val = readl(reg + SUN8I_R40_PLL_MIPI_REG);
1272 val &= ~BIT(16);
1273 writel(val, reg + SUN8I_R40_PLL_MIPI_REG);
1274
1275 /* Force OHCI 12M parent to 12M divided from 48M */
1276 val = readl(reg + SUN8I_R40_USB_CLK_REG);
1277 val &= ~GENMASK(25, 20);
1278 writel(val, reg + SUN8I_R40_USB_CLK_REG);
1279
1280 sunxi_ccu_probe(node, reg, &sun8i_r40_ccu_desc);
1281
1282 /* Gate then ungate PLL CPU after any rate changes */
1283 ccu_pll_notifier_register(&sun8i_r40_pll_cpu_nb);
1284
1285 /* Reparent CPU during PLL CPU rate changes */
1286 ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk,
1287 &sun8i_r40_cpu_nb);
1288}
1289CLK_OF_DECLARE(sun8i_r40_ccu, "allwinner,sun8i-r40-ccu",
1290 sun8i_r40_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.h b/drivers/clk/sunxi-ng/ccu-sun8i-r40.h
new file mode 100644
index 000000000000..0db8e1e97af8
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.h
@@ -0,0 +1,69 @@
1/*
2 * Copyright 2017 Icenowy Zheng <icenowy@aosc.io>
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 as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
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 _CCU_SUN8I_R40_H_
16#define _CCU_SUN8I_R40_H_
17
18#include <dt-bindings/clock/sun8i-r40-ccu.h>
19#include <dt-bindings/reset/sun8i-r40-ccu.h>
20
21#define CLK_OSC_12M 0
22#define CLK_PLL_CPU 1
23#define CLK_PLL_AUDIO_BASE 2
24#define CLK_PLL_AUDIO 3
25#define CLK_PLL_AUDIO_2X 4
26#define CLK_PLL_AUDIO_4X 5
27#define CLK_PLL_AUDIO_8X 6
28#define CLK_PLL_VIDEO0 7
29#define CLK_PLL_VIDEO0_2X 8
30#define CLK_PLL_VE 9
31#define CLK_PLL_DDR0 10
32#define CLK_PLL_PERIPH0 11
33#define CLK_PLL_PERIPH0_SATA 12
34#define CLK_PLL_PERIPH0_2X 13
35#define CLK_PLL_PERIPH1 14
36#define CLK_PLL_PERIPH1_2X 15
37#define CLK_PLL_VIDEO1 16
38#define CLK_PLL_VIDEO1_2X 17
39#define CLK_PLL_SATA 18
40#define CLK_PLL_SATA_OUT 19
41#define CLK_PLL_GPU 20
42#define CLK_PLL_MIPI 21
43#define CLK_PLL_DE 22
44#define CLK_PLL_DDR1 23
45
46/* The CPU clock is exported */
47
48#define CLK_AXI 25
49#define CLK_AHB1 26
50#define CLK_APB1 27
51#define CLK_APB2 28
52
53/* All the bus gates are exported */
54
55/* The first bunch of module clocks are exported */
56
57#define CLK_DRAM 132
58
59/* All the DRAM gates are exported */
60
61/* Some more module clocks are exported */
62
63#define CLK_MBUS 155
64
65/* Another bunch of module clocks are exported */
66
67#define CLK_NUMBER (CLK_OUTB + 1)
68
69#endif /* _CCU_SUN8I_R40_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
index a34a78d7fb28..621b1cd996db 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
@@ -575,8 +575,7 @@ static void __init sun8i_v3s_ccu_setup(struct device_node *node)
575 575
576 reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 576 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
577 if (IS_ERR(reg)) { 577 if (IS_ERR(reg)) {
578 pr_err("%s: Could not map the clock registers\n", 578 pr_err("%pOF: Could not map the clock registers\n", node);
579 of_node_full_name(node));
580 return; 579 return;
581 } 580 }
582 581
diff --git a/drivers/clk/sunxi-ng/ccu_div.c b/drivers/clk/sunxi-ng/ccu_div.c
index c0e5c10d0091..baa3cf96507b 100644
--- a/drivers/clk/sunxi-ng/ccu_div.c
+++ b/drivers/clk/sunxi-ng/ccu_div.c
@@ -21,10 +21,18 @@ static unsigned long ccu_div_round_rate(struct ccu_mux_internal *mux,
21{ 21{
22 struct ccu_div *cd = data; 22 struct ccu_div *cd = data;
23 23
24 return divider_round_rate_parent(&cd->common.hw, parent, 24 if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
25 rate *= cd->fixed_post_div;
26
27 rate = divider_round_rate_parent(&cd->common.hw, parent,
25 rate, parent_rate, 28 rate, parent_rate,
26 cd->div.table, cd->div.width, 29 cd->div.table, cd->div.width,
27 cd->div.flags); 30 cd->div.flags);
31
32 if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
33 rate /= cd->fixed_post_div;
34
35 return rate;
28} 36}
29 37
30static void ccu_div_disable(struct clk_hw *hw) 38static void ccu_div_disable(struct clk_hw *hw)
@@ -62,8 +70,13 @@ static unsigned long ccu_div_recalc_rate(struct clk_hw *hw,
62 parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1, 70 parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1,
63 parent_rate); 71 parent_rate);
64 72
65 return divider_recalc_rate(hw, parent_rate, val, cd->div.table, 73 val = divider_recalc_rate(hw, parent_rate, val, cd->div.table,
66 cd->div.flags); 74 cd->div.flags);
75
76 if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
77 val /= cd->fixed_post_div;
78
79 return val;
67} 80}
68 81
69static int ccu_div_determine_rate(struct clk_hw *hw, 82static int ccu_div_determine_rate(struct clk_hw *hw,
@@ -86,6 +99,9 @@ static int ccu_div_set_rate(struct clk_hw *hw, unsigned long rate,
86 parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1, 99 parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1,
87 parent_rate); 100 parent_rate);
88 101
102 if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
103 rate *= cd->fixed_post_div;
104
89 val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width, 105 val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width,
90 cd->div.flags); 106 cd->div.flags);
91 107
diff --git a/drivers/clk/sunxi-ng/ccu_div.h b/drivers/clk/sunxi-ng/ccu_div.h
index 08d074451204..f3a5028dcd14 100644
--- a/drivers/clk/sunxi-ng/ccu_div.h
+++ b/drivers/clk/sunxi-ng/ccu_div.h
@@ -86,9 +86,10 @@ struct ccu_div_internal {
86struct ccu_div { 86struct ccu_div {
87 u32 enable; 87 u32 enable;
88 88
89 struct ccu_div_internal div; 89 struct ccu_div_internal div;
90 struct ccu_mux_internal mux; 90 struct ccu_mux_internal mux;
91 struct ccu_common common; 91 struct ccu_common common;
92 unsigned int fixed_post_div;
92}; 93};
93 94
94#define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg, \ 95#define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg, \
diff --git a/drivers/clk/sunxi-ng/ccu_frac.c b/drivers/clk/sunxi-ng/ccu_frac.c
index 8b5eb7756bf7..d1d168d4c4f0 100644
--- a/drivers/clk/sunxi-ng/ccu_frac.c
+++ b/drivers/clk/sunxi-ng/ccu_frac.c
@@ -67,25 +67,25 @@ unsigned long ccu_frac_helper_read_rate(struct ccu_common *common,
67{ 67{
68 u32 reg; 68 u32 reg;
69 69
70 printk("%s: Read fractional\n", clk_hw_get_name(&common->hw)); 70 pr_debug("%s: Read fractional\n", clk_hw_get_name(&common->hw));
71 71
72 if (!(common->features & CCU_FEATURE_FRACTIONAL)) 72 if (!(common->features & CCU_FEATURE_FRACTIONAL))
73 return 0; 73 return 0;
74 74
75 printk("%s: clock is fractional (rates %lu and %lu)\n", 75 pr_debug("%s: clock is fractional (rates %lu and %lu)\n",
76 clk_hw_get_name(&common->hw), cf->rates[0], cf->rates[1]); 76 clk_hw_get_name(&common->hw), cf->rates[0], cf->rates[1]);
77 77
78 reg = readl(common->base + common->reg); 78 reg = readl(common->base + common->reg);
79 79
80 printk("%s: clock reg is 0x%x (select is 0x%x)\n", 80 pr_debug("%s: clock reg is 0x%x (select is 0x%x)\n",
81 clk_hw_get_name(&common->hw), reg, cf->select); 81 clk_hw_get_name(&common->hw), reg, cf->select);
82 82
83 return (reg & cf->select) ? cf->rates[1] : cf->rates[0]; 83 return (reg & cf->select) ? cf->rates[1] : cf->rates[0];
84} 84}
85 85
86int ccu_frac_helper_set_rate(struct ccu_common *common, 86int ccu_frac_helper_set_rate(struct ccu_common *common,
87 struct ccu_frac_internal *cf, 87 struct ccu_frac_internal *cf,
88 unsigned long rate) 88 unsigned long rate, u32 lock)
89{ 89{
90 unsigned long flags; 90 unsigned long flags;
91 u32 reg, sel; 91 u32 reg, sel;
@@ -106,5 +106,7 @@ int ccu_frac_helper_set_rate(struct ccu_common *common,
106 writel(reg | sel, common->base + common->reg); 106 writel(reg | sel, common->base + common->reg);
107 spin_unlock_irqrestore(common->lock, flags); 107 spin_unlock_irqrestore(common->lock, flags);
108 108
109 ccu_helper_wait_for_lock(common, lock);
110
109 return 0; 111 return 0;
110} 112}
diff --git a/drivers/clk/sunxi-ng/ccu_frac.h b/drivers/clk/sunxi-ng/ccu_frac.h
index 7b1ee380156f..efe2dd6bac01 100644
--- a/drivers/clk/sunxi-ng/ccu_frac.h
+++ b/drivers/clk/sunxi-ng/ccu_frac.h
@@ -48,6 +48,6 @@ unsigned long ccu_frac_helper_read_rate(struct ccu_common *common,
48 48
49int ccu_frac_helper_set_rate(struct ccu_common *common, 49int ccu_frac_helper_set_rate(struct ccu_common *common,
50 struct ccu_frac_internal *cf, 50 struct ccu_frac_internal *cf,
51 unsigned long rate); 51 unsigned long rate, u32 lock);
52 52
53#endif /* _CCU_FRAC_H_ */ 53#endif /* _CCU_FRAC_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c
index 20d0300867f2..12e0783caee6 100644
--- a/drivers/clk/sunxi-ng/ccu_mult.c
+++ b/drivers/clk/sunxi-ng/ccu_mult.c
@@ -111,10 +111,14 @@ static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate,
111 unsigned long flags; 111 unsigned long flags;
112 u32 reg; 112 u32 reg;
113 113
114 if (ccu_frac_helper_has_rate(&cm->common, &cm->frac, rate)) 114 if (ccu_frac_helper_has_rate(&cm->common, &cm->frac, rate)) {
115 return ccu_frac_helper_set_rate(&cm->common, &cm->frac, rate); 115 ccu_frac_helper_enable(&cm->common, &cm->frac);
116 else 116
117 return ccu_frac_helper_set_rate(&cm->common, &cm->frac,
118 rate, cm->lock);
119 } else {
117 ccu_frac_helper_disable(&cm->common, &cm->frac); 120 ccu_frac_helper_disable(&cm->common, &cm->frac);
121 }
118 122
119 parent_rate = ccu_mux_helper_apply_prediv(&cm->common, &cm->mux, -1, 123 parent_rate = ccu_mux_helper_apply_prediv(&cm->common, &cm->mux, -1,
120 parent_rate); 124 parent_rate);
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
index 44b16dc8fea6..841840e35e61 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.c
+++ b/drivers/clk/sunxi-ng/ccu_nkm.c
@@ -75,7 +75,7 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
75 unsigned long parent_rate) 75 unsigned long parent_rate)
76{ 76{
77 struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); 77 struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
78 unsigned long n, m, k; 78 unsigned long n, m, k, rate;
79 u32 reg; 79 u32 reg;
80 80
81 reg = readl(nkm->common.base + nkm->common.reg); 81 reg = readl(nkm->common.base + nkm->common.reg);
@@ -98,7 +98,12 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
98 if (!m) 98 if (!m)
99 m++; 99 m++;
100 100
101 return parent_rate * n * k / m; 101 rate = parent_rate * n * k / m;
102
103 if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
104 rate /= nkm->fixed_post_div;
105
106 return rate;
102} 107}
103 108
104static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux, 109static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
@@ -117,9 +122,17 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
117 _nkm.min_m = 1; 122 _nkm.min_m = 1;
118 _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width; 123 _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
119 124
125 if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
126 rate *= nkm->fixed_post_div;
127
120 ccu_nkm_find_best(*parent_rate, rate, &_nkm); 128 ccu_nkm_find_best(*parent_rate, rate, &_nkm);
121 129
122 return *parent_rate * _nkm.n * _nkm.k / _nkm.m; 130 rate = *parent_rate * _nkm.n * _nkm.k / _nkm.m;
131
132 if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
133 rate /= nkm->fixed_post_div;
134
135 return rate;
123} 136}
124 137
125static int ccu_nkm_determine_rate(struct clk_hw *hw, 138static int ccu_nkm_determine_rate(struct clk_hw *hw,
@@ -139,6 +152,9 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
139 unsigned long flags; 152 unsigned long flags;
140 u32 reg; 153 u32 reg;
141 154
155 if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
156 rate *= nkm->fixed_post_div;
157
142 _nkm.min_n = nkm->n.min ?: 1; 158 _nkm.min_n = nkm->n.min ?: 1;
143 _nkm.max_n = nkm->n.max ?: 1 << nkm->n.width; 159 _nkm.max_n = nkm->n.max ?: 1 << nkm->n.width;
144 _nkm.min_k = nkm->k.min ?: 1; 160 _nkm.min_k = nkm->k.min ?: 1;
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
index 34580894f4d1..cc6efb70a102 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.h
+++ b/drivers/clk/sunxi-ng/ccu_nkm.h
@@ -34,6 +34,8 @@ struct ccu_nkm {
34 struct ccu_div_internal m; 34 struct ccu_div_internal m;
35 struct ccu_mux_internal mux; 35 struct ccu_mux_internal mux;
36 36
37 unsigned int fixed_post_div;
38
37 struct ccu_common common; 39 struct ccu_common common;
38}; 40};
39 41
diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c
index 5e5e90a4a50c..a32158e8f2e3 100644
--- a/drivers/clk/sunxi-ng/ccu_nm.c
+++ b/drivers/clk/sunxi-ng/ccu_nm.c
@@ -117,10 +117,23 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
117 unsigned long flags; 117 unsigned long flags;
118 u32 reg; 118 u32 reg;
119 119
120 if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) 120 if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) {
121 return ccu_frac_helper_set_rate(&nm->common, &nm->frac, rate); 121 spin_lock_irqsave(nm->common.lock, flags);
122 else 122
123 /* most SoCs require M to be 0 if fractional mode is used */
124 reg = readl(nm->common.base + nm->common.reg);
125 reg &= ~GENMASK(nm->m.width + nm->m.shift - 1, nm->m.shift);
126 writel(reg, nm->common.base + nm->common.reg);
127
128 spin_unlock_irqrestore(nm->common.lock, flags);
129
130 ccu_frac_helper_enable(&nm->common, &nm->frac);
131
132 return ccu_frac_helper_set_rate(&nm->common, &nm->frac,
133 rate, nm->lock);
134 } else {
123 ccu_frac_helper_disable(&nm->common, &nm->frac); 135 ccu_frac_helper_disable(&nm->common, &nm->frac);
136 }
124 137
125 _nm.min_n = nm->n.min ?: 1; 138 _nm.min_n = nm->n.min ?: 1;
126 _nm.max_n = nm->n.max ?: 1 << nm->n.width; 139 _nm.max_n = nm->n.max ?: 1 << nm->n.width;
diff --git a/drivers/clk/sunxi/clk-sun8i-bus-gates.c b/drivers/clk/sunxi/clk-sun8i-bus-gates.c
index 63fdb790df29..bee305bdddbe 100644
--- a/drivers/clk/sunxi/clk-sun8i-bus-gates.c
+++ b/drivers/clk/sunxi/clk-sun8i-bus-gates.c
@@ -78,6 +78,10 @@ static void __init sun8i_h3_bus_gates_init(struct device_node *node)
78 clk_parent = APB1; 78 clk_parent = APB1;
79 else if (index >= 96 && index <= 127) 79 else if (index >= 96 && index <= 127)
80 clk_parent = APB2; 80 clk_parent = APB2;
81 else {
82 WARN_ON(true);
83 continue;
84 }
81 85
82 clk_reg = reg + 4 * (index / 32); 86 clk_reg = reg + 4 * (index / 32);
83 clk_bit = index % 32; 87 clk_bit = index % 32;
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index f2c9274b8bd5..aa4add580516 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -666,15 +666,14 @@ static struct clk * __init sunxi_mux_clk_setup(struct device_node *node,
666 666
667 reg = of_iomap(node, 0); 667 reg = of_iomap(node, 0);
668 if (!reg) { 668 if (!reg) {
669 pr_err("Could not map registers for mux-clk: %s\n", 669 pr_err("Could not map registers for mux-clk: %pOF\n", node);
670 of_node_full_name(node));
671 return NULL; 670 return NULL;
672 } 671 }
673 672
674 i = of_clk_parent_fill(node, parents, SUNXI_MAX_PARENTS); 673 i = of_clk_parent_fill(node, parents, SUNXI_MAX_PARENTS);
675 if (of_property_read_string(node, "clock-output-names", &clk_name)) { 674 if (of_property_read_string(node, "clock-output-names", &clk_name)) {
676 pr_err("%s: could not read clock-output-names from \"%s\"\n", 675 pr_err("%s: could not read clock-output-names from \"%pOF\"\n",
677 __func__, of_node_full_name(node)); 676 __func__, node);
678 goto out_unmap; 677 goto out_unmap;
679 } 678 }
680 679
@@ -797,16 +796,15 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
797 796
798 reg = of_iomap(node, 0); 797 reg = of_iomap(node, 0);
799 if (!reg) { 798 if (!reg) {
800 pr_err("Could not map registers for mux-clk: %s\n", 799 pr_err("Could not map registers for mux-clk: %pOF\n", node);
801 of_node_full_name(node));
802 return; 800 return;
803 } 801 }
804 802
805 clk_parent = of_clk_get_parent_name(node, 0); 803 clk_parent = of_clk_get_parent_name(node, 0);
806 804
807 if (of_property_read_string(node, "clock-output-names", &clk_name)) { 805 if (of_property_read_string(node, "clock-output-names", &clk_name)) {
808 pr_err("%s: could not read clock-output-names from \"%s\"\n", 806 pr_err("%s: could not read clock-output-names from \"%pOF\"\n",
809 __func__, of_node_full_name(node)); 807 __func__, node);
810 goto out_unmap; 808 goto out_unmap;
811 } 809 }
812 810
@@ -1010,8 +1008,7 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node,
1010 1008
1011 reg = of_iomap(node, 0); 1009 reg = of_iomap(node, 0);
1012 if (!reg) { 1010 if (!reg) {
1013 pr_err("Could not map registers for divs-clk: %s\n", 1011 pr_err("Could not map registers for divs-clk: %pOF\n", node);
1014 of_node_full_name(node));
1015 return NULL; 1012 return NULL;
1016 } 1013 }
1017 1014
diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c
index 74e7544f861b..11a5066e5c27 100644
--- a/drivers/clk/tegra/clk-emc.c
+++ b/drivers/clk/tegra/clk-emc.c
@@ -378,7 +378,7 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra,
378 378
379 err = of_property_read_u32(node, "clock-frequency", &tmp); 379 err = of_property_read_u32(node, "clock-frequency", &tmp);
380 if (err) { 380 if (err) {
381 pr_err("timing %s: failed to read rate\n", node->full_name); 381 pr_err("timing %pOF: failed to read rate\n", node);
382 return err; 382 return err;
383 } 383 }
384 384
@@ -386,8 +386,7 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra,
386 386
387 err = of_property_read_u32(node, "nvidia,parent-clock-frequency", &tmp); 387 err = of_property_read_u32(node, "nvidia,parent-clock-frequency", &tmp);
388 if (err) { 388 if (err) {
389 pr_err("timing %s: failed to read parent rate\n", 389 pr_err("timing %pOF: failed to read parent rate\n", node);
390 node->full_name);
391 return err; 390 return err;
392 } 391 }
393 392
@@ -395,8 +394,7 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra,
395 394
396 timing->parent = of_clk_get_by_name(node, "emc-parent"); 395 timing->parent = of_clk_get_by_name(node, "emc-parent");
397 if (IS_ERR(timing->parent)) { 396 if (IS_ERR(timing->parent)) {
398 pr_err("timing %s: failed to get parent clock\n", 397 pr_err("timing %pOF: failed to get parent clock\n", node);
399 node->full_name);
400 return PTR_ERR(timing->parent); 398 return PTR_ERR(timing->parent);
401 } 399 }
402 400
@@ -409,8 +407,8 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra,
409 } 407 }
410 } 408 }
411 if (timing->parent_index == 0xff) { 409 if (timing->parent_index == 0xff) {
412 pr_err("timing %s: %s is not a valid parent\n", 410 pr_err("timing %pOF: %s is not a valid parent\n",
413 node->full_name, __clk_get_name(timing->parent)); 411 node, __clk_get_name(timing->parent));
414 clk_put(timing->parent); 412 clk_put(timing->parent);
415 return -EINVAL; 413 return -EINVAL;
416 } 414 }
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 159a854779e6..7c369e21c91c 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -363,7 +363,7 @@ static void _clk_pll_enable(struct clk_hw *hw)
363 val = pll_readl(pll->params->iddq_reg, pll); 363 val = pll_readl(pll->params->iddq_reg, pll);
364 val &= ~BIT(pll->params->iddq_bit_idx); 364 val &= ~BIT(pll->params->iddq_bit_idx);
365 pll_writel(val, pll->params->iddq_reg, pll); 365 pll_writel(val, pll->params->iddq_reg, pll);
366 udelay(2); 366 udelay(5);
367 } 367 }
368 368
369 if (pll->params->reset_reg) { 369 if (pll->params->reset_reg) {
@@ -418,6 +418,26 @@ static void _clk_pll_disable(struct clk_hw *hw)
418 } 418 }
419} 419}
420 420
421static void pll_clk_start_ss(struct tegra_clk_pll *pll)
422{
423 if (pll->params->defaults_set && pll->params->ssc_ctrl_reg) {
424 u32 val = pll_readl(pll->params->ssc_ctrl_reg, pll);
425
426 val |= pll->params->ssc_ctrl_en_mask;
427 pll_writel(val, pll->params->ssc_ctrl_reg, pll);
428 }
429}
430
431static void pll_clk_stop_ss(struct tegra_clk_pll *pll)
432{
433 if (pll->params->defaults_set && pll->params->ssc_ctrl_reg) {
434 u32 val = pll_readl(pll->params->ssc_ctrl_reg, pll);
435
436 val &= ~pll->params->ssc_ctrl_en_mask;
437 pll_writel(val, pll->params->ssc_ctrl_reg, pll);
438 }
439}
440
421static int clk_pll_enable(struct clk_hw *hw) 441static int clk_pll_enable(struct clk_hw *hw)
422{ 442{
423 struct tegra_clk_pll *pll = to_clk_pll(hw); 443 struct tegra_clk_pll *pll = to_clk_pll(hw);
@@ -431,6 +451,8 @@ static int clk_pll_enable(struct clk_hw *hw)
431 451
432 ret = clk_pll_wait_for_lock(pll); 452 ret = clk_pll_wait_for_lock(pll);
433 453
454 pll_clk_start_ss(pll);
455
434 if (pll->lock) 456 if (pll->lock)
435 spin_unlock_irqrestore(pll->lock, flags); 457 spin_unlock_irqrestore(pll->lock, flags);
436 458
@@ -445,6 +467,8 @@ static void clk_pll_disable(struct clk_hw *hw)
445 if (pll->lock) 467 if (pll->lock)
446 spin_lock_irqsave(pll->lock, flags); 468 spin_lock_irqsave(pll->lock, flags);
447 469
470 pll_clk_stop_ss(pll);
471
448 _clk_pll_disable(hw); 472 _clk_pll_disable(hw);
449 473
450 if (pll->lock) 474 if (pll->lock)
@@ -666,6 +690,8 @@ static void _get_pll_mnp(struct tegra_clk_pll *pll,
666 struct tegra_clk_pll_params *params = pll->params; 690 struct tegra_clk_pll_params *params = pll->params;
667 struct div_nmp *div_nmp = params->div_nmp; 691 struct div_nmp *div_nmp = params->div_nmp;
668 692
693 *cfg = (struct tegra_clk_pll_freq_table) { };
694
669 if ((params->flags & (TEGRA_PLLM | TEGRA_PLLMB)) && 695 if ((params->flags & (TEGRA_PLLM | TEGRA_PLLMB)) &&
670 (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & 696 (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) &
671 PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { 697 PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) {
@@ -716,26 +742,6 @@ static void _update_pll_cpcon(struct tegra_clk_pll *pll,
716 pll_writel_misc(val, pll); 742 pll_writel_misc(val, pll);
717} 743}
718 744
719static void pll_clk_start_ss(struct tegra_clk_pll *pll)
720{
721 if (pll->params->defaults_set && pll->params->ssc_ctrl_reg) {
722 u32 val = pll_readl(pll->params->ssc_ctrl_reg, pll);
723
724 val |= pll->params->ssc_ctrl_en_mask;
725 pll_writel(val, pll->params->ssc_ctrl_reg, pll);
726 }
727}
728
729static void pll_clk_stop_ss(struct tegra_clk_pll *pll)
730{
731 if (pll->params->defaults_set && pll->params->ssc_ctrl_reg) {
732 u32 val = pll_readl(pll->params->ssc_ctrl_reg, pll);
733
734 val &= ~pll->params->ssc_ctrl_en_mask;
735 pll_writel(val, pll->params->ssc_ctrl_reg, pll);
736 }
737}
738
739static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, 745static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
740 unsigned long rate) 746 unsigned long rate)
741{ 747{
@@ -2251,7 +2257,7 @@ tegra_clk_register_pllu_tegra114(const char *name, const char *parent_name,
2251} 2257}
2252#endif 2258#endif
2253 2259
2254#if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC) 2260#if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC) || defined(CONFIG_ARCH_TEGRA_210_SOC)
2255static const struct clk_ops tegra_clk_pllss_ops = { 2261static const struct clk_ops tegra_clk_pllss_ops = {
2256 .is_enabled = clk_pll_is_enabled, 2262 .is_enabled = clk_pll_is_enabled,
2257 .enable = clk_pll_enable, 2263 .enable = clk_pll_enable,
@@ -2349,7 +2355,6 @@ struct clk *tegra_clk_register_pllre_tegra210(const char *name,
2349 struct tegra_clk_pll_params *pll_params, 2355 struct tegra_clk_pll_params *pll_params,
2350 spinlock_t *lock, unsigned long parent_rate) 2356 spinlock_t *lock, unsigned long parent_rate)
2351{ 2357{
2352 u32 val;
2353 struct tegra_clk_pll *pll; 2358 struct tegra_clk_pll *pll;
2354 struct clk *clk; 2359 struct clk *clk;
2355 2360
@@ -2363,26 +2368,8 @@ struct clk *tegra_clk_register_pllre_tegra210(const char *name,
2363 if (IS_ERR(pll)) 2368 if (IS_ERR(pll))
2364 return ERR_CAST(pll); 2369 return ERR_CAST(pll);
2365 2370
2366 /* program minimum rate by default */
2367
2368 val = pll_readl_base(pll);
2369 if (val & PLL_BASE_ENABLE)
2370 WARN_ON(readl_relaxed(clk_base + pll_params->iddq_reg) &
2371 BIT(pll_params->iddq_bit_idx));
2372 else {
2373 val = 0x4 << divm_shift(pll);
2374 val |= 0x41 << divn_shift(pll);
2375 pll_writel_base(val, pll);
2376 }
2377
2378 /* disable lock override */
2379
2380 val = pll_readl_misc(pll);
2381 val &= ~BIT(29);
2382 pll_writel_misc(val, pll);
2383
2384 clk = _tegra_clk_register_pll(pll, name, parent_name, flags, 2371 clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
2385 &tegra_clk_pllre_ops); 2372 &tegra_clk_pll_ops);
2386 if (IS_ERR(clk)) 2373 if (IS_ERR(clk))
2387 kfree(pll); 2374 kfree(pll);
2388 2375
@@ -2604,46 +2591,6 @@ struct clk *tegra_clk_register_pllc_tegra210(const char *name,
2604 return clk; 2591 return clk;
2605} 2592}
2606 2593
2607struct clk *tegra_clk_register_pllxc_tegra210(const char *name,
2608 const char *parent_name, void __iomem *clk_base,
2609 void __iomem *pmc, unsigned long flags,
2610 struct tegra_clk_pll_params *pll_params,
2611 spinlock_t *lock)
2612{
2613 struct tegra_clk_pll *pll;
2614 struct clk *clk, *parent;
2615 unsigned long parent_rate;
2616
2617 parent = __clk_lookup(parent_name);
2618 if (!parent) {
2619 WARN(1, "parent clk %s of %s must be registered first\n",
2620 name, parent_name);
2621 return ERR_PTR(-EINVAL);
2622 }
2623
2624 if (!pll_params->pdiv_tohw)
2625 return ERR_PTR(-EINVAL);
2626
2627 parent_rate = clk_get_rate(parent);
2628
2629 pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate);
2630
2631 if (pll_params->adjust_vco)
2632 pll_params->vco_min = pll_params->adjust_vco(pll_params,
2633 parent_rate);
2634
2635 pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
2636 if (IS_ERR(pll))
2637 return ERR_CAST(pll);
2638
2639 clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
2640 &tegra_clk_pll_ops);
2641 if (IS_ERR(clk))
2642 kfree(pll);
2643
2644 return clk;
2645}
2646
2647struct clk *tegra_clk_register_pllss_tegra210(const char *name, 2594struct clk *tegra_clk_register_pllss_tegra210(const char *name,
2648 const char *parent_name, void __iomem *clk_base, 2595 const char *parent_name, void __iomem *clk_base,
2649 unsigned long flags, 2596 unsigned long flags,
@@ -2652,10 +2599,8 @@ struct clk *tegra_clk_register_pllss_tegra210(const char *name,
2652{ 2599{
2653 struct tegra_clk_pll *pll; 2600 struct tegra_clk_pll *pll;
2654 struct clk *clk, *parent; 2601 struct clk *clk, *parent;
2655 struct tegra_clk_pll_freq_table cfg;
2656 unsigned long parent_rate; 2602 unsigned long parent_rate;
2657 u32 val; 2603 u32 val;
2658 int i;
2659 2604
2660 if (!pll_params->div_nmp) 2605 if (!pll_params->div_nmp)
2661 return ERR_PTR(-EINVAL); 2606 return ERR_PTR(-EINVAL);
@@ -2667,13 +2612,11 @@ struct clk *tegra_clk_register_pllss_tegra210(const char *name,
2667 return ERR_PTR(-EINVAL); 2612 return ERR_PTR(-EINVAL);
2668 } 2613 }
2669 2614
2670 pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); 2615 val = readl_relaxed(clk_base + pll_params->base_reg);
2671 if (IS_ERR(pll)) 2616 if (val & PLLSS_REF_SRC_SEL_MASK) {
2672 return ERR_CAST(pll); 2617 WARN(1, "not supported reference clock for %s\n", name);
2673 2618 return ERR_PTR(-EINVAL);
2674 val = pll_readl_base(pll); 2619 }
2675 val &= ~PLLSS_REF_SRC_SEL_MASK;
2676 pll_writel_base(val, pll);
2677 2620
2678 parent_rate = clk_get_rate(parent); 2621 parent_rate = clk_get_rate(parent);
2679 2622
@@ -2683,36 +2626,10 @@ struct clk *tegra_clk_register_pllss_tegra210(const char *name,
2683 pll_params->vco_min = pll_params->adjust_vco(pll_params, 2626 pll_params->vco_min = pll_params->adjust_vco(pll_params,
2684 parent_rate); 2627 parent_rate);
2685 2628
2686 /* initialize PLL to minimum rate */ 2629 pll_params->flags |= TEGRA_PLL_BYPASS;
2687 2630 pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
2688 cfg.m = _pll_fixed_mdiv(pll_params, parent_rate); 2631 if (IS_ERR(pll))
2689 cfg.n = cfg.m * pll_params->vco_min / parent_rate; 2632 return ERR_CAST(pll);
2690
2691 for (i = 0; pll_params->pdiv_tohw[i].pdiv; i++)
2692 ;
2693 if (!i) {
2694 kfree(pll);
2695 return ERR_PTR(-EINVAL);
2696 }
2697
2698 cfg.p = pll_params->pdiv_tohw[i-1].hw_val;
2699
2700 _update_pll_mnp(pll, &cfg);
2701
2702 pll_writel_misc(PLLSS_MISC_DEFAULT, pll);
2703
2704 val = pll_readl_base(pll);
2705 if (val & PLL_BASE_ENABLE) {
2706 if (val & BIT(pll_params->iddq_bit_idx)) {
2707 WARN(1, "%s is on but IDDQ set\n", name);
2708 kfree(pll);
2709 return ERR_PTR(-EINVAL);
2710 }
2711 } else
2712 val |= BIT(pll_params->iddq_bit_idx);
2713
2714 val &= ~PLLSS_LOCK_OVERRIDE;
2715 pll_writel_base(val, pll);
2716 2633
2717 clk = _tegra_clk_register_pll(pll, name, parent_name, flags, 2634 clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
2718 &tegra_clk_pll_ops); 2635 &tegra_clk_pll_ops);
diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c
index 294bfe40a4f5..848255cc0209 100644
--- a/drivers/clk/tegra/clk-tegra-periph.c
+++ b/drivers/clk/tegra/clk-tegra-periph.c
@@ -216,7 +216,8 @@
216 _clk_num, _clk_id) \ 216 _clk_num, _clk_id) \
217 TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 217 TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\
218 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\ 218 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\
219 _clk_num, 0, _clk_id, _parents##_idx, 0, NULL) 219 _clk_num, TEGRA_PERIPH_ON_APB, _clk_id, \
220 _parents##_idx, 0, NULL)
220 221
221#define XUSB(_name, _parents, _offset, \ 222#define XUSB(_name, _parents, _offset, \
222 _clk_num, _gate_flags, _clk_id) \ 223 _clk_num, _gate_flags, _clk_id) \
diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c
index 474de0f0c26d..4f6fd307cb70 100644
--- a/drivers/clk/tegra/clk-tegra-super-gen4.c
+++ b/drivers/clk/tegra/clk-tegra-super-gen4.c
@@ -232,8 +232,15 @@ static void __init tegra_super_clk_init(void __iomem *clk_base,
232 if (!dt_clk) 232 if (!dt_clk)
233 return; 233 return;
234 234
235 clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, 235#if defined(CONFIG_ARCH_TEGRA_210_SOC)
236 pmc_base, CLK_IGNORE_UNUSED, params, NULL); 236 if (gen_info->gen == gen5)
237 clk = tegra_clk_register_pllc_tegra210("pll_x", "pll_ref",
238 clk_base, pmc_base, CLK_IGNORE_UNUSED, params, NULL);
239 else
240#endif
241 clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base,
242 pmc_base, CLK_IGNORE_UNUSED, params, NULL);
243
237 *dt_clk = clk; 244 *dt_clk = clk;
238 245
239 /* PLLX_OUT0 */ 246 /* PLLX_OUT0 */
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index 1024e853ea65..6d7a613f2656 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -146,7 +146,7 @@
146#define PLLD_SDM_EN_MASK BIT(16) 146#define PLLD_SDM_EN_MASK BIT(16)
147 147
148#define PLLD2_SDM_EN_MASK BIT(31) 148#define PLLD2_SDM_EN_MASK BIT(31)
149#define PLLD2_SSC_EN_MASK BIT(30) 149#define PLLD2_SSC_EN_MASK 0
150 150
151#define PLLDP_SS_CFG 0x598 151#define PLLDP_SS_CFG 0x598
152#define PLLDP_SDM_EN_MASK BIT(31) 152#define PLLDP_SDM_EN_MASK BIT(31)
@@ -241,6 +241,9 @@
241#define PLL_SDM_COEFF BIT(13) 241#define PLL_SDM_COEFF BIT(13)
242#define sdin_din_to_data(din) ((u16)((din) ? : 0xFFFFU)) 242#define sdin_din_to_data(din) ((u16)((din) ? : 0xFFFFU))
243#define sdin_data_to_din(dat) (((dat) == 0xFFFFU) ? 0 : (s16)dat) 243#define sdin_data_to_din(dat) (((dat) == 0xFFFFU) ? 0 : (s16)dat)
244/* This macro returns ndiv effective scaled to SDM range */
245#define sdin_get_n_eff(cfg) ((cfg)->n * PLL_SDM_COEFF + ((cfg)->sdm_data ? \
246 (PLL_SDM_COEFF/2 + sdin_data_to_din((cfg)->sdm_data)) : 0))
244 247
245/* Tegra CPU clock and reset control regs */ 248/* Tegra CPU clock and reset control regs */
246#define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 249#define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470
@@ -715,8 +718,6 @@ static void plldss_defaults(const char *pll_name, struct tegra_clk_pll *plldss,
715 plldss->params->defaults_set = true; 718 plldss->params->defaults_set = true;
716 719
717 if (val & PLL_ENABLE) { 720 if (val & PLL_ENABLE) {
718 pr_warn("%s already enabled. Postponing set full defaults\n",
719 pll_name);
720 721
721 /* 722 /*
722 * PLL is ON: check if defaults already set, then set those 723 * PLL is ON: check if defaults already set, then set those
@@ -755,6 +756,10 @@ static void plldss_defaults(const char *pll_name, struct tegra_clk_pll *plldss,
755 (~PLLDSS_MISC1_CFG_EN_SDM)); 756 (~PLLDSS_MISC1_CFG_EN_SDM));
756 } 757 }
757 758
759 if (!plldss->params->defaults_set)
760 pr_warn("%s already enabled. Postponing set full defaults\n",
761 pll_name);
762
758 /* Enable lock detect */ 763 /* Enable lock detect */
759 if (val & PLLDSS_BASE_LOCK_OVERRIDE) { 764 if (val & PLLDSS_BASE_LOCK_OVERRIDE) {
760 val &= ~PLLDSS_BASE_LOCK_OVERRIDE; 765 val &= ~PLLDSS_BASE_LOCK_OVERRIDE;
@@ -1288,8 +1293,7 @@ static int tegra210_pll_fixed_mdiv_cfg(struct clk_hw *hw,
1288 s -= PLL_SDM_COEFF / 2; 1293 s -= PLL_SDM_COEFF / 2;
1289 cfg->sdm_data = sdin_din_to_data(s); 1294 cfg->sdm_data = sdin_din_to_data(s);
1290 } 1295 }
1291 cfg->output_rate *= cfg->n * PLL_SDM_COEFF + PLL_SDM_COEFF/2 + 1296 cfg->output_rate *= sdin_get_n_eff(cfg);
1292 sdin_data_to_din(cfg->sdm_data);
1293 cfg->output_rate /= p * cfg->m * PLL_SDM_COEFF; 1297 cfg->output_rate /= p * cfg->m * PLL_SDM_COEFF;
1294 } else { 1298 } else {
1295 cfg->output_rate *= cfg->n; 1299 cfg->output_rate *= cfg->n;
@@ -1314,8 +1318,7 @@ static int tegra210_pll_fixed_mdiv_cfg(struct clk_hw *hw,
1314 */ 1318 */
1315static void tegra210_clk_pll_set_gain(struct tegra_clk_pll_freq_table *cfg) 1319static void tegra210_clk_pll_set_gain(struct tegra_clk_pll_freq_table *cfg)
1316{ 1320{
1317 cfg->n = cfg->n * PLL_SDM_COEFF + PLL_SDM_COEFF/2 + 1321 cfg->n = sdin_get_n_eff(cfg);
1318 sdin_data_to_din(cfg->sdm_data);
1319 cfg->m *= PLL_SDM_COEFF; 1322 cfg->m *= PLL_SDM_COEFF;
1320} 1323}
1321 1324
@@ -2204,7 +2207,6 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = {
2204 [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true }, 2207 [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true },
2205 [tegra_clk_pll_g_ref] = { .dt_id = TEGRA210_CLK_PLL_G_REF, .present = true, }, 2208 [tegra_clk_pll_g_ref] = { .dt_id = TEGRA210_CLK_PLL_G_REF, .present = true, },
2206 [tegra_clk_uartb_8] = { .dt_id = TEGRA210_CLK_UARTB, .present = true }, 2209 [tegra_clk_uartb_8] = { .dt_id = TEGRA210_CLK_UARTB, .present = true },
2207 [tegra_clk_vfir] = { .dt_id = TEGRA210_CLK_VFIR, .present = true },
2208 [tegra_clk_spdif_in_8] = { .dt_id = TEGRA210_CLK_SPDIF_IN, .present = true }, 2210 [tegra_clk_spdif_in_8] = { .dt_id = TEGRA210_CLK_SPDIF_IN, .present = true },
2209 [tegra_clk_spdif_out] = { .dt_id = TEGRA210_CLK_SPDIF_OUT, .present = true }, 2211 [tegra_clk_spdif_out] = { .dt_id = TEGRA210_CLK_SPDIF_OUT, .present = true },
2210 [tegra_clk_vi_10] = { .dt_id = TEGRA210_CLK_VI, .present = true }, 2212 [tegra_clk_vi_10] = { .dt_id = TEGRA210_CLK_VI, .present = true },
@@ -2470,15 +2472,14 @@ static void tegra210_utmi_param_configure(void)
2470 reg |= UTMIP_PLL_CFG2_STABLE_COUNT(utmi_parameters[i].stable_count); 2472 reg |= UTMIP_PLL_CFG2_STABLE_COUNT(utmi_parameters[i].stable_count);
2471 2473
2472 reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0); 2474 reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0);
2473
2474 reg |= 2475 reg |=
2475 UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(utmi_parameters[i].active_delay_count); 2476 UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(utmi_parameters[i].active_delay_count);
2476 writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2); 2477 writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2);
2477 2478
2478 /* Program UTMIP PLL delay and oscillator frequency counts */ 2479 /* Program UTMIP PLL delay and oscillator frequency counts */
2479 reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1); 2480 reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1);
2480 reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0);
2481 2481
2482 reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0);
2482 reg |= 2483 reg |=
2483 UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(utmi_parameters[i].enable_delay_count); 2484 UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(utmi_parameters[i].enable_delay_count);
2484 2485
@@ -2494,7 +2495,8 @@ static void tegra210_utmi_param_configure(void)
2494 reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; 2495 reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN;
2495 reg |= UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP; 2496 reg |= UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP;
2496 writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); 2497 writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1);
2497 udelay(1); 2498
2499 udelay(20);
2498 2500
2499 /* Enable samplers for SNPS, XUSB_HOST, XUSB_DEV */ 2501 /* Enable samplers for SNPS, XUSB_HOST, XUSB_DEV */
2500 reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2); 2502 reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2);
@@ -2552,6 +2554,7 @@ static int tegra210_enable_pllu(void)
2552 reg = readl_relaxed(clk_base + pllu.params->ext_misc_reg[0]); 2554 reg = readl_relaxed(clk_base + pllu.params->ext_misc_reg[0]);
2553 reg &= ~BIT(pllu.params->iddq_bit_idx); 2555 reg &= ~BIT(pllu.params->iddq_bit_idx);
2554 writel_relaxed(reg, clk_base + pllu.params->ext_misc_reg[0]); 2556 writel_relaxed(reg, clk_base + pllu.params->ext_misc_reg[0]);
2557 udelay(5);
2555 2558
2556 reg = readl_relaxed(clk_base + PLLU_BASE); 2559 reg = readl_relaxed(clk_base + PLLU_BASE);
2557 reg &= ~GENMASK(20, 0); 2560 reg &= ~GENMASK(20, 0);
@@ -2559,6 +2562,7 @@ static int tegra210_enable_pllu(void)
2559 reg |= fentry->n << 8; 2562 reg |= fentry->n << 8;
2560 reg |= fentry->p << 16; 2563 reg |= fentry->p << 16;
2561 writel(reg, clk_base + PLLU_BASE); 2564 writel(reg, clk_base + PLLU_BASE);
2565 udelay(1);
2562 reg |= PLL_ENABLE; 2566 reg |= PLL_ENABLE;
2563 writel(reg, clk_base + PLLU_BASE); 2567 writel(reg, clk_base + PLLU_BASE);
2564 2568
@@ -2699,7 +2703,7 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
2699 struct clk *clk; 2703 struct clk *clk;
2700 2704
2701 /* PLLC */ 2705 /* PLLC */
2702 clk = tegra_clk_register_pllxc_tegra210("pll_c", "pll_ref", clk_base, 2706 clk = tegra_clk_register_pllc_tegra210("pll_c", "pll_ref", clk_base,
2703 pmc, 0, &pll_c_params, NULL); 2707 pmc, 0, &pll_c_params, NULL);
2704 if (!WARN_ON(IS_ERR(clk))) 2708 if (!WARN_ON(IS_ERR(clk)))
2705 clk_register_clkdev(clk, "pll_c", NULL); 2709 clk_register_clkdev(clk, "pll_c", NULL);
@@ -2798,14 +2802,14 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
2798 /* PLLU_60M */ 2802 /* PLLU_60M */
2799 clk = clk_register_gate(NULL, "pll_u_60M", "pll_u_out2", 2803 clk = clk_register_gate(NULL, "pll_u_60M", "pll_u_out2",
2800 CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, 2804 CLK_SET_RATE_PARENT, clk_base + PLLU_BASE,
2801 23, 0, NULL); 2805 23, 0, &pll_u_lock);
2802 clk_register_clkdev(clk, "pll_u_60M", NULL); 2806 clk_register_clkdev(clk, "pll_u_60M", NULL);
2803 clks[TEGRA210_CLK_PLL_U_60M] = clk; 2807 clks[TEGRA210_CLK_PLL_U_60M] = clk;
2804 2808
2805 /* PLLU_48M */ 2809 /* PLLU_48M */
2806 clk = clk_register_gate(NULL, "pll_u_48M", "pll_u_out1", 2810 clk = clk_register_gate(NULL, "pll_u_48M", "pll_u_out1",
2807 CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, 2811 CLK_SET_RATE_PARENT, clk_base + PLLU_BASE,
2808 25, 0, NULL); 2812 25, 0, &pll_u_lock);
2809 clk_register_clkdev(clk, "pll_u_48M", NULL); 2813 clk_register_clkdev(clk, "pll_u_48M", NULL);
2810 clks[TEGRA210_CLK_PLL_U_48M] = clk; 2814 clks[TEGRA210_CLK_PLL_U_48M] = clk;
2811 2815
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 945b07093afa..872f1189ad7f 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -362,12 +362,6 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
362 struct tegra_clk_pll_params *pll_params, 362 struct tegra_clk_pll_params *pll_params,
363 spinlock_t *lock); 363 spinlock_t *lock);
364 364
365struct clk *tegra_clk_register_pllxc_tegra210(const char *name,
366 const char *parent_name, void __iomem *clk_base,
367 void __iomem *pmc, unsigned long flags,
368 struct tegra_clk_pll_params *pll_params,
369 spinlock_t *lock);
370
371struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, 365struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
372 void __iomem *clk_base, void __iomem *pmc, 366 void __iomem *clk_base, void __iomem *pmc,
373 unsigned long flags, 367 unsigned long flags,
diff --git a/drivers/clk/ti/adpll.c b/drivers/clk/ti/adpll.c
index 255cafb18336..d6036c788fab 100644
--- a/drivers/clk/ti/adpll.c
+++ b/drivers/clk/ti/adpll.c
@@ -222,7 +222,7 @@ static int ti_adpll_setup_clock(struct ti_adpll_data *d, struct clk *clock,
222 222
223 /* Separate con_id in format "pll040dcoclkldo" to fit MAX_CON_ID */ 223 /* Separate con_id in format "pll040dcoclkldo" to fit MAX_CON_ID */
224 postfix = strrchr(name, '.'); 224 postfix = strrchr(name, '.');
225 if (strlen(postfix) > 1) { 225 if (postfix && strlen(postfix) > 1) {
226 if (strlen(postfix) > ADPLL_MAX_CON_ID) 226 if (strlen(postfix) > ADPLL_MAX_CON_ID)
227 dev_warn(d->dev, "clock %s con_id lookup may fail\n", 227 dev_warn(d->dev, "clock %s con_id lookup may fail\n",
228 name); 228 name);
@@ -486,7 +486,7 @@ static u8 ti_adpll_get_parent(struct clk_hw *hw)
486 return 0; 486 return 0;
487} 487}
488 488
489static struct clk_ops ti_adpll_ops = { 489static const struct clk_ops ti_adpll_ops = {
490 .prepare = ti_adpll_prepare, 490 .prepare = ti_adpll_prepare,
491 .unprepare = ti_adpll_unprepare, 491 .unprepare = ti_adpll_unprepare,
492 .is_prepared = ti_adpll_is_prepared, 492 .is_prepared = ti_adpll_is_prepared,
diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c
index 06f486b3488c..83b148f8037c 100644
--- a/drivers/clk/ti/apll.c
+++ b/drivers/clk/ti/apll.c
@@ -304,7 +304,7 @@ static void omap2_apll_disable(struct clk_hw *hw)
304 ti_clk_ll_ops->clk_writel(v, &ad->control_reg); 304 ti_clk_ll_ops->clk_writel(v, &ad->control_reg);
305} 305}
306 306
307static struct clk_ops omap2_apll_ops = { 307static const struct clk_ops omap2_apll_ops = {
308 .enable = &omap2_apll_enable, 308 .enable = &omap2_apll_enable,
309 .disable = &omap2_apll_disable, 309 .disable = &omap2_apll_disable,
310 .is_enabled = &omap2_apll_is_enabled, 310 .is_enabled = &omap2_apll_is_enabled,
diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
index fbedc6a9fed0..07a805125e98 100644
--- a/drivers/clk/ti/clockdomain.c
+++ b/drivers/clk/ti/clockdomain.c
@@ -138,8 +138,8 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
138 for (i = 0; i < num_clks; i++) { 138 for (i = 0; i < num_clks; i++) {
139 clk = of_clk_get(node, i); 139 clk = of_clk_get(node, i);
140 if (IS_ERR(clk)) { 140 if (IS_ERR(clk)) {
141 pr_err("%s: Failed get %s' clock nr %d (%ld)\n", 141 pr_err("%s: Failed get %pOF' clock nr %d (%ld)\n",
142 __func__, node->full_name, i, PTR_ERR(clk)); 142 __func__, node, i, PTR_ERR(clk));
143 continue; 143 continue;
144 } 144 }
145 clk_hw = __clk_get_hw(clk); 145 clk_hw = __clk_get_hw(clk);
diff --git a/drivers/clk/ti/fapll.c b/drivers/clk/ti/fapll.c
index 66a0d0ed8b55..071af44b1ba8 100644
--- a/drivers/clk/ti/fapll.c
+++ b/drivers/clk/ti/fapll.c
@@ -268,7 +268,7 @@ static int ti_fapll_set_rate(struct clk_hw *hw, unsigned long rate,
268 return 0; 268 return 0;
269} 269}
270 270
271static struct clk_ops ti_fapll_ops = { 271static const struct clk_ops ti_fapll_ops = {
272 .enable = ti_fapll_enable, 272 .enable = ti_fapll_enable,
273 .disable = ti_fapll_disable, 273 .disable = ti_fapll_disable,
274 .is_enabled = ti_fapll_is_enabled, 274 .is_enabled = ti_fapll_is_enabled,
@@ -478,7 +478,7 @@ static int ti_fapll_synth_set_rate(struct clk_hw *hw, unsigned long rate,
478 return 0; 478 return 0;
479} 479}
480 480
481static struct clk_ops ti_fapll_synt_ops = { 481static const struct clk_ops ti_fapll_synt_ops = {
482 .enable = ti_fapll_synth_enable, 482 .enable = ti_fapll_synth_enable,
483 .disable = ti_fapll_synth_disable, 483 .disable = ti_fapll_synth_disable,
484 .is_enabled = ti_fapll_synth_is_enabled, 484 .is_enabled = ti_fapll_synth_is_enabled,
diff --git a/drivers/clk/uniphier/clk-uniphier-core.c b/drivers/clk/uniphier/clk-uniphier-core.c
index 2cf386347f0c..e09f3dd46318 100644
--- a/drivers/clk/uniphier/clk-uniphier-core.c
+++ b/drivers/clk/uniphier/clk-uniphier-core.c
@@ -111,10 +111,6 @@ static int uniphier_clk_remove(struct platform_device *pdev)
111static const struct of_device_id uniphier_clk_match[] = { 111static const struct of_device_id uniphier_clk_match[] = {
112 /* System clock */ 112 /* System clock */
113 { 113 {
114 .compatible = "socionext,uniphier-sld3-clock",
115 .data = uniphier_sld3_sys_clk_data,
116 },
117 {
118 .compatible = "socionext,uniphier-ld4-clock", 114 .compatible = "socionext,uniphier-ld4-clock",
119 .data = uniphier_ld4_sys_clk_data, 115 .data = uniphier_ld4_sys_clk_data,
120 }, 116 },
@@ -142,22 +138,22 @@ static const struct of_device_id uniphier_clk_match[] = {
142 .compatible = "socionext,uniphier-ld20-clock", 138 .compatible = "socionext,uniphier-ld20-clock",
143 .data = uniphier_ld20_sys_clk_data, 139 .data = uniphier_ld20_sys_clk_data,
144 }, 140 },
145 /* Media I/O clock, SD clock */
146 { 141 {
147 .compatible = "socionext,uniphier-sld3-mio-clock", 142 .compatible = "socionext,uniphier-pxs3-clock",
148 .data = uniphier_sld3_mio_clk_data, 143 .data = uniphier_pxs3_sys_clk_data,
149 }, 144 },
145 /* Media I/O clock, SD clock */
150 { 146 {
151 .compatible = "socionext,uniphier-ld4-mio-clock", 147 .compatible = "socionext,uniphier-ld4-mio-clock",
152 .data = uniphier_sld3_mio_clk_data, 148 .data = uniphier_ld4_mio_clk_data,
153 }, 149 },
154 { 150 {
155 .compatible = "socionext,uniphier-pro4-mio-clock", 151 .compatible = "socionext,uniphier-pro4-mio-clock",
156 .data = uniphier_sld3_mio_clk_data, 152 .data = uniphier_ld4_mio_clk_data,
157 }, 153 },
158 { 154 {
159 .compatible = "socionext,uniphier-sld8-mio-clock", 155 .compatible = "socionext,uniphier-sld8-mio-clock",
160 .data = uniphier_sld3_mio_clk_data, 156 .data = uniphier_ld4_mio_clk_data,
161 }, 157 },
162 { 158 {
163 .compatible = "socionext,uniphier-pro5-sd-clock", 159 .compatible = "socionext,uniphier-pro5-sd-clock",
@@ -169,12 +165,16 @@ static const struct of_device_id uniphier_clk_match[] = {
169 }, 165 },
170 { 166 {
171 .compatible = "socionext,uniphier-ld11-mio-clock", 167 .compatible = "socionext,uniphier-ld11-mio-clock",
172 .data = uniphier_sld3_mio_clk_data, 168 .data = uniphier_ld4_mio_clk_data,
173 }, 169 },
174 { 170 {
175 .compatible = "socionext,uniphier-ld20-sd-clock", 171 .compatible = "socionext,uniphier-ld20-sd-clock",
176 .data = uniphier_pro5_sd_clk_data, 172 .data = uniphier_pro5_sd_clk_data,
177 }, 173 },
174 {
175 .compatible = "socionext,uniphier-pxs3-sd-clock",
176 .data = uniphier_pro5_sd_clk_data,
177 },
178 /* Peripheral clock */ 178 /* Peripheral clock */
179 { 179 {
180 .compatible = "socionext,uniphier-ld4-peri-clock", 180 .compatible = "socionext,uniphier-ld4-peri-clock",
@@ -204,6 +204,10 @@ static const struct of_device_id uniphier_clk_match[] = {
204 .compatible = "socionext,uniphier-ld20-peri-clock", 204 .compatible = "socionext,uniphier-ld20-peri-clock",
205 .data = uniphier_pro4_peri_clk_data, 205 .data = uniphier_pro4_peri_clk_data,
206 }, 206 },
207 {
208 .compatible = "socionext,uniphier-pxs3-peri-clock",
209 .data = uniphier_pro4_peri_clk_data,
210 },
207 { /* sentinel */ } 211 { /* sentinel */ }
208}; 212};
209 213
diff --git a/drivers/clk/uniphier/clk-uniphier-mio.c b/drivers/clk/uniphier/clk-uniphier-mio.c
index 218d20f099ce..16e4d303f535 100644
--- a/drivers/clk/uniphier/clk-uniphier-mio.c
+++ b/drivers/clk/uniphier/clk-uniphier-mio.c
@@ -76,7 +76,7 @@
76#define UNIPHIER_MIO_CLK_DMAC(idx) \ 76#define UNIPHIER_MIO_CLK_DMAC(idx) \
77 UNIPHIER_CLK_GATE("miodmac", (idx), "stdmac", 0x20, 25) 77 UNIPHIER_CLK_GATE("miodmac", (idx), "stdmac", 0x20, 25)
78 78
79const struct uniphier_clk_data uniphier_sld3_mio_clk_data[] = { 79const struct uniphier_clk_data uniphier_ld4_mio_clk_data[] = {
80 UNIPHIER_MIO_CLK_SD_FIXED, 80 UNIPHIER_MIO_CLK_SD_FIXED,
81 UNIPHIER_MIO_CLK_SD(0, 0), 81 UNIPHIER_MIO_CLK_SD(0, 0),
82 UNIPHIER_MIO_CLK_SD(1, 1), 82 UNIPHIER_MIO_CLK_SD(1, 1),
@@ -85,11 +85,9 @@ const struct uniphier_clk_data uniphier_sld3_mio_clk_data[] = {
85 UNIPHIER_MIO_CLK_USB2(8, 0), 85 UNIPHIER_MIO_CLK_USB2(8, 0),
86 UNIPHIER_MIO_CLK_USB2(9, 1), 86 UNIPHIER_MIO_CLK_USB2(9, 1),
87 UNIPHIER_MIO_CLK_USB2(10, 2), 87 UNIPHIER_MIO_CLK_USB2(10, 2),
88 UNIPHIER_MIO_CLK_USB2(11, 3),
89 UNIPHIER_MIO_CLK_USB2_PHY(12, 0), 88 UNIPHIER_MIO_CLK_USB2_PHY(12, 0),
90 UNIPHIER_MIO_CLK_USB2_PHY(13, 1), 89 UNIPHIER_MIO_CLK_USB2_PHY(13, 1),
91 UNIPHIER_MIO_CLK_USB2_PHY(14, 2), 90 UNIPHIER_MIO_CLK_USB2_PHY(14, 2),
92 UNIPHIER_MIO_CLK_USB2_PHY(15, 3),
93 { /* sentinel */ } 91 { /* sentinel */ }
94}; 92};
95 93
diff --git a/drivers/clk/uniphier/clk-uniphier-sys.c b/drivers/clk/uniphier/clk-uniphier-sys.c
index ad0218182a9f..0e396f3da526 100644
--- a/drivers/clk/uniphier/clk-uniphier-sys.c
+++ b/drivers/clk/uniphier/clk-uniphier-sys.c
@@ -17,7 +17,7 @@
17 17
18#include "clk-uniphier.h" 18#include "clk-uniphier.h"
19 19
20#define UNIPHIER_SLD3_SYS_CLK_SD \ 20#define UNIPHIER_LD4_SYS_CLK_SD \
21 UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 8), \ 21 UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 8), \
22 UNIPHIER_CLK_FACTOR("sd-133m", -1, "vpll27a", 1, 2) 22 UNIPHIER_CLK_FACTOR("sd-133m", -1, "vpll27a", 1, 2)
23 23
@@ -30,7 +30,7 @@
30 UNIPHIER_CLK_FACTOR("sd-133m", -1, "spll", 1, 15) 30 UNIPHIER_CLK_FACTOR("sd-133m", -1, "spll", 1, 15)
31 31
32/* Denali driver requires clk_x rate (clk: 50MHz, clk_x & ecc_clk: 200MHz) */ 32/* Denali driver requires clk_x rate (clk: 50MHz, clk_x & ecc_clk: 200MHz) */
33#define UNIPHIER_SLD3_SYS_CLK_NAND(idx) \ 33#define UNIPHIER_LD4_SYS_CLK_NAND(idx) \
34 UNIPHIER_CLK_FACTOR("nand-200m", -1, "spll", 1, 8), \ 34 UNIPHIER_CLK_FACTOR("nand-200m", -1, "spll", 1, 8), \
35 UNIPHIER_CLK_GATE("nand", (idx), "nand-200m", 0x2104, 2) 35 UNIPHIER_CLK_GATE("nand", (idx), "nand-200m", 0x2104, 2)
36 36
@@ -45,7 +45,7 @@
45#define UNIPHIER_LD11_SYS_CLK_EMMC(idx) \ 45#define UNIPHIER_LD11_SYS_CLK_EMMC(idx) \
46 UNIPHIER_CLK_GATE("emmc", (idx), NULL, 0x210c, 2) 46 UNIPHIER_CLK_GATE("emmc", (idx), NULL, 0x210c, 2)
47 47
48#define UNIPHIER_SLD3_SYS_CLK_STDMAC(idx) \ 48#define UNIPHIER_LD4_SYS_CLK_STDMAC(idx) \
49 UNIPHIER_CLK_GATE("stdmac", (idx), NULL, 0x2104, 10) 49 UNIPHIER_CLK_GATE("stdmac", (idx), NULL, 0x2104, 10)
50 50
51#define UNIPHIER_LD11_SYS_CLK_STDMAC(idx) \ 51#define UNIPHIER_LD11_SYS_CLK_STDMAC(idx) \
@@ -57,19 +57,23 @@
57#define UNIPHIER_PRO4_SYS_CLK_USB3(idx, ch) \ 57#define UNIPHIER_PRO4_SYS_CLK_USB3(idx, ch) \
58 UNIPHIER_CLK_GATE("usb3" #ch, (idx), NULL, 0x2104, 16 + (ch)) 58 UNIPHIER_CLK_GATE("usb3" #ch, (idx), NULL, 0x2104, 16 + (ch))
59 59
60const struct uniphier_clk_data uniphier_sld3_sys_clk_data[] = { 60#define UNIPHIER_LD11_SYS_CLK_AIO(idx) \
61 UNIPHIER_CLK_FACTOR("spll", -1, "ref", 65, 1), /* 1597.44 MHz */ 61 UNIPHIER_CLK_FACTOR("aio-io200m", -1, "spll", 1, 10), \
62 UNIPHIER_CLK_FACTOR("upll", -1, "ref", 6000, 512), /* 288 MHz */ 62 UNIPHIER_CLK_GATE("aio", (idx), "aio-io200m", 0x2108, 0)
63 UNIPHIER_CLK_FACTOR("a2pll", -1, "ref", 24, 1), /* 589.824 MHz */ 63
64 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */ 64#define UNIPHIER_LD11_SYS_CLK_EVEA(idx) \
65 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16), 65 UNIPHIER_CLK_FACTOR("evea-io100m", -1, "spll", 1, 20), \
66 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), 66 UNIPHIER_CLK_GATE("evea", (idx), "evea-io100m", 0x2108, 1)
67 UNIPHIER_SLD3_SYS_CLK_NAND(2), 67
68 UNIPHIER_SLD3_SYS_CLK_SD, 68#define UNIPHIER_LD11_SYS_CLK_EXIV(idx) \
69 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), 69 UNIPHIER_CLK_FACTOR("exiv-io200m", -1, "spll", 1, 10), \
70 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), 70 UNIPHIER_CLK_GATE("exiv", (idx), "exiv-io200m", 0x2110, 2)
71 { /* sentinel */ } 71
72}; 72#define UNIPHIER_PRO4_SYS_CLK_ETHER(idx) \
73 UNIPHIER_CLK_GATE("ether", (idx), NULL, 0x2104, 12)
74
75#define UNIPHIER_LD11_SYS_CLK_ETHER(idx) \
76 UNIPHIER_CLK_GATE("ether", (idx), NULL, 0x210c, 6)
73 77
74const struct uniphier_clk_data uniphier_ld4_sys_clk_data[] = { 78const struct uniphier_clk_data uniphier_ld4_sys_clk_data[] = {
75 UNIPHIER_CLK_FACTOR("spll", -1, "ref", 65, 1), /* 1597.44 MHz */ 79 UNIPHIER_CLK_FACTOR("spll", -1, "ref", 65, 1), /* 1597.44 MHz */
@@ -78,10 +82,10 @@ const struct uniphier_clk_data uniphier_ld4_sys_clk_data[] = {
78 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */ 82 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */
79 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16), 83 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16),
80 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), 84 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16),
81 UNIPHIER_SLD3_SYS_CLK_NAND(2), 85 UNIPHIER_LD4_SYS_CLK_NAND(2),
82 UNIPHIER_SLD3_SYS_CLK_SD, 86 UNIPHIER_LD4_SYS_CLK_SD,
83 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), 87 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12),
84 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ 88 UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */
85 { /* sentinel */ } 89 { /* sentinel */ }
86}; 90};
87 91
@@ -92,10 +96,11 @@ const struct uniphier_clk_data uniphier_pro4_sys_clk_data[] = {
92 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */ 96 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */
93 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 8), 97 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 8),
94 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 32), 98 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 32),
95 UNIPHIER_SLD3_SYS_CLK_NAND(2), 99 UNIPHIER_LD4_SYS_CLK_NAND(2),
96 UNIPHIER_SLD3_SYS_CLK_SD, 100 UNIPHIER_LD4_SYS_CLK_SD,
97 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), 101 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12),
98 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC, MIO, RLE */ 102 UNIPHIER_PRO4_SYS_CLK_ETHER(6),
103 UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* HSC, MIO, RLE */
99 UNIPHIER_PRO4_SYS_CLK_GIO(12), /* Ether, SATA, USB3 */ 104 UNIPHIER_PRO4_SYS_CLK_GIO(12), /* Ether, SATA, USB3 */
100 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), 105 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0),
101 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), 106 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1),
@@ -108,10 +113,10 @@ const struct uniphier_clk_data uniphier_sld8_sys_clk_data[] = {
108 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */ 113 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */
109 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 20), 114 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 20),
110 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), 115 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16),
111 UNIPHIER_SLD3_SYS_CLK_NAND(2), 116 UNIPHIER_LD4_SYS_CLK_NAND(2),
112 UNIPHIER_SLD3_SYS_CLK_SD, 117 UNIPHIER_LD4_SYS_CLK_SD,
113 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), 118 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12),
114 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ 119 UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */
115 { /* sentinel */ } 120 { /* sentinel */ }
116}; 121};
117 122
@@ -123,7 +128,7 @@ const struct uniphier_clk_data uniphier_pro5_sys_clk_data[] = {
123 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48), 128 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48),
124 UNIPHIER_PRO5_SYS_CLK_NAND(2), 129 UNIPHIER_PRO5_SYS_CLK_NAND(2),
125 UNIPHIER_PRO5_SYS_CLK_SD, 130 UNIPHIER_PRO5_SYS_CLK_SD,
126 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC */ 131 UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* HSC */
127 UNIPHIER_PRO4_SYS_CLK_GIO(12), /* PCIe, USB3 */ 132 UNIPHIER_PRO4_SYS_CLK_GIO(12), /* PCIe, USB3 */
128 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), 133 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0),
129 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), 134 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1),
@@ -136,7 +141,8 @@ const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] = {
136 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48), 141 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48),
137 UNIPHIER_PRO5_SYS_CLK_NAND(2), 142 UNIPHIER_PRO5_SYS_CLK_NAND(2),
138 UNIPHIER_PRO5_SYS_CLK_SD, 143 UNIPHIER_PRO5_SYS_CLK_SD,
139 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC, RLE */ 144 UNIPHIER_PRO4_SYS_CLK_ETHER(6),
145 UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* HSC, RLE */
140 /* GIO is always clock-enabled: no function for 0x2104 bit6 */ 146 /* GIO is always clock-enabled: no function for 0x2104 bit6 */
141 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), 147 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0),
142 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), 148 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1),
@@ -156,8 +162,12 @@ const struct uniphier_clk_data uniphier_ld11_sys_clk_data[] = {
156 UNIPHIER_LD11_SYS_CLK_NAND(2), 162 UNIPHIER_LD11_SYS_CLK_NAND(2),
157 UNIPHIER_LD11_SYS_CLK_EMMC(4), 163 UNIPHIER_LD11_SYS_CLK_EMMC(4),
158 /* Index 5 reserved for eMMC PHY */ 164 /* Index 5 reserved for eMMC PHY */
165 UNIPHIER_LD11_SYS_CLK_ETHER(6),
159 UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC, MIO */ 166 UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC, MIO */
160 UNIPHIER_CLK_FACTOR("usb2", -1, "ref", 24, 25), 167 UNIPHIER_CLK_FACTOR("usb2", -1, "ref", 24, 25),
168 UNIPHIER_LD11_SYS_CLK_AIO(40),
169 UNIPHIER_LD11_SYS_CLK_EVEA(41),
170 UNIPHIER_LD11_SYS_CLK_EXIV(42),
161 /* CPU gears */ 171 /* CPU gears */
162 UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8), 172 UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8),
163 UNIPHIER_CLK_DIV4("mpll", 2, 3, 4, 8), 173 UNIPHIER_CLK_DIV4("mpll", 2, 3, 4, 8),
@@ -185,6 +195,7 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = {
185 UNIPHIER_LD11_SYS_CLK_EMMC(4), 195 UNIPHIER_LD11_SYS_CLK_EMMC(4),
186 /* Index 5 reserved for eMMC PHY */ 196 /* Index 5 reserved for eMMC PHY */
187 UNIPHIER_LD20_SYS_CLK_SD, 197 UNIPHIER_LD20_SYS_CLK_SD,
198 UNIPHIER_LD11_SYS_CLK_ETHER(6),
188 UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC */ 199 UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC */
189 /* GIO is always clock-enabled: no function for 0x210c bit5 */ 200 /* GIO is always clock-enabled: no function for 0x210c bit5 */
190 /* 201 /*
@@ -194,6 +205,9 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = {
194 UNIPHIER_CLK_GATE("usb30", 14, NULL, 0x210c, 14), 205 UNIPHIER_CLK_GATE("usb30", 14, NULL, 0x210c, 14),
195 UNIPHIER_CLK_GATE("usb30-phy0", 16, NULL, 0x210c, 12), 206 UNIPHIER_CLK_GATE("usb30-phy0", 16, NULL, 0x210c, 12),
196 UNIPHIER_CLK_GATE("usb30-phy1", 17, NULL, 0x210c, 13), 207 UNIPHIER_CLK_GATE("usb30-phy1", 17, NULL, 0x210c, 13),
208 UNIPHIER_LD11_SYS_CLK_AIO(40),
209 UNIPHIER_LD11_SYS_CLK_EVEA(41),
210 UNIPHIER_LD11_SYS_CLK_EXIV(42),
197 /* CPU gears */ 211 /* CPU gears */
198 UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8), 212 UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8),
199 UNIPHIER_CLK_DIV4("spll", 2, 3, 4, 8), 213 UNIPHIER_CLK_DIV4("spll", 2, 3, 4, 8),
@@ -209,3 +223,33 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = {
209 "spll/4", "spll/8", "s2pll/4", "s2pll/8"), 223 "spll/4", "spll/8", "s2pll/4", "s2pll/8"),
210 { /* sentinel */ } 224 { /* sentinel */ }
211}; 225};
226
227const struct uniphier_clk_data uniphier_pxs3_sys_clk_data[] = {
228 UNIPHIER_CLK_FACTOR("cpll", -1, "ref", 104, 1), /* ARM: 2600 MHz */
229 UNIPHIER_CLK_FACTOR("spll", -1, "ref", 80, 1), /* 2000 MHz */
230 UNIPHIER_CLK_FACTOR("s2pll", -1, "ref", 88, 1), /* IPP: 2400 MHz */
231 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34),
232 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40),
233 UNIPHIER_LD20_SYS_CLK_SD,
234 UNIPHIER_LD11_SYS_CLK_NAND(2),
235 UNIPHIER_LD11_SYS_CLK_EMMC(4),
236 UNIPHIER_CLK_GATE("usb30", 12, NULL, 0x2104, 4), /* =GIO0 */
237 UNIPHIER_CLK_GATE("usb31-0", 13, NULL, 0x2104, 5), /* =GIO1 */
238 UNIPHIER_CLK_GATE("usb31-1", 14, NULL, 0x2104, 6), /* =GIO1-1 */
239 UNIPHIER_CLK_GATE("usb30-phy0", 16, NULL, 0x210c, 16),
240 UNIPHIER_CLK_GATE("usb30-phy1", 17, NULL, 0x210c, 18),
241 UNIPHIER_CLK_GATE("usb30-phy2", 18, NULL, 0x210c, 20),
242 UNIPHIER_CLK_GATE("usb31-phy0", 20, NULL, 0x210c, 17),
243 UNIPHIER_CLK_GATE("usb31-phy1", 21, NULL, 0x210c, 19),
244 /* CPU gears */
245 UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8),
246 UNIPHIER_CLK_DIV4("spll", 2, 3, 4, 8),
247 UNIPHIER_CLK_DIV4("s2pll", 2, 3, 4, 8),
248 UNIPHIER_CLK_CPUGEAR("cpu-ca53", 33, 0x8080, 0xf, 8,
249 "cpll/2", "spll/2", "cpll/3", "spll/3",
250 "spll/4", "spll/8", "cpll/4", "cpll/8"),
251 UNIPHIER_CLK_CPUGEAR("cpu-ipp", 34, 0x8100, 0xf, 8,
252 "s2pll/2", "spll/2", "s2pll/3", "spll/3",
253 "spll/4", "spll/8", "s2pll/4", "s2pll/8"),
254 { /* sentinel */ }
255};
diff --git a/drivers/clk/uniphier/clk-uniphier.h b/drivers/clk/uniphier/clk-uniphier.h
index 01c16ecec48f..d10a009ada96 100644
--- a/drivers/clk/uniphier/clk-uniphier.h
+++ b/drivers/clk/uniphier/clk-uniphier.h
@@ -147,7 +147,6 @@ struct clk_hw *uniphier_clk_register_mux(struct device *dev,
147 const char *name, 147 const char *name,
148 const struct uniphier_clk_mux_data *data); 148 const struct uniphier_clk_mux_data *data);
149 149
150extern const struct uniphier_clk_data uniphier_sld3_sys_clk_data[];
151extern const struct uniphier_clk_data uniphier_ld4_sys_clk_data[]; 150extern const struct uniphier_clk_data uniphier_ld4_sys_clk_data[];
152extern const struct uniphier_clk_data uniphier_pro4_sys_clk_data[]; 151extern const struct uniphier_clk_data uniphier_pro4_sys_clk_data[];
153extern const struct uniphier_clk_data uniphier_sld8_sys_clk_data[]; 152extern const struct uniphier_clk_data uniphier_sld8_sys_clk_data[];
@@ -155,7 +154,8 @@ extern const struct uniphier_clk_data uniphier_pro5_sys_clk_data[];
155extern const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[]; 154extern const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[];
156extern const struct uniphier_clk_data uniphier_ld11_sys_clk_data[]; 155extern const struct uniphier_clk_data uniphier_ld11_sys_clk_data[];
157extern const struct uniphier_clk_data uniphier_ld20_sys_clk_data[]; 156extern const struct uniphier_clk_data uniphier_ld20_sys_clk_data[];
158extern const struct uniphier_clk_data uniphier_sld3_mio_clk_data[]; 157extern const struct uniphier_clk_data uniphier_pxs3_sys_clk_data[];
158extern const struct uniphier_clk_data uniphier_ld4_mio_clk_data[];
159extern const struct uniphier_clk_data uniphier_pro5_sd_clk_data[]; 159extern const struct uniphier_clk_data uniphier_pro5_sd_clk_data[];
160extern const struct uniphier_clk_data uniphier_ld4_peri_clk_data[]; 160extern const struct uniphier_clk_data uniphier_ld4_peri_clk_data[];
161extern const struct uniphier_clk_data uniphier_pro4_peri_clk_data[]; 161extern const struct uniphier_clk_data uniphier_pro4_peri_clk_data[];
diff --git a/drivers/clk/ux500/clk-prcc.c b/drivers/clk/ux500/clk-prcc.c
index 0e950769ed03..f50592775c9d 100644
--- a/drivers/clk/ux500/clk-prcc.c
+++ b/drivers/clk/ux500/clk-prcc.c
@@ -79,13 +79,13 @@ static int clk_prcc_is_enabled(struct clk_hw *hw)
79 return clk->is_enabled; 79 return clk->is_enabled;
80} 80}
81 81
82static struct clk_ops clk_prcc_pclk_ops = { 82static const struct clk_ops clk_prcc_pclk_ops = {
83 .enable = clk_prcc_pclk_enable, 83 .enable = clk_prcc_pclk_enable,
84 .disable = clk_prcc_pclk_disable, 84 .disable = clk_prcc_pclk_disable,
85 .is_enabled = clk_prcc_is_enabled, 85 .is_enabled = clk_prcc_is_enabled,
86}; 86};
87 87
88static struct clk_ops clk_prcc_kclk_ops = { 88static const struct clk_ops clk_prcc_kclk_ops = {
89 .enable = clk_prcc_kclk_enable, 89 .enable = clk_prcc_kclk_enable,
90 .disable = clk_prcc_kclk_disable, 90 .disable = clk_prcc_kclk_disable,
91 .is_enabled = clk_prcc_is_enabled, 91 .is_enabled = clk_prcc_is_enabled,
@@ -96,7 +96,7 @@ static struct clk *clk_reg_prcc(const char *name,
96 resource_size_t phy_base, 96 resource_size_t phy_base,
97 u32 cg_sel, 97 u32 cg_sel,
98 unsigned long flags, 98 unsigned long flags,
99 struct clk_ops *clk_prcc_ops) 99 const struct clk_ops *clk_prcc_ops)
100{ 100{
101 struct clk_prcc *clk; 101 struct clk_prcc *clk;
102 struct clk_init_data clk_prcc_init; 102 struct clk_init_data clk_prcc_init;
diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c
index 7f343821f4e4..6e3e16b2e5ca 100644
--- a/drivers/clk/ux500/clk-prcmu.c
+++ b/drivers/clk/ux500/clk-prcmu.c
@@ -186,7 +186,7 @@ static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw)
186 clk->is_prepared = 0; 186 clk->is_prepared = 0;
187} 187}
188 188
189static struct clk_ops clk_prcmu_scalable_ops = { 189static const struct clk_ops clk_prcmu_scalable_ops = {
190 .prepare = clk_prcmu_prepare, 190 .prepare = clk_prcmu_prepare,
191 .unprepare = clk_prcmu_unprepare, 191 .unprepare = clk_prcmu_unprepare,
192 .is_prepared = clk_prcmu_is_prepared, 192 .is_prepared = clk_prcmu_is_prepared,
@@ -198,7 +198,7 @@ static struct clk_ops clk_prcmu_scalable_ops = {
198 .set_rate = clk_prcmu_set_rate, 198 .set_rate = clk_prcmu_set_rate,
199}; 199};
200 200
201static struct clk_ops clk_prcmu_gate_ops = { 201static const struct clk_ops clk_prcmu_gate_ops = {
202 .prepare = clk_prcmu_prepare, 202 .prepare = clk_prcmu_prepare,
203 .unprepare = clk_prcmu_unprepare, 203 .unprepare = clk_prcmu_unprepare,
204 .is_prepared = clk_prcmu_is_prepared, 204 .is_prepared = clk_prcmu_is_prepared,
@@ -208,19 +208,19 @@ static struct clk_ops clk_prcmu_gate_ops = {
208 .recalc_rate = clk_prcmu_recalc_rate, 208 .recalc_rate = clk_prcmu_recalc_rate,
209}; 209};
210 210
211static struct clk_ops clk_prcmu_scalable_rate_ops = { 211static const struct clk_ops clk_prcmu_scalable_rate_ops = {
212 .is_enabled = clk_prcmu_is_enabled, 212 .is_enabled = clk_prcmu_is_enabled,
213 .recalc_rate = clk_prcmu_recalc_rate, 213 .recalc_rate = clk_prcmu_recalc_rate,
214 .round_rate = clk_prcmu_round_rate, 214 .round_rate = clk_prcmu_round_rate,
215 .set_rate = clk_prcmu_set_rate, 215 .set_rate = clk_prcmu_set_rate,
216}; 216};
217 217
218static struct clk_ops clk_prcmu_rate_ops = { 218static const struct clk_ops clk_prcmu_rate_ops = {
219 .is_enabled = clk_prcmu_is_enabled, 219 .is_enabled = clk_prcmu_is_enabled,
220 .recalc_rate = clk_prcmu_recalc_rate, 220 .recalc_rate = clk_prcmu_recalc_rate,
221}; 221};
222 222
223static struct clk_ops clk_prcmu_opp_gate_ops = { 223static const struct clk_ops clk_prcmu_opp_gate_ops = {
224 .prepare = clk_prcmu_opp_prepare, 224 .prepare = clk_prcmu_opp_prepare,
225 .unprepare = clk_prcmu_opp_unprepare, 225 .unprepare = clk_prcmu_opp_unprepare,
226 .is_prepared = clk_prcmu_is_prepared, 226 .is_prepared = clk_prcmu_is_prepared,
@@ -230,7 +230,7 @@ static struct clk_ops clk_prcmu_opp_gate_ops = {
230 .recalc_rate = clk_prcmu_recalc_rate, 230 .recalc_rate = clk_prcmu_recalc_rate,
231}; 231};
232 232
233static struct clk_ops clk_prcmu_opp_volt_scalable_ops = { 233static const struct clk_ops clk_prcmu_opp_volt_scalable_ops = {
234 .prepare = clk_prcmu_opp_volt_prepare, 234 .prepare = clk_prcmu_opp_volt_prepare,
235 .unprepare = clk_prcmu_opp_volt_unprepare, 235 .unprepare = clk_prcmu_opp_volt_unprepare,
236 .is_prepared = clk_prcmu_is_prepared, 236 .is_prepared = clk_prcmu_is_prepared,
@@ -247,7 +247,7 @@ static struct clk *clk_reg_prcmu(const char *name,
247 u8 cg_sel, 247 u8 cg_sel,
248 unsigned long rate, 248 unsigned long rate,
249 unsigned long flags, 249 unsigned long flags,
250 struct clk_ops *clk_prcmu_ops) 250 const struct clk_ops *clk_prcmu_ops)
251{ 251{
252 struct clk_prcmu *clk; 252 struct clk_prcmu *clk;
253 struct clk_init_data clk_prcmu_init; 253 struct clk_init_data clk_prcmu_init;
diff --git a/drivers/clk/ux500/clk-sysctrl.c b/drivers/clk/ux500/clk-sysctrl.c
index 266ddea630d2..8a4e93ce1e42 100644
--- a/drivers/clk/ux500/clk-sysctrl.c
+++ b/drivers/clk/ux500/clk-sysctrl.c
@@ -98,18 +98,18 @@ static u8 clk_sysctrl_get_parent(struct clk_hw *hw)
98 return clk->parent_index; 98 return clk->parent_index;
99} 99}
100 100
101static struct clk_ops clk_sysctrl_gate_ops = { 101static const struct clk_ops clk_sysctrl_gate_ops = {
102 .prepare = clk_sysctrl_prepare, 102 .prepare = clk_sysctrl_prepare,
103 .unprepare = clk_sysctrl_unprepare, 103 .unprepare = clk_sysctrl_unprepare,
104}; 104};
105 105
106static struct clk_ops clk_sysctrl_gate_fixed_rate_ops = { 106static const struct clk_ops clk_sysctrl_gate_fixed_rate_ops = {
107 .prepare = clk_sysctrl_prepare, 107 .prepare = clk_sysctrl_prepare,
108 .unprepare = clk_sysctrl_unprepare, 108 .unprepare = clk_sysctrl_unprepare,
109 .recalc_rate = clk_sysctrl_recalc_rate, 109 .recalc_rate = clk_sysctrl_recalc_rate,
110}; 110};
111 111
112static struct clk_ops clk_sysctrl_set_parent_ops = { 112static const struct clk_ops clk_sysctrl_set_parent_ops = {
113 .set_parent = clk_sysctrl_set_parent, 113 .set_parent = clk_sysctrl_set_parent,
114 .get_parent = clk_sysctrl_get_parent, 114 .get_parent = clk_sysctrl_get_parent,
115}; 115};
@@ -124,7 +124,7 @@ static struct clk *clk_reg_sysctrl(struct device *dev,
124 unsigned long rate, 124 unsigned long rate,
125 unsigned long enable_delay_us, 125 unsigned long enable_delay_us,
126 unsigned long flags, 126 unsigned long flags,
127 struct clk_ops *clk_sysctrl_ops) 127 const struct clk_ops *clk_sysctrl_ops)
128{ 128{
129 struct clk_sysctrl *clk; 129 struct clk_sysctrl *clk;
130 struct clk_init_data clk_sysctrl_init; 130 struct clk_init_data clk_sysctrl_init;
diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c
index 7e5add7d7752..e7a868b83fe5 100644
--- a/drivers/clk/versatile/clk-vexpress-osc.c
+++ b/drivers/clk/versatile/clk-vexpress-osc.c
@@ -61,7 +61,7 @@ static int vexpress_osc_set_rate(struct clk_hw *hw, unsigned long rate,
61 return regmap_write(osc->reg, 0, rate); 61 return regmap_write(osc->reg, 0, rate);
62} 62}
63 63
64static struct clk_ops vexpress_osc_ops = { 64static const struct clk_ops vexpress_osc_ops = {
65 .recalc_rate = vexpress_osc_recalc_rate, 65 .recalc_rate = vexpress_osc_recalc_rate,
66 .round_rate = vexpress_osc_round_rate, 66 .round_rate = vexpress_osc_round_rate,
67 .set_rate = vexpress_osc_set_rate, 67 .set_rate = vexpress_osc_set_rate,
diff --git a/drivers/clk/zte/clk-zx296718.c b/drivers/clk/zte/clk-zx296718.c
index 27f853d4c76b..354dd508c516 100644
--- a/drivers/clk/zte/clk-zx296718.c
+++ b/drivers/clk/zte/clk-zx296718.c
@@ -451,7 +451,7 @@ static struct zx_clk_fixed_factor top_ffactor_clk[] = {
451 FFACTOR(0, "emmc_mux_div2", "emmc_mux", 1, 2, CLK_SET_RATE_PARENT), 451 FFACTOR(0, "emmc_mux_div2", "emmc_mux", 1, 2, CLK_SET_RATE_PARENT),
452}; 452};
453 453
454static struct clk_div_table noc_div_table[] = { 454static const struct clk_div_table noc_div_table[] = {
455 { .val = 1, .div = 2, }, 455 { .val = 1, .div = 2, },
456 { .val = 3, .div = 4, }, 456 { .val = 3, .div = 4, },
457}; 457};
@@ -644,7 +644,7 @@ static int __init top_clocks_init(struct device_node *np)
644 return 0; 644 return 0;
645} 645}
646 646
647static struct clk_div_table common_even_div_table[] = { 647static const struct clk_div_table common_even_div_table[] = {
648 { .val = 0, .div = 1, }, 648 { .val = 0, .div = 1, },
649 { .val = 1, .div = 2, }, 649 { .val = 1, .div = 2, },
650 { .val = 3, .div = 4, }, 650 { .val = 3, .div = 4, },
@@ -656,7 +656,7 @@ static struct clk_div_table common_even_div_table[] = {
656 { .val = 15, .div = 16, }, 656 { .val = 15, .div = 16, },
657}; 657};
658 658
659static struct clk_div_table common_div_table[] = { 659static const struct clk_div_table common_div_table[] = {
660 { .val = 0, .div = 1, }, 660 { .val = 0, .div = 1, },
661 { .val = 1, .div = 2, }, 661 { .val = 1, .div = 2, },
662 { .val = 2, .div = 3, }, 662 { .val = 2, .div = 3, },
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8996.h b/include/dt-bindings/clock/qcom,gcc-msm8996.h
index 1f5c42254798..75b07cf5eed0 100644
--- a/include/dt-bindings/clock/qcom,gcc-msm8996.h
+++ b/include/dt-bindings/clock/qcom,gcc-msm8996.h
@@ -233,6 +233,8 @@
233#define GCC_PCIE_CLKREF_CLK 216 233#define GCC_PCIE_CLKREF_CLK 216
234#define GCC_RX2_USB2_CLKREF_CLK 217 234#define GCC_RX2_USB2_CLKREF_CLK 217
235#define GCC_RX1_USB2_CLKREF_CLK 218 235#define GCC_RX1_USB2_CLKREF_CLK 218
236#define GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK 219
237#define GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK 220
236 238
237#define GCC_SYSTEM_NOC_BCR 0 239#define GCC_SYSTEM_NOC_BCR 0
238#define GCC_CONFIG_NOC_BCR 1 240#define GCC_CONFIG_NOC_BCR 1
diff --git a/include/dt-bindings/clock/r8a77995-cpg-mssr.h b/include/dt-bindings/clock/r8a77995-cpg-mssr.h
new file mode 100644
index 000000000000..4e8ae3dee590
--- /dev/null
+++ b/include/dt-bindings/clock/r8a77995-cpg-mssr.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright (C) 2017 Glider bvba
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 as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9#ifndef __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__
10#define __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__
11
12#include <dt-bindings/clock/renesas-cpg-mssr.h>
13
14/* r8a77995 CPG Core Clocks */
15#define R8A77995_CLK_Z2 0
16#define R8A77995_CLK_ZG 1
17#define R8A77995_CLK_ZTR 2
18#define R8A77995_CLK_ZT 3
19#define R8A77995_CLK_ZX 4
20#define R8A77995_CLK_S0D1 5
21#define R8A77995_CLK_S1D1 6
22#define R8A77995_CLK_S1D2 7
23#define R8A77995_CLK_S1D4 8
24#define R8A77995_CLK_S2D1 9
25#define R8A77995_CLK_S2D2 10
26#define R8A77995_CLK_S2D4 11
27#define R8A77995_CLK_S3D1 12
28#define R8A77995_CLK_S3D2 13
29#define R8A77995_CLK_S3D4 14
30#define R8A77995_CLK_S1D4C 15
31#define R8A77995_CLK_S3D1C 16
32#define R8A77995_CLK_S3D2C 17
33#define R8A77995_CLK_S3D4C 18
34#define R8A77995_CLK_LB 19
35#define R8A77995_CLK_CL 20
36#define R8A77995_CLK_ZB3 21
37#define R8A77995_CLK_ZB3D2 22
38#define R8A77995_CLK_CR 23
39#define R8A77995_CLK_CRD2 24
40#define R8A77995_CLK_SD0H 25
41#define R8A77995_CLK_SD0 26
42#define R8A77995_CLK_SSP2 27
43#define R8A77995_CLK_SSP1 28
44#define R8A77995_CLK_RPC 29
45#define R8A77995_CLK_RPCD2 30
46#define R8A77995_CLK_ZA2 31
47#define R8A77995_CLK_ZA8 32
48#define R8A77995_CLK_Z2D 33
49#define R8A77995_CLK_CANFD 34
50#define R8A77995_CLK_MSO 35
51#define R8A77995_CLK_R 36
52#define R8A77995_CLK_OSC 37
53#define R8A77995_CLK_LV0 38
54#define R8A77995_CLK_LV1 39
55#define R8A77995_CLK_CP 40
56
57#endif /* __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h
index 56f841c22801..55655ab0a4c4 100644
--- a/include/dt-bindings/clock/rk3228-cru.h
+++ b/include/dt-bindings/clock/rk3228-cru.h
@@ -49,6 +49,7 @@
49#define SCLK_EMMC_DRV 117 49#define SCLK_EMMC_DRV 117
50#define SCLK_SDMMC_SAMPLE 118 50#define SCLK_SDMMC_SAMPLE 118
51#define SCLK_SDIO_SAMPLE 119 51#define SCLK_SDIO_SAMPLE 119
52#define SCLK_SDIO_SRC 120
52#define SCLK_EMMC_SAMPLE 121 53#define SCLK_EMMC_SAMPLE 121
53#define SCLK_VOP 122 54#define SCLK_VOP 122
54#define SCLK_HDMI_HDCP 123 55#define SCLK_HDMI_HDCP 123
diff --git a/include/dt-bindings/clock/rv1108-cru.h b/include/dt-bindings/clock/rv1108-cru.h
index f269d833e41a..d8d0e0456dc2 100644
--- a/include/dt-bindings/clock/rv1108-cru.h
+++ b/include/dt-bindings/clock/rv1108-cru.h
@@ -67,9 +67,9 @@
67#define SCLK_SPI 108 67#define SCLK_SPI 108
68#define SCLK_SARADC 109 68#define SCLK_SARADC 109
69#define SCLK_TSADC 110 69#define SCLK_TSADC 110
70#define SCLK_MACPHY_PRE 111 70#define SCLK_MAC_PRE 111
71#define SCLK_MACPHY 112 71#define SCLK_MAC 112
72#define SCLK_MACPHY_RX 113 72#define SCLK_MAC_RX 113
73#define SCLK_MAC_REF 114 73#define SCLK_MAC_REF 114
74#define SCLK_MAC_REFOUT 115 74#define SCLK_MAC_REFOUT 115
75#define SCLK_DSP_PFM 116 75#define SCLK_DSP_PFM 116
@@ -110,6 +110,7 @@
110#define ACLK_CIF2 207 110#define ACLK_CIF2 207
111#define ACLK_CIF3 208 111#define ACLK_CIF3 208
112#define ACLK_PERI 209 112#define ACLK_PERI 209
113#define ACLK_GMAC 210
113 114
114/* pclk gates */ 115/* pclk gates */
115#define PCLK_GPIO1 256 116#define PCLK_GPIO1 256
@@ -141,6 +142,7 @@
141#define PCLK_EFUSE0 282 142#define PCLK_EFUSE0 282
142#define PCLK_EFUSE1 283 143#define PCLK_EFUSE1 283
143#define PCLK_WDT 284 144#define PCLK_WDT 284
145#define PCLK_GMAC 285
144 146
145/* hclk gates */ 147/* hclk gates */
146#define HCLK_I2S0_8CH 320 148#define HCLK_I2S0_8CH 320
diff --git a/include/dt-bindings/clock/stm32h7-clks.h b/include/dt-bindings/clock/stm32h7-clks.h
new file mode 100644
index 000000000000..6637272b3242
--- /dev/null
+++ b/include/dt-bindings/clock/stm32h7-clks.h
@@ -0,0 +1,165 @@
1/* SYS, CORE AND BUS CLOCKS */
2#define SYS_D1CPRE 0
3#define HCLK 1
4#define PCLK1 2
5#define PCLK2 3
6#define PCLK3 4
7#define PCLK4 5
8#define HSI_DIV 6
9#define HSE_1M 7
10#define I2S_CKIN 8
11#define CK_DSI_PHY 9
12#define HSE_CK 10
13#define LSE_CK 11
14#define CSI_KER_DIV122 12
15#define RTC_CK 13
16#define CPU_SYSTICK 14
17
18/* OSCILLATOR BANK */
19#define OSC_BANK 18
20#define HSI_CK 18
21#define HSI_KER_CK 19
22#define CSI_CK 20
23#define CSI_KER_CK 21
24#define RC48_CK 22
25#define LSI_CK 23
26
27/* MCLOCK BANK */
28#define MCLK_BANK 28
29#define PER_CK 28
30#define PLLSRC 29
31#define SYS_CK 30
32#define TRACEIN_CK 31
33
34/* ODF BANK */
35#define ODF_BANK 32
36#define PLL1_P 32
37#define PLL1_Q 33
38#define PLL1_R 34
39#define PLL2_P 35
40#define PLL2_Q 36
41#define PLL2_R 37
42#define PLL3_P 38
43#define PLL3_Q 39
44#define PLL3_R 40
45
46/* MCO BANK */
47#define MCO_BANK 41
48#define MCO1 41
49#define MCO2 42
50
51/* PERIF BANK */
52#define PERIF_BANK 50
53#define D1SRAM1_CK 50
54#define ITCM_CK 51
55#define DTCM2_CK 52
56#define DTCM1_CK 53
57#define FLITF_CK 54
58#define JPGDEC_CK 55
59#define DMA2D_CK 56
60#define MDMA_CK 57
61#define USB2ULPI_CK 58
62#define USB1ULPI_CK 59
63#define ETH1RX_CK 60
64#define ETH1TX_CK 61
65#define ETH1MAC_CK 62
66#define ART_CK 63
67#define DMA2_CK 64
68#define DMA1_CK 65
69#define D2SRAM3_CK 66
70#define D2SRAM2_CK 67
71#define D2SRAM1_CK 68
72#define HASH_CK 69
73#define CRYPT_CK 70
74#define CAMITF_CK 71
75#define BKPRAM_CK 72
76#define HSEM_CK 73
77#define BDMA_CK 74
78#define CRC_CK 75
79#define GPIOK_CK 76
80#define GPIOJ_CK 77
81#define GPIOI_CK 78
82#define GPIOH_CK 79
83#define GPIOG_CK 80
84#define GPIOF_CK 81
85#define GPIOE_CK 82
86#define GPIOD_CK 83
87#define GPIOC_CK 84
88#define GPIOB_CK 85
89#define GPIOA_CK 86
90#define WWDG1_CK 87
91#define DAC12_CK 88
92#define WWDG2_CK 89
93#define TIM14_CK 90
94#define TIM13_CK 91
95#define TIM12_CK 92
96#define TIM7_CK 93
97#define TIM6_CK 94
98#define TIM5_CK 95
99#define TIM4_CK 96
100#define TIM3_CK 97
101#define TIM2_CK 98
102#define MDIOS_CK 99
103#define OPAMP_CK 100
104#define CRS_CK 101
105#define TIM17_CK 102
106#define TIM16_CK 103
107#define TIM15_CK 104
108#define TIM8_CK 105
109#define TIM1_CK 106
110#define TMPSENS_CK 107
111#define RTCAPB_CK 108
112#define VREF_CK 109
113#define COMP12_CK 110
114#define SYSCFG_CK 111
115
116/* KERNEL BANK */
117#define KERN_BANK 120
118#define SDMMC1_CK 120
119#define QUADSPI_CK 121
120#define FMC_CK 122
121#define USB2OTG_CK 123
122#define USB1OTG_CK 124
123#define ADC12_CK 125
124#define SDMMC2_CK 126
125#define RNG_CK 127
126#define ADC3_CK 128
127#define DSI_CK 129
128#define LTDC_CK 130
129#define USART8_CK 131
130#define USART7_CK 132
131#define HDMICEC_CK 133
132#define I2C3_CK 134
133#define I2C2_CK 135
134#define I2C1_CK 136
135#define UART5_CK 137
136#define UART4_CK 138
137#define USART3_CK 139
138#define USART2_CK 140
139#define SPDIFRX_CK 141
140#define SPI3_CK 142
141#define SPI2_CK 143
142#define LPTIM1_CK 144
143#define FDCAN_CK 145
144#define SWP_CK 146
145#define HRTIM_CK 147
146#define DFSDM1_CK 148
147#define SAI3_CK 149
148#define SAI2_CK 150
149#define SAI1_CK 151
150#define SPI5_CK 152
151#define SPI4_CK 153
152#define SPI1_CK 154
153#define USART6_CK 155
154#define USART1_CK 156
155#define SAI4B_CK 157
156#define SAI4A_CK 158
157#define LPTIM5_CK 159
158#define LPTIM4_CK 160
159#define LPTIM3_CK 161
160#define LPTIM2_CK 162
161#define I2C4_CK 163
162#define SPI6_CK 164
163#define LPUART1_CK 165
164
165#define STM32H7_MAX_CLKS 166
diff --git a/include/dt-bindings/clock/sun4i-a10-ccu.h b/include/dt-bindings/clock/sun4i-a10-ccu.h
new file mode 100644
index 000000000000..c5a53f38d654
--- /dev/null
+++ b/include/dt-bindings/clock/sun4i-a10-ccu.h
@@ -0,0 +1,200 @@
1/*
2 * Copyright (C) 2017 Priit Laes <plaes@plaes.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 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
39 * OTHER DEALINGS IN THE SOFTWARE.
40 */
41
42#ifndef _DT_BINDINGS_CLK_SUN4I_A10_H_
43#define _DT_BINDINGS_CLK_SUN4I_A10_H_
44
45#define CLK_HOSC 1
46#define CLK_CPU 20
47
48/* AHB Gates */
49#define CLK_AHB_OTG 26
50#define CLK_AHB_EHCI0 27
51#define CLK_AHB_OHCI0 28
52#define CLK_AHB_EHCI1 29
53#define CLK_AHB_OHCI1 30
54#define CLK_AHB_SS 31
55#define CLK_AHB_DMA 32
56#define CLK_AHB_BIST 33
57#define CLK_AHB_MMC0 34
58#define CLK_AHB_MMC1 35
59#define CLK_AHB_MMC2 36
60#define CLK_AHB_MMC3 37
61#define CLK_AHB_MS 38
62#define CLK_AHB_NAND 39
63#define CLK_AHB_SDRAM 40
64#define CLK_AHB_ACE 41
65#define CLK_AHB_EMAC 42
66#define CLK_AHB_TS 43
67#define CLK_AHB_SPI0 44
68#define CLK_AHB_SPI1 45
69#define CLK_AHB_SPI2 46
70#define CLK_AHB_SPI3 47
71#define CLK_AHB_PATA 48
72#define CLK_AHB_SATA 49
73#define CLK_AHB_GPS 50
74#define CLK_AHB_HSTIMER 51
75#define CLK_AHB_VE 52
76#define CLK_AHB_TVD 53
77#define CLK_AHB_TVE0 54
78#define CLK_AHB_TVE1 55
79#define CLK_AHB_LCD0 56
80#define CLK_AHB_LCD1 57
81#define CLK_AHB_CSI0 58
82#define CLK_AHB_CSI1 59
83#define CLK_AHB_HDMI0 60
84#define CLK_AHB_HDMI1 61
85#define CLK_AHB_DE_BE0 62
86#define CLK_AHB_DE_BE1 63
87#define CLK_AHB_DE_FE0 64
88#define CLK_AHB_DE_FE1 65
89#define CLK_AHB_GMAC 66
90#define CLK_AHB_MP 67
91#define CLK_AHB_GPU 68
92
93/* APB0 Gates */
94#define CLK_APB0_CODEC 69
95#define CLK_APB0_SPDIF 70
96#define CLK_APB0_I2S0 71
97#define CLK_APB0_AC97 72
98#define CLK_APB0_I2S1 73
99#define CLK_APB0_PIO 74
100#define CLK_APB0_IR0 75
101#define CLK_APB0_IR1 76
102#define CLK_APB0_I2S2 77
103#define CLK_APB0_KEYPAD 78
104
105/* APB1 Gates */
106#define CLK_APB1_I2C0 79
107#define CLK_APB1_I2C1 80
108#define CLK_APB1_I2C2 81
109#define CLK_APB1_I2C3 82
110#define CLK_APB1_CAN 83
111#define CLK_APB1_SCR 84
112#define CLK_APB1_PS20 85
113#define CLK_APB1_PS21 86
114#define CLK_APB1_I2C4 87
115#define CLK_APB1_UART0 88
116#define CLK_APB1_UART1 89
117#define CLK_APB1_UART2 90
118#define CLK_APB1_UART3 91
119#define CLK_APB1_UART4 92
120#define CLK_APB1_UART5 93
121#define CLK_APB1_UART6 94
122#define CLK_APB1_UART7 95
123
124/* IP clocks */
125#define CLK_NAND 96
126#define CLK_MS 97
127#define CLK_MMC0 98
128#define CLK_MMC0_OUTPUT 99
129#define CLK_MMC0_SAMPLE 100
130#define CLK_MMC1 101
131#define CLK_MMC1_OUTPUT 102
132#define CLK_MMC1_SAMPLE 103
133#define CLK_MMC2 104
134#define CLK_MMC2_OUTPUT 105
135#define CLK_MMC2_SAMPLE 106
136#define CLK_MMC3 107
137#define CLK_MMC3_OUTPUT 108
138#define CLK_MMC3_SAMPLE 109
139#define CLK_TS 110
140#define CLK_SS 111
141#define CLK_SPI0 112
142#define CLK_SPI1 113
143#define CLK_SPI2 114
144#define CLK_PATA 115
145#define CLK_IR0 116
146#define CLK_IR1 117
147#define CLK_I2S0 118
148#define CLK_AC97 119
149#define CLK_SPDIF 120
150#define CLK_KEYPAD 121
151#define CLK_SATA 122
152#define CLK_USB_OHCI0 123
153#define CLK_USB_OHCI1 124
154#define CLK_USB_PHY 125
155#define CLK_GPS 126
156#define CLK_SPI3 127
157#define CLK_I2S1 128
158#define CLK_I2S2 129
159
160/* DRAM Gates */
161#define CLK_DRAM_VE 130
162#define CLK_DRAM_CSI0 131
163#define CLK_DRAM_CSI1 132
164#define CLK_DRAM_TS 133
165#define CLK_DRAM_TVD 134
166#define CLK_DRAM_TVE0 135
167#define CLK_DRAM_TVE1 136
168#define CLK_DRAM_OUT 137
169#define CLK_DRAM_DE_FE1 138
170#define CLK_DRAM_DE_FE0 139
171#define CLK_DRAM_DE_BE0 140
172#define CLK_DRAM_DE_BE1 141
173#define CLK_DRAM_MP 142
174#define CLK_DRAM_ACE 143
175
176/* Display Engine Clocks */
177#define CLK_DE_BE0 144
178#define CLK_DE_BE1 145
179#define CLK_DE_FE0 146
180#define CLK_DE_FE1 147
181#define CLK_DE_MP 148
182#define CLK_TCON0_CH0 149
183#define CLK_TCON1_CH0 150
184#define CLK_CSI_SCLK 151
185#define CLK_TVD_SCLK2 152
186#define CLK_TVD 153
187#define CLK_TCON0_CH1_SCLK2 154
188#define CLK_TCON0_CH1 155
189#define CLK_TCON1_CH1_SCLK2 156
190#define CLK_TCON1_CH1 157
191#define CLK_CSI0 158
192#define CLK_CSI1 159
193#define CLK_CODEC 160
194#define CLK_VE 161
195#define CLK_AVS 162
196#define CLK_ACE 163
197#define CLK_HDMI 164
198#define CLK_GPU 165
199
200#endif /* _DT_BINDINGS_CLK_SUN4I_A10_H_ */
diff --git a/include/dt-bindings/clock/sun7i-a20-ccu.h b/include/dt-bindings/clock/sun7i-a20-ccu.h
new file mode 100644
index 000000000000..045a5178da0c
--- /dev/null
+++ b/include/dt-bindings/clock/sun7i-a20-ccu.h
@@ -0,0 +1,53 @@
1/*
2 * Copyright (C) 2017 Priit Laes <plaes@plaes.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 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
39 * OTHER DEALINGS IN THE SOFTWARE.
40 */
41
42#ifndef _DT_BINDINGS_CLK_SUN7I_A20_H_
43#define _DT_BINDINGS_CLK_SUN7I_A20_H_
44
45#include <dt-bindings/clock/sun4i-a10-ccu.h>
46
47#define CLK_MBUS 166
48#define CLK_HDMI1_SLOW 167
49#define CLK_HDMI1 168
50#define CLK_OUT_A 169
51#define CLK_OUT_B 170
52
53#endif /* _DT_BINDINGS_CLK_SUN7I_A20_H_ */
diff --git a/include/dt-bindings/clock/sun8i-r40-ccu.h b/include/dt-bindings/clock/sun8i-r40-ccu.h
new file mode 100644
index 000000000000..4fa5f69fc297
--- /dev/null
+++ b/include/dt-bindings/clock/sun8i-r40-ccu.h
@@ -0,0 +1,187 @@
1/*
2 * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
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_R40_H_
44#define _DT_BINDINGS_CLK_SUN8I_R40_H_
45
46#define CLK_CPU 24
47
48#define CLK_BUS_MIPI_DSI 29
49#define CLK_BUS_CE 30
50#define CLK_BUS_DMA 31
51#define CLK_BUS_MMC0 32
52#define CLK_BUS_MMC1 33
53#define CLK_BUS_MMC2 34
54#define CLK_BUS_MMC3 35
55#define CLK_BUS_NAND 36
56#define CLK_BUS_DRAM 37
57#define CLK_BUS_EMAC 38
58#define CLK_BUS_TS 39
59#define CLK_BUS_HSTIMER 40
60#define CLK_BUS_SPI0 41
61#define CLK_BUS_SPI1 42
62#define CLK_BUS_SPI2 43
63#define CLK_BUS_SPI3 44
64#define CLK_BUS_SATA 45
65#define CLK_BUS_OTG 46
66#define CLK_BUS_EHCI0 47
67#define CLK_BUS_EHCI1 48
68#define CLK_BUS_EHCI2 49
69#define CLK_BUS_OHCI0 50
70#define CLK_BUS_OHCI1 51
71#define CLK_BUS_OHCI2 52
72#define CLK_BUS_VE 53
73#define CLK_BUS_MP 54
74#define CLK_BUS_DEINTERLACE 55
75#define CLK_BUS_CSI0 56
76#define CLK_BUS_CSI1 57
77#define CLK_BUS_HDMI1 58
78#define CLK_BUS_HDMI0 59
79#define CLK_BUS_DE 60
80#define CLK_BUS_TVE0 61
81#define CLK_BUS_TVE1 62
82#define CLK_BUS_TVE_TOP 63
83#define CLK_BUS_GMAC 64
84#define CLK_BUS_GPU 65
85#define CLK_BUS_TVD0 66
86#define CLK_BUS_TVD1 67
87#define CLK_BUS_TVD2 68
88#define CLK_BUS_TVD3 69
89#define CLK_BUS_TVD_TOP 70
90#define CLK_BUS_TCON_LCD0 71
91#define CLK_BUS_TCON_LCD1 72
92#define CLK_BUS_TCON_TV0 73
93#define CLK_BUS_TCON_TV1 74
94#define CLK_BUS_TCON_TOP 75
95#define CLK_BUS_CODEC 76
96#define CLK_BUS_SPDIF 77
97#define CLK_BUS_AC97 78
98#define CLK_BUS_PIO 79
99#define CLK_BUS_IR0 80
100#define CLK_BUS_IR1 81
101#define CLK_BUS_THS 82
102#define CLK_BUS_KEYPAD 83
103#define CLK_BUS_I2S0 84
104#define CLK_BUS_I2S1 85
105#define CLK_BUS_I2S2 86
106#define CLK_BUS_I2C0 87
107#define CLK_BUS_I2C1 88
108#define CLK_BUS_I2C2 89
109#define CLK_BUS_I2C3 90
110#define CLK_BUS_CAN 91
111#define CLK_BUS_SCR 92
112#define CLK_BUS_PS20 93
113#define CLK_BUS_PS21 94
114#define CLK_BUS_I2C4 95
115#define CLK_BUS_UART0 96
116#define CLK_BUS_UART1 97
117#define CLK_BUS_UART2 98
118#define CLK_BUS_UART3 99
119#define CLK_BUS_UART4 100
120#define CLK_BUS_UART5 101
121#define CLK_BUS_UART6 102
122#define CLK_BUS_UART7 103
123#define CLK_BUS_DBG 104
124
125#define CLK_THS 105
126#define CLK_NAND 106
127#define CLK_MMC0 107
128#define CLK_MMC1 108
129#define CLK_MMC2 109
130#define CLK_MMC3 110
131#define CLK_TS 111
132#define CLK_CE 112
133#define CLK_SPI0 113
134#define CLK_SPI1 114
135#define CLK_SPI2 115
136#define CLK_SPI3 116
137#define CLK_I2S0 117
138#define CLK_I2S1 118
139#define CLK_I2S2 119
140#define CLK_AC97 120
141#define CLK_SPDIF 121
142#define CLK_KEYPAD 122
143#define CLK_SATA 123
144#define CLK_USB_PHY0 124
145#define CLK_USB_PHY1 125
146#define CLK_USB_PHY2 126
147#define CLK_USB_OHCI0 127
148#define CLK_USB_OHCI1 128
149#define CLK_USB_OHCI2 129
150#define CLK_IR0 130
151#define CLK_IR1 131
152
153#define CLK_DRAM_VE 133
154#define CLK_DRAM_CSI0 134
155#define CLK_DRAM_CSI1 135
156#define CLK_DRAM_TS 136
157#define CLK_DRAM_TVD 137
158#define CLK_DRAM_MP 138
159#define CLK_DRAM_DEINTERLACE 139
160#define CLK_DE 140
161#define CLK_MP 141
162#define CLK_TCON_LCD0 142
163#define CLK_TCON_LCD1 143
164#define CLK_TCON_TV0 144
165#define CLK_TCON_TV1 145
166#define CLK_DEINTERLACE 146
167#define CLK_CSI1_MCLK 147
168#define CLK_CSI_SCLK 148
169#define CLK_CSI0_MCLK 149
170#define CLK_VE 150
171#define CLK_CODEC 151
172#define CLK_AVS 152
173#define CLK_HDMI 153
174#define CLK_HDMI_SLOW 154
175
176#define CLK_DSI_DPHY 156
177#define CLK_TVE0 157
178#define CLK_TVE1 158
179#define CLK_TVD0 159
180#define CLK_TVD1 160
181#define CLK_TVD2 161
182#define CLK_TVD3 162
183#define CLK_GPU 163
184#define CLK_OUTA 164
185#define CLK_OUTB 165
186
187#endif /* _DT_BINDINGS_CLK_SUN8I_R40_H_ */
diff --git a/include/dt-bindings/mfd/stm32h7-rcc.h b/include/dt-bindings/mfd/stm32h7-rcc.h
new file mode 100644
index 000000000000..461a8e04453a
--- /dev/null
+++ b/include/dt-bindings/mfd/stm32h7-rcc.h
@@ -0,0 +1,136 @@
1/*
2 * This header provides constants for the STM32H7 RCC IP
3 */
4
5#ifndef _DT_BINDINGS_MFD_STM32H7_RCC_H
6#define _DT_BINDINGS_MFD_STM32H7_RCC_H
7
8/* AHB3 */
9#define STM32H7_RCC_AHB3_MDMA 0
10#define STM32H7_RCC_AHB3_DMA2D 4
11#define STM32H7_RCC_AHB3_JPGDEC 5
12#define STM32H7_RCC_AHB3_FMC 12
13#define STM32H7_RCC_AHB3_QUADSPI 14
14#define STM32H7_RCC_AHB3_SDMMC1 16
15#define STM32H7_RCC_AHB3_CPU 31
16
17#define STM32H7_AHB3_RESET(bit) (STM32H7_RCC_AHB3_##bit + (0x7C * 8))
18
19/* AHB1 */
20#define STM32H7_RCC_AHB1_DMA1 0
21#define STM32H7_RCC_AHB1_DMA2 1
22#define STM32H7_RCC_AHB1_ADC12 5
23#define STM32H7_RCC_AHB1_ART 14
24#define STM32H7_RCC_AHB1_ETH1MAC 15
25#define STM32H7_RCC_AHB1_USB1OTG 25
26#define STM32H7_RCC_AHB1_USB2OTG 27
27
28#define STM32H7_AHB1_RESET(bit) (STM32H7_RCC_AHB1_##bit + (0x80 * 8))
29
30/* AHB2 */
31#define STM32H7_RCC_AHB2_CAMITF 0
32#define STM32H7_RCC_AHB2_CRYPT 4
33#define STM32H7_RCC_AHB2_HASH 5
34#define STM32H7_RCC_AHB2_RNG 6
35#define STM32H7_RCC_AHB2_SDMMC2 9
36
37#define STM32H7_AHB2_RESET(bit) (STM32H7_RCC_AHB2_##bit + (0x84 * 8))
38
39/* AHB4 */
40#define STM32H7_RCC_AHB4_GPIOA 0
41#define STM32H7_RCC_AHB4_GPIOB 1
42#define STM32H7_RCC_AHB4_GPIOC 2
43#define STM32H7_RCC_AHB4_GPIOD 3
44#define STM32H7_RCC_AHB4_GPIOE 4
45#define STM32H7_RCC_AHB4_GPIOF 5
46#define STM32H7_RCC_AHB4_GPIOG 6
47#define STM32H7_RCC_AHB4_GPIOH 7
48#define STM32H7_RCC_AHB4_GPIOI 8
49#define STM32H7_RCC_AHB4_GPIOJ 9
50#define STM32H7_RCC_AHB4_GPIOK 10
51#define STM32H7_RCC_AHB4_CRC 19
52#define STM32H7_RCC_AHB4_BDMA 21
53#define STM32H7_RCC_AHB4_ADC3 24
54#define STM32H7_RCC_AHB4_HSEM 25
55
56#define STM32H7_AHB4_RESET(bit) (STM32H7_RCC_AHB4_##bit + (0x88 * 8))
57
58/* APB3 */
59#define STM32H7_RCC_APB3_LTDC 3
60#define STM32H7_RCC_APB3_DSI 4
61
62#define STM32H7_APB3_RESET(bit) (STM32H7_RCC_APB3_##bit + (0x8C * 8))
63
64/* APB1L */
65#define STM32H7_RCC_APB1L_TIM2 0
66#define STM32H7_RCC_APB1L_TIM3 1
67#define STM32H7_RCC_APB1L_TIM4 2
68#define STM32H7_RCC_APB1L_TIM5 3
69#define STM32H7_RCC_APB1L_TIM6 4
70#define STM32H7_RCC_APB1L_TIM7 5
71#define STM32H7_RCC_APB1L_TIM12 6
72#define STM32H7_RCC_APB1L_TIM13 7
73#define STM32H7_RCC_APB1L_TIM14 8
74#define STM32H7_RCC_APB1L_LPTIM1 9
75#define STM32H7_RCC_APB1L_SPI2 14
76#define STM32H7_RCC_APB1L_SPI3 15
77#define STM32H7_RCC_APB1L_SPDIF_RX 16
78#define STM32H7_RCC_APB1L_USART2 17
79#define STM32H7_RCC_APB1L_USART3 18
80#define STM32H7_RCC_APB1L_UART4 19
81#define STM32H7_RCC_APB1L_UART5 20
82#define STM32H7_RCC_APB1L_I2C1 21
83#define STM32H7_RCC_APB1L_I2C2 22
84#define STM32H7_RCC_APB1L_I2C3 23
85#define STM32H7_RCC_APB1L_HDMICEC 27
86#define STM32H7_RCC_APB1L_DAC12 29
87#define STM32H7_RCC_APB1L_USART7 30
88#define STM32H7_RCC_APB1L_USART8 31
89
90#define STM32H7_APB1L_RESET(bit) (STM32H7_RCC_APB1L_##bit + (0x90 * 8))
91
92/* APB1H */
93#define STM32H7_RCC_APB1H_CRS 1
94#define STM32H7_RCC_APB1H_SWP 2
95#define STM32H7_RCC_APB1H_OPAMP 4
96#define STM32H7_RCC_APB1H_MDIOS 5
97#define STM32H7_RCC_APB1H_FDCAN 8
98
99#define STM32H7_APB1H_RESET(bit) (STM32H7_RCC_APB1H_##bit + (0x94 * 8))
100
101/* APB2 */
102#define STM32H7_RCC_APB2_TIM1 0
103#define STM32H7_RCC_APB2_TIM8 1
104#define STM32H7_RCC_APB2_USART1 4
105#define STM32H7_RCC_APB2_USART6 5
106#define STM32H7_RCC_APB2_SPI1 12
107#define STM32H7_RCC_APB2_SPI4 13
108#define STM32H7_RCC_APB2_TIM15 16
109#define STM32H7_RCC_APB2_TIM16 17
110#define STM32H7_RCC_APB2_TIM17 18
111#define STM32H7_RCC_APB2_SPI5 20
112#define STM32H7_RCC_APB2_SAI1 22
113#define STM32H7_RCC_APB2_SAI2 23
114#define STM32H7_RCC_APB2_SAI3 24
115#define STM32H7_RCC_APB2_DFSDM1 28
116#define STM32H7_RCC_APB2_HRTIM 29
117
118#define STM32H7_APB2_RESET(bit) (STM32H7_RCC_APB2_##bit + (0x98 * 8))
119
120/* APB4 */
121#define STM32H7_RCC_APB4_SYSCFG 1
122#define STM32H7_RCC_APB4_LPUART1 3
123#define STM32H7_RCC_APB4_SPI6 5
124#define STM32H7_RCC_APB4_I2C4 7
125#define STM32H7_RCC_APB4_LPTIM2 9
126#define STM32H7_RCC_APB4_LPTIM3 10
127#define STM32H7_RCC_APB4_LPTIM4 11
128#define STM32H7_RCC_APB4_LPTIM5 12
129#define STM32H7_RCC_APB4_COMP12 14
130#define STM32H7_RCC_APB4_VREF 15
131#define STM32H7_RCC_APB4_SAI4 21
132#define STM32H7_RCC_APB4_TMPSENS 26
133
134#define STM32H7_APB4_RESET(bit) (STM32H7_RCC_APB4_##bit + (0x9C * 8))
135
136#endif /* _DT_BINDINGS_MFD_STM32H7_RCC_H */
diff --git a/include/dt-bindings/reset/sun4i-a10-ccu.h b/include/dt-bindings/reset/sun4i-a10-ccu.h
new file mode 100644
index 000000000000..5f4480bedc8a
--- /dev/null
+++ b/include/dt-bindings/reset/sun4i-a10-ccu.h
@@ -0,0 +1,69 @@
1/*
2 * Copyright (C) 2017 Priit Laes <plaes@plaes.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_SUN4I_A10_H
44#define _DT_BINDINGS_RST_SUN4I_A10_H
45
46#define RST_USB_PHY0 1
47#define RST_USB_PHY1 2
48#define RST_USB_PHY2 3
49#define RST_GPS 4
50#define RST_DE_BE0 5
51#define RST_DE_BE1 6
52#define RST_DE_FE0 7
53#define RST_DE_FE1 8
54#define RST_DE_MP 9
55#define RST_TVE0 10
56#define RST_TCON0 11
57#define RST_TVE1 12
58#define RST_TCON1 13
59#define RST_CSI0 14
60#define RST_CSI1 15
61#define RST_VE 16
62#define RST_ACE 17
63#define RST_LVDS 18
64#define RST_GPU 19
65#define RST_HDMI_H 20
66#define RST_HDMI_SYS 21
67#define RST_HDMI_AUDIO_DMA 22
68
69#endif /* DT_BINDINGS_RST_SUN4I_A10_H */
diff --git a/include/dt-bindings/reset/sun8i-r40-ccu.h b/include/dt-bindings/reset/sun8i-r40-ccu.h
new file mode 100644
index 000000000000..c5ebcf6672e4
--- /dev/null
+++ b/include/dt-bindings/reset/sun8i-r40-ccu.h
@@ -0,0 +1,130 @@
1/*
2 * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
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_R40_H_
44#define _DT_BINDINGS_RST_SUN8I_R40_H_
45
46#define RST_USB_PHY0 0
47#define RST_USB_PHY1 1
48#define RST_USB_PHY2 2
49
50#define RST_DRAM 3
51#define RST_MBUS 4
52
53#define RST_BUS_MIPI_DSI 5
54#define RST_BUS_CE 6
55#define RST_BUS_DMA 7
56#define RST_BUS_MMC0 8
57#define RST_BUS_MMC1 9
58#define RST_BUS_MMC2 10
59#define RST_BUS_MMC3 11
60#define RST_BUS_NAND 12
61#define RST_BUS_DRAM 13
62#define RST_BUS_EMAC 14
63#define RST_BUS_TS 15
64#define RST_BUS_HSTIMER 16
65#define RST_BUS_SPI0 17
66#define RST_BUS_SPI1 18
67#define RST_BUS_SPI2 19
68#define RST_BUS_SPI3 20
69#define RST_BUS_SATA 21
70#define RST_BUS_OTG 22
71#define RST_BUS_EHCI0 23
72#define RST_BUS_EHCI1 24
73#define RST_BUS_EHCI2 25
74#define RST_BUS_OHCI0 26
75#define RST_BUS_OHCI1 27
76#define RST_BUS_OHCI2 28
77#define RST_BUS_VE 29
78#define RST_BUS_MP 30
79#define RST_BUS_DEINTERLACE 31
80#define RST_BUS_CSI0 32
81#define RST_BUS_CSI1 33
82#define RST_BUS_HDMI0 34
83#define RST_BUS_HDMI1 35
84#define RST_BUS_DE 36
85#define RST_BUS_TVE0 37
86#define RST_BUS_TVE1 38
87#define RST_BUS_TVE_TOP 39
88#define RST_BUS_GMAC 40
89#define RST_BUS_GPU 41
90#define RST_BUS_TVD0 42
91#define RST_BUS_TVD1 43
92#define RST_BUS_TVD2 44
93#define RST_BUS_TVD3 45
94#define RST_BUS_TVD_TOP 46
95#define RST_BUS_TCON_LCD0 47
96#define RST_BUS_TCON_LCD1 48
97#define RST_BUS_TCON_TV0 49
98#define RST_BUS_TCON_TV1 50
99#define RST_BUS_TCON_TOP 51
100#define RST_BUS_DBG 52
101#define RST_BUS_LVDS 53
102#define RST_BUS_CODEC 54
103#define RST_BUS_SPDIF 55
104#define RST_BUS_AC97 56
105#define RST_BUS_IR0 57
106#define RST_BUS_IR1 58
107#define RST_BUS_THS 59
108#define RST_BUS_KEYPAD 60
109#define RST_BUS_I2S0 61
110#define RST_BUS_I2S1 62
111#define RST_BUS_I2S2 63
112#define RST_BUS_I2C0 64
113#define RST_BUS_I2C1 65
114#define RST_BUS_I2C2 66
115#define RST_BUS_I2C3 67
116#define RST_BUS_CAN 68
117#define RST_BUS_SCR 69
118#define RST_BUS_PS20 70
119#define RST_BUS_PS21 71
120#define RST_BUS_I2C4 72
121#define RST_BUS_UART0 73
122#define RST_BUS_UART1 74
123#define RST_BUS_UART2 75
124#define RST_BUS_UART3 76
125#define RST_BUS_UART4 77
126#define RST_BUS_UART5 78
127#define RST_BUS_UART6 79
128#define RST_BUS_UART7 80
129
130#endif /* _DT_BINDINGS_RST_SUN8I_R40_H_ */
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index c59c62571e4f..5100ec1b5d55 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -343,6 +343,7 @@ struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
343 u8 clk_gate_flags, spinlock_t *lock); 343 u8 clk_gate_flags, spinlock_t *lock);
344void clk_unregister_gate(struct clk *clk); 344void clk_unregister_gate(struct clk *clk);
345void clk_hw_unregister_gate(struct clk_hw *hw); 345void clk_hw_unregister_gate(struct clk_hw *hw);
346int clk_gate_is_enabled(struct clk_hw *hw);
346 347
347struct clk_div_table { 348struct clk_div_table {
348 unsigned int val; 349 unsigned int val;
@@ -565,6 +566,9 @@ struct clk_fractional_divider {
565 u8 nwidth; 566 u8 nwidth;
566 u32 nmask; 567 u32 nmask;
567 u8 flags; 568 u8 flags;
569 void (*approximation)(struct clk_hw *hw,
570 unsigned long rate, unsigned long *parent_rate,
571 unsigned long *m, unsigned long *n);
568 spinlock_t *lock; 572 spinlock_t *lock;
569}; 573};
570 574
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
index 17f413bbbedf..6aca5ce8a99a 100644
--- a/include/linux/clk/at91_pmc.h
+++ b/include/linux/clk/at91_pmc.h
@@ -185,4 +185,29 @@
185#define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ 185#define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */
186#define AT91_PMC_PCR_GCKEN (0x1 << 29) /* GCK Enable */ 186#define AT91_PMC_PCR_GCKEN (0x1 << 29) /* GCK Enable */
187 187
188#define AT91_PMC_AUDIO_PLL0 0x14c
189#define AT91_PMC_AUDIO_PLL_PLLEN (1 << 0)
190#define AT91_PMC_AUDIO_PLL_PADEN (1 << 1)
191#define AT91_PMC_AUDIO_PLL_PMCEN (1 << 2)
192#define AT91_PMC_AUDIO_PLL_RESETN (1 << 3)
193#define AT91_PMC_AUDIO_PLL_ND_OFFSET 8
194#define AT91_PMC_AUDIO_PLL_ND_MASK (0x7f << AT91_PMC_AUDIO_PLL_ND_OFFSET)
195#define AT91_PMC_AUDIO_PLL_ND(n) ((n) << AT91_PMC_AUDIO_PLL_ND_OFFSET)
196#define AT91_PMC_AUDIO_PLL_QDPMC_OFFSET 16
197#define AT91_PMC_AUDIO_PLL_QDPMC_MASK (0x7f << AT91_PMC_AUDIO_PLL_QDPMC_OFFSET)
198#define AT91_PMC_AUDIO_PLL_QDPMC(n) ((n) << AT91_PMC_AUDIO_PLL_QDPMC_OFFSET)
199
200#define AT91_PMC_AUDIO_PLL1 0x150
201#define AT91_PMC_AUDIO_PLL_FRACR_MASK 0x3fffff
202#define AT91_PMC_AUDIO_PLL_QDPAD_OFFSET 24
203#define AT91_PMC_AUDIO_PLL_QDPAD_MASK (0x7f << AT91_PMC_AUDIO_PLL_QDPAD_OFFSET)
204#define AT91_PMC_AUDIO_PLL_QDPAD(n) ((n) << AT91_PMC_AUDIO_PLL_QDPAD_OFFSET)
205#define AT91_PMC_AUDIO_PLL_QDPAD_DIV_OFFSET AT91_PMC_AUDIO_PLL_QDPAD_OFFSET
206#define AT91_PMC_AUDIO_PLL_QDPAD_DIV_MASK (0x3 << AT91_PMC_AUDIO_PLL_QDPAD_DIV_OFFSET)
207#define AT91_PMC_AUDIO_PLL_QDPAD_DIV(n) ((n) << AT91_PMC_AUDIO_PLL_QDPAD_DIV_OFFSET)
208#define AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_OFFSET 26
209#define AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MAX 0x1f
210#define AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MASK (AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MAX << AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_OFFSET)
211#define AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV(n) ((n) << AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_OFFSET)
212
188#endif 213#endif
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c
index 0cd7caaed9c4..8445edd06737 100644
--- a/sound/soc/atmel/atmel-classd.c
+++ b/sound/soc/atmel/atmel-classd.c
@@ -32,7 +32,6 @@ struct atmel_classd {
32 struct regmap *regmap; 32 struct regmap *regmap;
33 struct clk *pclk; 33 struct clk *pclk;
34 struct clk *gclk; 34 struct clk *gclk;
35 struct clk *aclk;
36 int irq; 35 int irq;
37 const struct atmel_classd_pdata *pdata; 36 const struct atmel_classd_pdata *pdata;
38}; 37};
@@ -330,11 +329,6 @@ static int atmel_classd_codec_dai_startup(struct snd_pcm_substream *substream,
330{ 329{
331 struct snd_soc_pcm_runtime *rtd = substream->private_data; 330 struct snd_soc_pcm_runtime *rtd = substream->private_data;
332 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); 331 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
333 int ret;
334
335 ret = clk_prepare_enable(dd->aclk);
336 if (ret)
337 return ret;
338 332
339 return clk_prepare_enable(dd->gclk); 333 return clk_prepare_enable(dd->gclk);
340} 334}
@@ -357,31 +351,31 @@ static int atmel_classd_codec_dai_digital_mute(struct snd_soc_dai *codec_dai,
357 return 0; 351 return 0;
358} 352}
359 353
360#define CLASSD_ACLK_RATE_11M2896_MPY_8 (112896 * 100 * 8) 354#define CLASSD_GCLK_RATE_11M2896_MPY_8 (112896 * 100 * 8)
361#define CLASSD_ACLK_RATE_12M288_MPY_8 (12288 * 1000 * 8) 355#define CLASSD_GCLK_RATE_12M288_MPY_8 (12288 * 1000 * 8)
362 356
363static struct { 357static struct {
364 int rate; 358 int rate;
365 int sample_rate; 359 int sample_rate;
366 int dsp_clk; 360 int dsp_clk;
367 unsigned long aclk_rate; 361 unsigned long gclk_rate;
368} const sample_rates[] = { 362} const sample_rates[] = {
369 { 8000, CLASSD_INTPMR_FRAME_8K, 363 { 8000, CLASSD_INTPMR_FRAME_8K,
370 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, 364 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 },
371 { 16000, CLASSD_INTPMR_FRAME_16K, 365 { 16000, CLASSD_INTPMR_FRAME_16K,
372 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, 366 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 },
373 { 32000, CLASSD_INTPMR_FRAME_32K, 367 { 32000, CLASSD_INTPMR_FRAME_32K,
374 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, 368 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 },
375 { 48000, CLASSD_INTPMR_FRAME_48K, 369 { 48000, CLASSD_INTPMR_FRAME_48K,
376 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, 370 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 },
377 { 96000, CLASSD_INTPMR_FRAME_96K, 371 { 96000, CLASSD_INTPMR_FRAME_96K,
378 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, 372 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 },
379 { 22050, CLASSD_INTPMR_FRAME_22K, 373 { 22050, CLASSD_INTPMR_FRAME_22K,
380 CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 }, 374 CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_GCLK_RATE_11M2896_MPY_8 },
381 { 44100, CLASSD_INTPMR_FRAME_44K, 375 { 44100, CLASSD_INTPMR_FRAME_44K,
382 CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 }, 376 CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_GCLK_RATE_11M2896_MPY_8 },
383 { 88200, CLASSD_INTPMR_FRAME_88K, 377 { 88200, CLASSD_INTPMR_FRAME_88K,
384 CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 }, 378 CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_GCLK_RATE_11M2896_MPY_8 },
385}; 379};
386 380
387static int 381static int
@@ -410,13 +404,12 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream,
410 } 404 }
411 405
412 dev_dbg(codec->dev, 406 dev_dbg(codec->dev,
413 "Selected SAMPLE_RATE of %dHz, ACLK_RATE of %ldHz\n", 407 "Selected SAMPLE_RATE of %dHz, GCLK_RATE of %ldHz\n",
414 sample_rates[best].rate, sample_rates[best].aclk_rate); 408 sample_rates[best].rate, sample_rates[best].gclk_rate);
415 409
416 clk_disable_unprepare(dd->gclk); 410 clk_disable_unprepare(dd->gclk);
417 clk_disable_unprepare(dd->aclk);
418 411
419 ret = clk_set_rate(dd->aclk, sample_rates[best].aclk_rate); 412 ret = clk_set_rate(dd->gclk, sample_rates[best].gclk_rate);
420 if (ret) 413 if (ret)
421 return ret; 414 return ret;
422 415
@@ -426,10 +419,6 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream,
426 419
427 snd_soc_update_bits(codec, CLASSD_INTPMR, mask, val); 420 snd_soc_update_bits(codec, CLASSD_INTPMR, mask, val);
428 421
429 ret = clk_prepare_enable(dd->aclk);
430 if (ret)
431 return ret;
432
433 return clk_prepare_enable(dd->gclk); 422 return clk_prepare_enable(dd->gclk);
434} 423}
435 424
@@ -441,7 +430,6 @@ atmel_classd_codec_dai_shutdown(struct snd_pcm_substream *substream,
441 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); 430 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
442 431
443 clk_disable_unprepare(dd->gclk); 432 clk_disable_unprepare(dd->gclk);
444 clk_disable_unprepare(dd->aclk);
445} 433}
446 434
447static int atmel_classd_codec_dai_prepare(struct snd_pcm_substream *substream, 435static int atmel_classd_codec_dai_prepare(struct snd_pcm_substream *substream,
@@ -596,13 +584,6 @@ static int atmel_classd_probe(struct platform_device *pdev)
596 return ret; 584 return ret;
597 } 585 }
598 586
599 dd->aclk = devm_clk_get(dev, "aclk");
600 if (IS_ERR(dd->aclk)) {
601 ret = PTR_ERR(dd->aclk);
602 dev_err(dev, "failed to get audio clock: %d\n", ret);
603 return ret;
604 }
605
606 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 587 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
607 io_base = devm_ioremap_resource(dev, res); 588 io_base = devm_ioremap_resource(dev, res);
608 if (IS_ERR(io_base)) { 589 if (IS_ERR(io_base)) {