History

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 ...

Linus Torvalds committed 9 years ago

Commit f60a2ab2 parents 561a8eb 73c950d142 files · +9354 −1101Browse files

Unified · Split

142 files
  1. Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt +16 −6
  2. Documentation/devicetree/bindings/clock/at91-clock.txt +10 −0
  3. Documentation/devicetree/bindings/clock/idt,versaclock5.txt +23 −7
  4. Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +2 −1
  5. Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt +55 −0
  6. Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt +5 −3
  7. Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt +28 −0
  8. Documentation/devicetree/bindings/clock/snps,pll-clock.txt +28 −0
  9. Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt +71 −0
  10. Documentation/devicetree/bindings/clock/sunxi-ccu.txt +6 −0
  11. Documentation/devicetree/bindings/clock/uniphier-clock.txt +3 −5
  12. Documentation/devicetree/bindings/sound/atmel-classd.txt +3 −6
  13. MAINTAINERS +12 −0
  14. arch/arm/mach-at91/Kconfig +4 −0
  15. drivers/clk/Kconfig +12 −5
  16. drivers/clk/Makefile +2 −1
  17. drivers/clk/at91/Makefile +1 −0
  18. drivers/clk/at91/clk-audio-pll.c +536 −0
  19. drivers/clk/at91/clk-generated.c +82 −19
  20. drivers/clk/axs10x/Makefile +1 −0
  21. drivers/clk/axs10x/pll_clock.c +346 −0
  22. drivers/clk/berlin/bg2.c +1 −2
  23. drivers/clk/berlin/bg2q.c +3 −4
  24. drivers/clk/clk-asm9260.c +2 −2
  25. drivers/clk/clk-conf.c +8 −8
  26. drivers/clk/clk-cs2000-cp.c +10 −4
  27. drivers/clk/clk-divider.c +4 −2
  28. drivers/clk/clk-fractional-divider.c +20 −8
  29. drivers/clk/clk-gate.c +2 −1
  30. drivers/clk/clk-gemini.c +0 −7
  31. drivers/clk/clk-hsdk-pll.c +431 −0
  32. drivers/clk/clk-mb86s7x.c +0 −390
  33. drivers/clk/clk-moxart.c +8 −8
  34. drivers/clk/clk-qoriq.c +22 −4
  35. drivers/clk/clk-si5351.c +5 −7
  36. drivers/clk/clk-stm32f4.c +2 −2
  37. drivers/clk/clk-stm32h7.c +1410 −0
  38. drivers/clk/clk-versaclock5.c +159 −13
  39. drivers/clk/clk-xgene.c +6 −9
  40. drivers/clk/clk.c +2 −2
  41. drivers/clk/clkdev.c +2 −2
  42. drivers/clk/hisilicon/clk-hi6220.c +3 −3
  43. drivers/clk/imx/clk-imx51-imx53.c +4 −4
  44. drivers/clk/imx/clk-imx6sl.c +3 −3
  45. drivers/clk/imx/clk-imx6sx.c +3 −3
  46. drivers/clk/imx/clk-imx6ul.c +3 −3
  47. drivers/clk/imx/clk-imx7d.c +2 −2
  48. drivers/clk/imx/clk-vf610.c +1 −1
  49. drivers/clk/mediatek/clk-cpumux.c +1 −5
  50. drivers/clk/mediatek/clk-mtk.c +1 −1
  51. drivers/clk/mediatek/reset.c +1 −1
  52. drivers/clk/meson/Kconfig +1 −0
  53. drivers/clk/meson/Makefile +1 −1
  54. drivers/clk/meson/gxbb-aoclk-32k.c +194 −0
  55. drivers/clk/meson/gxbb-aoclk-regmap.c +46 −0
  56. drivers/clk/meson/gxbb-aoclk.c +42 −23
  57. drivers/clk/meson/gxbb-aoclk.h +42 −0
  58. drivers/clk/meson/gxbb.c +183 −4
  59. drivers/clk/meson/meson8b.c +147 −12
  60. drivers/clk/meson/meson8b.h +8 −1
  61. drivers/clk/mmp/clk.c +1 −1
  62. drivers/clk/nxp/clk-lpc32xx.c +6 −6
  63. drivers/clk/qcom/clk-smd-rpm.c +0 −2
  64. drivers/clk/qcom/gcc-msm8916.c +1 −1
  65. drivers/clk/qcom/gcc-msm8996.c +28 −0
  66. drivers/clk/renesas/Kconfig +29 −19
  67. drivers/clk/renesas/Makefile +2 −0
  68. drivers/clk/renesas/clk-div6.c +3 −0
  69. drivers/clk/renesas/clk-mstp.c +1 −1
  70. drivers/clk/renesas/clk-rcar-gen2.c +1 −2
  71. drivers/clk/renesas/r8a7792-cpg-mssr.c +7 −0
  72. drivers/clk/renesas/r8a7795-cpg-mssr.c +17 −17
  73. drivers/clk/renesas/r8a7796-cpg-mssr.c +18 −17
  74. drivers/clk/renesas/r8a77995-cpg-mssr.c +236 −0
  75. drivers/clk/renesas/rcar-gen3-cpg.c +41 −28
  76. drivers/clk/renesas/rcar-gen3-cpg.h +12 −3
  77. drivers/clk/renesas/rcar-usb2-clock-sel.c +188 −0
  78. drivers/clk/renesas/renesas-cpg-mssr.c +6 −0
  79. drivers/clk/renesas/renesas-cpg-mssr.h +1 −0
  80. drivers/clk/rockchip/clk-rk3128.c +55 −14
  81. drivers/clk/rockchip/clk-rk3228.c +1 −1
  82. drivers/clk/rockchip/clk-rv1108.c +381 −81
  83. drivers/clk/rockchip/clk.c +36 −0
  84. drivers/clk/samsung/clk-exynos-audss.c +4 −4
  85. drivers/clk/samsung/clk-exynos5420.c +15 −8
  86. drivers/clk/sunxi-ng/Kconfig +18 −0
  87. drivers/clk/sunxi-ng/Makefile +2 −0
  88. drivers/clk/sunxi-ng/ccu-sun4i-a10.c +1456 −0
  89. drivers/clk/sunxi-ng/ccu-sun4i-a10.h +61 −0
  90. drivers/clk/sunxi-ng/ccu-sun5i.c +1 −2
  91. drivers/clk/sunxi-ng/ccu-sun6i-a31.c +1 −2
  92. drivers/clk/sunxi-ng/ccu-sun8i-a23.c +1 −2
  93. drivers/clk/sunxi-ng/ccu-sun8i-a33.c +1 −2
  94. drivers/clk/sunxi-ng/ccu-sun8i-h3.c +13 −3
  95. drivers/clk/sunxi-ng/ccu-sun8i-r.c +1 −2
  96. drivers/clk/sunxi-ng/ccu-sun8i-r.h +1 −1
  97. drivers/clk/sunxi-ng/ccu-sun8i-r40.c +1290 −0
  98. drivers/clk/sunxi-ng/ccu-sun8i-r40.h +69 −0
  99. drivers/clk/sunxi-ng/ccu-sun8i-v3s.c +1 −2
  100. drivers/clk/sunxi-ng/ccu_div.c +19 −3
  101. drivers/clk/sunxi-ng/ccu_div.h +2 −1
  102. drivers/clk/sunxi-ng/ccu_frac.c +8 −6
  103. drivers/clk/sunxi-ng/ccu_frac.h +1 −1
  104. drivers/clk/sunxi-ng/ccu_mult.c +7 −3
  105. drivers/clk/sunxi-ng/ccu_nkm.c +19 −3
  106. drivers/clk/sunxi-ng/ccu_nkm.h +2 −0
  107. drivers/clk/sunxi-ng/ccu_nm.c +16 −3
  108. drivers/clk/sunxi/clk-sun8i-bus-gates.c +4 −0
  109. drivers/clk/sunxi/clk-sunxi.c +7 −10
  110. drivers/clk/tegra/clk-emc.c +5 −7
  111. drivers/clk/tegra/clk-pll.c +38 −121
  112. drivers/clk/tegra/clk-tegra-periph.c +2 −1
  113. drivers/clk/tegra/clk-tegra-super-gen4.c +9 −2
  114. drivers/clk/tegra/clk-tegra210.c +18 −14
  115. drivers/clk/tegra/clk.h +0 −6
  116. drivers/clk/ti/adpll.c +2 −2
  117. drivers/clk/ti/apll.c +1 −1
  118. drivers/clk/ti/clockdomain.c +2 −2
  119. drivers/clk/ti/fapll.c +2 −2
  120. drivers/clk/uniphier/clk-uniphier-core.c +15 −11
  121. drivers/clk/uniphier/clk-uniphier-mio.c +1 −3
  122. drivers/clk/uniphier/clk-uniphier-sys.c +71 −27
  123. drivers/clk/uniphier/clk-uniphier.h +2 −2
  124. drivers/clk/ux500/clk-prcc.c +3 −3
  125. drivers/clk/ux500/clk-prcmu.c +7 −7
  126. drivers/clk/ux500/clk-sysctrl.c +4 −4
  127. drivers/clk/versatile/clk-vexpress-osc.c +1 −1
  128. drivers/clk/zte/clk-zx296718.c +3 −3
  129. include/dt-bindings/clock/qcom,gcc-msm8996.h +2 −0
  130. include/dt-bindings/clock/r8a77995-cpg-mssr.h +57 −0
  131. include/dt-bindings/clock/rk3228-cru.h +1 −0
  132. include/dt-bindings/clock/rv1108-cru.h +5 −3
  133. include/dt-bindings/clock/stm32h7-clks.h +165 −0
  134. include/dt-bindings/clock/sun4i-a10-ccu.h +200 −0
  135. include/dt-bindings/clock/sun7i-a20-ccu.h +53 −0
  136. include/dt-bindings/clock/sun8i-r40-ccu.h +187 −0
  137. include/dt-bindings/mfd/stm32h7-rcc.h +136 −0
  138. include/dt-bindings/reset/sun4i-a10-ccu.h +69 −0
  139. include/dt-bindings/reset/sun8i-r40-ccu.h +130 −0
  140. include/linux/clk-provider.h +4 −0
  141. include/linux/clk/at91_pmc.h +25 −0
  142. sound/soc/atmel/atmel-classd.c +14 −33
Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt+16−6
@@ -5,9 +5,11 @@ controllers within the Always-On part of the SoC. · 4 unmodified lines
55
66 Required Properties:
77
8−- compatible: should be "amlogic,gxbb-aoclkc"
9−- reg: physical base address of the clock controller and length of memory
10− mapped region.
8+- compatible: value should be different for each SoC family as :
9+ - GXBB (S905) : "amlogic,meson-gxbb-aoclkc"
10+ - GXL (S905X, S905D) : "amlogic,meson-gxl-aoclkc"
11+ - GXM (S912) : "amlogic,meson-gxm-aoclkc"
12+ followed by the common "amlogic,meson-gx-aoclkc"
1113
1214 - #clock-cells: should be 1.
1315
@@ -23,14 +25,22 @@ to specify the reset which they consume. All available resets are defined as · 9 unmodified lines
2325 preprocessor macros in the dt-bindings/reset/gxbb-aoclkc.h header and can be
2426 used in device tree sources.
2527
28+Parent 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+
2632 Example: AO Clock controller node:
2733
28− clkc_AO: clock-controller@040 {
29− compatible = "amlogic,gxbb-aoclkc";
30− reg = <0x0 0x040 0x0 0x4>;
34+ao_sysctrl: sys-ctrl@0 {
35+ compatible = "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd";
36+ reg = <0x0 0x0 0x0 0x100>;
37+
38+ clkc_AO: clock-controller {
39+ compatible = "amlogic,meson-gxbb-aoclkc", "amlogic,meson-gx-aoclkc";
3140 #clock-cells = <1>;
3241 #reset-cells = <1>;
3342 };
43+};
3444
3545 Example: UART controller node that consumes the clock and reset generated
3646 by the clock controller:
Documentation/devicetree/bindings/clock/at91-clock.txt+10−0
@@ -81,6 +81,16 @@ Required properties: · 80 unmodified lines
8181 "atmel,sama5d2-clk-generated":
8282 at91 generated clock
8383
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+
8494 Required properties for SCKC node:
8595 - reg : defines the IO memory reserved for the SCKC.
8696 - #size-cells : shall be 0 (reg is used to encode clk id).
Documentation/devicetree/bindings/clock/idt,versaclock5.txt+23−7
@@ -1,24 +1,32 @@
1−Binding for IDT VersaClock5 programmable i2c clock generator.
1+Binding for IDT VersaClock 5,6 programmable i2c clock generators.
22
3−The IDT VersaClock5 are programmable i2c clock generators providing
4−from 3 to 12 output clocks.
3+The IDT VersaClock 5 and VersaClock 6 are programmable i2c clock
4+generators providing from 3 to 12 output clocks.
55
66 ==I2C device node==
77
88 Required properties:
9−- compatible: shall be one of "idt,5p49v5923" , "idt,5p49v5933" ,
10− "idt,5p49v5935".
9+- compatible: shall be one of
10+ "idt,5p49v5923"
11+ "idt,5p49v5925"
12+ "idt,5p49v5933"
13+ "idt,5p49v5935"
14+ "idt,5p49v6901"
1115 - reg: i2c device address, shall be 0x68 or 0x6a.
1216 - #clock-cells: from common clock binding; shall be set to 1.
1317 - 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
1521 reference clock.
1622 - 5p49v5933 and
1723 - 5p49v5935: (optional) property not present (internal
1824 Xtal used) or CLKIN reference
1925 clock.
2026 - 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".
2230 - 5p49v5933 and
2331 - 5p49v5935: (optional) property not present or "clkin".
2432
@@ -37,6 +45,7 @@ clock specifier, the following mapping applies: · 12 unmodified lines
3745 1 -- OUT1
3846 2 -- OUT4
3947
48+5P49V5925 and
4049 5P49V5935:
4150 0 -- OUT0_SEL_I2CB
4251 1 -- OUT1
@@ -44,6 +53,13 @@ clock specifier, the following mapping applies: · 1 unmodified line
4453 3 -- OUT3
4554 4 -- OUT4
4655
56+5P49V6901:
57+ 0 -- OUT0_SEL_I2CB
58+ 1 -- OUT1
59+ 2 -- OUT2
60+ 3 -- OUT3
61+ 4 -- OUT4
62+
4763 ==Example==
4864
4965 /* 25MHz reference crystal */
Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt+2−1
@@ -22,6 +22,7 @@ Required Properties: · 21 unmodified lines
2222 - "renesas,r8a7794-cpg-mssr" for the r8a7794 SoC (R-Car E2)
2323 - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3)
2424 - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W)
25+ - "renesas,r8a77995-cpg-mssr" for the r8a77995 SoC (R-Car D3)
2526
2627 - reg: Base address and length of the memory resource used by the CPG/MSSR
2728 block
@@ -30,7 +31,7 @@ Required Properties: · 2 unmodified lines
3031 clock-names
3132 - clock-names: List of external parent clock names. Valid names are:
3233 - "extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794,
33− r8a7795, r8a7796)
34+ r8a7795, r8a7796, r8a77995)
3435 - "extalr" (r8a7795, r8a7796)
3536 - "usb_extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7793, r8a7794)
3637
Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt+55−0
@@ -0,0 +1,55 @@
1+* Renesas R-Car USB 2.0 clock selector
2+
3+This file provides information on what the device node for the R-Car USB 2.0
4+clock selector.
5+
6+If you connect an external clock to the USB_EXTAL pin only, you should set
7+the clock rate to "usb_extal" node only.
8+If you connect an oscillator to both the USB_XTAL and USB_EXTAL, this module
9+is not needed because this is default setting. (Of course, you can set the
10+clock rates to both "usb_extal" and "usb_xtal" nodes.
11+
12+Case 1: An external clock connects to R-Car SoC
13+ +----------+ +--- R-Car ---------------------+
14+ |External |---|USB_EXTAL ---> all usb channels|
15+ |clock | |USB_XTAL |
16+ +----------+ +-------------------------------+
17+In this case, we need this driver with "usb_extal" clock.
18+
19+Case 2: An oscillator connects to R-Car SoC
20+ +----------+ +--- R-Car ---------------------+
21+ |Oscillator|---|USB_EXTAL -+-> all usb channels|
22+ | |---|USB_XTAL --+ |
23+ +----------+ +-------------------------------+
24+In this case, we don't need this selector.
25+
26+Required 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+
46+Example (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+ };
Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt+5−3
@@ -1,12 +1,14 @@
1−* Rockchip RK3128 Clock and Reset Unit
1+* Rockchip RK3126/RK3128 Clock and Reset Unit
22
3−The RK3128 clock controller generates and supplies clock to various
3+The RK3126/RK3128 clock controller generates and supplies clock to various
44 controllers within the SoC and also implements a reset controller for SoC
55 peripherals.
66
77 Required Properties:
88
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.
1012 - reg: physical base address of the controller and length of memory mapped
1113 region.
1214 - #clock-cells: should be 1.
Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt+28−0
@@ -0,0 +1,28 @@
1+Binding for the HSDK Generic PLL clock
2+
3+This binding uses the common clock binding[1].
4+
5+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
6+
7+Required 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+
16+Example:
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+ };
Documentation/devicetree/bindings/clock/snps,pll-clock.txt+28−0
@@ -0,0 +1,28 @@
1+Binding for the AXS10X Generic PLL clock
2+
3+This binding uses the common clock binding[1].
4+
5+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
6+
7+Required 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
12+registers 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+
16+Example:
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+ };
Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt+71−0
@@ -0,0 +1,71 @@
1+STMicroelectronics STM32H7 Reset and Clock Controller
2+=====================================================
3+
4+The RCC IP is both a reset and a clock controller.
5+
6+Please refer to clock-bindings.txt for common clock controller binding usage.
7+Please also refer to reset.txt for common reset controller binding usage.
8+
9+Required 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+
25+Optional properties:
26+- st,syscfg: phandle for pwrcfg, mandatory to disable/enable backup domain
27+ write protection (RTC clock).
28+
29+Example:
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+
41+The peripheral clock consumer should specify the desired clock by
42+having the clock ID in its "clocks" phandle cell.
43+
44+Example:
45+
46+ timer5: timer@40000c00 {
47+ compatible = "st,stm32-timer";
48+ reg = <0x40000c00 0x400>;
49+ interrupts = <50>;
50+ clocks = <&rcc TIM5_CK>;
51+ };
52+
53+Specifying softreset control of devices
54+=======================================
55+
56+Device nodes should specify the reset channel required in their "resets"
57+property, containing a phandle to the reset device node and an index specifying
58+which channel to use.
59+The index is the bit number within the RCC registers bank, starting from RCC
60+base address.
61+It is calculated as: index = register_offset / 4 * 32 + bit_offset.
62+Where bit_offset is the bit offset within the register.
63+
64+For example, for CRC reset:
65+ crc = AHB4RSTR_offset / 4 * 32 + CRCRST_bit_offset = 0x88 / 4 * 32 + 19 = 1107
66+
67+Example:
68+
69+ timer2 {
70+ resets = <&rcc STM32H7_APB1L_RESET(TIM2)>;
71+ };
Documentation/devicetree/bindings/clock/sunxi-ccu.txt+6−0
@@ -3,18 +3,24 @@ Allwinner Clock Control Unit Binding · 2 unmodified lines
33
44 Required properties :
55 - compatible: must contain one of the following compatibles:
6+ - "allwinner,sun4i-a10-ccu"
7+ - "allwinner,sun5i-a10s-ccu"
8+ - "allwinner,sun5i-a13-ccu"
69 - "allwinner,sun6i-a31-ccu"
10+ - "allwinner,sun7i-a20-ccu"
711 - "allwinner,sun8i-a23-ccu"
812 - "allwinner,sun8i-a33-ccu"
913 - "allwinner,sun8i-a83t-ccu"
1014 - "allwinner,sun8i-a83t-r-ccu"
1115 - "allwinner,sun8i-h3-ccu"
1216 - "allwinner,sun8i-h3-r-ccu"
17++ - "allwinner,sun8i-r40-ccu"
1318 - "allwinner,sun8i-v3s-ccu"
1419 - "allwinner,sun9i-a80-ccu"
1520 - "allwinner,sun50i-a64-ccu"
1621 - "allwinner,sun50i-a64-r-ccu"
1722 - "allwinner,sun50i-h5-ccu"
23+ - "nextthing,gr8-ccu"
1824
1925 - reg: Must contain the registers base address and length
2026 - clocks: phandle to the oscillators feeding the CCU. Two are needed:
Documentation/devicetree/bindings/clock/uniphier-clock.txt+3−5
@@ -6,7 +6,6 @@ System clock · 5 unmodified lines
66
77 Required properties:
88 - compatible: should be one of the following:
9− "socionext,uniphier-sld3-clock" - for sLD3 SoC.
109 "socionext,uniphier-ld4-clock" - for LD4 SoC.
1110 "socionext,uniphier-pro4-clock" - for Pro4 SoC.
1211 "socionext,uniphier-sld8-clock" - for sLD8 SoC.
@@ -14,6 +13,7 @@ Required properties: · 1 unmodified line
1413 "socionext,uniphier-pxs2-clock" - for PXs2/LD6b SoC.
1514 "socionext,uniphier-ld11-clock" - for LD11 SoC.
1615 "socionext,uniphier-ld20-clock" - for LD20 SoC.
16+ "socionext,uniphier-pxs3-clock" - for PXs3 SoC
1717 - #clock-cells: should be 1.
1818
1919 Example:
@@ -48,7 +48,6 @@ Media I/O (MIO) clock, SD clock · 28 unmodified lines
4848
4949 Required properties:
5050 - compatible: should be one of the following:
51− "socionext,uniphier-sld3-mio-clock" - for sLD3 SoC.
5251 "socionext,uniphier-ld4-mio-clock" - for LD4 SoC.
5352 "socionext,uniphier-pro4-mio-clock" - for Pro4 SoC.
5453 "socionext,uniphier-sld8-mio-clock" - for sLD8 SoC.
@@ -56,6 +55,7 @@ Required properties: · 1 unmodified line
5655 "socionext,uniphier-pxs2-sd-clock" - for PXs2/LD6b SoC.
5756 "socionext,uniphier-ld11-mio-clock" - for LD11 SoC.
5857 "socionext,uniphier-ld20-sd-clock" - for LD20 SoC.
58+ "socionext,uniphier-pxs3-sd-clock" - for PXs3 SoC
5959 - #clock-cells: should be 1.
6060
6161 Example:
@@ -82,11 +82,9 @@ Provided clocks: · 20 unmodified lines
8282 8: USB2 ch0 host
8383 9: USB2 ch1 host
8484 10: USB2 ch2 host
85−11: USB2 ch3 host
8685 12: USB2 ch0 PHY
8786 13: USB2 ch1 PHY
8887 14: USB2 ch2 PHY
89−15: USB2 ch3 PHY
9088
9189
9290 Peripheral clock
@@ -94,7 +92,6 @@ Peripheral clock · 1 unmodified line
9492
9593 Required properties:
9694 - compatible: should be one of the following:
97− "socionext,uniphier-sld3-peri-clock" - for sLD3 SoC.
9895 "socionext,uniphier-ld4-peri-clock" - for LD4 SoC.
9996 "socionext,uniphier-pro4-peri-clock" - for Pro4 SoC.
10097 "socionext,uniphier-sld8-peri-clock" - for sLD8 SoC.
@@ -102,6 +99,7 @@ Required properties: · 1 unmodified line
10299 "socionext,uniphier-pxs2-peri-clock" - for PXs2/LD6b SoC.
103100 "socionext,uniphier-ld11-peri-clock" - for LD11 SoC.
104101 "socionext,uniphier-ld20-peri-clock" - for LD20 SoC.
102+ "socionext,uniphier-pxs3-peri-clock" - for PXs3 SoC
105103 - #clock-cells: should be 1.
106104
107105 Example:
Documentation/devicetree/bindings/sound/atmel-classd.txt+3−6
@@ -13,13 +13,11 @@ Required properties: · 12 unmodified lines
1313 Must be "tx".
1414 - clock-names
1515 Tuple listing input clock names.
16− Required elements: "pclk", "gclk" and "aclk".
16+ Required elements: "pclk" and "gclk".
1717 - clocks
1818 Please refer to clock-bindings.txt.
1919 - assigned-clocks
2020 Should be <&classd_gclk>.
21−- assigned-clock-parents
22− Should be <&audio_pll_pmc>.
2321
2422 Optional properties:
2523 - pinctrl-names, pinctrl-0
@@ -45,10 +43,9 @@ classd: classd@fc048000 { · 19 unmodified lines
4543 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
4644 | AT91_XDMAC_DT_PERID(47))>;
4745 dma-names = "tx";
48− clocks = <&classd_clk>, <&classd_gclk>, <&audio_pll_pmc>;
49− clock-names = "pclk", "gclk", "aclk";
46+ clocks = <&classd_clk>, <&classd_gclk>;
47+ clock-names = "pclk", "gclk";
5048 assigned-clocks = <&classd_gclk>;
51− assigned-clock-parents = <&audio_pll_pmc>;
5249
5350 pinctrl-names = "default";
5451 pinctrl-0 = <&pinctrl_classd_default>;
MAINTAINERS+12−0
@@ -12842,6 +12842,18 @@ F: drivers/clocksource/arc_timer.c · 12841 unmodified lines
1284212842 F: drivers/tty/serial/arc_uart.c
1284312843 T: git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git
1284412844
12845+SYNOPSYS ARC HSDK SDP pll clock driver
12846+M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
12847+S: Supported
12848+F: drivers/clk/clk-hsdk-pll.c
12849+F: Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt
12850+
12851+SYNOPSYS ARC SDP clock driver
12852+M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
12853+S: Supported
12854+F: drivers/clk/axs10x/*
12855+F: Documentation/devicetree/bindings/clock/snps,pll-clock.txt
12856+
1284512857 SYNOPSYS ARC SDP platform support
1284612858 M: Alexey Brodkin <abrodkin@synopsys.com>
1284712859 S: Supported
arch/arm/mach-at91/Kconfig+4−0
@@ -26,6 +26,7 @@ config SOC_SAMA5D2 · 25 unmodified lines
2626 select HAVE_AT91_USB_CLK
2727 select HAVE_AT91_H32MX
2828 select HAVE_AT91_GENERATED_CLK
29+ select HAVE_AT91_AUDIO_PLL
2930 select PINCTRL_AT91PIO4
3031 help
3132 Select this if ou are using one of Atmel's SAMA5D2 family SoC.
@@ -125,6 +126,9 @@ config HAVE_AT91_H32MX · 93 unmodified lines
125126 config HAVE_AT91_GENERATED_CLK
126127 bool
127128
129+config HAVE_AT91_AUDIO_PLL
130+ bool
131+
128132 config SOC_SAM_V4_V5
129133 bool
130134
drivers/clk/Kconfig+12−5
@@ -31,6 +31,13 @@ config COMMON_CLK_WM831X · 30 unmodified lines
3131
3232 source "drivers/clk/versatile/Kconfig"
3333
34+config 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+
3441 config COMMON_CLK_MAX77686
3542 tristate "Clock driver for Maxim 77620/77686/77802 MFD"
3643 depends on MFD_MAX77686 || MFD_MAX77620 || COMPILE_TEST
@@ -39,10 +46,10 @@ config COMMON_CLK_MAX77686 · 2 unmodified lines
3946 clock.
4047
4148 config COMMON_CLK_RK808
42− tristate "Clock driver for RK808/RK818"
49+ tristate "Clock driver for RK805/RK808/RK818"
4350 depends on MFD_RK808
4451 ---help---
45− This driver supports RK808 and RK818 crystal oscillator clock. These
52+ This driver supports RK805, RK808 and RK818 crystal oscillator clock. These
4653 multi-function devices have two fixed-rate oscillators,
4754 clocked at 32KHz each. Clkout1 is always on, Clkout2 can off
4855 by control register.
@@ -210,14 +217,14 @@ config COMMON_CLK_OXNAS · 161 unmodified lines
210217 Support for the OXNAS SoC Family clocks.
211218
212219 config COMMON_CLK_VC5
213− tristate "Clock driver for IDT VersaClock5 devices"
220+ tristate "Clock driver for IDT VersaClock 5,6 devices"
214221 depends on I2C
215222 depends on OF
216223 select REGMAP_I2C
217224 help
218225 ---help---
219− This driver supports the IDT VersaClock5 programmable clock
220− generator.
226+ This driver supports the IDT VersaClock 5 and VersaClock 6
227+ programmable clock generators.
221228
222229 source "drivers/clk/bcm/Kconfig"
223230 source "drivers/clk/hisilicon/Kconfig"
drivers/clk/Makefile+2−1
@@ -27,8 +27,8 @@ obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o · 26 unmodified lines
2727 obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
2828 obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o
2929 obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
30+obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o
3031 obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
31−obj-$(CONFIG_ARCH_MB86S7X) += clk-mb86s7x.o
3232 obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
3333 obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
3434 obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
@@ -44,6 +44,7 @@ obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o · 9 unmodified lines
4444 obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o
4545 obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
4646 obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o
47+obj-$(CONFIG_ARCH_STM32) += clk-stm32h7.o
4748 obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o
4849 obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
4950 obj-$(CONFIG_ARCH_U300) += clk-u300.o
drivers/clk/at91/Makefile+1−0
@@ -6,6 +6,7 @@ obj-y += pmc.o sckc.o · 5 unmodified lines
66 obj-y += clk-slow.o clk-main.o clk-pll.o clk-plldiv.o clk-master.o
77 obj-y += clk-system.o clk-peripheral.o clk-programmable.o
88
9+obj-$(CONFIG_HAVE_AT91_AUDIO_PLL) += clk-audio-pll.o
910 obj-$(CONFIG_HAVE_AT91_UTMI) += clk-utmi.o
1011 obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o
1112 obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o
drivers/clk/at91/clk-audio-pll.c+536−0
@@ -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+
61+struct clk_audio_frac {
62+ struct clk_hw hw;
63+ struct regmap *regmap;
64+ u32 fracr;
65+ u8 nd;
66+};
67+
68+struct clk_audio_pad {
69+ struct clk_hw hw;
70+ struct regmap *regmap;
71+ u8 qdaudio;
72+ u8 div;
73+};
74+
75+struct 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+
85+static 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+
110+static 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+
123+static 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+
135+static 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+
146+static 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+
154+static 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+
162+static 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+
176+static 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+
190+static 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+
205+static 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+
219+static 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+
247+static 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+
276+static 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+
327+static 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+
360+static 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+
383+static 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+
407+static 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+
423+static 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+
431+static 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+
439+static 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+
447+static 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+
475+static 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+
492+static 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+
510+static 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+
528+CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_frac_setup,
529+ "atmel,sama5d2-clk-audio-pll-frac",
530+ of_sama5d2_clk_audio_pll_frac_setup);
531+CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pad_setup,
532+ "atmel,sama5d2-clk-audio-pll-pad",
533+ of_sama5d2_clk_audio_pll_pad_setup);
534+CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pmc_setup,
535+ "atmel,sama5d2-clk-audio-pll-pmc",
536+ of_sama5d2_clk_audio_pll_pmc_setup);
drivers/clk/at91/clk-generated.c+82−19
@@ -26,6 +26,13 @@ · 25 unmodified lines
2626 #define GENERATED_SOURCE_MAX 6
2727 #define GENERATED_MAX_DIV 255
2828
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+
2936 struct clk_generated {
3037 struct clk_hw hw;
3138 struct regmap *regmap;
@@ -34,6 +41,7 @@ struct clk_generated { · 2 unmodified lines
3441 u32 id;
3542 u32 gckdiv;
3643 u8 parent_id;
44+ bool audio_pll_allowed;
3745 };
3846
3947 #define to_clk_generated(hw) \
@@ -99,21 +107,41 @@ clk_generated_recalc_rate(struct clk_hw *hw, · 59 unmodified lines
99107 return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1);
100108 }
101109
110+static 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+
102132 static int clk_generated_determine_rate(struct clk_hw *hw,
103133 struct clk_rate_request *req)
104134 {
105135 struct clk_generated *gck = to_clk_generated(hw);
106136 struct clk_hw *parent = NULL;
137+ struct clk_rate_request req_parent = *req;
107138 long best_rate = -EINVAL;
108− unsigned long tmp_rate, min_rate;
139+ unsigned long min_rate, parent_rate;
109140 int best_diff = -1;
110− int tmp_diff;
111141 int i;
142+ u32 div;
112143
113− for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
114− u32 div;
115− unsigned long parent_rate;
116−
144+ for (i = 0; i < clk_hw_get_num_parents(hw) - 1; i++) {
117145 parent = clk_hw_get_parent_by_index(hw, i);
118146 if (!parent)
119147 continue;
@@ -124,25 +152,43 @@ static int clk_generated_determine_rate(struct clk_hw *hw, · 4 unmodified lines
124152 (gck->range.max && min_rate > gck->range.max))
125153 continue;
126154
127− for (div = 1; div < GENERATED_MAX_DIV + 2; div++) {
128− tmp_rate = DIV_ROUND_CLOSEST(parent_rate, div);
129− tmp_diff = abs(req->rate - tmp_rate);
155+ div = DIV_ROUND_CLOSEST(parent_rate, req->rate);
130156
131− if (best_diff < 0 || best_diff > tmp_diff) {
132− best_rate = tmp_rate;
133− best_diff = tmp_diff;
134− req->best_parent_rate = parent_rate;
135− req->best_parent_hw = parent;
136− }
157+ clk_generated_best_diff(req, parent, parent_rate, div,
158+ &best_diff, &best_rate);
137159
138− if (!best_diff || tmp_rate < req->rate)
139− break;
140− }
160+ if (!best_diff)
161+ break;
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);
141186
142187 if (!best_diff)
143188 break;
144189 }
145190
191+end:
146192 pr_debug("GCLK: %s, best_rate = %ld, parent clk: %s @ %ld\n",
147193 __func__, best_rate,
148194 __clk_get_name((req->best_parent_hw)->clk),
@@ -252,7 +298,8 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, · 103 unmodified lines
252298 init.ops = &generated_ops;
253299 init.parent_names = parent_names;
254300 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;
256303
257304 gck->id = id;
258305 gck->hw.init = &init;
@@ -284,6 +331,7 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np) · 25 unmodified lines
284331 struct device_node *gcknp;
285332 struct clk_range range = CLK_RANGE(0, 0);
286333 struct regmap *regmap;
334+ struct clk_generated *gck;
287335
288336 num_parents = of_clk_get_parent_count(np);
289337 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) · 25 unmodified lines
315363 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name,
316364 parent_names, num_parents,
317365 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+
318381 if (IS_ERR(hw))
319382 continue;
320383
drivers/clk/axs10x/Makefile+1−0
@@ -1 +1,2 @@
11 obj-y += i2s_pll_clock.o
2+obj-y += pll_clock.o
drivers/clk/axs10x/pll_clock.c+346−0
@@ -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+
69+struct axs10x_pll_cfg {
70+ u32 rate;
71+ u32 idiv;
72+ u32 fbdiv;
73+ u32 odiv;
74+};
75+
76+static 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+
86+static 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+
93+struct 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+
101+static inline void axs10x_pll_write(struct axs10x_pll_clk *clk, u32 reg,
102+ u32 val)
103+{
104+ iowrite32(val, clk->base + reg);
105+}
106+
107+static inline u32 axs10x_pll_read(struct axs10x_pll_clk *clk, u32 reg)
108+{
109+ return ioread32(clk->base + reg);
110+}
111+
112+static 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+
117+static 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+
125+static 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+
138+static 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+
155+static 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+
176+static 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+
212+static 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+
218+static 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+
265+static int axs10x_pll_clk_remove(struct platform_device *pdev)
266+{
267+ of_clk_del_provider(pdev->dev.of_node);
268+ return 0;
269+}
270+
271+static 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+
316+err_unregister_clk:
317+ clk_hw_unregister(&pll_clk->hw);
318+err_unmap_lock:
319+ iounmap(pll_clk->lock);
320+err_unmap_base:
321+ iounmap(pll_clk->base);
322+err_free_pll_clk:
323+ kfree(pll_clk);
324+}
325+CLK_OF_DECLARE(axs10x_pll_clock, "snps,axs10x-arc-pll-clock",
326+ of_axs10x_pll_clk_setup);
327+
328+static const struct of_device_id axs10x_pll_clk_id[] = {
329+ { .compatible = "snps,axs10x-pgu-pll-clock", .data = &pgu_pll_cfg},
330+ { }
331+};
332+MODULE_DEVICE_TABLE(of, axs10x_pll_clk_id);
333+
334+static 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+};
342+builtin_platform_driver(axs10x_pll_clk_driver);
343+
344+MODULE_AUTHOR("Vlad Zakharov <vzakhar@synopsys.com>");
345+MODULE_DESCRIPTION("Synopsys AXS10X SDP Generic PLL Clock Driver");
346+MODULE_LICENSE("GPL v2");
drivers/clk/berlin/bg2.c+1−2
@@ -679,8 +679,7 @@ static void __init berlin2_clock_setup(struct device_node *np) · 678 unmodified lines
679679 if (!IS_ERR(hws[n]))
680680 continue;
681681
682− pr_err("%s: Unable to register leaf clock %d\n",
683− np->full_name, n);
682+ pr_err("%pOF: Unable to register leaf clock %d\n", np, n);
684683 goto bg2_fail;
685684 }
686685
drivers/clk/berlin/bg2q.c+3−4
@@ -304,14 +304,14 @@ static void __init berlin2q_clock_setup(struct device_node *np) · 303 unmodified lines
304304
305305 gbase = of_iomap(parent_np, 0);
306306 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);
308308 return;
309309 }
310310
311311 /* BG2Q CPU PLL is not part of global registers */
312312 cpupll_base = of_iomap(parent_np, 1);
313313 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);
315315 iounmap(gbase);
316316 return;
317317 }
@@ -376,8 +376,7 @@ static void __init berlin2q_clock_setup(struct device_node *np) · 58 unmodified lines
376376 if (!IS_ERR(hws[n]))
377377 continue;
378378
379− pr_err("%s: Unable to register leaf clock %d\n",
380− np->full_name, n);
379+ pr_err("%pOF: Unable to register leaf clock %d\n", np, n);
381380 goto bg2q_fail;
382381 }
383382
drivers/clk/clk-asm9260.c+2−2
@@ -338,8 +338,8 @@ static void __init asm9260_acc_init(struct device_node *np) · 337 unmodified lines
338338 if (!IS_ERR(hws[n]))
339339 continue;
340340
341− pr_err("%s: Unable to register leaf clock %d\n",
342− np->full_name, n);
341+ pr_err("%pOF: Unable to register leaf clock %d\n",
342+ np, n);
343343 goto fail;
344344 }
345345
drivers/clk/clk-conf.c+8−8
@@ -23,8 +23,8 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier) · 22 unmodified lines
2323 num_parents = of_count_phandle_with_args(node, "assigned-clock-parents",
2424 "#clock-cells");
2525 if (num_parents == -EINVAL)
26− pr_err("clk: invalid value of clock-parents property at %s\n",
27− node->full_name);
26+ pr_err("clk: invalid value of clock-parents property at %pOF\n",
27+ node);
2828
2929 for (index = 0; index < num_parents; index++) {
3030 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) · 10 unmodified lines
4141 pclk = of_clk_get_from_provider(&clkspec);
4242 if (IS_ERR(pclk)) {
4343 if (PTR_ERR(pclk) != -EPROBE_DEFER)
44− pr_warn("clk: couldn't get parent clock %d for %s\n",
45− index, node->full_name);
44+ pr_warn("clk: couldn't get parent clock %d for %pOF\n",
45+ index, node);
4646 return PTR_ERR(pclk);
4747 }
4848
@@ -57,8 +57,8 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier) · 8 unmodified lines
5757 clk = of_clk_get_from_provider(&clkspec);
5858 if (IS_ERR(clk)) {
5959 if (PTR_ERR(clk) != -EPROBE_DEFER)
60− pr_warn("clk: couldn't get assigned clock %d for %s\n",
61− index, node->full_name);
60+ pr_warn("clk: couldn't get assigned clock %d for %pOF\n",
61+ index, node);
6262 rc = PTR_ERR(clk);
6363 goto err;
6464 }
@@ -102,8 +102,8 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier) · 37 unmodified lines
102102 clk = of_clk_get_from_provider(&clkspec);
103103 if (IS_ERR(clk)) {
104104 if (PTR_ERR(clk) != -EPROBE_DEFER)
105− pr_warn("clk: couldn't get clock %d for %s\n",
106− index, node->full_name);
105+ pr_warn("clk: couldn't get clock %d for %pOF\n",
106+ index, node);
107107 return PTR_ERR(clk);
108108 }
109109
drivers/clk/clk-cs2000-cp.c+10−4
@@ -343,6 +343,15 @@ static int cs2000_set_rate(struct clk_hw *hw, · 342 unmodified lines
343343 return __cs2000_set_rate(priv, ch, rate, parent_rate);
344344 }
345345
346+static 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+
346355 static int cs2000_enable(struct clk_hw *hw)
347356 {
348357 struct cs2000_priv *priv = hw_to_priv(hw);
@@ -535,11 +544,8 @@ probe_err: · 186 unmodified lines
535544 static int cs2000_resume(struct device *dev)
536545 {
537546 struct cs2000_priv *priv = dev_get_drvdata(dev);
538− int ch = 0; /* it uses ch0 only at this point */
539547
540− return __cs2000_set_rate(priv, ch,
541− priv->saved_rate,
542− priv->saved_parent_rate);
548+ return cs2000_set_saved_rate(priv);
543549 }
544550
545551 static const struct dev_pm_ops cs2000_pm_ops = {
drivers/clk/clk-divider.c+4−2
@@ -385,12 +385,14 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, · 384 unmodified lines
385385 unsigned long parent_rate)
386386 {
387387 struct clk_divider *divider = to_clk_divider(hw);
388− unsigned int value;
388+ int value;
389389 unsigned long flags = 0;
390390 u32 val;
391391
392392 value = divider_get_val(rate, parent_rate, divider->table,
393393 divider->width, divider->flags);
394+ if (value < 0)
395+ return value;
394396
395397 if (divider->lock)
396398 spin_lock_irqsave(divider->lock, flags);
@@ -403,7 +405,7 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, · 6 unmodified lines
403405 val = clk_readl(divider->reg);
404406 val &= ~(div_mask(divider->width) << divider->shift);
405407 }
406− val |= value << divider->shift;
408+ val |= (u32)value << divider->shift;
407409 clk_writel(val, divider->reg);
408410
409411 if (divider->lock)
drivers/clk/clk-fractional-divider.c+20−8
@@ -49,16 +49,12 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw, · 48 unmodified lines
4949 return ret;
5050 }
5151
52−static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
53− unsigned long *parent_rate)
52+static void clk_fd_general_approximation(struct clk_hw *hw, unsigned long rate,
53+ unsigned long *parent_rate,
54+ unsigned long *m, unsigned long *n)
5455 {
5556 struct clk_fractional_divider *fd = to_clk_fd(hw);
5657 unsigned long scale;
57− unsigned long m, n;
58− u64 ret;
59−
60− if (!rate || rate >= *parent_rate)
61− return *parent_rate;
6258
6359 /*
6460 * 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, · 6 unmodified lines
7167
7268 rational_best_approximation(rate, *parent_rate,
7369 GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
74− &m, &n);
70+ m, n);
71+}
72+
73+static 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);
7587
7688 ret = (u64)*parent_rate * m;
7789 do_div(ret, n);
drivers/clk/clk-gate.c+2−1
@@ -86,7 +86,7 @@ static void clk_gate_disable(struct clk_hw *hw) · 85 unmodified lines
8686 clk_gate_endisable(hw, 0);
8787 }
8888
89−static int clk_gate_is_enabled(struct clk_hw *hw)
89+int clk_gate_is_enabled(struct clk_hw *hw)
9090 {
9191 u32 reg;
9292 struct clk_gate *gate = to_clk_gate(hw);
@@ -101,6 +101,7 @@ static int clk_gate_is_enabled(struct clk_hw *hw) · 8 unmodified lines
101101
102102 return reg ? 1 : 0;
103103 }
104+EXPORT_SYMBOL_GPL(clk_gate_is_enabled);
104105
105106 const struct clk_ops clk_gate_ops = {
106107 .enable = clk_gate_enable,
drivers/clk/clk-gemini.c+0−7
@@ -37,7 +37,6 @@ static DEFINE_SPINLOCK(gemini_clk_lock); · 36 unmodified lines
3737
3838 #define GEMINI_GLOBAL_MISC_CONTROL 0x30
3939 #define PCI_CLK_66MHZ BIT(18)
40−#define PCI_CLK_OE BIT(17)
4140
4241 #define GEMINI_GLOBAL_CLOCK_CONTROL 0x34
4342 #define PCI_CLKRUN_EN BIT(16)
@@ -159,9 +158,6 @@ static int gemini_pci_enable(struct clk_hw *hw) · 115 unmodified lines
159158
160159 regmap_update_bits(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL,
161160 0, PCI_CLKRUN_EN);
162− regmap_update_bits(pciclk->map,
163− GEMINI_GLOBAL_MISC_CONTROL,
164− 0, PCI_CLK_OE);
165161 return 0;
166162 }
167163
@@ -169,9 +165,6 @@ static void gemini_pci_disable(struct clk_hw *hw) · 1 unmodified line
169165 {
170166 struct clk_gemini_pci *pciclk = to_pciclk(hw);
171167
172− regmap_update_bits(pciclk->map,
173− GEMINI_GLOBAL_MISC_CONTROL,
174− PCI_CLK_OE, 0);
175168 regmap_update_bits(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL,
176169 PCI_CLKRUN_EN, 0);
177170 }
drivers/clk/clk-hsdk-pll.c+431−0
@@ -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+
49+struct hsdk_pll_cfg {
50+ u32 rate;
51+ u32 idiv;
52+ u32 fbdiv;
53+ u32 odiv;
54+ u32 band;
55+};
56+
57+static 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+
80+static 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+
87+struct 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+
95+struct 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+
101+static int hsdk_pll_core_update_rate(struct hsdk_pll_clk *, unsigned long,
102+ const struct hsdk_pll_cfg *);
103+static int hsdk_pll_comm_update_rate(struct hsdk_pll_clk *, unsigned long,
104+ const struct hsdk_pll_cfg *);
105+
106+static const struct hsdk_pll_devdata core_pll_devdata = {
107+ .pll_cfg = asdt_pll_cfg,
108+ .update_rate = hsdk_pll_core_update_rate,
109+};
110+
111+static const struct hsdk_pll_devdata sdt_pll_devdata = {
112+ .pll_cfg = asdt_pll_cfg,
113+ .update_rate = hsdk_pll_comm_update_rate,
114+};
115+
116+static const struct hsdk_pll_devdata hdmi_pll_devdata = {
117+ .pll_cfg = hdmi_pll_cfg,
118+ .update_rate = hsdk_pll_comm_update_rate,
119+};
120+
121+static inline void hsdk_pll_write(struct hsdk_pll_clk *clk, u32 reg, u32 val)
122+{
123+ iowrite32(val, clk->regs + reg);
124+}
125+
126+static inline u32 hsdk_pll_read(struct hsdk_pll_clk *clk, u32 reg)
127+{
128+ return ioread32(clk->regs + reg);
129+}
130+
131+static 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+
147+static 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+
152+static 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+
157+static 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+
162+static 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+
195+static 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+
218+static 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+
238+static 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+
272+static 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+
292+static 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+
298+static 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+
347+static int hsdk_pll_clk_remove(struct platform_device *pdev)
348+{
349+ of_clk_del_provider(pdev->dev.of_node);
350+ return 0;
351+}
352+
353+static 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+
405+err_unmap_spec_regs:
406+ iounmap(pll_clk->spec_regs);
407+err_unmap_comm_regs:
408+ iounmap(pll_clk->regs);
409+err_free_pll_clk:
410+ kfree(pll_clk);
411+}
412+
413+/* Core PLL needed early for ARC cpus timers */
414+CLK_OF_DECLARE(hsdk_pll_clock, "snps,hsdk-core-pll-clock",
415+of_hsdk_pll_clk_setup);
416+
417+static 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+
423+static 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+};
431+builtin_platform_driver(hsdk_pll_clk_driver);
drivers/clk/clk-mb86s7x.c+0−390
@@ -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−
32−struct 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−
41−struct hack_rate {
42− unsigned clk_id;
43− unsigned long rate;
44− int gated;
45−};
46−
47−struct crg_clk {
48− struct clk_hw hw;
49− u8 cntrlr, domain, port;
50−};
51−
52−static 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−
92−static int crg_port_prepare(struct clk_hw *hw)
93−{
94− return crg_gate_control(hw, 1);
95−}
96−
97−static void crg_port_unprepare(struct clk_hw *hw)
98−{
99− crg_gate_control(hw, 0);
100−}
101−
102−static int
103−crg_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−
146−static unsigned long
147−crg_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−
156−static long
157−crg_port_round_rate(struct clk_hw *hw,
158− unsigned long rate, unsigned long *pr)
159−{
160− return rate;
161−}
162−
163−static int
164−crg_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−
170−const 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−
178−struct mb86s70_crg11 {
179− struct mutex lock; /* protects CLK populating and searching */
180−};
181−
182−static 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−
236−static 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−}
248−CLK_OF_DECLARE(crg11_gate, "fujitsu,mb86s70-crg11", crg_port_init);
249−
250−struct cl_clk {
251− struct clk_hw hw;
252− int cluster;
253−};
254−
255−struct mb86s7x_cpu_freq {
256− u32 payload_size;
257− u32 cluster_class;
258− u32 cluster_id;
259− u32 cpu_id;
260− u64 frequency;
261−};
262−
263−static 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−
297−static unsigned long
298−clc_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−
306−static long
307−clc_round_rate(struct clk_hw *hw, unsigned long rate,
308− unsigned long *unused)
309−{
310− return rate;
311−}
312−
313−static int
314−clc_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−
324−static 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−
330−static 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−
354−static 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);
386−exit:
387− of_node_put(np);
388− return ret;
389−}
390−module_init(mb86s7x_clclk_of_init);
drivers/clk/clk-moxart.c+8−8
@@ -18,7 +18,7 @@ · 17 unmodified lines
1818
1919 static void __init moxart_of_pll_clk_init(struct device_node *node)
2020 {
21− static void __iomem *base;
21+ void __iomem *base;
2222 struct clk_hw *hw;
2323 struct clk *ref_clk;
2424 unsigned int mul;
@@ -30,7 +30,7 @@ static void __init moxart_of_pll_clk_init(struct device_node *node) · 5 unmodified lines
3030
3131 base = of_iomap(node, 0);
3232 if (!base) {
33− pr_err("%s: of_iomap failed\n", node->full_name);
33+ pr_err("%pOF: of_iomap failed\n", node);
3434 return;
3535 }
3636
@@ -39,13 +39,13 @@ static void __init moxart_of_pll_clk_init(struct device_node *node) · 2 unmodified lines
3939
4040 ref_clk = of_clk_get(node, 0);
4141 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);
4343 return;
4444 }
4545
4646 hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mul, 1);
4747 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);
4949 return;
5050 }
5151
@@ -57,7 +57,7 @@ CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock", · 5 unmodified lines
5757
5858 static void __init moxart_of_apb_clk_init(struct device_node *node)
5959 {
60− static void __iomem *base;
60+ void __iomem *base;
6161 struct clk_hw *hw;
6262 struct clk *pll_clk;
6363 unsigned int div, val;
@@ -70,7 +70,7 @@ static void __init moxart_of_apb_clk_init(struct device_node *node) · 6 unmodified lines
7070
7171 base = of_iomap(node, 0);
7272 if (!base) {
73− pr_err("%s: of_iomap failed\n", node->full_name);
73+ pr_err("%pOF: of_iomap failed\n", node);
7474 return;
7575 }
7676
@@ -83,13 +83,13 @@ static void __init moxart_of_apb_clk_init(struct device_node *node) · 6 unmodified lines
8383
8484 pll_clk = of_clk_get(node, 0);
8585 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);
8787 return;
8888 }
8989
9090 hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, 1, div);
9191 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);
9393 return;
9494 }
9595
drivers/clk/clk-qoriq.c+22−4
@@ -12,6 +12,7 @@ · 11 unmodified lines
1212
1313 #include <linux/clk.h>
1414 #include <linux/clk-provider.h>
15+#include <linux/clkdev.h>
1516 #include <linux/fsl/guts.h>
1617 #include <linux/io.h>
1718 #include <linux/kernel.h>
@@ -536,6 +537,17 @@ static const struct clockgen_chipinfo chipinfo[] = { · 518 unmodified lines
536537 .pll_mask = 0x07,
537538 .flags = CG_PLL_8BIT,
538539 },
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+ },
539551 {
540552 .compat = "fsl,ls1012a-clockgen",
541553 .cmux_groups = {
@@ -1113,6 +1125,7 @@ static void __init create_one_pll(struct clockgen *cg, int idx) · 571 unmodified lines
11131125
11141126 for (i = 0; i < ARRAY_SIZE(pll->div); i++) {
11151127 struct clk *clk;
1128+ int ret;
11161129
11171130 snprintf(pll->div[i].name, sizeof(pll->div[i].name),
11181131 "cg-pll%d-div%d", idx, i + 1);
@@ -1126,6 +1139,11 @@ static void __init create_one_pll(struct clockgen *cg, int idx) · 7 unmodified lines
11261139 }
11271140
11281141 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+
11291147 }
11301148 }
11311149
@@ -1348,8 +1366,7 @@ static void __init clockgen_init(struct device_node *np) · 216 unmodified lines
13481366 }
13491367
13501368 if (i == ARRAY_SIZE(chipinfo)) {
1351− pr_err("%s: unknown clockgen node %s\n", __func__,
1352− np->full_name);
1369+ pr_err("%s: unknown clockgen node %pOF\n", __func__, np);
13531370 goto err;
13541371 }
13551372 clockgen.info = chipinfo[i];
@@ -1362,8 +1379,8 @@ static void __init clockgen_init(struct device_node *np) · 6 unmodified lines
13621379 if (guts) {
13631380 clockgen.guts = of_iomap(guts, 0);
13641381 if (!clockgen.guts) {
1365− pr_err("%s: Couldn't map %s regs\n", __func__,
1366− guts->full_name);
1382+ pr_err("%s: Couldn't map %pOF regs\n", __func__,
1383+ guts);
13671384 }
13681385 }
13691386
@@ -1398,6 +1415,7 @@ CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init); · 28 unmodified lines
13981415 CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init);
13991416 CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init);
14001417 CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init);
1418+CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen", clockgen_init);
14011419 CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init);
14021420
14031421 /* Legacy nodes */
drivers/clk/clk-si5351.c+5−7
@@ -519,6 +519,11 @@ static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate, · 518 unmodified lines
519519 SI5351_CLK_INTEGER_MODE,
520520 (hwdata->params.p2 == 0) ? SI5351_CLK_INTEGER_MODE : 0);
521521
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+
522527 dev_dbg(&hwdata->drvdata->client->dev,
523528 "%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n",
524529 __func__, clk_hw_get_name(hw),
@@ -1091,13 +1096,6 @@ static int si5351_clkout_set_rate(struct clk_hw *hw, unsigned long rate, · 566 unmodified lines
10911096 si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
10921097 SI5351_CLK_POWERDOWN, 0);
10931098
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−
11011099 dev_dbg(&hwdata->drvdata->client->dev,
11021100 "%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
11031101 __func__, clk_hw_get_name(hw), (1 << rdiv),
drivers/clk/clk-stm32f4.c+2−2
@@ -1541,8 +1541,8 @@ static void __init stm32f4_rcc_init(struct device_node *np) · 1540 unmodified lines
15411541 base + gd->offset, gd->bit_idx, 0, &stm32f4_clk_lock);
15421542
15431543 if (IS_ERR(clks[idx])) {
1544− pr_err("%s: Unable to register leaf clock %s\n",
1545− np->full_name, gd->name);
1544+ pr_err("%pOF: Unable to register leaf clock %s\n",
1545+ np, gd->name);
15461546 goto fail;
15471547 }
15481548 }
drivers/clk/clk-stm32h7.c+1410−0
@@ -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+
63+static DEFINE_SPINLOCK(stm32rcc_lock);
64+
65+static void __iomem *base;
66+static struct clk_hw **hws;
67+
68+/* System clock parent */
69+static const char * const sys_src[] = {
70+ "hsi_ck", "csi_ck", "hse_ck", "pll1_p" };
71+
72+static const char * const tracein_src[] = {
73+ "hsi_ck", "csi_ck", "hse_ck", "pll1_r" };
74+
75+static const char * const per_src[] = {
76+ "hsi_ker", "csi_ker", "hse_ck", "disabled" };
77+
78+static const char * const pll_src[] = {
79+ "hsi_ck", "csi_ck", "hse_ck", "no clock" };
80+
81+static const char * const sdmmc_src[] = { "pll1_q", "pll2_r" };
82+
83+static const char * const dsi_src[] = { "ck_dsi_phy", "pll2_q" };
84+
85+static const char * const qspi_src[] = {
86+ "hclk", "pll1_q", "pll2_r", "per_ck" };
87+
88+static const char * const fmc_src[] = {
89+ "hclk", "pll1_q", "pll2_r", "per_ck" };
90+
91+/* Kernel clock parent */
92+static const char * const swp_src[] = { "pclk1", "hsi_ker" };
93+
94+static const char * const fdcan_src[] = { "hse_ck", "pll1_q", "pll2_q" };
95+
96+static const char * const dfsdm1_src[] = { "pclk2", "sys_ck" };
97+
98+static const char * const spdifrx_src[] = {
99+ "pll1_q", "pll2_r", "pll3_r", "hsi_ker" };
100+
101+static const char *spi_src1[5] = {
102+ "pll1_q", "pll2_p", "pll3_p", NULL, "per_ck" };
103+
104+static const char * const spi_src2[] = {
105+ "pclk2", "pll2_q", "pll3_q", "hsi_ker", "csi_ker", "hse_ck" };
106+
107+static const char * const spi_src3[] = {
108+ "pclk4", "pll2_q", "pll3_q", "hsi_ker", "csi_ker", "hse_ck" };
109+
110+static const char * const lptim_src1[] = {
111+ "pclk1", "pll2_p", "pll3_r", "lse_ck", "lsi_ck", "per_ck" };
112+
113+static const char * const lptim_src2[] = {
114+ "pclk4", "pll2_p", "pll3_r", "lse_ck", "lsi_ck", "per_ck" };
115+
116+static const char * const cec_src[] = {"lse_ck", "lsi_ck", "csi_ker_div122" };
117+
118+static const char * const usbotg_src[] = {"pll1_q", "pll3_q", "rc48_ck" };
119+
120+/* i2c 1,2,3 src */
121+static const char * const i2c_src1[] = {
122+ "pclk1", "pll3_r", "hsi_ker", "csi_ker" };
123+
124+static const char * const i2c_src2[] = {
125+ "pclk4", "pll3_r", "hsi_ker", "csi_ker" };
126+
127+static const char * const rng_src[] = {
128+ "rc48_ck", "pll1_q", "lse_ck", "lsi_ck" };
129+
130+/* usart 1,6 src */
131+static 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 */
135+static const char * const usart_src2[] = {
136+ "pclk1", "pll2_q", "pll3_q", "hsi_ker", "csi_ker", "lse_ck" };
137+
138+static const char *sai_src[5] = {
139+ "pll1_q", "pll2_p", "pll3_p", NULL, "per_ck" };
140+
141+static const char * const adc_src[] = { "pll2_p", "pll3_r", "per_ck" };
142+
143+/* lptim 2,3,4,5 src */
144+static const char * const lpuart1_src[] = {
145+ "pclk3", "pll2_q", "pll3_q", "csi_ker", "lse_ck" };
146+
147+static const char * const hrtim_src[] = { "tim2_ker", "d1cpre" };
148+
149+/* RTC clock parent */
150+static const char * const rtc_src[] = { "off", "lse_ck", "lsi_ck", "hse_1M" };
151+
152+/* Micro-controller output clock parent */
153+static const char * const mco_src1[] = {
154+ "hsi_ck", "lse_ck", "hse_ck", "pll1_q", "rc48_ck" };
155+
156+static const char * const mco_src2[] = {
157+ "sys_ck", "pll2_p", "hse_ck", "pll1_p", "csi_ck", "lsi_ck" };
158+
159+/* LCD clock */
160+static const char * const ltdc_src[] = {"pll3_r"};
161+
162+/* Gate clock with ready bit and backup domain management */
163+struct 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+
173+static 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+
201+static 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+
222+static 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+
228+static 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+
264+struct gate_cfg {
265+ u32 offset;
266+ u8 bit_idx;
267+};
268+
269+struct muxdiv_cfg {
270+ u32 offset;
271+ u8 shift;
272+ u8 width;
273+};
274+
275+struct 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+
285+struct 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+ */
293+struct 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+
308+static 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+
326+static 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+
345+static 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+
362+struct 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+
372+static 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 */
436+struct 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+
444+static 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+
468+static const struct clk_ops timer_ker_ops = {
469+ .recalc_rate = timer_ker_recalc_rate,
470+};
471+
472+static 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+
508+static 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+
517+static 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+
523+static 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 */
570+struct 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+
594+static 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 */
602+struct 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+
624+static 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 */
634+struct 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+
642+struct 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+
649+static 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+
657+static 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+
665+static 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+
673+static 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+
679+struct 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+
700+struct 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+
709+static 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+
719+static 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+
729+static 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+
739+static 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+
747+static 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+
756+static 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+
788+static 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+
795+static 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 */
855+static 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+
861+static 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+
867+static 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+
889+static 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+
895+static 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+
919+static 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+
940+static 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+
946+static 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)\
965+M_ODF_F(_name, _parent, _gate_offset, _bit_idx, _rate_offset,\
966+ _rate_shift, _rate_width, 0)\
967+
968+static 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 */
991+struct 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+
1011+static 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) \
1092+KER_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+
1107+static 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+
1162+static 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+
1177+static struct composite_clk_gcfg rtc_clk_cfg = {
1178+ M_CFG_MUX(NULL, 0),
1179+ M_CFG_GATE(NULL, 0),
1180+};
1181+
1182+static 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 */
1186+static 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+
1204+static 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+
1209+static 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+
1402+err_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+ */
1410+CLK_OF_DECLARE_DRIVER(stm32h7_rcc, "st,stm32h743-rcc", stm32h7_rcc_init);
drivers/clk/clk-versaclock5.c+159−13
@@ -57,6 +57,7 @@ · 56 unmodified lines
5757 #define VC5_PRIM_SRC_SHDN 0x10
5858 #define VC5_PRIM_SRC_SHDN_EN_XTAL BIT(7)
5959 #define VC5_PRIM_SRC_SHDN_EN_CLKIN BIT(6)
60+#define VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ BIT(3)
6061 #define VC5_PRIM_SRC_SHDN_SP BIT(1)
6162 #define VC5_PRIM_SRC_SHDN_EN_GBL_SHDN BIT(0)
6263
@@ -122,12 +123,16 @@ · 59 unmodified lines
122123 /* flags to describe chip features */
123124 /* chip has built-in oscilator */
124125 #define VC5_HAS_INTERNAL_XTAL BIT(0)
126+/* chip has PFD requency doubler */
127+#define VC5_HAS_PFD_FREQ_DBL BIT(1)
125128
126129 /* Supported IDT VC5 models. */
127130 enum vc5_model {
128131 IDT_VC5_5P49V5923,
132+ IDT_VC5_5P49V5925,
129133 IDT_VC5_5P49V5933,
130134 IDT_VC5_5P49V5935,
135+ IDT_VC6_5P49V6901,
131136 };
132137
133138 /* Structure to describe features of a particular VC5 model */
@@ -157,6 +162,8 @@ struct vc5_driver_data { · 23 unmodified lines
157162 struct clk *pin_clkin;
158163 unsigned char clk_mux_ins;
159164 struct clk_hw clk_mux;
165+ struct clk_hw clk_mul;
166+ struct clk_hw clk_pfd;
160167 struct vc5_hw_data clk_pll;
161168 struct vc5_hw_data clk_fod[VC5_MAX_FOD_NUM];
162169 struct vc5_hw_data clk_out[VC5_MAX_CLK_OUT_NUM];
@@ -166,6 +173,14 @@ static const char * const vc5_mux_names[] = { · 3 unmodified lines
166173 "mux"
167174 };
168175
176+static const char * const vc5_dbl_names[] = {
177+ "dbl"
178+};
179+
180+static const char * const vc5_pfd_names[] = {
181+ "pfd"
182+};
183+
169184 static const char * const vc5_pll_names[] = {
170185 "pll"
171186 };
@@ -254,11 +269,64 @@ static int vc5_mux_set_parent(struct clk_hw *hw, u8 index) · 82 unmodified lines
254269 return regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, mask, src);
255270 }
256271
257−static unsigned long vc5_mux_recalc_rate(struct clk_hw *hw,
272+static const struct clk_ops vc5_mux_ops = {
273+ .set_parent = vc5_mux_set_parent,
274+ .get_parent = vc5_mux_get_parent,
275+};
276+
277+static unsigned long vc5_dbl_recalc_rate(struct clk_hw *hw,
258278 unsigned long parent_rate)
259279 {
260280 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+
291+static 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+
300+static 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+
319+static 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+
325+static 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);
262330 unsigned int prediv, div;
263331
264332 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, · 11 unmodified lines
276344 return parent_rate / VC5_REF_DIVIDER_REF_DIV(div);
277345 }
278346
279−static long vc5_mux_round_rate(struct clk_hw *hw, unsigned long rate,
347+static long vc5_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
280348 unsigned long *parent_rate)
281349 {
282350 unsigned long idiv;
@@ -296,11 +364,11 @@ static long vc5_mux_round_rate(struct clk_hw *hw, unsigned long rate, · 13 unmodified lines
296364 return *parent_rate / idiv;
297365 }
298366
299−static int vc5_mux_set_rate(struct clk_hw *hw, unsigned long rate,
367+static int vc5_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
300368 unsigned long parent_rate)
301369 {
302370 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);
304372 unsigned long idiv;
305373 u8 div;
306374
@@ -328,12 +396,10 @@ static int vc5_mux_set_rate(struct clk_hw *hw, unsigned long rate, · 21 unmodified lines
328396 return 0;
329397 }
330398
331−static const struct clk_ops vc5_mux_ops = {
332− .set_parent = vc5_mux_set_parent,
333− .get_parent = vc5_mux_get_parent,
334− .recalc_rate = vc5_mux_recalc_rate,
335− .round_rate = vc5_mux_round_rate,
336− .set_rate = vc5_mux_set_rate,
399+static const struct clk_ops vc5_pfd_ops = {
400+ .recalc_rate = vc5_pfd_recalc_rate,
401+ .round_rate = vc5_pfd_round_rate,
402+ .set_rate = vc5_pfd_set_rate,
337403 };
338404
339405 /*
@@ -426,6 +492,10 @@ static unsigned long vc5_fod_recalc_rate(struct clk_hw *hw, · 86 unmodified lines
426492 div_frc = (od_frc[0] << 22) | (od_frc[1] << 14) |
427493 (od_frc[2] << 6) | (od_frc[3] >> 2);
428494
495+ /* Avoid division by zero if the output is not configured. */
496+ if (div_int == 0 && div_frc == 0)
497+ return 0;
498+
429499 /* The PLL divider has 12 integer bits and 30 fractional bits */
430500 return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc);
431501 }
@@ -503,6 +573,25 @@ static int vc5_clk_out_prepare(struct clk_hw *hw) · 71 unmodified lines
503573 {
504574 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
505575 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+ }
506595
507596 /* Enable the clock buffer */
508597 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) · 7 unmodified lines
516605 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
517606 struct vc5_driver_data *vc5 = hwdata->vc5;
518607
519− /* Enable the clock buffer */
608+ /* Disable the clock buffer */
520609 regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
521610 VC5_CLK_OUTPUT_CFG1_EN_CLKBUF, 0);
522611 }
@@ -537,6 +626,9 @@ static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw) · 14 unmodified lines
537626 regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src);
538627 src &= mask;
539628
629+ if (src == 0) /* Input mux set to DISABLED */
630+ return 0;
631+
540632 if ((src & fodclkmask) == VC5_OUT_DIV_CONTROL_EN_FOD)
541633 return 0;
542634
@@ -595,7 +687,9 @@ static int vc5_map_index_to_output(const enum vc5_model model, · 52 unmodified lines
595687 case IDT_VC5_5P49V5933:
596688 return (n == 0) ? 0 : 3;
597689 case IDT_VC5_5P49V5923:
690+ case IDT_VC5_5P49V5925:
598691 case IDT_VC5_5P49V5935:
692+ case IDT_VC6_5P49V6901:
599693 default:
600694 return n;
601695 }
@@ -672,12 +766,46 @@ static int vc5_probe(struct i2c_client *client, · 70 unmodified lines
672766 goto err_clk;
673767 }
674768
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+
675803 /* Register PLL */
676804 memset(&init, 0, sizeof(init));
677805 init.name = vc5_pll_names[0];
678806 init.ops = &vc5_pll_ops;
679807 init.flags = CLK_SET_RATE_PARENT;
680− init.parent_names = vc5_mux_names;
808+ init.parent_names = vc5_pfd_names;
681809 init.num_parents = 1;
682810 vc5->clk_pll.num = 0;
683811 vc5->clk_pll.vc5 = vc5;
@@ -785,6 +913,13 @@ static const struct vc5_chip_info idt_5p49v5923_info = { · 101 unmodified lines
785913 .flags = 0,
786914 };
787915
916+static 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+
788923 static const struct vc5_chip_info idt_5p49v5933_info = {
789924 .model = IDT_VC5_5P49V5933,
790925 .clk_fod_cnt = 2,
@@ -799,18 +934,29 @@ static const struct vc5_chip_info idt_5p49v5935_info = { · 8 unmodified lines
799934 .flags = VC5_HAS_INTERNAL_XTAL,
800935 };
801936
937+static 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+
802944 static const struct i2c_device_id vc5_id[] = {
803945 { "5p49v5923", .driver_data = IDT_VC5_5P49V5923 },
946+ { "5p49v5925", .driver_data = IDT_VC5_5P49V5925 },
804947 { "5p49v5933", .driver_data = IDT_VC5_5P49V5933 },
805948 { "5p49v5935", .driver_data = IDT_VC5_5P49V5935 },
949+ { "5p49v6901", .driver_data = IDT_VC6_5P49V6901 },
806950 { }
807951 };
808952 MODULE_DEVICE_TABLE(i2c, vc5_id);
809953
810954 static const struct of_device_id clk_vc5_of_match[] = {
811955 { .compatible = "idt,5p49v5923", .data = &idt_5p49v5923_info },
956+ { .compatible = "idt,5p49v5925", .data = &idt_5p49v5925_info },
812957 { .compatible = "idt,5p49v5933", .data = &idt_5p49v5933_info },
813958 { .compatible = "idt,5p49v5935", .data = &idt_5p49v5935_info },
959+ { .compatible = "idt,5p49v6901", .data = &idt_5p49v6901_info },
814960 { },
815961 };
816962 MODULE_DEVICE_TABLE(of, clk_vc5_of_match);
drivers/clk/clk-xgene.c+6−9
@@ -192,7 +192,7 @@ static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_ty · 191 unmodified lines
192192
193193 reg = of_iomap(np, 0);
194194 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);
196196 return;
197197 }
198198 of_property_read_string(np, "clock-output-names", &clk_name);
@@ -409,12 +409,12 @@ static void xgene_pmdclk_init(struct device_node *np) · 210 unmodified lines
409409 /* Parse the DTS register for resource */
410410 rc = of_address_to_resource(np, 0, &res);
411411 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);
413413 return;
414414 }
415415 csr_reg = of_iomap(np, 0);
416416 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);
418418 return;
419419 }
420420 of_property_read_string(np, "clock-output-names", &clk_name);
@@ -703,16 +703,14 @@ static void __init xgene_devclk_init(struct device_node *np) · 282 unmodified lines
703703 rc = of_address_to_resource(np, i, &res);
704704 if (rc != 0) {
705705 if (i == 0) {
706− pr_err("no DTS register for %s\n",
707− np->full_name);
706+ pr_err("no DTS register for %pOF\n", np);
708707 return;
709708 }
710709 break;
711710 }
712711 map_res = of_iomap(np, i);
713712 if (map_res == NULL) {
714− pr_err("Unable to map resource %d for %s\n",
715− i, np->full_name);
713+ pr_err("Unable to map resource %d for %pOF\n", i, np);
716714 goto err;
717715 }
718716 if (strcmp(res.name, "div-reg") == 0)
@@ -747,8 +745,7 @@ static void __init xgene_devclk_init(struct device_node *np) · 28 unmodified lines
747745 pr_debug("Add %s clock\n", clk_name);
748746 rc = of_clk_add_provider(np, of_clk_src_simple_get, clk);
749747 if (rc != 0)
750− pr_err("%s: could register provider clk %s\n", __func__,
751− np->full_name);
748+ pr_err("%s: could register provider clk %pOF\n", __func__, np);
752749
753750 return;
754751
drivers/clk/clk.c+2−2
@@ -3132,7 +3132,7 @@ int of_clk_add_provider(struct device_node *np, · 3131 unmodified lines
31323132 mutex_lock(&of_clk_mutex);
31333133 list_add(&cp->link, &of_clk_providers);
31343134 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);
31363136
31373137 ret = of_clk_set_defaults(np, true);
31383138 if (ret < 0)
@@ -3167,7 +3167,7 @@ int of_clk_add_hw_provider(struct device_node *np, · 28 unmodified lines
31673167 mutex_lock(&of_clk_mutex);
31683168 list_add(&cp->link, &of_clk_providers);
31693169 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);
31713171
31723172 ret = of_clk_set_defaults(np, true);
31733173 if (ret < 0)
drivers/clk/clkdev.c+2−2
@@ -77,8 +77,8 @@ static struct clk *__of_clk_get_by_name(struct device_node *np, · 76 unmodified lines
7777 break;
7878 } else if (name && index >= 0) {
7979 if (PTR_ERR(clk) != -EPROBE_DEFER)
80− pr_err("ERROR: could not get clock %s:%s(%i)\n",
81− np->full_name, name ? name : "", index);
80+ pr_err("ERROR: could not get clock %pOF:%s(%i)\n",
81+ np, name ? name : "", index);
8282 return clk;
8383 }
8484
drivers/clk/hisilicon/clk-hi6220.c+3−3
@@ -55,9 +55,9 @@ static struct hisi_fixed_factor_clock hi6220_fixed_factor_clks[] __initdata = { · 54 unmodified lines
5555 };
5656
5757 static 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, },
59− { HI6220_WDT1_PCLK, "wdt1_pclk", "clk_tcxo", 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, },
58+ { HI6220_WDT0_PCLK, "wdt0_pclk", "ref32k", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 12, 0, },
59+ { HI6220_WDT1_PCLK, "wdt1_pclk", "ref32k", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 13, 0, },
60+ { HI6220_WDT2_PCLK, "wdt2_pclk", "ref32k", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 14, 0, },
6161 { HI6220_TIMER0_PCLK, "timer0_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 15, 0, },
6262 { HI6220_TIMER1_PCLK, "timer1_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 16, 0, },
6363 { HI6220_TIMER2_PCLK, "timer2_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 17, 0, },
drivers/clk/imx/clk-imx51-imx53.c+4−4
@@ -416,10 +416,10 @@ static void __init mx51_clocks_init(struct device_node *np) · 415 unmodified lines
416416
417417 clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1,
418418 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,
420− mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel));
421− clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
422− mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel));
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), CLK_SET_RATE_PARENT);
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), CLK_SET_RATE_PARENT);
423423 clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
424424 mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT);
425425 clk[IMX5_CLK_TVE_SEL] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1,
drivers/clk/imx/clk-imx6sl.c+3−3
@@ -71,7 +71,7 @@ static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", }; · 70 unmodified lines
7171 static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
7272 static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
7373
74−static struct clk_div_table clk_enet_ref_table[] = {
74+static const struct clk_div_table clk_enet_ref_table[] = {
7575 { .val = 0, .div = 20, },
7676 { .val = 1, .div = 10, },
7777 { .val = 2, .div = 5, },
@@ -79,14 +79,14 @@ static struct clk_div_table clk_enet_ref_table[] = { · 1 unmodified line
7979 { }
8080 };
8181
82−static struct clk_div_table post_div_table[] = {
82+static const struct clk_div_table post_div_table[] = {
8383 { .val = 2, .div = 1, },
8484 { .val = 1, .div = 2, },
8585 { .val = 0, .div = 4, },
8686 { }
8787 };
8888
89−static struct clk_div_table video_div_table[] = {
89+static const struct clk_div_table video_div_table[] = {
9090 { .val = 0, .div = 1, },
9191 { .val = 1, .div = 2, },
9292 { .val = 2, .div = 1, },
drivers/clk/imx/clk-imx6sx.c+3−3
@@ -105,7 +105,7 @@ static int const clks_init_on[] __initconst = { · 104 unmodified lines
105105 IMX6SX_CLK_EPIT2,
106106 };
107107
108−static struct clk_div_table clk_enet_ref_table[] = {
108+static const struct clk_div_table clk_enet_ref_table[] = {
109109 { .val = 0, .div = 20, },
110110 { .val = 1, .div = 10, },
111111 { .val = 2, .div = 5, },
@@ -113,14 +113,14 @@ static struct clk_div_table clk_enet_ref_table[] = { · 1 unmodified line
113113 { }
114114 };
115115
116−static struct clk_div_table post_div_table[] = {
116+static const struct clk_div_table post_div_table[] = {
117117 { .val = 2, .div = 1, },
118118 { .val = 1, .div = 2, },
119119 { .val = 0, .div = 4, },
120120 { }
121121 };
122122
123−static struct clk_div_table video_div_table[] = {
123+static const struct clk_div_table video_div_table[] = {
124124 { .val = 0, .div = 1, },
125125 { .val = 1, .div = 2, },
126126 { .val = 2, .div = 1, },
drivers/clk/imx/clk-imx6ul.c+3−3
@@ -78,7 +78,7 @@ static int const clks_init_on[] __initconst = { · 77 unmodified lines
7878 IMX6UL_CLK_MMDC_P0_FAST, IMX6UL_CLK_MMDC_P0_IPG,
7979 };
8080
81−static struct clk_div_table clk_enet_ref_table[] = {
81+static const struct clk_div_table clk_enet_ref_table[] = {
8282 { .val = 0, .div = 20, },
8383 { .val = 1, .div = 10, },
8484 { .val = 2, .div = 5, },
@@ -86,14 +86,14 @@ static struct clk_div_table clk_enet_ref_table[] = { · 1 unmodified line
8686 { }
8787 };
8888
89−static struct clk_div_table post_div_table[] = {
89+static const struct clk_div_table post_div_table[] = {
9090 { .val = 2, .div = 1, },
9191 { .val = 1, .div = 2, },
9292 { .val = 0, .div = 4, },
9393 { }
9494 };
9595
96−static struct clk_div_table video_div_table[] = {
96+static const struct clk_div_table video_div_table[] = {
9797 { .val = 0, .div = 1, },
9898 { .val = 1, .div = 2, },
9999 { .val = 2, .div = 1, },
drivers/clk/imx/clk-imx7d.c+2−2
@@ -27,7 +27,7 @@ static u32 share_count_sai2; · 26 unmodified lines
2727 static u32 share_count_sai3;
2828 static u32 share_count_nand;
2929
30−static struct clk_div_table test_div_table[] = {
30+static const struct clk_div_table test_div_table[] = {
3131 { .val = 3, .div = 1, },
3232 { .val = 2, .div = 1, },
3333 { .val = 1, .div = 2, },
@@ -35,7 +35,7 @@ static struct clk_div_table test_div_table[] = { · 1 unmodified line
3535 { }
3636 };
3737
38−static struct clk_div_table post_div_table[] = {
38+static const struct clk_div_table post_div_table[] = {
3939 { .val = 3, .div = 4, },
4040 { .val = 2, .div = 1, },
4141 { .val = 1, .div = 2, },
drivers/clk/imx/clk-vf610.c+1−1
@@ -102,7 +102,7 @@ static const char *ftm_ext_sels[] = {"sirc_128k", "sxosc", "fxosc_half", "audio_ · 101 unmodified lines
102102 static const char *ftm_fix_sels[] = { "sxosc", "ipg_bus", };
103103
104104
105−static struct clk_div_table pll4_audio_div_table[] = {
105+static const struct clk_div_table pll4_audio_div_table[] = {
106106 { .val = 0, .div = 1 },
107107 { .val = 1, .div = 2 },
108108 { .val = 2, .div = 6 },
drivers/clk/mediatek/clk-cpumux.c+1−5
@@ -27,7 +27,6 @@ static inline struct mtk_clk_cpumux *to_mtk_clk_cpumux(struct clk_hw *_hw) · 26 unmodified lines
2727 static u8 clk_cpumux_get_parent(struct clk_hw *hw)
2828 {
2929 struct mtk_clk_cpumux *mux = to_mtk_clk_cpumux(hw);
30− int num_parents = clk_hw_get_num_parents(hw);
3130 unsigned int val;
3231
3332 regmap_read(mux->regmap, mux->reg, &val);
@@ -35,9 +34,6 @@ static u8 clk_cpumux_get_parent(struct clk_hw *hw) · 1 unmodified line
3534 val >>= mux->shift;
3635 val &= mux->mask;
3736
38− if (val >= num_parents)
39− return -EINVAL;
40−
4137 return val;
4238 }
4339
@@ -98,7 +94,7 @@ int __init mtk_clk_register_cpumuxes(struct device_node *node, · 54 unmodified lines
9894
9995 regmap = syscon_node_to_regmap(node);
10096 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,
10298 PTR_ERR(regmap));
10399 return PTR_ERR(regmap);
104100 }
drivers/clk/mediatek/clk-mtk.c+1−1
@@ -114,7 +114,7 @@ int mtk_clk_register_gates(struct device_node *node, · 113 unmodified lines
114114
115115 regmap = syscon_node_to_regmap(node);
116116 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,
118118 PTR_ERR(regmap));
119119 return PTR_ERR(regmap);
120120 }
drivers/clk/mediatek/reset.c+1−1
@@ -72,7 +72,7 @@ void mtk_register_reset_controller(struct device_node *np, · 71 unmodified lines
7272
7373 regmap = syscon_node_to_regmap(np);
7474 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,
7676 PTR_ERR(regmap));
7777 return;
7878 }
drivers/clk/meson/Kconfig+1−0
@@ -6,6 +6,7 @@ config COMMON_CLK_AMLOGIC · 5 unmodified lines
66 config COMMON_CLK_MESON8B
77 bool
88 depends on COMMON_CLK_AMLOGIC
9+ select RESET_CONTROLLER
910 help
1011 Support for the clock controller on AmLogic S802 (Meson8),
1112 S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you
drivers/clk/meson/Makefile+1−1
@@ -4,4 +4,4 @@ · 3 unmodified lines
44
55 obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o clk-audio-divider.o
66 obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o
7−obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
7+obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-regmap.o gxbb-aoclk-32k.o
drivers/clk/meson/gxbb-aoclk-32k.c+194−0
@@ -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+
44+struct 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+
54+static 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+ */
74+static 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+
110+static 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+
123+static 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+
141+static 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+
190+const 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+};
drivers/clk/meson/gxbb-aoclk-regmap.c+46−0
@@ -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+
13+static 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+
21+static 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+
29+static 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+
42+const 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+};
drivers/clk/meson/gxbb-aoclk.c+42−23
@@ -56,16 +56,20 @@ · 55 unmodified lines
5656 #include <linux/of_address.h>
5757 #include <linux/platform_device.h>
5858 #include <linux/reset-controller.h>
59+#include <linux/mfd/syscon.h>
60+#include <linux/regmap.h>
5961 #include <linux/init.h>
62+#include <linux/delay.h>
6063 #include <dt-bindings/clock/gxbb-aoclkc.h>
6164 #include <dt-bindings/reset/gxbb-aoclkc.h>
65+#include "gxbb-aoclk.h"
6266
6367 static DEFINE_SPINLOCK(gxbb_aoclk_lock);
6468
6569 struct gxbb_aoclk_reset_controller {
6670 struct reset_controller_dev reset;
6771 unsigned int *data;
68− void __iomem *base;
72+ struct regmap *regmap;
6973 };
7074
7175 static 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, · 2 unmodified lines
7478 struct gxbb_aoclk_reset_controller *reset =
7579 container_of(rcdev, struct gxbb_aoclk_reset_controller, reset);
7680
77− writel(BIT(reset->data[id]), reset->base);
78−
79− return 0;
81+ return regmap_write(reset->regmap, AO_RTI_GEN_CNTL_REG0,
82+ BIT(reset->data[id]));
8083 }
8184
8285 static const struct reset_control_ops gxbb_aoclk_reset_ops = {
@@ -84,13 +87,12 @@ static const struct reset_control_ops gxbb_aoclk_reset_ops = { · 1 unmodified line
8487 };
8588
8689 #define GXBB_AO_GATE(_name, _bit) \
87−static struct clk_gate _name##_ao = { \
88− .reg = (void __iomem *)0, \
90+static struct aoclk_gate_regmap _name##_ao = { \
8991 .bit_idx = (_bit), \
9092 .lock = &gxbb_aoclk_lock, \
9193 .hw.init = &(struct clk_init_data) { \
9294 .name = #_name "_ao", \
93− .ops = &clk_gate_ops, \
95+ .ops = &meson_aoclk_gate_regmap_ops, \
9496 .parent_names = (const char *[]){ "clk81" }, \
9597 .num_parents = 1, \
9698 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
@@ -104,6 +106,17 @@ GXBB_AO_GATE(uart1, 3); · 7 unmodified lines
104106 GXBB_AO_GATE(uart2, 5);
105107 GXBB_AO_GATE(ir_blaster, 6);
106108
109+static 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+
107120 static unsigned int gxbb_aoclk_reset[] = {
108121 [RESET_AO_REMOTE] = 16,
109122 [RESET_AO_I2C_MASTER] = 18,
@@ -113,7 +126,7 @@ static unsigned int gxbb_aoclk_reset[] = { · 3 unmodified lines
113126 [RESET_AO_IR_BLASTER] = 23,
114127 };
115128
116−static struct clk_gate *gxbb_aoclk_gate[] = {
129+static struct aoclk_gate_regmap *gxbb_aoclk_gate[] = {
117130 [CLKID_AO_REMOTE] = &remote_ao,
118131 [CLKID_AO_I2C_MASTER] = &i2c_master_ao,
119132 [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao,
@@ -130,30 +143,30 @@ static struct clk_hw_onecell_data gxbb_aoclk_onecell_data = { · 10 unmodified lines
130143 [CLKID_AO_UART1] = &uart1_ao.hw,
131144 [CLKID_AO_UART2] = &uart2_ao.hw,
132145 [CLKID_AO_IR_BLASTER] = &ir_blaster_ao.hw,
146+ [CLKID_AO_CEC_32K] = &cec_32k_ao.hw,
133147 },
134− .num = ARRAY_SIZE(gxbb_aoclk_gate),
148+ .num = 7,
135149 };
136150
137151 static int gxbb_aoclkc_probe(struct platform_device *pdev)
138152 {
139− struct resource *res;
140− void __iomem *base;
141− int ret, clkid;
142− struct device *dev = &pdev->dev;
143153 struct gxbb_aoclk_reset_controller *rstc;
154+ struct device *dev = &pdev->dev;
155+ struct regmap *regmap;
156+ int ret, clkid;
144157
145158 rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL);
146159 if (!rstc)
147160 return -ENOMEM;
148161
149− /* Generic clocks */
150− res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
151− base = devm_ioremap_resource(dev, res);
152− if (IS_ERR(base))
153− return PTR_ERR(base);
162+ regmap = syscon_node_to_regmap(of_get_parent(dev->of_node));
163+ if (IS_ERR(regmap)) {
164+ dev_err(dev, "failed to get regmap\n");
165+ return -ENODEV;
166+ }
154167
155168 /* Reset Controller */
156− rstc->base = base;
169+ rstc->regmap = regmap;
157170 rstc->data = gxbb_aoclk_reset;
158171 rstc->reset.ops = &gxbb_aoclk_reset_ops;
159172 rstc->reset.nr_resets = ARRAY_SIZE(gxbb_aoclk_reset);
@@ -161,10 +174,10 @@ static int gxbb_aoclkc_probe(struct platform_device *pdev) · 1 unmodified line
161174 ret = devm_reset_controller_register(dev, &rstc->reset);
162175
163176 /*
164− * Populate base address and register all clks
177+ * Populate regmap and register all clks
165178 */
166− for (clkid = 0; clkid < gxbb_aoclk_onecell_data.num; clkid++) {
167− gxbb_aoclk_gate[clkid]->reg = base;
179+ for (clkid = 0; clkid < ARRAY_SIZE(gxbb_aoclk_gate); clkid++) {
180+ gxbb_aoclk_gate[clkid]->regmap = regmap;
168181
169182 ret = devm_clk_hw_register(dev,
170183 gxbb_aoclk_onecell_data.hws[clkid]);
@@ -172,12 +185,18 @@ static int gxbb_aoclkc_probe(struct platform_device *pdev) · 1 unmodified line
172185 return ret;
173186 }
174187
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+
175194 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
176195 &gxbb_aoclk_onecell_data);
177196 }
178197
179198 static const struct of_device_id gxbb_aoclkc_match_table[] = {
180− { .compatible = "amlogic,gxbb-aoclkc" },
199+ { .compatible = "amlogic,meson-gx-aoclkc" },
181200 { }
182201 };
183202
drivers/clk/meson/gxbb-aoclk.h+42−0
@@ -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+
20+struct 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+
30+extern const struct clk_ops meson_aoclk_gate_regmap_ops;
31+
32+struct 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+
40+extern const struct clk_ops meson_aoclk_cec_32k_ops;
41+
42+#endif /* __GXBB_AOCLKC_H */
drivers/clk/meson/gxbb.c+183−4
@@ -850,13 +850,14 @@ static struct meson_clk_audio_divider gxbb_cts_amclk_div = { · 849 unmodified lines
850850 .shift = 0,
851851 .width = 8,
852852 },
853+ .flags = CLK_DIVIDER_ROUND_CLOSEST,
853854 .lock = &clk_lock,
854855 .hw.init = &(struct clk_init_data){
855856 .name = "cts_amclk_div",
856857 .ops = &meson_clk_audio_divider_ops,
857858 .parent_names = (const char *[]){ "cts_amclk_sel" },
858859 .num_parents = 1,
859− .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST,
860+ .flags = CLK_SET_RATE_PARENT,
860861 },
861862 };
862863
@@ -880,7 +881,7 @@ static struct clk_mux gxbb_cts_mclk_i958_sel = { · 17 unmodified lines
880881 /* Default parent unknown (register reset value: 0) */
881882 .table = (u32[]){ 1, 2, 3 },
882883 .lock = &clk_lock,
883− .hw.init = &(struct clk_init_data){
884+ .hw.init = &(struct clk_init_data) {
884885 .name = "cts_mclk_i958_sel",
885886 .ops = &clk_mux_ops,
886887 .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" },
@@ -894,12 +895,13 @@ static struct clk_divider gxbb_cts_mclk_i958_div = { · 7 unmodified lines
894895 .shift = 16,
895896 .width = 8,
896897 .lock = &clk_lock,
897− .hw.init = &(struct clk_init_data){
898+ .flags = CLK_DIVIDER_ROUND_CLOSEST,
899+ .hw.init = &(struct clk_init_data) {
898900 .name = "cts_mclk_i958_div",
899901 .ops = &clk_divider_ops,
900902 .parent_names = (const char *[]){ "cts_mclk_i958_sel" },
901903 .num_parents = 1,
902− .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST,
904+ .flags = CLK_SET_RATE_PARENT,
903905 },
904906 };
905907
@@ -979,6 +981,156 @@ static struct clk_mux gxbb_32k_clk_sel = { · 73 unmodified lines
979981 },
980982 };
981983
984+static 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 */
996+static 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+
1010+static 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+
1025+static 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 */
1049+static 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+
1063+static 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+
1078+static 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 */
1092+static 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+
1106+static 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+
1121+static 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+
9821134 /* Everything Else (EE) domain gates */
9831135 static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0);
9841136 static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1);
@@ -1188,6 +1340,15 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = { · 203 unmodified lines
11881340 [CLKID_32K_CLK] = &gxbb_32k_clk.hw,
11891341 [CLKID_32K_CLK_SEL] = &gxbb_32k_clk_sel.hw,
11901342 [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,
11911352 [NR_CLKS] = NULL,
11921353 },
11931354 .num = NR_CLKS,
@@ -1311,6 +1472,15 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { · 117 unmodified lines
13111472 [CLKID_32K_CLK] = &gxbb_32k_clk.hw,
13121473 [CLKID_32K_CLK_SEL] = &gxbb_32k_clk_sel.hw,
13131474 [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,
13141484 [NR_CLKS] = NULL,
13151485 },
13161486 .num = NR_CLKS,
@@ -1427,6 +1597,9 @@ static struct clk_gate *const gxbb_clk_gates[] = { · 110 unmodified lines
14271597 &gxbb_cts_amclk,
14281598 &gxbb_cts_mclk_i958,
14291599 &gxbb_32k_clk,
1600+ &gxbb_sd_emmc_a_clk0,
1601+ &gxbb_sd_emmc_b_clk0,
1602+ &gxbb_sd_emmc_c_clk0,
14301603 };
14311604
14321605 static struct clk_mux *const gxbb_clk_muxes[] = {
@@ -1439,6 +1612,9 @@ static struct clk_mux *const gxbb_clk_muxes[] = { · 6 unmodified lines
14391612 &gxbb_cts_mclk_i958_sel,
14401613 &gxbb_cts_i958,
14411614 &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,
14421618 };
14431619
14441620 static struct clk_divider *const gxbb_clk_dividers[] = {
@@ -1448,6 +1624,9 @@ static struct clk_divider *const gxbb_clk_dividers[] = { · 3 unmodified lines
14481624 &gxbb_mali_1_div,
14491625 &gxbb_cts_mclk_i958_div,
14501626 &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,
14511630 };
14521631
14531632 static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = {
drivers/clk/meson/meson8b.c+147−12
@@ -25,6 +25,8 @@ · 24 unmodified lines
2525 #include <linux/clk-provider.h>
2626 #include <linux/of_address.h>
2727 #include <linux/platform_device.h>
28+#include <linux/reset-controller.h>
29+#include <linux/slab.h>
2830 #include <linux/init.h>
2931
3032 #include "clkc.h"
@@ -32,6 +34,13 @@ · 1 unmodified line
3234
3335 static DEFINE_SPINLOCK(clk_lock);
3436
37+static void __iomem *clk_base;
38+
39+struct meson8b_clk_reset {
40+ struct reset_controller_dev reset;
41+ void __iomem *base;
42+};
43+
3544 static const struct pll_rate_table sys_pll_rate_table[] = {
3645 PLL_RATE(312000000, 52, 1, 2),
3746 PLL_RATE(336000000, 56, 1, 2),
@@ -696,20 +705,114 @@ static struct clk_divider *const meson8b_clk_dividers[] = { · 658 unmodified lines
696705 &meson8b_mpeg_clk_div,
697706 };
698707
708+static 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+
762+static 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+
790+static 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+
796+static 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+
802+static const struct reset_control_ops meson8b_clk_reset_ops = {
803+ .assert = meson8b_clk_reset_assert,
804+ .deassert = meson8b_clk_reset_deassert,
805+};
806+
699807 static int meson8b_clkc_probe(struct platform_device *pdev)
700808 {
701− void __iomem *clk_base;
702809 int ret, clkid, i;
703810 struct clk_hw *parent_hw;
704811 struct clk *parent_clk;
705812 struct device *dev = &pdev->dev;
706813
707− /* Generic clocks and PLLs */
708− clk_base = of_iomap(dev->of_node, 1);
709− if (!clk_base) {
710− pr_err("%s: Unable to map clk base\n", __func__);
814+ if (!clk_base)
711815 return -ENXIO;
712− }
713816
714817 /* Populate base address for PLLs */
715818 for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
@@ -749,7 +852,7 @@ static int meson8b_clkc_probe(struct platform_device *pdev) · 33 unmodified lines
749852 /* FIXME convert to devm_clk_register */
750853 ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[clkid]);
751854 if (ret)
752− goto iounmap;
855+ return ret;
753856 }
754857
755858 /*
@@ -772,15 +875,11 @@ static int meson8b_clkc_probe(struct platform_device *pdev) · 16 unmodified lines
772875 if (ret) {
773876 pr_err("%s: failed to register clock notifier for cpu_clk\n",
774877 __func__);
775− goto iounmap;
878+ return ret;
776879 }
777880
778881 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
779882 &meson8b_hw_onecell_data);
780−
781−iounmap:
782− iounmap(clk_base);
783− return ret;
784883 }
785884
786885 static const struct of_device_id meson8b_clkc_match_table[] = {
@@ -799,3 +898,39 @@ static struct platform_driver meson8b_driver = { · 12 unmodified lines
799898 };
800899
801900 builtin_platform_driver(meson8b_driver);
901+
902+static 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+
931+CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc",
932+ meson8b_clkc_reset_init);
933+CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc",
934+ meson8b_clkc_reset_init);
935+CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc",
936+ meson8b_clkc_reset_init);
drivers/clk/meson/meson8b.h+8−1
@@ -37,6 +37,9 @@ · 36 unmodified lines
3737 #define HHI_GCLK_AO 0x154 /* 0x55 offset in data sheet */
3838 #define HHI_SYS_CPU_CLK_CNTL1 0x15c /* 0x57 offset in data sheet */
3939 #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 */
4043 #define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */
4144 #define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */
4245 #define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
@@ -68,7 +71,11 @@ · 25 unmodified lines
6871
6972 #define CLK_NR_CLKS 96
7073
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+ */
7278 #include <dt-bindings/clock/meson8b-clkc.h>
79+#include <dt-bindings/reset/amlogic,meson8b-clkc-reset.h>
7380
7481 #endif /* __MESON8B_H */
drivers/clk/mmp/clk.c+1−1
@@ -9,7 +9,7 @@ · 8 unmodified lines
99 void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
1010 int nr_clks)
1111 {
12− static struct clk **clk_table;
12+ struct clk **clk_table;
1313
1414 clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
1515 if (!clk_table)
drivers/clk/nxp/clk-lpc32xx.c+6−6
@@ -885,7 +885,7 @@ static const struct clk_ops clk_usb_i2c_ops = { · 884 unmodified lines
885885 .recalc_rate = clk_usb_i2c_recalc_rate,
886886 };
887887
888−static int clk_gate_enable(struct clk_hw *hw)
888+static int lpc32xx_clk_gate_enable(struct clk_hw *hw)
889889 {
890890 struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw);
891891 u32 mask = BIT(clk->bit_idx);
@@ -894,7 +894,7 @@ static int clk_gate_enable(struct clk_hw *hw) · 2 unmodified lines
894894 return regmap_update_bits(clk_regmap, clk->reg, mask, val);
895895 }
896896
897−static void clk_gate_disable(struct clk_hw *hw)
897+static void lpc32xx_clk_gate_disable(struct clk_hw *hw)
898898 {
899899 struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw);
900900 u32 mask = BIT(clk->bit_idx);
@@ -903,7 +903,7 @@ static void clk_gate_disable(struct clk_hw *hw) · 2 unmodified lines
903903 regmap_update_bits(clk_regmap, clk->reg, mask, val);
904904 }
905905
906−static int clk_gate_is_enabled(struct clk_hw *hw)
906+static int lpc32xx_clk_gate_is_enabled(struct clk_hw *hw)
907907 {
908908 struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw);
909909 u32 val;
@@ -916,9 +916,9 @@ static int clk_gate_is_enabled(struct clk_hw *hw) · 6 unmodified lines
916916 }
917917
918918 static const struct clk_ops lpc32xx_clk_gate_ops = {
919− .enable = clk_gate_enable,
920− .disable = clk_gate_disable,
921− .is_enabled = clk_gate_is_enabled,
919+ .enable = lpc32xx_clk_gate_enable,
920+ .disable = lpc32xx_clk_gate_disable,
921+ .is_enabled = lpc32xx_clk_gate_is_enabled,
922922 };
923923
924924 #define div_mask(width) ((1 << (width)) - 1)
drivers/clk/qcom/clk-smd-rpm.c+0−2
@@ -412,8 +412,6 @@ static const struct clk_ops clk_smd_rpm_ops = { · 411 unmodified lines
412412 static const struct clk_ops clk_smd_rpm_branch_ops = {
413413 .prepare = clk_smd_rpm_prepare,
414414 .unprepare = clk_smd_rpm_unprepare,
415− .round_rate = clk_smd_rpm_round_rate,
416− .recalc_rate = clk_smd_rpm_recalc_rate,
417415 };
418416
419417 /* msm8916 */
drivers/clk/qcom/gcc-msm8916.c+1−1
@@ -1176,7 +1176,7 @@ static struct clk_rcg2 bimc_gpu_clk_src = { · 1175 unmodified lines
11761176 .parent_names = gcc_xo_gpll0_bimc,
11771177 .num_parents = 3,
11781178 .flags = CLK_GET_RATE_NOCACHE,
1179− .ops = &clk_rcg2_shared_ops,
1179+ .ops = &clk_rcg2_ops,
11801180 },
11811181 };
11821182
drivers/clk/qcom/gcc-msm8996.c+28−0
@@ -2730,6 +2730,32 @@ static struct clk_fixed_factor ufs_rx_cfg_clk_src = { · 2729 unmodified lines
27302730 },
27312731 };
27322732
2733+static 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+
2746+static 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+
27332759 static struct clk_branch gcc_ufs_rx_cfg_clk = {
27342760 .halt_reg = 0x75014,
27352761 .clkr = {
@@ -3307,6 +3333,8 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { · 571 unmodified lines
33073333 [GCC_UFS_AHB_CLK] = &gcc_ufs_ahb_clk.clkr,
33083334 [GCC_UFS_TX_CFG_CLK] = &gcc_ufs_tx_cfg_clk.clkr,
33093335 [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,
33103338 [GCC_UFS_TX_SYMBOL_0_CLK] = &gcc_ufs_tx_symbol_0_clk.clkr,
33113339 [GCC_UFS_RX_SYMBOL_0_CLK] = &gcc_ufs_rx_symbol_0_clk.clkr,
33123340 [GCC_UFS_RX_SYMBOL_1_CLK] = &gcc_ufs_rx_symbol_1_clk.clkr,
drivers/clk/renesas/Kconfig+29−19
@@ -15,6 +15,7 @@ config CLK_RENESAS · 14 unmodified lines
1515 select CLK_R8A7794 if ARCH_R8A7794
1616 select CLK_R8A7795 if ARCH_R8A7795
1717 select CLK_R8A7796 if ARCH_R8A7796
18+ select CLK_R8A77995 if ARCH_R8A77995
1819 select CLK_SH73A0 if ARCH_SH73A0
1920
2021 if CLK_RENESAS
@@ -34,94 +35,103 @@ config CLK_EMEV2 · 13 unmodified lines
3435 bool "Emma Mobile EV2 clock support" if COMPILE_TEST
3536
3637 config CLK_RZA1
37− bool
38+ bool "RZ/A1H clock support" if COMPILE_TEST
3839 select CLK_RENESAS_CPG_MSTP
3940
4041 config CLK_R8A73A4
41− bool
42+ bool "R-Mobile APE6 clock support" if COMPILE_TEST
4243 select CLK_RENESAS_CPG_MSTP
4344 select CLK_RENESAS_DIV6
4445
4546 config CLK_R8A7740
46− bool
47+ bool "R-Mobile A1 clock support" if COMPILE_TEST
4748 select CLK_RENESAS_CPG_MSTP
4849 select CLK_RENESAS_DIV6
4950
5051 config CLK_R8A7743
51− bool
52+ bool "RZ/G1M clock support" if COMPILE_TEST
5253 select CLK_RCAR_GEN2_CPG
5354
5455 config CLK_R8A7745
55− bool
56+ bool "RZ/G1E clock support" if COMPILE_TEST
5657 select CLK_RCAR_GEN2_CPG
5758
5859 config CLK_R8A7778
59− bool
60+ bool "R-Car M1A clock support" if COMPILE_TEST
6061 select CLK_RENESAS_CPG_MSTP
6162
6263 config CLK_R8A7779
63− bool
64+ bool "R-Car H1 clock support" if COMPILE_TEST
6465 select CLK_RENESAS_CPG_MSTP
6566
6667 config CLK_R8A7790
67− bool
68+ bool "R-Car H2 clock support" if COMPILE_TEST
6869 select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY
6970 select CLK_RCAR_GEN2_CPG
7071 select CLK_RENESAS_DIV6
7172
7273 config CLK_R8A7791
73− bool
74+ bool "R-Car M2-W/N clock support" if COMPILE_TEST
7475 select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY
7576 select CLK_RCAR_GEN2_CPG
7677 select CLK_RENESAS_DIV6
7778
7879 config CLK_R8A7792
79− bool
80+ bool "R-Car V2H clock support" if COMPILE_TEST
8081 select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY
8182 select CLK_RCAR_GEN2_CPG
8283
8384 config CLK_R8A7794
84− bool
85+ bool "R-Car E2 clock support" if COMPILE_TEST
8586 select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY
8687 select CLK_RCAR_GEN2_CPG
8788 select CLK_RENESAS_DIV6
8889
8990 config CLK_R8A7795
90− bool
91+ bool "R-Car H3 clock support" if COMPILE_TEST
9192 select CLK_RCAR_GEN3_CPG
9293
9394 config CLK_R8A7796
94− bool
95+ bool "R-Car M3-W clock support" if COMPILE_TEST
96+ select CLK_RCAR_GEN3_CPG
97+
98+config CLK_R8A77995
99+ bool "R-Car D3 clock support" if COMPILE_TEST
95100 select CLK_RCAR_GEN3_CPG
96101
97102 config CLK_SH73A0
98− bool
103+ bool "SH-Mobile AG5 clock support" if COMPILE_TEST
99104 select CLK_RENESAS_CPG_MSTP
100105 select CLK_RENESAS_DIV6
101106
102107
103108 # Family
104109 config CLK_RCAR_GEN2
105− bool
110+ bool "R-Car Gen2 legacy clock support" if COMPILE_TEST
106111 select CLK_RENESAS_CPG_MSTP
107112 select CLK_RENESAS_DIV6
108113
109114 config CLK_RCAR_GEN2_CPG
110− bool
115+ bool "R-Car Gen2 CPG clock support" if COMPILE_TEST
111116 select CLK_RENESAS_CPG_MSSR
112117
113118 config CLK_RCAR_GEN3_CPG
114− bool
119+ bool "R-Car Gen3 CPG clock support" if COMPILE_TEST
115120 select CLK_RENESAS_CPG_MSSR
116121
122+config 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
117127
118128 # Generic
119129 config CLK_RENESAS_CPG_MSSR
120− bool
130+ bool "CPG/MSSR clock support" if COMPILE_TEST
121131 select CLK_RENESAS_DIV6
122132
123133 config CLK_RENESAS_CPG_MSTP
124− bool
134+ bool "MSTP clock support" if COMPILE_TEST
125135
126136 config CLK_RENESAS_DIV6
127137 bool "DIV6 clock support" if COMPILE_TEST
drivers/clk/renesas/Makefile+2−0
@@ -13,12 +13,14 @@ obj-$(CONFIG_CLK_R8A7792) += r8a7792-cpg-mssr.o · 12 unmodified lines
1313 obj-$(CONFIG_CLK_R8A7794) += r8a7794-cpg-mssr.o
1414 obj-$(CONFIG_CLK_R8A7795) += r8a7795-cpg-mssr.o
1515 obj-$(CONFIG_CLK_R8A7796) += r8a7796-cpg-mssr.o
16+obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o
1617 obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o
1718
1819 # Family
1920 obj-$(CONFIG_CLK_RCAR_GEN2) += clk-rcar-gen2.o
2021 obj-$(CONFIG_CLK_RCAR_GEN2_CPG) += rcar-gen2-cpg.o
2122 obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o
23+obj-$(CONFIG_CLK_RCAR_USB2_CLOCK_SEL) += rcar-usb2-clock-sel.o
2224
2325 # Generic
2426 obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o
drivers/clk/renesas/clk-div6.c+3−0
@@ -29,6 +29,9 @@ · 28 unmodified lines
2929 * @hw: handle between common and hardware-specific interfaces
3030 * @reg: IO-remapped register
3131 * @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
3235 */
3336 struct div6_clock {
3437 struct clk_hw hw;
drivers/clk/renesas/clk-mstp.c+1−1
@@ -335,7 +335,7 @@ void __init cpg_mstp_add_clk_domain(struct device_node *np) · 334 unmodified lines
335335 u32 ncells;
336336
337337 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);
339339 return;
340340 }
341341
drivers/clk/renesas/clk-rcar-gen2.c+1−2
@@ -407,8 +407,7 @@ static void __init rcar_gen2_cpg_clocks_init(struct device_node *np) · 406 unmodified lines
407407
408408 if (rcar_rst_read_mode_pins(&cpg_mode)) {
409409 /* Backward-compatibility with old DT */
410− pr_warn("%s: failed to obtain mode pins from RST\n",
411− np->full_name);
410+ pr_warn("%pOF: failed to obtain mode pins from RST\n", np);
412411 cpg_mode = rcar_gen2_read_mode_pins();
413412 }
414413
drivers/clk/renesas/r8a7792-cpg-mssr.c+7−0
@@ -118,6 +118,13 @@ static const struct mssr_mod_clk r8a7792_mod_clks[] __initconst = { · 117 unmodified lines
118118 DEF_MOD("vin1", 810, R8A7792_CLK_ZG),
119119 DEF_MOD("vin0", 811, R8A7792_CLK_ZG),
120120 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),
121128 DEF_MOD("gyro-adc", 901, R8A7792_CLK_P),
122129 DEF_MOD("gpio7", 904, R8A7792_CLK_CP),
123130 DEF_MOD("gpio6", 905, R8A7792_CLK_CP),
drivers/clk/renesas/r8a7795-cpg-mssr.c+17−17
@@ -305,23 +305,23 @@ static const unsigned int r8a7795_crit_mod_clks[] __initconst = { · 304 unmodified lines
305305 (((md) & BIT(17)) >> 17))
306306
307307 static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = {
308− /* EXTAL div PLL1 mult PLL3 mult */
309− { 1, 192, 192, },
310− { 1, 192, 128, },
311− { 0, /* Prohibited setting */ },
312− { 1, 192, 192, },
313− { 1, 160, 160, },
314− { 1, 160, 106, },
315− { 0, /* Prohibited setting */ },
316− { 1, 160, 160, },
317− { 1, 128, 128, },
318− { 1, 128, 84, },
319− { 0, /* Prohibited setting */ },
320− { 1, 128, 128, },
321− { 2, 192, 192, },
322− { 2, 192, 128, },
323− { 0, /* Prohibited setting */ },
324− { 2, 192, 192, },
308+ /* EXTAL div PLL1 mult/div PLL3 mult/div */
309+ { 1, 192, 1, 192, 1, },
310+ { 1, 192, 1, 128, 1, },
311+ { 0, /* Prohibited setting */ },
312+ { 1, 192, 1, 192, 1, },
313+ { 1, 160, 1, 160, 1, },
314+ { 1, 160, 1, 106, 1, },
315+ { 0, /* Prohibited setting */ },
316+ { 1, 160, 1, 160, 1, },
317+ { 1, 128, 1, 128, 1, },
318+ { 1, 128, 1, 84, 1, },
319+ { 0, /* Prohibited setting */ },
320+ { 1, 128, 1, 128, 1, },
321+ { 2, 192, 1, 192, 1, },
322+ { 2, 192, 1, 128, 1, },
323+ { 0, /* Prohibited setting */ },
324+ { 2, 192, 1, 192, 1, },
325325 };
326326
327327 static const struct soc_device_attribute r8a7795es1[] __initconst = {
drivers/clk/renesas/r8a7796-cpg-mssr.c+18−17
@@ -138,6 +138,7 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = { · 137 unmodified lines
138138 DEF_MOD("sdif0", 314, R8A7796_CLK_SD0),
139139 DEF_MOD("pcie1", 318, R8A7796_CLK_S3D1),
140140 DEF_MOD("pcie0", 319, R8A7796_CLK_S3D1),
141+ DEF_MOD("usb3-if0", 328, R8A7796_CLK_S3D1),
141142 DEF_MOD("usb-dmac0", 330, R8A7796_CLK_S3D1),
142143 DEF_MOD("usb-dmac1", 331, R8A7796_CLK_S3D1),
143144 DEF_MOD("rwdt", 402, R8A7796_CLK_R),
@@ -277,23 +278,23 @@ static const unsigned int r8a7796_crit_mod_clks[] __initconst = { · 133 unmodified lines
277278 (((md) & BIT(17)) >> 17))
278279
279280 static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = {
280− /* EXTAL div PLL1 mult PLL3 mult */
281− { 1, 192, 192, },
282− { 1, 192, 128, },
283− { 0, /* Prohibited setting */ },
284− { 1, 192, 192, },
285− { 1, 160, 160, },
286− { 1, 160, 106, },
287− { 0, /* Prohibited setting */ },
288− { 1, 160, 160, },
289− { 1, 128, 128, },
290− { 1, 128, 84, },
291− { 0, /* Prohibited setting */ },
292− { 1, 128, 128, },
293− { 2, 192, 192, },
294− { 2, 192, 128, },
295− { 0, /* Prohibited setting */ },
296− { 2, 192, 192, },
281+ /* EXTAL div PLL1 mult/div PLL3 mult/div */
282+ { 1, 192, 1, 192, 1, },
283+ { 1, 192, 1, 128, 1, },
284+ { 0, /* Prohibited setting */ },
285+ { 1, 192, 1, 192, 1, },
286+ { 1, 160, 1, 160, 1, },
287+ { 1, 160, 1, 106, 1, },
288+ { 0, /* Prohibited setting */ },
289+ { 1, 160, 1, 160, 1, },
290+ { 1, 128, 1, 128, 1, },
291+ { 1, 128, 1, 84, 1, },
292+ { 0, /* Prohibited setting */ },
293+ { 1, 128, 1, 128, 1, },
294+ { 2, 192, 1, 192, 1, },
295+ { 2, 192, 1, 128, 1, },
296+ { 0, /* Prohibited setting */ },
297+ { 2, 192, 1, 192, 1, },
297298 };
298299
299300 static int __init r8a7796_cpg_mssr_init(struct device *dev)
drivers/clk/renesas/r8a77995-cpg-mssr.c+236−0
@@ -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+
26+enum 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+
54+static 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+
107+static 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+
179+static 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+
196+static 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+
202+static 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+
217+const 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+};
drivers/clk/renesas/rcar-gen3-cpg.c+41−28
@@ -60,6 +60,7 @@ struct sd_clock { · 59 unmodified lines
6060 unsigned int div_num;
6161 unsigned int div_min;
6262 unsigned int div_max;
63+ unsigned int cur_div_idx;
6364 };
6465
6566 /* SDn divider
@@ -96,21 +97,10 @@ static const struct sd_div_table cpg_sd_div_table[] = { · 30 unmodified lines
9697 static int cpg_sd_clock_enable(struct clk_hw *hw)
9798 {
9899 struct sd_clock *clock = to_sd_clock(hw);
99− u32 val, sd_fc;
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;
100+ u32 val = readl(clock->reg);
111101
112102 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;
114104
115105 writel(val, clock->reg);
116106
@@ -135,21 +125,9 @@ static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, · 18 unmodified lines
135125 unsigned long parent_rate)
136126 {
137127 struct sd_clock *clock = to_sd_clock(hw);
138− unsigned long rate = parent_rate;
139− u32 val, sd_fc;
140− unsigned int i;
141128
142− val = readl(clock->reg);
143−
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);
129+ return DIV_ROUND_CLOSEST(parent_rate,
130+ clock->div_table[clock->cur_div_idx].div);
153131 }
154132
155133 static 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, · 34 unmodified lines
190168 if (i >= clock->div_num)
191169 return -EINVAL;
192170
171+ clock->cur_div_idx = i;
172+
193173 val = readl(clock->reg);
194174 val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK);
195175 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, · 19 unmodified lines
215195 struct sd_clock *clock;
216196 struct clk *clk;
217197 unsigned int i;
198+ u32 sd_fc;
218199
219200 clock = kzalloc(sizeof(*clock), GFP_KERNEL);
220201 if (!clock)
@@ -231,6 +212,18 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, · 10 unmodified lines
231212 clock->div_table = cpg_sd_div_table;
232213 clock->div_num = ARRAY_SIZE(cpg_sd_div_table);
233214
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+
234227 clock->div_max = clock->div_table[0].div;
235228 clock->div_min = clock->div_max;
236229 for (i = 1; i < clock->div_num; i++) {
@@ -279,7 +272,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, · 42 unmodified lines
279272 unsigned int div = 1;
280273 u32 value;
281274
282− parent = clks[core->parent];
275+ parent = clks[core->parent & 0xffff]; /* CLK_TYPE_PE uses high bits */
283276 if (IS_ERR(parent))
284277 return ERR_CAST(parent);
285278
@@ -303,6 +296,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, · 17 unmodified lines
303296
304297 case CLK_TYPE_GEN3_PLL1:
305298 mult = cpg_pll_config->pll1_mult;
299+ div = cpg_pll_config->pll1_div;
306300 break;
307301
308302 case CLK_TYPE_GEN3_PLL2:
@@ -320,6 +314,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, · 11 unmodified lines
320314
321315 case CLK_TYPE_GEN3_PLL3:
322316 mult = cpg_pll_config->pll3_mult;
317+ div = cpg_pll_config->pll3_div;
323318 break;
324319
325320 case CLK_TYPE_GEN3_PLL4:
@@ -360,6 +355,24 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, · 34 unmodified lines
360355 parent = clks[cpg_clk_extalr];
361356 break;
362357
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+
363376 default:
364377 return ERR_PTR(-EINVAL);
365378 }
drivers/clk/renesas/rcar-gen3-cpg.h+12−3
@@ -20,15 +20,24 @@ enum rcar_gen3_clk_types { · 19 unmodified lines
2020 CLK_TYPE_GEN3_PLL4,
2121 CLK_TYPE_GEN3_SD,
2222 CLK_TYPE_GEN3_R,
23+ CLK_TYPE_GEN3_PE,
2324 };
2425
2526 #define DEF_GEN3_SD(_name, _id, _parent, _offset) \
2627 DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset)
2728
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+
2835 struct rcar_gen3_cpg_pll_config {
29− unsigned int extal_div;
30− unsigned int pll1_mult;
31− unsigned int pll3_mult;
36+ u8 extal_div;
37+ u8 pll1_mult;
38+ u8 pll1_div;
39+ u8 pll3_mult;
40+ u8 pll3_div;
3241 };
3342
3443 #define CPG_RCKCR 0x240
drivers/clk/renesas/rcar-usb2-clock-sel.c+188−0
@@ -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+
31+struct 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+
39+static 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+
50+static 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+
56+static 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+
63+static 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+ */
74+static const struct clk_ops usb2_clock_sel_clock_ops = {
75+ .enable = usb2_clock_sel_enable,
76+ .disable = usb2_clock_sel_disable,
77+};
78+
79+static const struct of_device_id rcar_usb2_clock_sel_match[] = {
80+ { .compatible = "renesas,rcar-gen3-usb2-clock-sel" },
81+ { }
82+};
83+
84+static 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+
94+static 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+
104+static 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+
117+static 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+
171+static 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+
176+static 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+};
185+builtin_platform_driver(rcar_usb2_clock_sel_driver);
186+
187+MODULE_DESCRIPTION("Renesas R-Car USB2 clock selector Driver");
188+MODULE_LICENSE("GPL v2");
drivers/clk/renesas/renesas-cpg-mssr.c+6−0
@@ -679,6 +679,12 @@ static const struct of_device_id cpg_mssr_match[] = { · 678 unmodified lines
679679 .compatible = "renesas,r8a7796-cpg-mssr",
680680 .data = &r8a7796_cpg_mssr_info,
681681 },
682+#endif
683+#ifdef CONFIG_CLK_R8A77995
684+ {
685+ .compatible = "renesas,r8a77995-cpg-mssr",
686+ .data = &r8a77995_cpg_mssr_info,
687+ },
682688 #endif
683689 { /* sentinel */ }
684690 };
drivers/clk/renesas/renesas-cpg-mssr.h+1−0
@@ -138,6 +138,7 @@ extern const struct cpg_mssr_info r8a7792_cpg_mssr_info; · 137 unmodified lines
138138 extern const struct cpg_mssr_info r8a7794_cpg_mssr_info;
139139 extern const struct cpg_mssr_info r8a7795_cpg_mssr_info;
140140 extern const struct cpg_mssr_info r8a7796_cpg_mssr_info;
141+extern const struct cpg_mssr_info r8a77995_cpg_mssr_info;
141142
142143
143144 /*
drivers/clk/rockchip/clk-rk3128.c+55−14
@@ -201,7 +201,7 @@ static struct rockchip_clk_branch rk3128_uart2_fracmux __initdata = · 200 unmodified lines
201201 MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
202202 RK2928_CLKSEL_CON(15), 8, 2, MFLAGS);
203203
204−static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = {
204+static struct rockchip_clk_branch common_clk_branches[] __initdata = {
205205 /*
206206 * Clock-Architecture Diagram 1
207207 */
@@ -459,10 +459,6 @@ static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = { · 251 unmodified lines
459459 RK2928_CLKSEL_CON(2), 14, 2, MFLAGS, 8, 5, DFLAGS,
460460 RK2928_CLKGATE_CON(10), 15, GFLAGS),
461461
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−
466462 COMPOSITE_NOMUX(PCLK_PMU_PRE, "pclk_pmu_pre", "cpll", 0,
467463 RK2928_CLKSEL_CON(29), 8, 6, DFLAGS,
468464 RK2928_CLKGATE_CON(1), 0, GFLAGS),
@@ -495,7 +491,6 @@ static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = { · 26 unmodified lines
495491 GATE(ACLK_DMAC, "aclk_dmac", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS),
496492 GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 15, GFLAGS),
497493 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),
499494
500495 GATE(HCLK_I2S_8CH, "hclk_i2s_8ch", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
501496 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 = { · 39 unmodified lines
541536 GATE(0, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 6, GFLAGS),
542537 GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS),
543538
544− GATE(PCLK_HDMI, "pclk_hdmi", "pclk_cpu", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS),
545539 GATE(PCLK_ACODEC, "pclk_acodec", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS),
546540 GATE(0, "pclk_ddrupctl", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 7, GFLAGS),
547541 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 = { · 13 unmodified lines
561555 MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 0),
562556 };
563557
558+static 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+
564+static 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+
564573 static const char *const rk3128_critical_clocks[] __initconst = {
565574 "aclk_cpu",
566575 "hclk_cpu",
@@ -570,7 +579,7 @@ static const char *const rk3128_critical_clocks[] __initconst = { · 3 unmodified lines
570579 "pclk_peri",
571580 };
572581
573−static void __init rk3128_clk_init(struct device_node *np)
582+static struct rockchip_clk_provider *__init rk3128_common_clk_init(struct device_node *np)
574583 {
575584 struct rockchip_clk_provider *ctx;
576585 void __iomem *reg_base;
@@ -578,23 +587,21 @@ static void __init rk3128_clk_init(struct device_node *np) · 1 unmodified line
578587 reg_base = of_iomap(np, 0);
579588 if (!reg_base) {
580589 pr_err("%s: could not map cru region\n", __func__);
581− return;
590+ return ERR_PTR(-ENOMEM);
582591 }
583592
584593 ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
585594 if (IS_ERR(ctx)) {
586595 pr_err("%s: rockchip clk init failed\n", __func__);
587596 iounmap(reg_base);
588− return;
597+ return ERR_PTR(-ENOMEM);
589598 }
590599
591600 rockchip_clk_register_plls(ctx, rk3128_pll_clks,
592601 ARRAY_SIZE(rk3128_pll_clks),
593602 RK3128_GRF_SOC_STATUS0);
594− rockchip_clk_register_branches(ctx, rk3128_clk_branches,
595− ARRAY_SIZE(rk3128_clk_branches));
596− rockchip_clk_protect_critical(rk3128_critical_clocks,
597− ARRAY_SIZE(rk3128_critical_clocks));
603+ rockchip_clk_register_branches(ctx, common_clk_branches,
604+ ARRAY_SIZE(common_clk_branches));
598605
599606 rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
600607 mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
@@ -606,6 +613,40 @@ static void __init rk3128_clk_init(struct device_node *np) · 5 unmodified lines
606613
607614 rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL);
608615
616+ return ctx;
617+}
618+
619+static 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+
635+CLK_OF_DECLARE(rk3126_cru, "rockchip,rk3126-cru", rk3126_clk_init);
636+
637+static 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+
609650 rockchip_clk_of_add_provider(np, ctx);
610651 }
611652
drivers/clk/rockchip/clk-rk3228.c+1−1
@@ -391,7 +391,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { · 390 unmodified lines
391391 RK2928_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 8, DFLAGS,
392392 RK2928_CLKGATE_CON(2), 11, GFLAGS),
393393
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,
395395 RK2928_CLKSEL_CON(11), 10, 2, MFLAGS,
396396 RK2928_CLKGATE_CON(2), 13, GFLAGS),
397397 DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0,
drivers/clk/rockchip/clk-rv1108.c+381−81
@@ -93,9 +93,24 @@ static struct rockchip_pll_rate_table rv1108_pll_rates[] = { · 92 unmodified lines
9393 }
9494
9595 static struct rockchip_cpuclk_rate_table rv1108_cpuclk_rates[] __initdata = {
96− RV1108_CPUCLK_RATE(816000000, 4),
97− RV1108_CPUCLK_RATE(600000000, 4),
98− RV1108_CPUCLK_RATE(312000000, 4),
96+ RV1108_CPUCLK_RATE(1608000000, 7),
97+ RV1108_CPUCLK_RATE(1512000000, 7),
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),
99114 };
100115
101116 static const struct rockchip_cpuclk_reg_data rv1108_cpuclk_data = {
@@ -105,7 +120,7 @@ static const struct rockchip_cpuclk_reg_data rv1108_cpuclk_data = { · 3 unmodified lines
105120 .mux_core_alt = 1,
106121 .mux_core_main = 0,
107122 .mux_core_shift = 8,
108− .mux_core_mask = 0x1,
123+ .mux_core_mask = 0x3,
109124 };
110125
111126 PNAME(mux_pll_p) = { "xin24m", "xin24m"};
@@ -114,30 +129,42 @@ PNAME(mux_armclk_p) = { "apll_core", "gpll_core", "dpll_core" }; · 2 unmodified lines
114129 PNAME(mux_usb480m_pre_p) = { "usbphy", "xin24m" };
115130 PNAME(mux_hdmiphy_phy_p) = { "hdmiphy", "xin24m" };
116131 PNAME(mux_dclk_hdmiphy_pre_p) = { "dclk_hdmiphy_src_gpll", "dclk_hdmiphy_src_dpll" };
117−PNAME(mux_pll_src_4plls_p) = { "dpll", "hdmiphy", "gpll", "usb480m" };
132+PNAME(mux_pll_src_4plls_p) = { "dpll", "gpll", "hdmiphy", "usb480m" };
118133 PNAME(mux_pll_src_3plls_p) = { "apll", "gpll", "dpll" };
119134 PNAME(mux_pll_src_2plls_p) = { "dpll", "gpll" };
120135 PNAME(mux_pll_src_apll_gpll_p) = { "apll", "gpll" };
121−PNAME(mux_aclk_peri_src_p) = { "aclk_peri_src_dpll", "aclk_peri_src_gpll" };
136+PNAME(mux_aclk_peri_src_p) = { "aclk_peri_src_gpll", "aclk_peri_src_dpll" };
122137 PNAME(mux_aclk_bus_src_p) = { "aclk_bus_src_gpll", "aclk_bus_src_apll", "aclk_bus_src_dpll" };
123138 PNAME(mux_mmc_src_p) = { "dpll", "gpll", "xin24m", "usb480m" };
124139 PNAME(mux_pll_src_dpll_gpll_usb480m_p) = { "dpll", "gpll", "usb480m" };
125140 PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" };
126141 PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" };
127142 PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" };
128−PNAME(mux_sclk_macphy_p) = { "sclk_macphy_pre", "ext_gmac" };
143+PNAME(mux_sclk_mac_p) = { "sclk_mac_pre", "ext_gmac" };
129144 PNAME(mux_i2s0_pre_p) = { "i2s0_src", "i2s0_frac", "ext_i2s", "xin12m" };
130145 PNAME(mux_i2s_out_p) = { "i2s0_pre", "xin12m" };
131−PNAME(mux_i2s1_p) = { "i2s1_src", "i2s1_frac", "xin12m" };
132−PNAME(mux_i2s2_p) = { "i2s2_src", "i2s2_frac", "xin12m" };
146+PNAME(mux_i2s1_p) = { "i2s1_src", "i2s1_frac", "dummy", "xin12m" };
147+PNAME(mux_i2s2_p) = { "i2s2_src", "i2s2_frac", "dummy", "xin12m" };
148+PNAME(mux_wifi_src_p) = { "gpll", "xin24m" };
149+PNAME(mux_cifout_src_p) = { "hdmiphy", "gpll" };
150+PNAME(mux_cifout_p) = { "sclk_cifout_src", "xin24m" };
151+PNAME(mux_sclk_cif0_src_p) = { "pclk_vip", "clk_cif0_chn_out", "pclkin_cvbs2cif" };
152+PNAME(mux_sclk_cif1_src_p) = { "pclk_vip", "clk_cif1_chn_out", "pclkin_cvbs2cif" };
153+PNAME(mux_sclk_cif2_src_p) = { "pclk_vip", "clk_cif2_chn_out", "pclkin_cvbs2cif" };
154+PNAME(mux_sclk_cif3_src_p) = { "pclk_vip", "clk_cif3_chn_out", "pclkin_cvbs2cif" };
155+PNAME(mux_dsp_src_p) = { "dpll", "gpll", "apll", "usb480m" };
156+PNAME(mux_dclk_hdmiphy_p) = { "hdmiphy", "xin24m" };
157+PNAME(mux_dclk_vop_p) = { "dclk_hdmiphy", "dclk_vop_src" };
158+PNAME(mux_hdmi_cec_src_p) = { "dpll", "gpll", "xin24m" };
159+PNAME(mux_cvbs_src_p) = { "apll", "io_cvbs_clkin", "hdmiphy", "gpll" };
133160
134161 static struct rockchip_pll_clock rv1108_pll_clks[] __initdata = {
135162 [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),
137164 [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),
139166 [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),
141168 };
142169
143170 #define MFLAGS CLK_MUX_HIWORD_MASK
@@ -170,10 +197,10 @@ static struct rockchip_clk_branch rv1108_i2s2_fracmux __initdata = · 26 unmodified lines
170197 RV1108_CLKSEL_CON(7), 12, 2, MFLAGS);
171198
172199 static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = {
173− MUX(0, "hdmi_phy", mux_hdmiphy_phy_p, CLK_SET_RATE_PARENT,
174− RV1108_MISC_CON, 13, 2, MFLAGS),
200+ MUX(0, "hdmiphy", mux_hdmiphy_phy_p, CLK_SET_RATE_PARENT,
201+ RV1108_MISC_CON, 13, 1, MFLAGS),
175202 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),
177204 /*
178205 * Clock-Architecture Diagram 2
179206 */
@@ -197,50 +224,212 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { · 17 unmodified lines
197224 RV1108_CLKGATE_CON(11), 1, GFLAGS),
198225
199226 /* 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),
200243
201244 /* 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),
202274
203275 /* PD_PMU_wrapper */
204276 COMPOSITE_NOMUX(0, "pmu_24m_ena", "gpll", CLK_IGNORE_UNUSED,
205277 RV1108_CLKSEL_CON(38), 0, 5, DFLAGS,
206278 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,
208280 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,
210282 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,
212284 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,
214286 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,
216288 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,
218290 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,
220292 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,
222294 RV1108_CLKSEL_CON(12), 7, 1, MFLAGS, 0, 7, DFLAGS,
223295 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,
225297 RV1108_CLKSEL_CON(19), 7, 1, MFLAGS, 0, 7, DFLAGS,
226298 RV1108_CLKGATE_CON(8), 14, GFLAGS),
227299 GATE(0, "pvtm_pmu", "xin24m", CLK_IGNORE_UNUSED,
228300 RV1108_CLKGATE_CON(8), 13, GFLAGS),
229301
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+
230410 /*
231411 * Clock-Architecture Diagram 4
232412 */
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,
234414 RV1108_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS,
235415 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,
237417 RV1108_CLKGATE_CON(17), 0, GFLAGS),
238418 COMPOSITE_NOMUX(0, "hclk_vio_pre", "aclk_vio0_pre", 0,
239419 RV1108_CLKSEL_CON(29), 0, 5, DFLAGS,
240420 RV1108_CLKGATE_CON(7), 2, GFLAGS),
421+ GATE(HCLK_VIO, "hclk_vio", "hclk_vio_pre", 0,
422+ RV1108_CLKGATE_CON(17), 2, GFLAGS),
241423 COMPOSITE_NOMUX(0, "pclk_vio_pre", "aclk_vio0_pre", 0,
242424 RV1108_CLKSEL_CON(29), 8, 5, DFLAGS,
243425 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),
244433
245434 INVERTER(0, "pclk_vip", "ext_vip",
246435 RV1108_CLKSEL_CON(31), 8, IFLAGS),
@@ -252,8 +441,63 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { · 5 unmodified lines
252441 RV1108_CLKGATE_CON(6), 5, GFLAGS),
253442 GATE(0, "dclk_hdmiphy_src_dpll", "dpll", CLK_IGNORE_UNUSED,
254443 RV1108_CLKGATE_CON(6), 4, GFLAGS),
255− COMPOSITE_NOGATE(0, "dclk_hdmiphy", mux_dclk_hdmiphy_pre_p, 0,
256− RV1108_CLKSEL_CON(32), 6, 2, MFLAGS, 8, 6, DFLAGS),
444+ COMPOSITE_NOGATE(0, "dclk_hdmiphy_pre", mux_dclk_hdmiphy_pre_p, 0,
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),
257501
258502 /*
259503 * Clock-Architecture Diagram 5
@@ -261,10 +505,11 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { · 1 unmodified line
261505
262506 FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
263507
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,
265510 RV1108_CLKSEL_CON(5), 8, 1, MFLAGS, 0, 7, DFLAGS,
266511 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,
268513 RV1108_CLKSEL_CON(8), 0,
269514 RV1108_CLKGATE_CON(2), 1, GFLAGS,
270515 &rv1108_i2s0_fracmux),
@@ -274,7 +519,7 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { · 3 unmodified lines
274519 RV1108_CLKSEL_CON(5), 15, 1, MFLAGS,
275520 RV1108_CLKGATE_CON(2), 3, GFLAGS),
276521
277− COMPOSITE(0, "i2s1_src", mux_pll_src_2plls_p, 0,
522+ COMPOSITE(SCLK_I2S1_SRC, "i2s1_src", mux_pll_src_2plls_p, 0,
278523 RV1108_CLKSEL_CON(6), 8, 1, MFLAGS, 0, 7, DFLAGS,
279524 RV1108_CLKGATE_CON(2), 4, GFLAGS),
280525 COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_src", CLK_SET_RATE_PARENT,
@@ -284,7 +529,7 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { · 3 unmodified lines
284529 GATE(SCLK_I2S1, "sclk_i2s1", "i2s1_pre", CLK_SET_RATE_PARENT,
285530 RV1108_CLKGATE_CON(2), 6, GFLAGS),
286531
287− COMPOSITE(0, "i2s2_src", mux_pll_src_2plls_p, 0,
532+ COMPOSITE(SCLK_I2S2_SRC, "i2s2_src", mux_pll_src_2plls_p, 0,
288533 RV1108_CLKSEL_CON(7), 8, 1, MFLAGS, 0, 7, DFLAGS,
289534 RV1108_CLKGATE_CON(3), 8, GFLAGS),
290535 COMPOSITE_FRACMUX(0, "i2s2_frac", "i2s2_src", CLK_SET_RATE_PARENT,
@@ -303,32 +548,53 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { · 12 unmodified lines
303548 RV1108_CLKGATE_CON(1), 2, GFLAGS),
304549 COMPOSITE_NOGATE(ACLK_PRE, "aclk_bus_pre", mux_aclk_bus_src_p, 0,
305550 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,
307552 RV1108_CLKSEL_CON(3), 0, 5, DFLAGS,
308553 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,
310555 RV1108_CLKSEL_CON(3), 8, 5, DFLAGS,
311556 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,
313558 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,
315560 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,
317562 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,
319564 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,
321566 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,
323568 RV1108_CLKGATE_CON(13), 4, GFLAGS),
324569
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,
326592 RV1108_CLKSEL_CON(13), 12, 2, MFLAGS, 0, 7, DFLAGS,
327593 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,
329595 RV1108_CLKSEL_CON(14), 12, 2, MFLAGS, 0, 7, DFLAGS,
330596 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,
332598 RV1108_CLKSEL_CON(15), 12, 2, MFLAGS, 0, 7, DFLAGS,
333599 RV1108_CLKGATE_CON(3), 5, GFLAGS),
334600
@@ -344,44 +610,58 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { · 9 unmodified lines
344610 RV1108_CLKSEL_CON(18), 0,
345611 RV1108_CLKGATE_CON(3), 6, GFLAGS,
346612 &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,
348614 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,
350616 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,
352618 RV1108_CLKGATE_CON(13), 12, GFLAGS),
353619
354− COMPOSITE(0, "clk_i2c1", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
355− RV1108_CLKSEL_CON(19), 15, 2, MFLAGS, 8, 7, DFLAGS,
620+ COMPOSITE(SCLK_I2C1, "clk_i2c1", mux_pll_src_2plls_p, 0,
621+ RV1108_CLKSEL_CON(19), 15, 1, MFLAGS, 8, 7, DFLAGS,
356622 RV1108_CLKGATE_CON(3), 7, GFLAGS),
357− COMPOSITE(0, "clk_i2c2", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
358− RV1108_CLKSEL_CON(20), 7, 2, MFLAGS, 0, 7, DFLAGS,
623+ COMPOSITE(SCLK_I2C2, "clk_i2c2", mux_pll_src_2plls_p, 0,
624+ RV1108_CLKSEL_CON(20), 7, 1, MFLAGS, 0, 7, DFLAGS,
359625 RV1108_CLKGATE_CON(3), 8, GFLAGS),
360− COMPOSITE(0, "clk_i2c3", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
361− RV1108_CLKSEL_CON(20), 15, 2, MFLAGS, 8, 7, DFLAGS,
626+ COMPOSITE(SCLK_I2C3, "clk_i2c3", mux_pll_src_2plls_p, 0,
627+ RV1108_CLKSEL_CON(20), 15, 1, MFLAGS, 8, 7, DFLAGS,
362628 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,
364630 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,
366632 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,
368634 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,
370636 RV1108_CLKSEL_CON(12), 15, 2, MFLAGS, 8, 7, DFLAGS,
371637 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,
373639 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,
375641 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,
377643 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,
379645 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,
381647 RV1108_CLKGATE_CON(13), 9, GFLAGS),
382648
383649 GATE(0, "pclk_grf", "pclk_bus_pre", CLK_IGNORE_UNUSED,
384650 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),
385665
386666 GATE(ACLK_DMAC, "aclk_dmac", "aclk_bus_pre", 0,
387667 RV1108_CLKGATE_CON(12), 2, GFLAGS),
@@ -397,18 +677,24 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { · 9 unmodified lines
397677 RV1108_CLKGATE_CON(0), 9, GFLAGS),
398678 GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED,
399679 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,
401681 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,
403685 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,
405687 RV1108_CLKGATE_CON(12), 4, GFLAGS),
406− GATE(0, "ddrc", "ddrphy", CLK_IGNORE_UNUSED,
688+ GATE(0, "nclk_ddrupctl", "clk_ddr", CLK_IGNORE_UNUSED,
407689 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,
409691 RV1108_CLKGATE_CON(12), 6, GFLAGS),
410692 GATE(0, "timer_clk", "xin24m", CLK_IGNORE_UNUSED,
411693 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),
412698
413699 /*
414700 * Clock-Architecture Diagram 6
@@ -418,23 +704,23 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { · 3 unmodified lines
418704 COMPOSITE_NOMUX(0, "pclk_periph_pre", "gpll", 0,
419705 RV1108_CLKSEL_CON(23), 10, 5, DFLAGS,
420706 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,
422708 RV1108_CLKGATE_CON(15), 13, GFLAGS),
423709 COMPOSITE_NOMUX(0, "hclk_periph_pre", "gpll", 0,
424710 RV1108_CLKSEL_CON(23), 5, 5, DFLAGS,
425711 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,
427713 RV1108_CLKGATE_CON(15), 12, GFLAGS),
428714
429715 GATE(0, "aclk_peri_src_dpll", "dpll", CLK_IGNORE_UNUSED,
430716 RV1108_CLKGATE_CON(4), 1, GFLAGS),
431717 GATE(0, "aclk_peri_src_gpll", "gpll", CLK_IGNORE_UNUSED,
432718 RV1108_CLKGATE_CON(4), 2, GFLAGS),
433− COMPOSITE(0, "aclk_periph", mux_aclk_peri_src_p, CLK_IGNORE_UNUSED,
434− RV1108_CLKSEL_CON(23), 15, 2, MFLAGS, 0, 5, DFLAGS,
719+ COMPOSITE(ACLK_PERI, "aclk_periph", mux_aclk_peri_src_p, 0,
720+ RV1108_CLKSEL_CON(23), 15, 1, MFLAGS, 0, 5, DFLAGS,
435721 RV1108_CLKGATE_CON(15), 11, GFLAGS),
436722
437− COMPOSITE(SCLK_SDMMC, "sclk_sdmmc0", mux_mmc_src_p, 0,
723+ COMPOSITE(SCLK_SDMMC, "sclk_sdmmc", mux_mmc_src_p, 0,
438724 RV1108_CLKSEL_CON(25), 8, 2, MFLAGS, 0, 8, DFLAGS,
439725 RV1108_CLKGATE_CON(5), 0, GFLAGS),
440726
@@ -454,23 +740,31 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { · 13 unmodified lines
454740 GATE(HCLK_EMMC, "hclk_emmc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 2, GFLAGS),
455741
456742 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,
458744 RV1108_CLKGATE_CON(5), 3, GFLAGS),
459745 GATE(HCLK_NANDC, "hclk_nandc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 3, GFLAGS),
460746
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+
461753 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,
463755 RV1108_CLKGATE_CON(5), 4, GFLAGS),
464756 GATE(HCLK_SFC, "hclk_sfc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 10, GFLAGS),
465757
466− COMPOSITE(0, "sclk_macphy_pre", mux_pll_src_apll_gpll_p, 0,
467− RV1108_CLKSEL_CON(24), 12, 2, MFLAGS, 0, 5, DFLAGS,
758+ COMPOSITE(SCLK_MAC_PRE, "sclk_mac_pre", mux_pll_src_apll_gpll_p, 0,
759+ RV1108_CLKSEL_CON(24), 12, 1, MFLAGS, 0, 5, DFLAGS,
468760 RV1108_CLKGATE_CON(4), 10, GFLAGS),
469− MUX(0, "sclk_macphy", mux_sclk_macphy_p, CLK_SET_RATE_PARENT,
470− RV1108_CLKSEL_CON(24), 8, 2, MFLAGS),
471− GATE(0, "sclk_macphy_rx", "sclk_macphy", 0, RV1108_CLKGATE_CON(4), 8, GFLAGS),
472− GATE(0, "sclk_mac_ref", "sclk_macphy", 0, RV1108_CLKGATE_CON(4), 6, GFLAGS),
473− GATE(0, "sclk_mac_refout", "sclk_macphy", 0, RV1108_CLKGATE_CON(4), 7, GFLAGS),
761+ MUX(SCLK_MAC, "sclk_mac", mux_sclk_mac_p, CLK_SET_RATE_PARENT,
762+ RV1108_CLKSEL_CON(24), 8, 1, MFLAGS),
763+ GATE(SCLK_MAC_RX, "sclk_mac_rx", "sclk_mac", 0, RV1108_CLKGATE_CON(4), 8, GFLAGS),
764+ GATE(SCLK_MAC_REF, "sclk_mac_ref", "sclk_mac", 0, RV1108_CLKGATE_CON(4), 6, 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),
474768
475769 MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RV1108_SDMMC_CON0, 1),
476770 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 = { · 7 unmodified lines
484778
485779 static const char *const rv1108_critical_clocks[] __initconst = {
486780 "aclk_core",
487− "aclk_bus_src_gpll",
781+ "aclk_bus",
782+ "hclk_bus",
783+ "pclk_bus",
488784 "aclk_periph",
489785 "hclk_periph",
490786 "pclk_periph",
787+ "nclk_ddrupctl",
788+ "pclk_ddrmon",
789+ "pclk_acodecphy",
790+ "pclk_pmu",
491791 };
492792
493793 static void __init rv1108_clk_init(struct device_node *np)
drivers/clk/rockchip/clk.c+36−0
@@ -29,6 +29,7 @@ · 28 unmodified lines
2929 #include <linux/mfd/syscon.h>
3030 #include <linux/regmap.h>
3131 #include <linux/reboot.h>
32+#include <linux/rational.h>
3233 #include "clk.h"
3334
3435 /**
@@ -164,6 +165,40 @@ static int rockchip_clk_frac_notifier_cb(struct notifier_block *nb, · 129 unmodified lines
164165 return notifier_from_errno(ret);
165166 }
166167
168+/**
169+ * fractional divider must set that denominator is 20 times larger than
170+ * numerator to generate precise clock frequency.
171+ */
172+static 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+
167202 static struct clk *rockchip_clk_register_frac_branch(
168203 struct rockchip_clk_provider *ctx, const char *name,
169204 const char *const *parent_names, u8 num_parents,
@@ -210,6 +245,7 @@ static struct clk *rockchip_clk_register_frac_branch( · 40 unmodified lines
210245 div->nwidth = 16;
211246 div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift;
212247 div->lock = lock;
248+ div->approximation = rockchip_fractional_approximation;
213249 div_ops = &clk_fractional_divider_ops;
214250
215251 clk = clk_register_composite(NULL, name, parent_names, num_parents,
drivers/clk/samsung/clk-exynos-audss.c+4−4
@@ -180,7 +180,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) · 179 unmodified lines
180180 }
181181 clk_table[EXYNOS_MOUT_AUDSS] = clk_hw_register_mux(NULL, "mout_audss",
182182 mout_audss_p, ARRAY_SIZE(mout_audss_p),
183− CLK_SET_RATE_NO_REPARENT,
183+ CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
184184 reg_base + ASS_CLK_SRC, 0, 1, 0, &lock);
185185
186186 cdclk = devm_clk_get(&pdev->dev, "cdclk");
@@ -195,11 +195,11 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) · 8 unmodified lines
195195 reg_base + ASS_CLK_SRC, 2, 2, 0, &lock);
196196
197197 clk_table[EXYNOS_DOUT_SRP] = clk_hw_register_divider(NULL, "dout_srp",
198− "mout_audss", 0, reg_base + ASS_CLK_DIV, 0, 4,
199− 0, &lock);
198+ "mout_audss", CLK_SET_RATE_PARENT,
199+ reg_base + ASS_CLK_DIV, 0, 4, 0, &lock);
200200
201201 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,
203203 reg_base + ASS_CLK_DIV, 4, 4, 0, &lock);
204204
205205 clk_table[EXYNOS_DOUT_I2S] = clk_hw_register_divider(NULL, "dout_i2s",
drivers/clk/samsung/clk-exynos5420.c+15−8
@@ -537,8 +537,8 @@ static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = { · 536 unmodified lines
537537
538538 MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore",
539539 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,
541− SRC_TOP7, 20, 2),
540+ MUX_F(CLK_MOUT_MAU_EPLL, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p,
541+ SRC_TOP7, 20, 2, CLK_SET_RATE_PARENT, 0),
542542 MUX(0, "sclk_bpll", mout_bpll_p, SRC_TOP7, 24, 1),
543543 MUX(0, "mout_epll2", mout_epll2_5800_p, SRC_TOP7, 28, 1),
544544
@@ -547,8 +547,8 @@ static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = { · 2 unmodified lines
547547 MUX(0, "mout_aclk432_cam", mout_group6_5800_p, SRC_TOP8, 24, 2),
548548 MUX(0, "mout_aclk432_scaler", mout_group6_5800_p, SRC_TOP8, 28, 2),
549549
550− MUX(CLK_MOUT_USER_MAU_EPLL, "mout_user_mau_epll", mout_group16_5800_p,
551− SRC_TOP9, 8, 1),
550+ MUX_F(CLK_MOUT_USER_MAU_EPLL, "mout_user_mau_epll", mout_group16_5800_p,
551+ SRC_TOP9, 8, 1, CLK_SET_RATE_PARENT, 0),
552552 MUX(0, "mout_user_aclk550_cam", mout_group15_5800_p,
553553 SRC_TOP9, 16, 1),
554554 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 = { · 35 unmodified lines
590590 GATE_BUS_TOP, 24, 0, 0),
591591 GATE(CLK_ACLK432_SCALER, "aclk432_scaler", "mout_user_aclk432_scaler",
592592 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),
593595 };
594596
595597 static const struct samsung_mux_clock exynos5420_mux_clks[] __initconst = {
@@ -629,6 +631,11 @@ static const struct samsung_div_clock exynos5420_div_clks[] __initconst = { · 33 unmodified lines
629631 "mout_aclk400_wcore_bpll", DIV_TOP0, 16, 3),
630632 };
631633
634+static 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+
632639 static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = {
633640 MUX(0, "mout_user_pclk66_gpio", mout_user_pclk66_gpio_p,
634641 SRC_TOP7, 4, 1),
@@ -706,7 +713,8 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { · 71 unmodified lines
706713 MUX(0, "mout_sclk_spll", mout_spll_p, SRC_TOP6, 8, 1),
707714 MUX(0, "mout_sclk_ipll", mout_ipll_p, SRC_TOP6, 12, 1),
708715 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),
710718 MUX(0, "mout_sclk_dpll", mout_dpll_p, SRC_TOP6, 24, 1),
711719 MUX(0, "mout_sclk_cpll", mout_cpll_p, SRC_TOP6, 28, 1),
712720
@@ -1001,9 +1009,6 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = { · 288 unmodified lines
10011009 GATE(0, "aclk300_disp1", "mout_user_aclk300_disp1",
10021010 SRC_MASK_TOP2, 24, CLK_IS_CRITICAL, 0),
10031011
1004− GATE(CLK_MAU_EPLL, "mau_epll", "mout_mau_epll_clk",
1005− SRC_MASK_TOP7, 20, 0, 0),
1006−
10071012 /* sclk */
10081013 GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_uart0",
10091014 GATE_TOP_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0),
@@ -1440,6 +1445,8 @@ static void __init exynos5x_clk_init(struct device_node *np, · 430 unmodified lines
14401445 ARRAY_SIZE(exynos5420_mux_clks));
14411446 samsung_clk_register_div(ctx, exynos5420_div_clks,
14421447 ARRAY_SIZE(exynos5420_div_clks));
1448+ samsung_clk_register_gate(ctx, exynos5420_gate_clks,
1449+ ARRAY_SIZE(exynos5420_gate_clks));
14431450 } else {
14441451 samsung_clk_register_fixed_factor(
14451452 ctx, exynos5800_fixed_factor_clks,
drivers/clk/sunxi-ng/Kconfig+18−0
@@ -11,6 +11,19 @@ config SUN50I_A64_CCU · 10 unmodified lines
1111 default ARM64 && ARCH_SUNXI
1212 depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
1313
14+config 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+
1427 config SUN5I_CCU
1528 bool "Support for the Allwinner sun5i family CCM"
1629 default MACH_SUN5I
@@ -48,6 +61,11 @@ config SUN8I_V3S_CCU · 31 unmodified lines
4861 config SUN8I_DE2_CCU
4962 bool "Support for the Allwinner SoCs DE2 CCU"
5063
64+config SUN8I_R40_CCU
65+ bool "Support for the Allwinner R40 CCU"
66+ default MACH_SUN8I
67+ depends on MACH_SUN8I || COMPILE_TEST
68+
5169 config SUN9I_A80_CCU
5270 bool "Support for the Allwinner A80 CCU"
5371 default MACH_SUN9I
drivers/clk/sunxi-ng/Makefile+2−0
@@ -20,6 +20,7 @@ lib-$(CONFIG_SUNXI_CCU) += ccu_mp.o · 19 unmodified lines
2020
2121 # SoC support
2222 obj-$(CONFIG_SUN50I_A64_CCU) += ccu-sun50i-a64.o
23+obj-$(CONFIG_SUN4I_A10_CCU) += ccu-sun4i-a10.o
2324 obj-$(CONFIG_SUN5I_CCU) += ccu-sun5i.o
2425 obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o
2526 obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o
@@ -29,6 +30,7 @@ obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o · 3 unmodified lines
2930 obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o
3031 obj-$(CONFIG_SUN8I_DE2_CCU) += ccu-sun8i-de2.o
3132 obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o
33+obj-$(CONFIG_SUN8I_R40_CCU) += ccu-sun8i-r40.o
3234 obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o
3335 obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o
3436 obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o
drivers/clk/sunxi-ng/ccu-sun4i-a10.c+1456−0
@@ -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+
34+static 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
58+static 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+
72+static 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+
89+static 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+
104+static 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+
117+static 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+
130+static SUNXI_CCU_M(pll_ddr_clk, "pll-ddr", "pll-ddr-base", 0x020, 0, 2,
131+ CLK_IS_CRITICAL);
132+
133+static 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+
143+static 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+
156+static CLK_FIXED_FACTOR(pll_periph_clk, "pll-periph", "pll-periph-base",
157+ 2, 1, CLK_SET_RATE_PARENT);
158+
159+/* Not documented on A10 */
160+static 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+
173+static 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 */
191+static 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+
204+static SUNXI_CCU_GATE(hosc_clk, "hosc", "osc24M", 0x050, BIT(0), 0);
205+
206+static const char *const cpu_parents[] = { "osc32k", "hosc",
207+ "pll-core", "pll-periph" };
208+static const struct ccu_mux_fixed_prediv cpu_predivs[] = {
209+ { .index = 3, .div = 3, },
210+};
211+
212+#define SUN4I_AHB_REG 0x054
213+static 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+
230+static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x054, 0, 2, 0);
231+
232+static 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+
240+static const char *const ahb_sun7i_parents[] = { "axi", "pll-periph",
241+ "pll-periph" };
242+static const struct ccu_mux_fixed_prediv ahb_sun7i_predivs[] = {
243+ { .index = 1, .div = 2, },
244+ { /* Sentinel */ },
245+};
246+static 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+
264+static 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+};
271+static SUNXI_CCU_DIV_TABLE(apb0_clk, "apb0", "ahb",
272+ 0x054, 8, 2, apb0_div_table, 0);
273+
274+static const char *const apb1_parents[] = { "hosc", "pll-periph", "osc32k" };
275+static 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 */
282+static SUNXI_CCU_GATE(axi_dram_clk, "axi-dram", "ahb",
283+ 0x05c, BIT(31), 0);
284+
285+static SUNXI_CCU_GATE(ahb_otg_clk, "ahb-otg", "ahb",
286+ 0x060, BIT(0), 0);
287+static SUNXI_CCU_GATE(ahb_ehci0_clk, "ahb-ehci0", "ahb",
288+ 0x060, BIT(1), 0);
289+static SUNXI_CCU_GATE(ahb_ohci0_clk, "ahb-ohci0", "ahb",
290+ 0x060, BIT(2), 0);
291+static SUNXI_CCU_GATE(ahb_ehci1_clk, "ahb-ehci1", "ahb",
292+ 0x060, BIT(3), 0);
293+static SUNXI_CCU_GATE(ahb_ohci1_clk, "ahb-ohci1", "ahb",
294+ 0x060, BIT(4), 0);
295+static SUNXI_CCU_GATE(ahb_ss_clk, "ahb-ss", "ahb",
296+ 0x060, BIT(5), 0);
297+static SUNXI_CCU_GATE(ahb_dma_clk, "ahb-dma", "ahb",
298+ 0x060, BIT(6), 0);
299+static SUNXI_CCU_GATE(ahb_bist_clk, "ahb-bist", "ahb",
300+ 0x060, BIT(7), 0);
301+static SUNXI_CCU_GATE(ahb_mmc0_clk, "ahb-mmc0", "ahb",
302+ 0x060, BIT(8), 0);
303+static SUNXI_CCU_GATE(ahb_mmc1_clk, "ahb-mmc1", "ahb",
304+ 0x060, BIT(9), 0);
305+static SUNXI_CCU_GATE(ahb_mmc2_clk, "ahb-mmc2", "ahb",
306+ 0x060, BIT(10), 0);
307+static SUNXI_CCU_GATE(ahb_mmc3_clk, "ahb-mmc3", "ahb",
308+ 0x060, BIT(11), 0);
309+static SUNXI_CCU_GATE(ahb_ms_clk, "ahb-ms", "ahb",
310+ 0x060, BIT(12), 0);
311+static SUNXI_CCU_GATE(ahb_nand_clk, "ahb-nand", "ahb",
312+ 0x060, BIT(13), 0);
313+static SUNXI_CCU_GATE(ahb_sdram_clk, "ahb-sdram", "ahb",
314+ 0x060, BIT(14), CLK_IS_CRITICAL);
315+
316+static SUNXI_CCU_GATE(ahb_ace_clk, "ahb-ace", "ahb",
317+ 0x060, BIT(16), 0);
318+static SUNXI_CCU_GATE(ahb_emac_clk, "ahb-emac", "ahb",
319+ 0x060, BIT(17), 0);
320+static SUNXI_CCU_GATE(ahb_ts_clk, "ahb-ts", "ahb",
321+ 0x060, BIT(18), 0);
322+static SUNXI_CCU_GATE(ahb_spi0_clk, "ahb-spi0", "ahb",
323+ 0x060, BIT(20), 0);
324+static SUNXI_CCU_GATE(ahb_spi1_clk, "ahb-spi1", "ahb",
325+ 0x060, BIT(21), 0);
326+static SUNXI_CCU_GATE(ahb_spi2_clk, "ahb-spi2", "ahb",
327+ 0x060, BIT(22), 0);
328+static SUNXI_CCU_GATE(ahb_spi3_clk, "ahb-spi3", "ahb",
329+ 0x060, BIT(23), 0);
330+static SUNXI_CCU_GATE(ahb_pata_clk, "ahb-pata", "ahb",
331+ 0x060, BIT(24), 0);
332+/* Not documented on A20 */
333+static SUNXI_CCU_GATE(ahb_sata_clk, "ahb-sata", "ahb",
334+ 0x060, BIT(25), 0);
335+/* Not present on A20 */
336+static SUNXI_CCU_GATE(ahb_gps_clk, "ahb-gps", "ahb",
337+ 0x060, BIT(26), 0);
338+/* Not present on A10 */
339+static SUNXI_CCU_GATE(ahb_hstimer_clk, "ahb-hstimer", "ahb",
340+ 0x060, BIT(28), 0);
341+
342+static SUNXI_CCU_GATE(ahb_ve_clk, "ahb-ve", "ahb",
343+ 0x064, BIT(0), 0);
344+static SUNXI_CCU_GATE(ahb_tvd_clk, "ahb-tvd", "ahb",
345+ 0x064, BIT(1), 0);
346+static SUNXI_CCU_GATE(ahb_tve0_clk, "ahb-tve0", "ahb",
347+ 0x064, BIT(2), 0);
348+static SUNXI_CCU_GATE(ahb_tve1_clk, "ahb-tve1", "ahb",
349+ 0x064, BIT(3), 0);
350+static SUNXI_CCU_GATE(ahb_lcd0_clk, "ahb-lcd0", "ahb",
351+ 0x064, BIT(4), 0);
352+static SUNXI_CCU_GATE(ahb_lcd1_clk, "ahb-lcd1", "ahb",
353+ 0x064, BIT(5), 0);
354+static SUNXI_CCU_GATE(ahb_csi0_clk, "ahb-csi0", "ahb",
355+ 0x064, BIT(8), 0);
356+static SUNXI_CCU_GATE(ahb_csi1_clk, "ahb-csi1", "ahb",
357+ 0x064, BIT(9), 0);
358+/* Not present on A10 */
359+static SUNXI_CCU_GATE(ahb_hdmi1_clk, "ahb-hdmi1", "ahb",
360+ 0x064, BIT(10), 0);
361+static SUNXI_CCU_GATE(ahb_hdmi0_clk, "ahb-hdmi0", "ahb",
362+ 0x064, BIT(11), 0);
363+static SUNXI_CCU_GATE(ahb_de_be0_clk, "ahb-de-be0", "ahb",
364+ 0x064, BIT(12), 0);
365+static SUNXI_CCU_GATE(ahb_de_be1_clk, "ahb-de-be1", "ahb",
366+ 0x064, BIT(13), 0);
367+static SUNXI_CCU_GATE(ahb_de_fe0_clk, "ahb-de-fe0", "ahb",
368+ 0x064, BIT(14), 0);
369+static SUNXI_CCU_GATE(ahb_de_fe1_clk, "ahb-de-fe1", "ahb",
370+ 0x064, BIT(15), 0);
371+/* Not present on A10 */
372+static SUNXI_CCU_GATE(ahb_gmac_clk, "ahb-gmac", "ahb",
373+ 0x064, BIT(17), 0);
374+static SUNXI_CCU_GATE(ahb_mp_clk, "ahb-mp", "ahb",
375+ 0x064, BIT(18), 0);
376+static SUNXI_CCU_GATE(ahb_gpu_clk, "ahb-gpu", "ahb",
377+ 0x064, BIT(20), 0);
378+
379+static SUNXI_CCU_GATE(apb0_codec_clk, "apb0-codec", "apb0",
380+ 0x068, BIT(0), 0);
381+static SUNXI_CCU_GATE(apb0_spdif_clk, "apb0-spdif", "apb0",
382+ 0x068, BIT(1), 0);
383+static SUNXI_CCU_GATE(apb0_ac97_clk, "apb0-ac97", "apb0",
384+ 0x068, BIT(2), 0);
385+static SUNXI_CCU_GATE(apb0_i2s0_clk, "apb0-i2s0", "apb0",
386+ 0x068, BIT(3), 0);
387+/* Not present on A10 */
388+static SUNXI_CCU_GATE(apb0_i2s1_clk, "apb0-i2s1", "apb0",
389+ 0x068, BIT(4), 0);
390+static SUNXI_CCU_GATE(apb0_pio_clk, "apb0-pio", "apb0",
391+ 0x068, BIT(5), 0);
392+static SUNXI_CCU_GATE(apb0_ir0_clk, "apb0-ir0", "apb0",
393+ 0x068, BIT(6), 0);
394+static SUNXI_CCU_GATE(apb0_ir1_clk, "apb0-ir1", "apb0",
395+ 0x068, BIT(7), 0);
396+/* Not present on A10 */
397+static SUNXI_CCU_GATE(apb0_i2s2_clk, "apb0-i2s2", "apb0",
398+ 0x068, BIT(8), 0);
399+static SUNXI_CCU_GATE(apb0_keypad_clk, "apb0-keypad", "apb0",
400+ 0x068, BIT(10), 0);
401+
402+static SUNXI_CCU_GATE(apb1_i2c0_clk, "apb1-i2c0", "apb1",
403+ 0x06c, BIT(0), 0);
404+static SUNXI_CCU_GATE(apb1_i2c1_clk, "apb1-i2c1", "apb1",
405+ 0x06c, BIT(1), 0);
406+static SUNXI_CCU_GATE(apb1_i2c2_clk, "apb1-i2c2", "apb1",
407+ 0x06c, BIT(2), 0);
408+/* Not present on A10 */
409+static SUNXI_CCU_GATE(apb1_i2c3_clk, "apb1-i2c3", "apb1",
410+ 0x06c, BIT(3), 0);
411+static SUNXI_CCU_GATE(apb1_can_clk, "apb1-can", "apb1",
412+ 0x06c, BIT(4), 0);
413+static SUNXI_CCU_GATE(apb1_scr_clk, "apb1-scr", "apb1",
414+ 0x06c, BIT(5), 0);
415+static SUNXI_CCU_GATE(apb1_ps20_clk, "apb1-ps20", "apb1",
416+ 0x06c, BIT(6), 0);
417+static SUNXI_CCU_GATE(apb1_ps21_clk, "apb1-ps21", "apb1",
418+ 0x06c, BIT(7), 0);
419+/* Not present on A10 */
420+static SUNXI_CCU_GATE(apb1_i2c4_clk, "apb1-i2c4", "apb1",
421+ 0x06c, BIT(15), 0);
422+static SUNXI_CCU_GATE(apb1_uart0_clk, "apb1-uart0", "apb1",
423+ 0x06c, BIT(16), 0);
424+static SUNXI_CCU_GATE(apb1_uart1_clk, "apb1-uart1", "apb1",
425+ 0x06c, BIT(17), 0);
426+static SUNXI_CCU_GATE(apb1_uart2_clk, "apb1-uart2", "apb1",
427+ 0x06c, BIT(18), 0);
428+static SUNXI_CCU_GATE(apb1_uart3_clk, "apb1-uart3", "apb1",
429+ 0x06c, BIT(19), 0);
430+static SUNXI_CCU_GATE(apb1_uart4_clk, "apb1-uart4", "apb1",
431+ 0x06c, BIT(20), 0);
432+static SUNXI_CCU_GATE(apb1_uart5_clk, "apb1-uart5", "apb1",
433+ 0x06c, BIT(21), 0);
434+static SUNXI_CCU_GATE(apb1_uart6_clk, "apb1-uart6", "apb1",
435+ 0x06c, BIT(22), 0);
436+static SUNXI_CCU_GATE(apb1_uart7_clk, "apb1-uart7", "apb1",
437+ 0x06c, BIT(23), 0);
438+
439+static const char *const mod0_default_parents[] = { "hosc", "pll-periph",
440+ "pll-ddr-other" };
441+static 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 */
449+static 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+
456+static 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 */
464+static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
465+ 0x088, 8, 3, 0);
466+static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
467+ 0x088, 20, 3, 0);
468+
469+static 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 */
477+static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
478+ 0x08c, 8, 3, 0);
479+static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
480+ 0x08c, 20, 3, 0);
481+
482+static 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 */
490+static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
491+ 0x090, 8, 3, 0);
492+static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
493+ 0x090, 20, 3, 0);
494+
495+static 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 */
503+static SUNXI_CCU_PHASE(mmc3_output_clk, "mmc3_output", "mmc3",
504+ 0x094, 8, 3, 0);
505+static SUNXI_CCU_PHASE(mmc3_sample_clk, "mmc3_sample", "mmc3",
506+ 0x094, 20, 3, 0);
507+
508+static 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+
515+static 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+
522+static 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+
529+static 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+
536+static 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 */
544+static 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? */
552+static const char *const ir_parents_sun4i[] = { "hosc", "pll-periph",
553+ "pll-ddr-other" };
554+static 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+
561+static 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);
567+static const char *const ir_parents_sun7i[] = { "hosc", "pll-periph",
568+ "pll-ddr-other", "osc32k" };
569+static 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+
576+static 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+
583+static const char *const audio_parents[] = { "pll-audio-8x", "pll-audio-4x",
584+ "pll-audio-2x", "pll-audio" };
585+static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", audio_parents,
586+ 0x0b8, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
587+
588+static 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 */
592+static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", audio_parents,
593+ 0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
594+
595+static const char *const keypad_parents[] = { "hosc", "losc"};
596+static const u8 keypad_table[] = { 0, 2 };
597+static 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+ */
616+static const char *const sata_parents[] = {"pll-periph-sata", "sata-ext"};
617+static SUNXI_CCU_MUX_WITH_GATE(sata_clk, "sata", sata_parents,
618+ 0x0c8, 24, 1, BIT(31), CLK_SET_RATE_PARENT);
619+
620+
621+static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "pll-periph",
622+ 0x0cc, BIT(6), 0);
623+static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "pll-periph",
624+ 0x0cc, BIT(7), 0);
625+static SUNXI_CCU_GATE(usb_phy_clk, "usb-phy", "pll-periph",
626+ 0x0cc, BIT(8), 0);
627+
628+/* TODO: GPS CLK 0x0d0 */
629+
630+static 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 */
638+static 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 */
642+static SUNXI_CCU_MUX_WITH_GATE(i2s2_clk, "i2s2", audio_parents,
643+ 0x0dc, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
644+
645+static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "pll-ddr",
646+ 0x100, BIT(0), 0);
647+static SUNXI_CCU_GATE(dram_csi0_clk, "dram-csi0", "pll-ddr",
648+ 0x100, BIT(1), 0);
649+static SUNXI_CCU_GATE(dram_csi1_clk, "dram-csi1", "pll-ddr",
650+ 0x100, BIT(2), 0);
651+static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "pll-ddr",
652+ 0x100, BIT(3), 0);
653+static SUNXI_CCU_GATE(dram_tvd_clk, "dram-tvd", "pll-ddr",
654+ 0x100, BIT(4), 0);
655+static SUNXI_CCU_GATE(dram_tve0_clk, "dram-tve0", "pll-ddr",
656+ 0x100, BIT(5), 0);
657+static 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 */
661+static SUNXI_CCU_GATE(dram_out_clk, "dram-out", "pll-ddr",
662+ 0x100, BIT(15), CLK_IS_CRITICAL);
663+static SUNXI_CCU_GATE(dram_de_fe1_clk, "dram-de-fe1", "pll-ddr",
664+ 0x100, BIT(24), 0);
665+static SUNXI_CCU_GATE(dram_de_fe0_clk, "dram-de-fe0", "pll-ddr",
666+ 0x100, BIT(25), 0);
667+static SUNXI_CCU_GATE(dram_de_be0_clk, "dram-de-be0", "pll-ddr",
668+ 0x100, BIT(26), 0);
669+static SUNXI_CCU_GATE(dram_de_be1_clk, "dram-de-be1", "pll-ddr",
670+ 0x100, BIT(27), 0);
671+static SUNXI_CCU_GATE(dram_mp_clk, "dram-mp", "pll-ddr",
672+ 0x100, BIT(28), 0);
673+static SUNXI_CCU_GATE(dram_ace_clk, "dram-ace", "pll-ddr",
674+ 0x100, BIT(29), 0);
675+
676+static const char *const de_parents[] = { "pll-video0", "pll-video1",
677+ "pll-ddr-other" };
678+static SUNXI_CCU_M_WITH_MUX_GATE(de_be0_clk, "de-be0", de_parents,
679+ 0x104, 0, 4, 24, 2, BIT(31), 0);
680+
681+static SUNXI_CCU_M_WITH_MUX_GATE(de_be1_clk, "de-be1", de_parents,
682+ 0x108, 0, 4, 24, 2, BIT(31), 0);
683+
684+static SUNXI_CCU_M_WITH_MUX_GATE(de_fe0_clk, "de-fe0", de_parents,
685+ 0x10c, 0, 4, 24, 2, BIT(31), 0);
686+
687+static 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 */
691+static SUNXI_CCU_M_WITH_MUX_GATE(de_mp_clk, "de-mp", de_parents,
692+ 0x114, 0, 4, 24, 2, BIT(31), 0);
693+
694+static const char *const disp_parents[] = { "pll-video0", "pll-video1",
695+ "pll-video0-2x", "pll-video1-2x" };
696+static SUNXI_CCU_MUX_WITH_GATE(tcon0_ch0_clk, "tcon0-ch0-sclk", disp_parents,
697+ 0x118, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
698+static SUNXI_CCU_MUX_WITH_GATE(tcon1_ch0_clk, "tcon1-ch0-sclk", disp_parents,
699+ 0x11c, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
700+
701+static const char *const csi_sclk_parents[] = { "pll-video0", "pll-ve",
702+ "pll-ddr-other", "pll-periph" };
703+
704+static 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 */
709+static const char *const tvd_parents[] = { "pll-video0", "pll-video1" };
710+static 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 */
714+static 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+
723+static SUNXI_CCU_M_WITH_GATE(tvd_sclk1_sun7i_clk, "tvd-sclk1", "tvd-sclk2",
724+ 0x128, 0, 4, BIT(31), 0);
725+
726+static 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+
731+static 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+
736+static 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+
741+static 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+
746+static const char *const csi_parents[] = { "hosc", "pll-video0", "pll-video1",
747+ "pll-video0-2x", "pll-video1-2x"};
748+static const u8 csi_table[] = { 0, 1, 2, 5, 6};
749+static 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+
753+static 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+
757+static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", 0x13c, 16, 8, BIT(31), 0);
758+
759+static SUNXI_CCU_GATE(codec_clk, "codec", "pll-audio",
760+ 0x140, BIT(31), CLK_SET_RATE_PARENT);
761+
762+static SUNXI_CCU_GATE(avs_clk, "avs", "hosc", 0x144, BIT(31), 0);
763+
764+static const char *const ace_parents[] = { "pll-ve", "pll-ddr-other" };
765+static SUNXI_CCU_M_WITH_MUX_GATE(ace_clk, "ace", ace_parents,
766+ 0x148, 0, 4, 24, 1, BIT(31), 0);
767+
768+static 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+
772+static const char *const gpu_parents_sun4i[] = { "pll-video0", "pll-ve",
773+ "pll-ddr-other",
774+ "pll-video1" };
775+static 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+
779+static const char *const gpu_parents_sun7i[] = { "pll-video0", "pll-ve",
780+ "pll-ddr-other", "pll-video1",
781+ "pll-gpu" };
782+static const u8 gpu_table_sun7i[] = { 0, 1, 2, 3, 4 };
783+static 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+
788+static const char *const mbus_sun4i_parents[] = { "hosc", "pll-periph",
789+ "pll-ddr-other" };
790+static 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);
793+static const char *const mbus_sun7i_parents[] = { "hosc", "pll-periph-base",
794+ "pll-ddr-other" };
795+static 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+
799+static SUNXI_CCU_GATE(hdmi1_slow_clk, "hdmi1-slow", "hosc", 0x178, BIT(31), 0);
800+
801+static const char *const hdmi1_parents[] = { "pll-video0", "pll-video1" };
802+static const u8 hdmi1_table[] = { 0, 1};
803+static 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+
808+static const char *const out_parents[] = { "hosc", "osc32k", "hosc" };
809+static const struct ccu_mux_fixed_prediv clk_out_predivs[] = {
810+ { .index = 0, .div = 750, },
811+};
812+
813+static 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+};
832+static 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+
852+static 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 */
1025+static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
1026+ "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
1027+static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
1028+ "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
1029+static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
1030+ "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
1031+static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
1032+ "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
1033+static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x",
1034+ "pll-video0", 1, 2, CLK_SET_RATE_PARENT);
1035+static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x",
1036+ "pll-video1", 1, 2, CLK_SET_RATE_PARENT);
1037+
1038+
1039+static 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+};
1191+static 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+
1365+static 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+
1390+static 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+
1400+static 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+
1410+static 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+
1444+static void __init sun4i_a10_ccu_setup(struct device_node *node)
1445+{
1446+ sun4i_ccu_init(node, &sun4i_a10_ccu_desc);
1447+}
1448+CLK_OF_DECLARE(sun4i_a10_ccu, "allwinner,sun4i-a10-ccu",
1449+ sun4i_a10_ccu_setup);
1450+
1451+static void __init sun7i_a20_ccu_setup(struct device_node *node)
1452+{
1453+ sun4i_ccu_init(node, &sun7i_a20_ccu_desc);
1454+}
1455+CLK_OF_DECLARE(sun7i_a20_ccu, "allwinner,sun7i-a20-ccu",
1456+ sun7i_a20_ccu_setup);
drivers/clk/sunxi-ng/ccu-sun4i-a10.h+61−0
@@ -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_ */
drivers/clk/sunxi-ng/ccu-sun5i.c+1−2
@@ -976,8 +976,7 @@ static void __init sun5i_ccu_init(struct device_node *node, · 975 unmodified lines
976976
977977 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
978978 if (IS_ERR(reg)) {
979− pr_err("%s: Could not map the clock registers\n",
980− of_node_full_name(node));
979+ pr_err("%pOF: Could not map the clock registers\n", node);
981980 return;
982981 }
983982
drivers/clk/sunxi-ng/ccu-sun6i-a31.c+1−2
@@ -1217,8 +1217,7 @@ static void __init sun6i_a31_ccu_setup(struct device_node *node) · 1216 unmodified lines
12171217
12181218 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
12191219 if (IS_ERR(reg)) {
1220− pr_err("%s: Could not map the clock registers\n",
1221− of_node_full_name(node));
1220+ pr_err("%pOF: Could not map the clock registers\n", node);
12221221 return;
12231222 }
12241223
drivers/clk/sunxi-ng/ccu-sun8i-a23.c+1−2
@@ -716,8 +716,7 @@ static void __init sun8i_a23_ccu_setup(struct device_node *node) · 715 unmodified lines
716716
717717 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
718718 if (IS_ERR(reg)) {
719− pr_err("%s: Could not map the clock registers\n",
720− of_node_full_name(node));
719+ pr_err("%pOF: Could not map the clock registers\n", node);
721720 return;
722721 }
723722
drivers/clk/sunxi-ng/ccu-sun8i-a33.c+1−2
@@ -777,8 +777,7 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node) · 776 unmodified lines
777777
778778 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
779779 if (IS_ERR(reg)) {
780− pr_err("%s: Could not map the clock registers\n",
781− of_node_full_name(node));
780+ pr_err("%pOF: Could not map the clock registers\n", node);
782781 return;
783782 }
784783
drivers/clk/sunxi-ng/ccu-sun8i-h3.c+13−3
@@ -135,7 +135,7 @@ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de", · 134 unmodified lines
135135 static const char * const cpux_parents[] = { "osc32k", "osc24M",
136136 "pll-cpux" , "pll-cpux" };
137137 static 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);
139139
140140 static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0);
141141
@@ -1103,6 +1103,13 @@ static const struct sunxi_ccu_desc sun50i_h5_ccu_desc = { · 961 unmodified lines
11031103 .num_resets = ARRAY_SIZE(sun50i_h5_ccu_resets),
11041104 };
11051105
1106+static 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+
11061113 static struct ccu_mux_nb sun8i_h3_cpu_nb = {
11071114 .common = &cpux_clk.common,
11081115 .cm = &cpux_clk.mux,
@@ -1118,8 +1125,7 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node, · 9 unmodified lines
11181125
11191126 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
11201127 if (IS_ERR(reg)) {
1121− pr_err("%s: Could not map the clock registers\n",
1122− of_node_full_name(node));
1128+ pr_err("%pOF: Could not map the clock registers\n", node);
11231129 return;
11241130 }
11251131
@@ -1130,6 +1136,10 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node, · 4 unmodified lines
11301136
11311137 sunxi_ccu_probe(node, reg, desc);
11321138
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 */
11331143 ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
11341144 &sun8i_h3_cpu_nb);
11351145 }
drivers/clk/sunxi-ng/ccu-sun8i-r.c+1−2
@@ -290,8 +290,7 @@ static void __init sunxi_r_ccu_init(struct device_node *node, · 289 unmodified lines
290290
291291 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
292292 if (IS_ERR(reg)) {
293− pr_err("%s: Could not map the clock registers\n",
294− of_node_full_name(node));
293+ pr_err("%pOF: Could not map the clock registers\n", node);
295294 return;
296295 }
297296
drivers/clk/sunxi-ng/ccu-sun8i-r.h+1−1
@@ -13,7 +13,7 @@ · 12 unmodified lines
1313 */
1414
1515 #ifndef _CCU_SUN8I_R_H
16−#define _CCU_SUN8I_R_H_
16+#define _CCU_SUN8I_R_H
1717
1818 #include <dt-bindings/clock/sun8i-r-ccu.h>
1919 #include <dt-bindings/reset/sun8i-r-ccu.h>
drivers/clk/sunxi-ng/ccu-sun8i-r40.c+1290−0
@@ -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. */
33+static 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+
59+static 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. */
68+static 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. */
81+static 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. */
94+static 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. */
104+static 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+
119+static 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. */
138+static 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. */
154+static 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+
166+static 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+
182+static const char * const pll_sata_out_parents[] = { "pll-sata",
183+ "pll-periph0-sata" };
184+static 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. */
191+static 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+
215+static const char * const pll_mipi_parents[] = { "pll-video0" };
216+static 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. */
233+static 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. */
246+static 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+
254+static const char * const cpu_parents[] = { "osc32k", "osc24M",
255+ "pll-cpu", "pll-cpu" };
256+static SUNXI_CCU_MUX(cpu_clk, "cpu", cpu_parents,
257+ 0x050, 16, 2, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT);
258+
259+static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x050, 0, 2, 0);
260+
261+static const char * const ahb1_parents[] = { "osc32k", "osc24M",
262+ "axi", "pll-periph0" };
263+static const struct ccu_mux_var_prediv ahb1_predivs[] = {
264+ { .index = 3, .shift = 6, .width = 2 },
265+};
266+static 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+
287+static 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+};
294+static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1",
295+ 0x054, 8, 2, apb1_div_table, 0);
296+
297+static const char * const apb2_parents[] = { "osc32k", "osc24M",
298+ "pll-periph0-2x",
299+ "pll-periph0-2x" };
300+static 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+
306+static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb1",
307+ 0x060, BIT(1), 0);
308+static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "ahb1",
309+ 0x060, BIT(5), 0);
310+static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1",
311+ 0x060, BIT(6), 0);
312+static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1",
313+ 0x060, BIT(8), 0);
314+static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1",
315+ 0x060, BIT(9), 0);
316+static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1",
317+ 0x060, BIT(10), 0);
318+static SUNXI_CCU_GATE(bus_mmc3_clk, "bus-mmc3", "ahb1",
319+ 0x060, BIT(11), 0);
320+static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb1",
321+ 0x060, BIT(13), 0);
322+static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1",
323+ 0x060, BIT(14), 0);
324+static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb1",
325+ 0x060, BIT(17), 0);
326+static SUNXI_CCU_GATE(bus_ts_clk, "bus-ts", "ahb1",
327+ 0x060, BIT(18), 0);
328+static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1",
329+ 0x060, BIT(19), 0);
330+static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1",
331+ 0x060, BIT(20), 0);
332+static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb1",
333+ 0x060, BIT(21), 0);
334+static SUNXI_CCU_GATE(bus_spi2_clk, "bus-spi2", "ahb1",
335+ 0x060, BIT(22), 0);
336+static SUNXI_CCU_GATE(bus_spi3_clk, "bus-spi3", "ahb1",
337+ 0x060, BIT(23), 0);
338+static SUNXI_CCU_GATE(bus_sata_clk, "bus-sata", "ahb1",
339+ 0x060, BIT(24), 0);
340+static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1",
341+ 0x060, BIT(25), 0);
342+static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb1",
343+ 0x060, BIT(26), 0);
344+static SUNXI_CCU_GATE(bus_ehci1_clk, "bus-ehci1", "ahb1",
345+ 0x060, BIT(27), 0);
346+static SUNXI_CCU_GATE(bus_ehci2_clk, "bus-ehci2", "ahb1",
347+ 0x060, BIT(28), 0);
348+static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb1",
349+ 0x060, BIT(29), 0);
350+static SUNXI_CCU_GATE(bus_ohci1_clk, "bus-ohci1", "ahb1",
351+ 0x060, BIT(30), 0);
352+static SUNXI_CCU_GATE(bus_ohci2_clk, "bus-ohci2", "ahb1",
353+ 0x060, BIT(31), 0);
354+
355+static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb1",
356+ 0x064, BIT(0), 0);
357+static SUNXI_CCU_GATE(bus_mp_clk, "bus-mp", "ahb1",
358+ 0x064, BIT(2), 0);
359+static SUNXI_CCU_GATE(bus_deinterlace_clk, "bus-deinterlace", "ahb1",
360+ 0x064, BIT(5), 0);
361+static SUNXI_CCU_GATE(bus_csi0_clk, "bus-csi0", "ahb1",
362+ 0x064, BIT(8), 0);
363+static SUNXI_CCU_GATE(bus_csi1_clk, "bus-csi1", "ahb1",
364+ 0x064, BIT(9), 0);
365+static SUNXI_CCU_GATE(bus_hdmi0_clk, "bus-hdmi0", "ahb1",
366+ 0x064, BIT(10), 0);
367+static SUNXI_CCU_GATE(bus_hdmi1_clk, "bus-hdmi1", "ahb1",
368+ 0x064, BIT(11), 0);
369+static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "ahb1",
370+ 0x064, BIT(12), 0);
371+static SUNXI_CCU_GATE(bus_tve0_clk, "bus-tve0", "ahb1",
372+ 0x064, BIT(13), 0);
373+static SUNXI_CCU_GATE(bus_tve1_clk, "bus-tve1", "ahb1",
374+ 0x064, BIT(14), 0);
375+static SUNXI_CCU_GATE(bus_tve_top_clk, "bus-tve-top", "ahb1",
376+ 0x064, BIT(15), 0);
377+static SUNXI_CCU_GATE(bus_gmac_clk, "bus-gmac", "ahb1",
378+ 0x064, BIT(17), 0);
379+static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "ahb1",
380+ 0x064, BIT(20), 0);
381+static SUNXI_CCU_GATE(bus_tvd0_clk, "bus-tvd0", "ahb1",
382+ 0x064, BIT(21), 0);
383+static SUNXI_CCU_GATE(bus_tvd1_clk, "bus-tvd1", "ahb1",
384+ 0x064, BIT(22), 0);
385+static SUNXI_CCU_GATE(bus_tvd2_clk, "bus-tvd2", "ahb1",
386+ 0x064, BIT(23), 0);
387+static SUNXI_CCU_GATE(bus_tvd3_clk, "bus-tvd3", "ahb1",
388+ 0x064, BIT(24), 0);
389+static SUNXI_CCU_GATE(bus_tvd_top_clk, "bus-tvd-top", "ahb1",
390+ 0x064, BIT(25), 0);
391+static SUNXI_CCU_GATE(bus_tcon_lcd0_clk, "bus-tcon-lcd0", "ahb1",
392+ 0x064, BIT(26), 0);
393+static SUNXI_CCU_GATE(bus_tcon_lcd1_clk, "bus-tcon-lcd1", "ahb1",
394+ 0x064, BIT(27), 0);
395+static SUNXI_CCU_GATE(bus_tcon_tv0_clk, "bus-tcon-tv0", "ahb1",
396+ 0x064, BIT(28), 0);
397+static SUNXI_CCU_GATE(bus_tcon_tv1_clk, "bus-tcon-tv1", "ahb1",
398+ 0x064, BIT(29), 0);
399+static SUNXI_CCU_GATE(bus_tcon_top_clk, "bus-tcon-top", "ahb1",
400+ 0x064, BIT(30), 0);
401+
402+static SUNXI_CCU_GATE(bus_codec_clk, "bus-codec", "apb1",
403+ 0x068, BIT(0), 0);
404+static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1",
405+ 0x068, BIT(1), 0);
406+static SUNXI_CCU_GATE(bus_ac97_clk, "bus-ac97", "apb1",
407+ 0x068, BIT(2), 0);
408+static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb1",
409+ 0x068, BIT(5), 0);
410+static SUNXI_CCU_GATE(bus_ir0_clk, "bus-ir0", "apb1",
411+ 0x068, BIT(6), 0);
412+static SUNXI_CCU_GATE(bus_ir1_clk, "bus-ir1", "apb1",
413+ 0x068, BIT(7), 0);
414+static SUNXI_CCU_GATE(bus_ths_clk, "bus-ths", "apb1",
415+ 0x068, BIT(8), 0);
416+static SUNXI_CCU_GATE(bus_keypad_clk, "bus-keypad", "apb1",
417+ 0x068, BIT(10), 0);
418+static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1",
419+ 0x068, BIT(12), 0);
420+static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1",
421+ 0x068, BIT(13), 0);
422+static SUNXI_CCU_GATE(bus_i2s2_clk, "bus-i2s2", "apb1",
423+ 0x068, BIT(14), 0);
424+
425+static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2",
426+ 0x06c, BIT(0), 0);
427+static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2",
428+ 0x06c, BIT(1), 0);
429+static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2",
430+ 0x06c, BIT(2), 0);
431+static 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+ */
437+static SUNXI_CCU_GATE(bus_can_clk, "bus-can", "apb2",
438+ 0x06c, BIT(4), 0);
439+static SUNXI_CCU_GATE(bus_scr_clk, "bus-scr", "apb2",
440+ 0x06c, BIT(5), 0);
441+static SUNXI_CCU_GATE(bus_ps20_clk, "bus-ps20", "apb2",
442+ 0x06c, BIT(6), 0);
443+static SUNXI_CCU_GATE(bus_ps21_clk, "bus-ps21", "apb2",
444+ 0x06c, BIT(7), 0);
445+static SUNXI_CCU_GATE(bus_i2c4_clk, "bus-i2c4", "apb2",
446+ 0x06c, BIT(15), 0);
447+static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2",
448+ 0x06c, BIT(16), 0);
449+static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2",
450+ 0x06c, BIT(17), 0);
451+static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2",
452+ 0x06c, BIT(18), 0);
453+static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2",
454+ 0x06c, BIT(19), 0);
455+static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2",
456+ 0x06c, BIT(20), 0);
457+static SUNXI_CCU_GATE(bus_uart5_clk, "bus-uart5", "apb2",
458+ 0x06c, BIT(21), 0);
459+static SUNXI_CCU_GATE(bus_uart6_clk, "bus-uart6", "apb2",
460+ 0x06c, BIT(22), 0);
461+static SUNXI_CCU_GATE(bus_uart7_clk, "bus-uart7", "apb2",
462+ 0x06c, BIT(23), 0);
463+
464+static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "ahb1",
465+ 0x070, BIT(7), 0);
466+
467+static const char * const ths_parents[] = { "osc24M" };
468+static 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+
481+static const char * const mod0_default_parents[] = { "osc24M", "pll-periph0",
482+ "pll-periph1" };
483+static 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+
490+static 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+
497+static 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+
504+static 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+
511+static 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+
518+static const char * const ts_parents[] = { "osc24M", "pll-periph0", };
519+static 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+
526+static const char * const ce_parents[] = { "osc24M", "pll-periph0-2x",
527+ "pll-periph1-2x" };
528+static 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+
535+static 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+
542+static 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+
549+static 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+
556+static 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+
563+static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
564+ "pll-audio-2x", "pll-audio" };
565+static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents,
566+ 0x0b0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
567+
568+static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", i2s_parents,
569+ 0x0b4, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
570+
571+static SUNXI_CCU_MUX_WITH_GATE(i2s2_clk, "i2s2", i2s_parents,
572+ 0x0b8, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
573+
574+static SUNXI_CCU_MUX_WITH_GATE(ac97_clk, "ac97", i2s_parents,
575+ 0x0bc, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
576+
577+static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", i2s_parents,
578+ 0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
579+
580+static const char * const keypad_parents[] = { "osc24M", "osc32k" };
581+static const u8 keypad_table[] = { 0, 2 };
582+static 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+
596+static const char * const sata_parents[] = { "pll-sata-out", "sata-ext" };
597+static 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+
606+static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
607+ 0x0cc, BIT(8), 0);
608+static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M",
609+ 0x0cc, BIT(9), 0);
610+static SUNXI_CCU_GATE(usb_phy2_clk, "usb-phy2", "osc24M",
611+ 0x0cc, BIT(10), 0);
612+static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc12M",
613+ 0x0cc, BIT(16), 0);
614+static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc12M",
615+ 0x0cc, BIT(17), 0);
616+static SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc12M",
617+ 0x0cc, BIT(18), 0);
618+
619+static const char * const ir_parents[] = { "osc24M", "pll-periph0",
620+ "pll-periph1", "osc32k" };
621+static 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+
628+static 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+
635+static const char * const dram_parents[] = { "pll-ddr0", "pll-ddr1" };
636+static SUNXI_CCU_M_WITH_MUX(dram_clk, "dram", dram_parents,
637+ 0x0f4, 0, 2, 20, 2, CLK_IS_CRITICAL);
638+
639+static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "dram",
640+ 0x100, BIT(0), 0);
641+static SUNXI_CCU_GATE(dram_csi0_clk, "dram-csi0", "dram",
642+ 0x100, BIT(1), 0);
643+static SUNXI_CCU_GATE(dram_csi1_clk, "dram-csi1", "dram",
644+ 0x100, BIT(2), 0);
645+static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "dram",
646+ 0x100, BIT(3), 0);
647+static SUNXI_CCU_GATE(dram_tvd_clk, "dram-tvd", "dram",
648+ 0x100, BIT(4), 0);
649+static SUNXI_CCU_GATE(dram_mp_clk, "dram-mp", "dram",
650+ 0x100, BIT(5), 0);
651+static SUNXI_CCU_GATE(dram_deinterlace_clk, "dram-deinterlace", "dram",
652+ 0x100, BIT(6), 0);
653+
654+static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" };
655+static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
656+ 0x104, 0, 4, 24, 3, BIT(31), 0);
657+static SUNXI_CCU_M_WITH_MUX_GATE(mp_clk, "mp", de_parents,
658+ 0x108, 0, 4, 24, 3, BIT(31), 0);
659+
660+static const char * const tcon_parents[] = { "pll-video0", "pll-video1",
661+ "pll-video0-2x", "pll-video1-2x",
662+ "pll-mipi" };
663+static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd0_clk, "tcon-lcd0", tcon_parents,
664+ 0x110, 24, 3, BIT(31), CLK_SET_RATE_PARENT);
665+static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd1_clk, "tcon-lcd1", tcon_parents,
666+ 0x114, 24, 3, BIT(31), CLK_SET_RATE_PARENT);
667+static SUNXI_CCU_M_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0", tcon_parents,
668+ 0x118, 0, 4, 24, 3, BIT(31), 0);
669+static SUNXI_CCU_M_WITH_MUX_GATE(tcon_tv1_clk, "tcon-tv1", tcon_parents,
670+ 0x11c, 0, 4, 24, 3, BIT(31), 0);
671+
672+static const char * const deinterlace_parents[] = { "pll-periph0",
673+ "pll-periph1" };
674+static SUNXI_CCU_M_WITH_MUX_GATE(deinterlace_clk, "deinterlace",
675+ deinterlace_parents, 0x124, 0, 4, 24, 3,
676+ BIT(31), 0);
677+
678+static const char * const csi_mclk_parents[] = { "osc24M", "pll-video1",
679+ "pll-periph1" };
680+static SUNXI_CCU_M_WITH_MUX_GATE(csi1_mclk_clk, "csi1-mclk", csi_mclk_parents,
681+ 0x130, 0, 5, 8, 3, BIT(15), 0);
682+
683+static const char * const csi_sclk_parents[] = { "pll-periph0", "pll-periph1" };
684+static SUNXI_CCU_M_WITH_MUX_GATE(csi_sclk_clk, "csi-sclk", csi_sclk_parents,
685+ 0x134, 16, 4, 24, 3, BIT(31), 0);
686+
687+static SUNXI_CCU_M_WITH_MUX_GATE(csi0_mclk_clk, "csi0-mclk", csi_mclk_parents,
688+ 0x134, 0, 5, 8, 3, BIT(15), 0);
689+
690+static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
691+ 0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT);
692+
693+static SUNXI_CCU_GATE(codec_clk, "codec", "pll-audio",
694+ 0x140, BIT(31), CLK_SET_RATE_PARENT);
695+static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M",
696+ 0x144, BIT(31), 0);
697+
698+static const char * const hdmi_parents[] = { "pll-video0", "pll-video1" };
699+static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents,
700+ 0x150, 0, 4, 24, 2, BIT(31), 0);
701+
702+static 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+ */
712+static const char * const mbus_parents[] = { "osc24M", "pll-periph0-2x",
713+ "pll-ddr0" };
714+static 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+
721+static const char * const dsi_dphy_parents[] = { "pll-video0", "pll-video1",
722+ "pll-periph0" };
723+static SUNXI_CCU_M_WITH_MUX_GATE(dsi_dphy_clk, "dsi-dphy", dsi_dphy_parents,
724+ 0x168, 0, 4, 8, 2, BIT(15), 0);
725+
726+static SUNXI_CCU_M_WITH_MUX_GATE(tve0_clk, "tve0", tcon_parents,
727+ 0x180, 0, 4, 24, 3, BIT(31), 0);
728+static SUNXI_CCU_M_WITH_MUX_GATE(tve1_clk, "tve1", tcon_parents,
729+ 0x184, 0, 4, 24, 3, BIT(31), 0);
730+
731+static const char * const tvd_parents[] = { "pll-video0", "pll-video1",
732+ "pll-video0-2x", "pll-video1-2x" };
733+static SUNXI_CCU_M_WITH_MUX_GATE(tvd0_clk, "tvd0", tvd_parents,
734+ 0x188, 0, 4, 24, 3, BIT(31), 0);
735+static SUNXI_CCU_M_WITH_MUX_GATE(tvd1_clk, "tvd1", tvd_parents,
736+ 0x18c, 0, 4, 24, 3, BIT(31), 0);
737+static SUNXI_CCU_M_WITH_MUX_GATE(tvd2_clk, "tvd2", tvd_parents,
738+ 0x190, 0, 4, 24, 3, BIT(31), 0);
739+static SUNXI_CCU_M_WITH_MUX_GATE(tvd3_clk, "tvd3", tvd_parents,
740+ 0x194, 0, 4, 24, 3, BIT(31), 0);
741+
742+static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu",
743+ 0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT);
744+
745+static const char * const out_parents[] = { "osc24M", "osc32k", "osc24M" };
746+static const struct ccu_mux_fixed_prediv out_predivs[] = {
747+ { .index = 0, .div = 750, },
748+};
749+
750+static 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+
768+static 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+
786+static 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 */
947+static CLK_FIXED_FACTOR(osc12M_clk, "osc12M", "osc24M", 2, 1, 0);
948+
949+/* We hardcode the divider to 4 for now */
950+static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
951+ "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
952+static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
953+ "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
954+static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
955+ "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
956+static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
957+ "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
958+static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x",
959+ "pll-periph0", 1, 2, 0);
960+static CLK_FIXED_FACTOR(pll_periph1_2x_clk, "pll-periph1-2x",
961+ "pll-periph1", 1, 2, 0);
962+static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x",
963+ "pll-video0", 1, 2, 0);
964+static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x",
965+ "pll-video1", 1, 2, 0);
966+
967+static 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+
1139+static 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+
1229+static 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+
1239+static 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+
1246+static 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+
1253+static 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+}
1289+CLK_OF_DECLARE(sun8i_r40_ccu, "allwinner,sun8i-r40-ccu",
1290+ sun8i_r40_ccu_setup);
drivers/clk/sunxi-ng/ccu-sun8i-r40.h+69−0
@@ -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_ */
drivers/clk/sunxi-ng/ccu-sun8i-v3s.c+1−2
@@ -575,8 +575,7 @@ static void __init sun8i_v3s_ccu_setup(struct device_node *node) · 574 unmodified lines
575575
576576 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
577577 if (IS_ERR(reg)) {
578− pr_err("%s: Could not map the clock registers\n",
579− of_node_full_name(node));
578+ pr_err("%pOF: Could not map the clock registers\n", node);
580579 return;
581580 }
582581
drivers/clk/sunxi-ng/ccu_div.c+19−3
@@ -21,10 +21,18 @@ static unsigned long ccu_div_round_rate(struct ccu_mux_internal *mux, · 20 unmodified lines
2121 {
2222 struct ccu_div *cd = data;
2323
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,
2528 rate, parent_rate,
2629 cd->div.table, cd->div.width,
2730 cd->div.flags);
31+
32+ if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
33+ rate /= cd->fixed_post_div;
34+
35+ return rate;
2836 }
2937
3038 static void ccu_div_disable(struct clk_hw *hw)
@@ -62,8 +70,13 @@ static unsigned long ccu_div_recalc_rate(struct clk_hw *hw, · 31 unmodified lines
6270 parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1,
6371 parent_rate);
6472
65− return divider_recalc_rate(hw, parent_rate, val, cd->div.table,
66− cd->div.flags);
73+ val = divider_recalc_rate(hw, parent_rate, val, cd->div.table,
74+ cd->div.flags);
75+
76+ if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
77+ val /= cd->fixed_post_div;
78+
79+ return val;
6780 }
6881
6982 static 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, · 16 unmodified lines
8699 parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1,
87100 parent_rate);
88101
102+ if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
103+ rate *= cd->fixed_post_div;
104+
89105 val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width,
90106 cd->div.flags);
91107
drivers/clk/sunxi-ng/ccu_div.h+2−1
@@ -86,9 +86,10 @@ struct ccu_div_internal { · 85 unmodified lines
8686 struct ccu_div {
8787 u32 enable;
8888
89− struct ccu_div_internal div;
89+ struct ccu_div_internal div;
9090 struct ccu_mux_internal mux;
9191 struct ccu_common common;
92+ unsigned int fixed_post_div;
9293 };
9394
9495 #define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg, \
drivers/clk/sunxi-ng/ccu_frac.c+8−6
@@ -67,25 +67,25 @@ unsigned long ccu_frac_helper_read_rate(struct ccu_common *common, · 66 unmodified lines
6767 {
6868 u32 reg;
6969
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));
7171
7272 if (!(common->features & CCU_FEATURE_FRACTIONAL))
7373 return 0;
7474
75− printk("%s: clock is fractional (rates %lu and %lu)\n",
76− clk_hw_get_name(&common->hw), cf->rates[0], cf->rates[1]);
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]);
7777
7878 reg = readl(common->base + common->reg);
7979
80− printk("%s: clock reg is 0x%x (select is 0x%x)\n",
81− clk_hw_get_name(&common->hw), reg, cf->select);
80+ pr_debug("%s: clock reg is 0x%x (select is 0x%x)\n",
81+ clk_hw_get_name(&common->hw), reg, cf->select);
8282
8383 return (reg & cf->select) ? cf->rates[1] : cf->rates[0];
8484 }
8585
8686 int ccu_frac_helper_set_rate(struct ccu_common *common,
8787 struct ccu_frac_internal *cf,
88− unsigned long rate)
88+ unsigned long rate, u32 lock)
8989 {
9090 unsigned long flags;
9191 u32 reg, sel;
@@ -106,5 +106,7 @@ int ccu_frac_helper_set_rate(struct ccu_common *common, · 14 unmodified lines
106106 writel(reg | sel, common->base + common->reg);
107107 spin_unlock_irqrestore(common->lock, flags);
108108
109+ ccu_helper_wait_for_lock(common, lock);
110+
109111 return 0;
110112 }
drivers/clk/sunxi-ng/ccu_frac.h+1−1
@@ -48,6 +48,6 @@ unsigned long ccu_frac_helper_read_rate(struct ccu_common *common, · 47 unmodified lines
4848
4949 int ccu_frac_helper_set_rate(struct ccu_common *common,
5050 struct ccu_frac_internal *cf,
51− unsigned long rate);
51+ unsigned long rate, u32 lock);
5252
5353 #endif /* _CCU_FRAC_H_ */
drivers/clk/sunxi-ng/ccu_mult.c+7−3
@@ -111,10 +111,14 @@ static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate, · 110 unmodified lines
111111 unsigned long flags;
112112 u32 reg;
113113
114− if (ccu_frac_helper_has_rate(&cm->common, &cm->frac, rate))
115− return ccu_frac_helper_set_rate(&cm->common, &cm->frac, rate);
116− else
114+ if (ccu_frac_helper_has_rate(&cm->common, &cm->frac, rate)) {
115+ ccu_frac_helper_enable(&cm->common, &cm->frac);
116+
117+ return ccu_frac_helper_set_rate(&cm->common, &cm->frac,
118+ rate, cm->lock);
119+ } else {
117120 ccu_frac_helper_disable(&cm->common, &cm->frac);
121+ }
118122
119123 parent_rate = ccu_mux_helper_apply_prediv(&cm->common, &cm->mux, -1,
120124 parent_rate);
drivers/clk/sunxi-ng/ccu_nkm.c+19−3
@@ -75,7 +75,7 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw, · 74 unmodified lines
7575 unsigned long parent_rate)
7676 {
7777 struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
78− unsigned long n, m, k;
78+ unsigned long n, m, k, rate;
7979 u32 reg;
8080
8181 reg = readl(nkm->common.base + nkm->common.reg);
@@ -98,7 +98,12 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw, · 16 unmodified lines
9898 if (!m)
9999 m++;
100100
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;
102107 }
103108
104109 static 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, · 12 unmodified lines
117122 _nkm.min_m = 1;
118123 _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
119124
125+ if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
126+ rate *= nkm->fixed_post_div;
127+
120128 ccu_nkm_find_best(*parent_rate, rate, &_nkm);
121129
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;
123136 }
124137
125138 static 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, · 13 unmodified lines
139152 unsigned long flags;
140153 u32 reg;
141154
155+ if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
156+ rate *= nkm->fixed_post_div;
157+
142158 _nkm.min_n = nkm->n.min ?: 1;
143159 _nkm.max_n = nkm->n.max ?: 1 << nkm->n.width;
144160 _nkm.min_k = nkm->k.min ?: 1;
drivers/clk/sunxi-ng/ccu_nkm.h+2−0
@@ -34,6 +34,8 @@ struct ccu_nkm { · 33 unmodified lines
3434 struct ccu_div_internal m;
3535 struct ccu_mux_internal mux;
3636
37+ unsigned int fixed_post_div;
38+
3739 struct ccu_common common;
3840 };
3941
drivers/clk/sunxi-ng/ccu_nm.c+16−3
@@ -117,10 +117,23 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate, · 116 unmodified lines
117117 unsigned long flags;
118118 u32 reg;
119119
120− if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate))
121− return ccu_frac_helper_set_rate(&nm->common, &nm->frac, rate);
122− else
120+ if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) {
121+ spin_lock_irqsave(nm->common.lock, flags);
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 {
123135 ccu_frac_helper_disable(&nm->common, &nm->frac);
136+ }
124137
125138 _nm.min_n = nm->n.min ?: 1;
126139 _nm.max_n = nm->n.max ?: 1 << nm->n.width;
drivers/clk/sunxi/clk-sun8i-bus-gates.c+4−0
@@ -78,6 +78,10 @@ static void __init sun8i_h3_bus_gates_init(struct device_node *node) · 77 unmodified lines
7878 clk_parent = APB1;
7979 else if (index >= 96 && index <= 127)
8080 clk_parent = APB2;
81+ else {
82+ WARN_ON(true);
83+ continue;
84+ }
8185
8286 clk_reg = reg + 4 * (index / 32);
8387 clk_bit = index % 32;
drivers/clk/sunxi/clk-sunxi.c+7−10
@@ -666,15 +666,14 @@ static struct clk * __init sunxi_mux_clk_setup(struct device_node *node, · 665 unmodified lines
666666
667667 reg = of_iomap(node, 0);
668668 if (!reg) {
669− pr_err("Could not map registers for mux-clk: %s\n",
670− of_node_full_name(node));
669+ pr_err("Could not map registers for mux-clk: %pOF\n", node);
671670 return NULL;
672671 }
673672
674673 i = of_clk_parent_fill(node, parents, SUNXI_MAX_PARENTS);
675674 if (of_property_read_string(node, "clock-output-names", &clk_name)) {
676− pr_err("%s: could not read clock-output-names from \"%s\"\n",
677− __func__, of_node_full_name(node));
675+ pr_err("%s: could not read clock-output-names from \"%pOF\"\n",
676+ __func__, node);
678677 goto out_unmap;
679678 }
680679
@@ -797,16 +796,15 @@ static void __init sunxi_divider_clk_setup(struct device_node *node, · 116 unmodified lines
797796
798797 reg = of_iomap(node, 0);
799798 if (!reg) {
800− pr_err("Could not map registers for mux-clk: %s\n",
801− of_node_full_name(node));
799+ pr_err("Could not map registers for mux-clk: %pOF\n", node);
802800 return;
803801 }
804802
805803 clk_parent = of_clk_get_parent_name(node, 0);
806804
807805 if (of_property_read_string(node, "clock-output-names", &clk_name)) {
808− pr_err("%s: could not read clock-output-names from \"%s\"\n",
809− __func__, of_node_full_name(node));
806+ pr_err("%s: could not read clock-output-names from \"%pOF\"\n",
807+ __func__, node);
810808 goto out_unmap;
811809 }
812810
@@ -1010,8 +1008,7 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, · 197 unmodified lines
10101008
10111009 reg = of_iomap(node, 0);
10121010 if (!reg) {
1013− pr_err("Could not map registers for divs-clk: %s\n",
1014− of_node_full_name(node));
1011+ pr_err("Could not map registers for divs-clk: %pOF\n", node);
10151012 return NULL;
10161013 }
10171014
drivers/clk/tegra/clk-emc.c+5−7
@@ -378,7 +378,7 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra, · 377 unmodified lines
378378
379379 err = of_property_read_u32(node, "clock-frequency", &tmp);
380380 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);
382382 return err;
383383 }
384384
@@ -386,8 +386,7 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra, · 1 unmodified line
386386
387387 err = of_property_read_u32(node, "nvidia,parent-clock-frequency", &tmp);
388388 if (err) {
389− pr_err("timing %s: failed to read parent rate\n",
390− node->full_name);
389+ pr_err("timing %pOF: failed to read parent rate\n", node);
391390 return err;
392391 }
393392
@@ -395,8 +394,7 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra, · 1 unmodified line
395394
396395 timing->parent = of_clk_get_by_name(node, "emc-parent");
397396 if (IS_ERR(timing->parent)) {
398− pr_err("timing %s: failed to get parent clock\n",
399− node->full_name);
397+ pr_err("timing %pOF: failed to get parent clock\n", node);
400398 return PTR_ERR(timing->parent);
401399 }
402400
@@ -409,8 +407,8 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra, · 6 unmodified lines
409407 }
410408 }
411409 if (timing->parent_index == 0xff) {
412− pr_err("timing %s: %s is not a valid parent\n",
413− node->full_name, __clk_get_name(timing->parent));
410+ pr_err("timing %pOF: %s is not a valid parent\n",
411+ node, __clk_get_name(timing->parent));
414412 clk_put(timing->parent);
415413 return -EINVAL;
416414 }
drivers/clk/tegra/clk-pll.c+38−121
@@ -363,7 +363,7 @@ static void _clk_pll_enable(struct clk_hw *hw) · 362 unmodified lines
363363 val = pll_readl(pll->params->iddq_reg, pll);
364364 val &= ~BIT(pll->params->iddq_bit_idx);
365365 pll_writel(val, pll->params->iddq_reg, pll);
366− udelay(2);
366+ udelay(5);
367367 }
368368
369369 if (pll->params->reset_reg) {
@@ -418,6 +418,26 @@ static void _clk_pll_disable(struct clk_hw *hw) · 48 unmodified lines
418418 }
419419 }
420420
421+static 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+
431+static 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+
421441 static int clk_pll_enable(struct clk_hw *hw)
422442 {
423443 struct tegra_clk_pll *pll = to_clk_pll(hw);
@@ -431,6 +451,8 @@ static int clk_pll_enable(struct clk_hw *hw) · 7 unmodified lines
431451
432452 ret = clk_pll_wait_for_lock(pll);
433453
454+ pll_clk_start_ss(pll);
455+
434456 if (pll->lock)
435457 spin_unlock_irqrestore(pll->lock, flags);
436458
@@ -445,6 +467,8 @@ static void clk_pll_disable(struct clk_hw *hw) · 8 unmodified lines
445467 if (pll->lock)
446468 spin_lock_irqsave(pll->lock, flags);
447469
470+ pll_clk_stop_ss(pll);
471+
448472 _clk_pll_disable(hw);
449473
450474 if (pll->lock)
@@ -666,6 +690,8 @@ static void _get_pll_mnp(struct tegra_clk_pll *pll, · 215 unmodified lines
666690 struct tegra_clk_pll_params *params = pll->params;
667691 struct div_nmp *div_nmp = params->div_nmp;
668692
693+ *cfg = (struct tegra_clk_pll_freq_table) { };
694+
669695 if ((params->flags & (TEGRA_PLLM | TEGRA_PLLMB)) &&
670696 (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) &
671697 PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) {
@@ -716,26 +742,6 @@ static void _update_pll_cpcon(struct tegra_clk_pll *pll, · 44 unmodified lines
716742 pll_writel_misc(val, pll);
717743 }
718744
719−static 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−
729−static 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−
739745 static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
740746 unsigned long rate)
741747 {
@@ -2251,7 +2257,7 @@ tegra_clk_register_pllu_tegra114(const char *name, const char *parent_name, · 1509 unmodified lines
22512257 }
22522258 #endif
22532259
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)
22552261 static const struct clk_ops tegra_clk_pllss_ops = {
22562262 .is_enabled = clk_pll_is_enabled,
22572263 .enable = clk_pll_enable,
@@ -2349,7 +2355,6 @@ struct clk *tegra_clk_register_pllre_tegra210(const char *name, · 91 unmodified lines
23492355 struct tegra_clk_pll_params *pll_params,
23502356 spinlock_t *lock, unsigned long parent_rate)
23512357 {
2352− u32 val;
23532358 struct tegra_clk_pll *pll;
23542359 struct clk *clk;
23552360
@@ -2363,26 +2368,8 @@ struct clk *tegra_clk_register_pllre_tegra210(const char *name, · 7 unmodified lines
23632368 if (IS_ERR(pll))
23642369 return ERR_CAST(pll);
23652370
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−
23842371 clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
2385− &tegra_clk_pllre_ops);
2372+ &tegra_clk_pll_ops);
23862373 if (IS_ERR(clk))
23872374 kfree(pll);
23882375
@@ -2604,46 +2591,6 @@ struct clk *tegra_clk_register_pllc_tegra210(const char *name, · 215 unmodified lines
26042591 return clk;
26052592 }
26062593
2607−struct 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−
26472594 struct clk *tegra_clk_register_pllss_tegra210(const char *name,
26482595 const char *parent_name, void __iomem *clk_base,
26492596 unsigned long flags,
@@ -2652,10 +2599,8 @@ struct clk *tegra_clk_register_pllss_tegra210(const char *name, · 2 unmodified lines
26522599 {
26532600 struct tegra_clk_pll *pll;
26542601 struct clk *clk, *parent;
2655− struct tegra_clk_pll_freq_table cfg;
26562602 unsigned long parent_rate;
26572603 u32 val;
2658− int i;
26592604
26602605 if (!pll_params->div_nmp)
26612606 return ERR_PTR(-EINVAL);
@@ -2667,13 +2612,11 @@ struct clk *tegra_clk_register_pllss_tegra210(const char *name, · 5 unmodified lines
26672612 return ERR_PTR(-EINVAL);
26682613 }
26692614
2670− pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
2671− if (IS_ERR(pll))
2672− return ERR_CAST(pll);
2673−
2674− val = pll_readl_base(pll);
2675− val &= ~PLLSS_REF_SRC_SEL_MASK;
2676− pll_writel_base(val, pll);
2615+ val = readl_relaxed(clk_base + pll_params->base_reg);
2616+ if (val & PLLSS_REF_SRC_SEL_MASK) {
2617+ WARN(1, "not supported reference clock for %s\n", name);
2618+ return ERR_PTR(-EINVAL);
2619+ }
26772620
26782621 parent_rate = clk_get_rate(parent);
26792622
@@ -2683,36 +2626,10 @@ struct clk *tegra_clk_register_pllss_tegra210(const char *name, · 3 unmodified lines
26832626 pll_params->vco_min = pll_params->adjust_vco(pll_params,
26842627 parent_rate);
26852628
2686− /* initialize PLL to minimum rate */
2687−
2688− cfg.m = _pll_fixed_mdiv(pll_params, parent_rate);
2689− cfg.n = cfg.m * pll_params->vco_min / parent_rate;
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);
2629+ pll_params->flags |= TEGRA_PLL_BYPASS;
2630+ pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
2631+ if (IS_ERR(pll))
2632+ return ERR_CAST(pll);
27162633
27172634 clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
27182635 &tegra_clk_pll_ops);
drivers/clk/tegra/clk-tegra-periph.c+2−1
@@ -216,7 +216,8 @@ · 215 unmodified lines
216216 _clk_num, _clk_id) \
217217 TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\
218218 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)
220221
221222 #define XUSB(_name, _parents, _offset, \
222223 _clk_num, _gate_flags, _clk_id) \
drivers/clk/tegra/clk-tegra-super-gen4.c+9−2
@@ -232,8 +232,15 @@ static void __init tegra_super_clk_init(void __iomem *clk_base, · 231 unmodified lines
232232 if (!dt_clk)
233233 return;
234234
235− clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base,
236− pmc_base, CLK_IGNORE_UNUSED, params, NULL);
235+#if defined(CONFIG_ARCH_TEGRA_210_SOC)
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+
237244 *dt_clk = clk;
238245
239246 /* PLLX_OUT0 */
drivers/clk/tegra/clk-tegra210.c+18−14
@@ -146,7 +146,7 @@ · 145 unmodified lines
146146 #define PLLD_SDM_EN_MASK BIT(16)
147147
148148 #define PLLD2_SDM_EN_MASK BIT(31)
149−#define PLLD2_SSC_EN_MASK BIT(30)
149+#define PLLD2_SSC_EN_MASK 0
150150
151151 #define PLLDP_SS_CFG 0x598
152152 #define PLLDP_SDM_EN_MASK BIT(31)
@@ -241,6 +241,9 @@ · 88 unmodified lines
241241 #define PLL_SDM_COEFF BIT(13)
242242 #define sdin_din_to_data(din) ((u16)((din) ? : 0xFFFFU))
243243 #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))
244247
245248 /* Tegra CPU clock and reset control regs */
246249 #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, · 468 unmodified lines
715718 plldss->params->defaults_set = true;
716719
717720 if (val & PLL_ENABLE) {
718− pr_warn("%s already enabled. Postponing set full defaults\n",
719− pll_name);
720721
721722 /*
722723 * 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, · 32 unmodified lines
755756 (~PLLDSS_MISC1_CFG_EN_SDM));
756757 }
757758
759+ if (!plldss->params->defaults_set)
760+ pr_warn("%s already enabled. Postponing set full defaults\n",
761+ pll_name);
762+
758763 /* Enable lock detect */
759764 if (val & PLLDSS_BASE_LOCK_OVERRIDE) {
760765 val &= ~PLLDSS_BASE_LOCK_OVERRIDE;
@@ -1288,8 +1293,7 @@ static int tegra210_pll_fixed_mdiv_cfg(struct clk_hw *hw, · 527 unmodified lines
12881293 s -= PLL_SDM_COEFF / 2;
12891294 cfg->sdm_data = sdin_din_to_data(s);
12901295 }
1291− cfg->output_rate *= cfg->n * PLL_SDM_COEFF + PLL_SDM_COEFF/2 +
1292− sdin_data_to_din(cfg->sdm_data);
1296+ cfg->output_rate *= sdin_get_n_eff(cfg);
12931297 cfg->output_rate /= p * cfg->m * PLL_SDM_COEFF;
12941298 } else {
12951299 cfg->output_rate *= cfg->n;
@@ -1314,8 +1318,7 @@ static int tegra210_pll_fixed_mdiv_cfg(struct clk_hw *hw, · 18 unmodified lines
13141318 */
13151319 static void tegra210_clk_pll_set_gain(struct tegra_clk_pll_freq_table *cfg)
13161320 {
1317− cfg->n = cfg->n * PLL_SDM_COEFF + PLL_SDM_COEFF/2 +
1318− sdin_data_to_din(cfg->sdm_data);
1321+ cfg->n = sdin_get_n_eff(cfg);
13191322 cfg->m *= PLL_SDM_COEFF;
13201323 }
13211324
@@ -2204,7 +2207,6 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { · 882 unmodified lines
22042207 [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true },
22052208 [tegra_clk_pll_g_ref] = { .dt_id = TEGRA210_CLK_PLL_G_REF, .present = true, },
22062209 [tegra_clk_uartb_8] = { .dt_id = TEGRA210_CLK_UARTB, .present = true },
2207− [tegra_clk_vfir] = { .dt_id = TEGRA210_CLK_VFIR, .present = true },
22082210 [tegra_clk_spdif_in_8] = { .dt_id = TEGRA210_CLK_SPDIF_IN, .present = true },
22092211 [tegra_clk_spdif_out] = { .dt_id = TEGRA210_CLK_SPDIF_OUT, .present = true },
22102212 [tegra_clk_vi_10] = { .dt_id = TEGRA210_CLK_VI, .present = true },
@@ -2470,15 +2472,14 @@ static void tegra210_utmi_param_configure(void) · 259 unmodified lines
24702472 reg |= UTMIP_PLL_CFG2_STABLE_COUNT(utmi_parameters[i].stable_count);
24712473
24722474 reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0);
2473−
24742475 reg |=
24752476 UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(utmi_parameters[i].active_delay_count);
24762477 writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2);
24772478
24782479 /* Program UTMIP PLL delay and oscillator frequency counts */
24792480 reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1);
2480− reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0);
24812481
2482+ reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0);
24822483 reg |=
24832484 UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(utmi_parameters[i].enable_delay_count);
24842485
@@ -2494,7 +2495,8 @@ static void tegra210_utmi_param_configure(void) · 9 unmodified lines
24942495 reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN;
24952496 reg |= UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP;
24962497 writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1);
2497− udelay(1);
2498+
2499+ udelay(20);
24982500
24992501 /* Enable samplers for SNPS, XUSB_HOST, XUSB_DEV */
25002502 reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2);
@@ -2552,6 +2554,7 @@ static int tegra210_enable_pllu(void) · 51 unmodified lines
25522554 reg = readl_relaxed(clk_base + pllu.params->ext_misc_reg[0]);
25532555 reg &= ~BIT(pllu.params->iddq_bit_idx);
25542556 writel_relaxed(reg, clk_base + pllu.params->ext_misc_reg[0]);
2557+ udelay(5);
25552558
25562559 reg = readl_relaxed(clk_base + PLLU_BASE);
25572560 reg &= ~GENMASK(20, 0);
@@ -2559,6 +2562,7 @@ static int tegra210_enable_pllu(void) · 1 unmodified line
25592562 reg |= fentry->n << 8;
25602563 reg |= fentry->p << 16;
25612564 writel(reg, clk_base + PLLU_BASE);
2565+ udelay(1);
25622566 reg |= PLL_ENABLE;
25632567 writel(reg, clk_base + PLLU_BASE);
25642568
@@ -2699,7 +2703,7 @@ static void __init tegra210_pll_init(void __iomem *clk_base, · 134 unmodified lines
26992703 struct clk *clk;
27002704
27012705 /* 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,
27032707 pmc, 0, &pll_c_params, NULL);
27042708 if (!WARN_ON(IS_ERR(clk)))
27052709 clk_register_clkdev(clk, "pll_c", NULL);
@@ -2798,14 +2802,14 @@ static void __init tegra210_pll_init(void __iomem *clk_base, · 92 unmodified lines
27982802 /* PLLU_60M */
27992803 clk = clk_register_gate(NULL, "pll_u_60M", "pll_u_out2",
28002804 CLK_SET_RATE_PARENT, clk_base + PLLU_BASE,
2801− 23, 0, NULL);
2805+ 23, 0, &pll_u_lock);
28022806 clk_register_clkdev(clk, "pll_u_60M", NULL);
28032807 clks[TEGRA210_CLK_PLL_U_60M] = clk;
28042808
28052809 /* PLLU_48M */
28062810 clk = clk_register_gate(NULL, "pll_u_48M", "pll_u_out1",
28072811 CLK_SET_RATE_PARENT, clk_base + PLLU_BASE,
2808− 25, 0, NULL);
2812+ 25, 0, &pll_u_lock);
28092813 clk_register_clkdev(clk, "pll_u_48M", NULL);
28102814 clks[TEGRA210_CLK_PLL_U_48M] = clk;
28112815
drivers/clk/tegra/clk.h+0−6
@@ -362,12 +362,6 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, · 361 unmodified lines
362362 struct tegra_clk_pll_params *pll_params,
363363 spinlock_t *lock);
364364
365−struct 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−
371365 struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
372366 void __iomem *clk_base, void __iomem *pmc,
373367 unsigned long flags,
drivers/clk/ti/adpll.c+2−2
@@ -222,7 +222,7 @@ static int ti_adpll_setup_clock(struct ti_adpll_data *d, struct clk *clock, · 221 unmodified lines
222222
223223 /* Separate con_id in format "pll040dcoclkldo" to fit MAX_CON_ID */
224224 postfix = strrchr(name, '.');
225− if (strlen(postfix) > 1) {
225+ if (postfix && strlen(postfix) > 1) {
226226 if (strlen(postfix) > ADPLL_MAX_CON_ID)
227227 dev_warn(d->dev, "clock %s con_id lookup may fail\n",
228228 name);
@@ -486,7 +486,7 @@ static u8 ti_adpll_get_parent(struct clk_hw *hw) · 257 unmodified lines
486486 return 0;
487487 }
488488
489−static struct clk_ops ti_adpll_ops = {
489+static const struct clk_ops ti_adpll_ops = {
490490 .prepare = ti_adpll_prepare,
491491 .unprepare = ti_adpll_unprepare,
492492 .is_prepared = ti_adpll_is_prepared,
drivers/clk/ti/apll.c+1−1
@@ -304,7 +304,7 @@ static void omap2_apll_disable(struct clk_hw *hw) · 303 unmodified lines
304304 ti_clk_ll_ops->clk_writel(v, &ad->control_reg);
305305 }
306306
307−static struct clk_ops omap2_apll_ops = {
307+static const struct clk_ops omap2_apll_ops = {
308308 .enable = &omap2_apll_enable,
309309 .disable = &omap2_apll_disable,
310310 .is_enabled = &omap2_apll_is_enabled,
drivers/clk/ti/clockdomain.c+2−2
@@ -138,8 +138,8 @@ static void __init of_ti_clockdomain_setup(struct device_node *node) · 137 unmodified lines
138138 for (i = 0; i < num_clks; i++) {
139139 clk = of_clk_get(node, i);
140140 if (IS_ERR(clk)) {
141− pr_err("%s: Failed get %s' clock nr %d (%ld)\n",
142− __func__, node->full_name, i, PTR_ERR(clk));
141+ pr_err("%s: Failed get %pOF' clock nr %d (%ld)\n",
142+ __func__, node, i, PTR_ERR(clk));
143143 continue;
144144 }
145145 clk_hw = __clk_get_hw(clk);
drivers/clk/ti/fapll.c+2−2
@@ -268,7 +268,7 @@ static int ti_fapll_set_rate(struct clk_hw *hw, unsigned long rate, · 267 unmodified lines
268268 return 0;
269269 }
270270
271−static struct clk_ops ti_fapll_ops = {
271+static const struct clk_ops ti_fapll_ops = {
272272 .enable = ti_fapll_enable,
273273 .disable = ti_fapll_disable,
274274 .is_enabled = ti_fapll_is_enabled,
@@ -478,7 +478,7 @@ static int ti_fapll_synth_set_rate(struct clk_hw *hw, unsigned long rate, · 203 unmodified lines
478478 return 0;
479479 }
480480
481−static struct clk_ops ti_fapll_synt_ops = {
481+static const struct clk_ops ti_fapll_synt_ops = {
482482 .enable = ti_fapll_synth_enable,
483483 .disable = ti_fapll_synth_disable,
484484 .is_enabled = ti_fapll_synth_is_enabled,
drivers/clk/uniphier/clk-uniphier-core.c+15−11
@@ -110,10 +110,6 @@ static int uniphier_clk_remove(struct platform_device *pdev) · 109 unmodified lines
110110
111111 static const struct of_device_id uniphier_clk_match[] = {
112112 /* System clock */
113− {
114− .compatible = "socionext,uniphier-sld3-clock",
115− .data = uniphier_sld3_sys_clk_data,
116− },
117113 {
118114 .compatible = "socionext,uniphier-ld4-clock",
119115 .data = uniphier_ld4_sys_clk_data,
@@ -142,22 +138,22 @@ static const struct of_device_id uniphier_clk_match[] = { · 22 unmodified lines
142138 .compatible = "socionext,uniphier-ld20-clock",
143139 .data = uniphier_ld20_sys_clk_data,
144140 },
145− /* Media I/O clock, SD clock */
146141 {
147− .compatible = "socionext,uniphier-sld3-mio-clock",
148− .data = uniphier_sld3_mio_clk_data,
142+ .compatible = "socionext,uniphier-pxs3-clock",
143+ .data = uniphier_pxs3_sys_clk_data,
149144 },
145+ /* Media I/O clock, SD clock */
150146 {
151147 .compatible = "socionext,uniphier-ld4-mio-clock",
152− .data = uniphier_sld3_mio_clk_data,
148+ .data = uniphier_ld4_mio_clk_data,
153149 },
154150 {
155151 .compatible = "socionext,uniphier-pro4-mio-clock",
156− .data = uniphier_sld3_mio_clk_data,
152+ .data = uniphier_ld4_mio_clk_data,
157153 },
158154 {
159155 .compatible = "socionext,uniphier-sld8-mio-clock",
160− .data = uniphier_sld3_mio_clk_data,
156+ .data = uniphier_ld4_mio_clk_data,
161157 },
162158 {
163159 .compatible = "socionext,uniphier-pro5-sd-clock",
@@ -169,12 +165,16 @@ static const struct of_device_id uniphier_clk_match[] = { · 5 unmodified lines
169165 },
170166 {
171167 .compatible = "socionext,uniphier-ld11-mio-clock",
172− .data = uniphier_sld3_mio_clk_data,
168+ .data = uniphier_ld4_mio_clk_data,
173169 },
174170 {
175171 .compatible = "socionext,uniphier-ld20-sd-clock",
176172 .data = uniphier_pro5_sd_clk_data,
177173 },
174+ {
175+ .compatible = "socionext,uniphier-pxs3-sd-clock",
176+ .data = uniphier_pro5_sd_clk_data,
177+ },
178178 /* Peripheral clock */
179179 {
180180 .compatible = "socionext,uniphier-ld4-peri-clock",
@@ -204,6 +204,10 @@ static const struct of_device_id uniphier_clk_match[] = { · 23 unmodified lines
204204 .compatible = "socionext,uniphier-ld20-peri-clock",
205205 .data = uniphier_pro4_peri_clk_data,
206206 },
207+ {
208+ .compatible = "socionext,uniphier-pxs3-peri-clock",
209+ .data = uniphier_pro4_peri_clk_data,
210+ },
207211 { /* sentinel */ }
208212 };
209213
drivers/clk/uniphier/clk-uniphier-mio.c+1−3
@@ -76,7 +76,7 @@ · 75 unmodified lines
7676 #define UNIPHIER_MIO_CLK_DMAC(idx) \
7777 UNIPHIER_CLK_GATE("miodmac", (idx), "stdmac", 0x20, 25)
7878
79−const struct uniphier_clk_data uniphier_sld3_mio_clk_data[] = {
79+const struct uniphier_clk_data uniphier_ld4_mio_clk_data[] = {
8080 UNIPHIER_MIO_CLK_SD_FIXED,
8181 UNIPHIER_MIO_CLK_SD(0, 0),
8282 UNIPHIER_MIO_CLK_SD(1, 1),
@@ -85,11 +85,9 @@ const struct uniphier_clk_data uniphier_sld3_mio_clk_data[] = { · 2 unmodified lines
8585 UNIPHIER_MIO_CLK_USB2(8, 0),
8686 UNIPHIER_MIO_CLK_USB2(9, 1),
8787 UNIPHIER_MIO_CLK_USB2(10, 2),
88− UNIPHIER_MIO_CLK_USB2(11, 3),
8988 UNIPHIER_MIO_CLK_USB2_PHY(12, 0),
9089 UNIPHIER_MIO_CLK_USB2_PHY(13, 1),
9190 UNIPHIER_MIO_CLK_USB2_PHY(14, 2),
92− UNIPHIER_MIO_CLK_USB2_PHY(15, 3),
9391 { /* sentinel */ }
9492 };
9593
drivers/clk/uniphier/clk-uniphier-sys.c+71−27
@@ -17,7 +17,7 @@ · 16 unmodified lines
1717
1818 #include "clk-uniphier.h"
1919
20−#define UNIPHIER_SLD3_SYS_CLK_SD \
20+#define UNIPHIER_LD4_SYS_CLK_SD \
2121 UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 8), \
2222 UNIPHIER_CLK_FACTOR("sd-133m", -1, "vpll27a", 1, 2)
2323
@@ -30,7 +30,7 @@ · 6 unmodified lines
3030 UNIPHIER_CLK_FACTOR("sd-133m", -1, "spll", 1, 15)
3131
3232 /* 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) \
3434 UNIPHIER_CLK_FACTOR("nand-200m", -1, "spll", 1, 8), \
3535 UNIPHIER_CLK_GATE("nand", (idx), "nand-200m", 0x2104, 2)
3636
@@ -45,7 +45,7 @@ · 8 unmodified lines
4545 #define UNIPHIER_LD11_SYS_CLK_EMMC(idx) \
4646 UNIPHIER_CLK_GATE("emmc", (idx), NULL, 0x210c, 2)
4747
48−#define UNIPHIER_SLD3_SYS_CLK_STDMAC(idx) \
48+#define UNIPHIER_LD4_SYS_CLK_STDMAC(idx) \
4949 UNIPHIER_CLK_GATE("stdmac", (idx), NULL, 0x2104, 10)
5050
5151 #define UNIPHIER_LD11_SYS_CLK_STDMAC(idx) \
@@ -57,19 +57,23 @@ · 5 unmodified lines
5757 #define UNIPHIER_PRO4_SYS_CLK_USB3(idx, ch) \
5858 UNIPHIER_CLK_GATE("usb3" #ch, (idx), NULL, 0x2104, 16 + (ch))
5959
60−const struct uniphier_clk_data uniphier_sld3_sys_clk_data[] = {
61− UNIPHIER_CLK_FACTOR("spll", -1, "ref", 65, 1), /* 1597.44 MHz */
62− UNIPHIER_CLK_FACTOR("upll", -1, "ref", 6000, 512), /* 288 MHz */
63− UNIPHIER_CLK_FACTOR("a2pll", -1, "ref", 24, 1), /* 589.824 MHz */
64− UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */
65− UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16),
66− UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16),
67− UNIPHIER_SLD3_SYS_CLK_NAND(2),
68− UNIPHIER_SLD3_SYS_CLK_SD,
69− UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12),
70− UNIPHIER_SLD3_SYS_CLK_STDMAC(8),
71− { /* sentinel */ }
72−};
60+#define UNIPHIER_LD11_SYS_CLK_AIO(idx) \
61+ UNIPHIER_CLK_FACTOR("aio-io200m", -1, "spll", 1, 10), \
62+ UNIPHIER_CLK_GATE("aio", (idx), "aio-io200m", 0x2108, 0)
63+
64+#define UNIPHIER_LD11_SYS_CLK_EVEA(idx) \
65+ UNIPHIER_CLK_FACTOR("evea-io100m", -1, "spll", 1, 20), \
66+ UNIPHIER_CLK_GATE("evea", (idx), "evea-io100m", 0x2108, 1)
67+
68+#define UNIPHIER_LD11_SYS_CLK_EXIV(idx) \
69+ UNIPHIER_CLK_FACTOR("exiv-io200m", -1, "spll", 1, 10), \
70+ UNIPHIER_CLK_GATE("exiv", (idx), "exiv-io200m", 0x2110, 2)
71+
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)
7377
7478 const struct uniphier_clk_data uniphier_ld4_sys_clk_data[] = {
7579 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[] = { · 2 unmodified lines
7882 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */
7983 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16),
8084 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16),
81− UNIPHIER_SLD3_SYS_CLK_NAND(2),
82− UNIPHIER_SLD3_SYS_CLK_SD,
85+ UNIPHIER_LD4_SYS_CLK_NAND(2),
86+ UNIPHIER_LD4_SYS_CLK_SD,
8387 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 */
8589 { /* sentinel */ }
8690 };
8791
@@ -92,10 +96,11 @@ const struct uniphier_clk_data uniphier_pro4_sys_clk_data[] = { · 4 unmodified lines
9296 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */
9397 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 8),
9498 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 32),
95− UNIPHIER_SLD3_SYS_CLK_NAND(2),
96− UNIPHIER_SLD3_SYS_CLK_SD,
99+ UNIPHIER_LD4_SYS_CLK_NAND(2),
100+ UNIPHIER_LD4_SYS_CLK_SD,
97101 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 */
99104 UNIPHIER_PRO4_SYS_CLK_GIO(12), /* Ether, SATA, USB3 */
100105 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0),
101106 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1),
@@ -108,10 +113,10 @@ const struct uniphier_clk_data uniphier_sld8_sys_clk_data[] = { · 6 unmodified lines
108113 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */
109114 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 20),
110115 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16),
111− UNIPHIER_SLD3_SYS_CLK_NAND(2),
112− UNIPHIER_SLD3_SYS_CLK_SD,
116+ UNIPHIER_LD4_SYS_CLK_NAND(2),
117+ UNIPHIER_LD4_SYS_CLK_SD,
113118 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 */
115120 { /* sentinel */ }
116121 };
117122
@@ -123,7 +128,7 @@ const struct uniphier_clk_data uniphier_pro5_sys_clk_data[] = { · 5 unmodified lines
123128 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48),
124129 UNIPHIER_PRO5_SYS_CLK_NAND(2),
125130 UNIPHIER_PRO5_SYS_CLK_SD,
126− UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC */
131+ UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* HSC */
127132 UNIPHIER_PRO4_SYS_CLK_GIO(12), /* PCIe, USB3 */
128133 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0),
129134 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1),
@@ -136,7 +141,8 @@ const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] = { · 6 unmodified lines
136141 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48),
137142 UNIPHIER_PRO5_SYS_CLK_NAND(2),
138143 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 */
140146 /* GIO is always clock-enabled: no function for 0x2104 bit6 */
141147 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0),
142148 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1),
@@ -156,8 +162,12 @@ const struct uniphier_clk_data uniphier_ld11_sys_clk_data[] = { · 13 unmodified lines
156162 UNIPHIER_LD11_SYS_CLK_NAND(2),
157163 UNIPHIER_LD11_SYS_CLK_EMMC(4),
158164 /* Index 5 reserved for eMMC PHY */
165+ UNIPHIER_LD11_SYS_CLK_ETHER(6),
159166 UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC, MIO */
160167 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),
161171 /* CPU gears */
162172 UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8),
163173 UNIPHIER_CLK_DIV4("mpll", 2, 3, 4, 8),
@@ -185,6 +195,7 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = { · 21 unmodified lines
185195 UNIPHIER_LD11_SYS_CLK_EMMC(4),
186196 /* Index 5 reserved for eMMC PHY */
187197 UNIPHIER_LD20_SYS_CLK_SD,
198+ UNIPHIER_LD11_SYS_CLK_ETHER(6),
188199 UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC */
189200 /* GIO is always clock-enabled: no function for 0x210c bit5 */
190201 /*
@@ -194,6 +205,9 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = { · 3 unmodified lines
194205 UNIPHIER_CLK_GATE("usb30", 14, NULL, 0x210c, 14),
195206 UNIPHIER_CLK_GATE("usb30-phy0", 16, NULL, 0x210c, 12),
196207 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),
197211 /* CPU gears */
198212 UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8),
199213 UNIPHIER_CLK_DIV4("spll", 2, 3, 4, 8),
@@ -209,3 +223,33 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = { · 9 unmodified lines
209223 "spll/4", "spll/8", "s2pll/4", "s2pll/8"),
210224 { /* sentinel */ }
211225 };
226+
227+const 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+};
drivers/clk/uniphier/clk-uniphier.h+2−2
@@ -147,7 +147,6 @@ struct clk_hw *uniphier_clk_register_mux(struct device *dev, · 146 unmodified lines
147147 const char *name,
148148 const struct uniphier_clk_mux_data *data);
149149
150−extern const struct uniphier_clk_data uniphier_sld3_sys_clk_data[];
151150 extern const struct uniphier_clk_data uniphier_ld4_sys_clk_data[];
152151 extern const struct uniphier_clk_data uniphier_pro4_sys_clk_data[];
153152 extern 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[]; · 1 unmodified line
155154 extern const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[];
156155 extern const struct uniphier_clk_data uniphier_ld11_sys_clk_data[];
157156 extern const struct uniphier_clk_data uniphier_ld20_sys_clk_data[];
158−extern const struct uniphier_clk_data uniphier_sld3_mio_clk_data[];
157+extern const struct uniphier_clk_data uniphier_pxs3_sys_clk_data[];
158+extern const struct uniphier_clk_data uniphier_ld4_mio_clk_data[];
159159 extern const struct uniphier_clk_data uniphier_pro5_sd_clk_data[];
160160 extern const struct uniphier_clk_data uniphier_ld4_peri_clk_data[];
161161 extern const struct uniphier_clk_data uniphier_pro4_peri_clk_data[];
drivers/clk/ux500/clk-prcc.c+3−3
@@ -79,13 +79,13 @@ static int clk_prcc_is_enabled(struct clk_hw *hw) · 78 unmodified lines
7979 return clk->is_enabled;
8080 }
8181
82−static struct clk_ops clk_prcc_pclk_ops = {
82+static const struct clk_ops clk_prcc_pclk_ops = {
8383 .enable = clk_prcc_pclk_enable,
8484 .disable = clk_prcc_pclk_disable,
8585 .is_enabled = clk_prcc_is_enabled,
8686 };
8787
88−static struct clk_ops clk_prcc_kclk_ops = {
88+static const struct clk_ops clk_prcc_kclk_ops = {
8989 .enable = clk_prcc_kclk_enable,
9090 .disable = clk_prcc_kclk_disable,
9191 .is_enabled = clk_prcc_is_enabled,
@@ -96,7 +96,7 @@ static struct clk *clk_reg_prcc(const char *name, · 4 unmodified lines
9696 resource_size_t phy_base,
9797 u32 cg_sel,
9898 unsigned long flags,
99− struct clk_ops *clk_prcc_ops)
99+ const struct clk_ops *clk_prcc_ops)
100100 {
101101 struct clk_prcc *clk;
102102 struct clk_init_data clk_prcc_init;
drivers/clk/ux500/clk-prcmu.c+7−7
@@ -186,7 +186,7 @@ static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw) · 185 unmodified lines
186186 clk->is_prepared = 0;
187187 }
188188
189−static struct clk_ops clk_prcmu_scalable_ops = {
189+static const struct clk_ops clk_prcmu_scalable_ops = {
190190 .prepare = clk_prcmu_prepare,
191191 .unprepare = clk_prcmu_unprepare,
192192 .is_prepared = clk_prcmu_is_prepared,
@@ -198,7 +198,7 @@ static struct clk_ops clk_prcmu_scalable_ops = { · 5 unmodified lines
198198 .set_rate = clk_prcmu_set_rate,
199199 };
200200
201−static struct clk_ops clk_prcmu_gate_ops = {
201+static const struct clk_ops clk_prcmu_gate_ops = {
202202 .prepare = clk_prcmu_prepare,
203203 .unprepare = clk_prcmu_unprepare,
204204 .is_prepared = clk_prcmu_is_prepared,
@@ -208,19 +208,19 @@ static struct clk_ops clk_prcmu_gate_ops = { · 3 unmodified lines
208208 .recalc_rate = clk_prcmu_recalc_rate,
209209 };
210210
211−static struct clk_ops clk_prcmu_scalable_rate_ops = {
211+static const struct clk_ops clk_prcmu_scalable_rate_ops = {
212212 .is_enabled = clk_prcmu_is_enabled,
213213 .recalc_rate = clk_prcmu_recalc_rate,
214214 .round_rate = clk_prcmu_round_rate,
215215 .set_rate = clk_prcmu_set_rate,
216216 };
217217
218−static struct clk_ops clk_prcmu_rate_ops = {
218+static const struct clk_ops clk_prcmu_rate_ops = {
219219 .is_enabled = clk_prcmu_is_enabled,
220220 .recalc_rate = clk_prcmu_recalc_rate,
221221 };
222222
223−static struct clk_ops clk_prcmu_opp_gate_ops = {
223+static const struct clk_ops clk_prcmu_opp_gate_ops = {
224224 .prepare = clk_prcmu_opp_prepare,
225225 .unprepare = clk_prcmu_opp_unprepare,
226226 .is_prepared = clk_prcmu_is_prepared,
@@ -230,7 +230,7 @@ static struct clk_ops clk_prcmu_opp_gate_ops = { · 3 unmodified lines
230230 .recalc_rate = clk_prcmu_recalc_rate,
231231 };
232232
233−static struct clk_ops clk_prcmu_opp_volt_scalable_ops = {
233+static const struct clk_ops clk_prcmu_opp_volt_scalable_ops = {
234234 .prepare = clk_prcmu_opp_volt_prepare,
235235 .unprepare = clk_prcmu_opp_volt_unprepare,
236236 .is_prepared = clk_prcmu_is_prepared,
@@ -247,7 +247,7 @@ static struct clk *clk_reg_prcmu(const char *name, · 10 unmodified lines
247247 u8 cg_sel,
248248 unsigned long rate,
249249 unsigned long flags,
250− struct clk_ops *clk_prcmu_ops)
250+ const struct clk_ops *clk_prcmu_ops)
251251 {
252252 struct clk_prcmu *clk;
253253 struct clk_init_data clk_prcmu_init;
drivers/clk/ux500/clk-sysctrl.c+4−4
@@ -98,18 +98,18 @@ static u8 clk_sysctrl_get_parent(struct clk_hw *hw) · 97 unmodified lines
9898 return clk->parent_index;
9999 }
100100
101−static struct clk_ops clk_sysctrl_gate_ops = {
101+static const struct clk_ops clk_sysctrl_gate_ops = {
102102 .prepare = clk_sysctrl_prepare,
103103 .unprepare = clk_sysctrl_unprepare,
104104 };
105105
106−static struct clk_ops clk_sysctrl_gate_fixed_rate_ops = {
106+static const struct clk_ops clk_sysctrl_gate_fixed_rate_ops = {
107107 .prepare = clk_sysctrl_prepare,
108108 .unprepare = clk_sysctrl_unprepare,
109109 .recalc_rate = clk_sysctrl_recalc_rate,
110110 };
111111
112−static struct clk_ops clk_sysctrl_set_parent_ops = {
112+static const struct clk_ops clk_sysctrl_set_parent_ops = {
113113 .set_parent = clk_sysctrl_set_parent,
114114 .get_parent = clk_sysctrl_get_parent,
115115 };
@@ -124,7 +124,7 @@ static struct clk *clk_reg_sysctrl(struct device *dev, · 8 unmodified lines
124124 unsigned long rate,
125125 unsigned long enable_delay_us,
126126 unsigned long flags,
127− struct clk_ops *clk_sysctrl_ops)
127+ const struct clk_ops *clk_sysctrl_ops)
128128 {
129129 struct clk_sysctrl *clk;
130130 struct clk_init_data clk_sysctrl_init;
drivers/clk/versatile/clk-vexpress-osc.c+1−1
@@ -61,7 +61,7 @@ static int vexpress_osc_set_rate(struct clk_hw *hw, unsigned long rate, · 60 unmodified lines
6161 return regmap_write(osc->reg, 0, rate);
6262 }
6363
64−static struct clk_ops vexpress_osc_ops = {
64+static const struct clk_ops vexpress_osc_ops = {
6565 .recalc_rate = vexpress_osc_recalc_rate,
6666 .round_rate = vexpress_osc_round_rate,
6767 .set_rate = vexpress_osc_set_rate,
drivers/clk/zte/clk-zx296718.c+3−3
@@ -451,7 +451,7 @@ static struct zx_clk_fixed_factor top_ffactor_clk[] = { · 450 unmodified lines
451451 FFACTOR(0, "emmc_mux_div2", "emmc_mux", 1, 2, CLK_SET_RATE_PARENT),
452452 };
453453
454−static struct clk_div_table noc_div_table[] = {
454+static const struct clk_div_table noc_div_table[] = {
455455 { .val = 1, .div = 2, },
456456 { .val = 3, .div = 4, },
457457 };
@@ -644,7 +644,7 @@ static int __init top_clocks_init(struct device_node *np) · 186 unmodified lines
644644 return 0;
645645 }
646646
647−static struct clk_div_table common_even_div_table[] = {
647+static const struct clk_div_table common_even_div_table[] = {
648648 { .val = 0, .div = 1, },
649649 { .val = 1, .div = 2, },
650650 { .val = 3, .div = 4, },
@@ -656,7 +656,7 @@ static struct clk_div_table common_even_div_table[] = { · 5 unmodified lines
656656 { .val = 15, .div = 16, },
657657 };
658658
659−static struct clk_div_table common_div_table[] = {
659+static const struct clk_div_table common_div_table[] = {
660660 { .val = 0, .div = 1, },
661661 { .val = 1, .div = 2, },
662662 { .val = 2, .div = 3, },
include/dt-bindings/clock/qcom,gcc-msm8996.h+2−0
@@ -233,6 +233,8 @@ · 232 unmodified lines
233233 #define GCC_PCIE_CLKREF_CLK 216
234234 #define GCC_RX2_USB2_CLKREF_CLK 217
235235 #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
236238
237239 #define GCC_SYSTEM_NOC_BCR 0
238240 #define GCC_CONFIG_NOC_BCR 1
include/dt-bindings/clock/r8a77995-cpg-mssr.h+57−0
@@ -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__ */
include/dt-bindings/clock/rk3228-cru.h+1−0
@@ -49,6 +49,7 @@ · 48 unmodified lines
4949 #define SCLK_EMMC_DRV 117
5050 #define SCLK_SDMMC_SAMPLE 118
5151 #define SCLK_SDIO_SAMPLE 119
52+#define SCLK_SDIO_SRC 120
5253 #define SCLK_EMMC_SAMPLE 121
5354 #define SCLK_VOP 122
5455 #define SCLK_HDMI_HDCP 123
include/dt-bindings/clock/rv1108-cru.h+5−3
@@ -67,9 +67,9 @@ · 66 unmodified lines
6767 #define SCLK_SPI 108
6868 #define SCLK_SARADC 109
6969 #define SCLK_TSADC 110
70−#define SCLK_MACPHY_PRE 111
71−#define SCLK_MACPHY 112
72−#define SCLK_MACPHY_RX 113
70+#define SCLK_MAC_PRE 111
71+#define SCLK_MAC 112
72+#define SCLK_MAC_RX 113
7373 #define SCLK_MAC_REF 114
7474 #define SCLK_MAC_REFOUT 115
7575 #define SCLK_DSP_PFM 116
@@ -110,6 +110,7 @@ · 34 unmodified lines
110110 #define ACLK_CIF2 207
111111 #define ACLK_CIF3 208
112112 #define ACLK_PERI 209
113+#define ACLK_GMAC 210
113114
114115 /* pclk gates */
115116 #define PCLK_GPIO1 256
@@ -141,6 +142,7 @@ · 25 unmodified lines
141142 #define PCLK_EFUSE0 282
142143 #define PCLK_EFUSE1 283
143144 #define PCLK_WDT 284
145+#define PCLK_GMAC 285
144146
145147 /* hclk gates */
146148 #define HCLK_I2S0_8CH 320
include/dt-bindings/clock/stm32h7-clks.h+165−0
@@ -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
include/dt-bindings/clock/sun4i-a10-ccu.h+200−0
@@ -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_ */
include/dt-bindings/clock/sun7i-a20-ccu.h+53−0
@@ -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_ */
include/dt-bindings/clock/sun8i-r40-ccu.h+187−0
@@ -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_ */
include/dt-bindings/mfd/stm32h7-rcc.h+136−0
@@ -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 */
include/dt-bindings/reset/sun4i-a10-ccu.h+69−0
@@ -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 */
include/dt-bindings/reset/sun8i-r40-ccu.h+130−0
@@ -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_ */
include/linux/clk-provider.h+4−0
@@ -343,6 +343,7 @@ struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name, · 342 unmodified lines
343343 u8 clk_gate_flags, spinlock_t *lock);
344344 void clk_unregister_gate(struct clk *clk);
345345 void clk_hw_unregister_gate(struct clk_hw *hw);
346+int clk_gate_is_enabled(struct clk_hw *hw);
346347
347348 struct clk_div_table {
348349 unsigned int val;
@@ -565,6 +566,9 @@ struct clk_fractional_divider { · 216 unmodified lines
565566 u8 nwidth;
566567 u32 nmask;
567568 u8 flags;
569+ void (*approximation)(struct clk_hw *hw,
570+ unsigned long rate, unsigned long *parent_rate,
571+ unsigned long *m, unsigned long *n);
568572 spinlock_t *lock;
569573 };
570574
include/linux/clk/at91_pmc.h+25−0
@@ -185,4 +185,29 @@ · 184 unmodified lines
185185 #define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */
186186 #define AT91_PMC_PCR_GCKEN (0x1 << 29) /* GCK Enable */
187187
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+
188213 #endif
sound/soc/atmel/atmel-classd.c+14−33
@@ -32,7 +32,6 @@ struct atmel_classd { · 31 unmodified lines
3232 struct regmap *regmap;
3333 struct clk *pclk;
3434 struct clk *gclk;
35− struct clk *aclk;
3635 int irq;
3736 const struct atmel_classd_pdata *pdata;
3837 };
@@ -330,11 +329,6 @@ static int atmel_classd_codec_dai_startup(struct snd_pcm_substream *substream, · 291 unmodified lines
330329 {
331330 struct snd_soc_pcm_runtime *rtd = substream->private_data;
332331 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;
338332
339333 return clk_prepare_enable(dd->gclk);
340334 }
@@ -357,31 +351,31 @@ static int atmel_classd_codec_dai_digital_mute(struct snd_soc_dai *codec_dai, · 16 unmodified lines
357351 return 0;
358352 }
359353
360−#define CLASSD_ACLK_RATE_11M2896_MPY_8 (112896 * 100 * 8)
361−#define CLASSD_ACLK_RATE_12M288_MPY_8 (12288 * 1000 * 8)
354+#define CLASSD_GCLK_RATE_11M2896_MPY_8 (112896 * 100 * 8)
355+#define CLASSD_GCLK_RATE_12M288_MPY_8 (12288 * 1000 * 8)
362356
363357 static struct {
364358 int rate;
365359 int sample_rate;
366360 int dsp_clk;
367− unsigned long aclk_rate;
361+ unsigned long gclk_rate;
368362 } const sample_rates[] = {
369363 { 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 },
371365 { 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 },
373367 { 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 },
375369 { 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 },
377371 { 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 },
379373 { 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 },
381375 { 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 },
383377 { 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 },
385379 };
386380
387381 static int
@@ -410,13 +404,12 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream, · 22 unmodified lines
410404 }
411405
412406 dev_dbg(codec->dev,
413− "Selected SAMPLE_RATE of %dHz, ACLK_RATE of %ldHz\n",
414− sample_rates[best].rate, sample_rates[best].aclk_rate);
407+ "Selected SAMPLE_RATE of %dHz, GCLK_RATE of %ldHz\n",
408+ sample_rates[best].rate, sample_rates[best].gclk_rate);
415409
416410 clk_disable_unprepare(dd->gclk);
417− clk_disable_unprepare(dd->aclk);
418411
419− ret = clk_set_rate(dd->aclk, sample_rates[best].aclk_rate);
412+ ret = clk_set_rate(dd->gclk, sample_rates[best].gclk_rate);
420413 if (ret)
421414 return ret;
422415
@@ -426,10 +419,6 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream, · 3 unmodified lines
426419
427420 snd_soc_update_bits(codec, CLASSD_INTPMR, mask, val);
428421
429− ret = clk_prepare_enable(dd->aclk);
430− if (ret)
431− return ret;
432−
433422 return clk_prepare_enable(dd->gclk);
434423 }
435424
@@ -441,7 +430,6 @@ atmel_classd_codec_dai_shutdown(struct snd_pcm_substream *substream, · 5 unmodified lines
441430 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
442431
443432 clk_disable_unprepare(dd->gclk);
444− clk_disable_unprepare(dd->aclk);
445433 }
446434
447435 static int atmel_classd_codec_dai_prepare(struct snd_pcm_substream *substream,
@@ -596,13 +584,6 @@ static int atmel_classd_probe(struct platform_device *pdev) · 148 unmodified lines
596584 return ret;
597585 }
598586
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−
606587 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
607588 io_base = devm_ioremap_resource(dev, res);
608589 if (IS_ERR(io_base)) {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t