History

Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux

Pull clk updates from Stephen Boyd: "This time around we have four lines of diff in the core framework, removing a function that isn't used anymore. Otherwise the main new thing for the common clk framework is that it is selectable in the Kconfig language now. Hopefully this will let clk drivers and clk consumers be testable on more than the architectures that support the clk framework. The goal is to introduce some Kunit tests for the framework. Outside of the core framework we have the usual set of various driver updates and non-critical fixes. The dirstat shows that the new Baikal-T1 driver is the largest addition this time around in terms of lines of code. After that the x86 (Intel), Qualcomm, and Mediatek drivers introduce many lines to support new or upcoming SoCs. After that the dirstat shows the usual suspects working on their SoC support by fixing minor bugs, correcting data and converting some of their DT bindings to YAML. Core: - Allow the COMMON_CLK config to be selectable New Drivers: - Clk driver for Baikal-T1 SoCs - Mediatek MT6765 clock support - Support for Intel Agilex clks - Add support for X1830 and X1000 Ingenic SoC clk controllers - Add support for the new Renesas RZ/G1H (R8A7742) SoC - Add support for Qualcomm's MSM8939 Generic Clock Controller Updates: - Support IDT VersaClock 5P49V5925 - Bunch of updates for HSDK clock generation unit (CGU) driver - Start making audio and GPU clks work on Marvell MMP2/MMP3 SoCs - Add some GPU, NPU, and UFS clks to Qualcomm SM8150 driver - Enable supply regulators for GPU gdscs on Qualcomm SoCs - Add support for Si5342, Si5344 and Si5345 chips - Support custom flags in Xilinx zynq firmware - Various small fixes to the Xilinx clk driver - A single minor rounding fix for the legacy Allwinner clock support - A few patches from Abel Vesa as preparation of adding audiomix clock support on i.MX - A couple of cleanups from Anson Huang for i.MX clk-sscg-pll and clk-pllv3 drivers - Drop dependency on ARM64 for i.MX8M clock driver, to support aarch32 mode on aarch64 hardware - A series from Peng Fan to improve i.MX8M clock drivers, using composite clock for core and bus clk slice - Set a better parent clock for flexcan on i.MX6UL to support CiA102 defined bit rates - A couple changes for EMC frequency scaling on Tegra210 - Support for CPU frequency scaling on Tegra20/Tegra30 - New clk gate for CSI test pattern generator on Tegra210 - Regression fixes for Samsung exynos542x and exynos5433 SoCs - Use of fallthrough; attribute for Samsung s3c24xx - Updates and fixup HDMI and video clocks on Meson8b - Fixup reset polarity on Meson8b - Fix GPU glitch free mux switch on Meson gx and g12 - A minor fix for the currently unused suspend/resume handling on Renesas RZ/A1 and RZ/A2 - Two more conversions of Renesas DT bindings to json-schema - Add support for the USB 2.0 clock selector on Renesas R-Car M3-W+" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (155 commits) clk: mediatek: Remove ifr{0,1}_cfg_regs structures clk: baikal-t1: remove redundant assignment to variable 'divider' clk: baikal-t1: fix spelling mistake "Uncompatible" -> "Incompatible" dt-bindings: clock: Add a missing include to MMP Audio Clock binding dt: Add bindings for IDT VersaClock 5P49V5925 clk: vc5: Add support for IDT VersaClock 5P49V6965 clk: Add Baikal-T1 CCU Dividers driver clk: Add Baikal-T1 CCU PLLs driver dt-bindings: clk: Add Baikal-T1 CCU Dividers binding dt-bindings: clk: Add Baikal-T1 CCU PLLs binding clk: mediatek: assign the initial value to clk_init_data of mtk_mux clk: mediatek: Add MT6765 clock support clk: mediatek: add mt6765 clock IDs dt-bindings: clock: mediatek: document clk bindings vcodecsys for Mediatek MT6765 SoC dt-bindings: clock: mediatek: document clk bindings mipi0a for Mediatek MT6765 SoC dt-bindings: clock: mediatek: document clk bindings for Mediatek MT6765 SoC CLK: HSDK: CGU: add support for 148.5MHz clock CLK: HSDK: CGU: support PLL bypassing CLK: HSDK: CGU: check if PLL is bypassed first clk: clk-si5341: Add support for the Si5345 series ...

Linus Torvalds committed 6 years ago

Commit 6f630782 parents 3a2a875 9ac1eaf203 files · +15228 −1245Browse files

Unified · Split

203 files
  1. Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt +1 −0
  2. Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt +1 −0
  3. Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt +1 −0
  4. Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt +1 −0
  5. Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt +1 −0
  6. Documentation/devicetree/bindings/arm/mediatek/mediatek,mipi0a.txt +28 −0
  7. Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt +1 −0
  8. Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml +1 −0
  9. Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt +1 −0
  10. Documentation/devicetree/bindings/arm/mediatek/mediatek,vcodecsys.txt +27 −0
  11. Documentation/devicetree/bindings/clock/baikal,bt1-ccu-div.yaml +188 −0
  12. Documentation/devicetree/bindings/clock/baikal,bt1-ccu-pll.yaml +131 −0
  13. Documentation/devicetree/bindings/clock/idt,versaclock5.txt +1 −0
  14. Documentation/devicetree/bindings/clock/intel,agilex.yaml +46 −0
  15. Documentation/devicetree/bindings/clock/intel,cgu-lgm.yaml +44 −0
  16. Documentation/devicetree/bindings/clock/marvell,mmp2-audio-clock.yaml +75 −0
  17. Documentation/devicetree/bindings/clock/marvell,mmp2-clock.yaml +5 −0
  18. Documentation/devicetree/bindings/clock/qcom,a53pll.txt +0 −22
  19. Documentation/devicetree/bindings/clock/qcom,a53pll.yaml +40 −0
  20. Documentation/devicetree/bindings/clock/qcom,gcc.yaml +3 −0
  21. Documentation/devicetree/bindings/clock/qcom,mmcc.yaml +4 −0
  22. Documentation/devicetree/bindings/clock/renesas,cpg-div6-clock.yaml +60 −0
  23. Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt +0 −40
  24. Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml +1 −0
  25. Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt +0 −60
  26. Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.yaml +82 −0
  27. Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt +3 −1
  28. Documentation/devicetree/bindings/clock/silabs,si5341.txt +10 −1
  29. Documentation/devicetree/bindings/clock/sprd,sc9863a-clk.yaml +1 −0
  30. MAINTAINERS +1 −0
  31. arch/Kconfig +0 −6
  32. arch/arm/Kconfig +2 −3
  33. arch/arm/mach-mmp/Kconfig +2 −0
  34. arch/arm/mach-mmp/Makefile +0 −6
  35. arch/arm/mach-mmp/clock-mmp2.c +0 −114
  36. arch/arm/mach-mmp/clock-pxa168.c +0 −94
  37. arch/arm/mach-mmp/clock-pxa910.c +0 −70
  38. arch/arm/mach-mmp/clock.c +0 −105
  39. arch/arm/mach-mmp/clock.h +0 −65
  40. arch/arm/mach-mmp/pxa168.c +0 −1
  41. arch/arm/mach-mmp/time.c +0 −1
  42. arch/arm/mach-vt8500/Kconfig +0 −1
  43. arch/arm64/Kconfig.platforms +0 −1
  44. arch/c6x/Kconfig +1 −0
  45. arch/h8300/Kconfig +0 −1
  46. arch/m68k/Kconfig.cpu +1 −1
  47. arch/mips/Kconfig +3 −4
  48. arch/mips/ralink/Kconfig +4 −0
  49. arch/sh/boards/Kconfig +5 −0
  50. arch/unicore32/Kconfig +1 −1
  51. drivers/clk/Kconfig +28 −5
  52. drivers/clk/Makefile +3 −1
  53. drivers/clk/at91/at91rm9200.c +9 −3
  54. drivers/clk/at91/at91sam9260.c +10 −3
  55. drivers/clk/at91/at91sam9g45.c +7 −3
  56. drivers/clk/at91/at91sam9n12.c +9 −3
  57. drivers/clk/at91/at91sam9rl.c +7 −3
  58. drivers/clk/at91/at91sam9x5.c +7 −3
  59. drivers/clk/at91/pmc.c +20 −27
  60. drivers/clk/at91/pmc.h +6 −2
  61. drivers/clk/at91/sam9x60.c +7 −3
  62. drivers/clk/at91/sama5d2.c +10 −3
  63. drivers/clk/at91/sama5d3.c +7 −3
  64. drivers/clk/at91/sama5d4.c +7 −3
  65. drivers/clk/baikal-t1/Kconfig +42 −0
  66. drivers/clk/baikal-t1/Makefile +3 −0
  67. drivers/clk/baikal-t1/ccu-div.c +602 −0
  68. drivers/clk/baikal-t1/ccu-div.h +110 −0
  69. drivers/clk/baikal-t1/ccu-pll.c +558 −0
  70. drivers/clk/baikal-t1/ccu-pll.h +64 −0
  71. drivers/clk/baikal-t1/clk-ccu-div.c +485 −0
  72. drivers/clk/baikal-t1/clk-ccu-pll.c +204 −0
  73. drivers/clk/bcm/clk-bcm2835.c +43 −37
  74. drivers/clk/clk-ast2600.c +25 −6
  75. drivers/clk/clk-hsdk-pll.c +39 −31
  76. drivers/clk/clk-si5341.c +64 −5
  77. drivers/clk/clk-versaclock5.c +11 −0
  78. drivers/clk/clk.c +0 −4
  79. drivers/clk/imx/Kconfig +4 −4
  80. drivers/clk/imx/clk-composite-8m.c +55 −1
  81. drivers/clk/imx/clk-gate2.c +23 −8
  82. drivers/clk/imx/clk-imx6ul.c +1 −1
  83. drivers/clk/imx/clk-imx7ulp.c +4 −2
  84. drivers/clk/imx/clk-imx8mm.c +12 −15
  85. drivers/clk/imx/clk-imx8mn.c +11 −14
  86. drivers/clk/imx/clk-imx8mp.c +74 −74
  87. drivers/clk/imx/clk-imx8mq.c +13 −16
  88. drivers/clk/imx/clk-pll14xx.c +4 −4
  89. drivers/clk/imx/clk-pllv3.c +5 −11
  90. drivers/clk/imx/clk-sscg-pll.c +0 −10
  91. drivers/clk/imx/clk.h +59 −3
  92. drivers/clk/ingenic/Kconfig +10 −0
  93. drivers/clk/ingenic/Makefile +1 −0
  94. drivers/clk/ingenic/cgu.c +14 −14
  95. drivers/clk/ingenic/cgu.h +4 −0
  96. drivers/clk/ingenic/jz4725b-cgu.c +4 −0
  97. drivers/clk/ingenic/jz4740-cgu.c +4 −0
  98. drivers/clk/ingenic/jz4770-cgu.c +7 −1
  99. drivers/clk/ingenic/jz4780-cgu.c +3 −0
  100. drivers/clk/ingenic/tcu.c +1 −1
  101. drivers/clk/ingenic/x1000-cgu.c +117 −6
  102. drivers/clk/ingenic/x1830-cgu.c +448 −0
  103. drivers/clk/mediatek/Kconfig +86 −0
  104. drivers/clk/mediatek/Makefile +7 −0
  105. drivers/clk/mediatek/clk-mt6765-audio.c +100 −0
  106. drivers/clk/mediatek/clk-mt6765-cam.c +74 −0
  107. drivers/clk/mediatek/clk-mt6765-img.c +70 −0
  108. drivers/clk/mediatek/clk-mt6765-mipi0a.c +68 −0
  109. drivers/clk/mediatek/clk-mt6765-mm.c +96 −0
  110. drivers/clk/mediatek/clk-mt6765-vcodec.c +70 −0
  111. drivers/clk/mediatek/clk-mt6765.c +922 −0
  112. drivers/clk/mediatek/clk-mux.c +1 −1
  113. drivers/clk/meson/g12a.c +22 −8
  114. drivers/clk/meson/gxbb.c +22 −18
  115. drivers/clk/meson/meson8b.c +85 −35
  116. drivers/clk/meson/meson8b.h +4 −1
  117. drivers/clk/mmp/Makefile +2 −1
  118. drivers/clk/mmp/clk-audio.c +443 −0
  119. drivers/clk/mmp/clk-frac.c +19 −8
  120. drivers/clk/mmp/clk-of-mmp2.c +98 −6
  121. drivers/clk/mmp/clk.h +11 −0
  122. drivers/clk/mmp/pwr-island.c +115 −0
  123. drivers/clk/qcom/Kconfig +8 −0
  124. drivers/clk/qcom/Makefile +1 −0
  125. drivers/clk/qcom/gcc-msm8916.c +4 −4
  126. drivers/clk/qcom/gcc-msm8939.c +3988 −0
  127. drivers/clk/qcom/gcc-msm8998.c +27 −0
  128. drivers/clk/qcom/gcc-sc7180.c +58 −36
  129. drivers/clk/qcom/gcc-sm8150.c +148 −0
  130. drivers/clk/qcom/gdsc.c +23 −0
  131. drivers/clk/qcom/gdsc.h +4 −0
  132. drivers/clk/qcom/mmcc-msm8996.c +2 −0
  133. drivers/clk/renesas/Kconfig +5 −3
  134. drivers/clk/renesas/Makefile +1 −0
  135. drivers/clk/renesas/r8a7742-cpg-mssr.c +275 −0
  136. drivers/clk/renesas/r9a06g032-clocks.c +3 −3
  137. drivers/clk/renesas/renesas-cpg-mssr.c +11 −3
  138. drivers/clk/renesas/renesas-cpg-mssr.h +1 −0
  139. drivers/clk/samsung/clk-exynos5420.c +10 −8
  140. drivers/clk/samsung/clk-exynos5433.c +2 −1
  141. drivers/clk/samsung/clk-s3c2443.c +1 −1
  142. drivers/clk/socfpga/Makefile +2 −0
  143. drivers/clk/socfpga/clk-agilex.c +454 −0
  144. drivers/clk/socfpga/clk-gate-s10.c +3 −2
  145. drivers/clk/socfpga/clk-periph-s10.c +6 −4
  146. drivers/clk/socfpga/clk-pll-a10.c +1 −3
  147. drivers/clk/socfpga/clk-pll-s10.c +72 −6
  148. drivers/clk/socfpga/clk-pll.c +1 −3
  149. drivers/clk/socfpga/clk-s10.c +131 −29
  150. drivers/clk/socfpga/stratix10-clk.h +6 −4
  151. drivers/clk/sprd/gate.c +7 −0
  152. drivers/clk/sprd/gate.h +9 −0
  153. drivers/clk/sprd/pll.c +1 −1
  154. drivers/clk/sprd/sc9863a-clk.c +48 −16
  155. drivers/clk/st/clk-flexgen.c +1 −0
  156. drivers/clk/sunxi/clk-sunxi.c +1 −1
  157. drivers/clk/tegra/Kconfig +0 −4
  158. drivers/clk/tegra/Makefile +3 −1
  159. drivers/clk/tegra/clk-pll.c +11 −1
  160. drivers/clk/tegra/clk-tegra-super-cclk.c +212 −0
  161. drivers/clk/tegra/clk-tegra124-emc.c +0 −0
  162. drivers/clk/tegra/clk-tegra20.c +5 −2
  163. drivers/clk/tegra/clk-tegra210-emc.c +369 −0
  164. drivers/clk/tegra/clk-tegra210.c +75 −19
  165. drivers/clk/tegra/clk-tegra30.c +4 −2
  166. drivers/clk/tegra/clk.h +21 −3
  167. drivers/clk/ti/clk-44xx.c +7 −7
  168. drivers/clk/ti/clk-54xx.c +7 −7
  169. drivers/clk/ti/clk-7xx.c +3 −12
  170. drivers/clk/ti/composite.c +1 −0
  171. drivers/clk/versatile/clk-versatile.c +1 −1
  172. drivers/clk/x86/Kconfig +8 −0
  173. drivers/clk/x86/Makefile +1 −0
  174. drivers/clk/x86/clk-cgu-pll.c +156 −0
  175. drivers/clk/x86/clk-cgu.c +636 −0
  176. drivers/clk/x86/clk-cgu.h +335 −0
  177. drivers/clk/x86/clk-lgm.c +475 −0
  178. drivers/clk/zynqmp/clk-zynqmp.h +1 −0
  179. drivers/clk/zynqmp/clkc.c +18 −6
  180. drivers/clk/zynqmp/divider.c +19 −8
  181. drivers/i2c/busses/i2c-s3c2410.c +1 −2
  182. drivers/mmc/host/Kconfig +1 −1
  183. include/dt-bindings/clock/agilex-clock.h +70 −0
  184. include/dt-bindings/clock/at91.h +4 −0
  185. include/dt-bindings/clock/bt1-ccu.h +48 −0
  186. include/dt-bindings/clock/imx7ulp-clock.h +4 −1
  187. include/dt-bindings/clock/imx8mp-clock.h +89 −1
  188. include/dt-bindings/clock/intel,lgm-clk.h +165 −0
  189. include/dt-bindings/clock/marvell,mmp2-audio.h +10 −0
  190. include/dt-bindings/clock/marvell,mmp2.h +3 −0
  191. include/dt-bindings/clock/meson8b-clkc.h +1 −0
  192. include/dt-bindings/clock/mt6765-clk.h +313 −0
  193. include/dt-bindings/clock/qcom,gcc-msm8939.h +206 −0
  194. include/dt-bindings/clock/qcom,gcc-msm8998.h +1 −0
  195. include/dt-bindings/clock/qcom,gcc-sc7180.h +1 −0
  196. include/dt-bindings/clock/sprd,sc9863a-clk.h +5 −0
  197. include/dt-bindings/clock/tegra210-car.h +2 −2
  198. include/dt-bindings/clock/x1000-cgu.h +36 −28
  199. include/dt-bindings/clock/x1830-cgu.h +55 −0
  200. include/dt-bindings/power/marvell,mmp2.h +11 −0
  201. include/dt-bindings/reset/bt1-ccu.h +25 −0
  202. include/dt-bindings/reset/qcom,gcc-msm8939.h +110 −0
  203. include/linux/clk/tegra.h +27 −0
Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt+1−0
@@ -8,6 +8,7 @@ Required Properties: · 7 unmodified lines
88 - compatible: Should be one of:
99 - "mediatek,mt2701-apmixedsys"
1010 - "mediatek,mt2712-apmixedsys", "syscon"
11+ - "mediatek,mt6765-apmixedsys", "syscon"
1112 - "mediatek,mt6779-apmixedsys", "syscon"
1213 - "mediatek,mt6797-apmixedsys"
1314 - "mediatek,mt7622-apmixedsys"
Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt+1−0
@@ -7,6 +7,7 @@ Required Properties: · 6 unmodified lines
77
88 - compatible: Should be one of:
99 - "mediatek,mt2701-audsys", "syscon"
10+ - "mediatek,mt6765-audsys", "syscon"
1011 - "mediatek,mt6779-audio", "syscon"
1112 - "mediatek,mt7622-audsys", "syscon"
1213 - "mediatek,mt7623-audsys", "mediatek,mt2701-audsys", "syscon"
Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt+1−0
@@ -6,6 +6,7 @@ The MediaTek camsys controller provides various clocks to the system. · 5 unmodified lines
66 Required Properties:
77
88 - compatible: Should be one of:
9+ - "mediatek,mt6765-camsys", "syscon"
910 - "mediatek,mt6779-camsys", "syscon"
1011 - "mediatek,mt8183-camsys", "syscon"
1112 - #clock-cells: Must be 1
Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt+1−0
@@ -8,6 +8,7 @@ Required Properties: · 7 unmodified lines
88 - compatible: Should be one of:
99 - "mediatek,mt2701-imgsys", "syscon"
1010 - "mediatek,mt2712-imgsys", "syscon"
11+ - "mediatek,mt6765-imgsys", "syscon"
1112 - "mediatek,mt6779-imgsys", "syscon"
1213 - "mediatek,mt6797-imgsys", "syscon"
1314 - "mediatek,mt7623-imgsys", "mediatek,mt2701-imgsys", "syscon"
Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt+1−0
@@ -9,6 +9,7 @@ Required Properties: · 8 unmodified lines
99 - compatible: Should be one of:
1010 - "mediatek,mt2701-infracfg", "syscon"
1111 - "mediatek,mt2712-infracfg", "syscon"
12+ - "mediatek,mt6765-infracfg", "syscon"
1213 - "mediatek,mt6779-infracfg_ao", "syscon"
1314 - "mediatek,mt6797-infracfg", "syscon"
1415 - "mediatek,mt7622-infracfg", "syscon"
Documentation/devicetree/bindings/arm/mediatek/mediatek,mipi0a.txt+28−0
@@ -0,0 +1,28 @@
1+Mediatek mipi0a (mipi_rx_ana_csi0a) controller
2+============================
3+
4+The Mediatek mipi0a controller provides various clocks
5+to the system.
6+
7+Required Properties:
8+
9+- compatible: Should be one of:
10+ - "mediatek,mt6765-mipi0a", "syscon"
11+- #clock-cells: Must be 1
12+
13+The mipi0a controller uses the common clk binding from
14+Documentation/devicetree/bindings/clock/clock-bindings.txt
15+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
16+
17+The mipi0a controller also uses the common power domain from
18+Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
19+The available power doamins are defined in dt-bindings/power/mt*-power.h.
20+
21+Example:
22+
23+mipi0a: clock-controller@11c10000 {
24+ compatible = "mediatek,mt6765-mipi0a", "syscon";
25+ reg = <0 0x11c10000 0 0x1000>;
26+ power-domains = <&scpsys MT6765_POWER_DOMAIN_CAM>;
27+ #clock-cells = <1>;
28+};
Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt+1−0
@@ -9,6 +9,7 @@ Required Properties: · 8 unmodified lines
99 - compatible: Should be one of:
1010 - "mediatek,mt2701-mmsys", "syscon"
1111 - "mediatek,mt2712-mmsys", "syscon"
12+ - "mediatek,mt6765-mmsys", "syscon"
1213 - "mediatek,mt6779-mmsys", "syscon"
1314 - "mediatek,mt6797-mmsys", "syscon"
1415 - "mediatek,mt7623-mmsys", "mediatek,mt2701-mmsys", "syscon"
Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml+1−0
@@ -20,6 +20,7 @@ properties: · 19 unmodified lines
2020 - enum:
2121 - mediatek,mt2701-pericfg
2222 - mediatek,mt2712-pericfg
23+ - mediatek,mt6765-pericfg
2324 - mediatek,mt7622-pericfg
2425 - mediatek,mt7629-pericfg
2526 - mediatek,mt8135-pericfg
Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt+1−0
@@ -8,6 +8,7 @@ Required Properties: · 7 unmodified lines
88 - compatible: Should be one of:
99 - "mediatek,mt2701-topckgen"
1010 - "mediatek,mt2712-topckgen", "syscon"
11+ - "mediatek,mt6765-topckgen", "syscon"
1112 - "mediatek,mt6779-topckgen", "syscon"
1213 - "mediatek,mt6797-topckgen"
1314 - "mediatek,mt7622-topckgen"
Documentation/devicetree/bindings/arm/mediatek/mediatek,vcodecsys.txt+27−0
@@ -0,0 +1,27 @@
1+Mediatek vcodecsys controller
2+============================
3+
4+The Mediatek vcodecsys controller provides various clocks to the system.
5+
6+Required Properties:
7+
8+- compatible: Should be one of:
9+ - "mediatek,mt6765-vcodecsys", "syscon"
10+- #clock-cells: Must be 1
11+
12+The vcodecsys controller uses the common clk binding from
13+Documentation/devicetree/bindings/clock/clock-bindings.txt
14+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
15+
16+The vcodecsys controller also uses the common power domain from
17+Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
18+The available power doamins are defined in dt-bindings/power/mt*-power.h.
19+
20+Example:
21+
22+venc_gcon: clock-controller@17000000 {
23+ compatible = "mediatek,mt6765-vcodecsys", "syscon";
24+ reg = <0 0x17000000 0 0x10000>;
25+ power-domains = <&scpsys MT6765_POWER_DOMAIN_VCODEC>;
26+ #clock-cells = <1>;
27+};
Documentation/devicetree/bindings/clock/baikal,bt1-ccu-div.yaml+188−0
@@ -0,0 +1,188 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+# Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
3+%YAML 1.2
4+---
5+$id: http://devicetree.org/schemas/clock/baikal,bt1-ccu-div.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
7+
8+title: Baikal-T1 Clock Control Unit Dividers
9+
10+maintainers:
11+ - Serge Semin <fancer.lancer@gmail.com>
12+
13+description: |
14+ Clocks Control Unit is the core of Baikal-T1 SoC System Controller
15+ responsible for the chip subsystems clocking and resetting. The CCU is
16+ connected with an external fixed rate oscillator, which signal is transformed
17+ into clocks of various frequencies and then propagated to either individual
18+ IP-blocks or to groups of blocks (clock domains). The transformation is done
19+ by means of an embedded into CCU PLLs and gateable/non-gateable dividers. The
20+ later ones are described in this binding. Each clock domain can be also
21+ individually reset by using the domain clocks divider configuration
22+ registers. Baikal-T1 CCU is logically divided into the next components:
23+ 1) External oscillator (normally XTAL's 25 MHz crystal oscillator, but
24+ in general can provide any frequency supported by the CCU PLLs).
25+ 2) PLLs clocks generators (PLLs).
26+ 3) AXI-bus clock dividers (AXI) - described in this binding file.
27+ 4) System devices reference clock dividers (SYS) - described in this binding
28+ file.
29+ which are connected with each other as shown on the next figure:
30+
31+ +---------------+
32+ | Baikal-T1 CCU |
33+ | +----+------|- MIPS P5600 cores
34+ | +-|PLLs|------|- DDR controller
35+ | | +----+ |
36+ +----+ | | | | |
37+ |XTAL|--|-+ | | +---+-|
38+ +----+ | | | +-|AXI|-|- AXI-bus
39+ | | | +---+-|
40+ | | | |
41+ | | +----+---+-|- APB-bus
42+ | +-------|SYS|-|- Low-speed Devices
43+ | +---+-|- High-speed Devices
44+ +---------------+
45+
46+ Each sub-block is represented as a separate DT node and has an individual
47+ driver to be bound with.
48+
49+ In order to create signals of wide range frequencies the external oscillator
50+ output is primarily connected to a set of CCU PLLs. Some of PLLs CLKOUT are
51+ then passed over CCU dividers to create signals required for the target clock
52+ domain (like AXI-bus or System Device consumers). The dividers have the
53+ following structure:
54+
55+ +--------------+
56+ CLKIN --|->+----+ 1|\ |
57+ SETCLK--|--|/DIV|->| | |
58+ CLKDIV--|--| | | |-|->CLKLOUT
59+ LOCK----|--+----+ | | |
60+ | |/ |
61+ | | |
62+ EN------|-----------+ |
63+ RST-----|--------------|->RSTOUT
64+ +--------------+
65+
66+ where CLKIN is the reference clock coming either from CCU PLLs or from an
67+ external clock oscillator, SETCLK - a command to update the output clock in
68+ accordance with a set divider, CLKDIV - clocks divider, LOCK - a signal of
69+ the output clock stabilization, EN - enable/disable the divider block,
70+ RST/RSTOUT - reset clocks domain signal. Depending on the consumer IP-core
71+ peculiarities the dividers may lack of some functionality depicted on the
72+ figure above (like EN, CLKDIV/LOCK/SETCLK). In this case the corresponding
73+ clock provider just doesn't expose either switching functions, or the rate
74+ configuration, or both of them.
75+
76+ The clock dividers, which output clock is then consumed by the SoC individual
77+ devices, are united into a single clocks provider called System Devices CCU.
78+ Similarly the dividers with output clocks utilized as AXI-bus reference clocks
79+ are called AXI-bus CCU. Both of them use the common clock bindings with no
80+ custom properties. The list of exported clocks and reset signals can be found
81+ in the files: 'include/dt-bindings/clock/bt1-ccu.h' and
82+ 'include/dt-bindings/reset/bt1-ccu.h'. Since System Devices and AXI-bus CCU
83+ are a part of the Baikal-T1 SoC System Controller their DT nodes are supposed
84+ to be a children of later one.
85+
86+if:
87+ properties:
88+ compatible:
89+ contains:
90+ const: baikal,bt1-ccu-axi
91+
92+then:
93+ properties:
94+ clocks:
95+ items:
96+ - description: CCU SATA PLL output clock
97+ - description: CCU PCIe PLL output clock
98+ - description: CCU Ethernet PLL output clock
99+
100+ clock-names:
101+ items:
102+ - const: sata_clk
103+ - const: pcie_clk
104+ - const: eth_clk
105+
106+else:
107+ properties:
108+ clocks:
109+ items:
110+ - description: External reference clock
111+ - description: CCU SATA PLL output clock
112+ - description: CCU PCIe PLL output clock
113+ - description: CCU Ethernet PLL output clock
114+
115+ clock-names:
116+ items:
117+ - const: ref_clk
118+ - const: sata_clk
119+ - const: pcie_clk
120+ - const: eth_clk
121+
122+properties:
123+ compatible:
124+ enum:
125+ - baikal,bt1-ccu-axi
126+ - baikal,bt1-ccu-sys
127+
128+ reg:
129+ maxItems: 1
130+
131+ "#clock-cells":
132+ const: 1
133+
134+ "#reset-cells":
135+ const: 1
136+
137+unevaluatedProperties: false
138+
139+required:
140+ - compatible
141+ - "#clock-cells"
142+ - clocks
143+ - clock-names
144+
145+examples:
146+ # AXI-bus Clock Control Unit node:
147+ - |
148+ #include <dt-bindings/clock/bt1-ccu.h>
149+
150+ clock-controller@1f04d030 {
151+ compatible = "baikal,bt1-ccu-axi";
152+ reg = <0x1f04d030 0x030>;
153+ #clock-cells = <1>;
154+ #reset-cells = <1>;
155+
156+ clocks = <&ccu_pll CCU_SATA_PLL>,
157+ <&ccu_pll CCU_PCIE_PLL>,
158+ <&ccu_pll CCU_ETH_PLL>;
159+ clock-names = "sata_clk", "pcie_clk", "eth_clk";
160+ };
161+ # System Devices Clock Control Unit node:
162+ - |
163+ #include <dt-bindings/clock/bt1-ccu.h>
164+
165+ clock-controller@1f04d060 {
166+ compatible = "baikal,bt1-ccu-sys";
167+ reg = <0x1f04d060 0x0a0>;
168+ #clock-cells = <1>;
169+ #reset-cells = <1>;
170+
171+ clocks = <&clk25m>,
172+ <&ccu_pll CCU_SATA_PLL>,
173+ <&ccu_pll CCU_PCIE_PLL>,
174+ <&ccu_pll CCU_ETH_PLL>;
175+ clock-names = "ref_clk", "sata_clk", "pcie_clk",
176+ "eth_clk";
177+ };
178+ # Required Clock Control Unit PLL node:
179+ - |
180+ ccu_pll: clock-controller@1f04d000 {
181+ compatible = "baikal,bt1-ccu-pll";
182+ reg = <0x1f04d000 0x028>;
183+ #clock-cells = <1>;
184+
185+ clocks = <&clk25m>;
186+ clock-names = "ref_clk";
187+ };
188+...
Documentation/devicetree/bindings/clock/baikal,bt1-ccu-pll.yaml+131−0
@@ -0,0 +1,131 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+# Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
3+%YAML 1.2
4+---
5+$id: http://devicetree.org/schemas/clock/baikal,bt1-ccu-pll.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
7+
8+title: Baikal-T1 Clock Control Unit PLL
9+
10+maintainers:
11+ - Serge Semin <fancer.lancer@gmail.com>
12+
13+description: |
14+ Clocks Control Unit is the core of Baikal-T1 SoC System Controller
15+ responsible for the chip subsystems clocking and resetting. The CCU is
16+ connected with an external fixed rate oscillator, which signal is transformed
17+ into clocks of various frequencies and then propagated to either individual
18+ IP-blocks or to groups of blocks (clock domains). The transformation is done
19+ by means of PLLs and gateable/non-gateable dividers embedded into the CCU.
20+ It's logically divided into the next components:
21+ 1) External oscillator (normally XTAL's 25 MHz crystal oscillator, but
22+ in general can provide any frequency supported by the CCU PLLs).
23+ 2) PLLs clocks generators (PLLs) - described in this binding file.
24+ 3) AXI-bus clock dividers (AXI).
25+ 4) System devices reference clock dividers (SYS).
26+ which are connected with each other as shown on the next figure:
27+
28+ +---------------+
29+ | Baikal-T1 CCU |
30+ | +----+------|- MIPS P5600 cores
31+ | +-|PLLs|------|- DDR controller
32+ | | +----+ |
33+ +----+ | | | | |
34+ |XTAL|--|-+ | | +---+-|
35+ +----+ | | | +-|AXI|-|- AXI-bus
36+ | | | +---+-|
37+ | | | |
38+ | | +----+---+-|- APB-bus
39+ | +-------|SYS|-|- Low-speed Devices
40+ | +---+-|- High-speed Devices
41+ +---------------+
42+
43+ Each CCU sub-block is represented as a separate dts-node and has an
44+ individual driver to be bound with.
45+
46+ In order to create signals of wide range frequencies the external oscillator
47+ output is primarily connected to a set of CCU PLLs. There are five PLLs
48+ to create a clock for the MIPS P5600 cores, the embedded DDR controller,
49+ SATA, Ethernet and PCIe domains. The last three domains though named by the
50+ biggest system interfaces in fact include nearly all of the rest SoC
51+ peripherals. Each of the PLLs is based on True Circuits TSMC CLN28HPM core
52+ with an interface wrapper (so called safe PLL' clocks switcher) to simplify
53+ the PLL configuration procedure. The PLLs work as depicted on the next
54+ diagram:
55+
56+ +--------------------------+
57+ | |
58+ +-->+---+ +---+ +---+ | +---+ 0|\
59+ CLKF--->|/NF|--->|PFD|...|VCO|-+->|/OD|--->| |
60+ +---+ +->+---+ +---+ /->+---+ | |--->CLKOUT
61+ CLKOD---------C----------------+ 1| |
62+ +--------C--------------------------->|/
63+ | | ^
64+ Rclk-+->+---+ | |
65+ CLKR--->|/NR|-+ |
66+ +---+ |
67+ BYPASS--------------------------------------+
68+ BWADJ--->
69+
70+ where Rclk is the reference clock coming from XTAL, NR - reference clock
71+ divider, NF - PLL clock multiplier, OD - VCO output clock divider, CLKOUT -
72+ output clock, BWADJ is the PLL bandwidth adjustment parameter. At this moment
73+ the binding supports the PLL dividers configuration in accordance with a
74+ requested rate, while bypassing and bandwidth adjustment settings can be
75+ added in future if it gets to be necessary.
76+
77+ The PLLs CLKOUT is then either directly connected with the corresponding
78+ clocks consumer (like P5600 cores or DDR controller) or passed over a CCU
79+ divider to create a signal required for the clock domain.
80+
81+ The CCU PLL dts-node uses the common clock bindings with no custom
82+ parameters. The list of exported clocks can be found in
83+ 'include/dt-bindings/clock/bt1-ccu.h'. Since CCU PLL is a part of the
84+ Baikal-T1 SoC System Controller its DT node is supposed to be a child of
85+ later one.
86+
87+properties:
88+ compatible:
89+ const: baikal,bt1-ccu-pll
90+
91+ reg:
92+ maxItems: 1
93+
94+ "#clock-cells":
95+ const: 1
96+
97+ clocks:
98+ description: External reference clock
99+ maxItems: 1
100+
101+ clock-names:
102+ const: ref_clk
103+
104+unevaluatedProperties: false
105+
106+required:
107+ - compatible
108+ - "#clock-cells"
109+ - clocks
110+ - clock-names
111+
112+examples:
113+ # Clock Control Unit PLL node:
114+ - |
115+ clock-controller@1f04d000 {
116+ compatible = "baikal,bt1-ccu-pll";
117+ reg = <0x1f04d000 0x028>;
118+ #clock-cells = <1>;
119+
120+ clocks = <&clk25m>;
121+ clock-names = "ref_clk";
122+ };
123+ # Required external oscillator:
124+ - |
125+ clk25m: clock-oscillator-25m {
126+ compatible = "fixed-clock";
127+ #clock-cells = <0>;
128+ clock-frequency = <25000000>;
129+ clock-output-names = "clk25m";
130+ };
131+...
Documentation/devicetree/bindings/clock/idt,versaclock5.txt+1−0
@@ -12,6 +12,7 @@ Required properties: · 11 unmodified lines
1212 "idt,5p49v5933"
1313 "idt,5p49v5935"
1414 "idt,5p49v6901"
15+ "idt,5p49v6965"
1516 - reg: i2c device address, shall be 0x68 or 0x6a.
1617 - #clock-cells: from common clock binding; shall be set to 1.
1718 - clocks: from common clock binding; list of parent clock handles,
Documentation/devicetree/bindings/clock/intel,agilex.yaml+46−0
@@ -0,0 +1,46 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/clock/intel,agilex.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Intel SoCFPGA Agilex platform clock controller binding
8+
9+maintainers:
10+ - Dinh Nguyen <dinguyen@kernel.org>
11+
12+description:
13+ The Intel Agilex Clock controller is an integrated clock controller, which
14+ generates and supplies to all modules.
15+
16+properties:
17+ compatible:
18+ const: intel,agilex-clkmgr
19+
20+ '#clock-cells':
21+ const: 1
22+
23+ reg:
24+ maxItems: 1
25+
26+ clocks:
27+ maxItems: 1
28+
29+required:
30+ - compatible
31+ - reg
32+ - clocks
33+ - '#clock-cells'
34+
35+additionalProperties: false
36+
37+examples:
38+ # Clock controller node:
39+ - |
40+ clkmgr: clock-controller@ffd10000 {
41+ compatible = "intel,agilex-clkmgr";
42+ reg = <0xffd10000 0x1000>;
43+ clocks = <&osc1>;
44+ #clock-cells = <1>;
45+ };
46+...
Documentation/devicetree/bindings/clock/intel,cgu-lgm.yaml+44−0
@@ -0,0 +1,44 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/clock/intel,cgu-lgm.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Intel Lightning Mountain SoC's Clock Controller(CGU) Binding
8+
9+maintainers:
10+ - Rahul Tanwar <rahul.tanwar@linux.intel.com>
11+
12+description: |
13+ Lightning Mountain(LGM) SoC's Clock Generation Unit(CGU) driver provides
14+ all means to access the CGU hardware module in order to generate a series
15+ of clocks for the whole system and individual peripherals.
16+
17+ Please refer to include/dt-bindings/clock/intel,lgm-clk.h header file, it
18+ defines all available clocks as macros. These macros can be used in device
19+ tree sources.
20+
21+properties:
22+ compatible:
23+ const: intel,cgu-lgm
24+
25+ reg:
26+ maxItems: 1
27+
28+ '#clock-cells':
29+ const: 1
30+
31+required:
32+ - compatible
33+ - reg
34+ - '#clock-cells'
35+
36+examples:
37+ - |
38+ cgu: clock-controller@e0200000 {
39+ compatible = "intel,cgu-lgm";
40+ reg = <0xe0200000 0x33c>;
41+ #clock-cells = <1>;
42+ };
43+
44+...
Documentation/devicetree/bindings/clock/marvell,mmp2-audio-clock.yaml+75−0
@@ -0,0 +1,75 @@
1+# SPDX-License-Identifier: (GPL-2.0+ OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/clock/marvell,mmp2-audio-clock.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Marvell MMP2 Audio Clock Controller
8+
9+maintainers:
10+ - Lubomir Rintel <lkundrak@v3.sk>
11+
12+description: |
13+ The audio clock controller generates and supplies the clocks to the audio
14+ codec.
15+
16+ Each clock is assigned an identifier and client nodes use this identifier
17+ to specify the clock which they consume.
18+
19+ All these identifiers could be found in
20+ <dt-bindings/clock/marvell,mmp2-audio.h>.
21+
22+properties:
23+ compatible:
24+ enum:
25+ - marvell,mmp2-audio-clock
26+
27+ reg:
28+ maxItems: 1
29+
30+ clocks:
31+ items:
32+ - description: Audio subsystem clock
33+ - description: The crystal oscillator clock
34+ - description: First I2S clock
35+ - description: Second I2S clock
36+
37+ clock-names:
38+ items:
39+ - const: audio
40+ - const: vctcxo
41+ - const: i2s0
42+ - const: i2s1
43+
44+ '#clock-cells':
45+ const: 1
46+
47+ power-domains:
48+ maxItems: 1
49+
50+required:
51+ - compatible
52+ - reg
53+ - clocks
54+ - clock-names
55+ - '#clock-cells'
56+
57+additionalProperties: false
58+
59+examples:
60+ - |
61+ #include <dt-bindings/clock/marvell,mmp2-audio.h>
62+ #include <dt-bindings/clock/marvell,mmp2.h>
63+ #include <dt-bindings/power/marvell,mmp2.h>
64+
65+ clock-controller@d42a0c30 {
66+ compatible = "marvell,mmp2-audio-clock";
67+ reg = <0xd42a0c30 0x10>;
68+ clock-names = "audio", "vctcxo", "i2s0", "i2s1";
69+ clocks = <&soc_clocks MMP2_CLK_AUDIO>,
70+ <&soc_clocks MMP2_CLK_VCTCXO>,
71+ <&soc_clocks MMP2_CLK_I2S0>,
72+ <&soc_clocks MMP2_CLK_I2S1>;
73+ power-domains = <&soc_clocks MMP2_POWER_DOMAIN_AUDIO>;
74+ #clock-cells = <1>;
75+ };
Documentation/devicetree/bindings/clock/marvell,mmp2-clock.yaml+5−0
@@ -42,12 +42,16 @@ properties: · 41 unmodified lines
4242 '#reset-cells':
4343 const: 1
4444
45+ '#power-domain-cells':
46+ const: 1
47+
4548 required:
4649 - compatible
4750 - reg
4851 - reg-names
4952 - '#clock-cells'
5053 - '#reset-cells'
54+ - '#power-domain-cells'
5155
5256 additionalProperties: false
5357
@@ -61,4 +65,5 @@ examples: · 7 unmodified lines
6165 reg-names = "mpmu", "apmu", "apbc";
6266 #clock-cells = <1>;
6367 #reset-cells = <1>;
68+ #power-domain-cells = <1>;
6469 };
Documentation/devicetree/bindings/clock/qcom,a53pll.txt+0−22
@@ -1,22 +0,0 @@
1−Qualcomm MSM8916 A53 PLL Binding
2−--------------------------------
3−The A53 PLL on MSM8916 platforms is the main CPU PLL used used for frequencies
4−above 1GHz.
5−
6−Required properties :
7−- compatible : Shall contain only one of the following:
8−
9− "qcom,msm8916-a53pll"
10−
11−- reg : shall contain base register location and length
12−
13−- #clock-cells : must be set to <0>
14−
15−Example:
16−
17− a53pll: clock@b016000 {
18− compatible = "qcom,msm8916-a53pll";
19− reg = <0xb016000 0x40>;
20− #clock-cells = <0>;
21− };
22−
Documentation/devicetree/bindings/clock/qcom,a53pll.yaml+40−0
@@ -0,0 +1,40 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/clock/qcom,a53pll.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Qualcomm A53 PLL Binding
8+
9+maintainers:
10+ - Sivaprakash Murugesan <sivaprak@codeaurora.org>
11+
12+description:
13+ The A53 PLL on few Qualcomm platforms is the main CPU PLL used used for
14+ frequencies above 1GHz.
15+
16+properties:
17+ compatible:
18+ const: qcom,msm8916-a53pll
19+
20+ reg:
21+ maxItems: 1
22+
23+ '#clock-cells':
24+ const: 0
25+
26+required:
27+ - compatible
28+ - reg
29+ - '#clock-cells'
30+
31+additionalProperties: false
32+
33+examples:
34+ #Example 1 - A53 PLL found on MSM8916 devices
35+ - |
36+ a53pll: clock@b016000 {
37+ compatible = "qcom,msm8916-a53pll";
38+ reg = <0xb016000 0x40>;
39+ #clock-cells = <0>;
40+ };
Documentation/devicetree/bindings/clock/qcom,gcc.yaml+3−0
@@ -22,6 +22,8 @@ description: | · 21 unmodified lines
2222 - dt-bindings/reset/qcom,gcc-ipq6018.h
2323 - dt-bindings/clock/qcom,gcc-ipq806x.h (qcom,gcc-ipq8064)
2424 - dt-bindings/reset/qcom,gcc-ipq806x.h (qcom,gcc-ipq8064)
25+ - dt-bindings/clock/qcom,gcc-msm8939.h
26+ - dt-bindings/reset/qcom,gcc-msm8939.h
2527 - dt-bindings/clock/qcom,gcc-msm8660.h
2628 - dt-bindings/reset/qcom,gcc-msm8660.h
2729 - dt-bindings/clock/qcom,gcc-msm8974.h
@@ -41,6 +43,7 @@ properties: · 13 unmodified lines
4143 - qcom,gcc-ipq8064
4244 - qcom,gcc-msm8660
4345 - qcom,gcc-msm8916
46+ - qcom,gcc-msm8939
4447 - qcom,gcc-msm8960
4548 - qcom,gcc-msm8974
4649 - qcom,gcc-msm8974pro
Documentation/devicetree/bindings/clock/qcom,mmcc.yaml+4−0
@@ -67,6 +67,10 @@ properties: · 66 unmodified lines
6767 description:
6868 Protected clock specifier list as per common clock binding
6969
70+ vdd-gfx-supply:
71+ description:
72+ Regulator supply for the GPU_GX GDSC
73+
7074 required:
7175 - compatible
7276 - reg
Documentation/devicetree/bindings/clock/renesas,cpg-div6-clock.yaml+60−0
@@ -0,0 +1,60 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/clock/renesas,cpg-div6-clock.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Renesas CPG DIV6 Clock
8+
9+maintainers:
10+ - Geert Uytterhoeven <geert+renesas@glider.be>
11+
12+description:
13+ The CPG DIV6 clocks are variable factor clocks provided by the Clock Pulse
14+ Generator (CPG). Their clock input is divided by a configurable factor from 1
15+ to 64.
16+
17+properties:
18+ compatible:
19+ items:
20+ - enum:
21+ - renesas,r8a73a4-div6-clock # R-Mobile APE6
22+ - renesas,r8a7740-div6-clock # R-Mobile A1
23+ - renesas,sh73a0-div6-clock # SH-Mobile AG5
24+ - const: renesas,cpg-div6-clock
25+
26+ reg:
27+ maxItems: 1
28+
29+ clocks:
30+ oneOf:
31+ - maxItems: 1
32+ - maxItems: 4
33+ - maxItems: 8
34+ description:
35+ For clocks with multiple parents, invalid settings must be specified as
36+ "<0>".
37+
38+ '#clock-cells':
39+ const: 0
40+
41+ clock-output-names: true
42+
43+required:
44+ - compatible
45+ - reg
46+ - clocks
47+ - '#clock-cells'
48+
49+additionalProperties: false
50+
51+examples:
52+ - |
53+ #include <dt-bindings/clock/r8a73a4-clock.h>
54+ sdhi2_clk: sdhi2_clk@e615007c {
55+ compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
56+ reg = <0xe615007c 4>;
57+ clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>, <0>,
58+ <&extal2_clk>;
59+ #clock-cells = <0>;
60+ };
Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt+0−40
@@ -1,40 +0,0 @@
1−* Renesas CPG DIV6 Clock
2−
3−The CPG DIV6 clocks are variable factor clocks provided by the Clock Pulse
4−Generator (CPG). Their clock input is divided by a configurable factor from 1
5−to 64.
6−
7−Required Properties:
8−
9− - compatible: Must be one of the following
10− - "renesas,r8a73a4-div6-clock" for R8A73A4 (R-Mobile APE6) DIV6 clocks
11− - "renesas,r8a7740-div6-clock" for R8A7740 (R-Mobile A1) DIV6 clocks
12− - "renesas,r8a7790-div6-clock" for R8A7790 (R-Car H2) DIV6 clocks
13− - "renesas,r8a7791-div6-clock" for R8A7791 (R-Car M2-W) DIV6 clocks
14− - "renesas,r8a7793-div6-clock" for R8A7793 (R-Car M2-N) DIV6 clocks
15− - "renesas,r8a7794-div6-clock" for R8A7794 (R-Car E2) DIV6 clocks
16− - "renesas,sh73a0-div6-clock" for SH73A0 (SH-Mobile AG5) DIV6 clocks
17− and "renesas,cpg-div6-clock" as a fallback.
18− - reg: Base address and length of the memory resource used by the DIV6 clock
19− - clocks: Reference to the parent clock(s); either one, four, or eight
20− clocks must be specified. For clocks with multiple parents, invalid
21− settings must be specified as "<0>".
22− - #clock-cells: Must be 0
23−
24−
25−Optional Properties:
26−
27− - clock-output-names: The name of the clock as a free-form string
28−
29−
30−Example
31−-------
32−
33− sdhi2_clk: sdhi2_clk@e615007c {
34− compatible = "renesas,r8a73a4-div6-clock", "renesas,cpg-div6-clock";
35− reg = <0 0xe615007c 0 4>;
36− clocks = <&pll1_div2_clk>, <&cpg_clocks R8A73A4_CLK_PLL2S>,
37− <0>, <&extal2_clk>;
38− #clock-cells = <0>;
39− clock-output-names = "sdhi2ck";
40− };
Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml+1−0
@@ -25,6 +25,7 @@ properties: · 24 unmodified lines
2525 compatible:
2626 enum:
2727 - renesas,r7s9210-cpg-mssr # RZ/A2
28+ - renesas,r8a7742-cpg-mssr # RZ/G1H
2829 - renesas,r8a7743-cpg-mssr # RZ/G1M
2930 - renesas,r8a7744-cpg-mssr # RZ/G1N
3031 - renesas,r8a7745-cpg-mssr # RZ/G1E
Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt+0−60
@@ -1,60 +0,0 @@
1−* Renesas CPG Module Stop (MSTP) Clocks
2−
3−The CPG can gate SoC device clocks. The gates are organized in groups of up to
4−32 gates.
5−
6−This device tree binding describes a single 32 gate clocks group per node.
7−Clocks are referenced by user nodes by the MSTP node phandle and the clock
8−index in the group, from 0 to 31.
9−
10−Required Properties:
11−
12− - compatible: Must be one of the following
13− - "renesas,r7s72100-mstp-clocks" for R7S72100 (RZ) MSTP gate clocks
14− - "renesas,r8a73a4-mstp-clocks" for R8A73A4 (R-Mobile APE6) MSTP gate clocks
15− - "renesas,r8a7740-mstp-clocks" for R8A7740 (R-Mobile A1) MSTP gate clocks
16− - "renesas,r8a7778-mstp-clocks" for R8A7778 (R-Car M1) MSTP gate clocks
17− - "renesas,r8a7779-mstp-clocks" for R8A7779 (R-Car H1) MSTP gate clocks
18− - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks
19− - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2-W) MSTP gate clocks
20− - "renesas,r8a7792-mstp-clocks" for R8A7792 (R-Car V2H) MSTP gate clocks
21− - "renesas,r8a7793-mstp-clocks" for R8A7793 (R-Car M2-N) MSTP gate clocks
22− - "renesas,r8a7794-mstp-clocks" for R8A7794 (R-Car E2) MSTP gate clocks
23− - "renesas,sh73a0-mstp-clocks" for SH73A0 (SH-MobileAG5) MSTP gate clocks
24− and "renesas,cpg-mstp-clocks" as a fallback.
25− - reg: Base address and length of the I/O mapped registers used by the MSTP
26− clocks. The first register is the clock control register and is mandatory.
27− The second register is the clock status register and is optional when not
28− implemented in hardware.
29− - clocks: Reference to the parent clocks, one per output clock. The parents
30− must appear in the same order as the output clocks.
31− - #clock-cells: Must be 1
32− - clock-output-names: The name of the clocks as free-form strings
33− - clock-indices: Indices of the gate clocks into the group (0 to 31)
34−
35−The clocks, clock-output-names and clock-indices properties contain one entry
36−per gate clock. The MSTP groups are sparsely populated. Unimplemented gate
37−clocks must not be declared.
38−
39−
40−Example
41−-------
42−
43− #include <dt-bindings/clock/r8a7790-clock.h>
44−
45− mstp3_clks: mstp3_clks@e615013c {
46− compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
47− reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
48− clocks = <&cp_clk>, <&mmc1_clk>, <&sd3_clk>, <&sd2_clk>,
49− <&cpg_clocks R8A7790_CLK_SD1>, <&cpg_clocks R8A7790_CLK_SD0>,
50− <&mmc0_clk>;
51− #clock-cells = <1>;
52− clock-output-names =
53− "tpu0", "mmcif1", "sdhi3", "sdhi2",
54− "sdhi1", "sdhi0", "mmcif0";
55− clock-indices = <
56− R8A7790_CLK_TPU0 R8A7790_CLK_MMCIF1 R8A7790_CLK_SDHI3
57− R8A7790_CLK_SDHI2 R8A7790_CLK_SDHI1 R8A7790_CLK_SDHI0
58− R8A7790_CLK_MMCIF0
59− >;
60− };
Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.yaml+82−0
@@ -0,0 +1,82 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/clock/renesas,cpg-mstp-clocks.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Renesas Clock Pulse Generator (CPG) Module Stop (MSTP) Clocks
8+
9+maintainers:
10+ - Geert Uytterhoeven <geert+renesas@glider.be>
11+
12+description:
13+ The Clock Pulse Generator (CPG) can gate SoC device clocks. The gates are
14+ organized in groups of up to 32 gates.
15+
16+ This device tree binding describes a single 32 gate clocks group per node.
17+ Clocks are referenced by user nodes by the Module Stop (MSTP) node phandle
18+ and the clock index in the group, from 0 to 31.
19+
20+properties:
21+ compatible:
22+ items:
23+ - enum:
24+ - renesas,r7s72100-mstp-clocks # RZ/A1
25+ - renesas,r8a73a4-mstp-clocks # R-Mobile APE6
26+ - renesas,r8a7740-mstp-clocks # R-Mobile A1
27+ - renesas,r8a7778-mstp-clocks # R-Car M1
28+ - renesas,r8a7779-mstp-clocks # R-Car H1
29+ - renesas,sh73a0-mstp-clocks # SH-Mobile AG5
30+ - const: renesas,cpg-mstp-clocks
31+
32+ reg:
33+ minItems: 1
34+ items:
35+ - description: Module Stop Control Register (MSTPCR)
36+ - description: Module Stop Status Register (MSTPSR)
37+
38+ clocks:
39+ minItems: 1
40+ maxItems: 32
41+
42+ '#clock-cells':
43+ const: 1
44+
45+ clock-indices:
46+ minItems: 1
47+ maxItems: 32
48+
49+ clock-output-names:
50+ minItems: 1
51+ maxItems: 32
52+
53+required:
54+ - compatible
55+ - reg
56+ - clocks
57+ - '#clock-cells'
58+ - clock-indices
59+ - clock-output-names
60+
61+additionalProperties: false
62+
63+examples:
64+ - |
65+ #include <dt-bindings/clock/r8a73a4-clock.h>
66+ mstp2_clks: mstp2_clks@e6150138 {
67+ compatible = "renesas,r8a73a4-mstp-clocks",
68+ "renesas,cpg-mstp-clocks";
69+ reg = <0xe6150138 4>, <0xe6150040 4>;
70+ clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>,
71+ <&mp_clk>, <&cpg_clocks R8A73A4_CLK_HP>;
72+ #clock-cells = <1>;
73+ clock-indices = <
74+ R8A73A4_CLK_SCIFA0 R8A73A4_CLK_SCIFA1
75+ R8A73A4_CLK_SCIFB0 R8A73A4_CLK_SCIFB1
76+ R8A73A4_CLK_SCIFB2 R8A73A4_CLK_SCIFB3
77+ R8A73A4_CLK_DMAC
78+ >;
79+ clock-output-names =
80+ "scifa0", "scifa1", "scifb0", "scifb1", "scifb2", "scifb3",
81+ "dmac";
82+ };
Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt+3−1
@@ -27,7 +27,9 @@ Required properties: · 26 unmodified lines
2727 - compatible: "renesas,r8a7795-rcar-usb2-clock-sel" if the device is a part of
2828 an R8A7795 SoC.
2929 "renesas,r8a7796-rcar-usb2-clock-sel" if the device if a part of
30− an R8A7796 SoC.
30+ an R8A77960 SoC.
31+ "renesas,r8a77961-rcar-usb2-clock-sel" if the device if a part of
32+ an R8A77961 SoC.
3133 "renesas,rcar-gen3-usb2-clock-sel" for a generic R-Car Gen3
3234 compatible device.
3335
Documentation/devicetree/bindings/clock/silabs,si5341.txt+10−1
@@ -1,15 +1,21 @@
1−Binding for Silicon Labs Si5341 and Si5340 programmable i2c clock generator.
1+Binding for Silicon Labs Si5340, Si5341 Si5342, Si5344 and Si5345 programmable
2+i2c clock generator.
23
34 Reference
45 [1] Si5341 Data Sheet
56 https://www.silabs.com/documents/public/data-sheets/Si5341-40-D-DataSheet.pdf
67 [2] Si5341 Reference Manual
78 https://www.silabs.com/documents/public/reference-manuals/Si5341-40-D-RM.pdf
9+[3] Si5345 Reference Manual
10+ https://www.silabs.com/documents/public/reference-manuals/Si5345-44-42-D-RM.pdf
811
912 The Si5341 and Si5340 are programmable i2c clock generators with up to 10 output
1013 clocks. The chip contains a PLL that sources 5 (or 4) multisynth clocks, which
1114 in turn can be directed to any of the 10 (or 4) outputs through a divider.
1215 The internal structure of the clock generators can be found in [2].
16+The Si5345 is similar to the Si5341 with the addition of fractional input
17+dividers and automatic input selection, as described in [3].
18+The Si5342 and Si5344 are smaller versions of the Si5345, with 2 or 4 outputs.
1319
1420 The driver can be used in "as is" mode, reading the current settings from the
1521 chip at boot, in case you have a (pre-)programmed device. If the PLL is not
@@ -28,6 +34,9 @@ Required properties: · 12 unmodified lines
2834 - compatible: shall be one of the following:
2935 "silabs,si5340" - Si5340 A/B/C/D
3036 "silabs,si5341" - Si5341 A/B/C/D
37+ "silabs,si5342" - Si5342 A/B/C/D
38+ "silabs,si5344" - Si5344 A/B/C/D
39+ "silabs,si5345" - Si5345 A/B/C/D
3140 - reg: i2c device address, usually 0x74
3241 - #clock-cells: from common clock binding; shall be set to 2.
3342 The first value is "0" for outputs, "1" for synthesizers.
Documentation/devicetree/bindings/clock/sprd,sc9863a-clk.yaml+1−0
@@ -28,6 +28,7 @@ properties: · 27 unmodified lines
2828 - sprd,sc9863a-rpll
2929 - sprd,sc9863a-dpll
3030 - sprd,sc9863a-mm-gate
31+ - sprd,sc9863a-mm-clk
3132 - sprd,sc9863a-apapb-gate
3233
3334 clocks:
MAINTAINERS+1−0
@@ -14493,6 +14493,7 @@ M: Geert Uytterhoeven <geert+renesas@glider.be> · 14492 unmodified lines
1449314493 L: linux-renesas-soc@vger.kernel.org
1449414494 S: Supported
1449514495 T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git clk-renesas
14496+F: Documentation/devicetree/bindings/clock/renesas,*
1449614497 F: drivers/clk/renesas/
1449714498
1449814499 RENESAS EMEV2 I2C DRIVER
arch/Kconfig+0−6
@@ -328,12 +328,6 @@ config HAVE_FUNCTION_ARG_ACCESS_API · 327 unmodified lines
328328 the API needed to access function arguments from pt_regs,
329329 declared in asm/ptrace.h
330330
331−config HAVE_CLK
332− bool
333− help
334− The <linux/clk.h> calls support software clock gating and
335− thus are a key power management tool on many systems.
336−
337331 config HAVE_HW_BREAKPOINT
338332 bool
339333 depends on PERF_EVENTS
arch/arm/Kconfig+2−3
@@ -367,6 +367,7 @@ config ARCH_EP93XX · 366 unmodified lines
367367 select CPU_ARM920T
368368 select GENERIC_CLOCKEVENTS
369369 select GPIOLIB
370+ select HAVE_LEGACY_CLK
370371 help
371372 This enables support for the Cirrus EP93xx series of CPUs.
372373
@@ -438,7 +439,6 @@ config ARCH_PXA · 65 unmodified lines
438439 select ARM_CPU_SUSPEND if PM
439440 select AUTO_ZRELADDR
440441 select COMMON_CLK
441− select CLKDEV_LOOKUP
442442 select CLKSRC_PXA
443443 select CLKSRC_MMIO
444444 select TIMER_OF
@@ -477,7 +477,6 @@ config ARCH_SA1100 · 32 unmodified lines
477477 bool "SA1100-based"
478478 select ARCH_MTD_XIP
479479 select ARCH_SPARSEMEM_ENABLE
480− select CLKDEV_LOOKUP
481480 select CLKSRC_MMIO
482481 select CLKSRC_PXA
483482 select TIMER_OF if OF
@@ -498,7 +497,6 @@ config ARCH_SA1100 · 14 unmodified lines
498497 config ARCH_S3C24XX
499498 bool "Samsung S3C24XX SoCs"
500499 select ATAGS
501− select CLKDEV_LOOKUP
502500 select CLKSRC_SAMSUNG_PWM
503501 select GENERIC_CLOCKEVENTS
504502 select GPIO_SAMSUNG
@@ -528,6 +526,7 @@ config ARCH_OMAP1 · 23 unmodified lines
528526 select GENERIC_IRQ_MULTI_HANDLER
529527 select GPIOLIB
530528 select HAVE_IDE
529+ select HAVE_LEGACY_CLK
531530 select IRQ_DOMAIN
532531 select NEED_MACH_IO_H if PCCARD
533532 select NEED_MACH_MEMORY_H
arch/arm/mach-mmp/Kconfig+2−0
@@ -124,6 +124,8 @@ config MACH_MMP2_DT · 123 unmodified lines
124124 select PINCTRL_SINGLE
125125 select ARCH_HAS_RESET_CONTROLLER
126126 select CPU_PJ4
127+ select PM_GENERIC_DOMAINS if PM
128+ select PM_GENERIC_DOMAINS_OF if PM && OF
127129 help
128130 Include support for Marvell MMP2 based platforms using
129131 the device tree.
arch/arm/mach-mmp/Makefile+0−6
@@ -12,12 +12,6 @@ obj-$(CONFIG_CPU_PXA910) += pxa910.o · 11 unmodified lines
1212 obj-$(CONFIG_CPU_MMP2) += mmp2.o
1313 obj-$(CONFIG_MMP_SRAM) += sram.o
1414
15−ifeq ($(CONFIG_COMMON_CLK), )
16−obj-y += clock.o
17−obj-$(CONFIG_CPU_PXA168) += clock-pxa168.o
18−obj-$(CONFIG_CPU_PXA910) += clock-pxa910.o
19−obj-$(CONFIG_CPU_MMP2) += clock-mmp2.o
20−endif
2115 ifeq ($(CONFIG_PM),y)
2216 obj-$(CONFIG_CPU_PXA910) += pm-pxa910.o
2317 obj-$(CONFIG_CPU_MMP2) += pm-mmp2.o
arch/arm/mach-mmp/clock-mmp2.c+0−114
@@ -1,114 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0
2−#include <linux/module.h>
3−#include <linux/kernel.h>
4−#include <linux/init.h>
5−#include <linux/list.h>
6−#include <linux/io.h>
7−#include <linux/clk.h>
8−#include <linux/clk/mmp.h>
9−
10−#include "addr-map.h"
11−
12−#include "common.h"
13−#include "clock.h"
14−
15−/*
16− * APB Clock register offsets for MMP2
17− */
18−#define APBC_RTC APBC_REG(0x000)
19−#define APBC_TWSI1 APBC_REG(0x004)
20−#define APBC_TWSI2 APBC_REG(0x008)
21−#define APBC_TWSI3 APBC_REG(0x00c)
22−#define APBC_TWSI4 APBC_REG(0x010)
23−#define APBC_KPC APBC_REG(0x018)
24−#define APBC_UART1 APBC_REG(0x02c)
25−#define APBC_UART2 APBC_REG(0x030)
26−#define APBC_UART3 APBC_REG(0x034)
27−#define APBC_GPIO APBC_REG(0x038)
28−#define APBC_PWM0 APBC_REG(0x03c)
29−#define APBC_PWM1 APBC_REG(0x040)
30−#define APBC_PWM2 APBC_REG(0x044)
31−#define APBC_PWM3 APBC_REG(0x048)
32−#define APBC_SSP0 APBC_REG(0x04c)
33−#define APBC_SSP1 APBC_REG(0x050)
34−#define APBC_SSP2 APBC_REG(0x054)
35−#define APBC_SSP3 APBC_REG(0x058)
36−#define APBC_SSP4 APBC_REG(0x05c)
37−#define APBC_SSP5 APBC_REG(0x060)
38−#define APBC_TWSI5 APBC_REG(0x07c)
39−#define APBC_TWSI6 APBC_REG(0x080)
40−#define APBC_UART4 APBC_REG(0x088)
41−
42−#define APMU_USB APMU_REG(0x05c)
43−#define APMU_NAND APMU_REG(0x060)
44−#define APMU_SDH0 APMU_REG(0x054)
45−#define APMU_SDH1 APMU_REG(0x058)
46−#define APMU_SDH2 APMU_REG(0x0e8)
47−#define APMU_SDH3 APMU_REG(0x0ec)
48−
49−static void sdhc_clk_enable(struct clk *clk)
50−{
51− uint32_t clk_rst;
52−
53− clk_rst = __raw_readl(clk->clk_rst);
54− clk_rst |= clk->enable_val;
55− __raw_writel(clk_rst, clk->clk_rst);
56−}
57−
58−static void sdhc_clk_disable(struct clk *clk)
59−{
60− uint32_t clk_rst;
61−
62− clk_rst = __raw_readl(clk->clk_rst);
63− clk_rst &= ~clk->enable_val;
64− __raw_writel(clk_rst, clk->clk_rst);
65−}
66−
67−struct clkops sdhc_clk_ops = {
68− .enable = sdhc_clk_enable,
69− .disable = sdhc_clk_disable,
70−};
71−
72−/* APB peripheral clocks */
73−static APBC_CLK(uart1, UART1, 1, 26000000);
74−static APBC_CLK(uart2, UART2, 1, 26000000);
75−static APBC_CLK(uart3, UART3, 1, 26000000);
76−static APBC_CLK(uart4, UART4, 1, 26000000);
77−static APBC_CLK(twsi1, TWSI1, 0, 26000000);
78−static APBC_CLK(twsi2, TWSI2, 0, 26000000);
79−static APBC_CLK(twsi3, TWSI3, 0, 26000000);
80−static APBC_CLK(twsi4, TWSI4, 0, 26000000);
81−static APBC_CLK(twsi5, TWSI5, 0, 26000000);
82−static APBC_CLK(twsi6, TWSI6, 0, 26000000);
83−static APBC_CLK(gpio, GPIO, 0, 26000000);
84−
85−static APMU_CLK(nand, NAND, 0xbf, 100000000);
86−static APMU_CLK_OPS(sdh0, SDH0, 0x1b, 200000000, &sdhc_clk_ops);
87−static APMU_CLK_OPS(sdh1, SDH1, 0x1b, 200000000, &sdhc_clk_ops);
88−static APMU_CLK_OPS(sdh2, SDH2, 0x1b, 200000000, &sdhc_clk_ops);
89−static APMU_CLK_OPS(sdh3, SDH3, 0x1b, 200000000, &sdhc_clk_ops);
90−
91−static struct clk_lookup mmp2_clkregs[] = {
92− INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
93− INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
94− INIT_CLKREG(&clk_uart3, "pxa2xx-uart.2", NULL),
95− INIT_CLKREG(&clk_uart4, "pxa2xx-uart.3", NULL),
96− INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.0", NULL),
97− INIT_CLKREG(&clk_twsi2, "pxa2xx-i2c.1", NULL),
98− INIT_CLKREG(&clk_twsi3, "pxa2xx-i2c.2", NULL),
99− INIT_CLKREG(&clk_twsi4, "pxa2xx-i2c.3", NULL),
100− INIT_CLKREG(&clk_twsi5, "pxa2xx-i2c.4", NULL),
101− INIT_CLKREG(&clk_twsi6, "pxa2xx-i2c.5", NULL),
102− INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
103− INIT_CLKREG(&clk_gpio, "mmp2-gpio", NULL),
104− INIT_CLKREG(&clk_sdh0, "sdhci-pxav3.0", "PXA-SDHCLK"),
105− INIT_CLKREG(&clk_sdh1, "sdhci-pxav3.1", "PXA-SDHCLK"),
106− INIT_CLKREG(&clk_sdh2, "sdhci-pxav3.2", "PXA-SDHCLK"),
107− INIT_CLKREG(&clk_sdh3, "sdhci-pxav3.3", "PXA-SDHCLK"),
108−};
109−
110−void __init mmp2_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
111− phys_addr_t apbc_phys)
112−{
113− clkdev_add_table(ARRAY_AND_SIZE(mmp2_clkregs));
114−}
arch/arm/mach-mmp/clock-pxa168.c+0−94
@@ -1,94 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0
2−#include <linux/module.h>
3−#include <linux/kernel.h>
4−#include <linux/init.h>
5−#include <linux/list.h>
6−#include <linux/io.h>
7−#include <linux/clk.h>
8−#include <linux/clk/mmp.h>
9−
10−#include "addr-map.h"
11−
12−#include "common.h"
13−#include "clock.h"
14−
15−/*
16− * APB clock register offsets for PXA168
17− */
18−#define APBC_UART1 APBC_REG(0x000)
19−#define APBC_UART2 APBC_REG(0x004)
20−#define APBC_GPIO APBC_REG(0x008)
21−#define APBC_PWM1 APBC_REG(0x00c)
22−#define APBC_PWM2 APBC_REG(0x010)
23−#define APBC_PWM3 APBC_REG(0x014)
24−#define APBC_PWM4 APBC_REG(0x018)
25−#define APBC_RTC APBC_REG(0x028)
26−#define APBC_TWSI0 APBC_REG(0x02c)
27−#define APBC_KPC APBC_REG(0x030)
28−#define APBC_TWSI1 APBC_REG(0x06c)
29−#define APBC_UART3 APBC_REG(0x070)
30−#define APBC_SSP1 APBC_REG(0x81c)
31−#define APBC_SSP2 APBC_REG(0x820)
32−#define APBC_SSP3 APBC_REG(0x84c)
33−#define APBC_SSP4 APBC_REG(0x858)
34−#define APBC_SSP5 APBC_REG(0x85c)
35−
36−#define APMU_NAND APMU_REG(0x060)
37−#define APMU_LCD APMU_REG(0x04c)
38−#define APMU_ETH APMU_REG(0x0fc)
39−#define APMU_USB APMU_REG(0x05c)
40−
41−/* APB peripheral clocks */
42−static APBC_CLK(uart1, UART1, 1, 14745600);
43−static APBC_CLK(uart2, UART2, 1, 14745600);
44−static APBC_CLK(uart3, UART3, 1, 14745600);
45−static APBC_CLK(twsi0, TWSI0, 1, 33000000);
46−static APBC_CLK(twsi1, TWSI1, 1, 33000000);
47−static APBC_CLK(pwm1, PWM1, 1, 13000000);
48−static APBC_CLK(pwm2, PWM2, 1, 13000000);
49−static APBC_CLK(pwm3, PWM3, 1, 13000000);
50−static APBC_CLK(pwm4, PWM4, 1, 13000000);
51−static APBC_CLK(ssp1, SSP1, 4, 0);
52−static APBC_CLK(ssp2, SSP2, 4, 0);
53−static APBC_CLK(ssp3, SSP3, 4, 0);
54−static APBC_CLK(ssp4, SSP4, 4, 0);
55−static APBC_CLK(ssp5, SSP5, 4, 0);
56−static APBC_CLK(gpio, GPIO, 0, 13000000);
57−static APBC_CLK(keypad, KPC, 0, 32000);
58−static APBC_CLK(rtc, RTC, 8, 32768);
59−
60−static APMU_CLK(nand, NAND, 0x19b, 156000000);
61−static APMU_CLK(lcd, LCD, 0x7f, 312000000);
62−static APMU_CLK(eth, ETH, 0x09, 0);
63−static APMU_CLK(usb, USB, 0x12, 0);
64−
65−/* device and clock bindings */
66−static struct clk_lookup pxa168_clkregs[] = {
67− INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
68− INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
69− INIT_CLKREG(&clk_uart3, "pxa2xx-uart.2", NULL),
70− INIT_CLKREG(&clk_twsi0, "pxa2xx-i2c.0", NULL),
71− INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.1", NULL),
72− INIT_CLKREG(&clk_pwm1, "pxa168-pwm.0", NULL),
73− INIT_CLKREG(&clk_pwm2, "pxa168-pwm.1", NULL),
74− INIT_CLKREG(&clk_pwm3, "pxa168-pwm.2", NULL),
75− INIT_CLKREG(&clk_pwm4, "pxa168-pwm.3", NULL),
76− INIT_CLKREG(&clk_ssp1, "pxa168-ssp.0", NULL),
77− INIT_CLKREG(&clk_ssp2, "pxa168-ssp.1", NULL),
78− INIT_CLKREG(&clk_ssp3, "pxa168-ssp.2", NULL),
79− INIT_CLKREG(&clk_ssp4, "pxa168-ssp.3", NULL),
80− INIT_CLKREG(&clk_ssp5, "pxa168-ssp.4", NULL),
81− INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
82− INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL),
83− INIT_CLKREG(&clk_gpio, "mmp-gpio", NULL),
84− INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL),
85− INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"),
86− INIT_CLKREG(&clk_usb, NULL, "PXA168-USBCLK"),
87− INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
88−};
89−
90−void __init pxa168_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
91− phys_addr_t apbc_phys)
92−{
93− clkdev_add_table(ARRAY_AND_SIZE(pxa168_clkregs));
94−}
arch/arm/mach-mmp/clock-pxa910.c+0−70
@@ -1,70 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0
2−#include <linux/module.h>
3−#include <linux/kernel.h>
4−#include <linux/init.h>
5−#include <linux/list.h>
6−#include <linux/io.h>
7−#include <linux/clk.h>
8−#include <linux/clk/mmp.h>
9−
10−#include "addr-map.h"
11−
12−#include "common.h"
13−#include "clock.h"
14−
15−/*
16− * APB Clock register offsets for PXA910
17− */
18−#define APBC_UART0 APBC_REG(0x000)
19−#define APBC_UART1 APBC_REG(0x004)
20−#define APBC_GPIO APBC_REG(0x008)
21−#define APBC_PWM1 APBC_REG(0x00c)
22−#define APBC_PWM2 APBC_REG(0x010)
23−#define APBC_PWM3 APBC_REG(0x014)
24−#define APBC_PWM4 APBC_REG(0x018)
25−#define APBC_SSP1 APBC_REG(0x01c)
26−#define APBC_SSP2 APBC_REG(0x020)
27−#define APBC_RTC APBC_REG(0x028)
28−#define APBC_TWSI0 APBC_REG(0x02c)
29−#define APBC_KPC APBC_REG(0x030)
30−#define APBC_SSP3 APBC_REG(0x04c)
31−#define APBC_TWSI1 APBC_REG(0x06c)
32−
33−#define APMU_NAND APMU_REG(0x060)
34−#define APMU_USB APMU_REG(0x05c)
35−
36−static APBC_CLK(uart1, UART0, 1, 14745600);
37−static APBC_CLK(uart2, UART1, 1, 14745600);
38−static APBC_CLK(twsi0, TWSI0, 1, 33000000);
39−static APBC_CLK(twsi1, TWSI1, 1, 33000000);
40−static APBC_CLK(pwm1, PWM1, 1, 13000000);
41−static APBC_CLK(pwm2, PWM2, 1, 13000000);
42−static APBC_CLK(pwm3, PWM3, 1, 13000000);
43−static APBC_CLK(pwm4, PWM4, 1, 13000000);
44−static APBC_CLK(gpio, GPIO, 0, 13000000);
45−static APBC_CLK(rtc, RTC, 8, 32768);
46−
47−static APMU_CLK(nand, NAND, 0x19b, 156000000);
48−static APMU_CLK(u2o, USB, 0x1b, 480000000);
49−
50−/* device and clock bindings */
51−static struct clk_lookup pxa910_clkregs[] = {
52− INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
53− INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
54− INIT_CLKREG(&clk_twsi0, "pxa2xx-i2c.0", NULL),
55− INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.1", NULL),
56− INIT_CLKREG(&clk_pwm1, "pxa910-pwm.0", NULL),
57− INIT_CLKREG(&clk_pwm2, "pxa910-pwm.1", NULL),
58− INIT_CLKREG(&clk_pwm3, "pxa910-pwm.2", NULL),
59− INIT_CLKREG(&clk_pwm4, "pxa910-pwm.3", NULL),
60− INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
61− INIT_CLKREG(&clk_gpio, "mmp-gpio", NULL),
62− INIT_CLKREG(&clk_u2o, NULL, "U2OCLK"),
63− INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
64−};
65−
66−void __init pxa910_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
67− phys_addr_t apbc_phys, phys_addr_t apbcp_phys)
68−{
69− clkdev_add_table(ARRAY_AND_SIZE(pxa910_clkregs));
70−}
arch/arm/mach-mmp/clock.c+0−105
@@ -1,105 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0-only
2−/*
3− * linux/arch/arm/mach-mmp/clock.c
4− */
5−
6−#include <linux/module.h>
7−#include <linux/kernel.h>
8−#include <linux/list.h>
9−#include <linux/spinlock.h>
10−#include <linux/clk.h>
11−#include <linux/io.h>
12−
13−#include "regs-apbc.h"
14−#include "clock.h"
15−
16−static void apbc_clk_enable(struct clk *clk)
17−{
18− uint32_t clk_rst;
19−
20− clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(clk->fnclksel);
21− __raw_writel(clk_rst, clk->clk_rst);
22−}
23−
24−static void apbc_clk_disable(struct clk *clk)
25−{
26− __raw_writel(0, clk->clk_rst);
27−}
28−
29−struct clkops apbc_clk_ops = {
30− .enable = apbc_clk_enable,
31− .disable = apbc_clk_disable,
32−};
33−
34−static void apmu_clk_enable(struct clk *clk)
35−{
36− __raw_writel(clk->enable_val, clk->clk_rst);
37−}
38−
39−static void apmu_clk_disable(struct clk *clk)
40−{
41− __raw_writel(0, clk->clk_rst);
42−}
43−
44−struct clkops apmu_clk_ops = {
45− .enable = apmu_clk_enable,
46− .disable = apmu_clk_disable,
47−};
48−
49−static DEFINE_SPINLOCK(clocks_lock);
50−
51−int clk_enable(struct clk *clk)
52−{
53− unsigned long flags;
54−
55− spin_lock_irqsave(&clocks_lock, flags);
56− if (clk->enabled++ == 0)
57− clk->ops->enable(clk);
58− spin_unlock_irqrestore(&clocks_lock, flags);
59− return 0;
60−}
61−EXPORT_SYMBOL(clk_enable);
62−
63−void clk_disable(struct clk *clk)
64−{
65− unsigned long flags;
66−
67− if (!clk)
68− return;
69−
70− WARN_ON(clk->enabled == 0);
71−
72− spin_lock_irqsave(&clocks_lock, flags);
73− if (--clk->enabled == 0)
74− clk->ops->disable(clk);
75− spin_unlock_irqrestore(&clocks_lock, flags);
76−}
77−EXPORT_SYMBOL(clk_disable);
78−
79−unsigned long clk_get_rate(struct clk *clk)
80−{
81− unsigned long rate;
82−
83− if (clk->ops->getrate)
84− rate = clk->ops->getrate(clk);
85− else
86− rate = clk->rate;
87−
88− return rate;
89−}
90−EXPORT_SYMBOL(clk_get_rate);
91−
92−int clk_set_rate(struct clk *clk, unsigned long rate)
93−{
94− unsigned long flags;
95− int ret = -EINVAL;
96−
97− if (clk->ops->setrate) {
98− spin_lock_irqsave(&clocks_lock, flags);
99− ret = clk->ops->setrate(clk, rate);
100− spin_unlock_irqrestore(&clocks_lock, flags);
101− }
102−
103− return ret;
104−}
105−EXPORT_SYMBOL(clk_set_rate);
arch/arm/mach-mmp/clock.h+0−65
@@ -1,65 +0,0 @@
1−/* SPDX-License-Identifier: GPL-2.0-only */
2−
3−#include <linux/clkdev.h>
4−
5−struct clkops {
6− void (*enable)(struct clk *);
7− void (*disable)(struct clk *);
8− unsigned long (*getrate)(struct clk *);
9− int (*setrate)(struct clk *, unsigned long);
10−};
11−
12−struct clk {
13− const struct clkops *ops;
14−
15− void __iomem *clk_rst; /* clock reset control register */
16− int fnclksel; /* functional clock select (APBC) */
17− uint32_t enable_val; /* value for clock enable (APMU) */
18− unsigned long rate;
19− int enabled;
20−};
21−
22−extern struct clkops apbc_clk_ops;
23−extern struct clkops apmu_clk_ops;
24−
25−#define APBC_CLK(_name, _reg, _fnclksel, _rate) \
26−struct clk clk_##_name = { \
27− .clk_rst = APBC_##_reg, \
28− .fnclksel = _fnclksel, \
29− .rate = _rate, \
30− .ops = &apbc_clk_ops, \
31−}
32−
33−#define APBC_CLK_OPS(_name, _reg, _fnclksel, _rate, _ops) \
34−struct clk clk_##_name = { \
35− .clk_rst = APBC_##_reg, \
36− .fnclksel = _fnclksel, \
37− .rate = _rate, \
38− .ops = _ops, \
39−}
40−
41−#define APMU_CLK(_name, _reg, _eval, _rate) \
42−struct clk clk_##_name = { \
43− .clk_rst = APMU_##_reg, \
44− .enable_val = _eval, \
45− .rate = _rate, \
46− .ops = &apmu_clk_ops, \
47−}
48−
49−#define APMU_CLK_OPS(_name, _reg, _eval, _rate, _ops) \
50−struct clk clk_##_name = { \
51− .clk_rst = APMU_##_reg, \
52− .enable_val = _eval, \
53− .rate = _rate, \
54− .ops = _ops, \
55−}
56−
57−#define INIT_CLKREG(_clk, _devname, _conname) \
58− { \
59− .clk = _clk, \
60− .dev_id = _devname, \
61− .con_id = _conname, \
62− }
63−
64−extern struct clk clk_pxa168_gpio;
65−extern struct clk clk_pxa168_timers;
arch/arm/mach-mmp/pxa168.c+0−1
@@ -19,7 +19,6 @@ · 18 unmodified lines
1919 #include <asm/system_misc.h>
2020
2121 #include "addr-map.h"
22−#include "clock.h"
2322 #include "common.h"
2423 #include <linux/soc/mmp/cputype.h>
2524 #include "devices.h"
arch/arm/mach-mmp/time.c+0−1
@@ -34,7 +34,6 @@ · 33 unmodified lines
3434 #include "regs-apbc.h"
3535 #include "irqs.h"
3636 #include <linux/soc/mmp/cputype.h>
37−#include "clock.h"
3837
3938 #define TIMERS_VIRT_BASE TIMERS1_VIRT_BASE
4039
arch/arm/mach-vt8500/Kconfig+0−1
@@ -2,7 +2,6 @@ · 1 unmodified line
22 config ARCH_VT8500
33 bool
44 select GPIOLIB
5− select CLKDEV_LOOKUP
65 select VT8500_TIMER
76 select PINCTRL
87 help
arch/arm64/Kconfig.platforms+0−1
@@ -235,7 +235,6 @@ config ARCH_TEGRA · 234 unmodified lines
235235 bool "NVIDIA Tegra SoC Family"
236236 select ARCH_HAS_RESET_CONTROLLER
237237 select ARM_GIC_PM
238− select CLKDEV_LOOKUP
239238 select CLKSRC_MMIO
240239 select TIMER_OF
241240 select GENERIC_CLOCKEVENTS
arch/c6x/Kconfig+1−0
@@ -11,6 +11,7 @@ config C6X · 10 unmodified lines
1111 select ARCH_HAS_SYNC_DMA_FOR_CPU
1212 select ARCH_HAS_SYNC_DMA_FOR_DEVICE
1313 select CLKDEV_LOOKUP
14+ select HAVE_LEGACY_CLK
1415 select GENERIC_ATOMIC64
1516 select GENERIC_IRQ_SHOW
1617 select HAVE_ARCH_TRACEHOOK
arch/h8300/Kconfig+0−1
@@ -13,7 +13,6 @@ config H8300 · 12 unmodified lines
1313 select GENERIC_CPU_DEVICES
1414 select MODULES_USE_ELF_RELA
1515 select GENERIC_CLOCKEVENTS
16− select CLKDEV_LOOKUP
1716 select COMMON_CLK
1817 select ARCH_WANT_FRAME_POINTERS
1918 select OF
arch/m68k/Kconfig.cpu+1−1
@@ -28,7 +28,7 @@ config COLDFIRE · 27 unmodified lines
2828 select CPU_HAS_NO_MULDIV64
2929 select GENERIC_CSUM
3030 select GPIOLIB
31− select HAVE_CLK
31+ select HAVE_LEGACY_CLK
3232
3333 endchoice
3434
arch/mips/Kconfig+3−4
@@ -184,7 +184,7 @@ config AR7 · 183 unmodified lines
184184 select SYS_SUPPORTS_ZBOOT_UART16550
185185 select GPIOLIB
186186 select VLYNQ
187− select HAVE_CLK
187+ select HAVE_LEGACY_CLK
188188 help
189189 Support for the Texas Instruments AR7 System-on-a-Chip
190190 family: TNETD7100, 7200 and 7300.
@@ -212,9 +212,7 @@ config ATH79 · 21 unmodified lines
212212 select DMA_NONCOHERENT
213213 select GPIOLIB
214214 select PINCTRL
215− select HAVE_CLK
216215 select COMMON_CLK
217− select CLKDEV_LOOKUP
218216 select IRQ_MIPS_CPU
219217 select SYS_HAS_CPU_MIPS32_R2
220218 select SYS_HAS_EARLY_PRINTK
@@ -301,9 +299,9 @@ config BCM63XX · 80 unmodified lines
301299 select SYS_HAS_EARLY_PRINTK
302300 select SWAP_IO_SPACE
303301 select GPIOLIB
304− select HAVE_CLK
305302 select MIPS_L1_CACHE_SHIFT_4
306303 select CLKDEV_LOOKUP
304+ select HAVE_LEGACY_CLK
307305 help
308306 Support for BCM63XX based boards
309307
@@ -424,6 +422,7 @@ config LANTIQ · 114 unmodified lines
424422 select SWAP_IO_SPACE
425423 select BOOT_RAW
426424 select CLKDEV_LOOKUP
425+ select HAVE_LEGACY_CLK
427426 select USE_OF
428427 select PINCTRL
429428 select PINCTRL_LANTIQ
arch/mips/ralink/Kconfig+4−0
@@ -27,18 +27,22 @@ choice · 26 unmodified lines
2727 config SOC_RT288X
2828 bool "RT288x"
2929 select MIPS_L1_CACHE_SHIFT_4
30+ select HAVE_LEGACY_CLK
3031 select HAVE_PCI
3132
3233 config SOC_RT305X
3334 bool "RT305x"
35+ select HAVE_LEGACY_CLK
3436
3537 config SOC_RT3883
3638 bool "RT3883"
39+ select HAVE_LEGACY_CLK
3740 select HAVE_PCI
3841
3942 config SOC_MT7620
4043 bool "MT7620/8"
4144 select CPU_MIPSR2_IRQ_VI
45+ select HAVE_LEGACY_CLK
4246 select HAVE_PCI
4347
4448 config SOC_MT7621
arch/sh/boards/Kconfig+5−0
@@ -7,6 +7,11 @@ config SOLUTION_ENGINE · 6 unmodified lines
77 config SH_ALPHA_BOARD
88 bool
99
10+config SH_CUSTOM_CLK
11+ def_bool y
12+ depends on !SH_DEVICE_TREE
13+ select HAVE_LEGACY_CLK
14+
1015 config SH_DEVICE_TREE
1116 bool
1217 select OF
arch/unicore32/Kconfig+1−1
@@ -70,7 +70,7 @@ config ARCH_PUV3 · 69 unmodified lines
7070 def_bool y
7171 select CPU_UCV2
7272 select GENERIC_CLOCKEVENTS
73− select HAVE_CLK
73+ select HAVE_LEGACY_CLK
7474 select GPIOLIB
7575
7676 # CONFIGs for ARCH_PUV3
drivers/clk/Kconfig+28−5
@@ -1,5 +1,11 @@
11 # SPDX-License-Identifier: GPL-2.0
22
3+config HAVE_CLK
4+ bool
5+ help
6+ The <linux/clk.h> calls support software clock gating and
7+ thus are a key power management tool on many systems.
8+
39 config CLKDEV_LOOKUP
410 bool
511 select HAVE_CLK
@@ -7,8 +13,18 @@ config CLKDEV_LOOKUP · 1 unmodified line
713 config HAVE_CLK_PREPARE
814 bool
915
10−config COMMON_CLK
16+config HAVE_LEGACY_CLK # TODO: Remove once all legacy users are migrated
1117 bool
18+ select HAVE_CLK
19+ help
20+ Select this option when the clock API in <linux/clk.h> is implemented
21+ by platform/architecture code. This method is deprecated. Modern
22+ code should select COMMON_CLK instead and not define a custom
23+ 'struct clk'.
24+
25+menuconfig COMMON_CLK
26+ bool "Common Clock Framework"
27+ depends on !HAVE_LEGACY_CLK
1228 select HAVE_CLK_PREPARE
1329 select CLKDEV_LOOKUP
1430 select SRCU
@@ -20,8 +36,7 @@ config COMMON_CLK · 5 unmodified lines
2036 Architectures utilizing the common struct clk should select
2137 this option.
2238
23−menu "Common Clock Framework"
24− depends on COMMON_CLK
39+if COMMON_CLK
2540
2641 config COMMON_CLK_WM831X
2742 tristate "Clock driver for WM831x/2x PMICs"
@@ -252,7 +267,7 @@ config COMMON_CLK_XGENE · 224 unmodified lines
252267 default ARCH_XGENE
253268 depends on ARM64 || COMPILE_TEST
254269 ---help---
255− Sypport for the APM X-Gene SoC reference, PLL, and device clocks.
270+ Support for the APM X-Gene SoC reference, PLL, and device clocks.
256271
257272 config COMMON_CLK_LOCHNAGAR
258273 tristate "Cirrus Logic Lochnagar clock driver"
@@ -326,6 +341,12 @@ config COMMON_CLK_MMP2 · 67 unmodified lines
326341 help
327342 Support for Marvell MMP2 and MMP3 SoC clocks
328343
344+config COMMON_CLK_MMP2_AUDIO
345+ tristate "Clock driver for MMP2 Audio subsystem"
346+ depends on COMMON_CLK_MMP2 || COMPILE_TEST
347+ help
348+ This driver supports clocks for Audio subsystem on MMP2 SoC.
349+
329350 config COMMON_CLK_BD718XX
330351 tristate "Clock driver for 32K clk gates on ROHM PMICs"
331352 depends on MFD_ROHM_BD718XX || MFD_ROHM_BD70528 || MFD_ROHM_BD71828
@@ -341,6 +362,7 @@ config COMMON_CLK_FIXED_MMIO · 9 unmodified lines
341362
342363 source "drivers/clk/actions/Kconfig"
343364 source "drivers/clk/analogbits/Kconfig"
365+source "drivers/clk/baikal-t1/Kconfig"
344366 source "drivers/clk/bcm/Kconfig"
345367 source "drivers/clk/hisilicon/Kconfig"
346368 source "drivers/clk/imgtec/Kconfig"
@@ -360,6 +382,7 @@ source "drivers/clk/sunxi-ng/Kconfig" · 13 unmodified lines
360382 source "drivers/clk/tegra/Kconfig"
361383 source "drivers/clk/ti/Kconfig"
362384 source "drivers/clk/uniphier/Kconfig"
385+source "drivers/clk/x86/Kconfig"
363386 source "drivers/clk/zynqmp/Kconfig"
364387
365−endmenu
388+endif
drivers/clk/Makefile+3−1
@@ -75,6 +75,7 @@ obj-y += analogbits/ · 74 unmodified lines
7575 obj-$(CONFIG_COMMON_CLK_AT91) += at91/
7676 obj-$(CONFIG_ARCH_ARTPEC) += axis/
7777 obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/
78+obj-$(CONFIG_CLK_BAIKAL_T1) += baikal-t1/
7879 obj-y += bcm/
7980 obj-$(CONFIG_ARCH_BERLIN) += berlin/
8081 obj-$(CONFIG_ARCH_DAVINCI) += davinci/
@@ -104,10 +105,11 @@ obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/ · 23 unmodified lines
104105 obj-$(CONFIG_CLK_SIFIVE) += sifive/
105106 obj-$(CONFIG_ARCH_SIRF) += sirf/
106107 obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
108+obj-$(CONFIG_ARCH_AGILEX) += socfpga/
109+obj-$(CONFIG_ARCH_STRATIX10) += socfpga/
107110 obj-$(CONFIG_PLAT_SPEAR) += spear/
108111 obj-y += sprd/
109112 obj-$(CONFIG_ARCH_STI) += st/
110−obj-$(CONFIG_ARCH_STRATIX10) += socfpga/
111113 obj-$(CONFIG_ARCH_SUNXI) += sunxi/
112114 obj-$(CONFIG_SUNXI_CCU) += sunxi-ng/
113115 obj-$(CONFIG_ARCH_TEGRA) += tegra/
drivers/clk/at91/at91rm9200.c+9−3
@@ -98,9 +98,9 @@ static void __init at91rm9200_pmc_setup(struct device_node *np) · 97 unmodified lines
9898 if (IS_ERR(regmap))
9999 return;
100100
101− at91rm9200_pmc = pmc_data_allocate(PMC_MAIN + 1,
101+ at91rm9200_pmc = pmc_data_allocate(PMC_PLLBCK + 1,
102102 nck(at91rm9200_systemck),
103− nck(at91rm9200_periphck), 0);
103+ nck(at91rm9200_periphck), 0, 4);
104104 if (!at91rm9200_pmc)
105105 return;
106106
@@ -123,12 +123,16 @@ static void __init at91rm9200_pmc_setup(struct device_node *np) · 16 unmodified lines
123123 if (IS_ERR(hw))
124124 goto err_free;
125125
126+ at91rm9200_pmc->chws[PMC_PLLACK] = hw;
127+
126128 hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1,
127129 &at91rm9200_pll_layout,
128130 &rm9200_pll_characteristics);
129131 if (IS_ERR(hw))
130132 goto err_free;
131133
134+ at91rm9200_pmc->chws[PMC_PLLBCK] = hw;
135+
132136 parent_names[0] = slowxtal_name;
133137 parent_names[1] = "mainck";
134138 parent_names[2] = "pllack";
@@ -159,6 +163,8 @@ static void __init at91rm9200_pmc_setup(struct device_node *np) · 24 unmodified lines
159163 &at91rm9200_programmable_layout);
160164 if (IS_ERR(hw))
161165 goto err_free;
166+
167+ at91rm9200_pmc->pchws[i] = hw;
162168 }
163169
164170 for (i = 0; i < ARRAY_SIZE(at91rm9200_systemck); i++) {
@@ -187,7 +193,7 @@ static void __init at91rm9200_pmc_setup(struct device_node *np) · 22 unmodified lines
187193 return;
188194
189195 err_free:
190− pmc_data_free(at91rm9200_pmc);
196+ kfree(at91rm9200_pmc);
191197 }
192198 /*
193199 * While the TCB can be used as the clocksource, the system timer is most likely
drivers/clk/at91/at91sam9260.c+10−3
@@ -352,9 +352,10 @@ static void __init at91sam926x_pmc_setup(struct device_node *np, · 351 unmodified lines
352352 if (IS_ERR(regmap))
353353 return;
354354
355− at91sam9260_pmc = pmc_data_allocate(PMC_MAIN + 1,
355+ at91sam9260_pmc = pmc_data_allocate(PMC_PLLBCK + 1,
356356 ndck(data->sck, data->num_sck),
357− ndck(data->pck, data->num_pck), 0);
357+ ndck(data->pck, data->num_pck),
358+ 0, data->num_progck);
358359 if (!at91sam9260_pmc)
359360 return;
360361
@@ -398,12 +399,16 @@ static void __init at91sam926x_pmc_setup(struct device_node *np, · 37 unmodified lines
398399 if (IS_ERR(hw))
399400 goto err_free;
400401
402+ at91sam9260_pmc->chws[PMC_PLLACK] = hw;
403+
401404 hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1,
402405 data->pllb_layout,
403406 data->pllb_characteristics);
404407 if (IS_ERR(hw))
405408 goto err_free;
406409
410+ at91sam9260_pmc->chws[PMC_PLLBCK] = hw;
411+
407412 parent_names[0] = slck_name;
408413 parent_names[1] = "mainck";
409414 parent_names[2] = "pllack";
@@ -434,6 +439,8 @@ static void __init at91sam926x_pmc_setup(struct device_node *np, · 24 unmodified lines
434439 &at91rm9200_programmable_layout);
435440 if (IS_ERR(hw))
436441 goto err_free;
442+
443+ at91sam9260_pmc->pchws[i] = hw;
437444 }
438445
439446 for (i = 0; i < data->num_sck; i++) {
@@ -462,7 +469,7 @@ static void __init at91sam926x_pmc_setup(struct device_node *np, · 22 unmodified lines
462469 return;
463470
464471 err_free:
465− pmc_data_free(at91sam9260_pmc);
472+ kfree(at91sam9260_pmc);
466473 }
467474
468475 static void __init at91sam9260_pmc_setup(struct device_node *np)
drivers/clk/at91/at91sam9g45.c+7−3
@@ -115,9 +115,9 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np) · 114 unmodified lines
115115 if (IS_ERR(regmap))
116116 return;
117117
118− at91sam9g45_pmc = pmc_data_allocate(PMC_MAIN + 1,
118+ at91sam9g45_pmc = pmc_data_allocate(PMC_PLLACK + 1,
119119 nck(at91sam9g45_systemck),
120− nck(at91sam9g45_periphck), 0);
120+ nck(at91sam9g45_periphck), 0, 2);
121121 if (!at91sam9g45_pmc)
122122 return;
123123
@@ -143,6 +143,8 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np) · 19 unmodified lines
143143 if (IS_ERR(hw))
144144 goto err_free;
145145
146+ at91sam9g45_pmc->chws[PMC_PLLACK] = hw;
147+
146148 hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
147149 if (IS_ERR(hw))
148150 goto err_free;
@@ -182,6 +184,8 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np) · 33 unmodified lines
182184 &at91sam9g45_programmable_layout);
183185 if (IS_ERR(hw))
184186 goto err_free;
187+
188+ at91sam9g45_pmc->pchws[i] = hw;
185189 }
186190
187191 for (i = 0; i < ARRAY_SIZE(at91sam9g45_systemck); i++) {
@@ -210,7 +214,7 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np) · 22 unmodified lines
210214 return;
211215
212216 err_free:
213− pmc_data_free(at91sam9g45_pmc);
217+ kfree(at91sam9g45_pmc);
214218 }
215219 /*
216220 * The TCB is used as the clocksource so its clock is needed early. This means
drivers/clk/at91/at91sam9n12.c+9−3
@@ -128,8 +128,8 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np) · 127 unmodified lines
128128 if (IS_ERR(regmap))
129129 return;
130130
131− at91sam9n12_pmc = pmc_data_allocate(PMC_MAIN + 1,
132− nck(at91sam9n12_systemck), 31, 0);
131+ at91sam9n12_pmc = pmc_data_allocate(PMC_PLLBCK + 1,
132+ nck(at91sam9n12_systemck), 31, 0, 2);
133133 if (!at91sam9n12_pmc)
134134 return;
135135
@@ -162,11 +162,15 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np) · 26 unmodified lines
162162 if (IS_ERR(hw))
163163 goto err_free;
164164
165+ at91sam9n12_pmc->chws[PMC_PLLACK] = hw;
166+
165167 hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1,
166168 &at91rm9200_pll_layout, &pllb_characteristics);
167169 if (IS_ERR(hw))
168170 goto err_free;
169171
172+ at91sam9n12_pmc->chws[PMC_PLLBCK] = hw;
173+
170174 parent_names[0] = slck_name;
171175 parent_names[1] = "mainck";
172176 parent_names[2] = "plladivck";
@@ -198,6 +202,8 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np) · 25 unmodified lines
198202 &at91sam9x5_programmable_layout);
199203 if (IS_ERR(hw))
200204 goto err_free;
205+
206+ at91sam9n12_pmc->pchws[i] = hw;
201207 }
202208
203209 for (i = 0; i < ARRAY_SIZE(at91sam9n12_systemck); i++) {
@@ -228,7 +234,7 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np) · 24 unmodified lines
228234 return;
229235
230236 err_free:
231− pmc_data_free(at91sam9n12_pmc);
237+ kfree(at91sam9n12_pmc);
232238 }
233239 /*
234240 * The TCB is used as the clocksource so its clock is needed early. This means
drivers/clk/at91/at91sam9rl.c+7−3
@@ -87,9 +87,9 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np) · 86 unmodified lines
8787 if (IS_ERR(regmap))
8888 return;
8989
90− at91sam9rl_pmc = pmc_data_allocate(PMC_MAIN + 1,
90+ at91sam9rl_pmc = pmc_data_allocate(PMC_PLLACK + 1,
9191 nck(at91sam9rl_systemck),
92− nck(at91sam9rl_periphck), 0);
92+ nck(at91sam9rl_periphck), 0, 2);
9393 if (!at91sam9rl_pmc)
9494 return;
9595
@@ -105,6 +105,8 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np) · 9 unmodified lines
105105 if (IS_ERR(hw))
106106 goto err_free;
107107
108+ at91sam9rl_pmc->chws[PMC_PLLACK] = hw;
109+
108110 hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
109111 if (IS_ERR(hw))
110112 goto err_free;
@@ -138,6 +140,8 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np) · 27 unmodified lines
138140 &at91rm9200_programmable_layout);
139141 if (IS_ERR(hw))
140142 goto err_free;
143+
144+ at91sam9rl_pmc->pchws[i] = hw;
141145 }
142146
143147 for (i = 0; i < ARRAY_SIZE(at91sam9rl_systemck); i++) {
@@ -166,6 +170,6 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np) · 22 unmodified lines
166170 return;
167171
168172 err_free:
169− pmc_data_free(at91sam9rl_pmc);
173+ kfree(at91sam9rl_pmc);
170174 }
171175 CLK_OF_DECLARE_DRIVER(at91sam9rl_pmc, "atmel,at91sam9rl-pmc", at91sam9rl_pmc_setup);
drivers/clk/at91/at91sam9x5.c+7−3
@@ -150,8 +150,8 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, · 149 unmodified lines
150150 if (IS_ERR(regmap))
151151 return;
152152
153− at91sam9x5_pmc = pmc_data_allocate(PMC_MAIN + 1,
154− nck(at91sam9x5_systemck), 31, 0);
153+ at91sam9x5_pmc = pmc_data_allocate(PMC_PLLACK + 1,
154+ nck(at91sam9x5_systemck), 31, 0, 2);
155155 if (!at91sam9x5_pmc)
156156 return;
157157
@@ -184,6 +184,8 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, · 26 unmodified lines
184184 if (IS_ERR(hw))
185185 goto err_free;
186186
187+ at91sam9x5_pmc->chws[PMC_PLLACK] = hw;
188+
187189 hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
188190 if (IS_ERR(hw))
189191 goto err_free;
@@ -227,6 +229,8 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, · 37 unmodified lines
227229 &at91sam9x5_programmable_layout);
228230 if (IS_ERR(hw))
229231 goto err_free;
232+
233+ at91sam9x5_pmc->pchws[i] = hw;
230234 }
231235
232236 for (i = 0; i < ARRAY_SIZE(at91sam9x5_systemck); i++) {
@@ -278,7 +282,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, · 45 unmodified lines
278282 return;
279283
280284 err_free:
281− pmc_data_free(at91sam9x5_pmc);
285+ kfree(at91sam9x5_pmc);
282286 }
283287
284288 static void __init at91sam9g15_pmc_setup(struct device_node *np)
drivers/clk/at91/pmc.c+20−27
@@ -67,6 +67,10 @@ struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data) · 66 unmodified lines
6767 if (idx < pmc_data->ngck)
6868 return pmc_data->ghws[idx];
6969 break;
70+ case PMC_TYPE_PROGRAMMABLE:
71+ if (idx < pmc_data->npck)
72+ return pmc_data->pchws[idx];
73+ break;
7074 default:
7175 break;
7276 }
@@ -76,48 +80,34 @@ struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data) · 3 unmodified lines
7680 return ERR_PTR(-EINVAL);
7781 }
7882
79−void pmc_data_free(struct pmc_data *pmc_data)
80−{
81− kfree(pmc_data->chws);
82− kfree(pmc_data->shws);
83− kfree(pmc_data->phws);
84− kfree(pmc_data->ghws);
85−}
86−
8783 struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
88− unsigned int nperiph, unsigned int ngck)
84+ unsigned int nperiph, unsigned int ngck,
85+ unsigned int npck)
8986 {
90− struct pmc_data *pmc_data = kzalloc(sizeof(*pmc_data), GFP_KERNEL);
87+ unsigned int num_clks = ncore + nsystem + nperiph + ngck + npck;
88+ struct pmc_data *pmc_data;
9189
90+ pmc_data = kzalloc(struct_size(pmc_data, hwtable, num_clks),
91+ GFP_KERNEL);
9292 if (!pmc_data)
9393 return NULL;
9494
9595 pmc_data->ncore = ncore;
96− pmc_data->chws = kcalloc(ncore, sizeof(struct clk_hw *), GFP_KERNEL);
97− if (!pmc_data->chws)
98− goto err;
96+ pmc_data->chws = pmc_data->hwtable;
9997
10098 pmc_data->nsystem = nsystem;
101− pmc_data->shws = kcalloc(nsystem, sizeof(struct clk_hw *), GFP_KERNEL);
102− if (!pmc_data->shws)
103− goto err;
99+ pmc_data->shws = pmc_data->chws + ncore;
104100
105101 pmc_data->nperiph = nperiph;
106− pmc_data->phws = kcalloc(nperiph, sizeof(struct clk_hw *), GFP_KERNEL);
107− if (!pmc_data->phws)
108− goto err;
102+ pmc_data->phws = pmc_data->shws + nsystem;
109103
110104 pmc_data->ngck = ngck;
111− pmc_data->ghws = kcalloc(ngck, sizeof(struct clk_hw *), GFP_KERNEL);
112− if (!pmc_data->ghws)
113− goto err;
105+ pmc_data->ghws = pmc_data->phws + nperiph;
114106
115− return pmc_data;
116−
117−err:
118− pmc_data_free(pmc_data);
107+ pmc_data->npck = npck;
108+ pmc_data->pchws = pmc_data->ghws + ngck;
119109
120− return NULL;
110+ return pmc_data;
121111 }
122112
123113 #ifdef CONFIG_PM
@@ -274,8 +264,11 @@ static int __init pmc_register_ops(void) · 150 unmodified lines
274264 struct device_node *np;
275265
276266 np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids);
267+ if (!np)
268+ return -ENODEV;
277269
278270 pmcreg = device_node_to_regmap(np);
271+ of_node_put(np);
279272 if (IS_ERR(pmcreg))
280273 return PTR_ERR(pmcreg);
281274
drivers/clk/at91/pmc.h+6−2
@@ -24,6 +24,10 @@ struct pmc_data { · 23 unmodified lines
2424 struct clk_hw **phws;
2525 unsigned int ngck;
2626 struct clk_hw **ghws;
27+ unsigned int npck;
28+ struct clk_hw **pchws;
29+
30+ struct clk_hw *hwtable[];
2731 };
2832
2933 struct clk_range {
@@ -94,8 +98,8 @@ struct clk_pcr_layout { · 64 unmodified lines
9498 #define ndck(a, s) (a[s - 1].id + 1)
9599 #define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)
96100 struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
97− unsigned int nperiph, unsigned int ngck);
98−void pmc_data_free(struct pmc_data *pmc_data);
101+ unsigned int nperiph, unsigned int ngck,
102+ unsigned int npck);
99103
100104 int of_at91_get_clk_range(struct device_node *np, const char *propname,
101105 struct clk_range *range);
drivers/clk/at91/sam9x60.c+7−3
@@ -182,10 +182,10 @@ static void __init sam9x60_pmc_setup(struct device_node *np) · 181 unmodified lines
182182 if (IS_ERR(regmap))
183183 return;
184184
185− sam9x60_pmc = pmc_data_allocate(PMC_MAIN + 1,
185+ sam9x60_pmc = pmc_data_allocate(PMC_PLLACK + 1,
186186 nck(sam9x60_systemck),
187187 nck(sam9x60_periphck),
188− nck(sam9x60_gck));
188+ nck(sam9x60_gck), 8);
189189 if (!sam9x60_pmc)
190190 return;
191191
@@ -214,6 +214,8 @@ static void __init sam9x60_pmc_setup(struct device_node *np) · 22 unmodified lines
214214 if (IS_ERR(hw))
215215 goto err_free;
216216
217+ sam9x60_pmc->chws[PMC_PLLACK] = hw;
218+
217219 hw = sam9x60_clk_register_pll(regmap, &pmc_pll_lock, "upllck",
218220 "main_osc", 1, &upll_characteristics);
219221 if (IS_ERR(hw))
@@ -255,6 +257,8 @@ static void __init sam9x60_pmc_setup(struct device_node *np) · 35 unmodified lines
255257 &sam9x60_programmable_layout);
256258 if (IS_ERR(hw))
257259 goto err_free;
260+
261+ sam9x60_pmc->pchws[i] = hw;
258262 }
259263
260264 for (i = 0; i < ARRAY_SIZE(sam9x60_systemck); i++) {
@@ -299,7 +303,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np) · 38 unmodified lines
299303 return;
300304
301305 err_free:
302− pmc_data_free(sam9x60_pmc);
306+ kfree(sam9x60_pmc);
303307 }
304308 /* Some clks are used for a clocksource */
305309 CLK_OF_DECLARE(sam9x60_pmc, "microchip,sam9x60-pmc", sam9x60_pmc_setup);
drivers/clk/at91/sama5d2.c+10−3
@@ -89,6 +89,7 @@ static const struct { · 88 unmodified lines
8989 { .n = "i2s1_clk", .id = 55, .r = { .min = 0, .max = 83000000 }, },
9090 { .n = "can0_clk", .id = 56, .r = { .min = 0, .max = 83000000 }, },
9191 { .n = "can1_clk", .id = 57, .r = { .min = 0, .max = 83000000 }, },
92+ { .n = "ptc_clk", .id = 58, .r = { .min = 0, .max = 83000000 }, },
9293 { .n = "classd_clk", .id = 59, .r = { .min = 0, .max = 83000000 }, },
9394 };
9495
@@ -166,10 +167,10 @@ static void __init sama5d2_pmc_setup(struct device_node *np) · 71 unmodified lines
166167 if (IS_ERR(regmap))
167168 return;
168169
169− sama5d2_pmc = pmc_data_allocate(PMC_I2S1_MUX + 1,
170+ sama5d2_pmc = pmc_data_allocate(PMC_AUDIOPLLCK + 1,
170171 nck(sama5d2_systemck),
171172 nck(sama5d2_periph32ck),
172− nck(sama5d2_gck));
173+ nck(sama5d2_gck), 3);
173174 if (!sama5d2_pmc)
174175 return;
175176
@@ -202,6 +203,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np) · 26 unmodified lines
202203 if (IS_ERR(hw))
203204 goto err_free;
204205
206+ sama5d2_pmc->chws[PMC_PLLACK] = hw;
207+
205208 hw = at91_clk_register_audio_pll_frac(regmap, "audiopll_fracck",
206209 "mainck");
207210 if (IS_ERR(hw))
@@ -217,6 +220,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np) · 9 unmodified lines
217220 if (IS_ERR(hw))
218221 goto err_free;
219222
223+ sama5d2_pmc->chws[PMC_AUDIOPLLCK] = hw;
224+
220225 regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
221226 if (IS_ERR(regmap_sfr))
222227 regmap_sfr = NULL;
@@ -267,6 +272,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np) · 44 unmodified lines
267272 &sama5d2_programmable_layout);
268273 if (IS_ERR(hw))
269274 goto err_free;
275+
276+ sama5d2_pmc->pchws[i] = hw;
270277 }
271278
272279 for (i = 0; i < ARRAY_SIZE(sama5d2_systemck); i++) {
@@ -350,6 +357,6 @@ static void __init sama5d2_pmc_setup(struct device_node *np) · 77 unmodified lines
350357 return;
351358
352359 err_free:
353− pmc_data_free(sama5d2_pmc);
360+ kfree(sama5d2_pmc);
354361 }
355362 CLK_OF_DECLARE_DRIVER(sama5d2_pmc, "atmel,sama5d2-pmc", sama5d2_pmc_setup);
drivers/clk/at91/sama5d3.c+7−3
@@ -125,9 +125,9 @@ static void __init sama5d3_pmc_setup(struct device_node *np) · 124 unmodified lines
125125 if (IS_ERR(regmap))
126126 return;
127127
128− sama5d3_pmc = pmc_data_allocate(PMC_MAIN + 1,
128+ sama5d3_pmc = pmc_data_allocate(PMC_PLLACK + 1,
129129 nck(sama5d3_systemck),
130− nck(sama5d3_periphck), 0);
130+ nck(sama5d3_periphck), 0, 3);
131131 if (!sama5d3_pmc)
132132 return;
133133
@@ -158,6 +158,8 @@ static void __init sama5d3_pmc_setup(struct device_node *np) · 24 unmodified lines
158158 if (IS_ERR(hw))
159159 goto err_free;
160160
161+ sama5d3_pmc->chws[PMC_PLLACK] = hw;
162+
161163 hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
162164 if (IS_ERR(hw))
163165 goto err_free;
@@ -201,6 +203,8 @@ static void __init sama5d3_pmc_setup(struct device_node *np) · 37 unmodified lines
201203 &at91sam9x5_programmable_layout);
202204 if (IS_ERR(hw))
203205 goto err_free;
206+
207+ sama5d3_pmc->pchws[i] = hw;
204208 }
205209
206210 for (i = 0; i < ARRAY_SIZE(sama5d3_systemck); i++) {
@@ -231,7 +235,7 @@ static void __init sama5d3_pmc_setup(struct device_node *np) · 24 unmodified lines
231235 return;
232236
233237 err_free:
234− pmc_data_free(sama5d3_pmc);
238+ kfree(sama5d3_pmc);
235239 }
236240 /*
237241 * The TCB is used as the clocksource so its clock is needed early. This means
drivers/clk/at91/sama5d4.c+7−3
@@ -140,9 +140,9 @@ static void __init sama5d4_pmc_setup(struct device_node *np) · 139 unmodified lines
140140 if (IS_ERR(regmap))
141141 return;
142142
143− sama5d4_pmc = pmc_data_allocate(PMC_MCK2 + 1,
143+ sama5d4_pmc = pmc_data_allocate(PMC_PLLACK + 1,
144144 nck(sama5d4_systemck),
145− nck(sama5d4_periph32ck), 0);
145+ nck(sama5d4_periph32ck), 0, 3);
146146 if (!sama5d4_pmc)
147147 return;
148148
@@ -173,6 +173,8 @@ static void __init sama5d4_pmc_setup(struct device_node *np) · 24 unmodified lines
173173 if (IS_ERR(hw))
174174 goto err_free;
175175
176+ sama5d4_pmc->chws[PMC_PLLACK] = hw;
177+
176178 hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
177179 if (IS_ERR(hw))
178180 goto err_free;
@@ -224,6 +226,8 @@ static void __init sama5d4_pmc_setup(struct device_node *np) · 45 unmodified lines
224226 &at91sam9x5_programmable_layout);
225227 if (IS_ERR(hw))
226228 goto err_free;
229+
230+ sama5d4_pmc->pchws[i] = hw;
227231 }
228232
229233 for (i = 0; i < ARRAY_SIZE(sama5d4_systemck); i++) {
@@ -267,6 +271,6 @@ static void __init sama5d4_pmc_setup(struct device_node *np) · 37 unmodified lines
267271 return;
268272
269273 err_free:
270− pmc_data_free(sama5d4_pmc);
274+ kfree(sama5d4_pmc);
271275 }
272276 CLK_OF_DECLARE_DRIVER(sama5d4_pmc, "atmel,sama5d4-pmc", sama5d4_pmc_setup);
drivers/clk/baikal-t1/Kconfig+42−0
@@ -0,0 +1,42 @@
1+# SPDX-License-Identifier: GPL-2.0-only
2+config CLK_BAIKAL_T1
3+ bool "Baikal-T1 Clocks Control Unit interface"
4+ depends on (MIPS_BAIKAL_T1 && OF) || COMPILE_TEST
5+ default MIPS_BAIKAL_T1
6+ help
7+ Clocks Control Unit is the core of Baikal-T1 SoC System Controller
8+ responsible for the chip subsystems clocking and resetting. It
9+ consists of multiple global clock domains, which can be reset by
10+ means of the CCU control registers. These domains and devices placed
11+ in them are fed with clocks generated by a hierarchy of PLLs,
12+ configurable and fixed clock dividers. Enable this option to be able
13+ to select Baikal-T1 CCU PLLs and Dividers drivers.
14+
15+if CLK_BAIKAL_T1
16+
17+config CLK_BT1_CCU_PLL
18+ bool "Baikal-T1 CCU PLLs support"
19+ select MFD_SYSCON
20+ default MIPS_BAIKAL_T1
21+ help
22+ Enable this to support the PLLs embedded into the Baikal-T1 SoC
23+ System Controller. These are five PLLs placed at the root of the
24+ clocks hierarchy, right after an external reference oscillator
25+ (normally of 25MHz). They are used to generate high frequency
26+ signals, which are either directly wired to the consumers (like
27+ CPUs, DDR, etc.) or passed over the clock dividers to be only
28+ then used as an individual reference clock of a target device.
29+
30+config CLK_BT1_CCU_DIV
31+ bool "Baikal-T1 CCU Dividers support"
32+ select RESET_CONTROLLER
33+ select MFD_SYSCON
34+ default MIPS_BAIKAL_T1
35+ help
36+ Enable this to support the CCU dividers used to distribute clocks
37+ between AXI-bus and system devices coming from CCU PLLs of Baikal-T1
38+ SoC. CCU dividers can be either configurable or with fixed divider,
39+ either gateable or ungateable. Some of the CCU dividers can be as well
40+ used to reset the domains they're supplying clock to.
41+
42+endif
drivers/clk/baikal-t1/Makefile+3−0
@@ -0,0 +1,3 @@
1+# SPDX-License-Identifier: GPL-2.0-only
2+obj-$(CONFIG_CLK_BT1_CCU_PLL) += ccu-pll.o clk-ccu-pll.o
3+obj-$(CONFIG_CLK_BT1_CCU_DIV) += ccu-div.o clk-ccu-div.o
drivers/clk/baikal-t1/ccu-div.c+602−0
@@ -0,0 +1,602 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+/*
3+ * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
4+ *
5+ * Authors:
6+ * Serge Semin <Sergey.Semin@baikalelectronics.ru>
7+ * Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
8+ *
9+ * Baikal-T1 CCU Dividers interface driver
10+ */
11+
12+#define pr_fmt(fmt) "bt1-ccu-div: " fmt
13+
14+#include <linux/kernel.h>
15+#include <linux/printk.h>
16+#include <linux/bits.h>
17+#include <linux/bitfield.h>
18+#include <linux/slab.h>
19+#include <linux/clk-provider.h>
20+#include <linux/of.h>
21+#include <linux/spinlock.h>
22+#include <linux/regmap.h>
23+#include <linux/delay.h>
24+#include <linux/time64.h>
25+#include <linux/debugfs.h>
26+
27+#include "ccu-div.h"
28+
29+#define CCU_DIV_CTL 0x00
30+#define CCU_DIV_CTL_EN BIT(0)
31+#define CCU_DIV_CTL_RST BIT(1)
32+#define CCU_DIV_CTL_SET_CLKDIV BIT(2)
33+#define CCU_DIV_CTL_CLKDIV_FLD 4
34+#define CCU_DIV_CTL_CLKDIV_MASK(_width) \
35+ GENMASK((_width) + CCU_DIV_CTL_CLKDIV_FLD - 1, CCU_DIV_CTL_CLKDIV_FLD)
36+#define CCU_DIV_CTL_LOCK_SHIFTED BIT(27)
37+#define CCU_DIV_CTL_LOCK_NORMAL BIT(31)
38+
39+#define CCU_DIV_RST_DELAY_US 1
40+#define CCU_DIV_LOCK_CHECK_RETRIES 50
41+
42+#define CCU_DIV_CLKDIV_MIN 0
43+#define CCU_DIV_CLKDIV_MAX(_mask) \
44+ ((_mask) >> CCU_DIV_CTL_CLKDIV_FLD)
45+
46+/*
47+ * Use the next two methods until there are generic field setter and
48+ * getter available with non-constant mask support.
49+ */
50+static inline u32 ccu_div_get(u32 mask, u32 val)
51+{
52+ return (val & mask) >> CCU_DIV_CTL_CLKDIV_FLD;
53+}
54+
55+static inline u32 ccu_div_prep(u32 mask, u32 val)
56+{
57+ return (val << CCU_DIV_CTL_CLKDIV_FLD) & mask;
58+}
59+
60+static inline unsigned long ccu_div_lock_delay_ns(unsigned long ref_clk,
61+ unsigned long div)
62+{
63+ u64 ns = 4ULL * (div ?: 1) * NSEC_PER_SEC;
64+
65+ do_div(ns, ref_clk);
66+
67+ return ns;
68+}
69+
70+static inline unsigned long ccu_div_calc_freq(unsigned long ref_clk,
71+ unsigned long div)
72+{
73+ return ref_clk / (div ?: 1);
74+}
75+
76+static int ccu_div_var_update_clkdiv(struct ccu_div *div,
77+ unsigned long parent_rate,
78+ unsigned long divider)
79+{
80+ unsigned long nd;
81+ u32 val = 0;
82+ u32 lock;
83+ int count;
84+
85+ nd = ccu_div_lock_delay_ns(parent_rate, divider);
86+
87+ if (div->features & CCU_DIV_LOCK_SHIFTED)
88+ lock = CCU_DIV_CTL_LOCK_SHIFTED;
89+ else
90+ lock = CCU_DIV_CTL_LOCK_NORMAL;
91+
92+ regmap_update_bits(div->sys_regs, div->reg_ctl,
93+ CCU_DIV_CTL_SET_CLKDIV, CCU_DIV_CTL_SET_CLKDIV);
94+
95+ /*
96+ * Until there is nsec-version of readl_poll_timeout() is available
97+ * we have to implement the next polling loop.
98+ */
99+ count = CCU_DIV_LOCK_CHECK_RETRIES;
100+ do {
101+ ndelay(nd);
102+ regmap_read(div->sys_regs, div->reg_ctl, &val);
103+ if (val & lock)
104+ return 0;
105+ } while (--count);
106+
107+ return -ETIMEDOUT;
108+}
109+
110+static int ccu_div_var_enable(struct clk_hw *hw)
111+{
112+ struct clk_hw *parent_hw = clk_hw_get_parent(hw);
113+ struct ccu_div *div = to_ccu_div(hw);
114+ unsigned long flags;
115+ u32 val = 0;
116+ int ret;
117+
118+ if (!parent_hw) {
119+ pr_err("Can't enable '%s' with no parent", clk_hw_get_name(hw));
120+ return -EINVAL;
121+ }
122+
123+ regmap_read(div->sys_regs, div->reg_ctl, &val);
124+ if (val & CCU_DIV_CTL_EN)
125+ return 0;
126+
127+ spin_lock_irqsave(&div->lock, flags);
128+ ret = ccu_div_var_update_clkdiv(div, clk_hw_get_rate(parent_hw),
129+ ccu_div_get(div->mask, val));
130+ if (!ret)
131+ regmap_update_bits(div->sys_regs, div->reg_ctl,
132+ CCU_DIV_CTL_EN, CCU_DIV_CTL_EN);
133+ spin_unlock_irqrestore(&div->lock, flags);
134+ if (ret)
135+ pr_err("Divider '%s' lock timed out\n", clk_hw_get_name(hw));
136+
137+ return ret;
138+}
139+
140+static int ccu_div_gate_enable(struct clk_hw *hw)
141+{
142+ struct ccu_div *div = to_ccu_div(hw);
143+ unsigned long flags;
144+
145+ spin_lock_irqsave(&div->lock, flags);
146+ regmap_update_bits(div->sys_regs, div->reg_ctl,
147+ CCU_DIV_CTL_EN, CCU_DIV_CTL_EN);
148+ spin_unlock_irqrestore(&div->lock, flags);
149+
150+ return 0;
151+}
152+
153+static void ccu_div_gate_disable(struct clk_hw *hw)
154+{
155+ struct ccu_div *div = to_ccu_div(hw);
156+ unsigned long flags;
157+
158+ spin_lock_irqsave(&div->lock, flags);
159+ regmap_update_bits(div->sys_regs, div->reg_ctl, CCU_DIV_CTL_EN, 0);
160+ spin_unlock_irqrestore(&div->lock, flags);
161+}
162+
163+static int ccu_div_gate_is_enabled(struct clk_hw *hw)
164+{
165+ struct ccu_div *div = to_ccu_div(hw);
166+ u32 val = 0;
167+
168+ regmap_read(div->sys_regs, div->reg_ctl, &val);
169+
170+ return !!(val & CCU_DIV_CTL_EN);
171+}
172+
173+static unsigned long ccu_div_var_recalc_rate(struct clk_hw *hw,
174+ unsigned long parent_rate)
175+{
176+ struct ccu_div *div = to_ccu_div(hw);
177+ unsigned long divider;
178+ u32 val = 0;
179+
180+ regmap_read(div->sys_regs, div->reg_ctl, &val);
181+ divider = ccu_div_get(div->mask, val);
182+
183+ return ccu_div_calc_freq(parent_rate, divider);
184+}
185+
186+static inline unsigned long ccu_div_var_calc_divider(unsigned long rate,
187+ unsigned long parent_rate,
188+ unsigned int mask)
189+{
190+ unsigned long divider;
191+
192+ divider = parent_rate / rate;
193+ return clamp_t(unsigned long, divider, CCU_DIV_CLKDIV_MIN,
194+ CCU_DIV_CLKDIV_MAX(mask));
195+}
196+
197+static long ccu_div_var_round_rate(struct clk_hw *hw, unsigned long rate,
198+ unsigned long *parent_rate)
199+{
200+ struct ccu_div *div = to_ccu_div(hw);
201+ unsigned long divider;
202+
203+ divider = ccu_div_var_calc_divider(rate, *parent_rate, div->mask);
204+
205+ return ccu_div_calc_freq(*parent_rate, divider);
206+}
207+
208+/*
209+ * This method is used for the clock divider blocks, which support the
210+ * on-the-fly rate change. So due to lacking the EN bit functionality
211+ * they can't be gated before the rate adjustment.
212+ */
213+static int ccu_div_var_set_rate_slow(struct clk_hw *hw, unsigned long rate,
214+ unsigned long parent_rate)
215+{
216+ struct ccu_div *div = to_ccu_div(hw);
217+ unsigned long flags, divider;
218+ u32 val;
219+ int ret;
220+
221+ divider = ccu_div_var_calc_divider(rate, parent_rate, div->mask);
222+ if (divider == 1 && div->features & CCU_DIV_SKIP_ONE) {
223+ divider = 0;
224+ } else if (div->features & CCU_DIV_SKIP_ONE_TO_THREE) {
225+ if (divider == 1 || divider == 2)
226+ divider = 0;
227+ else if (divider == 3)
228+ divider = 4;
229+ }
230+
231+ val = ccu_div_prep(div->mask, divider);
232+
233+ spin_lock_irqsave(&div->lock, flags);
234+ regmap_update_bits(div->sys_regs, div->reg_ctl, div->mask, val);
235+ ret = ccu_div_var_update_clkdiv(div, parent_rate, divider);
236+ spin_unlock_irqrestore(&div->lock, flags);
237+ if (ret)
238+ pr_err("Divider '%s' lock timed out\n", clk_hw_get_name(hw));
239+
240+ return ret;
241+}
242+
243+/*
244+ * This method is used for the clock divider blocks, which don't support
245+ * the on-the-fly rate change.
246+ */
247+static int ccu_div_var_set_rate_fast(struct clk_hw *hw, unsigned long rate,
248+ unsigned long parent_rate)
249+{
250+ struct ccu_div *div = to_ccu_div(hw);
251+ unsigned long flags, divider;
252+ u32 val;
253+
254+ divider = ccu_div_var_calc_divider(rate, parent_rate, div->mask);
255+ val = ccu_div_prep(div->mask, divider);
256+
257+ /*
258+ * Also disable the clock divider block if it was enabled by default
259+ * or by the bootloader.
260+ */
261+ spin_lock_irqsave(&div->lock, flags);
262+ regmap_update_bits(div->sys_regs, div->reg_ctl,
263+ div->mask | CCU_DIV_CTL_EN, val);
264+ spin_unlock_irqrestore(&div->lock, flags);
265+
266+ return 0;
267+}
268+
269+static unsigned long ccu_div_fixed_recalc_rate(struct clk_hw *hw,
270+ unsigned long parent_rate)
271+{
272+ struct ccu_div *div = to_ccu_div(hw);
273+
274+ return ccu_div_calc_freq(parent_rate, div->divider);
275+}
276+
277+static long ccu_div_fixed_round_rate(struct clk_hw *hw, unsigned long rate,
278+ unsigned long *parent_rate)
279+{
280+ struct ccu_div *div = to_ccu_div(hw);
281+
282+ return ccu_div_calc_freq(*parent_rate, div->divider);
283+}
284+
285+static int ccu_div_fixed_set_rate(struct clk_hw *hw, unsigned long rate,
286+ unsigned long parent_rate)
287+{
288+ return 0;
289+}
290+
291+int ccu_div_reset_domain(struct ccu_div *div)
292+{
293+ unsigned long flags;
294+
295+ if (!div || !(div->features & CCU_DIV_RESET_DOMAIN))
296+ return -EINVAL;
297+
298+ spin_lock_irqsave(&div->lock, flags);
299+ regmap_update_bits(div->sys_regs, div->reg_ctl,
300+ CCU_DIV_CTL_RST, CCU_DIV_CTL_RST);
301+ spin_unlock_irqrestore(&div->lock, flags);
302+
303+ /* The next delay must be enough to cover all the resets. */
304+ udelay(CCU_DIV_RST_DELAY_US);
305+
306+ return 0;
307+}
308+
309+#ifdef CONFIG_DEBUG_FS
310+
311+struct ccu_div_dbgfs_bit {
312+ struct ccu_div *div;
313+ const char *name;
314+ u32 mask;
315+};
316+
317+#define CCU_DIV_DBGFS_BIT_ATTR(_name, _mask) { \
318+ .name = _name, \
319+ .mask = _mask \
320+ }
321+
322+static const struct ccu_div_dbgfs_bit ccu_div_bits[] = {
323+ CCU_DIV_DBGFS_BIT_ATTR("div_en", CCU_DIV_CTL_EN),
324+ CCU_DIV_DBGFS_BIT_ATTR("div_rst", CCU_DIV_CTL_RST),
325+ CCU_DIV_DBGFS_BIT_ATTR("div_bypass", CCU_DIV_CTL_SET_CLKDIV),
326+ CCU_DIV_DBGFS_BIT_ATTR("div_lock", CCU_DIV_CTL_LOCK_NORMAL)
327+};
328+
329+#define CCU_DIV_DBGFS_BIT_NUM ARRAY_SIZE(ccu_div_bits)
330+
331+/*
332+ * It can be dangerous to change the Divider settings behind clock framework
333+ * back, therefore we don't provide any kernel config based compile time option
334+ * for this feature to enable.
335+ */
336+#undef CCU_DIV_ALLOW_WRITE_DEBUGFS
337+#ifdef CCU_DIV_ALLOW_WRITE_DEBUGFS
338+
339+static int ccu_div_dbgfs_bit_set(void *priv, u64 val)
340+{
341+ const struct ccu_div_dbgfs_bit *bit = priv;
342+ struct ccu_div *div = bit->div;
343+ unsigned long flags;
344+
345+ spin_lock_irqsave(&div->lock, flags);
346+ regmap_update_bits(div->sys_regs, div->reg_ctl,
347+ bit->mask, val ? bit->mask : 0);
348+ spin_unlock_irqrestore(&div->lock, flags);
349+
350+ return 0;
351+}
352+
353+static int ccu_div_dbgfs_var_clkdiv_set(void *priv, u64 val)
354+{
355+ struct ccu_div *div = priv;
356+ unsigned long flags;
357+ u32 data;
358+
359+ val = clamp_t(u64, val, CCU_DIV_CLKDIV_MIN,
360+ CCU_DIV_CLKDIV_MAX(div->mask));
361+ data = ccu_div_prep(div->mask, val);
362+
363+ spin_lock_irqsave(&div->lock, flags);
364+ regmap_update_bits(div->sys_regs, div->reg_ctl, div->mask, data);
365+ spin_unlock_irqrestore(&div->lock, flags);
366+
367+ return 0;
368+}
369+
370+#define ccu_div_dbgfs_mode 0644
371+
372+#else /* !CCU_DIV_ALLOW_WRITE_DEBUGFS */
373+
374+#define ccu_div_dbgfs_bit_set NULL
375+#define ccu_div_dbgfs_var_clkdiv_set NULL
376+#define ccu_div_dbgfs_mode 0444
377+
378+#endif /* !CCU_DIV_ALLOW_WRITE_DEBUGFS */
379+
380+static int ccu_div_dbgfs_bit_get(void *priv, u64 *val)
381+{
382+ const struct ccu_div_dbgfs_bit *bit = priv;
383+ struct ccu_div *div = bit->div;
384+ u32 data = 0;
385+
386+ regmap_read(div->sys_regs, div->reg_ctl, &data);
387+ *val = !!(data & bit->mask);
388+
389+ return 0;
390+}
391+DEFINE_DEBUGFS_ATTRIBUTE(ccu_div_dbgfs_bit_fops,
392+ ccu_div_dbgfs_bit_get, ccu_div_dbgfs_bit_set, "%llu\n");
393+
394+static int ccu_div_dbgfs_var_clkdiv_get(void *priv, u64 *val)
395+{
396+ struct ccu_div *div = priv;
397+ u32 data = 0;
398+
399+ regmap_read(div->sys_regs, div->reg_ctl, &data);
400+ *val = ccu_div_get(div->mask, data);
401+
402+ return 0;
403+}
404+DEFINE_DEBUGFS_ATTRIBUTE(ccu_div_dbgfs_var_clkdiv_fops,
405+ ccu_div_dbgfs_var_clkdiv_get, ccu_div_dbgfs_var_clkdiv_set, "%llu\n");
406+
407+static int ccu_div_dbgfs_fixed_clkdiv_get(void *priv, u64 *val)
408+{
409+ struct ccu_div *div = priv;
410+
411+ *val = div->divider;
412+
413+ return 0;
414+}
415+DEFINE_DEBUGFS_ATTRIBUTE(ccu_div_dbgfs_fixed_clkdiv_fops,
416+ ccu_div_dbgfs_fixed_clkdiv_get, NULL, "%llu\n");
417+
418+static void ccu_div_var_debug_init(struct clk_hw *hw, struct dentry *dentry)
419+{
420+ struct ccu_div *div = to_ccu_div(hw);
421+ struct ccu_div_dbgfs_bit *bits;
422+ int didx, bidx, num = 2;
423+ const char *name;
424+
425+ num += !!(div->flags & CLK_SET_RATE_GATE) +
426+ !!(div->features & CCU_DIV_RESET_DOMAIN);
427+
428+ bits = kcalloc(num, sizeof(*bits), GFP_KERNEL);
429+ if (!bits)
430+ return;
431+
432+ for (didx = 0, bidx = 0; bidx < CCU_DIV_DBGFS_BIT_NUM; ++bidx) {
433+ name = ccu_div_bits[bidx].name;
434+ if (!(div->flags & CLK_SET_RATE_GATE) &&
435+ !strcmp("div_en", name)) {
436+ continue;
437+ }
438+
439+ if (!(div->features & CCU_DIV_RESET_DOMAIN) &&
440+ !strcmp("div_rst", name)) {
441+ continue;
442+ }
443+
444+ bits[didx] = ccu_div_bits[bidx];
445+ bits[didx].div = div;
446+
447+ if (div->features & CCU_DIV_LOCK_SHIFTED &&
448+ !strcmp("div_lock", name)) {
449+ bits[didx].mask = CCU_DIV_CTL_LOCK_SHIFTED;
450+ }
451+
452+ debugfs_create_file_unsafe(bits[didx].name, ccu_div_dbgfs_mode,
453+ dentry, &bits[didx],
454+ &ccu_div_dbgfs_bit_fops);
455+ ++didx;
456+ }
457+
458+ debugfs_create_file_unsafe("div_clkdiv", ccu_div_dbgfs_mode, dentry,
459+ div, &ccu_div_dbgfs_var_clkdiv_fops);
460+}
461+
462+static void ccu_div_gate_debug_init(struct clk_hw *hw, struct dentry *dentry)
463+{
464+ struct ccu_div *div = to_ccu_div(hw);
465+ struct ccu_div_dbgfs_bit *bit;
466+
467+ bit = kmalloc(sizeof(*bit), GFP_KERNEL);
468+ if (!bit)
469+ return;
470+
471+ *bit = ccu_div_bits[0];
472+ bit->div = div;
473+ debugfs_create_file_unsafe(bit->name, ccu_div_dbgfs_mode, dentry, bit,
474+ &ccu_div_dbgfs_bit_fops);
475+
476+ debugfs_create_file_unsafe("div_clkdiv", 0400, dentry, div,
477+ &ccu_div_dbgfs_fixed_clkdiv_fops);
478+}
479+
480+static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry)
481+{
482+ struct ccu_div *div = to_ccu_div(hw);
483+
484+ debugfs_create_file_unsafe("div_clkdiv", 0400, dentry, div,
485+ &ccu_div_dbgfs_fixed_clkdiv_fops);
486+}
487+
488+#else /* !CONFIG_DEBUG_FS */
489+
490+#define ccu_div_var_debug_init NULL
491+#define ccu_div_gate_debug_init NULL
492+#define ccu_div_fixed_debug_init NULL
493+
494+#endif /* !CONFIG_DEBUG_FS */
495+
496+static const struct clk_ops ccu_div_var_gate_to_set_ops = {
497+ .enable = ccu_div_var_enable,
498+ .disable = ccu_div_gate_disable,
499+ .is_enabled = ccu_div_gate_is_enabled,
500+ .recalc_rate = ccu_div_var_recalc_rate,
501+ .round_rate = ccu_div_var_round_rate,
502+ .set_rate = ccu_div_var_set_rate_fast,
503+ .debug_init = ccu_div_var_debug_init
504+};
505+
506+static const struct clk_ops ccu_div_var_nogate_ops = {
507+ .recalc_rate = ccu_div_var_recalc_rate,
508+ .round_rate = ccu_div_var_round_rate,
509+ .set_rate = ccu_div_var_set_rate_slow,
510+ .debug_init = ccu_div_var_debug_init
511+};
512+
513+static const struct clk_ops ccu_div_gate_ops = {
514+ .enable = ccu_div_gate_enable,
515+ .disable = ccu_div_gate_disable,
516+ .is_enabled = ccu_div_gate_is_enabled,
517+ .recalc_rate = ccu_div_fixed_recalc_rate,
518+ .round_rate = ccu_div_fixed_round_rate,
519+ .set_rate = ccu_div_fixed_set_rate,
520+ .debug_init = ccu_div_gate_debug_init
521+};
522+
523+static const struct clk_ops ccu_div_fixed_ops = {
524+ .recalc_rate = ccu_div_fixed_recalc_rate,
525+ .round_rate = ccu_div_fixed_round_rate,
526+ .set_rate = ccu_div_fixed_set_rate,
527+ .debug_init = ccu_div_fixed_debug_init
528+};
529+
530+struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init)
531+{
532+ struct clk_parent_data parent_data = { };
533+ struct clk_init_data hw_init = { };
534+ struct ccu_div *div;
535+ int ret;
536+
537+ if (!div_init)
538+ return ERR_PTR(-EINVAL);
539+
540+ div = kzalloc(sizeof(*div), GFP_KERNEL);
541+ if (!div)
542+ return ERR_PTR(-ENOMEM);
543+
544+ /*
545+ * Note since Baikal-T1 System Controller registers are MMIO-backed
546+ * we won't check the regmap IO operations return status, because it
547+ * must be zero anyway.
548+ */
549+ div->hw.init = &hw_init;
550+ div->id = div_init->id;
551+ div->reg_ctl = div_init->base + CCU_DIV_CTL;
552+ div->sys_regs = div_init->sys_regs;
553+ div->flags = div_init->flags;
554+ div->features = div_init->features;
555+ spin_lock_init(&div->lock);
556+
557+ hw_init.name = div_init->name;
558+ hw_init.flags = div_init->flags;
559+
560+ if (div_init->type == CCU_DIV_VAR) {
561+ if (hw_init.flags & CLK_SET_RATE_GATE)
562+ hw_init.ops = &ccu_div_var_gate_to_set_ops;
563+ else
564+ hw_init.ops = &ccu_div_var_nogate_ops;
565+ div->mask = CCU_DIV_CTL_CLKDIV_MASK(div_init->width);
566+ } else if (div_init->type == CCU_DIV_GATE) {
567+ hw_init.ops = &ccu_div_gate_ops;
568+ div->divider = div_init->divider;
569+ } else if (div_init->type == CCU_DIV_FIXED) {
570+ hw_init.ops = &ccu_div_fixed_ops;
571+ div->divider = div_init->divider;
572+ } else {
573+ ret = -EINVAL;
574+ goto err_free_div;
575+ }
576+
577+ if (!div_init->parent_name) {
578+ ret = -EINVAL;
579+ goto err_free_div;
580+ }
581+ parent_data.fw_name = div_init->parent_name;
582+ hw_init.parent_data = &parent_data;
583+ hw_init.num_parents = 1;
584+
585+ ret = of_clk_hw_register(div_init->np, &div->hw);
586+ if (ret)
587+ goto err_free_div;
588+
589+ return div;
590+
591+err_free_div:
592+ kfree(div);
593+
594+ return ERR_PTR(ret);
595+}
596+
597+void ccu_div_hw_unregister(struct ccu_div *div)
598+{
599+ clk_hw_unregister(&div->hw);
600+
601+ kfree(div);
602+}
drivers/clk/baikal-t1/ccu-div.h+110−0
@@ -0,0 +1,110 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
4+ *
5+ * Baikal-T1 CCU Dividers interface driver
6+ */
7+#ifndef __CLK_BT1_CCU_DIV_H__
8+#define __CLK_BT1_CCU_DIV_H__
9+
10+#include <linux/clk-provider.h>
11+#include <linux/spinlock.h>
12+#include <linux/regmap.h>
13+#include <linux/bits.h>
14+#include <linux/of.h>
15+
16+/*
17+ * CCU Divider private flags
18+ * @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1.
19+ * It can be 0 though, which is functionally the same.
20+ * @CCU_DIV_SKIP_ONE_TO_THREE: For some reason divider can't be within [1,3].
21+ * It can be either 0 or greater than 3.
22+ * @CCU_DIV_LOCK_SHIFTED: Find lock-bit at non-standard position.
23+ * @CCU_DIV_RESET_DOMAIN: Provide reset clock domain method.
24+ */
25+#define CCU_DIV_SKIP_ONE BIT(1)
26+#define CCU_DIV_SKIP_ONE_TO_THREE BIT(2)
27+#define CCU_DIV_LOCK_SHIFTED BIT(3)
28+#define CCU_DIV_RESET_DOMAIN BIT(4)
29+
30+/*
31+ * enum ccu_div_type - CCU Divider types
32+ * @CCU_DIV_VAR: Clocks gate with variable divider.
33+ * @CCU_DIV_GATE: Clocks gate with fixed divider.
34+ * @CCU_DIV_FIXED: Ungateable clock with fixed divider.
35+ */
36+enum ccu_div_type {
37+ CCU_DIV_VAR,
38+ CCU_DIV_GATE,
39+ CCU_DIV_FIXED
40+};
41+
42+/*
43+ * struct ccu_div_init_data - CCU Divider initialization data
44+ * @id: Clocks private identifier.
45+ * @name: Clocks name.
46+ * @parent_name: Parent clocks name in a fw node.
47+ * @base: Divider register base address with respect to the sys_regs base.
48+ * @sys_regs: Baikal-T1 System Controller registers map.
49+ * @np: Pointer to the node describing the CCU Dividers.
50+ * @type: CCU divider type (variable, fixed with and without gate).
51+ * @width: Divider width if it's variable.
52+ * @divider: Divider fixed value.
53+ * @flags: CCU Divider clock flags.
54+ * @features: CCU Divider private features.
55+ */
56+struct ccu_div_init_data {
57+ unsigned int id;
58+ const char *name;
59+ const char *parent_name;
60+ unsigned int base;
61+ struct regmap *sys_regs;
62+ struct device_node *np;
63+ enum ccu_div_type type;
64+ union {
65+ unsigned int width;
66+ unsigned int divider;
67+ };
68+ unsigned long flags;
69+ unsigned long features;
70+};
71+
72+/*
73+ * struct ccu_div - CCU Divider descriptor
74+ * @hw: clk_hw of the divider.
75+ * @id: Clock private identifier.
76+ * @reg_ctl: Divider control register base address.
77+ * @sys_regs: Baikal-T1 System Controller registers map.
78+ * @lock: Divider state change spin-lock.
79+ * @mask: Divider field mask.
80+ * @divider: Divider fixed value.
81+ * @flags: Divider clock flags.
82+ * @features: CCU Divider private features.
83+ */
84+struct ccu_div {
85+ struct clk_hw hw;
86+ unsigned int id;
87+ unsigned int reg_ctl;
88+ struct regmap *sys_regs;
89+ spinlock_t lock;
90+ union {
91+ u32 mask;
92+ unsigned int divider;
93+ };
94+ unsigned long flags;
95+ unsigned long features;
96+};
97+#define to_ccu_div(_hw) container_of(_hw, struct ccu_div, hw)
98+
99+static inline struct clk_hw *ccu_div_get_clk_hw(struct ccu_div *div)
100+{
101+ return div ? &div->hw : NULL;
102+}
103+
104+struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *init);
105+
106+void ccu_div_hw_unregister(struct ccu_div *div);
107+
108+int ccu_div_reset_domain(struct ccu_div *div);
109+
110+#endif /* __CLK_BT1_CCU_DIV_H__ */
drivers/clk/baikal-t1/ccu-pll.c+558−0
@@ -0,0 +1,558 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+/*
3+ * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
4+ *
5+ * Authors:
6+ * Serge Semin <Sergey.Semin@baikalelectronics.ru>
7+ * Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
8+ *
9+ * Baikal-T1 CCU PLL interface driver
10+ */
11+
12+#define pr_fmt(fmt) "bt1-ccu-pll: " fmt
13+
14+#include <linux/kernel.h>
15+#include <linux/printk.h>
16+#include <linux/limits.h>
17+#include <linux/bits.h>
18+#include <linux/bitfield.h>
19+#include <linux/slab.h>
20+#include <linux/clk-provider.h>
21+#include <linux/of.h>
22+#include <linux/spinlock.h>
23+#include <linux/regmap.h>
24+#include <linux/iopoll.h>
25+#include <linux/time64.h>
26+#include <linux/rational.h>
27+#include <linux/debugfs.h>
28+
29+#include "ccu-pll.h"
30+
31+#define CCU_PLL_CTL 0x000
32+#define CCU_PLL_CTL_EN BIT(0)
33+#define CCU_PLL_CTL_RST BIT(1)
34+#define CCU_PLL_CTL_CLKR_FLD 2
35+#define CCU_PLL_CTL_CLKR_MASK GENMASK(7, CCU_PLL_CTL_CLKR_FLD)
36+#define CCU_PLL_CTL_CLKF_FLD 8
37+#define CCU_PLL_CTL_CLKF_MASK GENMASK(20, CCU_PLL_CTL_CLKF_FLD)
38+#define CCU_PLL_CTL_CLKOD_FLD 21
39+#define CCU_PLL_CTL_CLKOD_MASK GENMASK(24, CCU_PLL_CTL_CLKOD_FLD)
40+#define CCU_PLL_CTL_BYPASS BIT(30)
41+#define CCU_PLL_CTL_LOCK BIT(31)
42+#define CCU_PLL_CTL1 0x004
43+#define CCU_PLL_CTL1_BWADJ_FLD 3
44+#define CCU_PLL_CTL1_BWADJ_MASK GENMASK(14, CCU_PLL_CTL1_BWADJ_FLD)
45+
46+#define CCU_PLL_LOCK_CHECK_RETRIES 50
47+
48+#define CCU_PLL_NR_MAX \
49+ ((CCU_PLL_CTL_CLKR_MASK >> CCU_PLL_CTL_CLKR_FLD) + 1)
50+#define CCU_PLL_NF_MAX \
51+ ((CCU_PLL_CTL_CLKF_MASK >> (CCU_PLL_CTL_CLKF_FLD + 1)) + 1)
52+#define CCU_PLL_OD_MAX \
53+ ((CCU_PLL_CTL_CLKOD_MASK >> CCU_PLL_CTL_CLKOD_FLD) + 1)
54+#define CCU_PLL_NB_MAX \
55+ ((CCU_PLL_CTL1_BWADJ_MASK >> CCU_PLL_CTL1_BWADJ_FLD) + 1)
56+#define CCU_PLL_FDIV_MIN 427000UL
57+#define CCU_PLL_FDIV_MAX 3500000000UL
58+#define CCU_PLL_FOUT_MIN 200000000UL
59+#define CCU_PLL_FOUT_MAX 2500000000UL
60+#define CCU_PLL_FVCO_MIN 700000000UL
61+#define CCU_PLL_FVCO_MAX 3500000000UL
62+#define CCU_PLL_CLKOD_FACTOR 2
63+
64+static inline unsigned long ccu_pll_lock_delay_us(unsigned long ref_clk,
65+ unsigned long nr)
66+{
67+ u64 us = 500ULL * nr * USEC_PER_SEC;
68+
69+ do_div(us, ref_clk);
70+
71+ return us;
72+}
73+
74+static inline unsigned long ccu_pll_calc_freq(unsigned long ref_clk,
75+ unsigned long nr,
76+ unsigned long nf,
77+ unsigned long od)
78+{
79+ u64 tmp = ref_clk;
80+
81+ do_div(tmp, nr);
82+ tmp *= nf;
83+ do_div(tmp, od);
84+
85+ return tmp;
86+}
87+
88+static int ccu_pll_reset(struct ccu_pll *pll, unsigned long ref_clk,
89+ unsigned long nr)
90+{
91+ unsigned long ud, ut;
92+ u32 val;
93+
94+ ud = ccu_pll_lock_delay_us(ref_clk, nr);
95+ ut = ud * CCU_PLL_LOCK_CHECK_RETRIES;
96+
97+ regmap_update_bits(pll->sys_regs, pll->reg_ctl,
98+ CCU_PLL_CTL_RST, CCU_PLL_CTL_RST);
99+
100+ return regmap_read_poll_timeout_atomic(pll->sys_regs, pll->reg_ctl, val,
101+ val & CCU_PLL_CTL_LOCK, ud, ut);
102+}
103+
104+static int ccu_pll_enable(struct clk_hw *hw)
105+{
106+ struct clk_hw *parent_hw = clk_hw_get_parent(hw);
107+ struct ccu_pll *pll = to_ccu_pll(hw);
108+ unsigned long flags;
109+ u32 val = 0;
110+ int ret;
111+
112+ if (!parent_hw) {
113+ pr_err("Can't enable '%s' with no parent", clk_hw_get_name(hw));
114+ return -EINVAL;
115+ }
116+
117+ regmap_read(pll->sys_regs, pll->reg_ctl, &val);
118+ if (val & CCU_PLL_CTL_EN)
119+ return 0;
120+
121+ spin_lock_irqsave(&pll->lock, flags);
122+ regmap_write(pll->sys_regs, pll->reg_ctl, val | CCU_PLL_CTL_EN);
123+ ret = ccu_pll_reset(pll, clk_hw_get_rate(parent_hw),
124+ FIELD_GET(CCU_PLL_CTL_CLKR_MASK, val) + 1);
125+ spin_unlock_irqrestore(&pll->lock, flags);
126+ if (ret)
127+ pr_err("PLL '%s' reset timed out\n", clk_hw_get_name(hw));
128+
129+ return ret;
130+}
131+
132+static void ccu_pll_disable(struct clk_hw *hw)
133+{
134+ struct ccu_pll *pll = to_ccu_pll(hw);
135+ unsigned long flags;
136+
137+ spin_lock_irqsave(&pll->lock, flags);
138+ regmap_update_bits(pll->sys_regs, pll->reg_ctl, CCU_PLL_CTL_EN, 0);
139+ spin_unlock_irqrestore(&pll->lock, flags);
140+}
141+
142+static int ccu_pll_is_enabled(struct clk_hw *hw)
143+{
144+ struct ccu_pll *pll = to_ccu_pll(hw);
145+ u32 val = 0;
146+
147+ regmap_read(pll->sys_regs, pll->reg_ctl, &val);
148+
149+ return !!(val & CCU_PLL_CTL_EN);
150+}
151+
152+static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw,
153+ unsigned long parent_rate)
154+{
155+ struct ccu_pll *pll = to_ccu_pll(hw);
156+ unsigned long nr, nf, od;
157+ u32 val = 0;
158+
159+ regmap_read(pll->sys_regs, pll->reg_ctl, &val);
160+ nr = FIELD_GET(CCU_PLL_CTL_CLKR_MASK, val) + 1;
161+ nf = FIELD_GET(CCU_PLL_CTL_CLKF_MASK, val) + 1;
162+ od = FIELD_GET(CCU_PLL_CTL_CLKOD_MASK, val) + 1;
163+
164+ return ccu_pll_calc_freq(parent_rate, nr, nf, od);
165+}
166+
167+static void ccu_pll_calc_factors(unsigned long rate, unsigned long parent_rate,
168+ unsigned long *nr, unsigned long *nf,
169+ unsigned long *od)
170+{
171+ unsigned long err, freq, min_err = ULONG_MAX;
172+ unsigned long num, denom, n1, d1, nri;
173+ unsigned long nr_max, nf_max, od_max;
174+
175+ /*
176+ * Make sure PLL is working with valid input signal (Fdiv). If
177+ * you want to speed the function up just reduce CCU_PLL_NR_MAX.
178+ * This will cause a worse approximation though.
179+ */
180+ nri = (parent_rate / CCU_PLL_FDIV_MAX) + 1;
181+ nr_max = min(parent_rate / CCU_PLL_FDIV_MIN, CCU_PLL_NR_MAX);
182+
183+ /*
184+ * Find a closest [nr;nf;od] vector taking into account the
185+ * limitations like: 1) 700MHz <= Fvco <= 3.5GHz, 2) PLL Od is
186+ * either 1 or even number within the acceptable range (alas 1s
187+ * is also excluded by the next loop).
188+ */
189+ for (; nri <= nr_max; ++nri) {
190+ /* Use Od factor to fulfill the limitation 2). */
191+ num = CCU_PLL_CLKOD_FACTOR * rate;
192+ denom = parent_rate / nri;
193+
194+ /*
195+ * Make sure Fvco is within the acceptable range to fulfill
196+ * the condition 1). Note due to the CCU_PLL_CLKOD_FACTOR value
197+ * the actual upper limit is also divided by that factor.
198+ * It's not big problem for us since practically there is no
199+ * need in clocks with that high frequency.
200+ */
201+ nf_max = min(CCU_PLL_FVCO_MAX / denom, CCU_PLL_NF_MAX);
202+ od_max = CCU_PLL_OD_MAX / CCU_PLL_CLKOD_FACTOR;
203+
204+ /*
205+ * Bypass the out-of-bound values, which can't be properly
206+ * handled by the rational fraction approximation algorithm.
207+ */
208+ if (num / denom >= nf_max) {
209+ n1 = nf_max;
210+ d1 = 1;
211+ } else if (denom / num >= od_max) {
212+ n1 = 1;
213+ d1 = od_max;
214+ } else {
215+ rational_best_approximation(num, denom, nf_max, od_max,
216+ &n1, &d1);
217+ }
218+
219+ /* Select the best approximation of the target rate. */
220+ freq = ccu_pll_calc_freq(parent_rate, nri, n1, d1);
221+ err = abs((int64_t)freq - num);
222+ if (err < min_err) {
223+ min_err = err;
224+ *nr = nri;
225+ *nf = n1;
226+ *od = CCU_PLL_CLKOD_FACTOR * d1;
227+ }
228+ }
229+}
230+
231+static long ccu_pll_round_rate(struct clk_hw *hw, unsigned long rate,
232+ unsigned long *parent_rate)
233+{
234+ unsigned long nr = 1, nf = 1, od = 1;
235+
236+ ccu_pll_calc_factors(rate, *parent_rate, &nr, &nf, &od);
237+
238+ return ccu_pll_calc_freq(*parent_rate, nr, nf, od);
239+}
240+
241+/*
242+ * This method is used for PLLs, which support the on-the-fly dividers
243+ * adjustment. So there is no need in gating such clocks.
244+ */
245+static int ccu_pll_set_rate_reset(struct clk_hw *hw, unsigned long rate,
246+ unsigned long parent_rate)
247+{
248+ struct ccu_pll *pll = to_ccu_pll(hw);
249+ unsigned long nr, nf, od;
250+ unsigned long flags;
251+ u32 mask, val;
252+ int ret;
253+
254+ ccu_pll_calc_factors(rate, parent_rate, &nr, &nf, &od);
255+
256+ mask = CCU_PLL_CTL_CLKR_MASK | CCU_PLL_CTL_CLKF_MASK |
257+ CCU_PLL_CTL_CLKOD_MASK;
258+ val = FIELD_PREP(CCU_PLL_CTL_CLKR_MASK, nr - 1) |
259+ FIELD_PREP(CCU_PLL_CTL_CLKF_MASK, nf - 1) |
260+ FIELD_PREP(CCU_PLL_CTL_CLKOD_MASK, od - 1);
261+
262+ spin_lock_irqsave(&pll->lock, flags);
263+ regmap_update_bits(pll->sys_regs, pll->reg_ctl, mask, val);
264+ ret = ccu_pll_reset(pll, parent_rate, nr);
265+ spin_unlock_irqrestore(&pll->lock, flags);
266+ if (ret)
267+ pr_err("PLL '%s' reset timed out\n", clk_hw_get_name(hw));
268+
269+ return ret;
270+}
271+
272+/*
273+ * This method is used for PLLs, which don't support the on-the-fly dividers
274+ * adjustment. So the corresponding clocks are supposed to be gated first.
275+ */
276+static int ccu_pll_set_rate_norst(struct clk_hw *hw, unsigned long rate,
277+ unsigned long parent_rate)
278+{
279+ struct ccu_pll *pll = to_ccu_pll(hw);
280+ unsigned long nr, nf, od;
281+ unsigned long flags;
282+ u32 mask, val;
283+
284+ ccu_pll_calc_factors(rate, parent_rate, &nr, &nf, &od);
285+
286+ /*
287+ * Disable PLL if it was enabled by default or left enabled by the
288+ * system bootloader.
289+ */
290+ mask = CCU_PLL_CTL_CLKR_MASK | CCU_PLL_CTL_CLKF_MASK |
291+ CCU_PLL_CTL_CLKOD_MASK | CCU_PLL_CTL_EN;
292+ val = FIELD_PREP(CCU_PLL_CTL_CLKR_MASK, nr - 1) |
293+ FIELD_PREP(CCU_PLL_CTL_CLKF_MASK, nf - 1) |
294+ FIELD_PREP(CCU_PLL_CTL_CLKOD_MASK, od - 1);
295+
296+ spin_lock_irqsave(&pll->lock, flags);
297+ regmap_update_bits(pll->sys_regs, pll->reg_ctl, mask, val);
298+ spin_unlock_irqrestore(&pll->lock, flags);
299+
300+ return 0;
301+}
302+
303+#ifdef CONFIG_DEBUG_FS
304+
305+struct ccu_pll_dbgfs_bit {
306+ struct ccu_pll *pll;
307+ const char *name;
308+ unsigned int reg;
309+ u32 mask;
310+};
311+
312+struct ccu_pll_dbgfs_fld {
313+ struct ccu_pll *pll;
314+ const char *name;
315+ unsigned int reg;
316+ unsigned int lsb;
317+ u32 mask;
318+ u32 min;
319+ u32 max;
320+};
321+
322+#define CCU_PLL_DBGFS_BIT_ATTR(_name, _reg, _mask) \
323+ { \
324+ .name = _name, \
325+ .reg = _reg, \
326+ .mask = _mask \
327+ }
328+
329+#define CCU_PLL_DBGFS_FLD_ATTR(_name, _reg, _lsb, _mask, _min, _max) \
330+ { \
331+ .name = _name, \
332+ .reg = _reg, \
333+ .lsb = _lsb, \
334+ .mask = _mask, \
335+ .min = _min, \
336+ .max = _max \
337+ }
338+
339+static const struct ccu_pll_dbgfs_bit ccu_pll_bits[] = {
340+ CCU_PLL_DBGFS_BIT_ATTR("pll_en", CCU_PLL_CTL, CCU_PLL_CTL_EN),
341+ CCU_PLL_DBGFS_BIT_ATTR("pll_rst", CCU_PLL_CTL, CCU_PLL_CTL_RST),
342+ CCU_PLL_DBGFS_BIT_ATTR("pll_bypass", CCU_PLL_CTL, CCU_PLL_CTL_BYPASS),
343+ CCU_PLL_DBGFS_BIT_ATTR("pll_lock", CCU_PLL_CTL, CCU_PLL_CTL_LOCK)
344+};
345+
346+#define CCU_PLL_DBGFS_BIT_NUM ARRAY_SIZE(ccu_pll_bits)
347+
348+static const struct ccu_pll_dbgfs_fld ccu_pll_flds[] = {
349+ CCU_PLL_DBGFS_FLD_ATTR("pll_nr", CCU_PLL_CTL, CCU_PLL_CTL_CLKR_FLD,
350+ CCU_PLL_CTL_CLKR_MASK, 1, CCU_PLL_NR_MAX),
351+ CCU_PLL_DBGFS_FLD_ATTR("pll_nf", CCU_PLL_CTL, CCU_PLL_CTL_CLKF_FLD,
352+ CCU_PLL_CTL_CLKF_MASK, 1, CCU_PLL_NF_MAX),
353+ CCU_PLL_DBGFS_FLD_ATTR("pll_od", CCU_PLL_CTL, CCU_PLL_CTL_CLKOD_FLD,
354+ CCU_PLL_CTL_CLKOD_MASK, 1, CCU_PLL_OD_MAX),
355+ CCU_PLL_DBGFS_FLD_ATTR("pll_nb", CCU_PLL_CTL1, CCU_PLL_CTL1_BWADJ_FLD,
356+ CCU_PLL_CTL1_BWADJ_MASK, 1, CCU_PLL_NB_MAX)
357+};
358+
359+#define CCU_PLL_DBGFS_FLD_NUM ARRAY_SIZE(ccu_pll_flds)
360+
361+/*
362+ * It can be dangerous to change the PLL settings behind clock framework back,
363+ * therefore we don't provide any kernel config based compile time option for
364+ * this feature to enable.
365+ */
366+#undef CCU_PLL_ALLOW_WRITE_DEBUGFS
367+#ifdef CCU_PLL_ALLOW_WRITE_DEBUGFS
368+
369+static int ccu_pll_dbgfs_bit_set(void *priv, u64 val)
370+{
371+ const struct ccu_pll_dbgfs_bit *bit = priv;
372+ struct ccu_pll *pll = bit->pll;
373+ unsigned long flags;
374+
375+ spin_lock_irqsave(&pll->lock, flags);
376+ regmap_update_bits(pll->sys_regs, pll->reg_ctl + bit->reg,
377+ bit->mask, val ? bit->mask : 0);
378+ spin_unlock_irqrestore(&pll->lock, flags);
379+
380+ return 0;
381+}
382+
383+static int ccu_pll_dbgfs_fld_set(void *priv, u64 val)
384+{
385+ struct ccu_pll_dbgfs_fld *fld = priv;
386+ struct ccu_pll *pll = fld->pll;
387+ unsigned long flags;
388+ u32 data;
389+
390+ val = clamp_t(u64, val, fld->min, fld->max);
391+ data = ((val - 1) << fld->lsb) & fld->mask;
392+
393+ spin_lock_irqsave(&pll->lock, flags);
394+ regmap_update_bits(pll->sys_regs, pll->reg_ctl + fld->reg, fld->mask,
395+ data);
396+ spin_unlock_irqrestore(&pll->lock, flags);
397+
398+ return 0;
399+}
400+
401+#define ccu_pll_dbgfs_mode 0644
402+
403+#else /* !CCU_PLL_ALLOW_WRITE_DEBUGFS */
404+
405+#define ccu_pll_dbgfs_bit_set NULL
406+#define ccu_pll_dbgfs_fld_set NULL
407+#define ccu_pll_dbgfs_mode 0444
408+
409+#endif /* !CCU_PLL_ALLOW_WRITE_DEBUGFS */
410+
411+static int ccu_pll_dbgfs_bit_get(void *priv, u64 *val)
412+{
413+ struct ccu_pll_dbgfs_bit *bit = priv;
414+ struct ccu_pll *pll = bit->pll;
415+ u32 data = 0;
416+
417+ regmap_read(pll->sys_regs, pll->reg_ctl + bit->reg, &data);
418+ *val = !!(data & bit->mask);
419+
420+ return 0;
421+}
422+DEFINE_DEBUGFS_ATTRIBUTE(ccu_pll_dbgfs_bit_fops,
423+ ccu_pll_dbgfs_bit_get, ccu_pll_dbgfs_bit_set, "%llu\n");
424+
425+static int ccu_pll_dbgfs_fld_get(void *priv, u64 *val)
426+{
427+ struct ccu_pll_dbgfs_fld *fld = priv;
428+ struct ccu_pll *pll = fld->pll;
429+ u32 data = 0;
430+
431+ regmap_read(pll->sys_regs, pll->reg_ctl + fld->reg, &data);
432+ *val = ((data & fld->mask) >> fld->lsb) + 1;
433+
434+ return 0;
435+}
436+DEFINE_DEBUGFS_ATTRIBUTE(ccu_pll_dbgfs_fld_fops,
437+ ccu_pll_dbgfs_fld_get, ccu_pll_dbgfs_fld_set, "%llu\n");
438+
439+static void ccu_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
440+{
441+ struct ccu_pll *pll = to_ccu_pll(hw);
442+ struct ccu_pll_dbgfs_bit *bits;
443+ struct ccu_pll_dbgfs_fld *flds;
444+ int idx;
445+
446+ bits = kcalloc(CCU_PLL_DBGFS_BIT_NUM, sizeof(*bits), GFP_KERNEL);
447+ if (!bits)
448+ return;
449+
450+ for (idx = 0; idx < CCU_PLL_DBGFS_BIT_NUM; ++idx) {
451+ bits[idx] = ccu_pll_bits[idx];
452+ bits[idx].pll = pll;
453+
454+ debugfs_create_file_unsafe(bits[idx].name, ccu_pll_dbgfs_mode,
455+ dentry, &bits[idx],
456+ &ccu_pll_dbgfs_bit_fops);
457+ }
458+
459+ flds = kcalloc(CCU_PLL_DBGFS_FLD_NUM, sizeof(*flds), GFP_KERNEL);
460+ if (!flds)
461+ return;
462+
463+ for (idx = 0; idx < CCU_PLL_DBGFS_FLD_NUM; ++idx) {
464+ flds[idx] = ccu_pll_flds[idx];
465+ flds[idx].pll = pll;
466+
467+ debugfs_create_file_unsafe(flds[idx].name, ccu_pll_dbgfs_mode,
468+ dentry, &flds[idx],
469+ &ccu_pll_dbgfs_fld_fops);
470+ }
471+}
472+
473+#else /* !CONFIG_DEBUG_FS */
474+
475+#define ccu_pll_debug_init NULL
476+
477+#endif /* !CONFIG_DEBUG_FS */
478+
479+static const struct clk_ops ccu_pll_gate_to_set_ops = {
480+ .enable = ccu_pll_enable,
481+ .disable = ccu_pll_disable,
482+ .is_enabled = ccu_pll_is_enabled,
483+ .recalc_rate = ccu_pll_recalc_rate,
484+ .round_rate = ccu_pll_round_rate,
485+ .set_rate = ccu_pll_set_rate_norst,
486+ .debug_init = ccu_pll_debug_init
487+};
488+
489+static const struct clk_ops ccu_pll_straight_set_ops = {
490+ .enable = ccu_pll_enable,
491+ .disable = ccu_pll_disable,
492+ .is_enabled = ccu_pll_is_enabled,
493+ .recalc_rate = ccu_pll_recalc_rate,
494+ .round_rate = ccu_pll_round_rate,
495+ .set_rate = ccu_pll_set_rate_reset,
496+ .debug_init = ccu_pll_debug_init
497+};
498+
499+struct ccu_pll *ccu_pll_hw_register(const struct ccu_pll_init_data *pll_init)
500+{
501+ struct clk_parent_data parent_data = { };
502+ struct clk_init_data hw_init = { };
503+ struct ccu_pll *pll;
504+ int ret;
505+
506+ if (!pll_init)
507+ return ERR_PTR(-EINVAL);
508+
509+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
510+ if (!pll)
511+ return ERR_PTR(-ENOMEM);
512+
513+ /*
514+ * Note since Baikal-T1 System Controller registers are MMIO-backed
515+ * we won't check the regmap IO operations return status, because it
516+ * must be zero anyway.
517+ */
518+ pll->hw.init = &hw_init;
519+ pll->reg_ctl = pll_init->base + CCU_PLL_CTL;
520+ pll->reg_ctl1 = pll_init->base + CCU_PLL_CTL1;
521+ pll->sys_regs = pll_init->sys_regs;
522+ pll->id = pll_init->id;
523+ spin_lock_init(&pll->lock);
524+
525+ hw_init.name = pll_init->name;
526+ hw_init.flags = pll_init->flags;
527+
528+ if (hw_init.flags & CLK_SET_RATE_GATE)
529+ hw_init.ops = &ccu_pll_gate_to_set_ops;
530+ else
531+ hw_init.ops = &ccu_pll_straight_set_ops;
532+
533+ if (!pll_init->parent_name) {
534+ ret = -EINVAL;
535+ goto err_free_pll;
536+ }
537+ parent_data.fw_name = pll_init->parent_name;
538+ hw_init.parent_data = &parent_data;
539+ hw_init.num_parents = 1;
540+
541+ ret = of_clk_hw_register(pll_init->np, &pll->hw);
542+ if (ret)
543+ goto err_free_pll;
544+
545+ return pll;
546+
547+err_free_pll:
548+ kfree(pll);
549+
550+ return ERR_PTR(ret);
551+}
552+
553+void ccu_pll_hw_unregister(struct ccu_pll *pll)
554+{
555+ clk_hw_unregister(&pll->hw);
556+
557+ kfree(pll);
558+}
drivers/clk/baikal-t1/ccu-pll.h+64−0
@@ -0,0 +1,64 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
4+ *
5+ * Baikal-T1 CCU PLL interface driver
6+ */
7+#ifndef __CLK_BT1_CCU_PLL_H__
8+#define __CLK_BT1_CCU_PLL_H__
9+
10+#include <linux/clk-provider.h>
11+#include <linux/spinlock.h>
12+#include <linux/regmap.h>
13+#include <linux/bits.h>
14+#include <linux/of.h>
15+
16+/*
17+ * struct ccu_pll_init_data - CCU PLL initialization data
18+ * @id: Clock private identifier.
19+ * @name: Clocks name.
20+ * @parent_name: Clocks parent name in a fw node.
21+ * @base: PLL registers base address with respect to the sys_regs base.
22+ * @sys_regs: Baikal-T1 System Controller registers map.
23+ * @np: Pointer to the node describing the CCU PLLs.
24+ * @flags: PLL clock flags.
25+ */
26+struct ccu_pll_init_data {
27+ unsigned int id;
28+ const char *name;
29+ const char *parent_name;
30+ unsigned int base;
31+ struct regmap *sys_regs;
32+ struct device_node *np;
33+ unsigned long flags;
34+};
35+
36+/*
37+ * struct ccu_pll - CCU PLL descriptor
38+ * @hw: clk_hw of the PLL.
39+ * @id: Clock private identifier.
40+ * @reg_ctl: PLL control register base.
41+ * @reg_ctl1: PLL control1 register base.
42+ * @sys_regs: Baikal-T1 System Controller registers map.
43+ * @lock: PLL state change spin-lock.
44+ */
45+struct ccu_pll {
46+ struct clk_hw hw;
47+ unsigned int id;
48+ unsigned int reg_ctl;
49+ unsigned int reg_ctl1;
50+ struct regmap *sys_regs;
51+ spinlock_t lock;
52+};
53+#define to_ccu_pll(_hw) container_of(_hw, struct ccu_pll, hw)
54+
55+static inline struct clk_hw *ccu_pll_get_clk_hw(struct ccu_pll *pll)
56+{
57+ return pll ? &pll->hw : NULL;
58+}
59+
60+struct ccu_pll *ccu_pll_hw_register(const struct ccu_pll_init_data *init);
61+
62+void ccu_pll_hw_unregister(struct ccu_pll *pll);
63+
64+#endif /* __CLK_BT1_CCU_PLL_H__ */
drivers/clk/baikal-t1/clk-ccu-div.c+485−0
@@ -0,0 +1,485 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+/*
3+ * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
4+ *
5+ * Authors:
6+ * Serge Semin <Sergey.Semin@baikalelectronics.ru>
7+ * Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
8+ *
9+ * Baikal-T1 CCU Dividers clock driver
10+ */
11+
12+#define pr_fmt(fmt) "bt1-ccu-div: " fmt
13+
14+#include <linux/kernel.h>
15+#include <linux/printk.h>
16+#include <linux/slab.h>
17+#include <linux/clk-provider.h>
18+#include <linux/reset-controller.h>
19+#include <linux/mfd/syscon.h>
20+#include <linux/of.h>
21+#include <linux/of_address.h>
22+#include <linux/of_platform.h>
23+#include <linux/ioport.h>
24+#include <linux/regmap.h>
25+
26+#include <dt-bindings/clock/bt1-ccu.h>
27+#include <dt-bindings/reset/bt1-ccu.h>
28+
29+#include "ccu-div.h"
30+
31+#define CCU_AXI_MAIN_BASE 0x030
32+#define CCU_AXI_DDR_BASE 0x034
33+#define CCU_AXI_SATA_BASE 0x038
34+#define CCU_AXI_GMAC0_BASE 0x03C
35+#define CCU_AXI_GMAC1_BASE 0x040
36+#define CCU_AXI_XGMAC_BASE 0x044
37+#define CCU_AXI_PCIE_M_BASE 0x048
38+#define CCU_AXI_PCIE_S_BASE 0x04C
39+#define CCU_AXI_USB_BASE 0x050
40+#define CCU_AXI_HWA_BASE 0x054
41+#define CCU_AXI_SRAM_BASE 0x058
42+
43+#define CCU_SYS_SATA_REF_BASE 0x060
44+#define CCU_SYS_APB_BASE 0x064
45+#define CCU_SYS_GMAC0_BASE 0x068
46+#define CCU_SYS_GMAC1_BASE 0x06C
47+#define CCU_SYS_XGMAC_BASE 0x070
48+#define CCU_SYS_USB_BASE 0x074
49+#define CCU_SYS_PVT_BASE 0x078
50+#define CCU_SYS_HWA_BASE 0x07C
51+#define CCU_SYS_UART_BASE 0x084
52+#define CCU_SYS_TIMER0_BASE 0x088
53+#define CCU_SYS_TIMER1_BASE 0x08C
54+#define CCU_SYS_TIMER2_BASE 0x090
55+#define CCU_SYS_WDT_BASE 0x150
56+
57+#define CCU_DIV_VAR_INFO(_id, _name, _pname, _base, _width, _flags, _features) \
58+ { \
59+ .id = _id, \
60+ .name = _name, \
61+ .parent_name = _pname, \
62+ .base = _base, \
63+ .type = CCU_DIV_VAR, \
64+ .width = _width, \
65+ .flags = _flags, \
66+ .features = _features \
67+ }
68+
69+#define CCU_DIV_GATE_INFO(_id, _name, _pname, _base, _divider) \
70+ { \
71+ .id = _id, \
72+ .name = _name, \
73+ .parent_name = _pname, \
74+ .base = _base, \
75+ .type = CCU_DIV_GATE, \
76+ .divider = _divider \
77+ }
78+
79+#define CCU_DIV_FIXED_INFO(_id, _name, _pname, _divider) \
80+ { \
81+ .id = _id, \
82+ .name = _name, \
83+ .parent_name = _pname, \
84+ .type = CCU_DIV_FIXED, \
85+ .divider = _divider \
86+ }
87+
88+#define CCU_DIV_RST_MAP(_rst_id, _clk_id) \
89+ { \
90+ .rst_id = _rst_id, \
91+ .clk_id = _clk_id \
92+ }
93+
94+struct ccu_div_info {
95+ unsigned int id;
96+ const char *name;
97+ const char *parent_name;
98+ unsigned int base;
99+ enum ccu_div_type type;
100+ union {
101+ unsigned int width;
102+ unsigned int divider;
103+ };
104+ unsigned long flags;
105+ unsigned long features;
106+};
107+
108+struct ccu_div_rst_map {
109+ unsigned int rst_id;
110+ unsigned int clk_id;
111+};
112+
113+struct ccu_div_data {
114+ struct device_node *np;
115+ struct regmap *sys_regs;
116+
117+ unsigned int divs_num;
118+ const struct ccu_div_info *divs_info;
119+ struct ccu_div **divs;
120+
121+ unsigned int rst_num;
122+ const struct ccu_div_rst_map *rst_map;
123+ struct reset_controller_dev rcdev;
124+};
125+#define to_ccu_div_data(_rcdev) container_of(_rcdev, struct ccu_div_data, rcdev)
126+
127+/*
128+ * AXI Main Interconnect (axi_main_clk) and DDR AXI-bus (axi_ddr_clk) clocks
129+ * must be left enabled in any case, since former one is responsible for
130+ * clocking a bus between CPU cores and the rest of the SoC components, while
131+ * the later is clocking the AXI-bus between DDR controller and the Main
132+ * Interconnect. So should any of these clocks get to be disabled, the system
133+ * will literally stop working. That's why we marked them as critical.
134+ */
135+static const struct ccu_div_info axi_info[] = {
136+ CCU_DIV_VAR_INFO(CCU_AXI_MAIN_CLK, "axi_main_clk", "pcie_clk",
137+ CCU_AXI_MAIN_BASE, 4,
138+ CLK_IS_CRITICAL, CCU_DIV_RESET_DOMAIN),
139+ CCU_DIV_VAR_INFO(CCU_AXI_DDR_CLK, "axi_ddr_clk", "sata_clk",
140+ CCU_AXI_DDR_BASE, 4,
141+ CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
142+ CCU_DIV_RESET_DOMAIN),
143+ CCU_DIV_VAR_INFO(CCU_AXI_SATA_CLK, "axi_sata_clk", "sata_clk",
144+ CCU_AXI_SATA_BASE, 4,
145+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
146+ CCU_DIV_VAR_INFO(CCU_AXI_GMAC0_CLK, "axi_gmac0_clk", "eth_clk",
147+ CCU_AXI_GMAC0_BASE, 4,
148+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
149+ CCU_DIV_VAR_INFO(CCU_AXI_GMAC1_CLK, "axi_gmac1_clk", "eth_clk",
150+ CCU_AXI_GMAC1_BASE, 4,
151+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
152+ CCU_DIV_VAR_INFO(CCU_AXI_XGMAC_CLK, "axi_xgmac_clk", "eth_clk",
153+ CCU_AXI_XGMAC_BASE, 4,
154+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
155+ CCU_DIV_VAR_INFO(CCU_AXI_PCIE_M_CLK, "axi_pcie_m_clk", "pcie_clk",
156+ CCU_AXI_PCIE_M_BASE, 4,
157+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
158+ CCU_DIV_VAR_INFO(CCU_AXI_PCIE_S_CLK, "axi_pcie_s_clk", "pcie_clk",
159+ CCU_AXI_PCIE_S_BASE, 4,
160+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
161+ CCU_DIV_VAR_INFO(CCU_AXI_USB_CLK, "axi_usb_clk", "sata_clk",
162+ CCU_AXI_USB_BASE, 4,
163+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
164+ CCU_DIV_VAR_INFO(CCU_AXI_HWA_CLK, "axi_hwa_clk", "sata_clk",
165+ CCU_AXI_HWA_BASE, 4,
166+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
167+ CCU_DIV_VAR_INFO(CCU_AXI_SRAM_CLK, "axi_sram_clk", "eth_clk",
168+ CCU_AXI_SRAM_BASE, 4,
169+ CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN)
170+};
171+
172+static const struct ccu_div_rst_map axi_rst_map[] = {
173+ CCU_DIV_RST_MAP(CCU_AXI_MAIN_RST, CCU_AXI_MAIN_CLK),
174+ CCU_DIV_RST_MAP(CCU_AXI_DDR_RST, CCU_AXI_DDR_CLK),
175+ CCU_DIV_RST_MAP(CCU_AXI_SATA_RST, CCU_AXI_SATA_CLK),
176+ CCU_DIV_RST_MAP(CCU_AXI_GMAC0_RST, CCU_AXI_GMAC0_CLK),
177+ CCU_DIV_RST_MAP(CCU_AXI_GMAC1_RST, CCU_AXI_GMAC1_CLK),
178+ CCU_DIV_RST_MAP(CCU_AXI_XGMAC_RST, CCU_AXI_XGMAC_CLK),
179+ CCU_DIV_RST_MAP(CCU_AXI_PCIE_M_RST, CCU_AXI_PCIE_M_CLK),
180+ CCU_DIV_RST_MAP(CCU_AXI_PCIE_S_RST, CCU_AXI_PCIE_S_CLK),
181+ CCU_DIV_RST_MAP(CCU_AXI_USB_RST, CCU_AXI_USB_CLK),
182+ CCU_DIV_RST_MAP(CCU_AXI_HWA_RST, CCU_AXI_HWA_CLK),
183+ CCU_DIV_RST_MAP(CCU_AXI_SRAM_RST, CCU_AXI_SRAM_CLK)
184+};
185+
186+/*
187+ * APB-bus clock is marked as critical since it's a main communication bus
188+ * for the SoC devices registers IO-operations.
189+ */
190+static const struct ccu_div_info sys_info[] = {
191+ CCU_DIV_VAR_INFO(CCU_SYS_SATA_REF_CLK, "sys_sata_ref_clk",
192+ "sata_clk", CCU_SYS_SATA_REF_BASE, 4,
193+ CLK_SET_RATE_GATE,
194+ CCU_DIV_SKIP_ONE | CCU_DIV_LOCK_SHIFTED |
195+ CCU_DIV_RESET_DOMAIN),
196+ CCU_DIV_VAR_INFO(CCU_SYS_APB_CLK, "sys_apb_clk",
197+ "pcie_clk", CCU_SYS_APB_BASE, 5,
198+ CLK_IS_CRITICAL, CCU_DIV_RESET_DOMAIN),
199+ CCU_DIV_GATE_INFO(CCU_SYS_GMAC0_TX_CLK, "sys_gmac0_tx_clk",
200+ "eth_clk", CCU_SYS_GMAC0_BASE, 5),
201+ CCU_DIV_FIXED_INFO(CCU_SYS_GMAC0_PTP_CLK, "sys_gmac0_ptp_clk",
202+ "eth_clk", 10),
203+ CCU_DIV_GATE_INFO(CCU_SYS_GMAC1_TX_CLK, "sys_gmac1_tx_clk",
204+ "eth_clk", CCU_SYS_GMAC1_BASE, 5),
205+ CCU_DIV_FIXED_INFO(CCU_SYS_GMAC1_PTP_CLK, "sys_gmac1_ptp_clk",
206+ "eth_clk", 10),
207+ CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk",
208+ "eth_clk", CCU_SYS_XGMAC_BASE, 8),
209+ CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_PTP_CLK, "sys_xgmac_ptp_clk",
210+ "eth_clk", 10),
211+ CCU_DIV_GATE_INFO(CCU_SYS_USB_CLK, "sys_usb_clk",
212+ "eth_clk", CCU_SYS_USB_BASE, 10),
213+ CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk",
214+ "ref_clk", CCU_SYS_PVT_BASE, 5,
215+ CLK_SET_RATE_GATE, 0),
216+ CCU_DIV_VAR_INFO(CCU_SYS_HWA_CLK, "sys_hwa_clk",
217+ "sata_clk", CCU_SYS_HWA_BASE, 4,
218+ CLK_SET_RATE_GATE, 0),
219+ CCU_DIV_VAR_INFO(CCU_SYS_UART_CLK, "sys_uart_clk",
220+ "eth_clk", CCU_SYS_UART_BASE, 17,
221+ CLK_SET_RATE_GATE, 0),
222+ CCU_DIV_FIXED_INFO(CCU_SYS_I2C1_CLK, "sys_i2c1_clk",
223+ "eth_clk", 10),
224+ CCU_DIV_FIXED_INFO(CCU_SYS_I2C2_CLK, "sys_i2c2_clk",
225+ "eth_clk", 10),
226+ CCU_DIV_FIXED_INFO(CCU_SYS_GPIO_CLK, "sys_gpio_clk",
227+ "ref_clk", 25),
228+ CCU_DIV_VAR_INFO(CCU_SYS_TIMER0_CLK, "sys_timer0_clk",
229+ "ref_clk", CCU_SYS_TIMER0_BASE, 17,
230+ CLK_SET_RATE_GATE, 0),
231+ CCU_DIV_VAR_INFO(CCU_SYS_TIMER1_CLK, "sys_timer1_clk",
232+ "ref_clk", CCU_SYS_TIMER1_BASE, 17,
233+ CLK_SET_RATE_GATE, 0),
234+ CCU_DIV_VAR_INFO(CCU_SYS_TIMER2_CLK, "sys_timer2_clk",
235+ "ref_clk", CCU_SYS_TIMER2_BASE, 17,
236+ CLK_SET_RATE_GATE, 0),
237+ CCU_DIV_VAR_INFO(CCU_SYS_WDT_CLK, "sys_wdt_clk",
238+ "eth_clk", CCU_SYS_WDT_BASE, 17,
239+ CLK_SET_RATE_GATE, CCU_DIV_SKIP_ONE_TO_THREE)
240+};
241+
242+static const struct ccu_div_rst_map sys_rst_map[] = {
243+ CCU_DIV_RST_MAP(CCU_SYS_SATA_REF_RST, CCU_SYS_SATA_REF_CLK),
244+ CCU_DIV_RST_MAP(CCU_SYS_APB_RST, CCU_SYS_APB_CLK),
245+};
246+
247+static struct ccu_div *ccu_div_find_desc(struct ccu_div_data *data,
248+ unsigned int clk_id)
249+{
250+ struct ccu_div *div;
251+ int idx;
252+
253+ for (idx = 0; idx < data->divs_num; ++idx) {
254+ div = data->divs[idx];
255+ if (div && div->id == clk_id)
256+ return div;
257+ }
258+
259+ return ERR_PTR(-EINVAL);
260+}
261+
262+static int ccu_div_reset(struct reset_controller_dev *rcdev,
263+ unsigned long rst_id)
264+{
265+ struct ccu_div_data *data = to_ccu_div_data(rcdev);
266+ const struct ccu_div_rst_map *map;
267+ struct ccu_div *div;
268+ int idx, ret;
269+
270+ for (idx = 0, map = data->rst_map; idx < data->rst_num; ++idx, ++map) {
271+ if (map->rst_id == rst_id)
272+ break;
273+ }
274+ if (idx == data->rst_num) {
275+ pr_err("Invalid reset ID %lu specified\n", rst_id);
276+ return -EINVAL;
277+ }
278+
279+ div = ccu_div_find_desc(data, map->clk_id);
280+ if (IS_ERR(div)) {
281+ pr_err("Invalid clock ID %d in mapping\n", map->clk_id);
282+ return PTR_ERR(div);
283+ }
284+
285+ ret = ccu_div_reset_domain(div);
286+ if (ret) {
287+ pr_err("Reset isn't supported by divider %s\n",
288+ clk_hw_get_name(ccu_div_get_clk_hw(div)));
289+ }
290+
291+ return ret;
292+}
293+
294+static const struct reset_control_ops ccu_div_rst_ops = {
295+ .reset = ccu_div_reset,
296+};
297+
298+static struct ccu_div_data *ccu_div_create_data(struct device_node *np)
299+{
300+ struct ccu_div_data *data;
301+ int ret;
302+
303+ data = kzalloc(sizeof(*data), GFP_KERNEL);
304+ if (!data)
305+ return ERR_PTR(-ENOMEM);
306+
307+ data->np = np;
308+ if (of_device_is_compatible(np, "baikal,bt1-ccu-axi")) {
309+ data->divs_num = ARRAY_SIZE(axi_info);
310+ data->divs_info = axi_info;
311+ data->rst_num = ARRAY_SIZE(axi_rst_map);
312+ data->rst_map = axi_rst_map;
313+ } else if (of_device_is_compatible(np, "baikal,bt1-ccu-sys")) {
314+ data->divs_num = ARRAY_SIZE(sys_info);
315+ data->divs_info = sys_info;
316+ data->rst_num = ARRAY_SIZE(sys_rst_map);
317+ data->rst_map = sys_rst_map;
318+ } else {
319+ pr_err("Incompatible DT node '%s' specified\n",
320+ of_node_full_name(np));
321+ ret = -EINVAL;
322+ goto err_kfree_data;
323+ }
324+
325+ data->divs = kcalloc(data->divs_num, sizeof(*data->divs), GFP_KERNEL);
326+ if (!data->divs) {
327+ ret = -ENOMEM;
328+ goto err_kfree_data;
329+ }
330+
331+ return data;
332+
333+err_kfree_data:
334+ kfree(data);
335+
336+ return ERR_PTR(ret);
337+}
338+
339+static void ccu_div_free_data(struct ccu_div_data *data)
340+{
341+ kfree(data->divs);
342+
343+ kfree(data);
344+}
345+
346+static int ccu_div_find_sys_regs(struct ccu_div_data *data)
347+{
348+ data->sys_regs = syscon_node_to_regmap(data->np->parent);
349+ if (IS_ERR(data->sys_regs)) {
350+ pr_err("Failed to find syscon regs for '%s'\n",
351+ of_node_full_name(data->np));
352+ return PTR_ERR(data->sys_regs);
353+ }
354+
355+ return 0;
356+}
357+
358+static struct clk_hw *ccu_div_of_clk_hw_get(struct of_phandle_args *clkspec,
359+ void *priv)
360+{
361+ struct ccu_div_data *data = priv;
362+ struct ccu_div *div;
363+ unsigned int clk_id;
364+
365+ clk_id = clkspec->args[0];
366+ div = ccu_div_find_desc(data, clk_id);
367+ if (IS_ERR(div)) {
368+ pr_info("Invalid clock ID %d specified\n", clk_id);
369+ return ERR_CAST(div);
370+ }
371+
372+ return ccu_div_get_clk_hw(div);
373+}
374+
375+static int ccu_div_clk_register(struct ccu_div_data *data)
376+{
377+ int idx, ret;
378+
379+ for (idx = 0; idx < data->divs_num; ++idx) {
380+ const struct ccu_div_info *info = &data->divs_info[idx];
381+ struct ccu_div_init_data init = {0};
382+
383+ init.id = info->id;
384+ init.name = info->name;
385+ init.parent_name = info->parent_name;
386+ init.np = data->np;
387+ init.type = info->type;
388+ init.flags = info->flags;
389+ init.features = info->features;
390+
391+ if (init.type == CCU_DIV_VAR) {
392+ init.base = info->base;
393+ init.sys_regs = data->sys_regs;
394+ init.width = info->width;
395+ } else if (init.type == CCU_DIV_GATE) {
396+ init.base = info->base;
397+ init.sys_regs = data->sys_regs;
398+ init.divider = info->divider;
399+ } else {
400+ init.divider = info->divider;
401+ }
402+
403+ data->divs[idx] = ccu_div_hw_register(&init);
404+ if (IS_ERR(data->divs[idx])) {
405+ ret = PTR_ERR(data->divs[idx]);
406+ pr_err("Couldn't register divider '%s' hw\n",
407+ init.name);
408+ goto err_hw_unregister;
409+ }
410+ }
411+
412+ ret = of_clk_add_hw_provider(data->np, ccu_div_of_clk_hw_get, data);
413+ if (ret) {
414+ pr_err("Couldn't register dividers '%s' clock provider\n",
415+ of_node_full_name(data->np));
416+ goto err_hw_unregister;
417+ }
418+
419+ return 0;
420+
421+err_hw_unregister:
422+ for (--idx; idx >= 0; --idx)
423+ ccu_div_hw_unregister(data->divs[idx]);
424+
425+ return ret;
426+}
427+
428+static void ccu_div_clk_unregister(struct ccu_div_data *data)
429+{
430+ int idx;
431+
432+ of_clk_del_provider(data->np);
433+
434+ for (idx = 0; idx < data->divs_num; ++idx)
435+ ccu_div_hw_unregister(data->divs[idx]);
436+}
437+
438+static int ccu_div_rst_register(struct ccu_div_data *data)
439+{
440+ int ret;
441+
442+ data->rcdev.ops = &ccu_div_rst_ops;
443+ data->rcdev.of_node = data->np;
444+ data->rcdev.nr_resets = data->rst_num;
445+
446+ ret = reset_controller_register(&data->rcdev);
447+ if (ret)
448+ pr_err("Couldn't register divider '%s' reset controller\n",
449+ of_node_full_name(data->np));
450+
451+ return ret;
452+}
453+
454+static void ccu_div_init(struct device_node *np)
455+{
456+ struct ccu_div_data *data;
457+ int ret;
458+
459+ data = ccu_div_create_data(np);
460+ if (IS_ERR(data))
461+ return;
462+
463+ ret = ccu_div_find_sys_regs(data);
464+ if (ret)
465+ goto err_free_data;
466+
467+ ret = ccu_div_clk_register(data);
468+ if (ret)
469+ goto err_free_data;
470+
471+ ret = ccu_div_rst_register(data);
472+ if (ret)
473+ goto err_clk_unregister;
474+
475+ return;
476+
477+err_clk_unregister:
478+ ccu_div_clk_unregister(data);
479+
480+err_free_data:
481+ ccu_div_free_data(data);
482+}
483+
484+CLK_OF_DECLARE(ccu_axi, "baikal,bt1-ccu-axi", ccu_div_init);
485+CLK_OF_DECLARE(ccu_sys, "baikal,bt1-ccu-sys", ccu_div_init);
drivers/clk/baikal-t1/clk-ccu-pll.c+204−0
@@ -0,0 +1,204 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+/*
3+ * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
4+ *
5+ * Authors:
6+ * Serge Semin <Sergey.Semin@baikalelectronics.ru>
7+ * Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
8+ *
9+ * Baikal-T1 CCU PLL clocks driver
10+ */
11+
12+#define pr_fmt(fmt) "bt1-ccu-pll: " fmt
13+
14+#include <linux/kernel.h>
15+#include <linux/printk.h>
16+#include <linux/slab.h>
17+#include <linux/clk-provider.h>
18+#include <linux/mfd/syscon.h>
19+#include <linux/of.h>
20+#include <linux/of_address.h>
21+#include <linux/ioport.h>
22+#include <linux/regmap.h>
23+
24+#include <dt-bindings/clock/bt1-ccu.h>
25+
26+#include "ccu-pll.h"
27+
28+#define CCU_CPU_PLL_BASE 0x000
29+#define CCU_SATA_PLL_BASE 0x008
30+#define CCU_DDR_PLL_BASE 0x010
31+#define CCU_PCIE_PLL_BASE 0x018
32+#define CCU_ETH_PLL_BASE 0x020
33+
34+#define CCU_PLL_INFO(_id, _name, _pname, _base, _flags) \
35+ { \
36+ .id = _id, \
37+ .name = _name, \
38+ .parent_name = _pname, \
39+ .base = _base, \
40+ .flags = _flags \
41+ }
42+
43+#define CCU_PLL_NUM ARRAY_SIZE(pll_info)
44+
45+struct ccu_pll_info {
46+ unsigned int id;
47+ const char *name;
48+ const char *parent_name;
49+ unsigned int base;
50+ unsigned long flags;
51+};
52+
53+/*
54+ * Mark as critical all PLLs except Ethernet one. CPU and DDR PLLs are sources
55+ * of CPU cores and DDR controller reference clocks, due to which they
56+ * obviously shouldn't be ever gated. SATA and PCIe PLLs are the parents of
57+ * APB-bus and DDR controller AXI-bus clocks. If they are gated the system will
58+ * be unusable.
59+ */
60+static const struct ccu_pll_info pll_info[] = {
61+ CCU_PLL_INFO(CCU_CPU_PLL, "cpu_pll", "ref_clk", CCU_CPU_PLL_BASE,
62+ CLK_IS_CRITICAL),
63+ CCU_PLL_INFO(CCU_SATA_PLL, "sata_pll", "ref_clk", CCU_SATA_PLL_BASE,
64+ CLK_IS_CRITICAL | CLK_SET_RATE_GATE),
65+ CCU_PLL_INFO(CCU_DDR_PLL, "ddr_pll", "ref_clk", CCU_DDR_PLL_BASE,
66+ CLK_IS_CRITICAL | CLK_SET_RATE_GATE),
67+ CCU_PLL_INFO(CCU_PCIE_PLL, "pcie_pll", "ref_clk", CCU_PCIE_PLL_BASE,
68+ CLK_IS_CRITICAL),
69+ CCU_PLL_INFO(CCU_ETH_PLL, "eth_pll", "ref_clk", CCU_ETH_PLL_BASE,
70+ CLK_SET_RATE_GATE)
71+};
72+
73+struct ccu_pll_data {
74+ struct device_node *np;
75+ struct regmap *sys_regs;
76+ struct ccu_pll *plls[CCU_PLL_NUM];
77+};
78+
79+static struct ccu_pll *ccu_pll_find_desc(struct ccu_pll_data *data,
80+ unsigned int clk_id)
81+{
82+ struct ccu_pll *pll;
83+ int idx;
84+
85+ for (idx = 0; idx < CCU_PLL_NUM; ++idx) {
86+ pll = data->plls[idx];
87+ if (pll && pll->id == clk_id)
88+ return pll;
89+ }
90+
91+ return ERR_PTR(-EINVAL);
92+}
93+
94+static struct ccu_pll_data *ccu_pll_create_data(struct device_node *np)
95+{
96+ struct ccu_pll_data *data;
97+
98+ data = kzalloc(sizeof(*data), GFP_KERNEL);
99+ if (!data)
100+ return ERR_PTR(-ENOMEM);
101+
102+ data->np = np;
103+
104+ return data;
105+}
106+
107+static void ccu_pll_free_data(struct ccu_pll_data *data)
108+{
109+ kfree(data);
110+}
111+
112+static int ccu_pll_find_sys_regs(struct ccu_pll_data *data)
113+{
114+ data->sys_regs = syscon_node_to_regmap(data->np->parent);
115+ if (IS_ERR(data->sys_regs)) {
116+ pr_err("Failed to find syscon regs for '%s'\n",
117+ of_node_full_name(data->np));
118+ return PTR_ERR(data->sys_regs);
119+ }
120+
121+ return 0;
122+}
123+
124+static struct clk_hw *ccu_pll_of_clk_hw_get(struct of_phandle_args *clkspec,
125+ void *priv)
126+{
127+ struct ccu_pll_data *data = priv;
128+ struct ccu_pll *pll;
129+ unsigned int clk_id;
130+
131+ clk_id = clkspec->args[0];
132+ pll = ccu_pll_find_desc(data, clk_id);
133+ if (IS_ERR(pll)) {
134+ pr_info("Invalid PLL clock ID %d specified\n", clk_id);
135+ return ERR_CAST(pll);
136+ }
137+
138+ return ccu_pll_get_clk_hw(pll);
139+}
140+
141+static int ccu_pll_clk_register(struct ccu_pll_data *data)
142+{
143+ int idx, ret;
144+
145+ for (idx = 0; idx < CCU_PLL_NUM; ++idx) {
146+ const struct ccu_pll_info *info = &pll_info[idx];
147+ struct ccu_pll_init_data init = {0};
148+
149+ init.id = info->id;
150+ init.name = info->name;
151+ init.parent_name = info->parent_name;
152+ init.base = info->base;
153+ init.sys_regs = data->sys_regs;
154+ init.np = data->np;
155+ init.flags = info->flags;
156+
157+ data->plls[idx] = ccu_pll_hw_register(&init);
158+ if (IS_ERR(data->plls[idx])) {
159+ ret = PTR_ERR(data->plls[idx]);
160+ pr_err("Couldn't register PLL hw '%s'\n",
161+ init.name);
162+ goto err_hw_unregister;
163+ }
164+ }
165+
166+ ret = of_clk_add_hw_provider(data->np, ccu_pll_of_clk_hw_get, data);
167+ if (ret) {
168+ pr_err("Couldn't register PLL provider of '%s'\n",
169+ of_node_full_name(data->np));
170+ goto err_hw_unregister;
171+ }
172+
173+ return 0;
174+
175+err_hw_unregister:
176+ for (--idx; idx >= 0; --idx)
177+ ccu_pll_hw_unregister(data->plls[idx]);
178+
179+ return ret;
180+}
181+
182+static __init void ccu_pll_init(struct device_node *np)
183+{
184+ struct ccu_pll_data *data;
185+ int ret;
186+
187+ data = ccu_pll_create_data(np);
188+ if (IS_ERR(data))
189+ return;
190+
191+ ret = ccu_pll_find_sys_regs(data);
192+ if (ret)
193+ goto err_free_data;
194+
195+ ret = ccu_pll_clk_register(data);
196+ if (ret)
197+ goto err_free_data;
198+
199+ return;
200+
201+err_free_data:
202+ ccu_pll_free_data(data);
203+}
204+CLK_OF_DECLARE(ccu_pll, "baikal,bt1-ccu-pll", ccu_pll_init);
drivers/clk/bcm/clk-bcm2835.c+43−37
@@ -396,8 +396,8 @@ out: · 395 unmodified lines
396396 }
397397
398398 static void bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base,
399− struct debugfs_reg32 *regs, size_t nregs,
400− struct dentry *dentry)
399+ const struct debugfs_reg32 *regs,
400+ size_t nregs, struct dentry *dentry)
401401 {
402402 struct debugfs_regset32 *regset;
403403
@@ -1240,7 +1240,7 @@ static u8 bcm2835_clock_get_parent(struct clk_hw *hw) · 836 unmodified lines
12401240 return (src & CM_SRC_MASK) >> CM_SRC_SHIFT;
12411241 }
12421242
1243−static struct debugfs_reg32 bcm2835_debugfs_clock_reg32[] = {
1243+static const struct debugfs_reg32 bcm2835_debugfs_clock_reg32[] = {
12441244 {
12451245 .name = "ctl",
12461246 .offset = 0,
@@ -1296,8 +1296,9 @@ static const struct clk_ops bcm2835_vpu_clock_clk_ops = { · 49 unmodified lines
12961296 };
12971297
12981298 static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman,
1299− const struct bcm2835_pll_data *data)
1299+ const void *data)
13001300 {
1301+ const struct bcm2835_pll_data *pll_data = data;
13011302 struct bcm2835_pll *pll;
13021303 struct clk_init_data init;
13031304 int ret;
@@ -1307,7 +1308,7 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman, · 3 unmodified lines
13071308 /* All of the PLLs derive from the external oscillator. */
13081309 init.parent_names = &cprman->real_parent_names[0];
13091310 init.num_parents = 1;
1310− init.name = data->name;
1311+ init.name = pll_data->name;
13111312 init.ops = &bcm2835_pll_clk_ops;
13121313 init.flags = CLK_IGNORE_UNUSED;
13131314
@@ -1316,7 +1317,7 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman, · 2 unmodified lines
13161317 return NULL;
13171318
13181319 pll->cprman = cprman;
1319− pll->data = data;
1320+ pll->data = pll_data;
13201321 pll->hw.init = &init;
13211322
13221323 ret = devm_clk_hw_register(cprman->dev, &pll->hw);
@@ -1327,35 +1328,36 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman, · 4 unmodified lines
13271328
13281329 static struct clk_hw *
13291330 bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
1330− const struct bcm2835_pll_divider_data *data)
1331+ const void *data)
13311332 {
1333+ const struct bcm2835_pll_divider_data *divider_data = data;
13321334 struct bcm2835_pll_divider *divider;
13331335 struct clk_init_data init;
13341336 const char *divider_name;
13351337 int ret;
13361338
1337− if (data->fixed_divider != 1) {
1339+ if (divider_data->fixed_divider != 1) {
13381340 divider_name = devm_kasprintf(cprman->dev, GFP_KERNEL,
1339− "%s_prediv", data->name);
1341+ "%s_prediv", divider_data->name);
13401342 if (!divider_name)
13411343 return NULL;
13421344 } else {
1343− divider_name = data->name;
1345+ divider_name = divider_data->name;
13441346 }
13451347
13461348 memset(&init, 0, sizeof(init));
13471349
1348− init.parent_names = &data->source_pll;
1350+ init.parent_names = &divider_data->source_pll;
13491351 init.num_parents = 1;
13501352 init.name = divider_name;
13511353 init.ops = &bcm2835_pll_divider_clk_ops;
1352− init.flags = data->flags | CLK_IGNORE_UNUSED;
1354+ init.flags = divider_data->flags | CLK_IGNORE_UNUSED;
13531355
13541356 divider = devm_kzalloc(cprman->dev, sizeof(*divider), GFP_KERNEL);
13551357 if (!divider)
13561358 return NULL;
13571359
1358− divider->div.reg = cprman->regs + data->a2w_reg;
1360+ divider->div.reg = cprman->regs + divider_data->a2w_reg;
13591361 divider->div.shift = A2W_PLL_DIV_SHIFT;
13601362 divider->div.width = A2W_PLL_DIV_BITS;
13611363 divider->div.flags = CLK_DIVIDER_MAX_AT_ZERO;
@@ -1364,7 +1366,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman, · 2 unmodified lines
13641366 divider->div.table = NULL;
13651367
13661368 divider->cprman = cprman;
1367− divider->data = data;
1369+ divider->data = divider_data;
13681370
13691371 ret = devm_clk_hw_register(cprman->dev, &divider->div.hw);
13701372 if (ret)
@@ -1374,20 +1376,22 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman, · 3 unmodified lines
13741376 * PLLH's channels have a fixed divide by 10 afterwards, which
13751377 * is what our consumers are actually using.
13761378 */
1377− if (data->fixed_divider != 1) {
1378− return clk_hw_register_fixed_factor(cprman->dev, data->name,
1379+ if (divider_data->fixed_divider != 1) {
1380+ return clk_hw_register_fixed_factor(cprman->dev,
1381+ divider_data->name,
13791382 divider_name,
13801383 CLK_SET_RATE_PARENT,
13811384 1,
1382− data->fixed_divider);
1385+ divider_data->fixed_divider);
13831386 }
13841387
13851388 return &divider->div.hw;
13861389 }
13871390
13881391 static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman,
1389− const struct bcm2835_clock_data *data)
1392+ const void *data)
13901393 {
1394+ const struct bcm2835_clock_data *clock_data = data;
13911395 struct bcm2835_clock *clock;
13921396 struct clk_init_data init;
13931397 const char *parents[1 << CM_SRC_BITS];
@@ -1398,8 +1402,8 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman, · 4 unmodified lines
13981402 * Replace our strings referencing parent clocks with the
13991403 * actual clock-output-name of the parent.
14001404 */
1401− for (i = 0; i < data->num_mux_parents; i++) {
1402− parents[i] = data->parents[i];
1405+ for (i = 0; i < clock_data->num_mux_parents; i++) {
1406+ parents[i] = clock_data->parents[i];
14031407
14041408 ret = match_string(cprman_parent_names,
14051409 ARRAY_SIZE(cprman_parent_names),
@@ -1410,18 +1414,18 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman, · 4 unmodified lines
14101414
14111415 memset(&init, 0, sizeof(init));
14121416 init.parent_names = parents;
1413− init.num_parents = data->num_mux_parents;
1414− init.name = data->name;
1415− init.flags = data->flags | CLK_IGNORE_UNUSED;
1417+ init.num_parents = clock_data->num_mux_parents;
1418+ init.name = clock_data->name;
1419+ init.flags = clock_data->flags | CLK_IGNORE_UNUSED;
14161420
14171421 /*
14181422 * Pass the CLK_SET_RATE_PARENT flag if we are allowed to propagate
14191423 * rate changes on at least of the parents.
14201424 */
1421− if (data->set_rate_parent)
1425+ if (clock_data->set_rate_parent)
14221426 init.flags |= CLK_SET_RATE_PARENT;
14231427
1424− if (data->is_vpu_clock) {
1428+ if (clock_data->is_vpu_clock) {
14251429 init.ops = &bcm2835_vpu_clock_clk_ops;
14261430 } else {
14271431 init.ops = &bcm2835_clock_clk_ops;
@@ -1430,7 +1434,7 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman, · 2 unmodified lines
14301434 /* If the clock wasn't actually enabled at boot, it's not
14311435 * critical.
14321436 */
1433− if (!(cprman_read(cprman, data->ctl_reg) & CM_ENABLE))
1437+ if (!(cprman_read(cprman, clock_data->ctl_reg) & CM_ENABLE))
14341438 init.flags &= ~CLK_IS_CRITICAL;
14351439 }
14361440
@@ -1439,7 +1443,7 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman, · 2 unmodified lines
14391443 return NULL;
14401444
14411445 clock->cprman = cprman;
1442− clock->data = data;
1446+ clock->data = clock_data;
14431447 clock->hw.init = &init;
14441448
14451449 ret = devm_clk_hw_register(cprman->dev, &clock->hw);
@@ -1448,25 +1452,27 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman, · 2 unmodified lines
14481452 return &clock->hw;
14491453 }
14501454
1451−static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman,
1452− const struct bcm2835_gate_data *data)
1455+static struct clk_hw *bcm2835_register_gate(struct bcm2835_cprman *cprman,
1456+ const void *data)
14531457 {
1454− return clk_register_gate(cprman->dev, data->name, data->parent,
1455− CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
1456− cprman->regs + data->ctl_reg,
1457− CM_GATE_BIT, 0, &cprman->regs_lock);
1458+ const struct bcm2835_gate_data *gate_data = data;
1459+
1460+ return clk_hw_register_gate(cprman->dev, gate_data->name,
1461+ gate_data->parent,
1462+ CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
1463+ cprman->regs + gate_data->ctl_reg,
1464+ CM_GATE_BIT, 0, &cprman->regs_lock);
14581465 }
14591466
1460−typedef struct clk_hw *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman,
1461− const void *data);
14621467 struct bcm2835_clk_desc {
1463− bcm2835_clk_register clk_register;
1468+ struct clk_hw *(*clk_register)(struct bcm2835_cprman *cprman,
1469+ const void *data);
14641470 unsigned int supported;
14651471 const void *data;
14661472 };
14671473
14681474 /* assignment helper macros for different clock types */
1469−#define _REGISTER(f, s, ...) { .clk_register = (bcm2835_clk_register)f, \
1475+#define _REGISTER(f, s, ...) { .clk_register = f, \
14701476 .supported = s, \
14711477 .data = __VA_ARGS__ }
14721478 #define REGISTER_PLL(s, ...) _REGISTER(&bcm2835_register_pll, \
drivers/clk/clk-ast2600.c+25−6
@@ -642,14 +642,22 @@ static const u32 ast2600_a0_axi_ahb_div_table[] = { · 641 unmodified lines
642642 2, 2, 3, 5,
643643 };
644644
645−static const u32 ast2600_a1_axi_ahb_div_table[] = {
646− 4, 6, 2, 4,
645+static const u32 ast2600_a1_axi_ahb_div0_tbl[] = {
646+ 3, 2, 3, 4,
647+};
648+
649+static const u32 ast2600_a1_axi_ahb_div1_tbl[] = {
650+ 3, 4, 6, 8,
651+};
652+
653+static const u32 ast2600_a1_axi_ahb200_tbl[] = {
654+ 3, 4, 3, 4, 2, 2, 2, 2,
647655 };
648656
649657 static void __init aspeed_g6_cc(struct regmap *map)
650658 {
651659 struct clk_hw *hw;
652− u32 val, div, chip_id, axi_div, ahb_div;
660+ u32 val, div, divbits, chip_id, axi_div, ahb_div;
653661
654662 clk_hw_register_fixed_rate(NULL, "clkin", NULL, 0, 25000000);
655663
@@ -679,11 +687,22 @@ static void __init aspeed_g6_cc(struct regmap *map) · 23 unmodified lines
679687 else
680688 axi_div = 2;
681689
690+ divbits = (val >> 11) & 0x3;
682691 regmap_read(map, ASPEED_G6_SILICON_REV, &chip_id);
683− if (chip_id & BIT(16))
684− ahb_div = ast2600_a1_axi_ahb_div_table[(val >> 11) & 0x3];
685− else
692+ if (chip_id & BIT(16)) {
693+ if (!divbits) {
694+ ahb_div = ast2600_a1_axi_ahb200_tbl[(val >> 8) & 0x3];
695+ if (val & BIT(16))
696+ ahb_div *= 2;
697+ } else {
698+ if (val & BIT(16))
699+ ahb_div = ast2600_a1_axi_ahb_div1_tbl[divbits];
700+ else
701+ ahb_div = ast2600_a1_axi_ahb_div0_tbl[divbits];
702+ }
703+ } else {
686704 ahb_div = ast2600_a0_axi_ahb_div_table[(val >> 11) & 0x3];
705+ }
687706
688707 hw = clk_hw_register_fixed_factor(NULL, "ahb", "hpll", 0, 1, axi_div * ahb_div);
689708 aspeed_g6_clk_data->hws[ASPEED_CLK_AHB] = hw;
drivers/clk/clk-hsdk-pll.c+39−31
@@ -53,35 +53,38 @@ struct hsdk_pll_cfg { · 52 unmodified lines
5353 u32 fbdiv;
5454 u32 odiv;
5555 u32 band;
56+ u32 bypass;
5657 };
5758
5859 static const struct hsdk_pll_cfg asdt_pll_cfg[] = {
59− { 100000000, 0, 11, 3, 0 },
60− { 133000000, 0, 15, 3, 0 },
61− { 200000000, 1, 47, 3, 0 },
62− { 233000000, 1, 27, 2, 0 },
63− { 300000000, 1, 35, 2, 0 },
64− { 333000000, 1, 39, 2, 0 },
65− { 400000000, 1, 47, 2, 0 },
66− { 500000000, 0, 14, 1, 0 },
67− { 600000000, 0, 17, 1, 0 },
68− { 700000000, 0, 20, 1, 0 },
69− { 800000000, 0, 23, 1, 0 },
70− { 900000000, 1, 26, 0, 0 },
71− { 1000000000, 1, 29, 0, 0 },
72− { 1100000000, 1, 32, 0, 0 },
73− { 1200000000, 1, 35, 0, 0 },
74− { 1300000000, 1, 38, 0, 0 },
75− { 1400000000, 1, 41, 0, 0 },
76− { 1500000000, 1, 44, 0, 0 },
77− { 1600000000, 1, 47, 0, 0 },
60+ { 100000000, 0, 11, 3, 0, 0 },
61+ { 133000000, 0, 15, 3, 0, 0 },
62+ { 200000000, 1, 47, 3, 0, 0 },
63+ { 233000000, 1, 27, 2, 0, 0 },
64+ { 300000000, 1, 35, 2, 0, 0 },
65+ { 333000000, 1, 39, 2, 0, 0 },
66+ { 400000000, 1, 47, 2, 0, 0 },
67+ { 500000000, 0, 14, 1, 0, 0 },
68+ { 600000000, 0, 17, 1, 0, 0 },
69+ { 700000000, 0, 20, 1, 0, 0 },
70+ { 800000000, 0, 23, 1, 0, 0 },
71+ { 900000000, 1, 26, 0, 0, 0 },
72+ { 1000000000, 1, 29, 0, 0, 0 },
73+ { 1100000000, 1, 32, 0, 0, 0 },
74+ { 1200000000, 1, 35, 0, 0, 0 },
75+ { 1300000000, 1, 38, 0, 0, 0 },
76+ { 1400000000, 1, 41, 0, 0, 0 },
77+ { 1500000000, 1, 44, 0, 0, 0 },
78+ { 1600000000, 1, 47, 0, 0, 0 },
7879 {}
7980 };
8081
8182 static const struct hsdk_pll_cfg hdmi_pll_cfg[] = {
82− { 297000000, 0, 21, 2, 0 },
83− { 540000000, 0, 19, 1, 0 },
84− { 594000000, 0, 21, 1, 0 },
83+ { 27000000, 0, 0, 0, 0, 1 },
84+ { 148500000, 0, 21, 3, 0, 0 },
85+ { 297000000, 0, 21, 2, 0, 0 },
86+ { 540000000, 0, 19, 1, 0, 0 },
87+ { 594000000, 0, 21, 1, 0, 0 },
8588 {}
8689 };
8790
@@ -134,11 +137,16 @@ static inline void hsdk_pll_set_cfg(struct hsdk_pll_clk *clk, · 46 unmodified lines
134137 {
135138 u32 val = 0;
136139
137− /* Powerdown and Bypass bits should be cleared */
138− val |= cfg->idiv << CGU_PLL_CTRL_IDIV_SHIFT;
139− val |= cfg->fbdiv << CGU_PLL_CTRL_FBDIV_SHIFT;
140− val |= cfg->odiv << CGU_PLL_CTRL_ODIV_SHIFT;
141− val |= cfg->band << CGU_PLL_CTRL_BAND_SHIFT;
140+ if (cfg->bypass) {
141+ val = hsdk_pll_read(clk, CGU_PLL_CTRL);
142+ val |= CGU_PLL_CTRL_BYPASS;
143+ } else {
144+ /* Powerdown and Bypass bits should be cleared */
145+ val |= cfg->idiv << CGU_PLL_CTRL_IDIV_SHIFT;
146+ val |= cfg->fbdiv << CGU_PLL_CTRL_FBDIV_SHIFT;
147+ val |= cfg->odiv << CGU_PLL_CTRL_ODIV_SHIFT;
148+ val |= cfg->band << CGU_PLL_CTRL_BAND_SHIFT;
149+ }
142150
143151 dev_dbg(clk->dev, "write configuration: %#x\n", val);
144152
@@ -172,14 +180,14 @@ static unsigned long hsdk_pll_recalc_rate(struct clk_hw *hw, · 27 unmodified lines
172180
173181 dev_dbg(clk->dev, "current configuration: %#x\n", val);
174182
175− /* Check if PLL is disabled */
176− if (val & CGU_PLL_CTRL_PD)
177− return 0;
178−
179183 /* Check if PLL is bypassed */
180184 if (val & CGU_PLL_CTRL_BYPASS)
181185 return parent_rate;
182186
187+ /* Check if PLL is disabled */
188+ if (val & CGU_PLL_CTRL_PD)
189+ return 0;
190+
183191 /* input divider = reg.idiv + 1 */
184192 idiv = 1 + ((val & CGU_PLL_CTRL_IDIV_MASK) >> CGU_PLL_CTRL_IDIV_SHIFT);
185193 /* fb divider = 2*(reg.fbdiv + 1) */
drivers/clk/clk-si5341.c+64−5
@@ -1,8 +1,14 @@
11 // SPDX-License-Identifier: GPL-2.0
22 /*
3− * Driver for Silicon Labs Si5341/Si5340 Clock generator
3+ * Driver for Silicon Labs Si5340, Si5341, Si5342, Si5344 and Si5345
44 * Copyright (C) 2019 Topic Embedded Products
55 * Author: Mike Looijmans <mike.looijmans@topic.nl>
6+ *
7+ * The Si5341 has 10 outputs and 5 synthesizers.
8+ * The Si5340 is a smaller version of the Si5341 with only 4 outputs.
9+ * The Si5345 is similar to the Si5341, with the addition of fractional input
10+ * dividers and automatic input selection.
11+ * The Si5342 and Si5344 are smaller versions of the Si5345.
612 */
713
814 #include <linux/clk.h>
@@ -18,11 +24,17 @@ · 9 unmodified lines
1824
1925 #define SI5341_NUM_INPUTS 4
2026
21−#define SI5341_MAX_NUM_OUTPUTS 10
2227 #define SI5340_MAX_NUM_OUTPUTS 4
28+#define SI5341_MAX_NUM_OUTPUTS 10
29+#define SI5342_MAX_NUM_OUTPUTS 2
30+#define SI5344_MAX_NUM_OUTPUTS 4
31+#define SI5345_MAX_NUM_OUTPUTS 10
2332
24−#define SI5341_NUM_SYNTH 5
2533 #define SI5340_NUM_SYNTH 4
34+#define SI5341_NUM_SYNTH 5
35+#define SI5342_NUM_SYNTH 2
36+#define SI5344_NUM_SYNTH 4
37+#define SI5345_NUM_SYNTH 5
2638
2739 /* Range of the synthesizer fractional divider */
2840 #define SI5341_SYNTH_N_MIN 10
@@ -65,6 +77,7 @@ struct clk_si5341 { · 36 unmodified lines
6577 u64 freq_vco; /* 13500–14256 MHz */
6678 u8 num_outputs;
6779 u8 num_synth;
80+ u16 chip_id;
6881 };
6982 #define to_clk_si5341(_hw) container_of(_hw, struct clk_si5341, hw)
7083
@@ -142,6 +155,7 @@ static const char * const si5341_input_clock_names[] = { · 71 unmodified lines
142155 };
143156
144157 /* Output configuration registers 0..9 are not quite logically organized */
158+/* Also for si5345 */
145159 static const u16 si5341_reg_output_offset[] = {
146160 0x0108,
147161 0x010D,
@@ -155,6 +169,7 @@ static const u16 si5341_reg_output_offset[] = { · 7 unmodified lines
155169 0x013A,
156170 };
157171
172+/* for si5340, si5342 and si5344 */
158173 static const u16 si5340_reg_output_offset[] = {
159174 0x0112,
160175 0x0117,
@@ -974,12 +989,32 @@ static int si5341_probe_chip_id(struct clk_si5341 *data) · 813 unmodified lines
974989 data->reg_output_offset = si5341_reg_output_offset;
975990 data->reg_rdiv_offset = si5341_reg_rdiv_offset;
976991 break;
992+ case 0x5342:
993+ data->num_outputs = SI5342_MAX_NUM_OUTPUTS;
994+ data->num_synth = SI5342_NUM_SYNTH;
995+ data->reg_output_offset = si5340_reg_output_offset;
996+ data->reg_rdiv_offset = si5340_reg_rdiv_offset;
997+ break;
998+ case 0x5344:
999+ data->num_outputs = SI5344_MAX_NUM_OUTPUTS;
1000+ data->num_synth = SI5344_NUM_SYNTH;
1001+ data->reg_output_offset = si5340_reg_output_offset;
1002+ data->reg_rdiv_offset = si5340_reg_rdiv_offset;
1003+ break;
1004+ case 0x5345:
1005+ data->num_outputs = SI5345_MAX_NUM_OUTPUTS;
1006+ data->num_synth = SI5345_NUM_SYNTH;
1007+ data->reg_output_offset = si5341_reg_output_offset;
1008+ data->reg_rdiv_offset = si5341_reg_rdiv_offset;
1009+ break;
9771010 default:
9781011 dev_err(&data->i2c_client->dev, "Model '%x' not supported\n",
9791012 model);
9801013 return -EINVAL;
9811014 }
9821015
1016+ data->chip_id = model;
1017+
9831018 return 0;
9841019 }
9851020
@@ -1054,6 +1089,11 @@ static const struct si5341_reg_default si5341_preamble[] = { · 68 unmodified lines
10541089 { 0x0B4E, 0x1A },
10551090 };
10561091
1092+static const struct si5341_reg_default si5345_preamble[] = {
1093+ { 0x0B25, 0x00 },
1094+ { 0x0540, 0x01 },
1095+};
1096+
10571097 static int si5341_send_preamble(struct clk_si5341 *data)
10581098 {
10591099 int res;
@@ -1068,8 +1108,14 @@ static int si5341_send_preamble(struct clk_si5341 *data) · 8 unmodified lines
10681108 res = regmap_write(data->regmap, 0xB24, revision < 2 ? 0xD8 : 0xC0);
10691109 if (res < 0)
10701110 return res;
1071− res = si5341_write_multiple(data,
1072− si5341_preamble, ARRAY_SIZE(si5341_preamble));
1111+
1112+ /* The si5342..si5345 require a different preamble */
1113+ if (data->chip_id > 0x5341)
1114+ res = si5341_write_multiple(data,
1115+ si5345_preamble, ARRAY_SIZE(si5345_preamble));
1116+ else
1117+ res = si5341_write_multiple(data,
1118+ si5341_preamble, ARRAY_SIZE(si5341_preamble));
10731119 if (res < 0)
10741120 return res;
10751121
@@ -1095,6 +1141,13 @@ static int si5341_finalize_defaults(struct clk_si5341 *data) · 19 unmodified lines
10951141 if (res < 0)
10961142 return res;
10971143
1144+ /* The si5342..si5345 have an additional post-amble */
1145+ if (data->chip_id > 0x5341) {
1146+ res = regmap_write(data->regmap, 0x540, 0x0);
1147+ if (res < 0)
1148+ return res;
1149+ }
1150+
10981151 /* Datasheet does not explain these nameless registers */
10991152 res = regmap_write(data->regmap, 0xB24, revision < 2 ? 0xDB : 0xC3);
11001153 if (res < 0)
@@ -1499,6 +1552,9 @@ static int si5341_probe(struct i2c_client *client, · 398 unmodified lines
14991552 static const struct i2c_device_id si5341_id[] = {
15001553 { "si5340", 0 },
15011554 { "si5341", 1 },
1555+ { "si5342", 2 },
1556+ { "si5344", 4 },
1557+ { "si5345", 5 },
15021558 { }
15031559 };
15041560 MODULE_DEVICE_TABLE(i2c, si5341_id);
@@ -1506,6 +1562,9 @@ MODULE_DEVICE_TABLE(i2c, si5341_id); · 1 unmodified line
15061562 static const struct of_device_id clk_si5341_of_match[] = {
15071563 { .compatible = "silabs,si5340" },
15081564 { .compatible = "silabs,si5341" },
1565+ { .compatible = "silabs,si5342" },
1566+ { .compatible = "silabs,si5344" },
1567+ { .compatible = "silabs,si5345" },
15091568 { }
15101569 };
15111570 MODULE_DEVICE_TABLE(of, clk_si5341_of_match);
drivers/clk/clk-versaclock5.c+11−0
@@ -124,6 +124,7 @@ enum vc5_model { · 123 unmodified lines
124124 IDT_VC5_5P49V5933,
125125 IDT_VC5_5P49V5935,
126126 IDT_VC6_5P49V6901,
127+ IDT_VC6_5P49V6965,
127128 };
128129
129130 /* Structure to describe features of a particular VC5 model */
@@ -683,6 +684,7 @@ static int vc5_map_index_to_output(const enum vc5_model model, · 553 unmodified lines
683684 case IDT_VC5_5P49V5925:
684685 case IDT_VC5_5P49V5935:
685686 case IDT_VC6_5P49V6901:
687+ case IDT_VC6_5P49V6965:
686688 default:
687689 return n;
688690 }
@@ -956,12 +958,20 @@ static const struct vc5_chip_info idt_5p49v6901_info = { · 267 unmodified lines
956958 .flags = VC5_HAS_PFD_FREQ_DBL,
957959 };
958960
961+static const struct vc5_chip_info idt_5p49v6965_info = {
962+ .model = IDT_VC6_5P49V6965,
963+ .clk_fod_cnt = 4,
964+ .clk_out_cnt = 5,
965+ .flags = 0,
966+};
967+
959968 static const struct i2c_device_id vc5_id[] = {
960969 { "5p49v5923", .driver_data = IDT_VC5_5P49V5923 },
961970 { "5p49v5925", .driver_data = IDT_VC5_5P49V5925 },
962971 { "5p49v5933", .driver_data = IDT_VC5_5P49V5933 },
963972 { "5p49v5935", .driver_data = IDT_VC5_5P49V5935 },
964973 { "5p49v6901", .driver_data = IDT_VC6_5P49V6901 },
974+ { "5p49v6965", .driver_data = IDT_VC6_5P49V6965 },
965975 { }
966976 };
967977 MODULE_DEVICE_TABLE(i2c, vc5_id);
@@ -972,6 +982,7 @@ static const struct of_device_id clk_vc5_of_match[] = { · 4 unmodified lines
972982 { .compatible = "idt,5p49v5933", .data = &idt_5p49v5933_info },
973983 { .compatible = "idt,5p49v5935", .data = &idt_5p49v5935_info },
974984 { .compatible = "idt,5p49v6901", .data = &idt_5p49v6901_info },
985+ { .compatible = "idt,5p49v6965", .data = &idt_5p49v6965_info },
975986 { },
976987 };
977988 MODULE_DEVICE_TABLE(of, clk_vc5_of_match);
drivers/clk/clk.c+0−4
@@ -3299,10 +3299,6 @@ static int __init clk_debug_init(void) · 3298 unmodified lines
32993299 late_initcall(clk_debug_init);
33003300 #else
33013301 static inline void clk_debug_register(struct clk_core *core) { }
3302−static inline void clk_debug_reparent(struct clk_core *core,
3303− struct clk_core *new_parent)
3304−{
3305−}
33063302 static inline void clk_debug_unregister(struct clk_core *core)
33073303 {
33083304 }
drivers/clk/imx/Kconfig+4−4
@@ -10,25 +10,25 @@ config MXC_CLK_SCU · 9 unmodified lines
1010
1111 config CLK_IMX8MM
1212 bool "IMX8MM CCM Clock Driver"
13− depends on ARCH_MXC && ARM64
13+ depends on ARCH_MXC
1414 help
1515 Build the driver for i.MX8MM CCM Clock Driver
1616
1717 config CLK_IMX8MN
1818 bool "IMX8MN CCM Clock Driver"
19− depends on ARCH_MXC && ARM64
19+ depends on ARCH_MXC
2020 help
2121 Build the driver for i.MX8MN CCM Clock Driver
2222
2323 config CLK_IMX8MP
2424 bool "IMX8MP CCM Clock Driver"
25− depends on ARCH_MXC && ARM64
25+ depends on ARCH_MXC
2626 help
2727 Build the driver for i.MX8MP CCM Clock Driver
2828
2929 config CLK_IMX8MQ
3030 bool "IMX8MQ CCM Clock Driver"
31− depends on ARCH_MXC && ARM64
31+ depends on ARCH_MXC
3232 help
3333 Build the driver for i.MX8MQ CCM Clock Driver
3434
drivers/clk/imx/clk-composite-8m.c+55−1
@@ -124,6 +124,52 @@ static const struct clk_ops imx8m_clk_composite_divider_ops = { · 123 unmodified lines
124124 .set_rate = imx8m_clk_composite_divider_set_rate,
125125 };
126126
127+static u8 imx8m_clk_composite_mux_get_parent(struct clk_hw *hw)
128+{
129+ return clk_mux_ops.get_parent(hw);
130+}
131+
132+static int imx8m_clk_composite_mux_set_parent(struct clk_hw *hw, u8 index)
133+{
134+ struct clk_mux *mux = to_clk_mux(hw);
135+ u32 val = clk_mux_index_to_val(mux->table, mux->flags, index);
136+ unsigned long flags = 0;
137+ u32 reg;
138+
139+ if (mux->lock)
140+ spin_lock_irqsave(mux->lock, flags);
141+
142+ reg = readl(mux->reg);
143+ reg &= ~(mux->mask << mux->shift);
144+ val = val << mux->shift;
145+ reg |= val;
146+ /*
147+ * write twice to make sure non-target interface
148+ * SEL_A/B point the same clk input.
149+ */
150+ writel(reg, mux->reg);
151+ writel(reg, mux->reg);
152+
153+ if (mux->lock)
154+ spin_unlock_irqrestore(mux->lock, flags);
155+
156+ return 0;
157+}
158+
159+static int
160+imx8m_clk_composite_mux_determine_rate(struct clk_hw *hw,
161+ struct clk_rate_request *req)
162+{
163+ return clk_mux_ops.determine_rate(hw, req);
164+}
165+
166+
167+static const struct clk_ops imx8m_clk_composite_mux_ops = {
168+ .get_parent = imx8m_clk_composite_mux_get_parent,
169+ .set_parent = imx8m_clk_composite_mux_set_parent,
170+ .determine_rate = imx8m_clk_composite_mux_determine_rate,
171+};
172+
127173 struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
128174 const char * const *parent_names,
129175 int num_parents, void __iomem *reg,
@@ -136,6 +182,7 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, · 6 unmodified lines
136182 struct clk_gate *gate = NULL;
137183 struct clk_mux *mux = NULL;
138184 const struct clk_ops *divider_ops;
185+ const struct clk_ops *mux_ops;
139186
140187 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
141188 if (!mux)
@@ -157,10 +204,17 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, · 15 unmodified lines
157204 div->shift = PCG_DIV_SHIFT;
158205 div->width = PCG_CORE_DIV_WIDTH;
159206 divider_ops = &clk_divider_ops;
207+ mux_ops = &imx8m_clk_composite_mux_ops;
208+ } else if (composite_flags & IMX_COMPOSITE_BUS) {
209+ div->shift = PCG_PREDIV_SHIFT;
210+ div->width = PCG_PREDIV_WIDTH;
211+ divider_ops = &imx8m_clk_composite_divider_ops;
212+ mux_ops = &imx8m_clk_composite_mux_ops;
160213 } else {
161214 div->shift = PCG_PREDIV_SHIFT;
162215 div->width = PCG_PREDIV_WIDTH;
163216 divider_ops = &imx8m_clk_composite_divider_ops;
217+ mux_ops = &clk_mux_ops;
164218 }
165219
166220 div->lock = &imx_ccm_lock;
@@ -176,7 +230,7 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, · 9 unmodified lines
176230 gate->lock = &imx_ccm_lock;
177231
178232 hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
179− mux_hw, &clk_mux_ops, div_hw,
233+ mux_hw, mux_ops, div_hw,
180234 divider_ops, gate_hw, &clk_gate_ops, flags);
181235 if (IS_ERR(hw))
182236 goto fail;
drivers/clk/imx/clk-gate2.c+23−8
@@ -41,21 +41,26 @@ static int clk_gate2_enable(struct clk_hw *hw) · 40 unmodified lines
4141 struct clk_gate2 *gate = to_clk_gate2(hw);
4242 u32 reg;
4343 unsigned long flags;
44+ int ret = 0;
4445
4546 spin_lock_irqsave(gate->lock, flags);
4647
4748 if (gate->share_count && (*gate->share_count)++ > 0)
4849 goto out;
4950
50− reg = readl(gate->reg);
51− reg &= ~(3 << gate->bit_idx);
52− reg |= gate->cgr_val << gate->bit_idx;
53− writel(reg, gate->reg);
51+ if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT) {
52+ ret = clk_gate_ops.enable(hw);
53+ } else {
54+ reg = readl(gate->reg);
55+ reg &= ~(3 << gate->bit_idx);
56+ reg |= gate->cgr_val << gate->bit_idx;
57+ writel(reg, gate->reg);
58+ }
5459
5560 out:
5661 spin_unlock_irqrestore(gate->lock, flags);
5762
58− return 0;
63+ return ret;
5964 }
6065
6166 static void clk_gate2_disable(struct clk_hw *hw)
@@ -73,9 +78,13 @@ static void clk_gate2_disable(struct clk_hw *hw) · 11 unmodified lines
7378 goto out;
7479 }
7580
76− reg = readl(gate->reg);
77− reg &= ~(3 << gate->bit_idx);
78− writel(reg, gate->reg);
81+ if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT) {
82+ clk_gate_ops.disable(hw);
83+ } else {
84+ reg = readl(gate->reg);
85+ reg &= ~(3 << gate->bit_idx);
86+ writel(reg, gate->reg);
87+ }
7988
8089 out:
8190 spin_unlock_irqrestore(gate->lock, flags);
@@ -95,6 +104,9 @@ static int clk_gate2_is_enabled(struct clk_hw *hw) · 13 unmodified lines
95104 {
96105 struct clk_gate2 *gate = to_clk_gate2(hw);
97106
107+ if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT)
108+ return clk_gate_ops.is_enabled(hw);
109+
98110 return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx);
99111 }
100112
@@ -104,6 +116,9 @@ static void clk_gate2_disable_unused(struct clk_hw *hw) · 3 unmodified lines
104116 unsigned long flags;
105117 u32 reg;
106118
119+ if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT)
120+ return;
121+
107122 spin_lock_irqsave(gate->lock, flags);
108123
109124 if (!gate->share_count || *gate->share_count == 0) {
drivers/clk/imx/clk-imx6ul.c+1−1
@@ -503,7 +503,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) · 502 unmodified lines
503503 clk_prepare_enable(hws[IMX6UL_CLK_USBPHY2_GATE]->clk);
504504 }
505505
506− clk_set_parent(hws[IMX6UL_CLK_CAN_SEL]->clk, hws[IMX6UL_CLK_PLL3_60M]->clk);
506+ clk_set_parent(hws[IMX6UL_CLK_CAN_SEL]->clk, hws[IMX6UL_CLK_PLL3_80M]->clk);
507507 if (clk_on_imx6ul())
508508 clk_set_parent(hws[IMX6UL_CLK_SIM_PRE_SEL]->clk, hws[IMX6UL_CLK_PLL3_USB_OTG]->clk);
509509 else if (clk_on_imx6ull())
drivers/clk/imx/clk-imx7ulp.c+4−2
@@ -29,7 +29,7 @@ static const char * const ddr_sels[] = { "apll_pfd_sel", "dummy", "dummy", "dum · 28 unmodified lines
2929 static const char * const nic_sels[] = { "firc", "ddr_clk", };
3030 static const char * const periph_plat_sels[] = { "dummy", "nic1_bus_clk", "nic1_clk", "ddr_clk", "apll_pfd2", "apll_pfd1", "apll_pfd0", "upll", };
3131 static const char * const periph_bus_sels[] = { "dummy", "sosc_bus_clk", "dummy", "firc_bus_clk", "rosc", "nic1_bus_clk", "nic1_clk", "spll_bus_clk", };
32−static const char * const arm_sels[] = { "divcore", "dummy", "dummy", "hsrun_divcore", };
32+static const char * const arm_sels[] = { "core", "dummy", "dummy", "hsrun_core", };
3333
3434 /* used by sosc/sirc/firc/ddr/spll/apll dividers */
3535 static const struct clk_div_table ulp_div_table[] = {
@@ -121,7 +121,9 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np) · 85 unmodified lines
121121 hws[IMX7ULP_CLK_DDR_SEL] = imx_clk_hw_mux_flags("ddr_sel", base + 0x30, 24, 2, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
122122
123123 hws[IMX7ULP_CLK_CORE_DIV] = imx_clk_hw_divider_flags("divcore", "scs_sel", base + 0x14, 16, 4, CLK_SET_RATE_PARENT);
124+ hws[IMX7ULP_CLK_CORE] = imx_clk_hw_cpu("core", "divcore", hws[IMX7ULP_CLK_CORE_DIV]->clk, hws[IMX7ULP_CLK_SYS_SEL]->clk, hws[IMX7ULP_CLK_SPLL_SEL]->clk, hws[IMX7ULP_CLK_FIRC]->clk);
124125 hws[IMX7ULP_CLK_HSRUN_CORE_DIV] = imx_clk_hw_divider_flags("hsrun_divcore", "hsrun_scs_sel", base + 0x1c, 16, 4, CLK_SET_RATE_PARENT);
126+ hws[IMX7ULP_CLK_HSRUN_CORE] = imx_clk_hw_cpu("hsrun_core", "hsrun_divcore", hws[IMX7ULP_CLK_HSRUN_CORE_DIV]->clk, hws[IMX7ULP_CLK_HSRUN_SYS_SEL]->clk, hws[IMX7ULP_CLK_SPLL_SEL]->clk, hws[IMX7ULP_CLK_FIRC]->clk);
125127
126128 hws[IMX7ULP_CLK_DDR_DIV] = imx_clk_hw_divider_gate("ddr_clk", "ddr_sel", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, base + 0x30, 0, 3,
127129 0, ulp_div_table, &imx_ccm_lock);
@@ -270,7 +272,7 @@ static void __init imx7ulp_clk_smc1_init(struct device_node *np) · 142 unmodified lines
270272 base = of_iomap(np, 0);
271273 WARN_ON(!base);
272274
273− hws[IMX7ULP_CLK_ARM] = imx_clk_hw_mux_flags("arm", base + 0x10, 8, 2, arm_sels, ARRAY_SIZE(arm_sels), CLK_IS_CRITICAL);
275+ hws[IMX7ULP_CLK_ARM] = imx_clk_hw_mux_flags("arm", base + 0x10, 8, 2, arm_sels, ARRAY_SIZE(arm_sels), CLK_SET_RATE_PARENT);
274276
275277 imx_check_clk_hws(hws, clk_data->num);
276278
drivers/clk/imx/clk-imx8mm.c+12−15
@@ -416,9 +416,9 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) · 415 unmodified lines
416416 return PTR_ERR(base);
417417
418418 /* Core Slice */
419− hws[IMX8MM_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels));
420− hws[IMX8MM_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
421− hws[IMX8MM_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
419+ hws[IMX8MM_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mm_a53_sels, base + 0x8000);
420+ hws[IMX8MM_CLK_A53_CG] = hws[IMX8MM_CLK_A53_DIV];
421+ hws[IMX8MM_CLK_A53_SRC] = hws[IMX8MM_CLK_A53_DIV];
422422
423423 hws[IMX8MM_CLK_M4_CORE] = imx8m_clk_hw_composite_core("arm_m4_core", imx8mm_m4_sels, base + 0x8080);
424424 hws[IMX8MM_CLK_VPU_CORE] = imx8m_clk_hw_composite_core("vpu_core", imx8mm_vpu_sels, base + 0x8100);
@@ -444,21 +444,21 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) · 19 unmodified lines
444444
445445 /* BUS */
446446 hws[IMX8MM_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mm_main_axi_sels, base + 0x8800);
447− hws[IMX8MM_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mm_enet_axi_sels, base + 0x8880);
447+ hws[IMX8MM_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mm_enet_axi_sels, base + 0x8880);
448448 hws[IMX8MM_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900);
449− hws[IMX8MM_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980);
450− hws[IMX8MM_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00);
451− hws[IMX8MM_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80);
452− hws[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_hw_composite("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00);
453− hws[IMX8MM_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80);
454− hws[IMX8MM_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00);
455− hws[IMX8MM_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80);
449+ hws[IMX8MM_CLK_VPU_BUS] = imx8m_clk_hw_composite_bus("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980);
450+ hws[IMX8MM_CLK_DISP_AXI] = imx8m_clk_hw_composite_bus("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00);
451+ hws[IMX8MM_CLK_DISP_APB] = imx8m_clk_hw_composite_bus("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80);
452+ hws[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_hw_composite_bus("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00);
453+ hws[IMX8MM_CLK_USB_BUS] = imx8m_clk_hw_composite_bus("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80);
454+ hws[IMX8MM_CLK_GPU_AXI] = imx8m_clk_hw_composite_bus("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00);
455+ hws[IMX8MM_CLK_GPU_AHB] = imx8m_clk_hw_composite_bus("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80);
456456 hws[IMX8MM_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mm_noc_sels, base + 0x8d00);
457457 hws[IMX8MM_CLK_NOC_APB] = imx8m_clk_hw_composite_critical("noc_apb", imx8mm_noc_apb_sels, base + 0x8d80);
458458
459459 /* AHB */
460460 hws[IMX8MM_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mm_ahb_sels, base + 0x9000);
461− hws[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100);
461+ hws[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100);
462462
463463 /* IPG */
464464 hws[IMX8MM_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
@@ -614,9 +614,6 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) · 149 unmodified lines
614614 hws[IMX8MM_ARM_PLL_OUT]->clk,
615615 hws[IMX8MM_CLK_A53_DIV]->clk);
616616
617− clk_hw_set_parent(hws[IMX8MM_CLK_A53_SRC], hws[IMX8MM_SYS_PLL1_800M]);
618− clk_hw_set_parent(hws[IMX8MM_CLK_A53_CORE], hws[IMX8MM_ARM_PLL_OUT]);
619−
620617 imx_check_clk_hws(hws, IMX8MM_CLK_END);
621618
622619 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
drivers/clk/imx/clk-imx8mn.c+11−14
@@ -413,9 +413,9 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) · 412 unmodified lines
413413 }
414414
415415 /* CORE */
416− hws[IMX8MN_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mn_a53_sels, ARRAY_SIZE(imx8mn_a53_sels));
417− hws[IMX8MN_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
418− hws[IMX8MN_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
416+ hws[IMX8MN_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mn_a53_sels, base + 0x8000);
417+ hws[IMX8MN_CLK_A53_SRC] = hws[IMX8MN_CLK_A53_DIV];
418+ hws[IMX8MN_CLK_A53_CG] = hws[IMX8MN_CLK_A53_DIV];
419419
420420 hws[IMX8MN_CLK_GPU_CORE] = imx8m_clk_hw_composite_core("gpu_core", imx8mn_gpu_core_sels, base + 0x8180);
421421 hws[IMX8MN_CLK_GPU_SHADER] = imx8m_clk_hw_composite_core("gpu_shader", imx8mn_gpu_shader_sels, base + 0x8200);
@@ -432,17 +432,17 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) · 10 unmodified lines
432432
433433 /* BUS */
434434 hws[IMX8MN_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mn_main_axi_sels, base + 0x8800);
435− hws[IMX8MN_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mn_enet_axi_sels, base + 0x8880);
436− hws[IMX8MN_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900);
437− hws[IMX8MN_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mn_disp_axi_sels, base + 0x8a00);
438− hws[IMX8MN_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mn_disp_apb_sels, base + 0x8a80);
439− hws[IMX8MN_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80);
440− hws[IMX8MN_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mn_gpu_axi_sels, base + 0x8c00);
441− hws[IMX8MN_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mn_gpu_ahb_sels, base + 0x8c80);
435+ hws[IMX8MN_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mn_enet_axi_sels, base + 0x8880);
436+ hws[IMX8MN_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_bus("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900);
437+ hws[IMX8MN_CLK_DISP_AXI] = imx8m_clk_hw_composite_bus("disp_axi", imx8mn_disp_axi_sels, base + 0x8a00);
438+ hws[IMX8MN_CLK_DISP_APB] = imx8m_clk_hw_composite_bus("disp_apb", imx8mn_disp_apb_sels, base + 0x8a80);
439+ hws[IMX8MN_CLK_USB_BUS] = imx8m_clk_hw_composite_bus("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80);
440+ hws[IMX8MN_CLK_GPU_AXI] = imx8m_clk_hw_composite_bus("gpu_axi", imx8mn_gpu_axi_sels, base + 0x8c00);
441+ hws[IMX8MN_CLK_GPU_AHB] = imx8m_clk_hw_composite_bus("gpu_ahb", imx8mn_gpu_ahb_sels, base + 0x8c80);
442442 hws[IMX8MN_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mn_noc_sels, base + 0x8d00);
443443
444444 hws[IMX8MN_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mn_ahb_sels, base + 0x9000);
445− hws[IMX8MN_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mn_audio_ahb_sels, base + 0x9100);
445+ hws[IMX8MN_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mn_audio_ahb_sels, base + 0x9100);
446446 hws[IMX8MN_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
447447 hws[IMX8MN_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
448448 hws[IMX8MN_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mn_dram_core_sels, ARRAY_SIZE(imx8mn_dram_core_sels), CLK_IS_CRITICAL);
@@ -565,9 +565,6 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) · 116 unmodified lines
565565 hws[IMX8MN_ARM_PLL_OUT]->clk,
566566 hws[IMX8MN_CLK_A53_DIV]->clk);
567567
568− clk_hw_set_parent(hws[IMX8MN_CLK_A53_SRC], hws[IMX8MN_SYS_PLL1_800M]);
569− clk_hw_set_parent(hws[IMX8MN_CLK_A53_CORE], hws[IMX8MN_ARM_PLL_OUT]);
570−
571568 imx_check_clk_hws(hws, IMX8MN_CLK_END);
572569
573570 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
drivers/clk/imx/clk-imx8mp.c+74−74
@@ -486,16 +486,16 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) · 485 unmodified lines
486486 hws[IMX8MP_SYS_PLL2] = imx_clk_hw_pll14xx("sys_pll2", "sys_pll2_ref_sel", anatop_base + 0x104, &imx_1416x_pll);
487487 hws[IMX8MP_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", anatop_base + 0x114, &imx_1416x_pll);
488488
489− hws[IMX8MP_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", anatop_base, 4, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
490− hws[IMX8MP_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", anatop_base + 0x14, 4, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
491− hws[IMX8MP_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", anatop_base + 0x28, 4, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
492− hws[IMX8MP_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", anatop_base + 0x50, 4, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
493− hws[IMX8MP_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", anatop_base + 0x64, 4, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
494− hws[IMX8MP_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", anatop_base + 0x74, 4, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
495− hws[IMX8MP_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", anatop_base + 0x84, 4, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
496− hws[IMX8MP_SYS_PLL1_BYPASS] = imx_clk_hw_mux_flags("sys_pll1_bypass", anatop_base + 0x94, 4, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
497− hws[IMX8MP_SYS_PLL2_BYPASS] = imx_clk_hw_mux_flags("sys_pll2_bypass", anatop_base + 0x104, 4, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
498− hws[IMX8MP_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", anatop_base + 0x114, 4, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
489+ hws[IMX8MP_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", anatop_base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
490+ hws[IMX8MP_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", anatop_base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
491+ hws[IMX8MP_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", anatop_base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
492+ hws[IMX8MP_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", anatop_base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
493+ hws[IMX8MP_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", anatop_base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
494+ hws[IMX8MP_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", anatop_base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
495+ hws[IMX8MP_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", anatop_base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
496+ hws[IMX8MP_SYS_PLL1_BYPASS] = imx_clk_hw_mux_flags("sys_pll1_bypass", anatop_base + 0x94, 28, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
497+ hws[IMX8MP_SYS_PLL2_BYPASS] = imx_clk_hw_mux_flags("sys_pll2_bypass", anatop_base + 0x104, 28, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
498+ hws[IMX8MP_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", anatop_base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
499499
500500 hws[IMX8MP_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", anatop_base, 13);
501501 hws[IMX8MP_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", anatop_base + 0x14, 13);
@@ -504,79 +504,82 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) · 2 unmodified lines
504504 hws[IMX8MP_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", anatop_base + 0x64, 11);
505505 hws[IMX8MP_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", anatop_base + 0x74, 11);
506506 hws[IMX8MP_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", anatop_base + 0x84, 11);
507− hws[IMX8MP_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1_bypass", anatop_base + 0x94, 11);
508− hws[IMX8MP_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2_bypass", anatop_base + 0x104, 11);
509507 hws[IMX8MP_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", anatop_base + 0x114, 11);
510508
511− hws[IMX8MP_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
512− hws[IMX8MP_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
513− hws[IMX8MP_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
514− hws[IMX8MP_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
515− hws[IMX8MP_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
516− hws[IMX8MP_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
517− hws[IMX8MP_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
518− hws[IMX8MP_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
509+ hws[IMX8MP_SYS_PLL1_40M_CG] = imx_clk_hw_gate("sys_pll1_40m_cg", "sys_pll1_bypass", anatop_base + 0x94, 27);
510+ hws[IMX8MP_SYS_PLL1_80M_CG] = imx_clk_hw_gate("sys_pll1_80m_cg", "sys_pll1_bypass", anatop_base + 0x94, 25);
511+ hws[IMX8MP_SYS_PLL1_100M_CG] = imx_clk_hw_gate("sys_pll1_100m_cg", "sys_pll1_bypass", anatop_base + 0x94, 23);
512+ hws[IMX8MP_SYS_PLL1_133M_CG] = imx_clk_hw_gate("sys_pll1_133m_cg", "sys_pll1_bypass", anatop_base + 0x94, 21);
513+ hws[IMX8MP_SYS_PLL1_160M_CG] = imx_clk_hw_gate("sys_pll1_160m_cg", "sys_pll1_bypass", anatop_base + 0x94, 19);
514+ hws[IMX8MP_SYS_PLL1_200M_CG] = imx_clk_hw_gate("sys_pll1_200m_cg", "sys_pll1_bypass", anatop_base + 0x94, 17);
515+ hws[IMX8MP_SYS_PLL1_266M_CG] = imx_clk_hw_gate("sys_pll1_266m_cg", "sys_pll1_bypass", anatop_base + 0x94, 15);
516+ hws[IMX8MP_SYS_PLL1_400M_CG] = imx_clk_hw_gate("sys_pll1_400m_cg", "sys_pll1_bypass", anatop_base + 0x94, 13);
517+ hws[IMX8MP_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1_bypass", anatop_base + 0x94, 11);
518+
519+ hws[IMX8MP_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20);
520+ hws[IMX8MP_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10);
521+ hws[IMX8MP_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8);
522+ hws[IMX8MP_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6);
523+ hws[IMX8MP_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5);
524+ hws[IMX8MP_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4);
525+ hws[IMX8MP_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3);
526+ hws[IMX8MP_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2);
519527 hws[IMX8MP_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
520528
521− hws[IMX8MP_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
522− hws[IMX8MP_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
523− hws[IMX8MP_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
524− hws[IMX8MP_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
525− hws[IMX8MP_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
526− hws[IMX8MP_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
527− hws[IMX8MP_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
528− hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
529+ hws[IMX8MP_SYS_PLL2_50M_CG] = imx_clk_hw_gate("sys_pll2_50m_cg", "sys_pll2_bypass", anatop_base + 0x104, 27);
530+ hws[IMX8MP_SYS_PLL2_100M_CG] = imx_clk_hw_gate("sys_pll2_100m_cg", "sys_pll2_bypass", anatop_base + 0x104, 25);
531+ hws[IMX8MP_SYS_PLL2_125M_CG] = imx_clk_hw_gate("sys_pll2_125m_cg", "sys_pll2_bypass", anatop_base + 0x104, 23);
532+ hws[IMX8MP_SYS_PLL2_166M_CG] = imx_clk_hw_gate("sys_pll2_166m_cg", "sys_pll2_bypass", anatop_base + 0x104, 21);
533+ hws[IMX8MP_SYS_PLL2_200M_CG] = imx_clk_hw_gate("sys_pll2_200m_cg", "sys_pll2_bypass", anatop_base + 0x104, 19);
534+ hws[IMX8MP_SYS_PLL2_250M_CG] = imx_clk_hw_gate("sys_pll2_250m_cg", "sys_pll2_bypass", anatop_base + 0x104, 17);
535+ hws[IMX8MP_SYS_PLL2_333M_CG] = imx_clk_hw_gate("sys_pll2_333m_cg", "sys_pll2_bypass", anatop_base + 0x104, 15);
536+ hws[IMX8MP_SYS_PLL2_500M_CG] = imx_clk_hw_gate("sys_pll2_500m_cg", "sys_pll2_bypass", anatop_base + 0x104, 13);
537+ hws[IMX8MP_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2_bypass", anatop_base + 0x104, 11);
538+
539+ hws[IMX8MP_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20);
540+ hws[IMX8MP_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10);
541+ hws[IMX8MP_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8);
542+ hws[IMX8MP_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6);
543+ hws[IMX8MP_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5);
544+ hws[IMX8MP_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4);
545+ hws[IMX8MP_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3);
546+ hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2);
529547 hws[IMX8MP_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
530548
531− hws[IMX8MP_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", ccm_base + 0x8000, 24, 3, imx8mp_a53_sels, ARRAY_SIZE(imx8mp_a53_sels));
532− hws[IMX8MP_CLK_M7_SRC] = imx_clk_hw_mux2("arm_m7_src", ccm_base + 0x8080, 24, 3, imx8mp_m7_sels, ARRAY_SIZE(imx8mp_m7_sels));
533− hws[IMX8MP_CLK_ML_SRC] = imx_clk_hw_mux2("ml_src", ccm_base + 0x8100, 24, 3, imx8mp_ml_sels, ARRAY_SIZE(imx8mp_ml_sels));
534− hws[IMX8MP_CLK_GPU3D_CORE_SRC] = imx_clk_hw_mux2("gpu3d_core_src", ccm_base + 0x8180, 24, 3, imx8mp_gpu3d_core_sels, ARRAY_SIZE(imx8mp_gpu3d_core_sels));
535− hws[IMX8MP_CLK_GPU3D_SHADER_SRC] = imx_clk_hw_mux2("gpu3d_shader_src", ccm_base + 0x8200, 24, 3, imx8mp_gpu3d_shader_sels, ARRAY_SIZE(imx8mp_gpu3d_shader_sels));
536− hws[IMX8MP_CLK_GPU2D_SRC] = imx_clk_hw_mux2("gpu2d_src", ccm_base + 0x8280, 24, 3, imx8mp_gpu2d_sels, ARRAY_SIZE(imx8mp_gpu2d_sels));
537− hws[IMX8MP_CLK_AUDIO_AXI_SRC] = imx_clk_hw_mux2("audio_axi_src", ccm_base + 0x8300, 24, 3, imx8mp_audio_axi_sels, ARRAY_SIZE(imx8mp_audio_axi_sels));
538− hws[IMX8MP_CLK_HSIO_AXI_SRC] = imx_clk_hw_mux2("hsio_axi_src", ccm_base + 0x8380, 24, 3, imx8mp_hsio_axi_sels, ARRAY_SIZE(imx8mp_hsio_axi_sels));
539− hws[IMX8MP_CLK_MEDIA_ISP_SRC] = imx_clk_hw_mux2("media_isp_src", ccm_base + 0x8400, 24, 3, imx8mp_media_isp_sels, ARRAY_SIZE(imx8mp_media_isp_sels));
540− hws[IMX8MP_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", ccm_base + 0x8000, 28);
541− hws[IMX8MP_CLK_M4_CG] = imx_clk_hw_gate3("arm_m7_cg", "arm_m7_src", ccm_base + 0x8080, 28);
542− hws[IMX8MP_CLK_ML_CG] = imx_clk_hw_gate3("ml_cg", "ml_src", ccm_base + 0x8100, 28);
543− hws[IMX8MP_CLK_GPU3D_CORE_CG] = imx_clk_hw_gate3("gpu3d_core_cg", "gpu3d_core_src", ccm_base + 0x8180, 28);
544− hws[IMX8MP_CLK_GPU3D_SHADER_CG] = imx_clk_hw_gate3("gpu3d_shader_cg", "gpu3d_shader_src", ccm_base + 0x8200, 28);
545− hws[IMX8MP_CLK_GPU2D_CG] = imx_clk_hw_gate3("gpu2d_cg", "gpu2d_src", ccm_base + 0x8280, 28);
546− hws[IMX8MP_CLK_AUDIO_AXI_CG] = imx_clk_hw_gate3("audio_axi_cg", "audio_axi_src", ccm_base + 0x8300, 28);
547− hws[IMX8MP_CLK_HSIO_AXI_CG] = imx_clk_hw_gate3("hsio_axi_cg", "hsio_axi_src", ccm_base + 0x8380, 28);
548− hws[IMX8MP_CLK_MEDIA_ISP_CG] = imx_clk_hw_gate3("media_isp_cg", "media_isp_src", ccm_base + 0x8400, 28);
549− hws[IMX8MP_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", ccm_base + 0x8000, 0, 3);
550− hws[IMX8MP_CLK_M7_DIV] = imx_clk_hw_divider2("arm_m7_div", "arm_m7_cg", ccm_base + 0x8080, 0, 3);
551− hws[IMX8MP_CLK_ML_DIV] = imx_clk_hw_divider2("ml_div", "ml_cg", ccm_base + 0x8100, 0, 3);
552− hws[IMX8MP_CLK_GPU3D_CORE_DIV] = imx_clk_hw_divider2("gpu3d_core_div", "gpu3d_core_cg", ccm_base + 0x8180, 0, 3);
553− hws[IMX8MP_CLK_GPU3D_SHADER_DIV] = imx_clk_hw_divider2("gpu3d_shader_div", "gpu3d_shader_cg", ccm_base + 0x8200, 0, 3);
554− hws[IMX8MP_CLK_GPU2D_DIV] = imx_clk_hw_divider2("gpu2d_div", "gpu2d_cg", ccm_base + 0x8280, 0, 3);
555− hws[IMX8MP_CLK_AUDIO_AXI_DIV] = imx_clk_hw_divider2("audio_axi_div", "audio_axi_cg", ccm_base + 0x8300, 0, 3);
556− hws[IMX8MP_CLK_HSIO_AXI_DIV] = imx_clk_hw_divider2("hsio_axi_div", "hsio_axi_cg", ccm_base + 0x8380, 0, 3);
557− hws[IMX8MP_CLK_MEDIA_ISP_DIV] = imx_clk_hw_divider2("media_isp_div", "media_isp_cg", ccm_base + 0x8400, 0, 3);
549+ hws[IMX8MP_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mp_a53_sels, ccm_base + 0x8000);
550+ hws[IMX8MP_CLK_A53_SRC] = hws[IMX8MP_CLK_A53_DIV];
551+ hws[IMX8MP_CLK_A53_CG] = hws[IMX8MP_CLK_A53_DIV];
552+ hws[IMX8MP_CLK_M7_CORE] = imx8m_clk_hw_composite_core("m7_core", imx8mp_m7_sels, ccm_base + 0x8080);
553+ hws[IMX8MP_CLK_ML_CORE] = imx8m_clk_hw_composite_core("ml_core", imx8mp_ml_sels, ccm_base + 0x8100);
554+ hws[IMX8MP_CLK_GPU3D_CORE] = imx8m_clk_hw_composite_core("gpu3d_core", imx8mp_gpu3d_core_sels, ccm_base + 0x8180);
555+ hws[IMX8MP_CLK_GPU3D_SHADER_CORE] = imx8m_clk_hw_composite("gpu3d_shader_core", imx8mp_gpu3d_shader_sels, ccm_base + 0x8200);
556+ hws[IMX8MP_CLK_GPU2D_CORE] = imx8m_clk_hw_composite("gpu2d_core", imx8mp_gpu2d_sels, ccm_base + 0x8280);
557+ hws[IMX8MP_CLK_AUDIO_AXI] = imx8m_clk_hw_composite("audio_axi", imx8mp_audio_axi_sels, ccm_base + 0x8300);
558+ hws[IMX8MP_CLK_AUDIO_AXI_SRC] = hws[IMX8MP_CLK_AUDIO_AXI];
559+ hws[IMX8MP_CLK_HSIO_AXI] = imx8m_clk_hw_composite("hsio_axi", imx8mp_hsio_axi_sels, ccm_base + 0x8380);
560+ hws[IMX8MP_CLK_MEDIA_ISP] = imx8m_clk_hw_composite("media_isp", imx8mp_media_isp_sels, ccm_base + 0x8400);
558561
559562 /* CORE SEL */
560563 hws[IMX8MP_CLK_A53_CORE] = imx_clk_hw_mux2("arm_a53_core", ccm_base + 0x9880, 24, 1, imx8mp_a53_core_sels, ARRAY_SIZE(imx8mp_a53_core_sels));
561564
562565 hws[IMX8MP_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mp_main_axi_sels, ccm_base + 0x8800);
563− hws[IMX8MP_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mp_enet_axi_sels, ccm_base + 0x8880);
566+ hws[IMX8MP_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mp_enet_axi_sels, ccm_base + 0x8880);
564567 hws[IMX8MP_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_critical("nand_usdhc_bus", imx8mp_nand_usdhc_sels, ccm_base + 0x8900);
565− hws[IMX8MP_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mp_vpu_bus_sels, ccm_base + 0x8980);
566− hws[IMX8MP_CLK_MEDIA_AXI] = imx8m_clk_hw_composite("media_axi", imx8mp_media_axi_sels, ccm_base + 0x8a00);
567− hws[IMX8MP_CLK_MEDIA_APB] = imx8m_clk_hw_composite("media_apb", imx8mp_media_apb_sels, ccm_base + 0x8a80);
568− hws[IMX8MP_CLK_HDMI_APB] = imx8m_clk_hw_composite("hdmi_apb", imx8mp_media_apb_sels, ccm_base + 0x8b00);
569− hws[IMX8MP_CLK_HDMI_AXI] = imx8m_clk_hw_composite("hdmi_axi", imx8mp_media_axi_sels, ccm_base + 0x8b80);
570− hws[IMX8MP_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mp_gpu_axi_sels, ccm_base + 0x8c00);
571− hws[IMX8MP_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mp_gpu_ahb_sels, ccm_base + 0x8c80);
568+ hws[IMX8MP_CLK_VPU_BUS] = imx8m_clk_hw_composite_bus("vpu_bus", imx8mp_vpu_bus_sels, ccm_base + 0x8980);
569+ hws[IMX8MP_CLK_MEDIA_AXI] = imx8m_clk_hw_composite_bus("media_axi", imx8mp_media_axi_sels, ccm_base + 0x8a00);
570+ hws[IMX8MP_CLK_MEDIA_APB] = imx8m_clk_hw_composite_bus("media_apb", imx8mp_media_apb_sels, ccm_base + 0x8a80);
571+ hws[IMX8MP_CLK_HDMI_APB] = imx8m_clk_hw_composite_bus("hdmi_apb", imx8mp_media_apb_sels, ccm_base + 0x8b00);
572+ hws[IMX8MP_CLK_HDMI_AXI] = imx8m_clk_hw_composite_bus("hdmi_axi", imx8mp_media_axi_sels, ccm_base + 0x8b80);
573+ hws[IMX8MP_CLK_GPU_AXI] = imx8m_clk_hw_composite_bus("gpu_axi", imx8mp_gpu_axi_sels, ccm_base + 0x8c00);
574+ hws[IMX8MP_CLK_GPU_AHB] = imx8m_clk_hw_composite_bus("gpu_ahb", imx8mp_gpu_ahb_sels, ccm_base + 0x8c80);
572575 hws[IMX8MP_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mp_noc_sels, ccm_base + 0x8d00);
573576 hws[IMX8MP_CLK_NOC_IO] = imx8m_clk_hw_composite_critical("noc_io", imx8mp_noc_io_sels, ccm_base + 0x8d80);
574− hws[IMX8MP_CLK_ML_AXI] = imx8m_clk_hw_composite("ml_axi", imx8mp_ml_axi_sels, ccm_base + 0x8e00);
575− hws[IMX8MP_CLK_ML_AHB] = imx8m_clk_hw_composite("ml_ahb", imx8mp_ml_ahb_sels, ccm_base + 0x8e80);
577+ hws[IMX8MP_CLK_ML_AXI] = imx8m_clk_hw_composite_bus("ml_axi", imx8mp_ml_axi_sels, ccm_base + 0x8e00);
578+ hws[IMX8MP_CLK_ML_AHB] = imx8m_clk_hw_composite_bus("ml_ahb", imx8mp_ml_ahb_sels, ccm_base + 0x8e80);
576579
577580 hws[IMX8MP_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb_root", imx8mp_ahb_sels, ccm_base + 0x9000);
578− hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100);
579− hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200);
581+ hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100);
582+ hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite_bus("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200);
580583
581584 hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1);
582585 hws[IMX8MP_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", ccm_base + 0x9180, 0, 1);
@@ -695,8 +698,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) · 112 unmodified lines
695698 hws[IMX8MP_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_root_clk", "ipg_root", ccm_base + 0x43a0, 0);
696699 hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "sim_enet_root_clk", ccm_base + 0x43b0, 0);
697700 hws[IMX8MP_CLK_SIM_ENET_ROOT] = imx_clk_hw_gate4("sim_enet_root_clk", "enet_axi", ccm_base + 0x4400, 0);
698− hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_div", ccm_base + 0x4450, 0);
699− hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core_div", ccm_base + 0x4460, 0);
701+ hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_core", ccm_base + 0x4450, 0);
702+ hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core", ccm_base + 0x4460, 0);
700703 hws[IMX8MP_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", ccm_base + 0x4470, 0);
701704 hws[IMX8MP_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", ccm_base + 0x4490, 0);
702705 hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0);
@@ -713,7 +716,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) · 10 unmodified lines
713716 hws[IMX8MP_CLK_GPU_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_axi", ccm_base + 0x4570, 0);
714717 hws[IMX8MP_CLK_VPU_VC8KE_ROOT] = imx_clk_hw_gate4("vpu_vc8ke_root_clk", "vpu_vc8000e", ccm_base + 0x4590, 0);
715718 hws[IMX8MP_CLK_VPU_G2_ROOT] = imx_clk_hw_gate4("vpu_g2_root_clk", "vpu_g2", ccm_base + 0x45a0, 0);
716− hws[IMX8MP_CLK_NPU_ROOT] = imx_clk_hw_gate4("npu_root_clk", "ml_div", ccm_base + 0x45b0, 0);
719+ hws[IMX8MP_CLK_NPU_ROOT] = imx_clk_hw_gate4("npu_root_clk", "ml_core", ccm_base + 0x45b0, 0);
717720 hws[IMX8MP_CLK_HSIO_ROOT] = imx_clk_hw_gate4("hsio_root_clk", "ipg_root", ccm_base + 0x45c0, 0);
718721 hws[IMX8MP_CLK_MEDIA_APB_ROOT] = imx_clk_hw_gate2_shared2("media_apb_root_clk", "media_apb", ccm_base + 0x45d0, 0, &share_count_media);
719722 hws[IMX8MP_CLK_MEDIA_AXI_ROOT] = imx_clk_hw_gate2_shared2("media_axi_root_clk", "media_axi", ccm_base + 0x45d0, 0, &share_count_media);
@@ -721,7 +724,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) · 1 unmodified line
721724 hws[IMX8MP_CLK_MEDIA_CAM2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam2_pix_root_clk", "media_cam2_pix", ccm_base + 0x45d0, 0, &share_count_media);
722725 hws[IMX8MP_CLK_MEDIA_DISP1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp1_pix_root_clk", "media_disp1_pix", ccm_base + 0x45d0, 0, &share_count_media);
723726 hws[IMX8MP_CLK_MEDIA_DISP2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp2_pix_root_clk", "media_disp2_pix", ccm_base + 0x45d0, 0, &share_count_media);
724− hws[IMX8MP_CLK_MEDIA_ISP_ROOT] = imx_clk_hw_gate2_shared2("media_isp_root_clk", "media_isp_div", ccm_base + 0x45d0, 0, &share_count_media);
727+ hws[IMX8MP_CLK_MEDIA_ISP_ROOT] = imx_clk_hw_gate2_shared2("media_isp_root_clk", "media_isp", ccm_base + 0x45d0, 0, &share_count_media);
725728
726729 hws[IMX8MP_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", ccm_base + 0x45e0, 0);
727730 hws[IMX8MP_CLK_HDMI_ROOT] = imx_clk_hw_gate4("hdmi_root_clk", "hdmi_axi", ccm_base + 0x45f0, 0);
@@ -735,9 +738,6 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) · 7 unmodified lines
735738 hws[IMX8MP_ARM_PLL_OUT]->clk,
736739 hws[IMX8MP_CLK_A53_DIV]->clk);
737740
738− clk_hw_set_parent(hws[IMX8MP_CLK_A53_SRC], hws[IMX8MP_SYS_PLL1_800M]);
739− clk_hw_set_parent(hws[IMX8MP_CLK_A53_CORE], hws[IMX8MP_ARM_PLL_OUT]);
740−
741741 imx_check_clk_hws(hws, IMX8MP_CLK_END);
742742
743743 of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
drivers/clk/imx/clk-imx8mq.c+13−16
@@ -405,9 +405,9 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) · 404 unmodified lines
405405 return PTR_ERR(base);
406406
407407 /* CORE */
408− hws[IMX8MQ_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels));
409− hws[IMX8MQ_CLK_A53_CG] = imx_clk_hw_gate3_flags("arm_a53_cg", "arm_a53_src", base + 0x8000, 28, CLK_IS_CRITICAL);
410− hws[IMX8MQ_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
408+ hws[IMX8MQ_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mq_a53_sels, base + 0x8000);
409+ hws[IMX8MQ_CLK_A53_CG] = hws[IMX8MQ_CLK_A53_DIV];
410+ hws[IMX8MQ_CLK_A53_SRC] = hws[IMX8MQ_CLK_A53_DIV];
411411
412412 hws[IMX8MQ_CLK_M4_CORE] = imx8m_clk_hw_composite_core("arm_m4_core", imx8mq_arm_m4_sels, base + 0x8080);
413413 hws[IMX8MQ_CLK_VPU_CORE] = imx8m_clk_hw_composite_core("vpu_core", imx8mq_vpu_sels, base + 0x8100);
@@ -432,22 +432,22 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) · 18 unmodified lines
432432
433433 /* BUS */
434434 hws[IMX8MQ_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mq_main_axi_sels, base + 0x8800);
435− hws[IMX8MQ_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mq_enet_axi_sels, base + 0x8880);
436− hws[IMX8MQ_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite("nand_usdhc_bus", imx8mq_nand_usdhc_sels, base + 0x8900);
437− hws[IMX8MQ_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mq_vpu_bus_sels, base + 0x8980);
438− hws[IMX8MQ_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mq_disp_axi_sels, base + 0x8a00);
439− hws[IMX8MQ_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mq_disp_apb_sels, base + 0x8a80);
440− hws[IMX8MQ_CLK_DISP_RTRM] = imx8m_clk_hw_composite("disp_rtrm", imx8mq_disp_rtrm_sels, base + 0x8b00);
441− hws[IMX8MQ_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80);
442− hws[IMX8MQ_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mq_gpu_axi_sels, base + 0x8c00);
443− hws[IMX8MQ_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mq_gpu_ahb_sels, base + 0x8c80);
435+ hws[IMX8MQ_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mq_enet_axi_sels, base + 0x8880);
436+ hws[IMX8MQ_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_bus("nand_usdhc_bus", imx8mq_nand_usdhc_sels, base + 0x8900);
437+ hws[IMX8MQ_CLK_VPU_BUS] = imx8m_clk_hw_composite_bus("vpu_bus", imx8mq_vpu_bus_sels, base + 0x8980);
438+ hws[IMX8MQ_CLK_DISP_AXI] = imx8m_clk_hw_composite_bus("disp_axi", imx8mq_disp_axi_sels, base + 0x8a00);
439+ hws[IMX8MQ_CLK_DISP_APB] = imx8m_clk_hw_composite_bus("disp_apb", imx8mq_disp_apb_sels, base + 0x8a80);
440+ hws[IMX8MQ_CLK_DISP_RTRM] = imx8m_clk_hw_composite_bus("disp_rtrm", imx8mq_disp_rtrm_sels, base + 0x8b00);
441+ hws[IMX8MQ_CLK_USB_BUS] = imx8m_clk_hw_composite_bus("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80);
442+ hws[IMX8MQ_CLK_GPU_AXI] = imx8m_clk_hw_composite_bus("gpu_axi", imx8mq_gpu_axi_sels, base + 0x8c00);
443+ hws[IMX8MQ_CLK_GPU_AHB] = imx8m_clk_hw_composite_bus("gpu_ahb", imx8mq_gpu_ahb_sels, base + 0x8c80);
444444 hws[IMX8MQ_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mq_noc_sels, base + 0x8d00);
445445 hws[IMX8MQ_CLK_NOC_APB] = imx8m_clk_hw_composite_critical("noc_apb", imx8mq_noc_apb_sels, base + 0x8d80);
446446
447447 /* AHB */
448448 /* AHB clock is used by the AHB bus therefore marked as critical */
449449 hws[IMX8MQ_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mq_ahb_sels, base + 0x9000);
450− hws[IMX8MQ_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mq_audio_ahb_sels, base + 0x9100);
450+ hws[IMX8MQ_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mq_audio_ahb_sels, base + 0x9100);
451451
452452 /* IPG */
453453 hws[IMX8MQ_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
@@ -599,9 +599,6 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) · 145 unmodified lines
599599 hws[IMX8MQ_ARM_PLL_OUT]->clk,
600600 hws[IMX8MQ_CLK_A53_DIV]->clk);
601601
602− clk_hw_set_parent(hws[IMX8MQ_CLK_A53_SRC], hws[IMX8MQ_SYS1_PLL_800M]);
603− clk_hw_set_parent(hws[IMX8MQ_CLK_A53_CORE], hws[IMX8MQ_ARM_PLL_OUT]);
604−
605602 imx_check_clk_hws(hws, IMX8MQ_CLK_END);
606603
607604 err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
drivers/clk/imx/clk-pll14xx.c+4−4
@@ -378,9 +378,9 @@ static const struct clk_ops clk_pll1443x_ops = { · 377 unmodified lines
378378 .set_rate = clk_pll1443x_set_rate,
379379 };
380380
381−struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
382− void __iomem *base,
383− const struct imx_pll14xx_clk *pll_clk)
381+struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name,
382+ const char *parent_name, void __iomem *base,
383+ const struct imx_pll14xx_clk *pll_clk)
384384 {
385385 struct clk_pll14xx *pll;
386386 struct clk_hw *hw;
@@ -426,7 +426,7 @@ struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name, · 39 unmodified lines
426426
427427 hw = &pll->hw;
428428
429− ret = clk_hw_register(NULL, hw);
429+ ret = clk_hw_register(dev, hw);
430430 if (ret) {
431431 pr_err("%s: failed to register pll %s %d\n",
432432 __func__, name, ret);
drivers/clk/imx/clk-pllv3.c+5−11
@@ -7,6 +7,7 @@ · 6 unmodified lines
77 #include <linux/clk-provider.h>
88 #include <linux/delay.h>
99 #include <linux/io.h>
10+#include <linux/iopoll.h>
1011 #include <linux/slab.h>
1112 #include <linux/jiffies.h>
1213 #include <linux/err.h>
@@ -25,6 +26,8 @@ · 12 unmodified lines
2526 #define IMX7_ENET_PLL_POWER (0x1 << 5)
2627 #define IMX7_DDR_PLL_POWER (0x1 << 20)
2728
29+#define PLL_LOCK_TIMEOUT 10000
30+
2831 /**
2932 * struct clk_pllv3 - IMX PLL clock version 3
3033 * @clk_hw: clock source
@@ -53,23 +56,14 @@ struct clk_pllv3 { · 22 unmodified lines
5356
5457 static int clk_pllv3_wait_lock(struct clk_pllv3 *pll)
5558 {
56− unsigned long timeout = jiffies + msecs_to_jiffies(10);
5759 u32 val = readl_relaxed(pll->base) & pll->power_bit;
5860
5961 /* No need to wait for lock when pll is not powered up */
6062 if ((pll->powerup_set && !val) || (!pll->powerup_set && val))
6163 return 0;
6264
63− /* Wait for PLL to lock */
64− do {
65− if (readl_relaxed(pll->base) & BM_PLL_LOCK)
66− break;
67− if (time_after(jiffies, timeout))
68− break;
69− usleep_range(50, 500);
70− } while (1);
71−
72− return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT;
65+ return readl_relaxed_poll_timeout(pll->base, val, val & BM_PLL_LOCK,
66+ 500, PLL_LOCK_TIMEOUT);
7367 }
7468
7569 static int clk_pllv3_prepare(struct clk_hw *hw)
drivers/clk/imx/clk-sscg-pll.c+0−10
@@ -72,7 +72,6 @@ struct clk_sscg_pll_setup { · 71 unmodified lines
7272 int divr2, divf2;
7373 int divq;
7474 int bypass;
75−
7675 uint64_t vco1;
7776 uint64_t vco2;
7877 uint64_t fout;
@@ -86,11 +85,8 @@ struct clk_sscg_pll_setup { · 7 unmodified lines
8685 struct clk_sscg_pll {
8786 struct clk_hw hw;
8887 const struct clk_ops ops;
89−
9088 void __iomem *base;
91−
9289 struct clk_sscg_pll_setup setup;
93−
9490 u8 parent;
9591 u8 bypass1;
9692 u8 bypass2;
@@ -194,7 +190,6 @@ static int clk_sscg_pll2_find_setup(struct clk_sscg_pll_setup *setup, · 97 unmodified lines
194190 struct clk_sscg_pll_setup *temp_setup,
195191 uint64_t ref)
196192 {
197−
198193 int ret;
199194
200195 if (ref < PLL_STAGE1_MIN_FREQ || ref > PLL_STAGE1_MAX_FREQ)
@@ -253,7 +248,6 @@ static int clk_sscg_pll1_find_setup(struct clk_sscg_pll_setup *setup, · 52 unmodified lines
253248 struct clk_sscg_pll_setup *temp_setup,
254249 uint64_t ref)
255250 {
256−
257251 int ret;
258252
259253 if (ref < PLL_REF_MIN_FREQ || ref > PLL_REF_MAX_FREQ)
@@ -280,7 +274,6 @@ static int clk_sscg_pll_find_setup(struct clk_sscg_pll_setup *setup, · 20 unmodified lines
280274 temp_setup.fout_request = rate;
281275
282276 switch (try_bypass) {
283−
284277 case PLL_BYPASS2:
285278 if (prate == rate) {
286279 setup->bypass = PLL_BYPASS2;
@@ -288,11 +281,9 @@ static int clk_sscg_pll_find_setup(struct clk_sscg_pll_setup *setup, · 1 unmodified line
288281 ret = 0;
289282 }
290283 break;
291−
292284 case PLL_BYPASS1:
293285 ret = clk_sscg_pll2_find_setup(setup, &temp_setup, prate);
294286 break;
295−
296287 case PLL_BYPASS_NONE:
297288 ret = clk_sscg_pll1_find_setup(setup, &temp_setup, prate);
298289 break;
@@ -301,7 +292,6 @@ static int clk_sscg_pll_find_setup(struct clk_sscg_pll_setup *setup, · 2 unmodified lines
301292 return ret;
302293 }
303294
304−
305295 static int clk_sscg_pll_is_prepared(struct clk_hw *hw)
306296 {
307297 struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
drivers/clk/imx/clk.h+59−3
@@ -5,6 +5,8 @@ · 4 unmodified lines
55 #include <linux/spinlock.h>
66 #include <linux/clk-provider.h>
77
8+#define IMX_CLK_GATE2_SINGLE_BIT 1
9+
810 extern spinlock_t imx_ccm_lock;
911
1012 void imx_check_clocks(struct clk *clks[], unsigned int count);
@@ -131,9 +133,9 @@ struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, · 120 unmodified lines
131133 #define imx_clk_pll14xx(name, parent_name, base, pll_clk) \
132134 to_clk(imx_clk_hw_pll14xx(name, parent_name, base, pll_clk))
133135
134−struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
135− void __iomem *base,
136− const struct imx_pll14xx_clk *pll_clk);
136+struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name,
137+ const char *parent_name, void __iomem *base,
138+ const struct imx_pll14xx_clk *pll_clk);
137139
138140 struct clk_hw *imx_clk_hw_pllv1(enum imx_pllv1_type type, const char *name,
139141 const char *parent, void __iomem *base);
@@ -240,6 +242,13 @@ static inline struct clk *to_clk(struct clk_hw *hw) · 100 unmodified lines
240242 return hw->clk;
241243 }
242244
245+static inline struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
246+ void __iomem *base,
247+ const struct imx_pll14xx_clk *pll_clk)
248+{
249+ return imx_dev_clk_hw_pll14xx(NULL, name, parent_name, base, pll_clk);
250+}
251+
243252 static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)
244253 {
245254 return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
@@ -310,6 +319,13 @@ static inline struct clk_hw *imx_clk_hw_gate(const char *name, const char *paren · 64 unmodified lines
310319 shift, 0, &imx_ccm_lock);
311320 }
312321
322+static inline struct clk_hw *imx_dev_clk_hw_gate(struct device *dev, const char *name,
323+ const char *parent, void __iomem *reg, u8 shift)
324+{
325+ return clk_hw_register_gate(dev, name, parent, CLK_SET_RATE_PARENT, reg,
326+ shift, 0, &imx_ccm_lock);
327+}
328+
313329 static inline struct clk_hw *imx_clk_hw_gate_dis(const char *name, const char *parent,
314330 void __iomem *reg, u8 shift)
315331 {
@@ -355,6 +371,17 @@ static inline struct clk_hw *imx_clk_hw_gate2_shared2(const char *name, · 39 unmodified lines
355371 &imx_ccm_lock, share_count);
356372 }
357373
374+static inline struct clk_hw *imx_dev_clk_hw_gate_shared(struct device *dev,
375+ const char *name, const char *parent,
376+ void __iomem *reg, u8 shift,
377+ unsigned int *share_count)
378+{
379+ return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
380+ CLK_OPS_PARENT_ENABLE, reg, shift, 0x3,
381+ IMX_CLK_GATE2_SINGLE_BIT,
382+ &imx_ccm_lock, share_count);
383+}
384+
358385 static inline struct clk *imx_clk_gate2_cgr(const char *name,
359386 const char *parent, void __iomem *reg, u8 shift, u8 cgr_val)
360387 {
@@ -411,6 +438,15 @@ static inline struct clk_hw *imx_clk_hw_mux(const char *name, void __iomem *reg, · 50 unmodified lines
411438 width, 0, &imx_ccm_lock);
412439 }
413440
441+static inline struct clk_hw *imx_dev_clk_hw_mux(struct device *dev,
442+ const char *name, void __iomem *reg, u8 shift,
443+ u8 width, const char * const *parents, int num_parents)
444+{
445+ return clk_hw_register_mux(dev, name, parents, num_parents,
446+ CLK_SET_RATE_NO_REPARENT | CLK_SET_PARENT_GATE,
447+ reg, shift, width, 0, &imx_ccm_lock);
448+}
449+
414450 static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
415451 u8 shift, u8 width, const char * const *parents,
416452 int num_parents)
@@ -473,11 +509,25 @@ static inline struct clk_hw *imx_clk_hw_mux_flags(const char *name, · 56 unmodified lines
473509 reg, shift, width, 0, &imx_ccm_lock);
474510 }
475511
512+static inline struct clk_hw *imx_dev_clk_hw_mux_flags(struct device *dev,
513+ const char *name,
514+ void __iomem *reg, u8 shift,
515+ u8 width,
516+ const char * const *parents,
517+ int num_parents,
518+ unsigned long flags)
519+{
520+ return clk_hw_register_mux(dev, name, parents, num_parents,
521+ flags | CLK_SET_RATE_NO_REPARENT,
522+ reg, shift, width, 0, &imx_ccm_lock);
523+}
524+
476525 struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
477526 struct clk *div, struct clk *mux, struct clk *pll,
478527 struct clk *step);
479528
480529 #define IMX_COMPOSITE_CORE BIT(0)
530+#define IMX_COMPOSITE_BUS BIT(1)
481531
482532 struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
483533 const char * const *parent_names,
@@ -486,6 +536,12 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, · 2 unmodified lines
486536 u32 composite_flags,
487537 unsigned long flags);
488538
539+#define imx8m_clk_hw_composite_bus(name, parent_names, reg) \
540+ imx8m_clk_hw_composite_flags(name, parent_names, \
541+ ARRAY_SIZE(parent_names), reg, \
542+ IMX_COMPOSITE_BUS, \
543+ CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
544+
489545 #define imx8m_clk_hw_composite_core(name, parent_names, reg) \
490546 imx8m_clk_hw_composite_flags(name, parent_names, \
491547 ARRAY_SIZE(parent_names), reg, \
drivers/clk/ingenic/Kconfig+10−0
@@ -55,6 +55,16 @@ config INGENIC_CGU_X1000 · 54 unmodified lines
5555
5656 If building for a X1000 SoC, you want to say Y here.
5757
58+config INGENIC_CGU_X1830
59+ bool "Ingenic X1830 CGU driver"
60+ default MACH_X1830
61+ select INGENIC_CGU_COMMON
62+ help
63+ Support the clocks provided by the CGU hardware on Ingenic X1830
64+ and compatible SoCs.
65+
66+ If building for a X1830 SoC, you want to say Y here.
67+
5868 config INGENIC_TCU_CLK
5969 bool "Ingenic JZ47xx TCU clocks driver"
6070 default MACH_INGENIC
drivers/clk/ingenic/Makefile+1−0
@@ -5,4 +5,5 @@ obj-$(CONFIG_INGENIC_CGU_JZ4725B) += jz4725b-cgu.o · 4 unmodified lines
55 obj-$(CONFIG_INGENIC_CGU_JZ4770) += jz4770-cgu.o
66 obj-$(CONFIG_INGENIC_CGU_JZ4780) += jz4780-cgu.o
77 obj-$(CONFIG_INGENIC_CGU_X1000) += x1000-cgu.o
8+obj-$(CONFIG_INGENIC_CGU_X1830) += x1830-cgu.o
89 obj-$(CONFIG_INGENIC_TCU_CLK) += tcu.o
drivers/clk/ingenic/cgu.c+14−14
@@ -76,16 +76,13 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) · 75 unmodified lines
7676 const struct ingenic_cgu_pll_info *pll_info;
7777 unsigned m, n, od_enc, od;
7878 bool bypass;
79− unsigned long flags;
8079 u32 ctl;
8180
8281 clk_info = &cgu->clock_info[ingenic_clk->idx];
8382 BUG_ON(clk_info->type != CGU_CLK_PLL);
8483 pll_info = &clk_info->pll;
8584
86− spin_lock_irqsave(&cgu->lock, flags);
8785 ctl = readl(cgu->base + pll_info->reg);
88− spin_unlock_irqrestore(&cgu->lock, flags);
8986
9087 m = (ctl >> pll_info->m_shift) & GENMASK(pll_info->m_bits - 1, 0);
9188 m += pll_info->m_offset;
@@ -93,6 +90,9 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) · 1 unmodified line
9390 n += pll_info->n_offset;
9491 od_enc = ctl >> pll_info->od_shift;
9592 od_enc &= GENMASK(pll_info->od_bits - 1, 0);
93+
94+ ctl = readl(cgu->base + pll_info->bypass_reg);
95+
9696 bypass = !pll_info->no_bypass_bit &&
9797 !!(ctl & BIT(pll_info->bypass_bit));
9898
@@ -106,7 +106,8 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) · 7 unmodified lines
106106 BUG_ON(od == pll_info->od_max);
107107 od++;
108108
109− return div_u64((u64)parent_rate * m, n * od);
109+ return div_u64((u64)parent_rate * m * pll_info->rate_multiplier,
110+ n * od);
110111 }
111112
112113 static unsigned long
@@ -139,7 +140,8 @@ ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info, · 26 unmodified lines
139140 if (pod)
140141 *pod = od;
141142
142− return div_u64((u64)parent_rate * m, n * od);
143+ return div_u64((u64)parent_rate * m * pll_info->rate_multiplier,
144+ n * od);
143145 }
144146
145147 static inline const struct ingenic_cgu_clk_info *to_clk_info(
@@ -212,9 +214,14 @@ static int ingenic_pll_enable(struct clk_hw *hw) · 66 unmodified lines
212214 u32 ctl;
213215
214216 spin_lock_irqsave(&cgu->lock, flags);
215− ctl = readl(cgu->base + pll_info->reg);
217+ ctl = readl(cgu->base + pll_info->bypass_reg);
216218
217219 ctl &= ~BIT(pll_info->bypass_bit);
220+
221+ writel(ctl, cgu->base + pll_info->bypass_reg);
222+
223+ ctl = readl(cgu->base + pll_info->reg);
224+
218225 ctl |= BIT(pll_info->enable_bit);
219226
220227 writel(ctl, cgu->base + pll_info->reg);
@@ -259,12 +266,9 @@ static int ingenic_pll_is_enabled(struct clk_hw *hw) · 38 unmodified lines
259266 struct ingenic_cgu *cgu = ingenic_clk->cgu;
260267 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
261268 const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
262− unsigned long flags;
263269 u32 ctl;
264270
265− spin_lock_irqsave(&cgu->lock, flags);
266271 ctl = readl(cgu->base + pll_info->reg);
267− spin_unlock_irqrestore(&cgu->lock, flags);
268272
269273 return !!(ctl & BIT(pll_info->enable_bit));
270274 }
@@ -562,16 +566,12 @@ static int ingenic_clk_is_enabled(struct clk_hw *hw) · 291 unmodified lines
562566 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
563567 struct ingenic_cgu *cgu = ingenic_clk->cgu;
564568 const struct ingenic_cgu_clk_info *clk_info;
565− unsigned long flags;
566569 int enabled = 1;
567570
568571 clk_info = &cgu->clock_info[ingenic_clk->idx];
569572
570− if (clk_info->type & CGU_CLK_GATE) {
571− spin_lock_irqsave(&cgu->lock, flags);
573+ if (clk_info->type & CGU_CLK_GATE)
572574 enabled = !ingenic_cgu_gate_get(cgu, &clk_info->gate);
573− spin_unlock_irqrestore(&cgu->lock, flags);
574− }
575575
576576 return enabled;
577577 }
drivers/clk/ingenic/cgu.h+4−0
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717 /**
1818 * struct ingenic_cgu_pll_info - information about a PLL
1919 * @reg: the offset of the PLL's control register within the CGU
20+ * @rate_multiplier: the multiplier needed by pll rate calculation
2021 * @m_shift: the number of bits to shift the multiplier value by (ie. the
2122 * index of the lowest bit of the multiplier value in the PLL's
2223 * control register)
@@ -37,6 +38,7 @@ · 14 unmodified lines
3738 * @od_encoding: a pointer to an array mapping post-VCO divider values to
3839 * their encoded values in the PLL control register, or -1 for
3940 * unsupported values
41+ * @bypass_reg: the offset of the bypass control register within the CGU
4042 * @bypass_bit: the index of the bypass bit in the PLL control register
4143 * @enable_bit: the index of the enable bit in the PLL control register
4244 * @stable_bit: the index of the stable bit in the PLL control register
@@ -44,10 +46,12 @@ · 1 unmodified line
4446 */
4547 struct ingenic_cgu_pll_info {
4648 unsigned reg;
49+ unsigned rate_multiplier;
4750 const s8 *od_encoding;
4851 u8 m_shift, m_bits, m_offset;
4952 u8 n_shift, n_bits, n_offset;
5053 u8 od_shift, od_bits, od_max;
54+ unsigned bypass_reg;
5155 u8 bypass_bit;
5256 u8 enable_bit;
5357 u8 stable_bit;
drivers/clk/ingenic/jz4725b-cgu.c+4−0
@@ -9,7 +9,9 @@ · 8 unmodified lines
99 #include <linux/clk-provider.h>
1010 #include <linux/delay.h>
1111 #include <linux/of.h>
12+
1213 #include <dt-bindings/clock/jz4725b-cgu.h>
14+
1315 #include "cgu.h"
1416 #include "pm.h"
1517
@@ -54,6 +56,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = { · 38 unmodified lines
5456 .parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
5557 .pll = {
5658 .reg = CGU_REG_CPPCR,
59+ .rate_multiplier = 1,
5760 .m_shift = 23,
5861 .m_bits = 9,
5962 .m_offset = 2,
@@ -65,6 +68,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = { · 5 unmodified lines
6568 .od_max = 4,
6669 .od_encoding = pll_od_encoding,
6770 .stable_bit = 10,
71+ .bypass_reg = CGU_REG_CPPCR,
6872 .bypass_bit = 9,
6973 .enable_bit = 8,
7074 },
drivers/clk/ingenic/jz4740-cgu.c+4−0
@@ -10,7 +10,9 @@ · 9 unmodified lines
1010 #include <linux/delay.h>
1111 #include <linux/io.h>
1212 #include <linux/of.h>
13+
1314 #include <dt-bindings/clock/jz4740-cgu.h>
15+
1416 #include "cgu.h"
1517 #include "pm.h"
1618
@@ -69,6 +71,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = { · 52 unmodified lines
6971 .parents = { JZ4740_CLK_EXT, -1, -1, -1 },
7072 .pll = {
7173 .reg = CGU_REG_CPPCR,
74+ .rate_multiplier = 1,
7275 .m_shift = 23,
7376 .m_bits = 9,
7477 .m_offset = 2,
@@ -80,6 +83,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = { · 5 unmodified lines
8083 .od_max = 4,
8184 .od_encoding = pll_od_encoding,
8285 .stable_bit = 10,
86+ .bypass_reg = CGU_REG_CPPCR,
8387 .bypass_bit = 9,
8488 .enable_bit = 8,
8589 },
drivers/clk/ingenic/jz4770-cgu.c+7−1
@@ -9,7 +9,9 @@ · 8 unmodified lines
99 #include <linux/delay.h>
1010 #include <linux/io.h>
1111 #include <linux/of.h>
12+
1213 #include <dt-bindings/clock/jz4770-cgu.h>
14+
1315 #include "cgu.h"
1416 #include "pm.h"
1517
@@ -102,6 +104,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { · 86 unmodified lines
102104 .parents = { JZ4770_CLK_EXT },
103105 .pll = {
104106 .reg = CGU_REG_CPPCR0,
107+ .rate_multiplier = 1,
105108 .m_shift = 24,
106109 .m_bits = 7,
107110 .m_offset = 1,
@@ -112,6 +115,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { · 4 unmodified lines
112115 .od_bits = 2,
113116 .od_max = 8,
114117 .od_encoding = pll_od_encoding,
118+ .bypass_reg = CGU_REG_CPPCR0,
115119 .bypass_bit = 9,
116120 .enable_bit = 8,
117121 .stable_bit = 10,
@@ -124,6 +128,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { · 6 unmodified lines
124128 .parents = { JZ4770_CLK_EXT },
125129 .pll = {
126130 .reg = CGU_REG_CPPCR1,
131+ .rate_multiplier = 1,
127132 .m_shift = 24,
128133 .m_bits = 7,
129134 .m_offset = 1,
@@ -134,9 +139,10 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { · 4 unmodified lines
134139 .od_bits = 2,
135140 .od_max = 8,
136141 .od_encoding = pll_od_encoding,
142+ .bypass_reg = CGU_REG_CPPCR1,
143+ .no_bypass_bit = true,
137144 .enable_bit = 7,
138145 .stable_bit = 6,
139− .no_bypass_bit = true,
140146 },
141147 },
142148
drivers/clk/ingenic/jz4780-cgu.c+3−0
@@ -13,6 +13,7 @@ · 12 unmodified lines
1313 #include <linux/of.h>
1414
1515 #include <dt-bindings/clock/jz4780-cgu.h>
16+
1617 #include "cgu.h"
1718 #include "pm.h"
1819
@@ -266,6 +267,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = { · 247 unmodified lines
266267
267268 #define DEF_PLL(name) { \
268269 .reg = CGU_REG_ ## name, \
270+ .rate_multiplier = 1, \
269271 .m_shift = 19, \
270272 .m_bits = 13, \
271273 .m_offset = 1, \
@@ -277,6 +279,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = { · 5 unmodified lines
277279 .od_max = 16, \
278280 .od_encoding = pll_od_encoding, \
279281 .stable_bit = 6, \
282+ .bypass_reg = CGU_REG_ ## name, \
280283 .bypass_bit = 1, \
281284 .enable_bit = 0, \
282285 }
drivers/clk/ingenic/tcu.c+1−1
@@ -323,7 +323,7 @@ static const struct ingenic_soc_info x1000_soc_info = { · 322 unmodified lines
323323 .has_tcu_clk = false,
324324 };
325325
326−static const struct of_device_id ingenic_tcu_of_match[] __initconst = {
326+static const struct of_device_id __maybe_unused ingenic_tcu_of_match[] __initconst = {
327327 { .compatible = "ingenic,jz4740-tcu", .data = &jz4740_soc_info, },
328328 { .compatible = "ingenic,jz4725b-tcu", .data = &jz4725b_soc_info, },
329329 { .compatible = "ingenic,jz4770-tcu", .data = &jz4770_soc_info, },
drivers/clk/ingenic/x1000-cgu.c+117−6
@@ -1,13 +1,16 @@
11 // SPDX-License-Identifier: GPL-2.0
22 /*
33 * X1000 SoC CGU driver
4− * Copyright (c) 2019 Zhou Yanjie <zhouyanjie@zoho.com>
4+ * Copyright (c) 2019 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
55 */
66
77 #include <linux/clk-provider.h>
88 #include <linux/delay.h>
9+#include <linux/io.h>
910 #include <linux/of.h>
11+
1012 #include <dt-bindings/clock/x1000-cgu.h>
13+
1114 #include "cgu.h"
1215 #include "pm.h"
1316
@@ -18,6 +21,9 @@ · 4 unmodified lines
1821 #define CGU_REG_CLKGR 0x20
1922 #define CGU_REG_OPCR 0x24
2023 #define CGU_REG_DDRCDR 0x2c
24+#define CGU_REG_USBPCR 0x3c
25+#define CGU_REG_USBPCR1 0x48
26+#define CGU_REG_USBCDR 0x50
2127 #define CGU_REG_MACCDR 0x54
2228 #define CGU_REG_I2SCDR 0x60
2329 #define CGU_REG_LPCDR 0x64
@@ -38,8 +44,47 @@ · 14 unmodified lines
3844 #define OPCR_SPENDN0 BIT(7)
3945 #define OPCR_SPENDN1 BIT(6)
4046
47+/* bits within the USBPCR register */
48+#define USBPCR_SIDDQ BIT(21)
49+#define USBPCR_OTG_DISABLE BIT(20)
50+
4151 static struct ingenic_cgu *cgu;
4252
53+static int x1000_usb_phy_enable(struct clk_hw *hw)
54+{
55+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
56+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
57+
58+ writel(readl(reg_opcr) | OPCR_SPENDN0, reg_opcr);
59+ writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr);
60+ return 0;
61+}
62+
63+static void x1000_usb_phy_disable(struct clk_hw *hw)
64+{
65+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
66+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
67+
68+ writel(readl(reg_opcr) & ~OPCR_SPENDN0, reg_opcr);
69+ writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr);
70+}
71+
72+static int x1000_usb_phy_is_enabled(struct clk_hw *hw)
73+{
74+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
75+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
76+
77+ return (readl(reg_opcr) & OPCR_SPENDN0) &&
78+ !(readl(reg_usbpcr) & USBPCR_SIDDQ) &&
79+ !(readl(reg_usbpcr) & USBPCR_OTG_DISABLE);
80+}
81+
82+static const struct clk_ops x1000_otg_phy_ops = {
83+ .enable = x1000_usb_phy_enable,
84+ .disable = x1000_usb_phy_disable,
85+ .is_enabled = x1000_usb_phy_is_enabled,
86+};
87+
4388 static const s8 pll_od_encoding[8] = {
4489 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3,
4590 };
@@ -58,6 +103,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = { · 12 unmodified lines
58103 .parents = { X1000_CLK_EXCLK, -1, -1, -1 },
59104 .pll = {
60105 .reg = CGU_REG_APLL,
106+ .rate_multiplier = 1,
61107 .m_shift = 24,
62108 .m_bits = 7,
63109 .m_offset = 1,
@@ -68,6 +114,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = { · 4 unmodified lines
68114 .od_bits = 2,
69115 .od_max = 8,
70116 .od_encoding = pll_od_encoding,
117+ .bypass_reg = CGU_REG_APLL,
71118 .bypass_bit = 9,
72119 .enable_bit = 8,
73120 .stable_bit = 10,
@@ -79,6 +126,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = { · 5 unmodified lines
79126 .parents = { X1000_CLK_EXCLK, -1, -1, -1 },
80127 .pll = {
81128 .reg = CGU_REG_MPLL,
129+ .rate_multiplier = 1,
82130 .m_shift = 24,
83131 .m_bits = 7,
84132 .m_offset = 1,
@@ -89,12 +137,22 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = { · 4 unmodified lines
89137 .od_bits = 2,
90138 .od_max = 8,
91139 .od_encoding = pll_od_encoding,
140+ .bypass_reg = CGU_REG_MPLL,
92141 .bypass_bit = 6,
93142 .enable_bit = 7,
94143 .stable_bit = 0,
95144 },
96145 },
97146
147+
148+ /* Custom (SoC-specific) OTG PHY */
149+
150+ [X1000_CLK_OTGPHY] = {
151+ "otg_phy", CGU_CLK_CUSTOM,
152+ .parents = { -1, -1, X1000_CLK_EXCLK, -1 },
153+ .custom = { &x1000_otg_phy_ops },
154+ },
155+
98156 /* Muxes & dividers */
99157
100158 [X1000_CLK_SCLKA] = {
@@ -110,9 +168,10 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = { · 9 unmodified lines
110168 },
111169
112170 [X1000_CLK_CPU] = {
113− "cpu", CGU_CLK_DIV,
171+ "cpu", CGU_CLK_DIV | CGU_CLK_GATE,
114172 .parents = { X1000_CLK_CPUMUX, -1, -1, -1 },
115173 .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
174+ .gate = { CGU_REG_CLKGR, 30 },
116175 },
117176
118177 [X1000_CLK_L2CACHE] = {
@@ -141,9 +200,10 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = { · 22 unmodified lines
141200 },
142201
143202 [X1000_CLK_PCLK] = {
144− "pclk", CGU_CLK_DIV,
203+ "pclk", CGU_CLK_DIV | CGU_CLK_GATE,
145204 .parents = { X1000_CLK_AHB2PMUX, -1, -1, -1 },
146205 .div = { CGU_REG_CPCCR, 16, 1, 4, 20, -1, -1 },
206+ .gate = { CGU_REG_CLKGR, 28 },
147207 },
148208
149209 [X1000_CLK_DDR] = {
@@ -156,12 +216,20 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = { · 6 unmodified lines
156216
157217 [X1000_CLK_MAC] = {
158218 "mac", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
159− .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL},
219+ .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL },
160220 .mux = { CGU_REG_MACCDR, 31, 1 },
161221 .div = { CGU_REG_MACCDR, 0, 1, 8, 29, 28, 27 },
162222 .gate = { CGU_REG_CLKGR, 25 },
163223 },
164224
225+ [X1000_CLK_LCD] = {
226+ "lcd", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
227+ .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL },
228+ .mux = { CGU_REG_LPCDR, 31, 1 },
229+ .div = { CGU_REG_LPCDR, 0, 1, 8, 28, 27, 26 },
230+ .gate = { CGU_REG_CLKGR, 23 },
231+ },
232+
165233 [X1000_CLK_MSCMUX] = {
166234 "msc_mux", CGU_CLK_MUX,
167235 .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL},
@@ -182,6 +250,15 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = { · 14 unmodified lines
182250 .gate = { CGU_REG_CLKGR, 5 },
183251 },
184252
253+ [X1000_CLK_OTG] = {
254+ "otg", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
255+ .parents = { X1000_CLK_EXCLK, -1,
256+ X1000_CLK_APLL, X1000_CLK_MPLL },
257+ .mux = { CGU_REG_USBCDR, 30, 2 },
258+ .div = { CGU_REG_USBCDR, 0, 1, 8, 29, 28, 27 },
259+ .gate = { CGU_REG_CLKGR, 3 },
260+ },
261+
185262 [X1000_CLK_SSIPLL] = {
186263 "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
187264 .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL, -1, -1 },
@@ -189,14 +266,32 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = { · 1 unmodified line
189266 .div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 },
190267 },
191268
269+ [X1000_CLK_SSIPLL_DIV2] = {
270+ "ssi_pll_div2", CGU_CLK_FIXDIV,
271+ .parents = { X1000_CLK_SSIPLL },
272+ .fixdiv = { 2 },
273+ },
274+
192275 [X1000_CLK_SSIMUX] = {
193276 "ssi_mux", CGU_CLK_MUX,
194− .parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL, -1, -1 },
277+ .parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL_DIV2, -1, -1 },
195278 .mux = { CGU_REG_SSICDR, 30, 1 },
196279 },
197280
198281 /* Gate-only clocks */
199282
283+ [X1000_CLK_EMC] = {
284+ "emc", CGU_CLK_GATE,
285+ .parents = { X1000_CLK_AHB2, -1, -1, -1 },
286+ .gate = { CGU_REG_CLKGR, 0 },
287+ },
288+
289+ [X1000_CLK_EFUSE] = {
290+ "efuse", CGU_CLK_GATE,
291+ .parents = { X1000_CLK_AHB2, -1, -1, -1 },
292+ .gate = { CGU_REG_CLKGR, 1 },
293+ },
294+
200295 [X1000_CLK_SFC] = {
201296 "sfc", CGU_CLK_GATE,
202297 .parents = { X1000_CLK_SSIPLL, -1, -1, -1 },
@@ -239,12 +334,24 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = { · 36 unmodified lines
239334 .gate = { CGU_REG_CLKGR, 16 },
240335 },
241336
337+ [X1000_CLK_TCU] = {
338+ "tcu", CGU_CLK_GATE,
339+ .parents = { X1000_CLK_EXCLK, -1, -1, -1 },
340+ .gate = { CGU_REG_CLKGR, 18 },
341+ },
342+
242343 [X1000_CLK_SSI] = {
243344 "ssi", CGU_CLK_GATE,
244345 .parents = { X1000_CLK_SSIMUX, -1, -1, -1 },
245346 .gate = { CGU_REG_CLKGR, 19 },
246347 },
247348
349+ [X1000_CLK_OST] = {
350+ "ost", CGU_CLK_GATE,
351+ .parents = { X1000_CLK_EXCLK, -1, -1, -1 },
352+ .gate = { CGU_REG_CLKGR, 20 },
353+ },
354+
248355 [X1000_CLK_PDMA] = {
249356 "pdma", CGU_CLK_GATE,
250357 .parents = { X1000_CLK_EXCLK, -1, -1, -1 },
@@ -271,4 +378,8 @@ static void __init x1000_cgu_init(struct device_node *np) · 20 unmodified lines
271378
272379 ingenic_cgu_register_syscore_ops(cgu);
273380 }
274−CLK_OF_DECLARE(x1000_cgu, "ingenic,x1000-cgu", x1000_cgu_init);
381+/*
382+ * CGU has some children devices, this is useful for probing children devices
383+ * in the case where the device node is compatible with "simple-mfd".
384+ */
385+CLK_OF_DECLARE_DRIVER(x1000_cgu, "ingenic,x1000-cgu", x1000_cgu_init);
drivers/clk/ingenic/x1830-cgu.c+448−0
@@ -0,0 +1,448 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * X1830 SoC CGU driver
4+ * Copyright (c) 2019 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
5+ */
6+
7+#include <linux/clk-provider.h>
8+#include <linux/delay.h>
9+#include <linux/io.h>
10+#include <linux/of.h>
11+
12+#include <dt-bindings/clock/x1830-cgu.h>
13+
14+#include "cgu.h"
15+#include "pm.h"
16+
17+/* CGU register offsets */
18+#define CGU_REG_CPCCR 0x00
19+#define CGU_REG_CPPCR 0x0c
20+#define CGU_REG_APLL 0x10
21+#define CGU_REG_MPLL 0x14
22+#define CGU_REG_CLKGR0 0x20
23+#define CGU_REG_OPCR 0x24
24+#define CGU_REG_CLKGR1 0x28
25+#define CGU_REG_DDRCDR 0x2c
26+#define CGU_REG_USBPCR 0x3c
27+#define CGU_REG_USBRDT 0x40
28+#define CGU_REG_USBVBFIL 0x44
29+#define CGU_REG_USBPCR1 0x48
30+#define CGU_REG_MACCDR 0x54
31+#define CGU_REG_EPLL 0x58
32+#define CGU_REG_I2SCDR 0x60
33+#define CGU_REG_LPCDR 0x64
34+#define CGU_REG_MSC0CDR 0x68
35+#define CGU_REG_I2SCDR1 0x70
36+#define CGU_REG_SSICDR 0x74
37+#define CGU_REG_CIMCDR 0x7c
38+#define CGU_REG_MSC1CDR 0xa4
39+#define CGU_REG_CMP_INTR 0xb0
40+#define CGU_REG_CMP_INTRE 0xb4
41+#define CGU_REG_DRCG 0xd0
42+#define CGU_REG_CPCSR 0xd4
43+#define CGU_REG_VPLL 0xe0
44+#define CGU_REG_MACPHYC 0xe8
45+
46+/* bits within the OPCR register */
47+#define OPCR_GATE_USBPHYCLK BIT(23)
48+#define OPCR_SPENDN0 BIT(7)
49+#define OPCR_SPENDN1 BIT(6)
50+
51+/* bits within the USBPCR register */
52+#define USBPCR_SIDDQ BIT(21)
53+#define USBPCR_OTG_DISABLE BIT(20)
54+
55+static struct ingenic_cgu *cgu;
56+
57+static int x1830_usb_phy_enable(struct clk_hw *hw)
58+{
59+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
60+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
61+
62+ writel((readl(reg_opcr) | OPCR_SPENDN0) & ~OPCR_GATE_USBPHYCLK, reg_opcr);
63+ writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr);
64+ return 0;
65+}
66+
67+static void x1830_usb_phy_disable(struct clk_hw *hw)
68+{
69+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
70+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
71+
72+ writel((readl(reg_opcr) & ~OPCR_SPENDN0) | OPCR_GATE_USBPHYCLK, reg_opcr);
73+ writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr);
74+}
75+
76+static int x1830_usb_phy_is_enabled(struct clk_hw *hw)
77+{
78+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
79+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
80+
81+ return (readl(reg_opcr) & OPCR_SPENDN0) &&
82+ !(readl(reg_usbpcr) & USBPCR_SIDDQ) &&
83+ !(readl(reg_usbpcr) & USBPCR_OTG_DISABLE);
84+}
85+
86+static const struct clk_ops x1830_otg_phy_ops = {
87+ .enable = x1830_usb_phy_enable,
88+ .disable = x1830_usb_phy_disable,
89+ .is_enabled = x1830_usb_phy_is_enabled,
90+};
91+
92+static const s8 pll_od_encoding[64] = {
93+ 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3,
94+ -1, -1, -1, -1, -1, -1, -1, 0x4,
95+ -1, -1, -1, -1, -1, -1, -1, -1,
96+ -1, -1, -1, -1, -1, -1, -1, 0x5,
97+ -1, -1, -1, -1, -1, -1, -1, -1,
98+ -1, -1, -1, -1, -1, -1, -1, -1,
99+ -1, -1, -1, -1, -1, -1, -1, -1,
100+ -1, -1, -1, -1, -1, -1, -1, 0x6,
101+};
102+
103+static const struct ingenic_cgu_clk_info x1830_cgu_clocks[] = {
104+
105+ /* External clocks */
106+
107+ [X1830_CLK_EXCLK] = { "ext", CGU_CLK_EXT },
108+ [X1830_CLK_RTCLK] = { "rtc", CGU_CLK_EXT },
109+
110+ /* PLLs */
111+
112+ [X1830_CLK_APLL] = {
113+ "apll", CGU_CLK_PLL,
114+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
115+ .pll = {
116+ .reg = CGU_REG_APLL,
117+ .rate_multiplier = 2,
118+ .m_shift = 20,
119+ .m_bits = 9,
120+ .m_offset = 1,
121+ .n_shift = 14,
122+ .n_bits = 6,
123+ .n_offset = 1,
124+ .od_shift = 11,
125+ .od_bits = 3,
126+ .od_max = 64,
127+ .od_encoding = pll_od_encoding,
128+ .bypass_reg = CGU_REG_CPPCR,
129+ .bypass_bit = 30,
130+ .enable_bit = 0,
131+ .stable_bit = 3,
132+ },
133+ },
134+
135+ [X1830_CLK_MPLL] = {
136+ "mpll", CGU_CLK_PLL,
137+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
138+ .pll = {
139+ .reg = CGU_REG_MPLL,
140+ .rate_multiplier = 2,
141+ .m_shift = 20,
142+ .m_bits = 9,
143+ .m_offset = 1,
144+ .n_shift = 14,
145+ .n_bits = 6,
146+ .n_offset = 1,
147+ .od_shift = 11,
148+ .od_bits = 3,
149+ .od_max = 64,
150+ .od_encoding = pll_od_encoding,
151+ .bypass_reg = CGU_REG_CPPCR,
152+ .bypass_bit = 28,
153+ .enable_bit = 0,
154+ .stable_bit = 3,
155+ },
156+ },
157+
158+ [X1830_CLK_EPLL] = {
159+ "epll", CGU_CLK_PLL,
160+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
161+ .pll = {
162+ .reg = CGU_REG_EPLL,
163+ .rate_multiplier = 2,
164+ .m_shift = 20,
165+ .m_bits = 9,
166+ .m_offset = 1,
167+ .n_shift = 14,
168+ .n_bits = 6,
169+ .n_offset = 1,
170+ .od_shift = 11,
171+ .od_bits = 3,
172+ .od_max = 64,
173+ .od_encoding = pll_od_encoding,
174+ .bypass_reg = CGU_REG_CPPCR,
175+ .bypass_bit = 24,
176+ .enable_bit = 0,
177+ .stable_bit = 3,
178+ },
179+ },
180+
181+ [X1830_CLK_VPLL] = {
182+ "vpll", CGU_CLK_PLL,
183+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
184+ .pll = {
185+ .reg = CGU_REG_VPLL,
186+ .rate_multiplier = 2,
187+ .m_shift = 20,
188+ .m_bits = 9,
189+ .m_offset = 1,
190+ .n_shift = 14,
191+ .n_bits = 6,
192+ .n_offset = 1,
193+ .od_shift = 11,
194+ .od_bits = 3,
195+ .od_max = 64,
196+ .od_encoding = pll_od_encoding,
197+ .bypass_reg = CGU_REG_CPPCR,
198+ .bypass_bit = 26,
199+ .enable_bit = 0,
200+ .stable_bit = 3,
201+ },
202+ },
203+
204+ /* Custom (SoC-specific) OTG PHY */
205+
206+ [X1830_CLK_OTGPHY] = {
207+ "otg_phy", CGU_CLK_CUSTOM,
208+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
209+ .custom = { &x1830_otg_phy_ops },
210+ },
211+
212+ /* Muxes & dividers */
213+
214+ [X1830_CLK_SCLKA] = {
215+ "sclk_a", CGU_CLK_MUX,
216+ .parents = { -1, X1830_CLK_EXCLK, X1830_CLK_APLL, -1 },
217+ .mux = { CGU_REG_CPCCR, 30, 2 },
218+ },
219+
220+ [X1830_CLK_CPUMUX] = {
221+ "cpu_mux", CGU_CLK_MUX,
222+ .parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
223+ .mux = { CGU_REG_CPCCR, 28, 2 },
224+ },
225+
226+ [X1830_CLK_CPU] = {
227+ "cpu", CGU_CLK_DIV | CGU_CLK_GATE,
228+ .parents = { X1830_CLK_CPUMUX, -1, -1, -1 },
229+ .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
230+ .gate = { CGU_REG_CLKGR1, 15 },
231+ },
232+
233+ [X1830_CLK_L2CACHE] = {
234+ "l2cache", CGU_CLK_DIV,
235+ .parents = { X1830_CLK_CPUMUX, -1, -1, -1 },
236+ .div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 },
237+ },
238+
239+ [X1830_CLK_AHB0] = {
240+ "ahb0", CGU_CLK_MUX | CGU_CLK_DIV,
241+ .parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
242+ .mux = { CGU_REG_CPCCR, 26, 2 },
243+ .div = { CGU_REG_CPCCR, 8, 1, 4, 21, -1, -1 },
244+ },
245+
246+ [X1830_CLK_AHB2PMUX] = {
247+ "ahb2_apb_mux", CGU_CLK_MUX,
248+ .parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
249+ .mux = { CGU_REG_CPCCR, 24, 2 },
250+ },
251+
252+ [X1830_CLK_AHB2] = {
253+ "ahb2", CGU_CLK_DIV,
254+ .parents = { X1830_CLK_AHB2PMUX, -1, -1, -1 },
255+ .div = { CGU_REG_CPCCR, 12, 1, 4, 20, -1, -1 },
256+ },
257+
258+ [X1830_CLK_PCLK] = {
259+ "pclk", CGU_CLK_DIV | CGU_CLK_GATE,
260+ .parents = { X1830_CLK_AHB2PMUX, -1, -1, -1 },
261+ .div = { CGU_REG_CPCCR, 16, 1, 4, 20, -1, -1 },
262+ .gate = { CGU_REG_CLKGR1, 14 },
263+ },
264+
265+ [X1830_CLK_DDR] = {
266+ "ddr", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
267+ .parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
268+ .mux = { CGU_REG_DDRCDR, 30, 2 },
269+ .div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 },
270+ .gate = { CGU_REG_CLKGR0, 31 },
271+ },
272+
273+ [X1830_CLK_MAC] = {
274+ "mac", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
275+ .parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
276+ X1830_CLK_VPLL, X1830_CLK_EPLL },
277+ .mux = { CGU_REG_MACCDR, 30, 2 },
278+ .div = { CGU_REG_MACCDR, 0, 1, 8, 29, 28, 27 },
279+ .gate = { CGU_REG_CLKGR1, 4 },
280+ },
281+
282+ [X1830_CLK_LCD] = {
283+ "lcd", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
284+ .parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
285+ X1830_CLK_VPLL, X1830_CLK_EPLL },
286+ .mux = { CGU_REG_LPCDR, 30, 2 },
287+ .div = { CGU_REG_LPCDR, 0, 1, 8, 28, 27, 26 },
288+ .gate = { CGU_REG_CLKGR1, 9 },
289+ },
290+
291+ [X1830_CLK_MSCMUX] = {
292+ "msc_mux", CGU_CLK_MUX,
293+ .parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
294+ X1830_CLK_VPLL, X1830_CLK_EPLL },
295+ .mux = { CGU_REG_MSC0CDR, 30, 2 },
296+ },
297+
298+ [X1830_CLK_MSC0] = {
299+ "msc0", CGU_CLK_DIV | CGU_CLK_GATE,
300+ .parents = { X1830_CLK_MSCMUX, -1, -1, -1 },
301+ .div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 },
302+ .gate = { CGU_REG_CLKGR0, 4 },
303+ },
304+
305+ [X1830_CLK_MSC1] = {
306+ "msc1", CGU_CLK_DIV | CGU_CLK_GATE,
307+ .parents = { X1830_CLK_MSCMUX, -1, -1, -1 },
308+ .div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 },
309+ .gate = { CGU_REG_CLKGR0, 5 },
310+ },
311+
312+ [X1830_CLK_SSIPLL] = {
313+ "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
314+ .parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
315+ X1830_CLK_VPLL, X1830_CLK_EPLL },
316+ .mux = { CGU_REG_SSICDR, 30, 2 },
317+ .div = { CGU_REG_SSICDR, 0, 1, 8, 28, 27, 26 },
318+ },
319+
320+ [X1830_CLK_SSIPLL_DIV2] = {
321+ "ssi_pll_div2", CGU_CLK_FIXDIV,
322+ .parents = { X1830_CLK_SSIPLL },
323+ .fixdiv = { 2 },
324+ },
325+
326+ [X1830_CLK_SSIMUX] = {
327+ "ssi_mux", CGU_CLK_MUX,
328+ .parents = { X1830_CLK_EXCLK, X1830_CLK_SSIPLL_DIV2, -1, -1 },
329+ .mux = { CGU_REG_SSICDR, 29, 1 },
330+ },
331+
332+ /* Gate-only clocks */
333+
334+ [X1830_CLK_EMC] = {
335+ "emc", CGU_CLK_GATE,
336+ .parents = { X1830_CLK_AHB2, -1, -1, -1 },
337+ .gate = { CGU_REG_CLKGR0, 0 },
338+ },
339+
340+ [X1830_CLK_EFUSE] = {
341+ "efuse", CGU_CLK_GATE,
342+ .parents = { X1830_CLK_AHB2, -1, -1, -1 },
343+ .gate = { CGU_REG_CLKGR0, 1 },
344+ },
345+
346+ [X1830_CLK_OTG] = {
347+ "otg", CGU_CLK_GATE,
348+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
349+ .gate = { CGU_REG_CLKGR0, 3 },
350+ },
351+
352+ [X1830_CLK_SSI0] = {
353+ "ssi0", CGU_CLK_GATE,
354+ .parents = { X1830_CLK_SSIMUX, -1, -1, -1 },
355+ .gate = { CGU_REG_CLKGR0, 6 },
356+ },
357+
358+ [X1830_CLK_SMB0] = {
359+ "smb0", CGU_CLK_GATE,
360+ .parents = { X1830_CLK_PCLK, -1, -1, -1 },
361+ .gate = { CGU_REG_CLKGR0, 7 },
362+ },
363+
364+ [X1830_CLK_SMB1] = {
365+ "smb1", CGU_CLK_GATE,
366+ .parents = { X1830_CLK_PCLK, -1, -1, -1 },
367+ .gate = { CGU_REG_CLKGR0, 8 },
368+ },
369+
370+ [X1830_CLK_SMB2] = {
371+ "smb2", CGU_CLK_GATE,
372+ .parents = { X1830_CLK_PCLK, -1, -1, -1 },
373+ .gate = { CGU_REG_CLKGR0, 9 },
374+ },
375+
376+ [X1830_CLK_UART0] = {
377+ "uart0", CGU_CLK_GATE,
378+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
379+ .gate = { CGU_REG_CLKGR0, 14 },
380+ },
381+
382+ [X1830_CLK_UART1] = {
383+ "uart1", CGU_CLK_GATE,
384+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
385+ .gate = { CGU_REG_CLKGR0, 15 },
386+ },
387+
388+ [X1830_CLK_SSI1] = {
389+ "ssi1", CGU_CLK_GATE,
390+ .parents = { X1830_CLK_SSIMUX, -1, -1, -1 },
391+ .gate = { CGU_REG_CLKGR0, 19 },
392+ },
393+
394+ [X1830_CLK_SFC] = {
395+ "sfc", CGU_CLK_GATE,
396+ .parents = { X1830_CLK_SSIPLL, -1, -1, -1 },
397+ .gate = { CGU_REG_CLKGR0, 20 },
398+ },
399+
400+ [X1830_CLK_PDMA] = {
401+ "pdma", CGU_CLK_GATE,
402+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
403+ .gate = { CGU_REG_CLKGR0, 21 },
404+ },
405+
406+ [X1830_CLK_TCU] = {
407+ "tcu", CGU_CLK_GATE,
408+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
409+ .gate = { CGU_REG_CLKGR0, 30 },
410+ },
411+
412+ [X1830_CLK_DTRNG] = {
413+ "dtrng", CGU_CLK_GATE,
414+ .parents = { X1830_CLK_PCLK, -1, -1, -1 },
415+ .gate = { CGU_REG_CLKGR1, 1 },
416+ },
417+
418+ [X1830_CLK_OST] = {
419+ "ost", CGU_CLK_GATE,
420+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
421+ .gate = { CGU_REG_CLKGR1, 11 },
422+ },
423+};
424+
425+static void __init x1830_cgu_init(struct device_node *np)
426+{
427+ int retval;
428+
429+ cgu = ingenic_cgu_new(x1830_cgu_clocks,
430+ ARRAY_SIZE(x1830_cgu_clocks), np);
431+ if (!cgu) {
432+ pr_err("%s: failed to initialise CGU\n", __func__);
433+ return;
434+ }
435+
436+ retval = ingenic_cgu_register_clocks(cgu);
437+ if (retval) {
438+ pr_err("%s: failed to register CGU Clocks\n", __func__);
439+ return;
440+ }
441+
442+ ingenic_cgu_register_syscore_ops(cgu);
443+}
444+/*
445+ * CGU has some children devices, this is useful for probing children devices
446+ * in the case where the device node is compatible with "simple-mfd".
447+ */
448+CLK_OF_DECLARE_DRIVER(x1830_cgu, "ingenic,x1830-cgu", x1830_cgu_init);
drivers/clk/mediatek/Kconfig+86−0
@@ -117,6 +117,92 @@ config COMMON_CLK_MT2712_VENCSYS · 116 unmodified lines
117117 ---help---
118118 This driver supports MediaTek MT2712 vencsys clocks.
119119
120+config COMMON_CLK_MT6765
121+ bool "Clock driver for MediaTek MT6765"
122+ depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
123+ select COMMON_CLK_MEDIATEK
124+ default ARCH_MEDIATEK && ARM64
125+ help
126+ This driver supports MediaTek MT6765 basic clocks.
127+
128+config COMMON_CLK_MT6765_AUDIOSYS
129+ bool "Clock driver for MediaTek MT6765 audiosys"
130+ depends on COMMON_CLK_MT6765
131+ help
132+ This driver supports MediaTek MT6765 audiosys clocks.
133+
134+config COMMON_CLK_MT6765_CAMSYS
135+ bool "Clock driver for MediaTek MT6765 camsys"
136+ depends on COMMON_CLK_MT6765
137+ help
138+ This driver supports MediaTek MT6765 camsys clocks.
139+
140+config COMMON_CLK_MT6765_GCESYS
141+ bool "Clock driver for MediaTek MT6765 gcesys"
142+ depends on COMMON_CLK_MT6765
143+ help
144+ This driver supports MediaTek MT6765 gcesys clocks.
145+
146+config COMMON_CLK_MT6765_MMSYS
147+ bool "Clock driver for MediaTek MT6765 mmsys"
148+ depends on COMMON_CLK_MT6765
149+ help
150+ This driver supports MediaTek MT6765 mmsys clocks.
151+
152+config COMMON_CLK_MT6765_IMGSYS
153+ bool "Clock driver for MediaTek MT6765 imgsys"
154+ depends on COMMON_CLK_MT6765
155+ help
156+ This driver supports MediaTek MT6765 imgsys clocks.
157+
158+config COMMON_CLK_MT6765_VCODECSYS
159+ bool "Clock driver for MediaTek MT6765 vcodecsys"
160+ depends on COMMON_CLK_MT6765
161+ help
162+ This driver supports MediaTek MT6765 vcodecsys clocks.
163+
164+config COMMON_CLK_MT6765_MFGSYS
165+ bool "Clock driver for MediaTek MT6765 mfgsys"
166+ depends on COMMON_CLK_MT6765
167+ help
168+ This driver supports MediaTek MT6765 mfgsys clocks.
169+
170+config COMMON_CLK_MT6765_MIPI0ASYS
171+ bool "Clock driver for MediaTek MT6765 mipi0asys"
172+ depends on COMMON_CLK_MT6765
173+ help
174+ This driver supports MediaTek MT6765 mipi0asys clocks.
175+
176+config COMMON_CLK_MT6765_MIPI0BSYS
177+ bool "Clock driver for MediaTek MT6765 mipi0bsys"
178+ depends on COMMON_CLK_MT6765
179+ help
180+ This driver supports MediaTek MT6765 mipi0bsys clocks.
181+
182+config COMMON_CLK_MT6765_MIPI1ASYS
183+ bool "Clock driver for MediaTek MT6765 mipi1asys"
184+ depends on COMMON_CLK_MT6765
185+ help
186+ This driver supports MediaTek MT6765 mipi1asys clocks.
187+
188+config COMMON_CLK_MT6765_MIPI1BSYS
189+ bool "Clock driver for MediaTek MT6765 mipi1bsys"
190+ depends on COMMON_CLK_MT6765
191+ help
192+ This driver supports MediaTek MT6765 mipi1bsys clocks.
193+
194+config COMMON_CLK_MT6765_MIPI2ASYS
195+ bool "Clock driver for MediaTek MT6765 mipi2asys"
196+ depends on COMMON_CLK_MT6765
197+ help
198+ This driver supports MediaTek MT6765 mipi2asys clocks.
199+
200+config COMMON_CLK_MT6765_MIPI2BSYS
201+ bool "Clock driver for MediaTek MT6765 mipi2bsys"
202+ depends on COMMON_CLK_MT6765
203+ help
204+ This driver supports MediaTek MT6765 mipi2bsys clocks.
205+
120206 config COMMON_CLK_MT6779
121207 bool "Clock driver for MediaTek MT6779"
122208 depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
drivers/clk/mediatek/Makefile+7−0
@@ -1,6 +1,13 @@
11 # SPDX-License-Identifier: GPL-2.0
22 obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o clk-mux.o
33
4+obj-$(CONFIG_COMMON_CLK_MT6765) += clk-mt6765.o
5+obj-$(CONFIG_COMMON_CLK_MT6765_AUDIOSYS) += clk-mt6765-audio.o
6+obj-$(CONFIG_COMMON_CLK_MT6765_CAMSYS) += clk-mt6765-cam.o
7+obj-$(CONFIG_COMMON_CLK_MT6765_IMGSYS) += clk-mt6765-img.o
8+obj-$(CONFIG_COMMON_CLK_MT6765_MIPI0ASYS) += clk-mt6765-mipi0a.o
9+obj-$(CONFIG_COMMON_CLK_MT6765_MMSYS) += clk-mt6765-mm.o
10+obj-$(CONFIG_COMMON_CLK_MT6765_VCODECSYS) += clk-mt6765-vcodec.o
411 obj-$(CONFIG_COMMON_CLK_MT6779) += clk-mt6779.o
512 obj-$(CONFIG_COMMON_CLK_MT6779_MMSYS) += clk-mt6779-mm.o
613 obj-$(CONFIG_COMMON_CLK_MT6779_IMGSYS) += clk-mt6779-img.o
drivers/clk/mediatek/clk-mt6765-audio.c+100−0
@@ -0,0 +1,100 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (c) 2018 MediaTek Inc.
4+ * Author: Owen Chen <owen.chen@mediatek.com>
5+ */
6+
7+#include <linux/clk-provider.h>
8+#include <linux/platform_device.h>
9+
10+#include "clk-mtk.h"
11+#include "clk-gate.h"
12+
13+#include <dt-bindings/clock/mt6765-clk.h>
14+
15+static const struct mtk_gate_regs audio0_cg_regs = {
16+ .set_ofs = 0x0,
17+ .clr_ofs = 0x0,
18+ .sta_ofs = 0x0,
19+};
20+
21+static const struct mtk_gate_regs audio1_cg_regs = {
22+ .set_ofs = 0x4,
23+ .clr_ofs = 0x4,
24+ .sta_ofs = 0x4,
25+};
26+
27+#define GATE_AUDIO0(_id, _name, _parent, _shift) { \
28+ .id = _id, \
29+ .name = _name, \
30+ .parent_name = _parent, \
31+ .regs = &audio0_cg_regs, \
32+ .shift = _shift, \
33+ .ops = &mtk_clk_gate_ops_no_setclr, \
34+ }
35+
36+#define GATE_AUDIO1(_id, _name, _parent, _shift) { \
37+ .id = _id, \
38+ .name = _name, \
39+ .parent_name = _parent, \
40+ .regs = &audio1_cg_regs, \
41+ .shift = _shift, \
42+ .ops = &mtk_clk_gate_ops_no_setclr, \
43+ }
44+
45+static const struct mtk_gate audio_clks[] = {
46+ /* AUDIO0 */
47+ GATE_AUDIO0(CLK_AUDIO_AFE, "aud_afe", "audio_ck", 2),
48+ GATE_AUDIO0(CLK_AUDIO_22M, "aud_22m", "aud_engen1_ck", 8),
49+ GATE_AUDIO0(CLK_AUDIO_APLL_TUNER, "aud_apll_tuner",
50+ "aud_engen1_ck", 19),
51+ GATE_AUDIO0(CLK_AUDIO_ADC, "aud_adc", "audio_ck", 24),
52+ GATE_AUDIO0(CLK_AUDIO_DAC, "aud_dac", "audio_ck", 25),
53+ GATE_AUDIO0(CLK_AUDIO_DAC_PREDIS, "aud_dac_predis",
54+ "audio_ck", 26),
55+ GATE_AUDIO0(CLK_AUDIO_TML, "aud_tml", "audio_ck", 27),
56+ /* AUDIO1 */
57+ GATE_AUDIO1(CLK_AUDIO_I2S1_BCLK, "aud_i2s1_bclk",
58+ "audio_ck", 4),
59+ GATE_AUDIO1(CLK_AUDIO_I2S2_BCLK, "aud_i2s2_bclk",
60+ "audio_ck", 5),
61+ GATE_AUDIO1(CLK_AUDIO_I2S3_BCLK, "aud_i2s3_bclk",
62+ "audio_ck", 6),
63+ GATE_AUDIO1(CLK_AUDIO_I2S4_BCLK, "aud_i2s4_bclk",
64+ "audio_ck", 7),
65+};
66+
67+static int clk_mt6765_audio_probe(struct platform_device *pdev)
68+{
69+ struct clk_onecell_data *clk_data;
70+ int r;
71+ struct device_node *node = pdev->dev.of_node;
72+
73+ clk_data = mtk_alloc_clk_data(CLK_AUDIO_NR_CLK);
74+
75+ mtk_clk_register_gates(node, audio_clks,
76+ ARRAY_SIZE(audio_clks), clk_data);
77+
78+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
79+
80+ if (r)
81+ pr_err("%s(): could not register clock provider: %d\n",
82+ __func__, r);
83+
84+ return r;
85+}
86+
87+static const struct of_device_id of_match_clk_mt6765_audio[] = {
88+ { .compatible = "mediatek,mt6765-audsys", },
89+ {}
90+};
91+
92+static struct platform_driver clk_mt6765_audio_drv = {
93+ .probe = clk_mt6765_audio_probe,
94+ .driver = {
95+ .name = "clk-mt6765-audio",
96+ .of_match_table = of_match_clk_mt6765_audio,
97+ },
98+};
99+
100+builtin_platform_driver(clk_mt6765_audio_drv);
drivers/clk/mediatek/clk-mt6765-cam.c+74−0
@@ -0,0 +1,74 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (c) 2018 MediaTek Inc.
4+ * Author: Owen Chen <owen.chen@mediatek.com>
5+ */
6+
7+#include <linux/clk-provider.h>
8+#include <linux/platform_device.h>
9+
10+#include "clk-mtk.h"
11+#include "clk-gate.h"
12+
13+#include <dt-bindings/clock/mt6765-clk.h>
14+
15+static const struct mtk_gate_regs cam_cg_regs = {
16+ .set_ofs = 0x4,
17+ .clr_ofs = 0x8,
18+ .sta_ofs = 0x0,
19+};
20+
21+#define GATE_CAM(_id, _name, _parent, _shift) { \
22+ .id = _id, \
23+ .name = _name, \
24+ .parent_name = _parent, \
25+ .regs = &cam_cg_regs, \
26+ .shift = _shift, \
27+ .ops = &mtk_clk_gate_ops_setclr, \
28+ }
29+
30+static const struct mtk_gate cam_clks[] = {
31+ GATE_CAM(CLK_CAM_LARB3, "cam_larb3", "mm_ck", 0),
32+ GATE_CAM(CLK_CAM_DFP_VAD, "cam_dfp_vad", "mm_ck", 1),
33+ GATE_CAM(CLK_CAM, "cam", "mm_ck", 6),
34+ GATE_CAM(CLK_CAMTG, "camtg", "mm_ck", 7),
35+ GATE_CAM(CLK_CAM_SENINF, "cam_seninf", "mm_ck", 8),
36+ GATE_CAM(CLK_CAMSV0, "camsv0", "mm_ck", 9),
37+ GATE_CAM(CLK_CAMSV1, "camsv1", "mm_ck", 10),
38+ GATE_CAM(CLK_CAMSV2, "camsv2", "mm_ck", 11),
39+ GATE_CAM(CLK_CAM_CCU, "cam_ccu", "mm_ck", 12),
40+};
41+
42+static int clk_mt6765_cam_probe(struct platform_device *pdev)
43+{
44+ struct clk_onecell_data *clk_data;
45+ int r;
46+ struct device_node *node = pdev->dev.of_node;
47+
48+ clk_data = mtk_alloc_clk_data(CLK_CAM_NR_CLK);
49+
50+ mtk_clk_register_gates(node, cam_clks, ARRAY_SIZE(cam_clks), clk_data);
51+
52+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
53+
54+ if (r)
55+ pr_err("%s(): could not register clock provider: %d\n",
56+ __func__, r);
57+
58+ return r;
59+}
60+
61+static const struct of_device_id of_match_clk_mt6765_cam[] = {
62+ { .compatible = "mediatek,mt6765-camsys", },
63+ {}
64+};
65+
66+static struct platform_driver clk_mt6765_cam_drv = {
67+ .probe = clk_mt6765_cam_probe,
68+ .driver = {
69+ .name = "clk-mt6765-cam",
70+ .of_match_table = of_match_clk_mt6765_cam,
71+ },
72+};
73+
74+builtin_platform_driver(clk_mt6765_cam_drv);
drivers/clk/mediatek/clk-mt6765-img.c+70−0
@@ -0,0 +1,70 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (c) 2018 MediaTek Inc.
4+ * Author: Owen Chen <owen.chen@mediatek.com>
5+ */
6+
7+#include <linux/clk-provider.h>
8+#include <linux/platform_device.h>
9+
10+#include "clk-mtk.h"
11+#include "clk-gate.h"
12+
13+#include <dt-bindings/clock/mt6765-clk.h>
14+
15+static const struct mtk_gate_regs img_cg_regs = {
16+ .set_ofs = 0x4,
17+ .clr_ofs = 0x8,
18+ .sta_ofs = 0x0,
19+};
20+
21+#define GATE_IMG(_id, _name, _parent, _shift) { \
22+ .id = _id, \
23+ .name = _name, \
24+ .parent_name = _parent, \
25+ .regs = &img_cg_regs, \
26+ .shift = _shift, \
27+ .ops = &mtk_clk_gate_ops_setclr, \
28+ }
29+
30+static const struct mtk_gate img_clks[] = {
31+ GATE_IMG(CLK_IMG_LARB2, "img_larb2", "mm_ck", 0),
32+ GATE_IMG(CLK_IMG_DIP, "img_dip", "mm_ck", 2),
33+ GATE_IMG(CLK_IMG_FDVT, "img_fdvt", "mm_ck", 3),
34+ GATE_IMG(CLK_IMG_DPE, "img_dpe", "mm_ck", 4),
35+ GATE_IMG(CLK_IMG_RSC, "img_rsc", "mm_ck", 5),
36+};
37+
38+static int clk_mt6765_img_probe(struct platform_device *pdev)
39+{
40+ struct clk_onecell_data *clk_data;
41+ int r;
42+ struct device_node *node = pdev->dev.of_node;
43+
44+ clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
45+
46+ mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks), clk_data);
47+
48+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
49+
50+ if (r)
51+ pr_err("%s(): could not register clock provider: %d\n",
52+ __func__, r);
53+
54+ return r;
55+}
56+
57+static const struct of_device_id of_match_clk_mt6765_img[] = {
58+ { .compatible = "mediatek,mt6765-imgsys", },
59+ {}
60+};
61+
62+static struct platform_driver clk_mt6765_img_drv = {
63+ .probe = clk_mt6765_img_probe,
64+ .driver = {
65+ .name = "clk-mt6765-img",
66+ .of_match_table = of_match_clk_mt6765_img,
67+ },
68+};
69+
70+builtin_platform_driver(clk_mt6765_img_drv);
drivers/clk/mediatek/clk-mt6765-mipi0a.c+68−0
@@ -0,0 +1,68 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (c) 2018 MediaTek Inc.
4+ * Author: Owen Chen <owen.chen@mediatek.com>
5+ */
6+
7+#include <linux/clk-provider.h>
8+#include <linux/platform_device.h>
9+
10+#include "clk-mtk.h"
11+#include "clk-gate.h"
12+
13+#include <dt-bindings/clock/mt6765-clk.h>
14+
15+static const struct mtk_gate_regs mipi0a_cg_regs = {
16+ .set_ofs = 0x80,
17+ .clr_ofs = 0x80,
18+ .sta_ofs = 0x80,
19+};
20+
21+#define GATE_MIPI0A(_id, _name, _parent, _shift) { \
22+ .id = _id, \
23+ .name = _name, \
24+ .parent_name = _parent, \
25+ .regs = &mipi0a_cg_regs, \
26+ .shift = _shift, \
27+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \
28+ }
29+
30+static const struct mtk_gate mipi0a_clks[] = {
31+ GATE_MIPI0A(CLK_MIPI0A_CSR_CSI_EN_0A,
32+ "mipi0a_csr_0a", "f_fseninf_ck", 1),
33+};
34+
35+static int clk_mt6765_mipi0a_probe(struct platform_device *pdev)
36+{
37+ struct clk_onecell_data *clk_data;
38+ int r;
39+ struct device_node *node = pdev->dev.of_node;
40+
41+ clk_data = mtk_alloc_clk_data(CLK_MIPI0A_NR_CLK);
42+
43+ mtk_clk_register_gates(node, mipi0a_clks,
44+ ARRAY_SIZE(mipi0a_clks), clk_data);
45+
46+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
47+
48+ if (r)
49+ pr_err("%s(): could not register clock provider: %d\n",
50+ __func__, r);
51+
52+ return r;
53+}
54+
55+static const struct of_device_id of_match_clk_mt6765_mipi0a[] = {
56+ { .compatible = "mediatek,mt6765-mipi0a", },
57+ {}
58+};
59+
60+static struct platform_driver clk_mt6765_mipi0a_drv = {
61+ .probe = clk_mt6765_mipi0a_probe,
62+ .driver = {
63+ .name = "clk-mt6765-mipi0a",
64+ .of_match_table = of_match_clk_mt6765_mipi0a,
65+ },
66+};
67+
68+builtin_platform_driver(clk_mt6765_mipi0a_drv);
drivers/clk/mediatek/clk-mt6765-mm.c+96−0
@@ -0,0 +1,96 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (c) 2018 MediaTek Inc.
4+ * Author: Owen Chen <owen.chen@mediatek.com>
5+ */
6+
7+#include <linux/clk-provider.h>
8+#include <linux/platform_device.h>
9+
10+#include "clk-mtk.h"
11+#include "clk-gate.h"
12+
13+#include <dt-bindings/clock/mt6765-clk.h>
14+
15+static const struct mtk_gate_regs mm_cg_regs = {
16+ .set_ofs = 0x104,
17+ .clr_ofs = 0x108,
18+ .sta_ofs = 0x100,
19+};
20+
21+#define GATE_MM(_id, _name, _parent, _shift) { \
22+ .id = _id, \
23+ .name = _name, \
24+ .parent_name = _parent, \
25+ .regs = &mm_cg_regs, \
26+ .shift = _shift, \
27+ .ops = &mtk_clk_gate_ops_setclr, \
28+ }
29+
30+static const struct mtk_gate mm_clks[] = {
31+ /* MM */
32+ GATE_MM(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_ck", 0),
33+ GATE_MM(CLK_MM_MDP_CCORR0, "mm_mdp_ccorr0", "mm_ck", 1),
34+ GATE_MM(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_ck", 2),
35+ GATE_MM(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_ck", 3),
36+ GATE_MM(CLK_MM_MDP_TDSHP0, "mm_mdp_tdshp0", "mm_ck", 4),
37+ GATE_MM(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_ck", 5),
38+ GATE_MM(CLK_MM_MDP_WDMA0, "mm_mdp_wdma0", "mm_ck", 6),
39+ GATE_MM(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_ck", 7),
40+ GATE_MM(CLK_MM_DISP_OVL0_2L, "mm_disp_ovl0_2l", "mm_ck", 8),
41+ GATE_MM(CLK_MM_DISP_RSZ0, "mm_disp_rsz0", "mm_ck", 9),
42+ GATE_MM(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_ck", 10),
43+ GATE_MM(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_ck", 11),
44+ GATE_MM(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_ck", 12),
45+ GATE_MM(CLK_MM_DISP_CCORR0, "mm_disp_ccorr0", "mm_ck", 13),
46+ GATE_MM(CLK_MM_DISP_AAL0, "mm_disp_aal0", "mm_ck", 14),
47+ GATE_MM(CLK_MM_DISP_GAMMA0, "mm_disp_gamma0", "mm_ck", 15),
48+ GATE_MM(CLK_MM_DISP_DITHER0, "mm_disp_dither0", "mm_ck", 16),
49+ GATE_MM(CLK_MM_DSI0, "mm_dsi0", "mm_ck", 17),
50+ GATE_MM(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_ck", 18),
51+ GATE_MM(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_ck", 19),
52+ GATE_MM(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_ck", 20),
53+ GATE_MM(CLK_MM_SMI_COMM0, "mm_smi_comm0", "mm_ck", 21),
54+ GATE_MM(CLK_MM_SMI_COMM1, "mm_smi_comm1", "mm_ck", 22),
55+ GATE_MM(CLK_MM_CAM_MDP, "mm_cam_mdp_ck", "mm_ck", 23),
56+ GATE_MM(CLK_MM_SMI_IMG, "mm_smi_img_ck", "mm_ck", 24),
57+ GATE_MM(CLK_MM_SMI_CAM, "mm_smi_cam_ck", "mm_ck", 25),
58+ GATE_MM(CLK_MM_IMG_DL_RELAY, "mm_img_dl_relay", "mm_ck", 26),
59+ GATE_MM(CLK_MM_IMG_DL_ASYNC_TOP, "mm_imgdl_async", "mm_ck", 27),
60+ GATE_MM(CLK_MM_DIG_DSI, "mm_dig_dsi_ck", "mm_ck", 28),
61+ GATE_MM(CLK_MM_F26M_HRTWT, "mm_hrtwt", "f_f26m_ck", 29),
62+};
63+
64+static int clk_mt6765_mm_probe(struct platform_device *pdev)
65+{
66+ struct clk_onecell_data *clk_data;
67+ int r;
68+ struct device_node *node = pdev->dev.of_node;
69+
70+ clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
71+
72+ mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks), clk_data);
73+
74+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
75+
76+ if (r)
77+ pr_err("%s(): could not register clock provider: %d\n",
78+ __func__, r);
79+
80+ return r;
81+}
82+
83+static const struct of_device_id of_match_clk_mt6765_mm[] = {
84+ { .compatible = "mediatek,mt6765-mmsys", },
85+ {}
86+};
87+
88+static struct platform_driver clk_mt6765_mm_drv = {
89+ .probe = clk_mt6765_mm_probe,
90+ .driver = {
91+ .name = "clk-mt6765-mm",
92+ .of_match_table = of_match_clk_mt6765_mm,
93+ },
94+};
95+
96+builtin_platform_driver(clk_mt6765_mm_drv);
drivers/clk/mediatek/clk-mt6765-vcodec.c+70−0
@@ -0,0 +1,70 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (c) 2018 MediaTek Inc.
4+ * Author: Owen Chen <owen.chen@mediatek.com>
5+ */
6+
7+#include <linux/clk-provider.h>
8+#include <linux/platform_device.h>
9+
10+#include "clk-mtk.h"
11+#include "clk-gate.h"
12+
13+#include <dt-bindings/clock/mt6765-clk.h>
14+
15+static const struct mtk_gate_regs venc_cg_regs = {
16+ .set_ofs = 0x4,
17+ .clr_ofs = 0x8,
18+ .sta_ofs = 0x0,
19+};
20+
21+#define GATE_VENC(_id, _name, _parent, _shift) { \
22+ .id = _id, \
23+ .name = _name, \
24+ .parent_name = _parent, \
25+ .regs = &venc_cg_regs, \
26+ .shift = _shift, \
27+ .ops = &mtk_clk_gate_ops_setclr_inv, \
28+ }
29+
30+static const struct mtk_gate venc_clks[] = {
31+ GATE_VENC(CLK_VENC_SET0_LARB, "venc_set0_larb", "mm_ck", 0),
32+ GATE_VENC(CLK_VENC_SET1_VENC, "venc_set1_venc", "mm_ck", 4),
33+ GATE_VENC(CLK_VENC_SET2_JPGENC, "jpgenc", "mm_ck", 8),
34+ GATE_VENC(CLK_VENC_SET3_VDEC, "venc_set3_vdec", "mm_ck", 12),
35+};
36+
37+static int clk_mt6765_vcodec_probe(struct platform_device *pdev)
38+{
39+ struct clk_onecell_data *clk_data;
40+ int r;
41+ struct device_node *node = pdev->dev.of_node;
42+
43+ clk_data = mtk_alloc_clk_data(CLK_VENC_NR_CLK);
44+
45+ mtk_clk_register_gates(node, venc_clks,
46+ ARRAY_SIZE(venc_clks), clk_data);
47+
48+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
49+
50+ if (r)
51+ pr_err("%s(): could not register clock provider: %d\n",
52+ __func__, r);
53+
54+ return r;
55+}
56+
57+static const struct of_device_id of_match_clk_mt6765_vcodec[] = {
58+ { .compatible = "mediatek,mt6765-vcodecsys", },
59+ {}
60+};
61+
62+static struct platform_driver clk_mt6765_vcodec_drv = {
63+ .probe = clk_mt6765_vcodec_probe,
64+ .driver = {
65+ .name = "clk-mt6765-vcodec",
66+ .of_match_table = of_match_clk_mt6765_vcodec,
67+ },
68+};
69+
70+builtin_platform_driver(clk_mt6765_vcodec_drv);
drivers/clk/mediatek/clk-mt6765.c+922−0
@@ -0,0 +1,922 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (c) 2018 MediaTek Inc.
4+ * Author: Owen Chen <owen.chen@mediatek.com>
5+ */
6+
7+#include <linux/clk-provider.h>
8+#include <linux/of.h>
9+#include <linux/of_address.h>
10+#include <linux/slab.h>
11+#include <linux/mfd/syscon.h>
12+#include <linux/of_device.h>
13+#include <linux/platform_device.h>
14+
15+#include "clk-mtk.h"
16+#include "clk-gate.h"
17+#include "clk-mux.h"
18+
19+#include <dt-bindings/clock/mt6765-clk.h>
20+
21+/*fmeter div select 4*/
22+#define _DIV4_ 1
23+
24+static DEFINE_SPINLOCK(mt6765_clk_lock);
25+
26+/* Total 12 subsys */
27+static void __iomem *cksys_base;
28+static void __iomem *apmixed_base;
29+
30+/* CKSYS */
31+#define CLK_SCP_CFG_0 (cksys_base + 0x200)
32+#define CLK_SCP_CFG_1 (cksys_base + 0x204)
33+
34+/* CG */
35+#define AP_PLL_CON3 (apmixed_base + 0x0C)
36+#define PLLON_CON0 (apmixed_base + 0x44)
37+#define PLLON_CON1 (apmixed_base + 0x48)
38+
39+/* clk cfg update */
40+#define CLK_CFG_0 0x40
41+#define CLK_CFG_0_SET 0x44
42+#define CLK_CFG_0_CLR 0x48
43+#define CLK_CFG_1 0x50
44+#define CLK_CFG_1_SET 0x54
45+#define CLK_CFG_1_CLR 0x58
46+#define CLK_CFG_2 0x60
47+#define CLK_CFG_2_SET 0x64
48+#define CLK_CFG_2_CLR 0x68
49+#define CLK_CFG_3 0x70
50+#define CLK_CFG_3_SET 0x74
51+#define CLK_CFG_3_CLR 0x78
52+#define CLK_CFG_4 0x80
53+#define CLK_CFG_4_SET 0x84
54+#define CLK_CFG_4_CLR 0x88
55+#define CLK_CFG_5 0x90
56+#define CLK_CFG_5_SET 0x94
57+#define CLK_CFG_5_CLR 0x98
58+#define CLK_CFG_6 0xa0
59+#define CLK_CFG_6_SET 0xa4
60+#define CLK_CFG_6_CLR 0xa8
61+#define CLK_CFG_7 0xb0
62+#define CLK_CFG_7_SET 0xb4
63+#define CLK_CFG_7_CLR 0xb8
64+#define CLK_CFG_8 0xc0
65+#define CLK_CFG_8_SET 0xc4
66+#define CLK_CFG_8_CLR 0xc8
67+#define CLK_CFG_9 0xd0
68+#define CLK_CFG_9_SET 0xd4
69+#define CLK_CFG_9_CLR 0xd8
70+#define CLK_CFG_10 0xe0
71+#define CLK_CFG_10_SET 0xe4
72+#define CLK_CFG_10_CLR 0xe8
73+#define CLK_CFG_UPDATE 0x004
74+
75+static const struct mtk_fixed_clk fixed_clks[] = {
76+ FIXED_CLK(CLK_TOP_F_FRTC, "f_frtc_ck", "clk32k", 32768),
77+ FIXED_CLK(CLK_TOP_CLK26M, "clk_26m_ck", "clk26m", 26000000),
78+ FIXED_CLK(CLK_TOP_DMPLL, "dmpll_ck", NULL, 466000000),
79+};
80+
81+static const struct mtk_fixed_factor top_divs[] = {
82+ FACTOR(CLK_TOP_SYSPLL, "syspll_ck", "mainpll", 1, 1),
83+ FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2),
84+ FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "syspll_d2", 1, 2),
85+ FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "syspll_d2", 1, 4),
86+ FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "syspll_d2", 1, 8),
87+ FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "syspll_d2", 1, 16),
88+ FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1, 3),
89+ FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "syspll_d3", 1, 2),
90+ FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "syspll_d3", 1, 4),
91+ FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "syspll_d3", 1, 8),
92+ FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5),
93+ FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "syspll_d5", 1, 2),
94+ FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "syspll_d5", 1, 4),
95+ FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll", 1, 7),
96+ FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "syspll_d7", 1, 2),
97+ FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "syspll_d7", 1, 4),
98+ FACTOR(CLK_TOP_UNIVPLL, "univpll", "univ2pll", 1, 2),
99+ FACTOR(CLK_TOP_USB20_192M, "usb20_192m_ck", "univpll", 2, 13),
100+ FACTOR(CLK_TOP_USB20_192M_D4, "usb20_192m_d4", "usb20_192m_ck", 1, 4),
101+ FACTOR(CLK_TOP_USB20_192M_D8, "usb20_192m_d8", "usb20_192m_ck", 1, 8),
102+ FACTOR(CLK_TOP_USB20_192M_D16,
103+ "usb20_192m_d16", "usb20_192m_ck", 1, 16),
104+ FACTOR(CLK_TOP_USB20_192M_D32,
105+ "usb20_192m_d32", "usb20_192m_ck", 1, 32),
106+ FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
107+ FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_d2", 1, 2),
108+ FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_d2", 1, 4),
109+ FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
110+ FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_d3", 1, 2),
111+ FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_d3", 1, 4),
112+ FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_d3", 1, 8),
113+ FACTOR(CLK_TOP_UNIVPLL2_D32, "univpll2_d32", "univpll_d3", 1, 32),
114+ FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
115+ FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll_d5", 1, 2),
116+ FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll_d5", 1, 4),
117+ FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1, 1),
118+ FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll_ck", 1, 2),
119+ FACTOR(CLK_TOP_MPLL, "mpll_ck", "mpll", 1, 1),
120+ FACTOR(CLK_TOP_DA_MPLL_104M_DIV, "mpll_104m_div", "mpll_ck", 1, 2),
121+ FACTOR(CLK_TOP_DA_MPLL_52M_DIV, "mpll_52m_div", "mpll_ck", 1, 4),
122+ FACTOR(CLK_TOP_MFGPLL, "mfgpll_ck", "mfgpll", 1, 1),
123+ FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1),
124+ FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll_ck", 1, 2),
125+ FACTOR(CLK_TOP_APLL1, "apll1_ck", "apll1", 1, 1),
126+ FACTOR(CLK_TOP_APLL1_D2, "apll1_d2", "apll1_ck", 1, 2),
127+ FACTOR(CLK_TOP_APLL1_D4, "apll1_d4", "apll1_ck", 1, 4),
128+ FACTOR(CLK_TOP_APLL1_D8, "apll1_d8", "apll1_ck", 1, 8),
129+ FACTOR(CLK_TOP_ULPOSC1, "ulposc1_ck", "ulposc1", 1, 1),
130+ FACTOR(CLK_TOP_ULPOSC1_D2, "ulposc1_d2", "ulposc1_ck", 1, 2),
131+ FACTOR(CLK_TOP_ULPOSC1_D4, "ulposc1_d4", "ulposc1_ck", 1, 4),
132+ FACTOR(CLK_TOP_ULPOSC1_D8, "ulposc1_d8", "ulposc1_ck", 1, 8),
133+ FACTOR(CLK_TOP_ULPOSC1_D16, "ulposc1_d16", "ulposc1_ck", 1, 16),
134+ FACTOR(CLK_TOP_ULPOSC1_D32, "ulposc1_d32", "ulposc1_ck", 1, 32),
135+ FACTOR(CLK_TOP_F_F26M, "f_f26m_ck", "clk_26m_ck", 1, 1),
136+ FACTOR(CLK_TOP_AXI, "axi_ck", "axi_sel", 1, 1),
137+ FACTOR(CLK_TOP_MM, "mm_ck", "mm_sel", 1, 1),
138+ FACTOR(CLK_TOP_SCP, "scp_ck", "scp_sel", 1, 1),
139+ FACTOR(CLK_TOP_MFG, "mfg_ck", "mfg_sel", 1, 1),
140+ FACTOR(CLK_TOP_F_FUART, "f_fuart_ck", "uart_sel", 1, 1),
141+ FACTOR(CLK_TOP_SPI, "spi_ck", "spi_sel", 1, 1),
142+ FACTOR(CLK_TOP_MSDC50_0, "msdc50_0_ck", "msdc50_0_sel", 1, 1),
143+ FACTOR(CLK_TOP_MSDC30_1, "msdc30_1_ck", "msdc30_1_sel", 1, 1),
144+ FACTOR(CLK_TOP_AUDIO, "audio_ck", "audio_sel", 1, 1),
145+ FACTOR(CLK_TOP_AUD_1, "aud_1_ck", "aud_1_sel", 1, 1),
146+ FACTOR(CLK_TOP_AUD_ENGEN1, "aud_engen1_ck", "aud_engen1_sel", 1, 1),
147+ FACTOR(CLK_TOP_F_FDISP_PWM, "f_fdisp_pwm_ck", "disp_pwm_sel", 1, 1),
148+ FACTOR(CLK_TOP_SSPM, "sspm_ck", "sspm_sel", 1, 1),
149+ FACTOR(CLK_TOP_DXCC, "dxcc_ck", "dxcc_sel", 1, 1),
150+ FACTOR(CLK_TOP_I2C, "i2c_ck", "i2c_sel", 1, 1),
151+ FACTOR(CLK_TOP_F_FPWM, "f_fpwm_ck", "pwm_sel", 1, 1),
152+ FACTOR(CLK_TOP_F_FSENINF, "f_fseninf_ck", "seninf_sel", 1, 1),
153+ FACTOR(CLK_TOP_AES_FDE, "aes_fde_ck", "aes_fde_sel", 1, 1),
154+ FACTOR(CLK_TOP_F_BIST2FPC, "f_bist2fpc_ck", "univpll2_d2", 1, 1),
155+ FACTOR(CLK_TOP_ARMPLL_DIVIDER_PLL0, "arm_div_pll0", "syspll_d2", 1, 1),
156+ FACTOR(CLK_TOP_ARMPLL_DIVIDER_PLL1, "arm_div_pll1", "syspll_ck", 1, 1),
157+ FACTOR(CLK_TOP_ARMPLL_DIVIDER_PLL2, "arm_div_pll2", "univpll_d2", 1, 1),
158+ FACTOR(CLK_TOP_DA_USB20_48M_DIV,
159+ "usb20_48m_div", "usb20_192m_d4", 1, 1),
160+ FACTOR(CLK_TOP_DA_UNIV_48M_DIV, "univ_48m_div", "usb20_192m_d4", 1, 1),
161+};
162+
163+static const char * const axi_parents[] = {
164+ "clk26m",
165+ "syspll_d7",
166+ "syspll1_d4",
167+ "syspll3_d2"
168+};
169+
170+static const char * const mem_parents[] = {
171+ "clk26m",
172+ "dmpll_ck",
173+ "apll1_ck"
174+};
175+
176+static const char * const mm_parents[] = {
177+ "clk26m",
178+ "mmpll_ck",
179+ "syspll1_d2",
180+ "syspll_d5",
181+ "syspll1_d4",
182+ "univpll_d5",
183+ "univpll1_d2",
184+ "mmpll_d2"
185+};
186+
187+static const char * const scp_parents[] = {
188+ "clk26m",
189+ "syspll4_d2",
190+ "univpll2_d2",
191+ "syspll1_d2",
192+ "univpll1_d2",
193+ "syspll_d3",
194+ "univpll_d3"
195+};
196+
197+static const char * const mfg_parents[] = {
198+ "clk26m",
199+ "mfgpll_ck",
200+ "syspll_d3",
201+ "univpll_d3"
202+};
203+
204+static const char * const atb_parents[] = {
205+ "clk26m",
206+ "syspll1_d4",
207+ "syspll1_d2"
208+};
209+
210+static const char * const camtg_parents[] = {
211+ "clk26m",
212+ "usb20_192m_d8",
213+ "univpll2_d8",
214+ "usb20_192m_d4",
215+ "univpll2_d32",
216+ "usb20_192m_d16",
217+ "usb20_192m_d32"
218+};
219+
220+static const char * const uart_parents[] = {
221+ "clk26m",
222+ "univpll2_d8"
223+};
224+
225+static const char * const spi_parents[] = {
226+ "clk26m",
227+ "syspll3_d2",
228+ "syspll4_d2",
229+ "syspll2_d4"
230+};
231+
232+static const char * const msdc5hclk_parents[] = {
233+ "clk26m",
234+ "syspll1_d2",
235+ "univpll1_d4",
236+ "syspll2_d2"
237+};
238+
239+static const char * const msdc50_0_parents[] = {
240+ "clk26m",
241+ "msdcpll_ck",
242+ "syspll2_d2",
243+ "syspll4_d2",
244+ "univpll1_d2",
245+ "syspll1_d2",
246+ "univpll_d5",
247+ "univpll1_d4"
248+};
249+
250+static const char * const msdc30_1_parents[] = {
251+ "clk26m",
252+ "msdcpll_d2",
253+ "univpll2_d2",
254+ "syspll2_d2",
255+ "syspll1_d4",
256+ "univpll1_d4",
257+ "usb20_192m_d4",
258+ "syspll2_d4"
259+};
260+
261+static const char * const audio_parents[] = {
262+ "clk26m",
263+ "syspll3_d4",
264+ "syspll4_d4",
265+ "syspll1_d16"
266+};
267+
268+static const char * const aud_intbus_parents[] = {
269+ "clk26m",
270+ "syspll1_d4",
271+ "syspll4_d2"
272+};
273+
274+static const char * const aud_1_parents[] = {
275+ "clk26m",
276+ "apll1_ck"
277+};
278+
279+static const char * const aud_engen1_parents[] = {
280+ "clk26m",
281+ "apll1_d2",
282+ "apll1_d4",
283+ "apll1_d8"
284+};
285+
286+static const char * const disp_pwm_parents[] = {
287+ "clk26m",
288+ "univpll2_d4",
289+ "ulposc1_d2",
290+ "ulposc1_d8"
291+};
292+
293+static const char * const sspm_parents[] = {
294+ "clk26m",
295+ "syspll1_d2",
296+ "syspll_d3"
297+};
298+
299+static const char * const dxcc_parents[] = {
300+ "clk26m",
301+ "syspll1_d2",
302+ "syspll1_d4",
303+ "syspll1_d8"
304+};
305+
306+static const char * const usb_top_parents[] = {
307+ "clk26m",
308+ "univpll3_d4"
309+};
310+
311+static const char * const spm_parents[] = {
312+ "clk26m",
313+ "syspll1_d8"
314+};
315+
316+static const char * const i2c_parents[] = {
317+ "clk26m",
318+ "univpll3_d4",
319+ "univpll3_d2",
320+ "syspll1_d8",
321+ "syspll2_d8"
322+};
323+
324+static const char * const pwm_parents[] = {
325+ "clk26m",
326+ "univpll3_d4",
327+ "syspll1_d8"
328+};
329+
330+static const char * const seninf_parents[] = {
331+ "clk26m",
332+ "univpll1_d4",
333+ "univpll1_d2",
334+ "univpll2_d2"
335+};
336+
337+static const char * const aes_fde_parents[] = {
338+ "clk26m",
339+ "msdcpll_ck",
340+ "univpll_d3",
341+ "univpll2_d2",
342+ "univpll1_d2",
343+ "syspll1_d2"
344+};
345+
346+static const char * const ulposc_parents[] = {
347+ "clk26m",
348+ "ulposc1_d4",
349+ "ulposc1_d8",
350+ "ulposc1_d16",
351+ "ulposc1_d32"
352+};
353+
354+static const char * const camtm_parents[] = {
355+ "clk26m",
356+ "univpll1_d4",
357+ "univpll1_d2",
358+ "univpll2_d2"
359+};
360+
361+#define INVALID_UPDATE_REG 0xFFFFFFFF
362+#define INVALID_UPDATE_SHIFT -1
363+#define INVALID_MUX_GATE -1
364+
365+static const struct mtk_mux top_muxes[] = {
366+ /* CLK_CFG_0 */
367+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
368+ CLK_CFG_0, CLK_CFG_0_SET, CLK_CFG_0_CLR,
369+ 0, 2, 7, CLK_CFG_UPDATE, 0, CLK_IS_CRITICAL),
370+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_MEM_SEL, "mem_sel", mem_parents,
371+ CLK_CFG_0, CLK_CFG_0_SET, CLK_CFG_0_CLR,
372+ 8, 2, 15, CLK_CFG_UPDATE, 1, CLK_IS_CRITICAL),
373+ MUX_GATE_CLR_SET_UPD(CLK_TOP_MM_SEL, "mm_sel", mm_parents, CLK_CFG_0,
374+ CLK_CFG_0_SET, CLK_CFG_0_CLR, 16, 3, 23,
375+ CLK_CFG_UPDATE, 2),
376+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, CLK_CFG_0,
377+ CLK_CFG_0_SET, CLK_CFG_0_CLR, 24, 3, 31,
378+ CLK_CFG_UPDATE, 3),
379+ /* CLK_CFG_1 */
380+ MUX_GATE_CLR_SET_UPD(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, CLK_CFG_1,
381+ CLK_CFG_1_SET, CLK_CFG_1_CLR, 0, 2, 7,
382+ CLK_CFG_UPDATE, 4),
383+ MUX_GATE_CLR_SET_UPD(CLK_TOP_ATB_SEL, "atb_sel", atb_parents, CLK_CFG_1,
384+ CLK_CFG_1_SET, CLK_CFG_1_CLR, 8, 2, 15,
385+ CLK_CFG_UPDATE, 5),
386+ MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG_SEL, "camtg_sel",
387+ camtg_parents, CLK_CFG_1, CLK_CFG_1_SET,
388+ CLK_CFG_1_CLR, 16, 3, 23, CLK_CFG_UPDATE, 6),
389+ MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG1_SEL, "camtg1_sel", camtg_parents,
390+ CLK_CFG_1, CLK_CFG_1_SET, CLK_CFG_1_CLR,
391+ 24, 3, 31, CLK_CFG_UPDATE, 7),
392+ /* CLK_CFG_2 */
393+ MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG2_SEL, "camtg2_sel",
394+ camtg_parents, CLK_CFG_2, CLK_CFG_2_SET,
395+ CLK_CFG_2_CLR, 0, 3, 7, CLK_CFG_UPDATE, 8),
396+ MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG3_SEL, "camtg3_sel", camtg_parents,
397+ CLK_CFG_2, CLK_CFG_2_SET, CLK_CFG_2_CLR,
398+ 8, 3, 15, CLK_CFG_UPDATE, 9),
399+ MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_parents,
400+ CLK_CFG_2, CLK_CFG_2_SET, CLK_CFG_2_CLR, 16, 1, 23,
401+ CLK_CFG_UPDATE, 10),
402+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, CLK_CFG_2,
403+ CLK_CFG_2_SET, CLK_CFG_2_CLR, 24, 2, 31,
404+ CLK_CFG_UPDATE, 11),
405+ /* CLK_CFG_3 */
406+ MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_HCLK_SEL, "msdc5hclk",
407+ msdc5hclk_parents, CLK_CFG_3, CLK_CFG_3_SET,
408+ CLK_CFG_3_CLR, 0, 2, 7, CLK_CFG_UPDATE, 12),
409+ MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel",
410+ msdc50_0_parents, CLK_CFG_3, CLK_CFG_3_SET,
411+ CLK_CFG_3_CLR, 8, 3, 15, CLK_CFG_UPDATE, 13),
412+ MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel",
413+ msdc30_1_parents, CLK_CFG_3, CLK_CFG_3_SET,
414+ CLK_CFG_3_CLR, 16, 3, 23, CLK_CFG_UPDATE, 14),
415+ MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO_SEL, "audio_sel", audio_parents,
416+ CLK_CFG_3, CLK_CFG_3_SET, CLK_CFG_3_CLR,
417+ 24, 2, 31, CLK_CFG_UPDATE, 15),
418+ /* CLK_CFG_4 */
419+ MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel",
420+ aud_intbus_parents, CLK_CFG_4, CLK_CFG_4_SET,
421+ CLK_CFG_4_CLR, 0, 2, 7, CLK_CFG_UPDATE, 16),
422+ MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_1_SEL, "aud_1_sel", aud_1_parents,
423+ CLK_CFG_4, CLK_CFG_4_SET, CLK_CFG_4_CLR,
424+ 8, 1, 15, CLK_CFG_UPDATE, 17),
425+ MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_ENGEN1_SEL, "aud_engen1_sel",
426+ aud_engen1_parents, CLK_CFG_4, CLK_CFG_4_SET,
427+ CLK_CFG_4_CLR, 16, 2, 23, CLK_CFG_UPDATE, 18),
428+ MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP_PWM_SEL, "disp_pwm_sel",
429+ disp_pwm_parents, CLK_CFG_4, CLK_CFG_4_SET,
430+ CLK_CFG_4_CLR, 24, 2, 31, CLK_CFG_UPDATE, 19),
431+ /* CLK_CFG_5 */
432+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SSPM_SEL, "sspm_sel", sspm_parents,
433+ CLK_CFG_5, CLK_CFG_5_SET, CLK_CFG_5_CLR, 0, 2, 7,
434+ CLK_CFG_UPDATE, 20),
435+ MUX_GATE_CLR_SET_UPD(CLK_TOP_DXCC_SEL, "dxcc_sel", dxcc_parents,
436+ CLK_CFG_5, CLK_CFG_5_SET, CLK_CFG_5_CLR, 8, 2, 15,
437+ CLK_CFG_UPDATE, 21),
438+ MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_TOP_SEL, "usb_top_sel",
439+ usb_top_parents, CLK_CFG_5, CLK_CFG_5_SET,
440+ CLK_CFG_5_CLR, 16, 1, 23, CLK_CFG_UPDATE, 22),
441+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SPM_SEL, "spm_sel", spm_parents, CLK_CFG_5,
442+ CLK_CFG_5_SET, CLK_CFG_5_CLR, 24, 1, 31,
443+ CLK_CFG_UPDATE, 23),
444+ /* CLK_CFG_6 */
445+ MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents, CLK_CFG_6,
446+ CLK_CFG_6_SET, CLK_CFG_6_CLR, 0, 3, 7, CLK_CFG_UPDATE,
447+ 24),
448+ MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, CLK_CFG_6,
449+ CLK_CFG_6_SET, CLK_CFG_6_CLR, 8, 2, 15, CLK_CFG_UPDATE,
450+ 25),
451+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF_SEL, "seninf_sel", seninf_parents,
452+ CLK_CFG_6, CLK_CFG_6_SET, CLK_CFG_6_CLR, 16, 2, 23,
453+ CLK_CFG_UPDATE, 26),
454+ MUX_GATE_CLR_SET_UPD(CLK_TOP_AES_FDE_SEL, "aes_fde_sel",
455+ aes_fde_parents, CLK_CFG_6, CLK_CFG_6_SET,
456+ CLK_CFG_6_CLR, 24, 3, 31, CLK_CFG_UPDATE, 27),
457+ /* CLK_CFG_7 */
458+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_PWRAP_ULPOSC_SEL, "ulposc_sel",
459+ ulposc_parents, CLK_CFG_7, CLK_CFG_7_SET,
460+ CLK_CFG_7_CLR, 0, 3, 7, CLK_CFG_UPDATE, 28,
461+ CLK_IS_CRITICAL),
462+ MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTM_SEL, "camtm_sel", camtm_parents,
463+ CLK_CFG_7, CLK_CFG_7_SET, CLK_CFG_7_CLR, 8, 2, 15,
464+ CLK_CFG_UPDATE, 29),
465+};
466+
467+static const struct mtk_gate_regs top0_cg_regs = {
468+ .set_ofs = 0x0,
469+ .clr_ofs = 0x0,
470+ .sta_ofs = 0x0,
471+};
472+
473+static const struct mtk_gate_regs top1_cg_regs = {
474+ .set_ofs = 0x104,
475+ .clr_ofs = 0x104,
476+ .sta_ofs = 0x104,
477+};
478+
479+static const struct mtk_gate_regs top2_cg_regs = {
480+ .set_ofs = 0x320,
481+ .clr_ofs = 0x320,
482+ .sta_ofs = 0x320,
483+};
484+
485+#define GATE_TOP0(_id, _name, _parent, _shift) { \
486+ .id = _id, \
487+ .name = _name, \
488+ .parent_name = _parent, \
489+ .regs = &top0_cg_regs, \
490+ .shift = _shift, \
491+ .ops = &mtk_clk_gate_ops_no_setclr, \
492+ }
493+
494+#define GATE_TOP1(_id, _name, _parent, _shift) { \
495+ .id = _id, \
496+ .name = _name, \
497+ .parent_name = _parent, \
498+ .regs = &top1_cg_regs, \
499+ .shift = _shift, \
500+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \
501+ }
502+
503+#define GATE_TOP2(_id, _name, _parent, _shift) { \
504+ .id = _id, \
505+ .name = _name, \
506+ .parent_name = _parent, \
507+ .regs = &top2_cg_regs, \
508+ .shift = _shift, \
509+ .ops = &mtk_clk_gate_ops_no_setclr, \
510+ }
511+
512+static const struct mtk_gate top_clks[] = {
513+ /* TOP0 */
514+ GATE_TOP0(CLK_TOP_MD_32K, "md_32k", "f_frtc_ck", 8),
515+ GATE_TOP0(CLK_TOP_MD_26M, "md_26m", "f_f26m_ck", 9),
516+ GATE_TOP0(CLK_TOP_MD2_32K, "md2_32k", "f_frtc_ck", 10),
517+ GATE_TOP0(CLK_TOP_MD2_26M, "md2_26m", "f_f26m_ck", 11),
518+ /* TOP1 */
519+ GATE_TOP1(CLK_TOP_ARMPLL_DIVIDER_PLL0_EN,
520+ "arm_div_pll0_en", "arm_div_pll0", 3),
521+ GATE_TOP1(CLK_TOP_ARMPLL_DIVIDER_PLL1_EN,
522+ "arm_div_pll1_en", "arm_div_pll1", 4),
523+ GATE_TOP1(CLK_TOP_ARMPLL_DIVIDER_PLL2_EN,
524+ "arm_div_pll2_en", "arm_div_pll2", 5),
525+ GATE_TOP1(CLK_TOP_FMEM_OCC_DRC_EN, "drc_en", "univpll2_d2", 6),
526+ GATE_TOP1(CLK_TOP_USB20_48M_EN, "usb20_48m_en", "usb20_48m_div", 8),
527+ GATE_TOP1(CLK_TOP_UNIVPLL_48M_EN, "univpll_48m_en", "univ_48m_div", 9),
528+ GATE_TOP1(CLK_TOP_F_UFS_MP_SAP_CFG_EN, "ufs_sap", "f_f26m_ck", 12),
529+ GATE_TOP1(CLK_TOP_F_BIST2FPC_EN, "bist2fpc", "f_bist2fpc_ck", 16),
530+ /* TOP2 */
531+ GATE_TOP2(CLK_TOP_APLL12_DIV0, "apll12_div0", "aud_1_ck", 2),
532+ GATE_TOP2(CLK_TOP_APLL12_DIV1, "apll12_div1", "aud_1_ck", 3),
533+ GATE_TOP2(CLK_TOP_APLL12_DIV2, "apll12_div2", "aud_1_ck", 4),
534+ GATE_TOP2(CLK_TOP_APLL12_DIV3, "apll12_div3", "aud_1_ck", 5),
535+};
536+
537+static const struct mtk_gate_regs ifr2_cg_regs = {
538+ .set_ofs = 0x80,
539+ .clr_ofs = 0x84,
540+ .sta_ofs = 0x90,
541+};
542+
543+static const struct mtk_gate_regs ifr3_cg_regs = {
544+ .set_ofs = 0x88,
545+ .clr_ofs = 0x8c,
546+ .sta_ofs = 0x94,
547+};
548+
549+static const struct mtk_gate_regs ifr4_cg_regs = {
550+ .set_ofs = 0xa4,
551+ .clr_ofs = 0xa8,
552+ .sta_ofs = 0xac,
553+};
554+
555+static const struct mtk_gate_regs ifr5_cg_regs = {
556+ .set_ofs = 0xc0,
557+ .clr_ofs = 0xc4,
558+ .sta_ofs = 0xc8,
559+};
560+
561+#define GATE_IFR2(_id, _name, _parent, _shift) { \
562+ .id = _id, \
563+ .name = _name, \
564+ .parent_name = _parent, \
565+ .regs = &ifr2_cg_regs, \
566+ .shift = _shift, \
567+ .ops = &mtk_clk_gate_ops_setclr, \
568+ }
569+
570+#define GATE_IFR3(_id, _name, _parent, _shift) { \
571+ .id = _id, \
572+ .name = _name, \
573+ .parent_name = _parent, \
574+ .regs = &ifr3_cg_regs, \
575+ .shift = _shift, \
576+ .ops = &mtk_clk_gate_ops_setclr, \
577+ }
578+
579+#define GATE_IFR4(_id, _name, _parent, _shift) { \
580+ .id = _id, \
581+ .name = _name, \
582+ .parent_name = _parent, \
583+ .regs = &ifr4_cg_regs, \
584+ .shift = _shift, \
585+ .ops = &mtk_clk_gate_ops_setclr, \
586+ }
587+
588+#define GATE_IFR5(_id, _name, _parent, _shift) { \
589+ .id = _id, \
590+ .name = _name, \
591+ .parent_name = _parent, \
592+ .regs = &ifr5_cg_regs, \
593+ .shift = _shift, \
594+ .ops = &mtk_clk_gate_ops_setclr, \
595+ }
596+
597+static const struct mtk_gate ifr_clks[] = {
598+ /* INFRA_TOPAXI */
599+ /* INFRA PERI */
600+ /* INFRA mode 0 */
601+ GATE_IFR2(CLK_IFR_ICUSB, "ifr_icusb", "axi_ck", 8),
602+ GATE_IFR2(CLK_IFR_GCE, "ifr_gce", "axi_ck", 9),
603+ GATE_IFR2(CLK_IFR_THERM, "ifr_therm", "axi_ck", 10),
604+ GATE_IFR2(CLK_IFR_I2C_AP, "ifr_i2c_ap", "i2c_ck", 11),
605+ GATE_IFR2(CLK_IFR_I2C_CCU, "ifr_i2c_ccu", "i2c_ck", 12),
606+ GATE_IFR2(CLK_IFR_I2C_SSPM, "ifr_i2c_sspm", "i2c_ck", 13),
607+ GATE_IFR2(CLK_IFR_I2C_RSV, "ifr_i2c_rsv", "i2c_ck", 14),
608+ GATE_IFR2(CLK_IFR_PWM_HCLK, "ifr_pwm_hclk", "axi_ck", 15),
609+ GATE_IFR2(CLK_IFR_PWM1, "ifr_pwm1", "f_fpwm_ck", 16),
610+ GATE_IFR2(CLK_IFR_PWM2, "ifr_pwm2", "f_fpwm_ck", 17),
611+ GATE_IFR2(CLK_IFR_PWM3, "ifr_pwm3", "f_fpwm_ck", 18),
612+ GATE_IFR2(CLK_IFR_PWM4, "ifr_pwm4", "f_fpwm_ck", 19),
613+ GATE_IFR2(CLK_IFR_PWM5, "ifr_pwm5", "f_fpwm_ck", 20),
614+ GATE_IFR2(CLK_IFR_PWM, "ifr_pwm", "f_fpwm_ck", 21),
615+ GATE_IFR2(CLK_IFR_UART0, "ifr_uart0", "f_fuart_ck", 22),
616+ GATE_IFR2(CLK_IFR_UART1, "ifr_uart1", "f_fuart_ck", 23),
617+ GATE_IFR2(CLK_IFR_GCE_26M, "ifr_gce_26m", "f_f26m_ck", 27),
618+ GATE_IFR2(CLK_IFR_CQ_DMA_FPC, "ifr_dma", "axi_ck", 28),
619+ GATE_IFR2(CLK_IFR_BTIF, "ifr_btif", "axi_ck", 31),
620+ /* INFRA mode 1 */
621+ GATE_IFR3(CLK_IFR_SPI0, "ifr_spi0", "spi_ck", 1),
622+ GATE_IFR3(CLK_IFR_MSDC0, "ifr_msdc0", "msdc5hclk", 2),
623+ GATE_IFR3(CLK_IFR_MSDC1, "ifr_msdc1", "axi_ck", 4),
624+ GATE_IFR3(CLK_IFR_TRNG, "ifr_trng", "axi_ck", 9),
625+ GATE_IFR3(CLK_IFR_AUXADC, "ifr_auxadc", "f_f26m_ck", 10),
626+ GATE_IFR3(CLK_IFR_CCIF1_AP, "ifr_ccif1_ap", "axi_ck", 12),
627+ GATE_IFR3(CLK_IFR_CCIF1_MD, "ifr_ccif1_md", "axi_ck", 13),
628+ GATE_IFR3(CLK_IFR_AUXADC_MD, "ifr_auxadc_md", "f_f26m_ck", 14),
629+ GATE_IFR3(CLK_IFR_AP_DMA, "ifr_ap_dma", "axi_ck", 18),
630+ GATE_IFR3(CLK_IFR_DEVICE_APC, "ifr_dapc", "axi_ck", 20),
631+ GATE_IFR3(CLK_IFR_CCIF_AP, "ifr_ccif_ap", "axi_ck", 23),
632+ GATE_IFR3(CLK_IFR_AUDIO, "ifr_audio", "axi_ck", 25),
633+ GATE_IFR3(CLK_IFR_CCIF_MD, "ifr_ccif_md", "axi_ck", 26),
634+ /* INFRA mode 2 */
635+ GATE_IFR4(CLK_IFR_RG_PWM_FBCLK6, "ifr_pwmfb", "f_f26m_ck", 0),
636+ GATE_IFR4(CLK_IFR_DISP_PWM, "ifr_disp_pwm", "f_fdisp_pwm_ck", 2),
637+ GATE_IFR4(CLK_IFR_CLDMA_BCLK, "ifr_cldmabclk", "axi_ck", 3),
638+ GATE_IFR4(CLK_IFR_AUDIO_26M_BCLK, "ifr_audio26m", "f_f26m_ck", 4),
639+ GATE_IFR4(CLK_IFR_SPI1, "ifr_spi1", "spi_ck", 6),
640+ GATE_IFR4(CLK_IFR_I2C4, "ifr_i2c4", "i2c_ck", 7),
641+ GATE_IFR4(CLK_IFR_SPI2, "ifr_spi2", "spi_ck", 9),
642+ GATE_IFR4(CLK_IFR_SPI3, "ifr_spi3", "spi_ck", 10),
643+ GATE_IFR4(CLK_IFR_I2C5, "ifr_i2c5", "i2c_ck", 18),
644+ GATE_IFR4(CLK_IFR_I2C5_ARBITER, "ifr_i2c5a", "i2c_ck", 19),
645+ GATE_IFR4(CLK_IFR_I2C5_IMM, "ifr_i2c5_imm", "i2c_ck", 20),
646+ GATE_IFR4(CLK_IFR_I2C1_ARBITER, "ifr_i2c1a", "i2c_ck", 21),
647+ GATE_IFR4(CLK_IFR_I2C1_IMM, "ifr_i2c1_imm", "i2c_ck", 22),
648+ GATE_IFR4(CLK_IFR_I2C2_ARBITER, "ifr_i2c2a", "i2c_ck", 23),
649+ GATE_IFR4(CLK_IFR_I2C2_IMM, "ifr_i2c2_imm", "i2c_ck", 24),
650+ GATE_IFR4(CLK_IFR_SPI4, "ifr_spi4", "spi_ck", 25),
651+ GATE_IFR4(CLK_IFR_SPI5, "ifr_spi5", "spi_ck", 26),
652+ GATE_IFR4(CLK_IFR_CQ_DMA, "ifr_cq_dma", "axi_ck", 27),
653+ GATE_IFR4(CLK_IFR_FAES_FDE, "ifr_faes_fde_ck", "aes_fde_ck", 29),
654+ /* INFRA mode 3 */
655+ GATE_IFR5(CLK_IFR_MSDC0_SELF, "ifr_msdc0sf", "msdc50_0_ck", 0),
656+ GATE_IFR5(CLK_IFR_MSDC1_SELF, "ifr_msdc1sf", "msdc50_0_ck", 1),
657+ GATE_IFR5(CLK_IFR_I2C6, "ifr_i2c6", "i2c_ck", 6),
658+ GATE_IFR5(CLK_IFR_AP_MSDC0, "ifr_ap_msdc0", "msdc50_0_ck", 7),
659+ GATE_IFR5(CLK_IFR_MD_MSDC0, "ifr_md_msdc0", "msdc50_0_ck", 8),
660+ GATE_IFR5(CLK_IFR_MSDC0_SRC, "ifr_msdc0_clk", "msdc50_0_ck", 9),
661+ GATE_IFR5(CLK_IFR_MSDC1_SRC, "ifr_msdc1_clk", "msdc30_1_ck", 10),
662+ GATE_IFR5(CLK_IFR_MCU_PM_BCLK, "ifr_mcu_pm_bclk", "axi_ck", 17),
663+ GATE_IFR5(CLK_IFR_CCIF2_AP, "ifr_ccif2_ap", "axi_ck", 18),
664+ GATE_IFR5(CLK_IFR_CCIF2_MD, "ifr_ccif2_md", "axi_ck", 19),
665+ GATE_IFR5(CLK_IFR_CCIF3_AP, "ifr_ccif3_ap", "axi_ck", 20),
666+ GATE_IFR5(CLK_IFR_CCIF3_MD, "ifr_ccif3_md", "axi_ck", 21),
667+};
668+
669+/* additional CCF control for mipi26M race condition(disp/camera) */
670+static const struct mtk_gate_regs apmixed_cg_regs = {
671+ .set_ofs = 0x14,
672+ .clr_ofs = 0x14,
673+ .sta_ofs = 0x14,
674+};
675+
676+#define GATE_APMIXED(_id, _name, _parent, _shift) { \
677+ .id = _id, \
678+ .name = _name, \
679+ .parent_name = _parent, \
680+ .regs = &apmixed_cg_regs, \
681+ .shift = _shift, \
682+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \
683+ }
684+
685+static const struct mtk_gate apmixed_clks[] = {
686+ /* AUDIO0 */
687+ GATE_APMIXED(CLK_APMIXED_SSUSB26M, "apmixed_ssusb26m", "f_f26m_ck",
688+ 4),
689+ GATE_APMIXED(CLK_APMIXED_APPLL26M, "apmixed_appll26m", "f_f26m_ck",
690+ 5),
691+ GATE_APMIXED(CLK_APMIXED_MIPIC0_26M, "apmixed_mipic026m", "f_f26m_ck",
692+ 6),
693+ GATE_APMIXED(CLK_APMIXED_MDPLLGP26M, "apmixed_mdpll26m", "f_f26m_ck",
694+ 7),
695+ GATE_APMIXED(CLK_APMIXED_MMSYS_F26M, "apmixed_mmsys26m", "f_f26m_ck",
696+ 8),
697+ GATE_APMIXED(CLK_APMIXED_UFS26M, "apmixed_ufs26m", "f_f26m_ck",
698+ 9),
699+ GATE_APMIXED(CLK_APMIXED_MIPIC1_26M, "apmixed_mipic126m", "f_f26m_ck",
700+ 11),
701+ GATE_APMIXED(CLK_APMIXED_MEMPLL26M, "apmixed_mempll26m", "f_f26m_ck",
702+ 13),
703+ GATE_APMIXED(CLK_APMIXED_CLKSQ_LVPLL_26M, "apmixed_lvpll26m",
704+ "f_f26m_ck", 14),
705+ GATE_APMIXED(CLK_APMIXED_MIPID0_26M, "apmixed_mipid026m", "f_f26m_ck",
706+ 16),
707+};
708+
709+#define MT6765_PLL_FMAX (3800UL * MHZ)
710+#define MT6765_PLL_FMIN (1500UL * MHZ)
711+
712+#define CON0_MT6765_RST_BAR BIT(23)
713+
714+#define PLL_INFO_NULL (0xFF)
715+
716+#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
717+ _pcwibits, _pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg,\
718+ _tuner_en_bit, _pcw_reg, _pcw_shift, _div_table) {\
719+ .id = _id, \
720+ .name = _name, \
721+ .reg = _reg, \
722+ .pwr_reg = _pwr_reg, \
723+ .en_mask = _en_mask, \
724+ .flags = _flags, \
725+ .rst_bar_mask = CON0_MT6765_RST_BAR, \
726+ .fmax = MT6765_PLL_FMAX, \
727+ .fmin = MT6765_PLL_FMIN, \
728+ .pcwbits = _pcwbits, \
729+ .pcwibits = _pcwibits, \
730+ .pd_reg = _pd_reg, \
731+ .pd_shift = _pd_shift, \
732+ .tuner_reg = _tuner_reg, \
733+ .tuner_en_reg = _tuner_en_reg, \
734+ .tuner_en_bit = _tuner_en_bit, \
735+ .pcw_reg = _pcw_reg, \
736+ .pcw_shift = _pcw_shift, \
737+ .div_table = _div_table, \
738+ }
739+
740+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
741+ _pcwibits, _pd_reg, _pd_shift, _tuner_reg, \
742+ _tuner_en_reg, _tuner_en_bit, _pcw_reg, \
743+ _pcw_shift) \
744+ PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, \
745+ _pcwbits, _pcwibits, _pd_reg, _pd_shift, \
746+ _tuner_reg, _tuner_en_reg, _tuner_en_bit, \
747+ _pcw_reg, _pcw_shift, NULL) \
748+
749+static const struct mtk_pll_data plls[] = {
750+ PLL(CLK_APMIXED_ARMPLL_L, "armpll_l", 0x021C, 0x0228, BIT(0),
751+ PLL_AO, 22, 8, 0x0220, 24, 0, 0, 0, 0x0220, 0),
752+ PLL(CLK_APMIXED_ARMPLL, "armpll", 0x020C, 0x0218, BIT(0),
753+ PLL_AO, 22, 8, 0x0210, 24, 0, 0, 0, 0x0210, 0),
754+ PLL(CLK_APMIXED_CCIPLL, "ccipll", 0x022C, 0x0238, BIT(0),
755+ PLL_AO, 22, 8, 0x0230, 24, 0, 0, 0, 0x0230, 0),
756+ PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x023C, 0x0248, BIT(0),
757+ (HAVE_RST_BAR | PLL_AO), 22, 8, 0x0240, 24, 0, 0, 0, 0x0240,
758+ 0),
759+ PLL(CLK_APMIXED_MFGPLL, "mfgpll", 0x024C, 0x0258, BIT(0),
760+ 0, 22, 8, 0x0250, 24, 0, 0, 0, 0x0250, 0),
761+ PLL(CLK_APMIXED_MMPLL, "mmpll", 0x025C, 0x0268, BIT(0),
762+ 0, 22, 8, 0x0260, 24, 0, 0, 0, 0x0260, 0),
763+ PLL(CLK_APMIXED_UNIV2PLL, "univ2pll", 0x026C, 0x0278, BIT(0),
764+ HAVE_RST_BAR, 22, 8, 0x0270, 24, 0, 0, 0, 0x0270, 0),
765+ PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x027C, 0x0288, BIT(0),
766+ 0, 22, 8, 0x0280, 24, 0, 0, 0, 0x0280, 0),
767+ PLL(CLK_APMIXED_APLL1, "apll1", 0x028C, 0x029C, BIT(0),
768+ 0, 32, 8, 0x0290, 24, 0x0040, 0x000C, 0, 0x0294, 0),
769+ PLL(CLK_APMIXED_MPLL, "mpll", 0x02A0, 0x02AC, BIT(0),
770+ PLL_AO, 22, 8, 0x02A4, 24, 0, 0, 0, 0x02A4, 0),
771+};
772+
773+static int clk_mt6765_apmixed_probe(struct platform_device *pdev)
774+{
775+ struct clk_onecell_data *clk_data;
776+ int r;
777+ struct device_node *node = pdev->dev.of_node;
778+ void __iomem *base;
779+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
780+
781+ base = devm_ioremap_resource(&pdev->dev, res);
782+ if (IS_ERR(base)) {
783+ pr_err("%s(): ioremap failed\n", __func__);
784+ return PTR_ERR(base);
785+ }
786+
787+ clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
788+
789+ mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
790+
791+ mtk_clk_register_gates(node, apmixed_clks,
792+ ARRAY_SIZE(apmixed_clks), clk_data);
793+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
794+
795+ if (r)
796+ pr_err("%s(): could not register clock provider: %d\n",
797+ __func__, r);
798+
799+ apmixed_base = base;
800+ /* MPLL, CCIPLL, MAINPLL set HW mode, TDCLKSQ, CLKSQ1 */
801+ writel(readl(AP_PLL_CON3) & 0xFFFFFFE1, AP_PLL_CON3);
802+ writel(readl(PLLON_CON0) & 0x01041041, PLLON_CON0);
803+ writel(readl(PLLON_CON1) & 0x01041041, PLLON_CON1);
804+
805+ return r;
806+}
807+
808+static int clk_mt6765_top_probe(struct platform_device *pdev)
809+{
810+ int r;
811+ struct device_node *node = pdev->dev.of_node;
812+ void __iomem *base;
813+ struct clk_onecell_data *clk_data;
814+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
815+
816+ base = devm_ioremap_resource(&pdev->dev, res);
817+ if (IS_ERR(base)) {
818+ pr_err("%s(): ioremap failed\n", __func__);
819+ return PTR_ERR(base);
820+ }
821+
822+ clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
823+
824+ mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks),
825+ clk_data);
826+ mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs),
827+ clk_data);
828+ mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes), node,
829+ &mt6765_clk_lock, clk_data);
830+ mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
831+ clk_data);
832+
833+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
834+
835+ if (r)
836+ pr_err("%s(): could not register clock provider: %d\n",
837+ __func__, r);
838+
839+ cksys_base = base;
840+ /* [4]:no need */
841+ writel(readl(CLK_SCP_CFG_0) | 0x3EF, CLK_SCP_CFG_0);
842+ /*[1,2,3,8]: no need*/
843+ writel(readl(CLK_SCP_CFG_1) | 0x1, CLK_SCP_CFG_1);
844+
845+ return r;
846+}
847+
848+static int clk_mt6765_ifr_probe(struct platform_device *pdev)
849+{
850+ struct clk_onecell_data *clk_data;
851+ int r;
852+ struct device_node *node = pdev->dev.of_node;
853+ void __iomem *base;
854+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
855+
856+ base = devm_ioremap_resource(&pdev->dev, res);
857+ if (IS_ERR(base)) {
858+ pr_err("%s(): ioremap failed\n", __func__);
859+ return PTR_ERR(base);
860+ }
861+
862+ clk_data = mtk_alloc_clk_data(CLK_IFR_NR_CLK);
863+
864+ mtk_clk_register_gates(node, ifr_clks, ARRAY_SIZE(ifr_clks),
865+ clk_data);
866+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
867+
868+ if (r)
869+ pr_err("%s(): could not register clock provider: %d\n",
870+ __func__, r);
871+
872+ return r;
873+}
874+
875+static const struct of_device_id of_match_clk_mt6765[] = {
876+ {
877+ .compatible = "mediatek,mt6765-apmixedsys",
878+ .data = clk_mt6765_apmixed_probe,
879+ }, {
880+ .compatible = "mediatek,mt6765-topckgen",
881+ .data = clk_mt6765_top_probe,
882+ }, {
883+ .compatible = "mediatek,mt6765-infracfg",
884+ .data = clk_mt6765_ifr_probe,
885+ }, {
886+ /* sentinel */
887+ }
888+};
889+
890+static int clk_mt6765_probe(struct platform_device *pdev)
891+{
892+ int (*clk_probe)(struct platform_device *d);
893+ int r;
894+
895+ clk_probe = of_device_get_match_data(&pdev->dev);
896+ if (!clk_probe)
897+ return -EINVAL;
898+
899+ r = clk_probe(pdev);
900+ if (r)
901+ dev_err(&pdev->dev,
902+ "could not register clock provider: %s: %d\n",
903+ pdev->name, r);
904+
905+ return r;
906+}
907+
908+static struct platform_driver clk_mt6765_drv = {
909+ .probe = clk_mt6765_probe,
910+ .driver = {
911+ .name = "clk-mt6765",
912+ .owner = THIS_MODULE,
913+ .of_match_table = of_match_clk_mt6765,
914+ },
915+};
916+
917+static int __init clk_mt6765_init(void)
918+{
919+ return platform_driver_register(&clk_mt6765_drv);
920+}
921+
922+arch_initcall(clk_mt6765_init);
drivers/clk/mediatek/clk-mux.c+1−1
@@ -160,7 +160,7 @@ struct clk *mtk_clk_register_mux(const struct mtk_mux *mux, · 159 unmodified lines
160160 spinlock_t *lock)
161161 {
162162 struct mtk_clk_mux *clk_mux;
163− struct clk_init_data init;
163+ struct clk_init_data init = {};
164164 struct clk *clk;
165165
166166 clk_mux = kzalloc(sizeof(*clk_mux), GFP_KERNEL);
drivers/clk/meson/g12a.c+22−8
@@ -3702,7 +3702,9 @@ static struct clk_regmap g12a_hdmi = { · 3701 unmodified lines
37023702
37033703 /*
37043704 * The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
3705− * muxed by a glitch-free switch.
3705+ * muxed by a glitch-free switch. The CCF can manage this glitch-free
3706+ * mux because it does top-to-bottom updates the each clock tree and
3707+ * switches to the "inactive" one when CLK_SET_RATE_GATE is set.
37063708 */
37073709 static const struct clk_parent_data g12a_mali_0_1_parent_data[] = {
37083710 { .fw_name = "xtal", },
@@ -3726,7 +3728,13 @@ static struct clk_regmap g12a_mali_0_sel = { · 17 unmodified lines
37263728 .ops = &clk_regmap_mux_ops,
37273729 .parent_data = g12a_mali_0_1_parent_data,
37283730 .num_parents = 8,
3729− .flags = CLK_SET_RATE_NO_REPARENT,
3731+ /*
3732+ * Don't request the parent to change the rate because
3733+ * all GPU frequencies can be derived from the fclk_*
3734+ * clocks and one special GP0_PLL setting. This is
3735+ * important because we need the MPLL clocks for audio.
3736+ */
3737+ .flags = 0,
37303738 },
37313739 };
37323740
@@ -3743,7 +3751,7 @@ static struct clk_regmap g12a_mali_0_div = { · 10 unmodified lines
37433751 &g12a_mali_0_sel.hw
37443752 },
37453753 .num_parents = 1,
3746− .flags = CLK_SET_RATE_NO_REPARENT,
3754+ .flags = CLK_SET_RATE_PARENT,
37473755 },
37483756 };
37493757
@@ -3759,7 +3767,7 @@ static struct clk_regmap g12a_mali_0 = { · 9 unmodified lines
37593767 &g12a_mali_0_div.hw
37603768 },
37613769 .num_parents = 1,
3762− .flags = CLK_SET_RATE_PARENT,
3770+ .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
37633771 },
37643772 };
37653773
@@ -3774,7 +3782,13 @@ static struct clk_regmap g12a_mali_1_sel = { · 8 unmodified lines
37743782 .ops = &clk_regmap_mux_ops,
37753783 .parent_data = g12a_mali_0_1_parent_data,
37763784 .num_parents = 8,
3777− .flags = CLK_SET_RATE_NO_REPARENT,
3785+ /*
3786+ * Don't request the parent to change the rate because
3787+ * all GPU frequencies can be derived from the fclk_*
3788+ * clocks and one special GP0_PLL setting. This is
3789+ * important because we need the MPLL clocks for audio.
3790+ */
3791+ .flags = 0,
37783792 },
37793793 };
37803794
@@ -3791,7 +3805,7 @@ static struct clk_regmap g12a_mali_1_div = { · 10 unmodified lines
37913805 &g12a_mali_1_sel.hw
37923806 },
37933807 .num_parents = 1,
3794− .flags = CLK_SET_RATE_NO_REPARENT,
3808+ .flags = CLK_SET_RATE_PARENT,
37953809 },
37963810 };
37973811
@@ -3807,7 +3821,7 @@ static struct clk_regmap g12a_mali_1 = { · 9 unmodified lines
38073821 &g12a_mali_1_div.hw
38083822 },
38093823 .num_parents = 1,
3810− .flags = CLK_SET_RATE_PARENT,
3824+ .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
38113825 },
38123826 };
38133827
@@ -3827,7 +3841,7 @@ static struct clk_regmap g12a_mali = { · 13 unmodified lines
38273841 .ops = &clk_regmap_mux_ops,
38283842 .parent_hws = g12a_mali_parent_hws,
38293843 .num_parents = 2,
3830− .flags = CLK_SET_RATE_NO_REPARENT,
3844+ .flags = CLK_SET_RATE_PARENT,
38313845 },
38323846 };
38333847
drivers/clk/meson/gxbb.c+22−18
@@ -957,7 +957,9 @@ static struct clk_regmap gxbb_sar_adc_clk = { · 956 unmodified lines
957957
958958 /*
959959 * The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
960− * muxed by a glitch-free switch.
960+ * muxed by a glitch-free switch. The CCF can manage this glitch-free
961+ * mux because it does top-to-bottom updates the each clock tree and
962+ * switches to the "inactive" one when CLK_SET_RATE_GATE is set.
961963 */
962964
963965 static const struct clk_parent_data gxbb_mali_0_1_parent_data[] = {
@@ -980,14 +982,15 @@ static struct clk_regmap gxbb_mali_0_sel = { · 16 unmodified lines
980982 .hw.init = &(struct clk_init_data){
981983 .name = "mali_0_sel",
982984 .ops = &clk_regmap_mux_ops,
983− /*
984− * bits 10:9 selects from 8 possible parents:
985− * xtal, gp0_pll, mpll2, mpll1, fclk_div7,
986− * fclk_div4, fclk_div3, fclk_div5
987− */
988985 .parent_data = gxbb_mali_0_1_parent_data,
989986 .num_parents = 8,
990− .flags = CLK_SET_RATE_NO_REPARENT,
987+ /*
988+ * Don't request the parent to change the rate because
989+ * all GPU frequencies can be derived from the fclk_*
990+ * clocks and one special GP0_PLL setting. This is
991+ * important because we need the MPLL clocks for audio.
992+ */
993+ .flags = 0,
991994 },
992995 };
993996
@@ -1004,7 +1007,7 @@ static struct clk_regmap gxbb_mali_0_div = { · 10 unmodified lines
10041007 &gxbb_mali_0_sel.hw
10051008 },
10061009 .num_parents = 1,
1007− .flags = CLK_SET_RATE_NO_REPARENT,
1010+ .flags = CLK_SET_RATE_PARENT,
10081011 },
10091012 };
10101013
@@ -1020,7 +1023,7 @@ static struct clk_regmap gxbb_mali_0 = { · 9 unmodified lines
10201023 &gxbb_mali_0_div.hw
10211024 },
10221025 .num_parents = 1,
1023− .flags = CLK_SET_RATE_PARENT,
1026+ .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
10241027 },
10251028 };
10261029
@@ -1033,14 +1036,15 @@ static struct clk_regmap gxbb_mali_1_sel = { · 6 unmodified lines
10331036 .hw.init = &(struct clk_init_data){
10341037 .name = "mali_1_sel",
10351038 .ops = &clk_regmap_mux_ops,
1036− /*
1037− * bits 10:9 selects from 8 possible parents:
1038− * xtal, gp0_pll, mpll2, mpll1, fclk_div7,
1039− * fclk_div4, fclk_div3, fclk_div5
1040− */
10411039 .parent_data = gxbb_mali_0_1_parent_data,
10421040 .num_parents = 8,
1043− .flags = CLK_SET_RATE_NO_REPARENT,
1041+ /*
1042+ * Don't request the parent to change the rate because
1043+ * all GPU frequencies can be derived from the fclk_*
1044+ * clocks and one special GP0_PLL setting. This is
1045+ * important because we need the MPLL clocks for audio.
1046+ */
1047+ .flags = 0,
10441048 },
10451049 };
10461050
@@ -1057,7 +1061,7 @@ static struct clk_regmap gxbb_mali_1_div = { · 10 unmodified lines
10571061 &gxbb_mali_1_sel.hw
10581062 },
10591063 .num_parents = 1,
1060− .flags = CLK_SET_RATE_NO_REPARENT,
1064+ .flags = CLK_SET_RATE_PARENT,
10611065 },
10621066 };
10631067
@@ -1073,7 +1077,7 @@ static struct clk_regmap gxbb_mali_1 = { · 9 unmodified lines
10731077 &gxbb_mali_1_div.hw
10741078 },
10751079 .num_parents = 1,
1076− .flags = CLK_SET_RATE_PARENT,
1080+ .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
10771081 },
10781082 };
10791083
@@ -1093,7 +1097,7 @@ static struct clk_regmap gxbb_mali = { · 13 unmodified lines
10931097 .ops = &clk_regmap_mux_ops,
10941098 .parent_hws = gxbb_mali_parent_hws,
10951099 .num_parents = 2,
1096− .flags = CLK_SET_RATE_NO_REPARENT,
1100+ .flags = CLK_SET_RATE_PARENT,
10971101 },
10981102 };
10991103
drivers/clk/meson/meson8b.c+85−35
@@ -1077,7 +1077,7 @@ static struct clk_regmap meson8b_vid_pll_in_sel = { · 1076 unmodified lines
10771077 * Meson8m2: vid2_pll
10781078 */
10791079 .parent_hws = (const struct clk_hw *[]) {
1080− &meson8b_hdmi_pll_dco.hw
1080+ &meson8b_hdmi_pll_lvds_out.hw
10811081 },
10821082 .num_parents = 1,
10831083 .flags = CLK_SET_RATE_PARENT,
@@ -1213,7 +1213,7 @@ static struct clk_regmap meson8b_vclk_in_en = { · 129 unmodified lines
12131213
12141214 static struct clk_regmap meson8b_vclk_div1_gate = {
12151215 .data = &(struct clk_regmap_gate_data){
1216− .offset = HHI_VID_CLK_DIV,
1216+ .offset = HHI_VID_CLK_CNTL,
12171217 .bit_idx = 0,
12181218 },
12191219 .hw.init = &(struct clk_init_data){
@@ -1243,7 +1243,7 @@ static struct clk_fixed_factor meson8b_vclk_div2_div = { · 23 unmodified lines
12431243
12441244 static struct clk_regmap meson8b_vclk_div2_div_gate = {
12451245 .data = &(struct clk_regmap_gate_data){
1246− .offset = HHI_VID_CLK_DIV,
1246+ .offset = HHI_VID_CLK_CNTL,
12471247 .bit_idx = 1,
12481248 },
12491249 .hw.init = &(struct clk_init_data){
@@ -1273,7 +1273,7 @@ static struct clk_fixed_factor meson8b_vclk_div4_div = { · 23 unmodified lines
12731273
12741274 static struct clk_regmap meson8b_vclk_div4_div_gate = {
12751275 .data = &(struct clk_regmap_gate_data){
1276− .offset = HHI_VID_CLK_DIV,
1276+ .offset = HHI_VID_CLK_CNTL,
12771277 .bit_idx = 2,
12781278 },
12791279 .hw.init = &(struct clk_init_data){
@@ -1303,7 +1303,7 @@ static struct clk_fixed_factor meson8b_vclk_div6_div = { · 23 unmodified lines
13031303
13041304 static struct clk_regmap meson8b_vclk_div6_div_gate = {
13051305 .data = &(struct clk_regmap_gate_data){
1306− .offset = HHI_VID_CLK_DIV,
1306+ .offset = HHI_VID_CLK_CNTL,
13071307 .bit_idx = 3,
13081308 },
13091309 .hw.init = &(struct clk_init_data){
@@ -1333,7 +1333,7 @@ static struct clk_fixed_factor meson8b_vclk_div12_div = { · 23 unmodified lines
13331333
13341334 static struct clk_regmap meson8b_vclk_div12_div_gate = {
13351335 .data = &(struct clk_regmap_gate_data){
1336− .offset = HHI_VID_CLK_DIV,
1336+ .offset = HHI_VID_CLK_CNTL,
13371337 .bit_idx = 4,
13381338 },
13391339 .hw.init = &(struct clk_init_data){
@@ -1725,7 +1725,7 @@ static struct clk_regmap meson8b_hdmi_sys_sel = { · 385 unmodified lines
17251725 },
17261726 .hw.init = &(struct clk_init_data){
17271727 .name = "hdmi_sys_sel",
1728− .ops = &clk_regmap_mux_ro_ops,
1728+ .ops = &clk_regmap_mux_ops,
17291729 /* FIXME: all other parents are unknown */
17301730 .parent_data = &(const struct clk_parent_data) {
17311731 .fw_name = "xtal",
@@ -1745,7 +1745,7 @@ static struct clk_regmap meson8b_hdmi_sys_div = { · 13 unmodified lines
17451745 },
17461746 .hw.init = &(struct clk_init_data){
17471747 .name = "hdmi_sys_div",
1748− .ops = &clk_regmap_divider_ro_ops,
1748+ .ops = &clk_regmap_divider_ops,
17491749 .parent_hws = (const struct clk_hw *[]) {
17501750 &meson8b_hdmi_sys_sel.hw
17511751 },
@@ -1761,7 +1761,7 @@ static struct clk_regmap meson8b_hdmi_sys = { · 9 unmodified lines
17611761 },
17621762 .hw.init = &(struct clk_init_data) {
17631763 .name = "hdmi_sys",
1764− .ops = &clk_regmap_gate_ro_ops,
1764+ .ops = &clk_regmap_gate_ops,
17651765 .parent_hws = (const struct clk_hw *[]) {
17661766 &meson8b_hdmi_sys_div.hw
17671767 },
@@ -1918,6 +1918,13 @@ static struct clk_regmap meson8b_mali = { · 150 unmodified lines
19181918 },
19191919 };
19201920
1921+static const struct reg_sequence meson8m2_gp_pll_init_regs[] = {
1922+ { .reg = HHI_GP_PLL_CNTL2, .def = 0x59c88000 },
1923+ { .reg = HHI_GP_PLL_CNTL3, .def = 0xca463823 },
1924+ { .reg = HHI_GP_PLL_CNTL4, .def = 0x0286a027 },
1925+ { .reg = HHI_GP_PLL_CNTL5, .def = 0x00003000 },
1926+};
1927+
19211928 static const struct pll_params_table meson8m2_gp_pll_params_table[] = {
19221929 PLL_PARAMS(182, 3),
19231930 { /* sentinel */ },
@@ -1951,6 +1958,8 @@ static struct clk_regmap meson8m2_gp_pll_dco = { · 27 unmodified lines
19511958 .width = 1,
19521959 },
19531960 .table = meson8m2_gp_pll_params_table,
1961+ .init_regs = meson8m2_gp_pll_init_regs,
1962+ .init_count = ARRAY_SIZE(meson8m2_gp_pll_init_regs),
19541963 },
19551964 .hw.init = &(struct clk_init_data){
19561965 .name = "gp_pll_dco",
@@ -2063,7 +2072,7 @@ static struct clk_regmap meson8b_vpu_0 = { · 106 unmodified lines
20632072 &meson8b_vpu_0_div.hw
20642073 },
20652074 .num_parents = 1,
2066− .flags = CLK_SET_RATE_PARENT,
2075+ .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
20672076 },
20682077 };
20692078
@@ -2134,10 +2143,18 @@ static struct clk_regmap meson8b_vpu_1 = { · 64 unmodified lines
21342143 &meson8b_vpu_1_div.hw
21352144 },
21362145 .num_parents = 1,
2137− .flags = CLK_SET_RATE_PARENT,
2146+ .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
21382147 },
21392148 };
21402149
2150+/*
2151+ * The VPU clock has two two identical clock trees (vpu_0 and vpu_1)
2152+ * muxed by a glitch-free switch on Meson8b and Meson8m2. The CCF can
2153+ * actually manage this glitch-free mux because it does top-to-bottom
2154+ * updates the each clock tree and switches to the "inactive" one when
2155+ * CLK_SET_RATE_GATE is set.
2156+ * Meson8 only has vpu_0 and no glitch-free mux.
2157+ */
21412158 static struct clk_regmap meson8b_vpu = {
21422159 .data = &(struct clk_regmap_mux_data){
21432160 .offset = HHI_VPU_CLK_CNTL,
@@ -2152,7 +2169,7 @@ static struct clk_regmap meson8b_vpu = { · 8 unmodified lines
21522169 &meson8b_vpu_1.hw,
21532170 },
21542171 .num_parents = 2,
2155− .flags = CLK_SET_RATE_NO_REPARENT,
2172+ .flags = CLK_SET_RATE_PARENT,
21562173 },
21572174 };
21582175
@@ -3506,54 +3523,87 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = { · 1347 unmodified lines
35063523 static const struct meson8b_clk_reset_line {
35073524 u32 reg;
35083525 u8 bit_idx;
3526+ bool active_low;
35093527 } meson8b_clk_reset_bits[] = {
35103528 [CLKC_RESET_L2_CACHE_SOFT_RESET] = {
3511− .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 30
3529+ .reg = HHI_SYS_CPU_CLK_CNTL0,
3530+ .bit_idx = 30,
3531+ .active_low = false,
35123532 },
35133533 [CLKC_RESET_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET] = {
3514− .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 29
3534+ .reg = HHI_SYS_CPU_CLK_CNTL0,
3535+ .bit_idx = 29,
3536+ .active_low = false,
35153537 },
35163538 [CLKC_RESET_SCU_SOFT_RESET] = {
3517− .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 28
3539+ .reg = HHI_SYS_CPU_CLK_CNTL0,
3540+ .bit_idx = 28,
3541+ .active_low = false,
35183542 },
35193543 [CLKC_RESET_CPU3_SOFT_RESET] = {
3520− .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 27
3544+ .reg = HHI_SYS_CPU_CLK_CNTL0,
3545+ .bit_idx = 27,
3546+ .active_low = false,
35213547 },
35223548 [CLKC_RESET_CPU2_SOFT_RESET] = {
3523− .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 26
3549+ .reg = HHI_SYS_CPU_CLK_CNTL0,
3550+ .bit_idx = 26,
3551+ .active_low = false,
35243552 },
35253553 [CLKC_RESET_CPU1_SOFT_RESET] = {
3526− .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 25
3554+ .reg = HHI_SYS_CPU_CLK_CNTL0,
3555+ .bit_idx = 25,
3556+ .active_low = false,
35273557 },
35283558 [CLKC_RESET_CPU0_SOFT_RESET] = {
3529− .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 24
3559+ .reg = HHI_SYS_CPU_CLK_CNTL0,
3560+ .bit_idx = 24,
3561+ .active_low = false,
35303562 },
35313563 [CLKC_RESET_A5_GLOBAL_RESET] = {
3532− .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 18
3564+ .reg = HHI_SYS_CPU_CLK_CNTL0,
3565+ .bit_idx = 18,
3566+ .active_low = false,
35333567 },
35343568 [CLKC_RESET_A5_AXI_SOFT_RESET] = {
3535− .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 17
3569+ .reg = HHI_SYS_CPU_CLK_CNTL0,
3570+ .bit_idx = 17,
3571+ .active_low = false,
35363572 },
35373573 [CLKC_RESET_A5_ABP_SOFT_RESET] = {
3538− .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 16
3574+ .reg = HHI_SYS_CPU_CLK_CNTL0,
3575+ .bit_idx = 16,
3576+ .active_low = false,
35393577 },
35403578 [CLKC_RESET_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET] = {
3541− .reg = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 30
3579+ .reg = HHI_SYS_CPU_CLK_CNTL1,
3580+ .bit_idx = 30,
3581+ .active_low = false,
35423582 },
35433583 [CLKC_RESET_VID_CLK_CNTL_SOFT_RESET] = {
3544− .reg = HHI_VID_CLK_CNTL, .bit_idx = 15
3584+ .reg = HHI_VID_CLK_CNTL,
3585+ .bit_idx = 15,
3586+ .active_low = false,
35453587 },
35463588 [CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST] = {
3547− .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 7
3589+ .reg = HHI_VID_DIVIDER_CNTL,
3590+ .bit_idx = 7,
3591+ .active_low = false,
35483592 },
35493593 [CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE] = {
3550− .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 3
3594+ .reg = HHI_VID_DIVIDER_CNTL,
3595+ .bit_idx = 3,
3596+ .active_low = false,
35513597 },
35523598 [CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST] = {
3553− .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 1
3599+ .reg = HHI_VID_DIVIDER_CNTL,
3600+ .bit_idx = 1,
3601+ .active_low = true,
35543602 },
35553603 [CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE] = {
3556− .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 0
3604+ .reg = HHI_VID_DIVIDER_CNTL,
3605+ .bit_idx = 0,
3606+ .active_low = true,
35573607 },
35583608 };
35593609
@@ -3562,22 +3612,22 @@ static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev, · 2 unmodified lines
35623612 {
35633613 struct meson8b_clk_reset *meson8b_clk_reset =
35643614 container_of(rcdev, struct meson8b_clk_reset, reset);
3565− unsigned long flags;
35663615 const struct meson8b_clk_reset_line *reset;
3616+ unsigned int value = 0;
3617+ unsigned long flags;
35673618
35683619 if (id >= ARRAY_SIZE(meson8b_clk_reset_bits))
35693620 return -EINVAL;
35703621
35713622 reset = &meson8b_clk_reset_bits[id];
35723623
3624+ if (assert != reset->active_low)
3625+ value = BIT(reset->bit_idx);
3626+
35733627 spin_lock_irqsave(&meson_clk_lock, flags);
35743628
3575− if (assert)
3576− regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
3577− BIT(reset->bit_idx), BIT(reset->bit_idx));
3578− else
3579− regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
3580− BIT(reset->bit_idx), 0);
3629+ regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
3630+ BIT(reset->bit_idx), value);
35813631
35823632 spin_unlock_irqrestore(&meson_clk_lock, flags);
35833633
drivers/clk/meson/meson8b.h+4−1
@@ -20,6 +20,10 @@ · 19 unmodified lines
2020 * [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
2121 */
2222 #define HHI_GP_PLL_CNTL 0x40 /* 0x10 offset in data sheet */
23+#define HHI_GP_PLL_CNTL2 0x44 /* 0x11 offset in data sheet */
24+#define HHI_GP_PLL_CNTL3 0x48 /* 0x12 offset in data sheet */
25+#define HHI_GP_PLL_CNTL4 0x4C /* 0x13 offset in data sheet */
26+#define HHI_GP_PLL_CNTL5 0x50 /* 0x14 offset in data sheet */
2327 #define HHI_VIID_CLK_DIV 0x128 /* 0x4a offset in data sheet */
2428 #define HHI_VIID_CLK_CNTL 0x12c /* 0x4b offset in data sheet */
2529 #define HHI_GCLK_MPEG0 0x140 /* 0x50 offset in data sheet */
@@ -146,7 +150,6 @@ · 120 unmodified lines
146150 #define CLKID_CTS_VDAC0 171
147151 #define CLKID_HDMI_SYS_SEL 172
148152 #define CLKID_HDMI_SYS_DIV 173
149−#define CLKID_HDMI_SYS 174
150153 #define CLKID_MALI_0_SEL 175
151154 #define CLKID_MALI_0_DIV 176
152155 #define CLKID_MALI_0 177
drivers/clk/mmp/Makefile+2−1
@@ -8,7 +8,8 @@ obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o · 7 unmodified lines
88 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
99
1010 obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o
11−obj-$(CONFIG_COMMON_CLK_MMP2) += clk-of-mmp2.o clk-pll.o
11+obj-$(CONFIG_COMMON_CLK_MMP2) += clk-of-mmp2.o clk-pll.o pwr-island.o
12+obj-$(CONFIG_COMMON_CLK_MMP2_AUDIO) += clk-audio.o
1213
1314 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
1415 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
drivers/clk/mmp/clk-audio.c+443−0
@@ -0,0 +1,443 @@
1+// SPDX-License-Identifier: GPL-2.0-or-later
2+/*
3+ * MMP Audio Clock Controller driver
4+ *
5+ * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
6+ */
7+
8+#include <linux/clk-provider.h>
9+#include <linux/io.h>
10+#include <linux/module.h>
11+#include <linux/platform_device.h>
12+#include <linux/pm_clock.h>
13+#include <linux/pm_runtime.h>
14+#include <linux/slab.h>
15+#include <dt-bindings/clock/marvell,mmp2-audio.h>
16+
17+/* Audio Controller Registers */
18+#define SSPA_AUD_CTRL 0x04
19+#define SSPA_AUD_PLL_CTRL0 0x08
20+#define SSPA_AUD_PLL_CTRL1 0x0c
21+
22+/* SSPA Audio Control Register */
23+#define SSPA_AUD_CTRL_SYSCLK_SHIFT 0
24+#define SSPA_AUD_CTRL_SYSCLK_DIV_SHIFT 1
25+#define SSPA_AUD_CTRL_SSPA0_MUX_SHIFT 7
26+#define SSPA_AUD_CTRL_SSPA0_SHIFT 8
27+#define SSPA_AUD_CTRL_SSPA0_DIV_SHIFT 9
28+#define SSPA_AUD_CTRL_SSPA1_SHIFT 16
29+#define SSPA_AUD_CTRL_SSPA1_DIV_SHIFT 17
30+#define SSPA_AUD_CTRL_SSPA1_MUX_SHIFT 23
31+#define SSPA_AUD_CTRL_DIV_MASK 0x7e
32+
33+/* SSPA Audio PLL Control 0 Register */
34+#define SSPA_AUD_PLL_CTRL0_DIV_OCLK_MODULO_MASK (0x7 << 28)
35+#define SSPA_AUD_PLL_CTRL0_DIV_OCLK_MODULO(x) ((x) << 28)
36+#define SSPA_AUD_PLL_CTRL0_FRACT_MASK (0xfffff << 8)
37+#define SSPA_AUD_PLL_CTRL0_FRACT(x) ((x) << 8)
38+#define SSPA_AUD_PLL_CTRL0_ENA_DITHER (1 << 7)
39+#define SSPA_AUD_PLL_CTRL0_ICP_2UA (0 << 5)
40+#define SSPA_AUD_PLL_CTRL0_ICP_5UA (1 << 5)
41+#define SSPA_AUD_PLL_CTRL0_ICP_7UA (2 << 5)
42+#define SSPA_AUD_PLL_CTRL0_ICP_10UA (3 << 5)
43+#define SSPA_AUD_PLL_CTRL0_DIV_FBCCLK_MASK (0x3 << 3)
44+#define SSPA_AUD_PLL_CTRL0_DIV_FBCCLK(x) ((x) << 3)
45+#define SSPA_AUD_PLL_CTRL0_DIV_MCLK_MASK (0x1 << 2)
46+#define SSPA_AUD_PLL_CTRL0_DIV_MCLK(x) ((x) << 2)
47+#define SSPA_AUD_PLL_CTRL0_PD_OVPROT_DIS (1 << 1)
48+#define SSPA_AUD_PLL_CTRL0_PU (1 << 0)
49+
50+/* SSPA Audio PLL Control 1 Register */
51+#define SSPA_AUD_PLL_CTRL1_SEL_FAST_CLK (1 << 24)
52+#define SSPA_AUD_PLL_CTRL1_CLK_SEL_MASK (1 << 11)
53+#define SSPA_AUD_PLL_CTRL1_CLK_SEL_AUDIO_PLL (1 << 11)
54+#define SSPA_AUD_PLL_CTRL1_CLK_SEL_VCXO (0 << 11)
55+#define SSPA_AUD_PLL_CTRL1_DIV_OCLK_PATTERN_MASK (0x7ff << 0)
56+#define SSPA_AUD_PLL_CTRL1_DIV_OCLK_PATTERN(x) ((x) << 0)
57+
58+struct mmp2_audio_clk {
59+ void __iomem *mmio_base;
60+
61+ struct clk_hw audio_pll_hw;
62+ struct clk_mux sspa_mux;
63+ struct clk_mux sspa1_mux;
64+ struct clk_divider sysclk_div;
65+ struct clk_divider sspa0_div;
66+ struct clk_divider sspa1_div;
67+ struct clk_gate sysclk_gate;
68+ struct clk_gate sspa0_gate;
69+ struct clk_gate sspa1_gate;
70+
71+ u32 aud_ctrl;
72+ u32 aud_pll_ctrl0;
73+ u32 aud_pll_ctrl1;
74+
75+ spinlock_t lock;
76+
77+ /* Must be last */
78+ struct clk_hw_onecell_data clk_data;
79+};
80+
81+static const struct {
82+ unsigned long parent_rate;
83+ unsigned long freq_vco;
84+ unsigned char mclk;
85+ unsigned char fbcclk;
86+ unsigned short fract;
87+} predivs[] = {
88+ { 26000000, 135475200, 0, 0, 0x8a18 },
89+ { 26000000, 147456000, 0, 1, 0x0da1 },
90+ { 38400000, 135475200, 1, 2, 0x8208 },
91+ { 38400000, 147456000, 1, 3, 0xaaaa },
92+};
93+
94+static const struct {
95+ unsigned char divisor;
96+ unsigned char modulo;
97+ unsigned char pattern;
98+} postdivs[] = {
99+ { 1, 3, 0, },
100+ { 2, 5, 0, },
101+ { 4, 0, 0, },
102+ { 6, 1, 1, },
103+ { 8, 1, 0, },
104+ { 9, 1, 2, },
105+ { 12, 2, 1, },
106+ { 16, 2, 0, },
107+ { 18, 2, 2, },
108+ { 24, 4, 1, },
109+ { 36, 4, 2, },
110+ { 48, 6, 1, },
111+ { 72, 6, 2, },
112+};
113+
114+static unsigned long audio_pll_recalc_rate(struct clk_hw *hw,
115+ unsigned long parent_rate)
116+{
117+ struct mmp2_audio_clk *priv = container_of(hw, struct mmp2_audio_clk, audio_pll_hw);
118+ unsigned int prediv;
119+ unsigned int postdiv;
120+ u32 aud_pll_ctrl0;
121+ u32 aud_pll_ctrl1;
122+
123+ aud_pll_ctrl0 = readl(priv->mmio_base + SSPA_AUD_PLL_CTRL0);
124+ aud_pll_ctrl0 &= SSPA_AUD_PLL_CTRL0_DIV_OCLK_MODULO_MASK |
125+ SSPA_AUD_PLL_CTRL0_FRACT_MASK |
126+ SSPA_AUD_PLL_CTRL0_ENA_DITHER |
127+ SSPA_AUD_PLL_CTRL0_DIV_FBCCLK_MASK |
128+ SSPA_AUD_PLL_CTRL0_DIV_MCLK_MASK |
129+ SSPA_AUD_PLL_CTRL0_PU;
130+
131+ aud_pll_ctrl1 = readl(priv->mmio_base + SSPA_AUD_PLL_CTRL1);
132+ aud_pll_ctrl1 &= SSPA_AUD_PLL_CTRL1_CLK_SEL_MASK |
133+ SSPA_AUD_PLL_CTRL1_DIV_OCLK_PATTERN_MASK;
134+
135+ for (prediv = 0; prediv < ARRAY_SIZE(predivs); prediv++) {
136+ if (predivs[prediv].parent_rate != parent_rate)
137+ continue;
138+ for (postdiv = 0; postdiv < ARRAY_SIZE(postdivs); postdiv++) {
139+ unsigned long freq;
140+ u32 val;
141+
142+ val = SSPA_AUD_PLL_CTRL0_ENA_DITHER;
143+ val |= SSPA_AUD_PLL_CTRL0_PU;
144+ val |= SSPA_AUD_PLL_CTRL0_DIV_OCLK_MODULO(postdivs[postdiv].modulo);
145+ val |= SSPA_AUD_PLL_CTRL0_FRACT(predivs[prediv].fract);
146+ val |= SSPA_AUD_PLL_CTRL0_DIV_FBCCLK(predivs[prediv].fbcclk);
147+ val |= SSPA_AUD_PLL_CTRL0_DIV_MCLK(predivs[prediv].mclk);
148+ if (val != aud_pll_ctrl0)
149+ continue;
150+
151+ val = SSPA_AUD_PLL_CTRL1_CLK_SEL_AUDIO_PLL;
152+ val |= SSPA_AUD_PLL_CTRL1_DIV_OCLK_PATTERN(postdivs[postdiv].pattern);
153+ if (val != aud_pll_ctrl1)
154+ continue;
155+
156+ freq = predivs[prediv].freq_vco;
157+ freq /= postdivs[postdiv].divisor;
158+ return freq;
159+ }
160+ }
161+
162+ return 0;
163+}
164+
165+static long audio_pll_round_rate(struct clk_hw *hw, unsigned long rate,
166+ unsigned long *parent_rate)
167+{
168+ unsigned int prediv;
169+ unsigned int postdiv;
170+ long rounded = 0;
171+
172+ for (prediv = 0; prediv < ARRAY_SIZE(predivs); prediv++) {
173+ if (predivs[prediv].parent_rate != *parent_rate)
174+ continue;
175+ for (postdiv = 0; postdiv < ARRAY_SIZE(postdivs); postdiv++) {
176+ long freq = predivs[prediv].freq_vco;
177+
178+ freq /= postdivs[postdiv].divisor;
179+ if (freq == rate)
180+ return rate;
181+ if (freq < rate)
182+ continue;
183+ if (rounded && freq > rounded)
184+ continue;
185+ rounded = freq;
186+ }
187+ }
188+
189+ return rounded;
190+}
191+
192+static int audio_pll_set_rate(struct clk_hw *hw, unsigned long rate,
193+ unsigned long parent_rate)
194+{
195+ struct mmp2_audio_clk *priv = container_of(hw, struct mmp2_audio_clk, audio_pll_hw);
196+ unsigned int prediv;
197+ unsigned int postdiv;
198+ unsigned long val;
199+
200+ for (prediv = 0; prediv < ARRAY_SIZE(predivs); prediv++) {
201+ if (predivs[prediv].parent_rate != parent_rate)
202+ continue;
203+
204+ for (postdiv = 0; postdiv < ARRAY_SIZE(postdivs); postdiv++) {
205+ if (rate * postdivs[postdiv].divisor != predivs[prediv].freq_vco)
206+ continue;
207+
208+ val = SSPA_AUD_PLL_CTRL0_ENA_DITHER;
209+ val |= SSPA_AUD_PLL_CTRL0_PU;
210+ val |= SSPA_AUD_PLL_CTRL0_DIV_OCLK_MODULO(postdivs[postdiv].modulo);
211+ val |= SSPA_AUD_PLL_CTRL0_FRACT(predivs[prediv].fract);
212+ val |= SSPA_AUD_PLL_CTRL0_DIV_FBCCLK(predivs[prediv].fbcclk);
213+ val |= SSPA_AUD_PLL_CTRL0_DIV_MCLK(predivs[prediv].mclk);
214+ writel(val, priv->mmio_base + SSPA_AUD_PLL_CTRL0);
215+
216+ val = SSPA_AUD_PLL_CTRL1_CLK_SEL_AUDIO_PLL;
217+ val |= SSPA_AUD_PLL_CTRL1_DIV_OCLK_PATTERN(postdivs[postdiv].pattern);
218+ writel(val, priv->mmio_base + SSPA_AUD_PLL_CTRL1);
219+
220+ return 0;
221+ }
222+ }
223+
224+ return -ERANGE;
225+}
226+
227+static const struct clk_ops audio_pll_ops = {
228+ .recalc_rate = audio_pll_recalc_rate,
229+ .round_rate = audio_pll_round_rate,
230+ .set_rate = audio_pll_set_rate,
231+};
232+
233+static int register_clocks(struct mmp2_audio_clk *priv, struct device *dev)
234+{
235+ const struct clk_parent_data sspa_mux_parents[] = {
236+ { .hw = &priv->audio_pll_hw },
237+ { .fw_name = "i2s0" },
238+ };
239+ const struct clk_parent_data sspa1_mux_parents[] = {
240+ { .hw = &priv->audio_pll_hw },
241+ { .fw_name = "i2s1" },
242+ };
243+ int ret;
244+
245+ priv->audio_pll_hw.init = CLK_HW_INIT_FW_NAME("audio_pll",
246+ "vctcxo", &audio_pll_ops,
247+ CLK_SET_RATE_PARENT);
248+ ret = devm_clk_hw_register(dev, &priv->audio_pll_hw);
249+ if (ret)
250+ return ret;
251+
252+ priv->sspa_mux.hw.init = CLK_HW_INIT_PARENTS_DATA("sspa_mux",
253+ sspa_mux_parents, &clk_mux_ops,
254+ CLK_SET_RATE_PARENT);
255+ priv->sspa_mux.reg = priv->mmio_base + SSPA_AUD_CTRL;
256+ priv->sspa_mux.mask = 1;
257+ priv->sspa_mux.shift = SSPA_AUD_CTRL_SSPA0_MUX_SHIFT;
258+ ret = devm_clk_hw_register(dev, &priv->sspa_mux.hw);
259+ if (ret)
260+ return ret;
261+
262+ priv->sysclk_div.hw.init = CLK_HW_INIT_HW("sys_div",
263+ &priv->sspa_mux.hw, &clk_divider_ops,
264+ CLK_SET_RATE_PARENT);
265+ priv->sysclk_div.reg = priv->mmio_base + SSPA_AUD_CTRL;
266+ priv->sysclk_div.shift = SSPA_AUD_CTRL_SYSCLK_DIV_SHIFT;
267+ priv->sysclk_div.width = 6;
268+ priv->sysclk_div.flags = CLK_DIVIDER_ONE_BASED;
269+ priv->sysclk_div.flags |= CLK_DIVIDER_ROUND_CLOSEST;
270+ priv->sysclk_div.flags |= CLK_DIVIDER_ALLOW_ZERO;
271+ ret = devm_clk_hw_register(dev, &priv->sysclk_div.hw);
272+ if (ret)
273+ return ret;
274+
275+ priv->sysclk_gate.hw.init = CLK_HW_INIT_HW("sys_clk",
276+ &priv->sysclk_div.hw, &clk_gate_ops,
277+ CLK_SET_RATE_PARENT);
278+ priv->sysclk_gate.reg = priv->mmio_base + SSPA_AUD_CTRL;
279+ priv->sysclk_gate.bit_idx = SSPA_AUD_CTRL_SYSCLK_SHIFT;
280+ ret = devm_clk_hw_register(dev, &priv->sysclk_gate.hw);
281+ if (ret)
282+ return ret;
283+
284+ priv->sspa0_div.hw.init = CLK_HW_INIT_HW("sspa0_div",
285+ &priv->sspa_mux.hw, &clk_divider_ops, 0);
286+ priv->sspa0_div.reg = priv->mmio_base + SSPA_AUD_CTRL;
287+ priv->sspa0_div.shift = SSPA_AUD_CTRL_SSPA0_DIV_SHIFT;
288+ priv->sspa0_div.width = 6;
289+ priv->sspa0_div.flags = CLK_DIVIDER_ONE_BASED;
290+ priv->sspa0_div.flags |= CLK_DIVIDER_ROUND_CLOSEST;
291+ priv->sspa0_div.flags |= CLK_DIVIDER_ALLOW_ZERO;
292+ ret = devm_clk_hw_register(dev, &priv->sspa0_div.hw);
293+ if (ret)
294+ return ret;
295+
296+ priv->sspa0_gate.hw.init = CLK_HW_INIT_HW("sspa0_clk",
297+ &priv->sspa0_div.hw, &clk_gate_ops,
298+ CLK_SET_RATE_PARENT);
299+ priv->sspa0_gate.reg = priv->mmio_base + SSPA_AUD_CTRL;
300+ priv->sspa0_gate.bit_idx = SSPA_AUD_CTRL_SSPA0_SHIFT;
301+ ret = devm_clk_hw_register(dev, &priv->sspa0_gate.hw);
302+ if (ret)
303+ return ret;
304+
305+ priv->sspa1_mux.hw.init = CLK_HW_INIT_PARENTS_DATA("sspa1_mux",
306+ sspa1_mux_parents, &clk_mux_ops,
307+ CLK_SET_RATE_PARENT);
308+ priv->sspa1_mux.reg = priv->mmio_base + SSPA_AUD_CTRL;
309+ priv->sspa1_mux.mask = 1;
310+ priv->sspa1_mux.shift = SSPA_AUD_CTRL_SSPA1_MUX_SHIFT;
311+ ret = devm_clk_hw_register(dev, &priv->sspa1_mux.hw);
312+ if (ret)
313+ return ret;
314+
315+ priv->sspa1_div.hw.init = CLK_HW_INIT_HW("sspa1_div",
316+ &priv->sspa1_mux.hw, &clk_divider_ops, 0);
317+ priv->sspa1_div.reg = priv->mmio_base + SSPA_AUD_CTRL;
318+ priv->sspa1_div.shift = SSPA_AUD_CTRL_SSPA1_DIV_SHIFT;
319+ priv->sspa1_div.width = 6;
320+ priv->sspa1_div.flags = CLK_DIVIDER_ONE_BASED;
321+ priv->sspa1_div.flags |= CLK_DIVIDER_ROUND_CLOSEST;
322+ priv->sspa1_div.flags |= CLK_DIVIDER_ALLOW_ZERO;
323+ ret = devm_clk_hw_register(dev, &priv->sspa1_div.hw);
324+ if (ret)
325+ return ret;
326+
327+ priv->sspa1_gate.hw.init = CLK_HW_INIT_HW("sspa1_clk",
328+ &priv->sspa1_div.hw, &clk_gate_ops,
329+ CLK_SET_RATE_PARENT);
330+ priv->sspa1_gate.reg = priv->mmio_base + SSPA_AUD_CTRL;
331+ priv->sspa1_gate.bit_idx = SSPA_AUD_CTRL_SSPA1_SHIFT;
332+ ret = devm_clk_hw_register(dev, &priv->sspa1_gate.hw);
333+ if (ret)
334+ return ret;
335+
336+ priv->clk_data.hws[MMP2_CLK_AUDIO_SYSCLK] = &priv->sysclk_gate.hw;
337+ priv->clk_data.hws[MMP2_CLK_AUDIO_SSPA0] = &priv->sspa0_gate.hw;
338+ priv->clk_data.hws[MMP2_CLK_AUDIO_SSPA1] = &priv->sspa1_gate.hw;
339+ priv->clk_data.num = MMP2_CLK_AUDIO_NR_CLKS;
340+
341+ return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
342+ &priv->clk_data);
343+}
344+
345+static int mmp2_audio_clk_probe(struct platform_device *pdev)
346+{
347+ struct mmp2_audio_clk *priv;
348+ int ret;
349+
350+ priv = devm_kzalloc(&pdev->dev,
351+ struct_size(priv, clk_data.hws,
352+ MMP2_CLK_AUDIO_NR_CLKS),
353+ GFP_KERNEL);
354+ if (!priv)
355+ return -ENOMEM;
356+
357+ spin_lock_init(&priv->lock);
358+ platform_set_drvdata(pdev, priv);
359+
360+ priv->mmio_base = devm_platform_ioremap_resource(pdev, 0);
361+ if (IS_ERR(priv->mmio_base))
362+ return PTR_ERR(priv->mmio_base);
363+
364+ pm_runtime_enable(&pdev->dev);
365+ ret = pm_clk_create(&pdev->dev);
366+ if (ret)
367+ goto disable_pm_runtime;
368+
369+ ret = pm_clk_add(&pdev->dev, "audio");
370+ if (ret)
371+ goto destroy_pm_clk;
372+
373+ ret = register_clocks(priv, &pdev->dev);
374+ if (ret)
375+ goto destroy_pm_clk;
376+
377+ return 0;
378+
379+destroy_pm_clk:
380+ pm_clk_destroy(&pdev->dev);
381+disable_pm_runtime:
382+ pm_runtime_disable(&pdev->dev);
383+
384+ return ret;
385+}
386+
387+static int mmp2_audio_clk_remove(struct platform_device *pdev)
388+{
389+ pm_clk_destroy(&pdev->dev);
390+ pm_runtime_disable(&pdev->dev);
391+
392+ return 0;
393+}
394+
395+static int __maybe_unused mmp2_audio_clk_suspend(struct device *dev)
396+{
397+ struct mmp2_audio_clk *priv = dev_get_drvdata(dev);
398+
399+ priv->aud_ctrl = readl(priv->mmio_base + SSPA_AUD_CTRL);
400+ priv->aud_pll_ctrl0 = readl(priv->mmio_base + SSPA_AUD_PLL_CTRL0);
401+ priv->aud_pll_ctrl1 = readl(priv->mmio_base + SSPA_AUD_PLL_CTRL1);
402+ pm_clk_suspend(dev);
403+
404+ return 0;
405+}
406+
407+static int __maybe_unused mmp2_audio_clk_resume(struct device *dev)
408+{
409+ struct mmp2_audio_clk *priv = dev_get_drvdata(dev);
410+
411+ pm_clk_resume(dev);
412+ writel(priv->aud_ctrl, priv->mmio_base + SSPA_AUD_CTRL);
413+ writel(priv->aud_pll_ctrl0, priv->mmio_base + SSPA_AUD_PLL_CTRL0);
414+ writel(priv->aud_pll_ctrl1, priv->mmio_base + SSPA_AUD_PLL_CTRL1);
415+
416+ return 0;
417+}
418+
419+static const struct dev_pm_ops mmp2_audio_clk_pm_ops = {
420+ SET_RUNTIME_PM_OPS(mmp2_audio_clk_suspend, mmp2_audio_clk_resume, NULL)
421+};
422+
423+static const struct of_device_id mmp2_audio_clk_of_match[] = {
424+ { .compatible = "marvell,mmp2-audio-clock" },
425+ {}
426+};
427+
428+MODULE_DEVICE_TABLE(of, mmp2_audio_clk_of_match);
429+
430+static struct platform_driver mmp2_audio_clk_driver = {
431+ .driver = {
432+ .name = "mmp2-audio-clock",
433+ .of_match_table = of_match_ptr(mmp2_audio_clk_of_match),
434+ .pm = &mmp2_audio_clk_pm_ops,
435+ },
436+ .probe = mmp2_audio_clk_probe,
437+ .remove = mmp2_audio_clk_remove,
438+};
439+module_platform_driver(mmp2_audio_clk_driver);
440+
441+MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
442+MODULE_DESCRIPTION("Clock driver for MMP2 Audio subsystem");
443+MODULE_LICENSE("GPL");
drivers/clk/mmp/clk-frac.c+19−8
@@ -28,13 +28,15 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate, · 27 unmodified lines
2828 unsigned long *prate)
2929 {
3030 struct mmp_clk_factor *factor = to_clk_factor(hw);
31− unsigned long rate = 0, prev_rate;
31+ u64 rate = 0, prev_rate;
3232 int i;
3333
3434 for (i = 0; i < factor->ftbl_cnt; i++) {
3535 prev_rate = rate;
36− rate = (((*prate / 10000) * factor->ftbl[i].den) /
37− (factor->ftbl[i].num * factor->masks->factor)) * 10000;
36+ rate = *prate;
37+ rate *= factor->ftbl[i].den;
38+ do_div(rate, factor->ftbl[i].num * factor->masks->factor);
39+
3840 if (rate > drate)
3941 break;
4042 }
@@ -54,6 +56,7 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, · 13 unmodified lines
5456 struct mmp_clk_factor *factor = to_clk_factor(hw);
5557 struct mmp_clk_factor_masks *masks = factor->masks;
5658 unsigned int val, num, den;
59+ u64 rate;
5760
5861 val = readl_relaxed(factor->base);
5962
@@ -66,8 +69,11 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, · 6 unmodified lines
6669 if (!den)
6770 return 0;
6871
69− return (((parent_rate / 10000) * den) /
70− (num * factor->masks->factor)) * 10000;
72+ rate = parent_rate;
73+ rate *= den;
74+ do_div(rate, num * factor->masks->factor);
75+
76+ return rate;
7177 }
7278
7379 /* Configures new clock rate*/
@@ -78,12 +84,14 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, · 4 unmodified lines
7884 struct mmp_clk_factor_masks *masks = factor->masks;
7985 int i;
8086 unsigned long val;
81− unsigned long rate = 0;
8287 unsigned long flags = 0;
88+ u64 rate = 0;
8389
8490 for (i = 0; i < factor->ftbl_cnt; i++) {
85− rate = (((prate / 10000) * factor->ftbl[i].den) /
86− (factor->ftbl[i].num * factor->masks->factor)) * 10000;
91+ rate = prate;
92+ rate *= factor->ftbl[i].den;
93+ do_div(rate, factor->ftbl[i].num * factor->masks->factor);
94+
8795 if (rate > drate)
8896 break;
8997 }
@@ -140,7 +148,10 @@ static int clk_factor_init(struct clk_hw *hw) · 50 unmodified lines
140148 val &= ~(masks->den_mask << masks->den_shift);
141149 val |= (factor->ftbl[0].den & masks->den_mask) <<
142150 masks->den_shift;
151+ }
143152
153+ if (!(val & masks->enable_mask) || i >= factor->ftbl_cnt) {
154+ val |= masks->enable_mask;
144155 writel(val, factor->base);
145156 }
146157
drivers/clk/mmp/clk-of-mmp2.c+98−6
@@ -17,8 +17,10 @@ · 16 unmodified lines
1717 #include <linux/delay.h>
1818 #include <linux/err.h>
1919 #include <linux/of_address.h>
20+#include <linux/clk.h>
2021
2122 #include <dt-bindings/clock/marvell,mmp2.h>
23+#include <dt-bindings/power/marvell,mmp2.h>
2224
2325 #include "clk.h"
2426 #include "reset.h"
@@ -45,6 +47,10 @@ · 20 unmodified lines
4547 #define APBC_SSP1 0x54
4648 #define APBC_SSP2 0x58
4749 #define APBC_SSP3 0x5c
50+#define APBC_THERMAL0 0x90
51+#define APBC_THERMAL1 0x98
52+#define APBC_THERMAL2 0x9c
53+#define APBC_THERMAL3 0xa0
4854 #define APMU_SDH0 0x54
4955 #define APMU_SDH1 0x58
5056 #define APMU_SDH2 0xe8
@@ -55,18 +61,19 @@ · 4 unmodified lines
5561 #define APMU_DISP1 0x110
5662 #define APMU_CCIC0 0x50
5763 #define APMU_CCIC1 0xf4
58−#define APBC_THERMAL0 0x90
59−#define APBC_THERMAL1 0x98
60−#define APBC_THERMAL2 0x9c
61−#define APBC_THERMAL3 0xa0
6264 #define APMU_USBHSIC0 0xf8
6365 #define APMU_USBHSIC1 0xfc
6466 #define APMU_GPU 0xcc
67+#define APMU_AUDIO 0x10c
68+#define APMU_CAMERA 0x1fc
6569
6670 #define MPMU_FCCR 0x8
6771 #define MPMU_POSR 0x10
6872 #define MPMU_UART_PLL 0x14
6973 #define MPMU_PLL2_CR 0x34
74+#define MPMU_I2S0_PLL 0x40
75+#define MPMU_I2S1_PLL 0x44
76+#define MPMU_ACGR 0x1024
7077 /* MMP3 specific below */
7178 #define MPMU_PLL3_CR 0x50
7279 #define MPMU_PLL3_CTRL1 0x58
@@ -82,6 +89,8 @@ enum mmp2_clk_model { · 9 unmodified lines
8289 struct mmp2_clk_unit {
8390 struct mmp_clk_unit unit;
8491 enum mmp2_clk_model model;
92+ struct genpd_onecell_data pd_data;
93+ struct generic_pm_domain *pm_domains[MMP2_NR_POWER_DOMAINS];
8594 void __iomem *mpmu_base;
8695 void __iomem *apmu_base;
8796 void __iomem *apbc_base;
@@ -91,6 +100,7 @@ static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { · 3 unmodified lines
91100 {MMP2_CLK_CLK32, "clk32", NULL, 0, 32768},
92101 {MMP2_CLK_VCTCXO, "vctcxo", NULL, 0, 26000000},
93102 {MMP2_CLK_USB_PLL, "usb_pll", NULL, 0, 480000000},
103+ {0, "i2s_pll", NULL, 0, 99666667},
94104 };
95105
96106 static struct mmp_param_pll_clk pll_clks[] = {
@@ -139,7 +149,35 @@ static struct mmp_clk_factor_tbl uart_factor_tbl[] = { · 42 unmodified lines
139149 {.num = 3521, .den = 689}, /*19.23MHZ */
140150 };
141151
142−static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit)
152+static struct mmp_clk_factor_masks i2s_factor_masks = {
153+ .factor = 2,
154+ .num_mask = 0x7fff,
155+ .den_mask = 0x1fff,
156+ .num_shift = 0,
157+ .den_shift = 15,
158+ .enable_mask = 0xd0000000,
159+};
160+
161+static struct mmp_clk_factor_tbl i2s_factor_tbl[] = {
162+ {.num = 24868, .den = 511}, /* 2.0480 MHz */
163+ {.num = 28003, .den = 793}, /* 2.8224 MHz */
164+ {.num = 24941, .den = 1025}, /* 4.0960 MHz */
165+ {.num = 28003, .den = 1586}, /* 5.6448 MHz */
166+ {.num = 31158, .den = 2561}, /* 8.1920 MHz */
167+ {.num = 16288, .den = 1845}, /* 11.2896 MHz */
168+ {.num = 20772, .den = 2561}, /* 12.2880 MHz */
169+ {.num = 8144, .den = 1845}, /* 22.5792 MHz */
170+ {.num = 10386, .den = 2561}, /* 24.5760 MHz */
171+};
172+
173+static DEFINE_SPINLOCK(acgr_lock);
174+
175+static struct mmp_param_gate_clk mpmu_gate_clks[] = {
176+ {MMP2_CLK_I2S0, "i2s0_clk", "i2s0_pll", CLK_SET_RATE_PARENT, MPMU_ACGR, 0x200000, 0x200000, 0x0, 0, &acgr_lock},
177+ {MMP2_CLK_I2S1, "i2s1_clk", "i2s1_pll", CLK_SET_RATE_PARENT, MPMU_ACGR, 0x100000, 0x100000, 0x0, 0, &acgr_lock},
178+};
179+
180+static void mmp2_main_clk_init(struct mmp2_clk_unit *pxa_unit)
143181 {
144182 struct clk *clk;
145183 struct mmp_clk_unit *unit = &pxa_unit->unit;
@@ -166,6 +204,20 @@ static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit) · 20 unmodified lines
166204 &uart_factor_masks, uart_factor_tbl,
167205 ARRAY_SIZE(uart_factor_tbl), NULL);
168206 mmp_clk_add(unit, MMP2_CLK_UART_PLL, clk);
207+
208+ mmp_clk_register_factor("i2s0_pll", "pll1_4",
209+ CLK_SET_RATE_PARENT,
210+ pxa_unit->mpmu_base + MPMU_I2S0_PLL,
211+ &i2s_factor_masks, i2s_factor_tbl,
212+ ARRAY_SIZE(i2s_factor_tbl), NULL);
213+ mmp_clk_register_factor("i2s1_pll", "pll1_4",
214+ CLK_SET_RATE_PARENT,
215+ pxa_unit->mpmu_base + MPMU_I2S1_PLL,
216+ &i2s_factor_masks, i2s_factor_tbl,
217+ ARRAY_SIZE(i2s_factor_tbl), NULL);
218+
219+ mmp_register_gate_clks(unit, mpmu_gate_clks, pxa_unit->mpmu_base,
220+ ARRAY_SIZE(mpmu_gate_clks));
169221 }
170222
171223 static DEFINE_SPINLOCK(uart0_lock);
@@ -271,6 +323,8 @@ static u32 mmp2_gpu_bus_parent_table[] = { 0x0000, 0x0020, 0x0030, · 99 unmodified lines
271323 static const char * const mmp3_gpu_bus_parent_names[] = {"pll1_4", "pll1_6", "pll1_2", "pll2_2"};
272324 static const char * const mmp3_gpu_gc_parent_names[] = {"pll1", "pll2", "pll1_p", "pll2_p"};
273325
326+static DEFINE_SPINLOCK(audio_lock);
327+
274328 static struct mmp_clk_mix_config ccic0_mix_config = {
275329 .reg_info = DEFINE_MIX_REG_INFO(4, 17, 2, 6, 32),
276330 };
@@ -326,6 +380,7 @@ static struct mmp_param_gate_clk apmu_gate_clks[] = { · 49 unmodified lines
326380 {MMP2_CLK_CCIC1_PHY, "ccic1_phy_clk", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x24, 0x24, 0x0, 0, &ccic1_lock},
327381 {MMP2_CLK_CCIC1_SPHY, "ccic1_sphy_clk", "ccic1_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x300, 0x300, 0x0, 0, &ccic1_lock},
328382 {MMP2_CLK_GPU_BUS, "gpu_bus_clk", "gpu_bus_mux", CLK_SET_RATE_PARENT, APMU_GPU, 0xa, 0xa, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock},
383+ {MMP2_CLK_AUDIO, "audio_clk", "audio_mix_clk", CLK_SET_RATE_PARENT, APMU_AUDIO, 0x12, 0x12, 0x0, 0, &audio_lock},
329384 };
330385
331386 static struct mmp_param_gate_clk mmp2_apmu_gate_clks[] = {
@@ -423,6 +478,41 @@ static void mmp2_clk_reset_init(struct device_node *np, · 91 unmodified lines
423478 mmp_clk_reset_register(np, cells, nr_resets);
424479 }
425480
481+static void mmp2_pm_domain_init(struct device_node *np,
482+ struct mmp2_clk_unit *pxa_unit)
483+{
484+ if (pxa_unit->model == CLK_MODEL_MMP3) {
485+ pxa_unit->pm_domains[MMP2_POWER_DOMAIN_GPU]
486+ = mmp_pm_domain_register("gpu",
487+ pxa_unit->apmu_base + APMU_GPU,
488+ 0x0600, 0x40003, 0x18000c, 0, &gpu_lock);
489+ } else {
490+ pxa_unit->pm_domains[MMP2_POWER_DOMAIN_GPU]
491+ = mmp_pm_domain_register("gpu",
492+ pxa_unit->apmu_base + APMU_GPU,
493+ 0x8600, 0x00003, 0x00000c,
494+ MMP_PM_DOMAIN_NO_DISABLE, &gpu_lock);
495+ }
496+ pxa_unit->pd_data.num_domains++;
497+
498+ pxa_unit->pm_domains[MMP2_POWER_DOMAIN_AUDIO]
499+ = mmp_pm_domain_register("audio",
500+ pxa_unit->apmu_base + APMU_AUDIO,
501+ 0x600, 0x2, 0, 0, &audio_lock);
502+ pxa_unit->pd_data.num_domains++;
503+
504+ if (pxa_unit->model == CLK_MODEL_MMP3) {
505+ pxa_unit->pm_domains[MMP3_POWER_DOMAIN_CAMERA]
506+ = mmp_pm_domain_register("camera",
507+ pxa_unit->apmu_base + APMU_CAMERA,
508+ 0x600, 0, 0, 0, NULL);
509+ pxa_unit->pd_data.num_domains++;
510+ }
511+
512+ pxa_unit->pd_data.domains = pxa_unit->pm_domains;
513+ of_genpd_add_provider_onecell(np, &pxa_unit->pd_data);
514+}
515+
426516 static void __init mmp2_clk_init(struct device_node *np)
427517 {
428518 struct mmp2_clk_unit *pxa_unit;
@@ -454,9 +544,11 @@ static void __init mmp2_clk_init(struct device_node *np) · 25 unmodified lines
454544 goto unmap_apmu_region;
455545 }
456546
547+ mmp2_pm_domain_init(np, pxa_unit);
548+
457549 mmp_clk_init(np, &pxa_unit->unit, MMP2_NR_CLKS);
458550
459− mmp2_pll_init(pxa_unit);
551+ mmp2_main_clk_init(pxa_unit);
460552
461553 mmp2_apb_periph_clk_init(pxa_unit);
462554
drivers/clk/mmp/clk.h+11−0
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 #define __MACH_MMP_CLK_H
44
55 #include <linux/clk-provider.h>
6+#include <linux/pm_domain.h>
67 #include <linux/clkdev.h>
78
89 #define APBC_NO_BUS_CTRL BIT(0)
@@ -16,6 +17,7 @@ struct mmp_clk_factor_masks { · 7 unmodified lines
1617 unsigned int den_mask;
1718 unsigned int num_shift;
1819 unsigned int den_shift;
20+ unsigned int enable_mask;
1921 };
2022
2123 struct mmp_clk_factor_tbl {
@@ -251,4 +253,13 @@ void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit, · 229 unmodified lines
251253 int nr_clks);
252254 void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
253255 struct clk *clk);
256+
257+/* Power islands */
258+#define MMP_PM_DOMAIN_NO_DISABLE BIT(0)
259+
260+struct generic_pm_domain *mmp_pm_domain_register(const char *name,
261+ void __iomem *reg,
262+ u32 power_on, u32 reset, u32 clock_enable,
263+ unsigned int flags, spinlock_t *lock);
264+
254265 #endif
drivers/clk/mmp/pwr-island.c+115−0
@@ -0,0 +1,115 @@
1+// SPDX-License-Identifier: GPL-2.0-or-later
2+/*
3+ * MMP PMU power island support
4+ *
5+ * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
6+ */
7+
8+#include <linux/pm_domain.h>
9+#include <linux/slab.h>
10+#include <linux/io.h>
11+
12+#include "clk.h"
13+
14+#define to_mmp_pm_domain(genpd) container_of(genpd, struct mmp_pm_domain, genpd)
15+
16+struct mmp_pm_domain {
17+ struct generic_pm_domain genpd;
18+ void __iomem *reg;
19+ spinlock_t *lock;
20+ u32 power_on;
21+ u32 reset;
22+ u32 clock_enable;
23+ unsigned int flags;
24+};
25+
26+static int mmp_pm_domain_power_on(struct generic_pm_domain *genpd)
27+{
28+ struct mmp_pm_domain *pm_domain = to_mmp_pm_domain(genpd);
29+ unsigned long flags = 0;
30+ u32 val;
31+
32+ if (pm_domain->lock)
33+ spin_lock_irqsave(pm_domain->lock, flags);
34+
35+ val = readl(pm_domain->reg);
36+
37+ /* Turn on the power island */
38+ val |= pm_domain->power_on;
39+ writel(val, pm_domain->reg);
40+
41+ /* Disable isolation */
42+ val |= 0x100;
43+ writel(val, pm_domain->reg);
44+
45+ /* Some blocks need to be reset after a power up */
46+ if (pm_domain->reset || pm_domain->clock_enable) {
47+ u32 after_power_on = val;
48+
49+ val &= ~pm_domain->reset;
50+ writel(val, pm_domain->reg);
51+
52+ val |= pm_domain->clock_enable;
53+ writel(val, pm_domain->reg);
54+
55+ val |= pm_domain->reset;
56+ writel(val, pm_domain->reg);
57+
58+ writel(after_power_on, pm_domain->reg);
59+ }
60+
61+ if (pm_domain->lock)
62+ spin_unlock_irqrestore(pm_domain->lock, flags);
63+
64+ return 0;
65+}
66+
67+static int mmp_pm_domain_power_off(struct generic_pm_domain *genpd)
68+{
69+ struct mmp_pm_domain *pm_domain = to_mmp_pm_domain(genpd);
70+ unsigned long flags = 0;
71+ u32 val;
72+
73+ if (pm_domain->flags & MMP_PM_DOMAIN_NO_DISABLE)
74+ return 0;
75+
76+ if (pm_domain->lock)
77+ spin_lock_irqsave(pm_domain->lock, flags);
78+
79+ /* Turn off and isolate the the power island. */
80+ val = readl(pm_domain->reg);
81+ val &= ~pm_domain->power_on;
82+ val &= ~0x100;
83+ writel(val, pm_domain->reg);
84+
85+ if (pm_domain->lock)
86+ spin_unlock_irqrestore(pm_domain->lock, flags);
87+
88+ return 0;
89+}
90+
91+struct generic_pm_domain *mmp_pm_domain_register(const char *name,
92+ void __iomem *reg,
93+ u32 power_on, u32 reset, u32 clock_enable,
94+ unsigned int flags, spinlock_t *lock)
95+{
96+ struct mmp_pm_domain *pm_domain;
97+
98+ pm_domain = kzalloc(sizeof(*pm_domain), GFP_KERNEL);
99+ if (!pm_domain)
100+ return ERR_PTR(-ENOMEM);
101+
102+ pm_domain->reg = reg;
103+ pm_domain->power_on = power_on;
104+ pm_domain->reset = reset;
105+ pm_domain->clock_enable = clock_enable;
106+ pm_domain->flags = flags;
107+ pm_domain->lock = lock;
108+
109+ pm_genpd_init(&pm_domain->genpd, NULL, true);
110+ pm_domain->genpd.name = name;
111+ pm_domain->genpd.power_on = mmp_pm_domain_power_on;
112+ pm_domain->genpd.power_off = mmp_pm_domain_power_off;
113+
114+ return &pm_domain->genpd;
115+}
drivers/clk/qcom/Kconfig+8−0
@@ -142,6 +142,14 @@ config MSM_GCC_8916 · 141 unmodified lines
142142 Say Y if you want to use devices such as UART, SPI i2c, USB,
143143 SD/eMMC, display, graphics, camera etc.
144144
145+config MSM_GCC_8939
146+ tristate "MSM8939 Global Clock Controller"
147+ select QCOM_GDSC
148+ help
149+ Support for the global clock controller on msm8939 devices.
150+ Say Y if you want to use devices such as UART, SPI i2c, USB,
151+ SD/eMMC, display, graphics, camera etc.
152+
145153 config MSM_GCC_8960
146154 tristate "APQ8064/MSM8960 Global Clock Controller"
147155 help
drivers/clk/qcom/Makefile+1−0
@@ -28,6 +28,7 @@ obj-$(CONFIG_MDM_GCC_9615) += gcc-mdm9615.o · 27 unmodified lines
2828 obj-$(CONFIG_MDM_LCC_9615) += lcc-mdm9615.o
2929 obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
3030 obj-$(CONFIG_MSM_GCC_8916) += gcc-msm8916.o
31+obj-$(CONFIG_MSM_GCC_8939) += gcc-msm8939.o
3132 obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
3233 obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
3334 obj-$(CONFIG_MSM_GCC_8994) += gcc-msm8994.o
drivers/clk/qcom/gcc-msm8916.c+4−4
@@ -260,7 +260,7 @@ static struct clk_pll gpll0 = { · 259 unmodified lines
260260 .l_reg = 0x21004,
261261 .m_reg = 0x21008,
262262 .n_reg = 0x2100c,
263− .config_reg = 0x21014,
263+ .config_reg = 0x21010,
264264 .mode_reg = 0x21000,
265265 .status_reg = 0x2101c,
266266 .status_bit = 17,
@@ -287,7 +287,7 @@ static struct clk_pll gpll1 = { · 20 unmodified lines
287287 .l_reg = 0x20004,
288288 .m_reg = 0x20008,
289289 .n_reg = 0x2000c,
290− .config_reg = 0x20014,
290+ .config_reg = 0x20010,
291291 .mode_reg = 0x20000,
292292 .status_reg = 0x2001c,
293293 .status_bit = 17,
@@ -314,7 +314,7 @@ static struct clk_pll gpll2 = { · 20 unmodified lines
314314 .l_reg = 0x4a004,
315315 .m_reg = 0x4a008,
316316 .n_reg = 0x4a00c,
317− .config_reg = 0x4a014,
317+ .config_reg = 0x4a010,
318318 .mode_reg = 0x4a000,
319319 .status_reg = 0x4a01c,
320320 .status_bit = 17,
@@ -341,7 +341,7 @@ static struct clk_pll bimc_pll = { · 20 unmodified lines
341341 .l_reg = 0x23004,
342342 .m_reg = 0x23008,
343343 .n_reg = 0x2300c,
344− .config_reg = 0x23014,
344+ .config_reg = 0x23010,
345345 .mode_reg = 0x23000,
346346 .status_reg = 0x2301c,
347347 .status_bit = 17,
drivers/clk/qcom/gcc-msm8939.c+3988−0
@@ -0,0 +1,3988 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+/*
3+ * Copyright 2020 Linaro Limited
4+ */
5+
6+#include <linux/kernel.h>
7+#include <linux/bitops.h>
8+#include <linux/err.h>
9+#include <linux/platform_device.h>
10+#include <linux/module.h>
11+#include <linux/of.h>
12+#include <linux/of_device.h>
13+#include <linux/clk-provider.h>
14+#include <linux/regmap.h>
15+#include <linux/reset-controller.h>
16+
17+#include <dt-bindings/clock/qcom,gcc-msm8939.h>
18+#include <dt-bindings/reset/qcom,gcc-msm8939.h>
19+
20+#include "common.h"
21+#include "clk-regmap.h"
22+#include "clk-pll.h"
23+#include "clk-rcg.h"
24+#include "clk-branch.h"
25+#include "reset.h"
26+#include "gdsc.h"
27+
28+enum {
29+ P_XO,
30+ P_GPLL0,
31+ P_GPLL0_AUX,
32+ P_BIMC,
33+ P_GPLL1,
34+ P_GPLL1_AUX,
35+ P_GPLL2,
36+ P_GPLL2_AUX,
37+ P_GPLL3,
38+ P_GPLL3_AUX,
39+ P_GPLL4,
40+ P_GPLL5,
41+ P_GPLL5_AUX,
42+ P_GPLL5_EARLY,
43+ P_GPLL6,
44+ P_GPLL6_AUX,
45+ P_SLEEP_CLK,
46+ P_DSI0_PHYPLL_BYTE,
47+ P_DSI0_PHYPLL_DSI,
48+ P_EXT_PRI_I2S,
49+ P_EXT_SEC_I2S,
50+ P_EXT_MCLK,
51+};
52+
53+static struct clk_pll gpll0 = {
54+ .l_reg = 0x21004,
55+ .m_reg = 0x21008,
56+ .n_reg = 0x2100c,
57+ .config_reg = 0x21010,
58+ .mode_reg = 0x21000,
59+ .status_reg = 0x2101c,
60+ .status_bit = 17,
61+ .clkr.hw.init = &(struct clk_init_data){
62+ .name = "gpll0",
63+ .parent_data = &(const struct clk_parent_data) {
64+ .fw_name = "xo",
65+ },
66+ .num_parents = 1,
67+ .ops = &clk_pll_ops,
68+ },
69+};
70+
71+static struct clk_regmap gpll0_vote = {
72+ .enable_reg = 0x45000,
73+ .enable_mask = BIT(0),
74+ .hw.init = &(struct clk_init_data){
75+ .name = "gpll0_vote",
76+ .parent_data = &(const struct clk_parent_data) {
77+ .hw = &gpll0.clkr.hw,
78+ },
79+ .num_parents = 1,
80+ .ops = &clk_pll_vote_ops,
81+ },
82+};
83+
84+static struct clk_pll gpll1 = {
85+ .l_reg = 0x20004,
86+ .m_reg = 0x20008,
87+ .n_reg = 0x2000c,
88+ .config_reg = 0x20010,
89+ .mode_reg = 0x20000,
90+ .status_reg = 0x2001c,
91+ .status_bit = 17,
92+ .clkr.hw.init = &(struct clk_init_data){
93+ .name = "gpll1",
94+ .parent_data = &(const struct clk_parent_data) {
95+ .fw_name = "xo",
96+ },
97+ .num_parents = 1,
98+ .ops = &clk_pll_ops,
99+ },
100+};
101+
102+static struct clk_regmap gpll1_vote = {
103+ .enable_reg = 0x45000,
104+ .enable_mask = BIT(1),
105+ .hw.init = &(struct clk_init_data){
106+ .name = "gpll1_vote",
107+ .parent_data = &(const struct clk_parent_data) {
108+ .hw = &gpll1.clkr.hw,
109+ },
110+ .num_parents = 1,
111+ .ops = &clk_pll_vote_ops,
112+ },
113+};
114+
115+static struct clk_pll gpll2 = {
116+ .l_reg = 0x4a004,
117+ .m_reg = 0x4a008,
118+ .n_reg = 0x4a00c,
119+ .config_reg = 0x4a010,
120+ .mode_reg = 0x4a000,
121+ .status_reg = 0x4a01c,
122+ .status_bit = 17,
123+ .clkr.hw.init = &(struct clk_init_data){
124+ .name = "gpll2",
125+ .parent_data = &(const struct clk_parent_data) {
126+ .fw_name = "xo",
127+ },
128+ .num_parents = 1,
129+ .ops = &clk_pll_ops,
130+ },
131+};
132+
133+static struct clk_regmap gpll2_vote = {
134+ .enable_reg = 0x45000,
135+ .enable_mask = BIT(2),
136+ .hw.init = &(struct clk_init_data){
137+ .name = "gpll2_vote",
138+ .parent_data = &(const struct clk_parent_data) {
139+ .hw = &gpll2.clkr.hw,
140+ },
141+ .num_parents = 1,
142+ .ops = &clk_pll_vote_ops,
143+ },
144+};
145+
146+static struct clk_pll bimc_pll = {
147+ .l_reg = 0x23004,
148+ .m_reg = 0x23008,
149+ .n_reg = 0x2300c,
150+ .config_reg = 0x23010,
151+ .mode_reg = 0x23000,
152+ .status_reg = 0x2301c,
153+ .status_bit = 17,
154+ .clkr.hw.init = &(struct clk_init_data){
155+ .name = "bimc_pll",
156+ .parent_data = &(const struct clk_parent_data) {
157+ .fw_name = "xo",
158+ },
159+ .num_parents = 1,
160+ .ops = &clk_pll_ops,
161+ },
162+};
163+
164+static struct clk_regmap bimc_pll_vote = {
165+ .enable_reg = 0x45000,
166+ .enable_mask = BIT(3),
167+ .hw.init = &(struct clk_init_data){
168+ .name = "bimc_pll_vote",
169+ .parent_data = &(const struct clk_parent_data) {
170+ .hw = &bimc_pll.clkr.hw,
171+ },
172+ .num_parents = 1,
173+ .ops = &clk_pll_vote_ops,
174+ },
175+};
176+
177+static struct clk_pll gpll3 = {
178+ .l_reg = 0x22004,
179+ .m_reg = 0x22008,
180+ .n_reg = 0x2200c,
181+ .config_reg = 0x22010,
182+ .mode_reg = 0x22000,
183+ .status_reg = 0x2201c,
184+ .status_bit = 17,
185+ .clkr.hw.init = &(struct clk_init_data){
186+ .name = "gpll3",
187+ .parent_data = &(const struct clk_parent_data) {
188+ .fw_name = "xo",
189+ },
190+ .num_parents = 1,
191+ .ops = &clk_pll_ops,
192+ },
193+};
194+
195+static struct clk_regmap gpll3_vote = {
196+ .enable_reg = 0x45000,
197+ .enable_mask = BIT(4),
198+ .hw.init = &(struct clk_init_data){
199+ .name = "gpll3_vote",
200+ .parent_data = &(const struct clk_parent_data) {
201+ .hw = &gpll3.clkr.hw,
202+ },
203+ .num_parents = 1,
204+ .ops = &clk_pll_vote_ops,
205+ },
206+};
207+
208+/* GPLL3 at 1100 MHz, main output enabled. */
209+static const struct pll_config gpll3_config = {
210+ .l = 57,
211+ .m = 7,
212+ .n = 24,
213+ .vco_val = 0x0,
214+ .vco_mask = BIT(20),
215+ .pre_div_val = 0x0,
216+ .pre_div_mask = BIT(12),
217+ .post_div_val = 0x0,
218+ .post_div_mask = BIT(9) | BIT(8),
219+ .mn_ena_mask = BIT(24),
220+ .main_output_mask = BIT(0),
221+ .aux_output_mask = BIT(1),
222+};
223+
224+static struct clk_pll gpll4 = {
225+ .l_reg = 0x24004,
226+ .m_reg = 0x24008,
227+ .n_reg = 0x2400c,
228+ .config_reg = 0x24010,
229+ .mode_reg = 0x24000,
230+ .status_reg = 0x2401c,
231+ .status_bit = 17,
232+ .clkr.hw.init = &(struct clk_init_data){
233+ .name = "gpll4",
234+ .parent_data = &(const struct clk_parent_data) {
235+ .fw_name = "xo",
236+ },
237+ .num_parents = 1,
238+ .ops = &clk_pll_ops,
239+ },
240+};
241+
242+static struct clk_regmap gpll4_vote = {
243+ .enable_reg = 0x45000,
244+ .enable_mask = BIT(5),
245+ .hw.init = &(struct clk_init_data){
246+ .name = "gpll4_vote",
247+ .parent_data = &(const struct clk_parent_data) {
248+ .hw = &gpll4.clkr.hw,
249+ },
250+ .num_parents = 1,
251+ .ops = &clk_pll_vote_ops,
252+ },
253+};
254+
255+/* GPLL4 at 1200 MHz, main output enabled. */
256+static struct pll_config gpll4_config = {
257+ .l = 62,
258+ .m = 1,
259+ .n = 2,
260+ .vco_val = 0x0,
261+ .vco_mask = BIT(20),
262+ .pre_div_val = 0x0,
263+ .pre_div_mask = BIT(12),
264+ .post_div_val = 0x0,
265+ .post_div_mask = BIT(9) | BIT(8),
266+ .mn_ena_mask = BIT(24),
267+ .main_output_mask = BIT(0),
268+};
269+
270+static struct clk_pll gpll5 = {
271+ .l_reg = 0x25004,
272+ .m_reg = 0x25008,
273+ .n_reg = 0x2500c,
274+ .config_reg = 0x25010,
275+ .mode_reg = 0x25000,
276+ .status_reg = 0x2501c,
277+ .status_bit = 17,
278+ .clkr.hw.init = &(struct clk_init_data){
279+ .name = "gpll5",
280+ .parent_data = &(const struct clk_parent_data) {
281+ .fw_name = "xo",
282+ },
283+ .num_parents = 1,
284+ .ops = &clk_pll_ops,
285+ },
286+};
287+
288+static struct clk_regmap gpll5_vote = {
289+ .enable_reg = 0x45000,
290+ .enable_mask = BIT(6),
291+ .hw.init = &(struct clk_init_data){
292+ .name = "gpll5_vote",
293+ .parent_data = &(const struct clk_parent_data) {
294+ .hw = &gpll5.clkr.hw,
295+ },
296+ .num_parents = 1,
297+ .ops = &clk_pll_vote_ops,
298+ },
299+};
300+
301+static struct clk_pll gpll6 = {
302+ .l_reg = 0x37004,
303+ .m_reg = 0x37008,
304+ .n_reg = 0x3700c,
305+ .config_reg = 0x37010,
306+ .mode_reg = 0x37000,
307+ .status_reg = 0x3701c,
308+ .status_bit = 17,
309+ .clkr.hw.init = &(struct clk_init_data){
310+ .name = "gpll6",
311+ .parent_data = &(const struct clk_parent_data) {
312+ .fw_name = "xo",
313+ },
314+ .num_parents = 1,
315+ .ops = &clk_pll_ops,
316+ },
317+};
318+
319+static struct clk_regmap gpll6_vote = {
320+ .enable_reg = 0x45000,
321+ .enable_mask = BIT(7),
322+ .hw.init = &(struct clk_init_data){
323+ .name = "gpll6_vote",
324+ .parent_data = &(const struct clk_parent_data) {
325+ .hw = &gpll6.clkr.hw,
326+ },
327+ .num_parents = 1,
328+ .ops = &clk_pll_vote_ops,
329+ },
330+};
331+
332+static const struct parent_map gcc_xo_gpll0_map[] = {
333+ { P_XO, 0 },
334+ { P_GPLL0, 1 },
335+};
336+
337+static const struct clk_parent_data gcc_xo_gpll0_parent_data[] = {
338+ { .fw_name = "xo" },
339+ { .hw = &gpll0_vote.hw },
340+};
341+
342+static const struct parent_map gcc_xo_gpll0_bimc_map[] = {
343+ { P_XO, 0 },
344+ { P_GPLL0, 1 },
345+ { P_BIMC, 2 },
346+};
347+
348+static const struct clk_parent_data gcc_xo_gpll0_bimc_parent_data[] = {
349+ { .fw_name = "xo" },
350+ { .hw = &gpll0_vote.hw },
351+ { .hw = &bimc_pll_vote.hw },
352+};
353+
354+static const struct parent_map gcc_xo_gpll0_gpll6a_map[] = {
355+ { P_XO, 0 },
356+ { P_GPLL0, 1 },
357+ { P_GPLL6_AUX, 2 },
358+};
359+
360+static const struct clk_parent_data gcc_xo_gpll0_gpll6a_parent_data[] = {
361+ { .fw_name = "xo" },
362+ { .hw = &gpll0_vote.hw },
363+ { .hw = &gpll6_vote.hw },
364+};
365+
366+static const struct parent_map gcc_xo_gpll0_gpll2a_gpll3_gpll6a_map[] = {
367+ { P_XO, 0 },
368+ { P_GPLL0, 1 },
369+ { P_GPLL2_AUX, 4 },
370+ { P_GPLL3, 2 },
371+ { P_GPLL6_AUX, 3 },
372+};
373+
374+static const struct clk_parent_data gcc_xo_gpll0_gpll2a_gpll3_gpll6a_parent_data[] = {
375+ { .fw_name = "xo" },
376+ { .hw = &gpll0_vote.hw },
377+ { .hw = &gpll2_vote.hw },
378+ { .hw = &gpll3_vote.hw },
379+ { .hw = &gpll6_vote.hw },
380+};
381+
382+static const struct parent_map gcc_xo_gpll0_gpll2_map[] = {
383+ { P_XO, 0 },
384+ { P_GPLL0, 1 },
385+ { P_GPLL2, 2 },
386+};
387+
388+static const struct clk_parent_data gcc_xo_gpll0_gpll2_parent_data[] = {
389+ { .fw_name = "xo" },
390+ { .hw = &gpll0_vote.hw },
391+ { .hw = &gpll2_vote.hw },
392+};
393+
394+static const struct parent_map gcc_xo_gpll0_gpll2_gpll4_map[] = {
395+ { P_XO, 0 },
396+ { P_GPLL0, 1 },
397+ { P_GPLL2, 3 },
398+ { P_GPLL4, 2 },
399+};
400+
401+static const struct clk_parent_data gcc_xo_gpll0_gpll2_gpll4_parent_data[] = {
402+ { .fw_name = "xo" },
403+ { .hw = &gpll0_vote.hw },
404+ { .hw = &gpll2_vote.hw },
405+ { .hw = &gpll4_vote.hw },
406+};
407+
408+static const struct parent_map gcc_xo_gpll0a_map[] = {
409+ { P_XO, 0 },
410+ { P_GPLL0_AUX, 2 },
411+};
412+
413+static const struct clk_parent_data gcc_xo_gpll0a_parent_data[] = {
414+ { .fw_name = "xo" },
415+ { .hw = &gpll0_vote.hw },
416+};
417+
418+static const struct parent_map gcc_xo_gpll0_gpll1a_sleep_map[] = {
419+ { P_XO, 0 },
420+ { P_GPLL0, 1 },
421+ { P_GPLL1_AUX, 2 },
422+ { P_SLEEP_CLK, 6 },
423+};
424+
425+static const struct clk_parent_data gcc_xo_gpll0_gpll1a_sleep_parent_data[] = {
426+ { .fw_name = "xo" },
427+ { .hw = &gpll0_vote.hw },
428+ { .hw = &gpll1_vote.hw },
429+ { .fw_name = "sleep_clk", .name = "sleep_clk" },
430+};
431+
432+static const struct parent_map gcc_xo_gpll0_gpll1a_gpll6_sleep_map[] = {
433+ { P_XO, 0 },
434+ { P_GPLL0, 1 },
435+ { P_GPLL1_AUX, 2 },
436+ { P_GPLL6, 2 },
437+ { P_SLEEP_CLK, 6 },
438+};
439+
440+static const struct clk_parent_data gcc_xo_gpll0_gpll1a_gpll6_sleep_parent_data[] = {
441+ { .fw_name = "xo" },
442+ { .hw = &gpll0_vote.hw },
443+ { .hw = &gpll1_vote.hw },
444+ { .hw = &gpll6_vote.hw },
445+ { .fw_name = "sleep_clk", .name = "sleep_clk" },
446+};
447+
448+static const struct parent_map gcc_xo_gpll0_gpll1a_map[] = {
449+ { P_XO, 0 },
450+ { P_GPLL0, 1 },
451+ { P_GPLL1_AUX, 2 },
452+};
453+
454+static const struct clk_parent_data gcc_xo_gpll0_gpll1a_parent_data[] = {
455+ { .fw_name = "xo" },
456+ { .hw = &gpll0_vote.hw },
457+ { .hw = &gpll1_vote.hw },
458+};
459+
460+static const struct parent_map gcc_xo_dsibyte_map[] = {
461+ { P_XO, 0, },
462+ { P_DSI0_PHYPLL_BYTE, 2 },
463+};
464+
465+static const struct clk_parent_data gcc_xo_dsibyte_parent_data[] = {
466+ { .fw_name = "xo" },
467+ { .fw_name = "dsi0pllbyte", .name = "dsi0pllbyte" },
468+};
469+
470+static const struct parent_map gcc_xo_gpll0a_dsibyte_map[] = {
471+ { P_XO, 0 },
472+ { P_GPLL0_AUX, 2 },
473+ { P_DSI0_PHYPLL_BYTE, 1 },
474+};
475+
476+static const struct clk_parent_data gcc_xo_gpll0a_dsibyte_parent_data[] = {
477+ { .fw_name = "xo" },
478+ { .hw = &gpll0_vote.hw },
479+ { .fw_name = "dsi0pllbyte", .name = "dsi0pllbyte" },
480+};
481+
482+static const struct parent_map gcc_xo_gpll1_dsiphy_gpll6_gpll3a_gpll0a_map[] = {
483+ { P_XO, 0 },
484+ { P_GPLL1, 1 },
485+ { P_DSI0_PHYPLL_DSI, 2 },
486+ { P_GPLL6, 3 },
487+ { P_GPLL3_AUX, 4 },
488+ { P_GPLL0_AUX, 5 },
489+};
490+
491+static const struct clk_parent_data gcc_xo_gpll1_dsiphy_gpll6_gpll3a_gpll0a_parent_data[] = {
492+ { .fw_name = "xo" },
493+ { .hw = &gpll1_vote.hw },
494+ { .fw_name = "dsi0pll", .name = "dsi0pll" },
495+ { .hw = &gpll6_vote.hw },
496+ { .hw = &gpll3_vote.hw },
497+ { .hw = &gpll0_vote.hw },
498+};
499+
500+static const struct parent_map gcc_xo_gpll0a_dsiphy_map[] = {
501+ { P_XO, 0 },
502+ { P_GPLL0_AUX, 2 },
503+ { P_DSI0_PHYPLL_DSI, 1 },
504+};
505+
506+static const struct clk_parent_data gcc_xo_gpll0a_dsiphy_parent_data[] = {
507+ { .fw_name = "xo" },
508+ { .hw = &gpll0_vote.hw },
509+ { .fw_name = "dsi0pll", .name = "dsi0pll" },
510+};
511+
512+static const struct parent_map gcc_xo_gpll0_gpll5a_gpll6_bimc_map[] = {
513+ { P_XO, 0 },
514+ { P_GPLL0, 1 },
515+ { P_GPLL5_AUX, 3 },
516+ { P_GPLL6, 2 },
517+ { P_BIMC, 4 },
518+};
519+
520+static const struct clk_parent_data gcc_xo_gpll0_gpll5a_gpll6_bimc_parent_data[] = {
521+ { .fw_name = "xo" },
522+ { .hw = &gpll0_vote.hw },
523+ { .hw = &gpll5_vote.hw },
524+ { .hw = &gpll6_vote.hw },
525+ { .hw = &bimc_pll_vote.hw },
526+};
527+
528+static const struct parent_map gcc_xo_gpll0_gpll1_sleep_map[] = {
529+ { P_XO, 0 },
530+ { P_GPLL0, 1 },
531+ { P_GPLL1, 2 },
532+ { P_SLEEP_CLK, 6 }
533+};
534+
535+static const struct clk_parent_data gcc_xo_gpll0_gpll1_sleep_parent_data[] = {
536+ { .fw_name = "xo" },
537+ { .hw = &gpll0_vote.hw },
538+ { .hw = &gpll1_vote.hw },
539+ { .fw_name = "sleep_clk", .name = "sleep_clk" },
540+};
541+
542+static const struct parent_map gcc_xo_gpll1_epi2s_emclk_sleep_map[] = {
543+ { P_XO, 0 },
544+ { P_GPLL1, 1 },
545+ { P_EXT_PRI_I2S, 2 },
546+ { P_EXT_MCLK, 3 },
547+ { P_SLEEP_CLK, 6 }
548+};
549+
550+static const struct clk_parent_data gcc_xo_gpll1_epi2s_emclk_sleep_parent_data[] = {
551+ { .fw_name = "xo" },
552+ { .hw = &gpll0_vote.hw },
553+ { .fw_name = "ext_pri_i2s", .name = "ext_pri_i2s" },
554+ { .fw_name = "ext_mclk", .name = "ext_mclk" },
555+ { .fw_name = "sleep_clk", .name = "sleep_clk" },
556+};
557+
558+static const struct parent_map gcc_xo_gpll1_esi2s_emclk_sleep_map[] = {
559+ { P_XO, 0 },
560+ { P_GPLL1, 1 },
561+ { P_EXT_SEC_I2S, 2 },
562+ { P_EXT_MCLK, 3 },
563+ { P_SLEEP_CLK, 6 }
564+};
565+
566+static const struct clk_parent_data gcc_xo_gpll1_esi2s_emclk_sleep_parent_data[] = {
567+ { .fw_name = "xo" },
568+ { .hw = &gpll1_vote.hw },
569+ { .fw_name = "ext_sec_i2s", .name = "ext_sec_i2s" },
570+ { .fw_name = "ext_mclk", .name = "ext_mclk" },
571+ { .fw_name = "sleep_clk", .name = "sleep_clk" },
572+};
573+
574+static const struct parent_map gcc_xo_sleep_map[] = {
575+ { P_XO, 0 },
576+ { P_SLEEP_CLK, 6 }
577+};
578+
579+static const struct clk_parent_data gcc_xo_sleep_parent_data[] = {
580+ { .fw_name = "xo" },
581+ { .fw_name = "sleep_clk", .name = "sleep_clk" },
582+};
583+
584+static const struct parent_map gcc_xo_gpll1_emclk_sleep_map[] = {
585+ { P_XO, 0 },
586+ { P_GPLL1, 1 },
587+ { P_EXT_MCLK, 2 },
588+ { P_SLEEP_CLK, 6 }
589+};
590+
591+static const struct clk_parent_data gcc_xo_gpll1_emclk_sleep_parent_data[] = {
592+ { .fw_name = "xo" },
593+ { .hw = &gpll1_vote.hw },
594+ { .fw_name = "ext_mclk", .name = "ext_mclk" },
595+ { .fw_name = "sleep_clk", .name = "sleep_clk" },
596+};
597+
598+static const struct parent_map gcc_xo_gpll6_gpll0_map[] = {
599+ { P_XO, 0 },
600+ { P_GPLL6, 1 },
601+ { P_GPLL0, 2 },
602+};
603+
604+static const struct clk_parent_data gcc_xo_gpll6_gpll0_parent_data[] = {
605+ { .fw_name = "xo" },
606+ { .hw = &gpll6_vote.hw },
607+ { .hw = &gpll0_vote.hw },
608+};
609+
610+static const struct parent_map gcc_xo_gpll6_gpll0a_map[] = {
611+ { P_XO, 0 },
612+ { P_GPLL6, 1 },
613+ { P_GPLL0_AUX, 2 },
614+};
615+
616+static const struct clk_parent_data gcc_xo_gpll6_gpll0a_parent_data[] = {
617+ { .fw_name = "xo" },
618+ { .hw = &gpll6_vote.hw },
619+ { .hw = &gpll0_vote.hw },
620+};
621+
622+static struct clk_rcg2 pcnoc_bfdcd_clk_src = {
623+ .cmd_rcgr = 0x27000,
624+ .hid_width = 5,
625+ .parent_map = gcc_xo_gpll0_map,
626+ .clkr.hw.init = &(struct clk_init_data){
627+ .name = "pcnoc_bfdcd_clk_src",
628+ .parent_data = gcc_xo_gpll0_parent_data,
629+ .num_parents = 2,
630+ .ops = &clk_rcg2_ops,
631+ },
632+};
633+
634+static struct clk_rcg2 system_noc_bfdcd_clk_src = {
635+ .cmd_rcgr = 0x26004,
636+ .hid_width = 5,
637+ .parent_map = gcc_xo_gpll0_gpll6a_map,
638+ .clkr.hw.init = &(struct clk_init_data){
639+ .name = "system_noc_bfdcd_clk_src",
640+ .parent_data = gcc_xo_gpll0_gpll6a_parent_data,
641+ .num_parents = 3,
642+ .ops = &clk_rcg2_ops,
643+ },
644+};
645+
646+static struct clk_rcg2 bimc_ddr_clk_src = {
647+ .cmd_rcgr = 0x32004,
648+ .hid_width = 5,
649+ .parent_map = gcc_xo_gpll0_bimc_map,
650+ .clkr.hw.init = &(struct clk_init_data){
651+ .name = "bimc_ddr_clk_src",
652+ .parent_data = gcc_xo_gpll0_bimc_parent_data,
653+ .num_parents = 3,
654+ .ops = &clk_rcg2_ops,
655+ .flags = CLK_GET_RATE_NOCACHE,
656+ },
657+};
658+
659+static const struct freq_tbl ftbl_gcc_camss_ahb_clk[] = {
660+ F(40000000, P_GPLL0, 10, 1, 2),
661+ F(80000000, P_GPLL0, 10, 0, 0),
662+ { }
663+};
664+
665+static struct clk_rcg2 camss_ahb_clk_src = {
666+ .cmd_rcgr = 0x5a000,
667+ .mnd_width = 8,
668+ .hid_width = 5,
669+ .parent_map = gcc_xo_gpll0_map,
670+ .freq_tbl = ftbl_gcc_camss_ahb_clk,
671+ .clkr.hw.init = &(struct clk_init_data){
672+ .name = "camss_ahb_clk_src",
673+ .parent_data = gcc_xo_gpll0_parent_data,
674+ .num_parents = 2,
675+ .ops = &clk_rcg2_ops,
676+ },
677+};
678+
679+static const struct freq_tbl ftbl_apss_ahb_clk[] = {
680+ F(19200000, P_XO, 1, 0, 0),
681+ F(50000000, P_GPLL0, 16, 0, 0),
682+ F(100000000, P_GPLL0, 8, 0, 0),
683+ F(133330000, P_GPLL0, 6, 0, 0),
684+ { }
685+};
686+
687+static struct clk_rcg2 apss_ahb_clk_src = {
688+ .cmd_rcgr = 0x46000,
689+ .hid_width = 5,
690+ .parent_map = gcc_xo_gpll0_map,
691+ .freq_tbl = ftbl_apss_ahb_clk,
692+ .clkr.hw.init = &(struct clk_init_data){
693+ .name = "apss_ahb_clk_src",
694+ .parent_data = gcc_xo_gpll0_parent_data,
695+ .num_parents = 2,
696+ .ops = &clk_rcg2_ops,
697+ },
698+};
699+
700+static const struct freq_tbl ftbl_gcc_camss_csi0_1_clk[] = {
701+ F(100000000, P_GPLL0, 8, 0, 0),
702+ F(200000000, P_GPLL0, 4, 0, 0),
703+ { }
704+};
705+
706+static struct clk_rcg2 csi0_clk_src = {
707+ .cmd_rcgr = 0x4e020,
708+ .hid_width = 5,
709+ .parent_map = gcc_xo_gpll0_map,
710+ .freq_tbl = ftbl_gcc_camss_csi0_1_clk,
711+ .clkr.hw.init = &(struct clk_init_data){
712+ .name = "csi0_clk_src",
713+ .parent_data = gcc_xo_gpll0_parent_data,
714+ .num_parents = 2,
715+ .ops = &clk_rcg2_ops,
716+ },
717+};
718+
719+static struct clk_rcg2 csi1_clk_src = {
720+ .cmd_rcgr = 0x4f020,
721+ .hid_width = 5,
722+ .parent_map = gcc_xo_gpll0_map,
723+ .freq_tbl = ftbl_gcc_camss_csi0_1_clk,
724+ .clkr.hw.init = &(struct clk_init_data){
725+ .name = "csi1_clk_src",
726+ .parent_data = gcc_xo_gpll0_parent_data,
727+ .num_parents = 2,
728+ .ops = &clk_rcg2_ops,
729+ },
730+};
731+
732+static const struct freq_tbl ftbl_gcc_oxili_gfx3d_clk[] = {
733+ F(19200000, P_XO, 1, 0, 0),
734+ F(50000000, P_GPLL0, 16, 0, 0),
735+ F(80000000, P_GPLL0, 10, 0, 0),
736+ F(100000000, P_GPLL0, 8, 0, 0),
737+ F(160000000, P_GPLL0, 5, 0, 0),
738+ F(200000000, P_GPLL0, 4, 0, 0),
739+ F(220000000, P_GPLL3, 5, 0, 0),
740+ F(266670000, P_GPLL0, 3, 0, 0),
741+ F(310000000, P_GPLL2_AUX, 3, 0, 0),
742+ F(400000000, P_GPLL0, 2, 0, 0),
743+ F(465000000, P_GPLL2_AUX, 2, 0, 0),
744+ F(550000000, P_GPLL3, 2, 0, 0),
745+ { }
746+};
747+
748+static struct clk_rcg2 gfx3d_clk_src = {
749+ .cmd_rcgr = 0x59000,
750+ .hid_width = 5,
751+ .parent_map = gcc_xo_gpll0_gpll2a_gpll3_gpll6a_map,
752+ .freq_tbl = ftbl_gcc_oxili_gfx3d_clk,
753+ .clkr.hw.init = &(struct clk_init_data){
754+ .name = "gfx3d_clk_src",
755+ .parent_data = gcc_xo_gpll0_gpll2a_gpll3_gpll6a_parent_data,
756+ .num_parents = 5,
757+ .ops = &clk_rcg2_ops,
758+ },
759+};
760+
761+static const struct freq_tbl ftbl_gcc_camss_vfe0_clk[] = {
762+ F(50000000, P_GPLL0, 16, 0, 0),
763+ F(80000000, P_GPLL0, 10, 0, 0),
764+ F(100000000, P_GPLL0, 8, 0, 0),
765+ F(160000000, P_GPLL0, 5, 0, 0),
766+ F(177780000, P_GPLL0, 4.5, 0, 0),
767+ F(200000000, P_GPLL0, 4, 0, 0),
768+ F(266670000, P_GPLL0, 3, 0, 0),
769+ F(320000000, P_GPLL0, 2.5, 0, 0),
770+ F(400000000, P_GPLL0, 2, 0, 0),
771+ F(465000000, P_GPLL2, 2, 0, 0),
772+ F(480000000, P_GPLL4, 2.5, 0, 0),
773+ F(600000000, P_GPLL4, 2, 0, 0),
774+ { }
775+};
776+
777+static struct clk_rcg2 vfe0_clk_src = {
778+ .cmd_rcgr = 0x58000,
779+ .hid_width = 5,
780+ .parent_map = gcc_xo_gpll0_gpll2_gpll4_map,
781+ .freq_tbl = ftbl_gcc_camss_vfe0_clk,
782+ .clkr.hw.init = &(struct clk_init_data){
783+ .name = "vfe0_clk_src",
784+ .parent_data = gcc_xo_gpll0_gpll2_gpll4_parent_data,
785+ .num_parents = 4,
786+ .ops = &clk_rcg2_ops,
787+ },
788+};
789+
790+static const struct freq_tbl ftbl_gcc_blsp1_qup1_6_i2c_apps_clk[] = {
791+ F(19200000, P_XO, 1, 0, 0),
792+ F(50000000, P_GPLL0, 16, 0, 0),
793+ { }
794+};
795+
796+static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
797+ .cmd_rcgr = 0x0200c,
798+ .hid_width = 5,
799+ .parent_map = gcc_xo_gpll0_map,
800+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
801+ .clkr.hw.init = &(struct clk_init_data){
802+ .name = "blsp1_qup1_i2c_apps_clk_src",
803+ .parent_data = gcc_xo_gpll0_parent_data,
804+ .num_parents = 2,
805+ .ops = &clk_rcg2_ops,
806+ },
807+};
808+
809+static const struct freq_tbl ftbl_gcc_blsp1_qup1_6_spi_apps_clk[] = {
810+ F(960000, P_XO, 10, 1, 2),
811+ F(4800000, P_XO, 4, 0, 0),
812+ F(9600000, P_XO, 2, 0, 0),
813+ F(16000000, P_GPLL0, 10, 1, 5),
814+ F(19200000, P_XO, 1, 0, 0),
815+ F(25000000, P_GPLL0, 16, 1, 2),
816+ F(50000000, P_GPLL0, 16, 0, 0),
817+ { }
818+};
819+
820+static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
821+ .cmd_rcgr = 0x02024,
822+ .mnd_width = 8,
823+ .hid_width = 5,
824+ .parent_map = gcc_xo_gpll0_map,
825+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
826+ .clkr.hw.init = &(struct clk_init_data){
827+ .name = "blsp1_qup1_spi_apps_clk_src",
828+ .parent_data = gcc_xo_gpll0_parent_data,
829+ .num_parents = 2,
830+ .ops = &clk_rcg2_ops,
831+ },
832+};
833+
834+static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
835+ .cmd_rcgr = 0x03000,
836+ .hid_width = 5,
837+ .parent_map = gcc_xo_gpll0_map,
838+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
839+ .clkr.hw.init = &(struct clk_init_data){
840+ .name = "blsp1_qup2_i2c_apps_clk_src",
841+ .parent_data = gcc_xo_gpll0_parent_data,
842+ .num_parents = 2,
843+ .ops = &clk_rcg2_ops,
844+ },
845+};
846+
847+static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
848+ .cmd_rcgr = 0x03014,
849+ .mnd_width = 8,
850+ .hid_width = 5,
851+ .parent_map = gcc_xo_gpll0_map,
852+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
853+ .clkr.hw.init = &(struct clk_init_data){
854+ .name = "blsp1_qup2_spi_apps_clk_src",
855+ .parent_data = gcc_xo_gpll0_parent_data,
856+ .num_parents = 2,
857+ .ops = &clk_rcg2_ops,
858+ },
859+};
860+
861+static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = {
862+ .cmd_rcgr = 0x04000,
863+ .hid_width = 5,
864+ .parent_map = gcc_xo_gpll0_map,
865+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
866+ .clkr.hw.init = &(struct clk_init_data){
867+ .name = "blsp1_qup3_i2c_apps_clk_src",
868+ .parent_data = gcc_xo_gpll0_parent_data,
869+ .num_parents = 2,
870+ .ops = &clk_rcg2_ops,
871+ },
872+};
873+
874+static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = {
875+ .cmd_rcgr = 0x04024,
876+ .mnd_width = 8,
877+ .hid_width = 5,
878+ .parent_map = gcc_xo_gpll0_map,
879+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
880+ .clkr.hw.init = &(struct clk_init_data){
881+ .name = "blsp1_qup3_spi_apps_clk_src",
882+ .parent_data = gcc_xo_gpll0_parent_data,
883+ .num_parents = 2,
884+ .ops = &clk_rcg2_ops,
885+ },
886+};
887+
888+static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = {
889+ .cmd_rcgr = 0x05000,
890+ .hid_width = 5,
891+ .parent_map = gcc_xo_gpll0_map,
892+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
893+ .clkr.hw.init = &(struct clk_init_data){
894+ .name = "blsp1_qup4_i2c_apps_clk_src",
895+ .parent_data = gcc_xo_gpll0_parent_data,
896+ .num_parents = 2,
897+ .ops = &clk_rcg2_ops,
898+ },
899+};
900+
901+static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = {
902+ .cmd_rcgr = 0x05024,
903+ .mnd_width = 8,
904+ .hid_width = 5,
905+ .parent_map = gcc_xo_gpll0_map,
906+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
907+ .clkr.hw.init = &(struct clk_init_data){
908+ .name = "blsp1_qup4_spi_apps_clk_src",
909+ .parent_data = gcc_xo_gpll0_parent_data,
910+ .num_parents = 2,
911+ .ops = &clk_rcg2_ops,
912+ },
913+};
914+
915+static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = {
916+ .cmd_rcgr = 0x06000,
917+ .hid_width = 5,
918+ .parent_map = gcc_xo_gpll0_map,
919+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
920+ .clkr.hw.init = &(struct clk_init_data){
921+ .name = "blsp1_qup5_i2c_apps_clk_src",
922+ .parent_data = gcc_xo_gpll0_parent_data,
923+ .num_parents = 2,
924+ .ops = &clk_rcg2_ops,
925+ },
926+};
927+
928+static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = {
929+ .cmd_rcgr = 0x06024,
930+ .mnd_width = 8,
931+ .hid_width = 5,
932+ .parent_map = gcc_xo_gpll0_map,
933+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
934+ .clkr.hw.init = &(struct clk_init_data){
935+ .name = "blsp1_qup5_spi_apps_clk_src",
936+ .parent_data = gcc_xo_gpll0_parent_data,
937+ .num_parents = 2,
938+ .ops = &clk_rcg2_ops,
939+ },
940+};
941+
942+static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = {
943+ .cmd_rcgr = 0x07000,
944+ .hid_width = 5,
945+ .parent_map = gcc_xo_gpll0_map,
946+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
947+ .clkr.hw.init = &(struct clk_init_data){
948+ .name = "blsp1_qup6_i2c_apps_clk_src",
949+ .parent_data = gcc_xo_gpll0_parent_data,
950+ .num_parents = 2,
951+ .ops = &clk_rcg2_ops,
952+ },
953+};
954+
955+static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = {
956+ .cmd_rcgr = 0x07024,
957+ .mnd_width = 8,
958+ .hid_width = 5,
959+ .parent_map = gcc_xo_gpll0_map,
960+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
961+ .clkr.hw.init = &(struct clk_init_data){
962+ .name = "blsp1_qup6_spi_apps_clk_src",
963+ .parent_data = gcc_xo_gpll0_parent_data,
964+ .num_parents = 2,
965+ .ops = &clk_rcg2_ops,
966+ },
967+};
968+
969+static const struct freq_tbl ftbl_gcc_blsp1_uart1_6_apps_clk[] = {
970+ F(3686400, P_GPLL0, 1, 72, 15625),
971+ F(7372800, P_GPLL0, 1, 144, 15625),
972+ F(14745600, P_GPLL0, 1, 288, 15625),
973+ F(16000000, P_GPLL0, 10, 1, 5),
974+ F(19200000, P_XO, 1, 0, 0),
975+ F(24000000, P_GPLL0, 1, 3, 100),
976+ F(25000000, P_GPLL0, 16, 1, 2),
977+ F(32000000, P_GPLL0, 1, 1, 25),
978+ F(40000000, P_GPLL0, 1, 1, 20),
979+ F(46400000, P_GPLL0, 1, 29, 500),
980+ F(48000000, P_GPLL0, 1, 3, 50),
981+ F(51200000, P_GPLL0, 1, 8, 125),
982+ F(56000000, P_GPLL0, 1, 7, 100),
983+ F(58982400, P_GPLL0, 1, 1152, 15625),
984+ F(60000000, P_GPLL0, 1, 3, 40),
985+ { }
986+};
987+
988+static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
989+ .cmd_rcgr = 0x02044,
990+ .mnd_width = 16,
991+ .hid_width = 5,
992+ .parent_map = gcc_xo_gpll0_map,
993+ .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
994+ .clkr.hw.init = &(struct clk_init_data){
995+ .name = "blsp1_uart1_apps_clk_src",
996+ .parent_data = gcc_xo_gpll0_parent_data,
997+ .num_parents = 2,
998+ .ops = &clk_rcg2_ops,
999+ },
1000+};
1001+
1002+static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
1003+ .cmd_rcgr = 0x03034,
1004+ .mnd_width = 16,
1005+ .hid_width = 5,
1006+ .parent_map = gcc_xo_gpll0_map,
1007+ .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
1008+ .clkr.hw.init = &(struct clk_init_data){
1009+ .name = "blsp1_uart2_apps_clk_src",
1010+ .parent_data = gcc_xo_gpll0_parent_data,
1011+ .num_parents = 2,
1012+ .ops = &clk_rcg2_ops,
1013+ },
1014+};
1015+
1016+static const struct freq_tbl ftbl_gcc_camss_cci_clk[] = {
1017+ F(19200000, P_XO, 1, 0, 0),
1018+ { }
1019+};
1020+
1021+static struct clk_rcg2 cci_clk_src = {
1022+ .cmd_rcgr = 0x51000,
1023+ .mnd_width = 8,
1024+ .hid_width = 5,
1025+ .parent_map = gcc_xo_gpll0a_map,
1026+ .freq_tbl = ftbl_gcc_camss_cci_clk,
1027+ .clkr.hw.init = &(struct clk_init_data){
1028+ .name = "cci_clk_src",
1029+ .parent_data = gcc_xo_gpll0a_parent_data,
1030+ .num_parents = 2,
1031+ .ops = &clk_rcg2_ops,
1032+ },
1033+};
1034+
1035+static const struct freq_tbl ftbl_gcc_camss_gp0_1_clk[] = {
1036+ F(100000000, P_GPLL0, 8, 0, 0),
1037+ F(200000000, P_GPLL0, 4, 0, 0),
1038+ { }
1039+};
1040+
1041+static struct clk_rcg2 camss_gp0_clk_src = {
1042+ .cmd_rcgr = 0x54000,
1043+ .mnd_width = 8,
1044+ .hid_width = 5,
1045+ .parent_map = gcc_xo_gpll0_gpll1a_sleep_map,
1046+ .freq_tbl = ftbl_gcc_camss_gp0_1_clk,
1047+ .clkr.hw.init = &(struct clk_init_data){
1048+ .name = "camss_gp0_clk_src",
1049+ .parent_data = gcc_xo_gpll0_gpll1a_sleep_parent_data,
1050+ .num_parents = 4,
1051+ .ops = &clk_rcg2_ops,
1052+ },
1053+};
1054+
1055+static struct clk_rcg2 camss_gp1_clk_src = {
1056+ .cmd_rcgr = 0x55000,
1057+ .mnd_width = 8,
1058+ .hid_width = 5,
1059+ .parent_map = gcc_xo_gpll0_gpll1a_sleep_map,
1060+ .freq_tbl = ftbl_gcc_camss_gp0_1_clk,
1061+ .clkr.hw.init = &(struct clk_init_data){
1062+ .name = "camss_gp1_clk_src",
1063+ .parent_data = gcc_xo_gpll0_gpll1a_sleep_parent_data,
1064+ .num_parents = 4,
1065+ .ops = &clk_rcg2_ops,
1066+ },
1067+};
1068+
1069+static const struct freq_tbl ftbl_gcc_camss_jpeg0_clk[] = {
1070+ F(133330000, P_GPLL0, 6, 0, 0),
1071+ F(266670000, P_GPLL0, 3, 0, 0),
1072+ F(320000000, P_GPLL0, 2.5, 0, 0),
1073+ { }
1074+};
1075+
1076+static struct clk_rcg2 jpeg0_clk_src = {
1077+ .cmd_rcgr = 0x57000,
1078+ .hid_width = 5,
1079+ .parent_map = gcc_xo_gpll0_map,
1080+ .freq_tbl = ftbl_gcc_camss_jpeg0_clk,
1081+ .clkr.hw.init = &(struct clk_init_data){
1082+ .name = "jpeg0_clk_src",
1083+ .parent_data = gcc_xo_gpll0_parent_data,
1084+ .num_parents = 2,
1085+ .ops = &clk_rcg2_ops,
1086+ },
1087+};
1088+
1089+static const struct freq_tbl ftbl_gcc_camss_mclk0_1_clk[] = {
1090+ F(24000000, P_GPLL0, 1, 1, 45),
1091+ F(66670000, P_GPLL0, 12, 0, 0),
1092+ { }
1093+};
1094+
1095+static struct clk_rcg2 mclk0_clk_src = {
1096+ .cmd_rcgr = 0x52000,
1097+ .mnd_width = 8,
1098+ .hid_width = 5,
1099+ .parent_map = gcc_xo_gpll0_gpll1a_gpll6_sleep_map,
1100+ .freq_tbl = ftbl_gcc_camss_mclk0_1_clk,
1101+ .clkr.hw.init = &(struct clk_init_data){
1102+ .name = "mclk0_clk_src",
1103+ .parent_data = gcc_xo_gpll0_gpll1a_gpll6_sleep_parent_data,
1104+ .num_parents = 5,
1105+ .ops = &clk_rcg2_ops,
1106+ },
1107+};
1108+
1109+static struct clk_rcg2 mclk1_clk_src = {
1110+ .cmd_rcgr = 0x53000,
1111+ .mnd_width = 8,
1112+ .hid_width = 5,
1113+ .parent_map = gcc_xo_gpll0_gpll1a_gpll6_sleep_map,
1114+ .freq_tbl = ftbl_gcc_camss_mclk0_1_clk,
1115+ .clkr.hw.init = &(struct clk_init_data){
1116+ .name = "mclk1_clk_src",
1117+ .parent_data = gcc_xo_gpll0_gpll1a_gpll6_sleep_parent_data,
1118+ .num_parents = 5,
1119+ .ops = &clk_rcg2_ops,
1120+ },
1121+};
1122+
1123+static const struct freq_tbl ftbl_gcc_camss_csi0_1phytimer_clk[] = {
1124+ F(100000000, P_GPLL0, 8, 0, 0),
1125+ F(200000000, P_GPLL0, 4, 0, 0),
1126+ { }
1127+};
1128+
1129+static struct clk_rcg2 csi0phytimer_clk_src = {
1130+ .cmd_rcgr = 0x4e000,
1131+ .hid_width = 5,
1132+ .parent_map = gcc_xo_gpll0_gpll1a_map,
1133+ .freq_tbl = ftbl_gcc_camss_csi0_1phytimer_clk,
1134+ .clkr.hw.init = &(struct clk_init_data){
1135+ .name = "csi0phytimer_clk_src",
1136+ .parent_data = gcc_xo_gpll0_gpll1a_parent_data,
1137+ .num_parents = 3,
1138+ .ops = &clk_rcg2_ops,
1139+ },
1140+};
1141+
1142+static struct clk_rcg2 csi1phytimer_clk_src = {
1143+ .cmd_rcgr = 0x4f000,
1144+ .hid_width = 5,
1145+ .parent_map = gcc_xo_gpll0_gpll1a_map,
1146+ .freq_tbl = ftbl_gcc_camss_csi0_1phytimer_clk,
1147+ .clkr.hw.init = &(struct clk_init_data){
1148+ .name = "csi1phytimer_clk_src",
1149+ .parent_data = gcc_xo_gpll0_gpll1a_parent_data,
1150+ .num_parents = 3,
1151+ .ops = &clk_rcg2_ops,
1152+ },
1153+};
1154+
1155+static const struct freq_tbl ftbl_gcc_camss_cpp_clk[] = {
1156+ F(160000000, P_GPLL0, 5, 0, 0),
1157+ F(320000000, P_GPLL0, 2.5, 0, 0),
1158+ F(465000000, P_GPLL2, 2, 0, 0),
1159+ { }
1160+};
1161+
1162+static struct clk_rcg2 cpp_clk_src = {
1163+ .cmd_rcgr = 0x58018,
1164+ .hid_width = 5,
1165+ .parent_map = gcc_xo_gpll0_gpll2_map,
1166+ .freq_tbl = ftbl_gcc_camss_cpp_clk,
1167+ .clkr.hw.init = &(struct clk_init_data){
1168+ .name = "cpp_clk_src",
1169+ .parent_data = gcc_xo_gpll0_gpll2_parent_data,
1170+ .num_parents = 3,
1171+ .ops = &clk_rcg2_ops,
1172+ },
1173+};
1174+
1175+static const struct freq_tbl ftbl_gcc_crypto_clk[] = {
1176+ F(50000000, P_GPLL0, 16, 0, 0),
1177+ F(80000000, P_GPLL0, 10, 0, 0),
1178+ F(100000000, P_GPLL0, 8, 0, 0),
1179+ F(160000000, P_GPLL0, 5, 0, 0),
1180+ { }
1181+};
1182+
1183+/* This is not in the documentation but is in the downstream driver */
1184+static struct clk_rcg2 crypto_clk_src = {
1185+ .cmd_rcgr = 0x16004,
1186+ .hid_width = 5,
1187+ .parent_map = gcc_xo_gpll0_map,
1188+ .freq_tbl = ftbl_gcc_crypto_clk,
1189+ .clkr.hw.init = &(struct clk_init_data){
1190+ .name = "crypto_clk_src",
1191+ .parent_data = gcc_xo_gpll0_parent_data,
1192+ .num_parents = 2,
1193+ .ops = &clk_rcg2_ops,
1194+ },
1195+};
1196+
1197+static const struct freq_tbl ftbl_gcc_gp1_3_clk[] = {
1198+ F(19200000, P_XO, 1, 0, 0),
1199+ { }
1200+};
1201+
1202+static struct clk_rcg2 gp1_clk_src = {
1203+ .cmd_rcgr = 0x08004,
1204+ .mnd_width = 8,
1205+ .hid_width = 5,
1206+ .parent_map = gcc_xo_gpll0_gpll1a_sleep_map,
1207+ .freq_tbl = ftbl_gcc_gp1_3_clk,
1208+ .clkr.hw.init = &(struct clk_init_data){
1209+ .name = "gp1_clk_src",
1210+ .parent_data = gcc_xo_gpll0_gpll1a_sleep_parent_data,
1211+ .num_parents = 3,
1212+ .ops = &clk_rcg2_ops,
1213+ },
1214+};
1215+
1216+static struct clk_rcg2 gp2_clk_src = {
1217+ .cmd_rcgr = 0x09004,
1218+ .mnd_width = 8,
1219+ .hid_width = 5,
1220+ .parent_map = gcc_xo_gpll0_gpll1a_sleep_map,
1221+ .freq_tbl = ftbl_gcc_gp1_3_clk,
1222+ .clkr.hw.init = &(struct clk_init_data){
1223+ .name = "gp2_clk_src",
1224+ .parent_data = gcc_xo_gpll0_gpll1a_sleep_parent_data,
1225+ .num_parents = 3,
1226+ .ops = &clk_rcg2_ops,
1227+ },
1228+};
1229+
1230+static struct clk_rcg2 gp3_clk_src = {
1231+ .cmd_rcgr = 0x0a004,
1232+ .mnd_width = 8,
1233+ .hid_width = 5,
1234+ .parent_map = gcc_xo_gpll0_gpll1a_sleep_map,
1235+ .freq_tbl = ftbl_gcc_gp1_3_clk,
1236+ .clkr.hw.init = &(struct clk_init_data){
1237+ .name = "gp3_clk_src",
1238+ .parent_data = gcc_xo_gpll0_gpll1a_sleep_parent_data,
1239+ .num_parents = 3,
1240+ .ops = &clk_rcg2_ops,
1241+ },
1242+};
1243+
1244+static struct clk_rcg2 byte0_clk_src = {
1245+ .cmd_rcgr = 0x4d044,
1246+ .hid_width = 5,
1247+ .parent_map = gcc_xo_gpll0a_dsibyte_map,
1248+ .clkr.hw.init = &(struct clk_init_data){
1249+ .name = "byte0_clk_src",
1250+ .parent_data = gcc_xo_gpll0a_dsibyte_parent_data,
1251+ .num_parents = 3,
1252+ .ops = &clk_byte2_ops,
1253+ .flags = CLK_SET_RATE_PARENT,
1254+ },
1255+};
1256+
1257+static struct clk_rcg2 byte1_clk_src = {
1258+ .cmd_rcgr = 0x4d0b0,
1259+ .hid_width = 5,
1260+ .parent_map = gcc_xo_gpll0a_dsibyte_map,
1261+ .clkr.hw.init = &(struct clk_init_data){
1262+ .name = "byte1_clk_src",
1263+ .parent_data = gcc_xo_gpll0a_dsibyte_parent_data,
1264+ .num_parents = 3,
1265+ .ops = &clk_byte2_ops,
1266+ .flags = CLK_SET_RATE_PARENT,
1267+ },
1268+};
1269+
1270+static const struct freq_tbl ftbl_gcc_mdss_esc_clk[] = {
1271+ F(19200000, P_XO, 1, 0, 0),
1272+ { }
1273+};
1274+
1275+static struct clk_rcg2 esc0_clk_src = {
1276+ .cmd_rcgr = 0x4d060,
1277+ .hid_width = 5,
1278+ .parent_map = gcc_xo_dsibyte_map,
1279+ .freq_tbl = ftbl_gcc_mdss_esc_clk,
1280+ .clkr.hw.init = &(struct clk_init_data){
1281+ .name = "esc0_clk_src",
1282+ .parent_data = gcc_xo_dsibyte_parent_data,
1283+ .num_parents = 2,
1284+ .ops = &clk_rcg2_ops,
1285+ },
1286+};
1287+
1288+static struct clk_rcg2 esc1_clk_src = {
1289+ .cmd_rcgr = 0x4d0a8,
1290+ .hid_width = 5,
1291+ .parent_map = gcc_xo_dsibyte_map,
1292+ .freq_tbl = ftbl_gcc_mdss_esc_clk,
1293+ .clkr.hw.init = &(struct clk_init_data){
1294+ .name = "esc1_clk_src",
1295+ .parent_data = gcc_xo_dsibyte_parent_data,
1296+ .num_parents = 2,
1297+ .ops = &clk_rcg2_ops,
1298+ },
1299+};
1300+
1301+static const struct freq_tbl ftbl_gcc_mdss_mdp_clk[] = {
1302+ F(50000000, P_GPLL0_AUX, 16, 0, 0),
1303+ F(80000000, P_GPLL0_AUX, 10, 0, 0),
1304+ F(100000000, P_GPLL0_AUX, 8, 0, 0),
1305+ F(160000000, P_GPLL0_AUX, 5, 0, 0),
1306+ F(177780000, P_GPLL0_AUX, 4.5, 0, 0),
1307+ F(200000000, P_GPLL0_AUX, 4, 0, 0),
1308+ F(266670000, P_GPLL0_AUX, 3, 0, 0),
1309+ F(307200000, P_GPLL1, 2, 0, 0),
1310+ F(366670000, P_GPLL3_AUX, 3, 0, 0),
1311+ { }
1312+};
1313+
1314+static struct clk_rcg2 mdp_clk_src = {
1315+ .cmd_rcgr = 0x4d014,
1316+ .hid_width = 5,
1317+ .parent_map = gcc_xo_gpll1_dsiphy_gpll6_gpll3a_gpll0a_map,
1318+ .freq_tbl = ftbl_gcc_mdss_mdp_clk,
1319+ .clkr.hw.init = &(struct clk_init_data){
1320+ .name = "mdp_clk_src",
1321+ .parent_data = gcc_xo_gpll1_dsiphy_gpll6_gpll3a_gpll0a_parent_data,
1322+ .num_parents = 6,
1323+ .ops = &clk_rcg2_ops,
1324+ },
1325+};
1326+
1327+static struct clk_rcg2 pclk0_clk_src = {
1328+ .cmd_rcgr = 0x4d000,
1329+ .mnd_width = 8,
1330+ .hid_width = 5,
1331+ .parent_map = gcc_xo_gpll0a_dsiphy_map,
1332+ .clkr.hw.init = &(struct clk_init_data){
1333+ .name = "pclk0_clk_src",
1334+ .parent_data = gcc_xo_gpll0a_dsiphy_parent_data,
1335+ .num_parents = 3,
1336+ .ops = &clk_pixel_ops,
1337+ .flags = CLK_SET_RATE_PARENT,
1338+ },
1339+};
1340+
1341+static struct clk_rcg2 pclk1_clk_src = {
1342+ .cmd_rcgr = 0x4d0b8,
1343+ .mnd_width = 8,
1344+ .hid_width = 5,
1345+ .parent_map = gcc_xo_gpll0a_dsiphy_map,
1346+ .clkr.hw.init = &(struct clk_init_data){
1347+ .name = "pclk1_clk_src",
1348+ .parent_data = gcc_xo_gpll0a_dsiphy_parent_data,
1349+ .num_parents = 3,
1350+ .ops = &clk_pixel_ops,
1351+ .flags = CLK_SET_RATE_PARENT,
1352+ },
1353+};
1354+
1355+static const struct freq_tbl ftbl_gcc_mdss_vsync_clk[] = {
1356+ F(19200000, P_XO, 1, 0, 0),
1357+ { }
1358+};
1359+
1360+static struct clk_rcg2 vsync_clk_src = {
1361+ .cmd_rcgr = 0x4d02c,
1362+ .hid_width = 5,
1363+ .parent_map = gcc_xo_gpll0a_map,
1364+ .freq_tbl = ftbl_gcc_mdss_vsync_clk,
1365+ .clkr.hw.init = &(struct clk_init_data){
1366+ .name = "vsync_clk_src",
1367+ .parent_data = gcc_xo_gpll0a_parent_data,
1368+ .num_parents = 2,
1369+ .ops = &clk_rcg2_ops,
1370+ },
1371+};
1372+
1373+static const struct freq_tbl ftbl_gcc_pdm2_clk[] = {
1374+ F(64000000, P_GPLL0, 12.5, 0, 0),
1375+ { }
1376+};
1377+
1378+/* This is not in the documentation but is in the downstream driver */
1379+static struct clk_rcg2 pdm2_clk_src = {
1380+ .cmd_rcgr = 0x44010,
1381+ .hid_width = 5,
1382+ .parent_map = gcc_xo_gpll0_map,
1383+ .freq_tbl = ftbl_gcc_pdm2_clk,
1384+ .clkr.hw.init = &(struct clk_init_data){
1385+ .name = "pdm2_clk_src",
1386+ .parent_data = gcc_xo_gpll0_parent_data,
1387+ .num_parents = 2,
1388+ .ops = &clk_rcg2_ops,
1389+ },
1390+};
1391+
1392+static const struct freq_tbl ftbl_gcc_sdcc_apps_clk[] = {
1393+ F(144000, P_XO, 16, 3, 25),
1394+ F(400000, P_XO, 12, 1, 4),
1395+ F(20000000, P_GPLL0, 10, 1, 4),
1396+ F(25000000, P_GPLL0, 16, 1, 2),
1397+ F(50000000, P_GPLL0, 16, 0, 0),
1398+ F(100000000, P_GPLL0, 8, 0, 0),
1399+ F(177770000, P_GPLL0, 4.5, 0, 0),
1400+ F(200000000, P_GPLL0, 4, 0, 0),
1401+ { }
1402+};
1403+
1404+static struct clk_rcg2 sdcc1_apps_clk_src = {
1405+ .cmd_rcgr = 0x42004,
1406+ .mnd_width = 8,
1407+ .hid_width = 5,
1408+ .parent_map = gcc_xo_gpll0_map,
1409+ .freq_tbl = ftbl_gcc_sdcc_apps_clk,
1410+ .clkr.hw.init = &(struct clk_init_data){
1411+ .name = "sdcc1_apps_clk_src",
1412+ .parent_data = gcc_xo_gpll0_parent_data,
1413+ .num_parents = 2,
1414+ .ops = &clk_rcg2_floor_ops,
1415+ },
1416+};
1417+
1418+static struct clk_rcg2 sdcc2_apps_clk_src = {
1419+ .cmd_rcgr = 0x43004,
1420+ .mnd_width = 8,
1421+ .hid_width = 5,
1422+ .parent_map = gcc_xo_gpll0_map,
1423+ .freq_tbl = ftbl_gcc_sdcc_apps_clk,
1424+ .clkr.hw.init = &(struct clk_init_data){
1425+ .name = "sdcc2_apps_clk_src",
1426+ .parent_data = gcc_xo_gpll0_parent_data,
1427+ .num_parents = 2,
1428+ .ops = &clk_rcg2_floor_ops,
1429+ },
1430+};
1431+
1432+static const struct freq_tbl ftbl_gcc_apss_tcu_clk[] = {
1433+ F(154285000, P_GPLL6, 7, 0, 0),
1434+ F(320000000, P_GPLL0, 2.5, 0, 0),
1435+ F(400000000, P_GPLL0, 2, 0, 0),
1436+ { }
1437+};
1438+
1439+static struct clk_rcg2 apss_tcu_clk_src = {
1440+ .cmd_rcgr = 0x1207c,
1441+ .hid_width = 5,
1442+ .parent_map = gcc_xo_gpll0_gpll5a_gpll6_bimc_map,
1443+ .freq_tbl = ftbl_gcc_apss_tcu_clk,
1444+ .clkr.hw.init = &(struct clk_init_data){
1445+ .name = "apss_tcu_clk_src",
1446+ .parent_data = gcc_xo_gpll0_gpll5a_gpll6_bimc_parent_data,
1447+ .num_parents = 5,
1448+ .ops = &clk_rcg2_ops,
1449+ },
1450+};
1451+
1452+static const struct freq_tbl ftbl_gcc_bimc_gpu_clk[] = {
1453+ F(19200000, P_XO, 1, 0, 0),
1454+ F(100000000, P_GPLL0, 8, 0, 0),
1455+ F(200000000, P_GPLL0, 4, 0, 0),
1456+ F(266500000, P_BIMC, 4, 0, 0),
1457+ F(400000000, P_GPLL0, 2, 0, 0),
1458+ F(533000000, P_BIMC, 2, 0, 0),
1459+ { }
1460+};
1461+
1462+static struct clk_rcg2 bimc_gpu_clk_src = {
1463+ .cmd_rcgr = 0x31028,
1464+ .hid_width = 5,
1465+ .parent_map = gcc_xo_gpll0_gpll5a_gpll6_bimc_map,
1466+ .freq_tbl = ftbl_gcc_bimc_gpu_clk,
1467+ .clkr.hw.init = &(struct clk_init_data){
1468+ .name = "bimc_gpu_clk_src",
1469+ .parent_data = gcc_xo_gpll0_gpll5a_gpll6_bimc_parent_data,
1470+ .num_parents = 5,
1471+ .flags = CLK_GET_RATE_NOCACHE,
1472+ .ops = &clk_rcg2_ops,
1473+ },
1474+};
1475+
1476+static const struct freq_tbl ftbl_gcc_usb_hs_system_clk[] = {
1477+ F(80000000, P_GPLL0, 10, 0, 0),
1478+ { }
1479+};
1480+
1481+static struct clk_rcg2 usb_hs_system_clk_src = {
1482+ .cmd_rcgr = 0x41010,
1483+ .hid_width = 5,
1484+ .parent_map = gcc_xo_gpll0_map,
1485+ .freq_tbl = ftbl_gcc_usb_hs_system_clk,
1486+ .clkr.hw.init = &(struct clk_init_data){
1487+ .name = "usb_hs_system_clk_src",
1488+ .parent_data = gcc_xo_gpll0_parent_data,
1489+ .num_parents = 2,
1490+ .ops = &clk_rcg2_ops,
1491+ },
1492+};
1493+
1494+static const struct freq_tbl ftbl_gcc_usb_fs_system_clk[] = {
1495+ F(64000000, P_GPLL0, 12.5, 0, 0),
1496+ { }
1497+};
1498+
1499+static struct clk_rcg2 usb_fs_system_clk_src = {
1500+ .cmd_rcgr = 0x3f010,
1501+ .hid_width = 5,
1502+ .parent_map = gcc_xo_gpll0_map,
1503+ .freq_tbl = ftbl_gcc_usb_fs_system_clk,
1504+ .clkr.hw.init = &(struct clk_init_data){
1505+ .name = "usb_fs_system_clk_src",
1506+ .parent_data = gcc_xo_gpll6_gpll0_parent_data,
1507+ .num_parents = 3,
1508+ .ops = &clk_rcg2_ops,
1509+ },
1510+};
1511+
1512+static const struct freq_tbl ftbl_gcc_usb_fs_ic_clk[] = {
1513+ F(60000000, P_GPLL6, 1, 1, 18),
1514+ { }
1515+};
1516+
1517+static struct clk_rcg2 usb_fs_ic_clk_src = {
1518+ .cmd_rcgr = 0x3f034,
1519+ .hid_width = 5,
1520+ .parent_map = gcc_xo_gpll0_map,
1521+ .freq_tbl = ftbl_gcc_usb_fs_ic_clk,
1522+ .clkr.hw.init = &(struct clk_init_data){
1523+ .name = "usb_fs_ic_clk_src",
1524+ .parent_data = gcc_xo_gpll6_gpll0a_parent_data,
1525+ .num_parents = 3,
1526+ .ops = &clk_rcg2_ops,
1527+ },
1528+};
1529+
1530+static const struct freq_tbl ftbl_gcc_ultaudio_ahb_clk[] = {
1531+ F(3200000, P_XO, 6, 0, 0),
1532+ F(6400000, P_XO, 3, 0, 0),
1533+ F(9600000, P_XO, 2, 0, 0),
1534+ F(19200000, P_XO, 1, 0, 0),
1535+ F(40000000, P_GPLL0, 10, 1, 2),
1536+ F(66670000, P_GPLL0, 12, 0, 0),
1537+ F(80000000, P_GPLL0, 10, 0, 0),
1538+ F(100000000, P_GPLL0, 8, 0, 0),
1539+ { }
1540+};
1541+
1542+static struct clk_rcg2 ultaudio_ahbfabric_clk_src = {
1543+ .cmd_rcgr = 0x1c010,
1544+ .hid_width = 5,
1545+ .mnd_width = 8,
1546+ .parent_map = gcc_xo_gpll0_gpll1_sleep_map,
1547+ .freq_tbl = ftbl_gcc_ultaudio_ahb_clk,
1548+ .clkr.hw.init = &(struct clk_init_data){
1549+ .name = "ultaudio_ahbfabric_clk_src",
1550+ .parent_data = gcc_xo_gpll0_gpll1_sleep_parent_data,
1551+ .num_parents = 4,
1552+ .ops = &clk_rcg2_ops,
1553+ },
1554+};
1555+
1556+static struct clk_branch gcc_ultaudio_ahbfabric_ixfabric_clk = {
1557+ .halt_reg = 0x1c028,
1558+ .clkr = {
1559+ .enable_reg = 0x1c028,
1560+ .enable_mask = BIT(0),
1561+ .hw.init = &(struct clk_init_data){
1562+ .name = "gcc_ultaudio_ahbfabric_ixfabric_clk",
1563+ .parent_data = &(const struct clk_parent_data){
1564+ .hw = &ultaudio_ahbfabric_clk_src.clkr.hw,
1565+ },
1566+ .num_parents = 1,
1567+ .flags = CLK_SET_RATE_PARENT,
1568+ .ops = &clk_branch2_ops,
1569+ },
1570+ },
1571+};
1572+
1573+static struct clk_branch gcc_ultaudio_ahbfabric_ixfabric_lpm_clk = {
1574+ .halt_reg = 0x1c024,
1575+ .clkr = {
1576+ .enable_reg = 0x1c024,
1577+ .enable_mask = BIT(0),
1578+ .hw.init = &(struct clk_init_data){
1579+ .name = "gcc_ultaudio_ahbfabric_ixfabric_lpm_clk",
1580+ .parent_data = &(const struct clk_parent_data){
1581+ .hw = &ultaudio_ahbfabric_clk_src.clkr.hw,
1582+ },
1583+ .num_parents = 1,
1584+ .flags = CLK_SET_RATE_PARENT,
1585+ .ops = &clk_branch2_ops,
1586+ },
1587+ },
1588+};
1589+
1590+static const struct freq_tbl ftbl_gcc_ultaudio_lpaif_i2s_clk[] = {
1591+ F(128000, P_XO, 10, 1, 15),
1592+ F(256000, P_XO, 5, 1, 15),
1593+ F(384000, P_XO, 5, 1, 10),
1594+ F(512000, P_XO, 5, 2, 15),
1595+ F(576000, P_XO, 5, 3, 20),
1596+ F(705600, P_GPLL1, 16, 1, 80),
1597+ F(768000, P_XO, 5, 1, 5),
1598+ F(800000, P_XO, 5, 5, 24),
1599+ F(1024000, P_XO, 5, 4, 15),
1600+ F(1152000, P_XO, 1, 3, 50),
1601+ F(1411200, P_GPLL1, 16, 1, 40),
1602+ F(1536000, P_XO, 1, 2, 25),
1603+ F(1600000, P_XO, 12, 0, 0),
1604+ F(1728000, P_XO, 5, 9, 20),
1605+ F(2048000, P_XO, 5, 8, 15),
1606+ F(2304000, P_XO, 5, 3, 5),
1607+ F(2400000, P_XO, 8, 0, 0),
1608+ F(2822400, P_GPLL1, 16, 1, 20),
1609+ F(3072000, P_XO, 5, 4, 5),
1610+ F(4096000, P_GPLL1, 9, 2, 49),
1611+ F(4800000, P_XO, 4, 0, 0),
1612+ F(5644800, P_GPLL1, 16, 1, 10),
1613+ F(6144000, P_GPLL1, 7, 1, 21),
1614+ F(8192000, P_GPLL1, 9, 4, 49),
1615+ F(9600000, P_XO, 2, 0, 0),
1616+ F(11289600, P_GPLL1, 16, 1, 5),
1617+ F(12288000, P_GPLL1, 7, 2, 21),
1618+ { }
1619+};
1620+
1621+static struct clk_rcg2 ultaudio_lpaif_pri_i2s_clk_src = {
1622+ .cmd_rcgr = 0x1c054,
1623+ .hid_width = 5,
1624+ .mnd_width = 8,
1625+ .parent_map = gcc_xo_gpll1_epi2s_emclk_sleep_map,
1626+ .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
1627+ .clkr.hw.init = &(struct clk_init_data){
1628+ .name = "ultaudio_lpaif_pri_i2s_clk_src",
1629+ .parent_data = gcc_xo_gpll1_epi2s_emclk_sleep_parent_data,
1630+ .num_parents = 5,
1631+ .ops = &clk_rcg2_ops,
1632+ },
1633+};
1634+
1635+static struct clk_branch gcc_ultaudio_lpaif_pri_i2s_clk = {
1636+ .halt_reg = 0x1c068,
1637+ .clkr = {
1638+ .enable_reg = 0x1c068,
1639+ .enable_mask = BIT(0),
1640+ .hw.init = &(struct clk_init_data){
1641+ .name = "gcc_ultaudio_lpaif_pri_i2s_clk",
1642+ .parent_data = &(const struct clk_parent_data){
1643+ .hw = &ultaudio_lpaif_pri_i2s_clk_src.clkr.hw,
1644+ },
1645+ .num_parents = 1,
1646+ .flags = CLK_SET_RATE_PARENT,
1647+ .ops = &clk_branch2_ops,
1648+ },
1649+ },
1650+};
1651+
1652+static struct clk_rcg2 ultaudio_lpaif_sec_i2s_clk_src = {
1653+ .cmd_rcgr = 0x1c06c,
1654+ .hid_width = 5,
1655+ .mnd_width = 8,
1656+ .parent_map = gcc_xo_gpll1_esi2s_emclk_sleep_map,
1657+ .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
1658+ .clkr.hw.init = &(struct clk_init_data){
1659+ .name = "ultaudio_lpaif_sec_i2s_clk_src",
1660+ .parent_data = gcc_xo_gpll1_esi2s_emclk_sleep_parent_data,
1661+ .num_parents = 5,
1662+ .ops = &clk_rcg2_ops,
1663+ },
1664+};
1665+
1666+static struct clk_branch gcc_ultaudio_lpaif_sec_i2s_clk = {
1667+ .halt_reg = 0x1c080,
1668+ .clkr = {
1669+ .enable_reg = 0x1c080,
1670+ .enable_mask = BIT(0),
1671+ .hw.init = &(struct clk_init_data){
1672+ .name = "gcc_ultaudio_lpaif_sec_i2s_clk",
1673+ .parent_data = &(const struct clk_parent_data){
1674+ .hw = &ultaudio_lpaif_sec_i2s_clk_src.clkr.hw,
1675+ },
1676+ .num_parents = 1,
1677+ .flags = CLK_SET_RATE_PARENT,
1678+ .ops = &clk_branch2_ops,
1679+ },
1680+ },
1681+};
1682+
1683+static struct clk_rcg2 ultaudio_lpaif_aux_i2s_clk_src = {
1684+ .cmd_rcgr = 0x1c084,
1685+ .hid_width = 5,
1686+ .mnd_width = 8,
1687+ .parent_map = gcc_xo_gpll1_emclk_sleep_map,
1688+ .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
1689+ .clkr.hw.init = &(struct clk_init_data){
1690+ .name = "ultaudio_lpaif_aux_i2s_clk_src",
1691+ .parent_data = gcc_xo_gpll1_esi2s_emclk_sleep_parent_data,
1692+ .num_parents = 5,
1693+ .ops = &clk_rcg2_ops,
1694+ },
1695+};
1696+
1697+static struct clk_branch gcc_ultaudio_lpaif_aux_i2s_clk = {
1698+ .halt_reg = 0x1c098,
1699+ .clkr = {
1700+ .enable_reg = 0x1c098,
1701+ .enable_mask = BIT(0),
1702+ .hw.init = &(struct clk_init_data){
1703+ .name = "gcc_ultaudio_lpaif_aux_i2s_clk",
1704+ .parent_data = &(const struct clk_parent_data){
1705+ .hw = &ultaudio_lpaif_aux_i2s_clk_src.clkr.hw,
1706+ },
1707+ .num_parents = 1,
1708+ .flags = CLK_SET_RATE_PARENT,
1709+ .ops = &clk_branch2_ops,
1710+ },
1711+ },
1712+};
1713+
1714+static const struct freq_tbl ftbl_gcc_ultaudio_xo_clk[] = {
1715+ F(19200000, P_XO, 1, 0, 0),
1716+ { }
1717+};
1718+
1719+static struct clk_rcg2 ultaudio_xo_clk_src = {
1720+ .cmd_rcgr = 0x1c034,
1721+ .hid_width = 5,
1722+ .parent_map = gcc_xo_sleep_map,
1723+ .freq_tbl = ftbl_gcc_ultaudio_xo_clk,
1724+ .clkr.hw.init = &(struct clk_init_data){
1725+ .name = "ultaudio_xo_clk_src",
1726+ .parent_data = gcc_xo_sleep_parent_data,
1727+ .num_parents = 2,
1728+ .ops = &clk_rcg2_ops,
1729+ },
1730+};
1731+
1732+static struct clk_branch gcc_ultaudio_avsync_xo_clk = {
1733+ .halt_reg = 0x1c04c,
1734+ .clkr = {
1735+ .enable_reg = 0x1c04c,
1736+ .enable_mask = BIT(0),
1737+ .hw.init = &(struct clk_init_data){
1738+ .name = "gcc_ultaudio_avsync_xo_clk",
1739+ .parent_data = &(const struct clk_parent_data){
1740+ .hw = &ultaudio_xo_clk_src.clkr.hw,
1741+ },
1742+ .num_parents = 1,
1743+ .flags = CLK_SET_RATE_PARENT,
1744+ .ops = &clk_branch2_ops,
1745+ },
1746+ },
1747+};
1748+
1749+static struct clk_branch gcc_ultaudio_stc_xo_clk = {
1750+ .halt_reg = 0x1c050,
1751+ .clkr = {
1752+ .enable_reg = 0x1c050,
1753+ .enable_mask = BIT(0),
1754+ .hw.init = &(struct clk_init_data){
1755+ .name = "gcc_ultaudio_stc_xo_clk",
1756+ .parent_data = &(const struct clk_parent_data){
1757+ .hw = &ultaudio_xo_clk_src.clkr.hw,
1758+ },
1759+ .num_parents = 1,
1760+ .flags = CLK_SET_RATE_PARENT,
1761+ .ops = &clk_branch2_ops,
1762+ },
1763+ },
1764+};
1765+
1766+static const struct freq_tbl ftbl_codec_clk[] = {
1767+ F(9600000, P_XO, 2, 0, 0),
1768+ F(12288000, P_XO, 1, 16, 25),
1769+ F(19200000, P_XO, 1, 0, 0),
1770+ F(11289600, P_EXT_MCLK, 1, 0, 0),
1771+ { }
1772+};
1773+
1774+static struct clk_rcg2 codec_digcodec_clk_src = {
1775+ .cmd_rcgr = 0x1c09c,
1776+ .mnd_width = 8,
1777+ .hid_width = 5,
1778+ .parent_map = gcc_xo_gpll1_emclk_sleep_map,
1779+ .freq_tbl = ftbl_codec_clk,
1780+ .clkr.hw.init = &(struct clk_init_data){
1781+ .name = "codec_digcodec_clk_src",
1782+ .parent_data = gcc_xo_gpll1_emclk_sleep_parent_data,
1783+ .num_parents = 4,
1784+ .ops = &clk_rcg2_ops,
1785+ },
1786+};
1787+
1788+static struct clk_branch gcc_codec_digcodec_clk = {
1789+ .halt_reg = 0x1c0b0,
1790+ .clkr = {
1791+ .enable_reg = 0x1c0b0,
1792+ .enable_mask = BIT(0),
1793+ .hw.init = &(struct clk_init_data){
1794+ .name = "gcc_ultaudio_codec_digcodec_clk",
1795+ .parent_data = &(const struct clk_parent_data){
1796+ .hw = &codec_digcodec_clk_src.clkr.hw,
1797+ },
1798+ .num_parents = 1,
1799+ .flags = CLK_SET_RATE_PARENT,
1800+ .ops = &clk_branch2_ops,
1801+ },
1802+ },
1803+};
1804+
1805+static struct clk_branch gcc_ultaudio_pcnoc_mport_clk = {
1806+ .halt_reg = 0x1c000,
1807+ .clkr = {
1808+ .enable_reg = 0x1c000,
1809+ .enable_mask = BIT(0),
1810+ .hw.init = &(struct clk_init_data){
1811+ .name = "gcc_ultaudio_pcnoc_mport_clk",
1812+ .parent_data = &(const struct clk_parent_data){
1813+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
1814+ },
1815+ .num_parents = 1,
1816+ .ops = &clk_branch2_ops,
1817+ },
1818+ },
1819+};
1820+
1821+static struct clk_branch gcc_ultaudio_pcnoc_sway_clk = {
1822+ .halt_reg = 0x1c004,
1823+ .clkr = {
1824+ .enable_reg = 0x1c004,
1825+ .enable_mask = BIT(0),
1826+ .hw.init = &(struct clk_init_data){
1827+ .name = "gcc_ultaudio_pcnoc_sway_clk",
1828+ .parent_data = &(const struct clk_parent_data){
1829+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
1830+ },
1831+ .num_parents = 1,
1832+ .ops = &clk_branch2_ops,
1833+ },
1834+ },
1835+};
1836+
1837+static const struct freq_tbl ftbl_gcc_venus0_vcodec0_clk[] = {
1838+ F(100000000, P_GPLL0, 8, 0, 0),
1839+ F(160000000, P_GPLL0, 5, 0, 0),
1840+ F(228570000, P_GPLL0, 3.5, 0, 0),
1841+ { }
1842+};
1843+
1844+static struct clk_rcg2 vcodec0_clk_src = {
1845+ .cmd_rcgr = 0x4C000,
1846+ .mnd_width = 8,
1847+ .hid_width = 5,
1848+ .parent_map = gcc_xo_gpll0_map,
1849+ .freq_tbl = ftbl_gcc_venus0_vcodec0_clk,
1850+ .clkr.hw.init = &(struct clk_init_data){
1851+ .name = "vcodec0_clk_src",
1852+ .parent_data = gcc_xo_gpll0_parent_data,
1853+ .num_parents = 2,
1854+ .ops = &clk_rcg2_ops,
1855+ },
1856+};
1857+
1858+static struct clk_branch gcc_blsp1_ahb_clk = {
1859+ .halt_reg = 0x01008,
1860+ .halt_check = BRANCH_HALT_VOTED,
1861+ .clkr = {
1862+ .enable_reg = 0x45004,
1863+ .enable_mask = BIT(10),
1864+ .hw.init = &(struct clk_init_data){
1865+ .name = "gcc_blsp1_ahb_clk",
1866+ .parent_data = &(const struct clk_parent_data){
1867+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
1868+ },
1869+ .num_parents = 1,
1870+ .ops = &clk_branch2_ops,
1871+ },
1872+ },
1873+};
1874+
1875+static struct clk_branch gcc_blsp1_sleep_clk = {
1876+ .halt_reg = 0x01004,
1877+ .clkr = {
1878+ .enable_reg = 0x01004,
1879+ .enable_mask = BIT(0),
1880+ .hw.init = &(struct clk_init_data){
1881+ .name = "gcc_blsp1_sleep_clk",
1882+ .ops = &clk_branch2_ops,
1883+ },
1884+ },
1885+};
1886+
1887+static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
1888+ .halt_reg = 0x02008,
1889+ .clkr = {
1890+ .enable_reg = 0x02008,
1891+ .enable_mask = BIT(0),
1892+ .hw.init = &(struct clk_init_data){
1893+ .name = "gcc_blsp1_qup1_i2c_apps_clk",
1894+ .parent_data = &(const struct clk_parent_data){
1895+ .hw = &blsp1_qup1_i2c_apps_clk_src.clkr.hw,
1896+ },
1897+ .num_parents = 1,
1898+ .flags = CLK_SET_RATE_PARENT,
1899+ .ops = &clk_branch2_ops,
1900+ },
1901+ },
1902+};
1903+
1904+static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
1905+ .halt_reg = 0x02004,
1906+ .clkr = {
1907+ .enable_reg = 0x02004,
1908+ .enable_mask = BIT(0),
1909+ .hw.init = &(struct clk_init_data){
1910+ .name = "gcc_blsp1_qup1_spi_apps_clk",
1911+ .parent_data = &(const struct clk_parent_data){
1912+ .hw = &blsp1_qup1_spi_apps_clk_src.clkr.hw,
1913+ },
1914+ .num_parents = 1,
1915+ .flags = CLK_SET_RATE_PARENT,
1916+ .ops = &clk_branch2_ops,
1917+ },
1918+ },
1919+};
1920+
1921+static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
1922+ .halt_reg = 0x03010,
1923+ .clkr = {
1924+ .enable_reg = 0x03010,
1925+ .enable_mask = BIT(0),
1926+ .hw.init = &(struct clk_init_data){
1927+ .name = "gcc_blsp1_qup2_i2c_apps_clk",
1928+ .parent_data = &(const struct clk_parent_data){
1929+ .hw = &blsp1_qup2_i2c_apps_clk_src.clkr.hw,
1930+ },
1931+ .num_parents = 1,
1932+ .flags = CLK_SET_RATE_PARENT,
1933+ .ops = &clk_branch2_ops,
1934+ },
1935+ },
1936+};
1937+
1938+static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
1939+ .halt_reg = 0x0300c,
1940+ .clkr = {
1941+ .enable_reg = 0x0300c,
1942+ .enable_mask = BIT(0),
1943+ .hw.init = &(struct clk_init_data){
1944+ .name = "gcc_blsp1_qup2_spi_apps_clk",
1945+ .parent_data = &(const struct clk_parent_data){
1946+ .hw = &blsp1_qup2_spi_apps_clk_src.clkr.hw,
1947+ },
1948+ .num_parents = 1,
1949+ .flags = CLK_SET_RATE_PARENT,
1950+ .ops = &clk_branch2_ops,
1951+ },
1952+ },
1953+};
1954+
1955+static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
1956+ .halt_reg = 0x04020,
1957+ .clkr = {
1958+ .enable_reg = 0x04020,
1959+ .enable_mask = BIT(0),
1960+ .hw.init = &(struct clk_init_data){
1961+ .name = "gcc_blsp1_qup3_i2c_apps_clk",
1962+ .parent_data = &(const struct clk_parent_data){
1963+ .hw = &blsp1_qup3_i2c_apps_clk_src.clkr.hw,
1964+ },
1965+ .num_parents = 1,
1966+ .flags = CLK_SET_RATE_PARENT,
1967+ .ops = &clk_branch2_ops,
1968+ },
1969+ },
1970+};
1971+
1972+static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
1973+ .halt_reg = 0x0401c,
1974+ .clkr = {
1975+ .enable_reg = 0x0401c,
1976+ .enable_mask = BIT(0),
1977+ .hw.init = &(struct clk_init_data){
1978+ .name = "gcc_blsp1_qup3_spi_apps_clk",
1979+ .parent_data = &(const struct clk_parent_data){
1980+ .hw = &blsp1_qup3_spi_apps_clk_src.clkr.hw,
1981+ },
1982+ .num_parents = 1,
1983+ .flags = CLK_SET_RATE_PARENT,
1984+ .ops = &clk_branch2_ops,
1985+ },
1986+ },
1987+};
1988+
1989+static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
1990+ .halt_reg = 0x05020,
1991+ .clkr = {
1992+ .enable_reg = 0x05020,
1993+ .enable_mask = BIT(0),
1994+ .hw.init = &(struct clk_init_data){
1995+ .name = "gcc_blsp1_qup4_i2c_apps_clk",
1996+ .parent_data = &(const struct clk_parent_data){
1997+ .hw = &blsp1_qup4_i2c_apps_clk_src.clkr.hw,
1998+ },
1999+ .num_parents = 1,
2000+ .flags = CLK_SET_RATE_PARENT,
2001+ .ops = &clk_branch2_ops,
2002+ },
2003+ },
2004+};
2005+
2006+static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
2007+ .halt_reg = 0x0501c,
2008+ .clkr = {
2009+ .enable_reg = 0x0501c,
2010+ .enable_mask = BIT(0),
2011+ .hw.init = &(struct clk_init_data){
2012+ .name = "gcc_blsp1_qup4_spi_apps_clk",
2013+ .parent_data = &(const struct clk_parent_data){
2014+ .hw = &blsp1_qup4_spi_apps_clk_src.clkr.hw,
2015+ },
2016+ .num_parents = 1,
2017+ .flags = CLK_SET_RATE_PARENT,
2018+ .ops = &clk_branch2_ops,
2019+ },
2020+ },
2021+};
2022+
2023+static struct clk_branch gcc_blsp1_qup5_i2c_apps_clk = {
2024+ .halt_reg = 0x06020,
2025+ .clkr = {
2026+ .enable_reg = 0x06020,
2027+ .enable_mask = BIT(0),
2028+ .hw.init = &(struct clk_init_data){
2029+ .name = "gcc_blsp1_qup5_i2c_apps_clk",
2030+ .parent_data = &(const struct clk_parent_data){
2031+ .hw = &blsp1_qup5_i2c_apps_clk_src.clkr.hw,
2032+ },
2033+ .num_parents = 1,
2034+ .flags = CLK_SET_RATE_PARENT,
2035+ .ops = &clk_branch2_ops,
2036+ },
2037+ },
2038+};
2039+
2040+static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = {
2041+ .halt_reg = 0x0601c,
2042+ .clkr = {
2043+ .enable_reg = 0x0601c,
2044+ .enable_mask = BIT(0),
2045+ .hw.init = &(struct clk_init_data){
2046+ .name = "gcc_blsp1_qup5_spi_apps_clk",
2047+ .parent_data = &(const struct clk_parent_data){
2048+ .hw = &blsp1_qup5_spi_apps_clk_src.clkr.hw,
2049+ },
2050+ .num_parents = 1,
2051+ .flags = CLK_SET_RATE_PARENT,
2052+ .ops = &clk_branch2_ops,
2053+ },
2054+ },
2055+};
2056+
2057+static struct clk_branch gcc_blsp1_qup6_i2c_apps_clk = {
2058+ .halt_reg = 0x07020,
2059+ .clkr = {
2060+ .enable_reg = 0x07020,
2061+ .enable_mask = BIT(0),
2062+ .hw.init = &(struct clk_init_data){
2063+ .name = "gcc_blsp1_qup6_i2c_apps_clk",
2064+ .parent_data = &(const struct clk_parent_data){
2065+ .hw = &blsp1_qup6_i2c_apps_clk_src.clkr.hw,
2066+ },
2067+ .num_parents = 1,
2068+ .flags = CLK_SET_RATE_PARENT,
2069+ .ops = &clk_branch2_ops,
2070+ },
2071+ },
2072+};
2073+
2074+static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = {
2075+ .halt_reg = 0x0701c,
2076+ .clkr = {
2077+ .enable_reg = 0x0701c,
2078+ .enable_mask = BIT(0),
2079+ .hw.init = &(struct clk_init_data){
2080+ .name = "gcc_blsp1_qup6_spi_apps_clk",
2081+ .parent_data = &(const struct clk_parent_data){
2082+ .hw = &blsp1_qup6_spi_apps_clk_src.clkr.hw,
2083+ },
2084+ .num_parents = 1,
2085+ .flags = CLK_SET_RATE_PARENT,
2086+ .ops = &clk_branch2_ops,
2087+ },
2088+ },
2089+};
2090+
2091+static struct clk_branch gcc_blsp1_uart1_apps_clk = {
2092+ .halt_reg = 0x0203c,
2093+ .clkr = {
2094+ .enable_reg = 0x0203c,
2095+ .enable_mask = BIT(0),
2096+ .hw.init = &(struct clk_init_data){
2097+ .name = "gcc_blsp1_uart1_apps_clk",
2098+ .parent_data = &(const struct clk_parent_data){
2099+ .hw = &blsp1_uart1_apps_clk_src.clkr.hw,
2100+ },
2101+ .num_parents = 1,
2102+ .flags = CLK_SET_RATE_PARENT,
2103+ .ops = &clk_branch2_ops,
2104+ },
2105+ },
2106+};
2107+
2108+static struct clk_branch gcc_blsp1_uart2_apps_clk = {
2109+ .halt_reg = 0x0302c,
2110+ .clkr = {
2111+ .enable_reg = 0x0302c,
2112+ .enable_mask = BIT(0),
2113+ .hw.init = &(struct clk_init_data){
2114+ .name = "gcc_blsp1_uart2_apps_clk",
2115+ .parent_data = &(const struct clk_parent_data){
2116+ .hw = &blsp1_uart2_apps_clk_src.clkr.hw,
2117+ },
2118+ .num_parents = 1,
2119+ .flags = CLK_SET_RATE_PARENT,
2120+ .ops = &clk_branch2_ops,
2121+ },
2122+ },
2123+};
2124+
2125+static struct clk_branch gcc_boot_rom_ahb_clk = {
2126+ .halt_reg = 0x1300c,
2127+ .halt_check = BRANCH_HALT_VOTED,
2128+ .clkr = {
2129+ .enable_reg = 0x45004,
2130+ .enable_mask = BIT(7),
2131+ .hw.init = &(struct clk_init_data){
2132+ .name = "gcc_boot_rom_ahb_clk",
2133+ .parent_data = &(const struct clk_parent_data){
2134+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
2135+ },
2136+ .num_parents = 1,
2137+ .ops = &clk_branch2_ops,
2138+ },
2139+ },
2140+};
2141+
2142+static struct clk_branch gcc_camss_cci_ahb_clk = {
2143+ .halt_reg = 0x5101c,
2144+ .clkr = {
2145+ .enable_reg = 0x5101c,
2146+ .enable_mask = BIT(0),
2147+ .hw.init = &(struct clk_init_data){
2148+ .name = "gcc_camss_cci_ahb_clk",
2149+ .parent_data = &(const struct clk_parent_data){
2150+ .hw = &camss_ahb_clk_src.clkr.hw,
2151+ },
2152+ .num_parents = 1,
2153+ .flags = CLK_SET_RATE_PARENT,
2154+ .ops = &clk_branch2_ops,
2155+ },
2156+ },
2157+};
2158+
2159+static struct clk_branch gcc_camss_cci_clk = {
2160+ .halt_reg = 0x51018,
2161+ .clkr = {
2162+ .enable_reg = 0x51018,
2163+ .enable_mask = BIT(0),
2164+ .hw.init = &(struct clk_init_data){
2165+ .name = "gcc_camss_cci_clk",
2166+ .parent_data = &(const struct clk_parent_data){
2167+ .hw = &cci_clk_src.clkr.hw,
2168+ },
2169+ .num_parents = 1,
2170+ .flags = CLK_SET_RATE_PARENT,
2171+ .ops = &clk_branch2_ops,
2172+ },
2173+ },
2174+};
2175+
2176+static struct clk_branch gcc_camss_csi0_ahb_clk = {
2177+ .halt_reg = 0x4e040,
2178+ .clkr = {
2179+ .enable_reg = 0x4e040,
2180+ .enable_mask = BIT(0),
2181+ .hw.init = &(struct clk_init_data){
2182+ .name = "gcc_camss_csi0_ahb_clk",
2183+ .parent_data = &(const struct clk_parent_data){
2184+ .hw = &camss_ahb_clk_src.clkr.hw,
2185+ },
2186+ .num_parents = 1,
2187+ .flags = CLK_SET_RATE_PARENT,
2188+ .ops = &clk_branch2_ops,
2189+ },
2190+ },
2191+};
2192+
2193+static struct clk_branch gcc_camss_csi0_clk = {
2194+ .halt_reg = 0x4e03c,
2195+ .clkr = {
2196+ .enable_reg = 0x4e03c,
2197+ .enable_mask = BIT(0),
2198+ .hw.init = &(struct clk_init_data){
2199+ .name = "gcc_camss_csi0_clk",
2200+ .parent_data = &(const struct clk_parent_data){
2201+ .hw = &csi0_clk_src.clkr.hw,
2202+ },
2203+ .num_parents = 1,
2204+ .flags = CLK_SET_RATE_PARENT,
2205+ .ops = &clk_branch2_ops,
2206+ },
2207+ },
2208+};
2209+
2210+static struct clk_branch gcc_camss_csi0phy_clk = {
2211+ .halt_reg = 0x4e048,
2212+ .clkr = {
2213+ .enable_reg = 0x4e048,
2214+ .enable_mask = BIT(0),
2215+ .hw.init = &(struct clk_init_data){
2216+ .name = "gcc_camss_csi0phy_clk",
2217+ .parent_data = &(const struct clk_parent_data){
2218+ .hw = &csi0_clk_src.clkr.hw,
2219+ },
2220+ .num_parents = 1,
2221+ .flags = CLK_SET_RATE_PARENT,
2222+ .ops = &clk_branch2_ops,
2223+ },
2224+ },
2225+};
2226+
2227+static struct clk_branch gcc_camss_csi0pix_clk = {
2228+ .halt_reg = 0x4e058,
2229+ .clkr = {
2230+ .enable_reg = 0x4e058,
2231+ .enable_mask = BIT(0),
2232+ .hw.init = &(struct clk_init_data){
2233+ .name = "gcc_camss_csi0pix_clk",
2234+ .parent_data = &(const struct clk_parent_data){
2235+ .hw = &csi0_clk_src.clkr.hw,
2236+ },
2237+ .num_parents = 1,
2238+ .flags = CLK_SET_RATE_PARENT,
2239+ .ops = &clk_branch2_ops,
2240+ },
2241+ },
2242+};
2243+
2244+static struct clk_branch gcc_camss_csi0rdi_clk = {
2245+ .halt_reg = 0x4e050,
2246+ .clkr = {
2247+ .enable_reg = 0x4e050,
2248+ .enable_mask = BIT(0),
2249+ .hw.init = &(struct clk_init_data){
2250+ .name = "gcc_camss_csi0rdi_clk",
2251+ .parent_data = &(const struct clk_parent_data){
2252+ .hw = &csi0_clk_src.clkr.hw,
2253+ },
2254+ .num_parents = 1,
2255+ .flags = CLK_SET_RATE_PARENT,
2256+ .ops = &clk_branch2_ops,
2257+ },
2258+ },
2259+};
2260+
2261+static struct clk_branch gcc_camss_csi1_ahb_clk = {
2262+ .halt_reg = 0x4f040,
2263+ .clkr = {
2264+ .enable_reg = 0x4f040,
2265+ .enable_mask = BIT(0),
2266+ .hw.init = &(struct clk_init_data){
2267+ .name = "gcc_camss_csi1_ahb_clk",
2268+ .parent_data = &(const struct clk_parent_data){
2269+ .hw = &camss_ahb_clk_src.clkr.hw,
2270+ },
2271+ .num_parents = 1,
2272+ .flags = CLK_SET_RATE_PARENT,
2273+ .ops = &clk_branch2_ops,
2274+ },
2275+ },
2276+};
2277+
2278+static struct clk_branch gcc_camss_csi1_clk = {
2279+ .halt_reg = 0x4f03c,
2280+ .clkr = {
2281+ .enable_reg = 0x4f03c,
2282+ .enable_mask = BIT(0),
2283+ .hw.init = &(struct clk_init_data){
2284+ .name = "gcc_camss_csi1_clk",
2285+ .parent_data = &(const struct clk_parent_data){
2286+ .hw = &csi1_clk_src.clkr.hw,
2287+ },
2288+ .num_parents = 1,
2289+ .flags = CLK_SET_RATE_PARENT,
2290+ .ops = &clk_branch2_ops,
2291+ },
2292+ },
2293+};
2294+
2295+static struct clk_branch gcc_camss_csi1phy_clk = {
2296+ .halt_reg = 0x4f048,
2297+ .clkr = {
2298+ .enable_reg = 0x4f048,
2299+ .enable_mask = BIT(0),
2300+ .hw.init = &(struct clk_init_data){
2301+ .name = "gcc_camss_csi1phy_clk",
2302+ .parent_data = &(const struct clk_parent_data){
2303+ .hw = &csi1_clk_src.clkr.hw,
2304+ },
2305+ .num_parents = 1,
2306+ .flags = CLK_SET_RATE_PARENT,
2307+ .ops = &clk_branch2_ops,
2308+ },
2309+ },
2310+};
2311+
2312+static struct clk_branch gcc_camss_csi1pix_clk = {
2313+ .halt_reg = 0x4f058,
2314+ .clkr = {
2315+ .enable_reg = 0x4f058,
2316+ .enable_mask = BIT(0),
2317+ .hw.init = &(struct clk_init_data){
2318+ .name = "gcc_camss_csi1pix_clk",
2319+ .parent_data = &(const struct clk_parent_data){
2320+ .hw = &csi1_clk_src.clkr.hw,
2321+ },
2322+ .num_parents = 1,
2323+ .flags = CLK_SET_RATE_PARENT,
2324+ .ops = &clk_branch2_ops,
2325+ },
2326+ },
2327+};
2328+
2329+static struct clk_branch gcc_camss_csi1rdi_clk = {
2330+ .halt_reg = 0x4f050,
2331+ .clkr = {
2332+ .enable_reg = 0x4f050,
2333+ .enable_mask = BIT(0),
2334+ .hw.init = &(struct clk_init_data){
2335+ .name = "gcc_camss_csi1rdi_clk",
2336+ .parent_data = &(const struct clk_parent_data){
2337+ .hw = &csi1_clk_src.clkr.hw,
2338+ },
2339+ .num_parents = 1,
2340+ .flags = CLK_SET_RATE_PARENT,
2341+ .ops = &clk_branch2_ops,
2342+ },
2343+ },
2344+};
2345+
2346+static struct clk_branch gcc_camss_csi_vfe0_clk = {
2347+ .halt_reg = 0x58050,
2348+ .clkr = {
2349+ .enable_reg = 0x58050,
2350+ .enable_mask = BIT(0),
2351+ .hw.init = &(struct clk_init_data){
2352+ .name = "gcc_camss_csi_vfe0_clk",
2353+ .parent_data = &(const struct clk_parent_data){
2354+ .hw = &vfe0_clk_src.clkr.hw,
2355+ },
2356+ .num_parents = 1,
2357+ .flags = CLK_SET_RATE_PARENT,
2358+ .ops = &clk_branch2_ops,
2359+ },
2360+ },
2361+};
2362+
2363+static struct clk_branch gcc_camss_gp0_clk = {
2364+ .halt_reg = 0x54018,
2365+ .clkr = {
2366+ .enable_reg = 0x54018,
2367+ .enable_mask = BIT(0),
2368+ .hw.init = &(struct clk_init_data){
2369+ .name = "gcc_camss_gp0_clk",
2370+ .parent_data = &(const struct clk_parent_data){
2371+ .hw = &camss_gp0_clk_src.clkr.hw,
2372+ },
2373+ .num_parents = 1,
2374+ .flags = CLK_SET_RATE_PARENT,
2375+ .ops = &clk_branch2_ops,
2376+ },
2377+ },
2378+};
2379+
2380+static struct clk_branch gcc_camss_gp1_clk = {
2381+ .halt_reg = 0x55018,
2382+ .clkr = {
2383+ .enable_reg = 0x55018,
2384+ .enable_mask = BIT(0),
2385+ .hw.init = &(struct clk_init_data){
2386+ .name = "gcc_camss_gp1_clk",
2387+ .parent_data = &(const struct clk_parent_data){
2388+ .hw = &camss_gp1_clk_src.clkr.hw,
2389+ },
2390+ .num_parents = 1,
2391+ .flags = CLK_SET_RATE_PARENT,
2392+ .ops = &clk_branch2_ops,
2393+ },
2394+ },
2395+};
2396+
2397+static struct clk_branch gcc_camss_ispif_ahb_clk = {
2398+ .halt_reg = 0x50004,
2399+ .clkr = {
2400+ .enable_reg = 0x50004,
2401+ .enable_mask = BIT(0),
2402+ .hw.init = &(struct clk_init_data){
2403+ .name = "gcc_camss_ispif_ahb_clk",
2404+ .parent_data = &(const struct clk_parent_data){
2405+ .hw = &camss_ahb_clk_src.clkr.hw,
2406+ },
2407+ .num_parents = 1,
2408+ .flags = CLK_SET_RATE_PARENT,
2409+ .ops = &clk_branch2_ops,
2410+ },
2411+ },
2412+};
2413+
2414+static struct clk_branch gcc_camss_jpeg0_clk = {
2415+ .halt_reg = 0x57020,
2416+ .clkr = {
2417+ .enable_reg = 0x57020,
2418+ .enable_mask = BIT(0),
2419+ .hw.init = &(struct clk_init_data){
2420+ .name = "gcc_camss_jpeg0_clk",
2421+ .parent_data = &(const struct clk_parent_data){
2422+ .hw = &jpeg0_clk_src.clkr.hw,
2423+ },
2424+ .num_parents = 1,
2425+ .flags = CLK_SET_RATE_PARENT,
2426+ .ops = &clk_branch2_ops,
2427+ },
2428+ },
2429+};
2430+
2431+static struct clk_branch gcc_camss_jpeg_ahb_clk = {
2432+ .halt_reg = 0x57024,
2433+ .clkr = {
2434+ .enable_reg = 0x57024,
2435+ .enable_mask = BIT(0),
2436+ .hw.init = &(struct clk_init_data){
2437+ .name = "gcc_camss_jpeg_ahb_clk",
2438+ .parent_data = &(const struct clk_parent_data){
2439+ .hw = &camss_ahb_clk_src.clkr.hw,
2440+ },
2441+ .num_parents = 1,
2442+ .flags = CLK_SET_RATE_PARENT,
2443+ .ops = &clk_branch2_ops,
2444+ },
2445+ },
2446+};
2447+
2448+static struct clk_branch gcc_camss_jpeg_axi_clk = {
2449+ .halt_reg = 0x57028,
2450+ .clkr = {
2451+ .enable_reg = 0x57028,
2452+ .enable_mask = BIT(0),
2453+ .hw.init = &(struct clk_init_data){
2454+ .name = "gcc_camss_jpeg_axi_clk",
2455+ .parent_data = &(const struct clk_parent_data){
2456+ .hw = &system_noc_bfdcd_clk_src.clkr.hw,
2457+ },
2458+ .num_parents = 1,
2459+ .flags = CLK_SET_RATE_PARENT,
2460+ .ops = &clk_branch2_ops,
2461+ },
2462+ },
2463+};
2464+
2465+static struct clk_branch gcc_camss_mclk0_clk = {
2466+ .halt_reg = 0x52018,
2467+ .clkr = {
2468+ .enable_reg = 0x52018,
2469+ .enable_mask = BIT(0),
2470+ .hw.init = &(struct clk_init_data){
2471+ .name = "gcc_camss_mclk0_clk",
2472+ .parent_data = &(const struct clk_parent_data){
2473+ .hw = &mclk0_clk_src.clkr.hw,
2474+ },
2475+ .num_parents = 1,
2476+ .flags = CLK_SET_RATE_PARENT,
2477+ .ops = &clk_branch2_ops,
2478+ },
2479+ },
2480+};
2481+
2482+static struct clk_branch gcc_camss_mclk1_clk = {
2483+ .halt_reg = 0x53018,
2484+ .clkr = {
2485+ .enable_reg = 0x53018,
2486+ .enable_mask = BIT(0),
2487+ .hw.init = &(struct clk_init_data){
2488+ .name = "gcc_camss_mclk1_clk",
2489+ .parent_data = &(const struct clk_parent_data){
2490+ .hw = &mclk1_clk_src.clkr.hw,
2491+ },
2492+ .num_parents = 1,
2493+ .flags = CLK_SET_RATE_PARENT,
2494+ .ops = &clk_branch2_ops,
2495+ },
2496+ },
2497+};
2498+
2499+static struct clk_branch gcc_camss_micro_ahb_clk = {
2500+ .halt_reg = 0x5600c,
2501+ .clkr = {
2502+ .enable_reg = 0x5600c,
2503+ .enable_mask = BIT(0),
2504+ .hw.init = &(struct clk_init_data){
2505+ .name = "gcc_camss_micro_ahb_clk",
2506+ .parent_data = &(const struct clk_parent_data){
2507+ .hw = &camss_ahb_clk_src.clkr.hw,
2508+ },
2509+ .num_parents = 1,
2510+ .flags = CLK_SET_RATE_PARENT,
2511+ .ops = &clk_branch2_ops,
2512+ },
2513+ },
2514+};
2515+
2516+static struct clk_branch gcc_camss_csi0phytimer_clk = {
2517+ .halt_reg = 0x4e01c,
2518+ .clkr = {
2519+ .enable_reg = 0x4e01c,
2520+ .enable_mask = BIT(0),
2521+ .hw.init = &(struct clk_init_data){
2522+ .name = "gcc_camss_csi0phytimer_clk",
2523+ .parent_data = &(const struct clk_parent_data){
2524+ .hw = &csi0phytimer_clk_src.clkr.hw,
2525+ },
2526+ .num_parents = 1,
2527+ .flags = CLK_SET_RATE_PARENT,
2528+ .ops = &clk_branch2_ops,
2529+ },
2530+ },
2531+};
2532+
2533+static struct clk_branch gcc_camss_csi1phytimer_clk = {
2534+ .halt_reg = 0x4f01c,
2535+ .clkr = {
2536+ .enable_reg = 0x4f01c,
2537+ .enable_mask = BIT(0),
2538+ .hw.init = &(struct clk_init_data){
2539+ .name = "gcc_camss_csi1phytimer_clk",
2540+ .parent_data = &(const struct clk_parent_data){
2541+ .hw = &csi1phytimer_clk_src.clkr.hw,
2542+ },
2543+ .num_parents = 1,
2544+ .flags = CLK_SET_RATE_PARENT,
2545+ .ops = &clk_branch2_ops,
2546+ },
2547+ },
2548+};
2549+
2550+static struct clk_branch gcc_camss_ahb_clk = {
2551+ .halt_reg = 0x5a014,
2552+ .clkr = {
2553+ .enable_reg = 0x5a014,
2554+ .enable_mask = BIT(0),
2555+ .hw.init = &(struct clk_init_data){
2556+ .name = "gcc_camss_ahb_clk",
2557+ .parent_data = &(const struct clk_parent_data){
2558+ .hw = &camss_ahb_clk_src.clkr.hw,
2559+ },
2560+ .num_parents = 1,
2561+ .flags = CLK_SET_RATE_PARENT,
2562+ .ops = &clk_branch2_ops,
2563+ },
2564+ },
2565+};
2566+
2567+static struct clk_branch gcc_camss_top_ahb_clk = {
2568+ .halt_reg = 0x56004,
2569+ .clkr = {
2570+ .enable_reg = 0x56004,
2571+ .enable_mask = BIT(0),
2572+ .hw.init = &(struct clk_init_data){
2573+ .name = "gcc_camss_top_ahb_clk",
2574+ .parent_data = &(const struct clk_parent_data){
2575+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
2576+ },
2577+ .num_parents = 1,
2578+ .flags = CLK_SET_RATE_PARENT,
2579+ .ops = &clk_branch2_ops,
2580+ },
2581+ },
2582+};
2583+
2584+static struct clk_branch gcc_camss_cpp_ahb_clk = {
2585+ .halt_reg = 0x58040,
2586+ .clkr = {
2587+ .enable_reg = 0x58040,
2588+ .enable_mask = BIT(0),
2589+ .hw.init = &(struct clk_init_data){
2590+ .name = "gcc_camss_cpp_ahb_clk",
2591+ .parent_data = &(const struct clk_parent_data){
2592+ .hw = &camss_ahb_clk_src.clkr.hw,
2593+ },
2594+ .num_parents = 1,
2595+ .flags = CLK_SET_RATE_PARENT,
2596+ .ops = &clk_branch2_ops,
2597+ },
2598+ },
2599+};
2600+
2601+static struct clk_branch gcc_camss_cpp_clk = {
2602+ .halt_reg = 0x5803c,
2603+ .clkr = {
2604+ .enable_reg = 0x5803c,
2605+ .enable_mask = BIT(0),
2606+ .hw.init = &(struct clk_init_data){
2607+ .name = "gcc_camss_cpp_clk",
2608+ .parent_data = &(const struct clk_parent_data){
2609+ .hw = &cpp_clk_src.clkr.hw,
2610+ },
2611+ .num_parents = 1,
2612+ .flags = CLK_SET_RATE_PARENT,
2613+ .ops = &clk_branch2_ops,
2614+ },
2615+ },
2616+};
2617+
2618+static struct clk_branch gcc_camss_vfe0_clk = {
2619+ .halt_reg = 0x58038,
2620+ .clkr = {
2621+ .enable_reg = 0x58038,
2622+ .enable_mask = BIT(0),
2623+ .hw.init = &(struct clk_init_data){
2624+ .name = "gcc_camss_vfe0_clk",
2625+ .parent_data = &(const struct clk_parent_data){
2626+ .hw = &vfe0_clk_src.clkr.hw,
2627+ },
2628+ .num_parents = 1,
2629+ .flags = CLK_SET_RATE_PARENT,
2630+ .ops = &clk_branch2_ops,
2631+ },
2632+ },
2633+};
2634+
2635+static struct clk_branch gcc_camss_vfe_ahb_clk = {
2636+ .halt_reg = 0x58044,
2637+ .clkr = {
2638+ .enable_reg = 0x58044,
2639+ .enable_mask = BIT(0),
2640+ .hw.init = &(struct clk_init_data){
2641+ .name = "gcc_camss_vfe_ahb_clk",
2642+ .parent_data = &(const struct clk_parent_data){
2643+ .hw = &camss_ahb_clk_src.clkr.hw,
2644+ },
2645+ .num_parents = 1,
2646+ .flags = CLK_SET_RATE_PARENT,
2647+ .ops = &clk_branch2_ops,
2648+ },
2649+ },
2650+};
2651+
2652+static struct clk_branch gcc_camss_vfe_axi_clk = {
2653+ .halt_reg = 0x58048,
2654+ .clkr = {
2655+ .enable_reg = 0x58048,
2656+ .enable_mask = BIT(0),
2657+ .hw.init = &(struct clk_init_data){
2658+ .name = "gcc_camss_vfe_axi_clk",
2659+ .parent_data = &(const struct clk_parent_data){
2660+ .hw = &system_noc_bfdcd_clk_src.clkr.hw,
2661+ },
2662+ .num_parents = 1,
2663+ .flags = CLK_SET_RATE_PARENT,
2664+ .ops = &clk_branch2_ops,
2665+ },
2666+ },
2667+};
2668+
2669+static struct clk_branch gcc_crypto_ahb_clk = {
2670+ .halt_reg = 0x16024,
2671+ .halt_check = BRANCH_HALT_VOTED,
2672+ .clkr = {
2673+ .enable_reg = 0x45004,
2674+ .enable_mask = BIT(0),
2675+ .hw.init = &(struct clk_init_data){
2676+ .name = "gcc_crypto_ahb_clk",
2677+ .parent_data = &(const struct clk_parent_data){
2678+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
2679+ },
2680+ .num_parents = 1,
2681+ .flags = CLK_SET_RATE_PARENT,
2682+ .ops = &clk_branch2_ops,
2683+ },
2684+ },
2685+};
2686+
2687+static struct clk_branch gcc_crypto_axi_clk = {
2688+ .halt_reg = 0x16020,
2689+ .halt_check = BRANCH_HALT_VOTED,
2690+ .clkr = {
2691+ .enable_reg = 0x45004,
2692+ .enable_mask = BIT(1),
2693+ .hw.init = &(struct clk_init_data){
2694+ .name = "gcc_crypto_axi_clk",
2695+ .parent_data = &(const struct clk_parent_data){
2696+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
2697+ },
2698+ .num_parents = 1,
2699+ .flags = CLK_SET_RATE_PARENT,
2700+ .ops = &clk_branch2_ops,
2701+ },
2702+ },
2703+};
2704+
2705+static struct clk_branch gcc_crypto_clk = {
2706+ .halt_reg = 0x1601c,
2707+ .halt_check = BRANCH_HALT_VOTED,
2708+ .clkr = {
2709+ .enable_reg = 0x45004,
2710+ .enable_mask = BIT(2),
2711+ .hw.init = &(struct clk_init_data){
2712+ .name = "gcc_crypto_clk",
2713+ .parent_data = &(const struct clk_parent_data){
2714+ .hw = &crypto_clk_src.clkr.hw,
2715+ },
2716+ .num_parents = 1,
2717+ .flags = CLK_SET_RATE_PARENT,
2718+ .ops = &clk_branch2_ops,
2719+ },
2720+ },
2721+};
2722+
2723+static struct clk_branch gcc_oxili_gmem_clk = {
2724+ .halt_reg = 0x59024,
2725+ .clkr = {
2726+ .enable_reg = 0x59024,
2727+ .enable_mask = BIT(0),
2728+ .hw.init = &(struct clk_init_data){
2729+ .name = "gcc_oxili_gmem_clk",
2730+ .parent_data = &(const struct clk_parent_data){
2731+ .hw = &gfx3d_clk_src.clkr.hw,
2732+ },
2733+ .num_parents = 1,
2734+ .flags = CLK_SET_RATE_PARENT,
2735+ .ops = &clk_branch2_ops,
2736+ },
2737+ },
2738+};
2739+
2740+static struct clk_branch gcc_gp1_clk = {
2741+ .halt_reg = 0x08000,
2742+ .clkr = {
2743+ .enable_reg = 0x08000,
2744+ .enable_mask = BIT(0),
2745+ .hw.init = &(struct clk_init_data){
2746+ .name = "gcc_gp1_clk",
2747+ .parent_data = &(const struct clk_parent_data){
2748+ .hw = &gp1_clk_src.clkr.hw,
2749+ },
2750+ .num_parents = 1,
2751+ .flags = CLK_SET_RATE_PARENT,
2752+ .ops = &clk_branch2_ops,
2753+ },
2754+ },
2755+};
2756+
2757+static struct clk_branch gcc_gp2_clk = {
2758+ .halt_reg = 0x09000,
2759+ .clkr = {
2760+ .enable_reg = 0x09000,
2761+ .enable_mask = BIT(0),
2762+ .hw.init = &(struct clk_init_data){
2763+ .name = "gcc_gp2_clk",
2764+ .parent_data = &(const struct clk_parent_data){
2765+ .hw = &gp2_clk_src.clkr.hw,
2766+ },
2767+ .num_parents = 1,
2768+ .flags = CLK_SET_RATE_PARENT,
2769+ .ops = &clk_branch2_ops,
2770+ },
2771+ },
2772+};
2773+
2774+static struct clk_branch gcc_gp3_clk = {
2775+ .halt_reg = 0x0a000,
2776+ .clkr = {
2777+ .enable_reg = 0x0a000,
2778+ .enable_mask = BIT(0),
2779+ .hw.init = &(struct clk_init_data){
2780+ .name = "gcc_gp3_clk",
2781+ .parent_data = &(const struct clk_parent_data){
2782+ .hw = &gp3_clk_src.clkr.hw,
2783+ },
2784+ .num_parents = 1,
2785+ .flags = CLK_SET_RATE_PARENT,
2786+ .ops = &clk_branch2_ops,
2787+ },
2788+ },
2789+};
2790+
2791+static struct clk_branch gcc_mdss_ahb_clk = {
2792+ .halt_reg = 0x4d07c,
2793+ .clkr = {
2794+ .enable_reg = 0x4d07c,
2795+ .enable_mask = BIT(0),
2796+ .hw.init = &(struct clk_init_data){
2797+ .name = "gcc_mdss_ahb_clk",
2798+ .parent_data = &(const struct clk_parent_data){
2799+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
2800+ },
2801+ .num_parents = 1,
2802+ .flags = CLK_SET_RATE_PARENT,
2803+ .ops = &clk_branch2_ops,
2804+ },
2805+ },
2806+};
2807+
2808+static struct clk_branch gcc_mdss_axi_clk = {
2809+ .halt_reg = 0x4d080,
2810+ .clkr = {
2811+ .enable_reg = 0x4d080,
2812+ .enable_mask = BIT(0),
2813+ .hw.init = &(struct clk_init_data){
2814+ .name = "gcc_mdss_axi_clk",
2815+ .parent_data = &(const struct clk_parent_data){
2816+ .hw = &system_noc_bfdcd_clk_src.clkr.hw,
2817+ },
2818+ .num_parents = 1,
2819+ .flags = CLK_SET_RATE_PARENT,
2820+ .ops = &clk_branch2_ops,
2821+ },
2822+ },
2823+};
2824+
2825+static struct clk_branch gcc_mdss_byte0_clk = {
2826+ .halt_reg = 0x4d094,
2827+ .clkr = {
2828+ .enable_reg = 0x4d094,
2829+ .enable_mask = BIT(0),
2830+ .hw.init = &(struct clk_init_data){
2831+ .name = "gcc_mdss_byte0_clk",
2832+ .parent_data = &(const struct clk_parent_data){
2833+ .hw = &byte0_clk_src.clkr.hw,
2834+ },
2835+ .num_parents = 1,
2836+ .flags = CLK_SET_RATE_PARENT,
2837+ .ops = &clk_branch2_ops,
2838+ },
2839+ },
2840+};
2841+
2842+static struct clk_branch gcc_mdss_byte1_clk = {
2843+ .halt_reg = 0x4d0a0,
2844+ .clkr = {
2845+ .enable_reg = 0x4d0a0,
2846+ .enable_mask = BIT(0),
2847+ .hw.init = &(struct clk_init_data){
2848+ .name = "gcc_mdss_byte1_clk",
2849+ .parent_data = &(const struct clk_parent_data){
2850+ .hw = &byte1_clk_src.clkr.hw,
2851+ },
2852+ .num_parents = 1,
2853+ .flags = CLK_SET_RATE_PARENT,
2854+ .ops = &clk_branch2_ops,
2855+ },
2856+ },
2857+};
2858+
2859+static struct clk_branch gcc_mdss_esc0_clk = {
2860+ .halt_reg = 0x4d098,
2861+ .clkr = {
2862+ .enable_reg = 0x4d098,
2863+ .enable_mask = BIT(0),
2864+ .hw.init = &(struct clk_init_data){
2865+ .name = "gcc_mdss_esc0_clk",
2866+ .parent_data = &(const struct clk_parent_data){
2867+ .hw = &esc0_clk_src.clkr.hw,
2868+ },
2869+ .num_parents = 1,
2870+ .flags = CLK_SET_RATE_PARENT,
2871+ .ops = &clk_branch2_ops,
2872+ },
2873+ },
2874+};
2875+
2876+static struct clk_branch gcc_mdss_esc1_clk = {
2877+ .halt_reg = 0x4d09c,
2878+ .clkr = {
2879+ .enable_reg = 0x4d09c,
2880+ .enable_mask = BIT(0),
2881+ .hw.init = &(struct clk_init_data){
2882+ .name = "gcc_mdss_esc1_clk",
2883+ .parent_data = &(const struct clk_parent_data){
2884+ .hw = &esc1_clk_src.clkr.hw,
2885+ },
2886+ .num_parents = 1,
2887+ .flags = CLK_SET_RATE_PARENT,
2888+ .ops = &clk_branch2_ops,
2889+ },
2890+ },
2891+};
2892+
2893+static struct clk_branch gcc_mdss_mdp_clk = {
2894+ .halt_reg = 0x4D088,
2895+ .clkr = {
2896+ .enable_reg = 0x4D088,
2897+ .enable_mask = BIT(0),
2898+ .hw.init = &(struct clk_init_data){
2899+ .name = "gcc_mdss_mdp_clk",
2900+ .parent_data = &(const struct clk_parent_data){
2901+ .hw = &mdp_clk_src.clkr.hw,
2902+ },
2903+ .num_parents = 1,
2904+ .flags = CLK_SET_RATE_PARENT,
2905+ .ops = &clk_branch2_ops,
2906+ },
2907+ },
2908+};
2909+
2910+static struct clk_branch gcc_mdss_pclk0_clk = {
2911+ .halt_reg = 0x4d084,
2912+ .clkr = {
2913+ .enable_reg = 0x4d084,
2914+ .enable_mask = BIT(0),
2915+ .hw.init = &(struct clk_init_data){
2916+ .name = "gcc_mdss_pclk0_clk",
2917+ .parent_data = &(const struct clk_parent_data){
2918+ .hw = &pclk0_clk_src.clkr.hw,
2919+ },
2920+ .num_parents = 1,
2921+ .flags = CLK_SET_RATE_PARENT,
2922+ .ops = &clk_branch2_ops,
2923+ },
2924+ },
2925+};
2926+
2927+static struct clk_branch gcc_mdss_pclk1_clk = {
2928+ .halt_reg = 0x4d0a4,
2929+ .clkr = {
2930+ .enable_reg = 0x4d0a4,
2931+ .enable_mask = BIT(0),
2932+ .hw.init = &(struct clk_init_data){
2933+ .name = "gcc_mdss_pclk1_clk",
2934+ .parent_data = &(const struct clk_parent_data){
2935+ .hw = &pclk1_clk_src.clkr.hw,
2936+ },
2937+ .num_parents = 1,
2938+ .flags = CLK_SET_RATE_PARENT,
2939+ .ops = &clk_branch2_ops,
2940+ },
2941+ },
2942+};
2943+
2944+static struct clk_branch gcc_mdss_vsync_clk = {
2945+ .halt_reg = 0x4d090,
2946+ .clkr = {
2947+ .enable_reg = 0x4d090,
2948+ .enable_mask = BIT(0),
2949+ .hw.init = &(struct clk_init_data){
2950+ .name = "gcc_mdss_vsync_clk",
2951+ .parent_data = &(const struct clk_parent_data){
2952+ .hw = &vsync_clk_src.clkr.hw,
2953+ },
2954+ .num_parents = 1,
2955+ .flags = CLK_SET_RATE_PARENT,
2956+ .ops = &clk_branch2_ops,
2957+ },
2958+ },
2959+};
2960+
2961+static struct clk_branch gcc_mss_cfg_ahb_clk = {
2962+ .halt_reg = 0x49000,
2963+ .clkr = {
2964+ .enable_reg = 0x49000,
2965+ .enable_mask = BIT(0),
2966+ .hw.init = &(struct clk_init_data){
2967+ .name = "gcc_mss_cfg_ahb_clk",
2968+ .parent_data = &(const struct clk_parent_data){
2969+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
2970+ },
2971+ .num_parents = 1,
2972+ .flags = CLK_SET_RATE_PARENT,
2973+ .ops = &clk_branch2_ops,
2974+ },
2975+ },
2976+};
2977+
2978+static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
2979+ .halt_reg = 0x49004,
2980+ .clkr = {
2981+ .enable_reg = 0x49004,
2982+ .enable_mask = BIT(0),
2983+ .hw.init = &(struct clk_init_data){
2984+ .name = "gcc_mss_q6_bimc_axi_clk",
2985+ .parent_data = &(const struct clk_parent_data){
2986+ .hw = &bimc_ddr_clk_src.clkr.hw,
2987+ },
2988+ .num_parents = 1,
2989+ .flags = CLK_SET_RATE_PARENT,
2990+ .ops = &clk_branch2_ops,
2991+ },
2992+ },
2993+};
2994+
2995+static struct clk_branch gcc_oxili_ahb_clk = {
2996+ .halt_reg = 0x59028,
2997+ .clkr = {
2998+ .enable_reg = 0x59028,
2999+ .enable_mask = BIT(0),
3000+ .hw.init = &(struct clk_init_data){
3001+ .name = "gcc_oxili_ahb_clk",
3002+ .parent_data = &(const struct clk_parent_data){
3003+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
3004+ },
3005+ .num_parents = 1,
3006+ .flags = CLK_SET_RATE_PARENT,
3007+ .ops = &clk_branch2_ops,
3008+ },
3009+ },
3010+};
3011+
3012+static struct clk_branch gcc_oxili_gfx3d_clk = {
3013+ .halt_reg = 0x59020,
3014+ .clkr = {
3015+ .enable_reg = 0x59020,
3016+ .enable_mask = BIT(0),
3017+ .hw.init = &(struct clk_init_data){
3018+ .name = "gcc_oxili_gfx3d_clk",
3019+ .parent_data = &(const struct clk_parent_data){
3020+ .hw = &gfx3d_clk_src.clkr.hw,
3021+ },
3022+ .num_parents = 1,
3023+ .flags = CLK_SET_RATE_PARENT,
3024+ .ops = &clk_branch2_ops,
3025+ },
3026+ },
3027+};
3028+
3029+static struct clk_branch gcc_pdm2_clk = {
3030+ .halt_reg = 0x4400c,
3031+ .clkr = {
3032+ .enable_reg = 0x4400c,
3033+ .enable_mask = BIT(0),
3034+ .hw.init = &(struct clk_init_data){
3035+ .name = "gcc_pdm2_clk",
3036+ .parent_data = &(const struct clk_parent_data){
3037+ .hw = &pdm2_clk_src.clkr.hw,
3038+ },
3039+ .num_parents = 1,
3040+ .flags = CLK_SET_RATE_PARENT,
3041+ .ops = &clk_branch2_ops,
3042+ },
3043+ },
3044+};
3045+
3046+static struct clk_branch gcc_pdm_ahb_clk = {
3047+ .halt_reg = 0x44004,
3048+ .clkr = {
3049+ .enable_reg = 0x44004,
3050+ .enable_mask = BIT(0),
3051+ .hw.init = &(struct clk_init_data){
3052+ .name = "gcc_pdm_ahb_clk",
3053+ .parent_data = &(const struct clk_parent_data){
3054+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
3055+ },
3056+ .num_parents = 1,
3057+ .flags = CLK_SET_RATE_PARENT,
3058+ .ops = &clk_branch2_ops,
3059+ },
3060+ },
3061+};
3062+
3063+static struct clk_branch gcc_prng_ahb_clk = {
3064+ .halt_reg = 0x13004,
3065+ .halt_check = BRANCH_HALT_VOTED,
3066+ .clkr = {
3067+ .enable_reg = 0x45004,
3068+ .enable_mask = BIT(8),
3069+ .hw.init = &(struct clk_init_data){
3070+ .name = "gcc_prng_ahb_clk",
3071+ .parent_data = &(const struct clk_parent_data){
3072+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
3073+ },
3074+ .num_parents = 1,
3075+ .ops = &clk_branch2_ops,
3076+ },
3077+ },
3078+};
3079+
3080+static struct clk_branch gcc_sdcc1_ahb_clk = {
3081+ .halt_reg = 0x4201c,
3082+ .clkr = {
3083+ .enable_reg = 0x4201c,
3084+ .enable_mask = BIT(0),
3085+ .hw.init = &(struct clk_init_data){
3086+ .name = "gcc_sdcc1_ahb_clk",
3087+ .parent_data = &(const struct clk_parent_data){
3088+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
3089+ },
3090+ .num_parents = 1,
3091+ .flags = CLK_SET_RATE_PARENT,
3092+ .ops = &clk_branch2_ops,
3093+ },
3094+ },
3095+};
3096+
3097+static struct clk_branch gcc_sdcc1_apps_clk = {
3098+ .halt_reg = 0x42018,
3099+ .clkr = {
3100+ .enable_reg = 0x42018,
3101+ .enable_mask = BIT(0),
3102+ .hw.init = &(struct clk_init_data){
3103+ .name = "gcc_sdcc1_apps_clk",
3104+ .parent_data = &(const struct clk_parent_data){
3105+ .hw = &sdcc1_apps_clk_src.clkr.hw,
3106+ },
3107+ .num_parents = 1,
3108+ .flags = CLK_SET_RATE_PARENT,
3109+ .ops = &clk_branch2_ops,
3110+ },
3111+ },
3112+};
3113+
3114+static struct clk_branch gcc_sdcc2_ahb_clk = {
3115+ .halt_reg = 0x4301c,
3116+ .clkr = {
3117+ .enable_reg = 0x4301c,
3118+ .enable_mask = BIT(0),
3119+ .hw.init = &(struct clk_init_data){
3120+ .name = "gcc_sdcc2_ahb_clk",
3121+ .parent_data = &(const struct clk_parent_data){
3122+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
3123+ },
3124+ .num_parents = 1,
3125+ .flags = CLK_SET_RATE_PARENT,
3126+ .ops = &clk_branch2_ops,
3127+ },
3128+ },
3129+};
3130+
3131+static struct clk_branch gcc_sdcc2_apps_clk = {
3132+ .halt_reg = 0x43018,
3133+ .clkr = {
3134+ .enable_reg = 0x43018,
3135+ .enable_mask = BIT(0),
3136+ .hw.init = &(struct clk_init_data){
3137+ .name = "gcc_sdcc2_apps_clk",
3138+ .parent_data = &(const struct clk_parent_data){
3139+ .hw = &sdcc2_apps_clk_src.clkr.hw,
3140+ },
3141+ .num_parents = 1,
3142+ .flags = CLK_SET_RATE_PARENT,
3143+ .ops = &clk_branch2_ops,
3144+ },
3145+ },
3146+};
3147+
3148+static struct clk_branch gcc_apss_tcu_clk = {
3149+ .halt_reg = 0x12018,
3150+ .halt_check = BRANCH_HALT_VOTED,
3151+ .clkr = {
3152+ .enable_reg = 0x4500c,
3153+ .enable_mask = BIT(1),
3154+ .hw.init = &(struct clk_init_data){
3155+ .name = "gcc_apss_tcu_clk",
3156+ .parent_data = &(const struct clk_parent_data){
3157+ .hw = &bimc_ddr_clk_src.clkr.hw,
3158+ },
3159+ .num_parents = 1,
3160+ .ops = &clk_branch2_ops,
3161+ },
3162+ },
3163+};
3164+
3165+static struct clk_branch gcc_gfx_tcu_clk = {
3166+ .halt_reg = 0x12020,
3167+ .halt_check = BRANCH_HALT_VOTED,
3168+ .clkr = {
3169+ .enable_reg = 0x4500c,
3170+ .enable_mask = BIT(2),
3171+ .hw.init = &(struct clk_init_data){
3172+ .name = "gcc_gfx_tcu_clk",
3173+ .parent_data = &(const struct clk_parent_data){
3174+ .hw = &bimc_ddr_clk_src.clkr.hw,
3175+ },
3176+ .num_parents = 1,
3177+ .ops = &clk_branch2_ops,
3178+ },
3179+ },
3180+};
3181+
3182+static struct clk_branch gcc_gfx_tbu_clk = {
3183+ .halt_reg = 0x12010,
3184+ .halt_check = BRANCH_HALT_VOTED,
3185+ .clkr = {
3186+ .enable_reg = 0x4500c,
3187+ .enable_mask = BIT(3),
3188+ .hw.init = &(struct clk_init_data){
3189+ .name = "gcc_gfx_tbu_clk",
3190+ .parent_data = &(const struct clk_parent_data){
3191+ .hw = &bimc_ddr_clk_src.clkr.hw,
3192+ },
3193+ .num_parents = 1,
3194+ .ops = &clk_branch2_ops,
3195+ },
3196+ },
3197+};
3198+
3199+static struct clk_branch gcc_mdp_tbu_clk = {
3200+ .halt_reg = 0x1201c,
3201+ .halt_check = BRANCH_HALT_VOTED,
3202+ .clkr = {
3203+ .enable_reg = 0x4500c,
3204+ .enable_mask = BIT(4),
3205+ .hw.init = &(struct clk_init_data){
3206+ .name = "gcc_mdp_tbu_clk",
3207+ .parent_data = &(const struct clk_parent_data){
3208+ .hw = &system_noc_bfdcd_clk_src.clkr.hw,
3209+ },
3210+ .num_parents = 1,
3211+ .flags = CLK_SET_RATE_PARENT,
3212+ .ops = &clk_branch2_ops,
3213+ },
3214+ },
3215+};
3216+
3217+static struct clk_branch gcc_venus_tbu_clk = {
3218+ .halt_reg = 0x12014,
3219+ .halt_check = BRANCH_HALT_VOTED,
3220+ .clkr = {
3221+ .enable_reg = 0x4500c,
3222+ .enable_mask = BIT(5),
3223+ .hw.init = &(struct clk_init_data){
3224+ .name = "gcc_venus_tbu_clk",
3225+ .parent_data = &(const struct clk_parent_data){
3226+ .hw = &system_noc_bfdcd_clk_src.clkr.hw,
3227+ },
3228+ .num_parents = 1,
3229+ .flags = CLK_SET_RATE_PARENT,
3230+ .ops = &clk_branch2_ops,
3231+ },
3232+ },
3233+};
3234+
3235+static struct clk_branch gcc_vfe_tbu_clk = {
3236+ .halt_reg = 0x1203c,
3237+ .halt_check = BRANCH_HALT_VOTED,
3238+ .clkr = {
3239+ .enable_reg = 0x4500c,
3240+ .enable_mask = BIT(9),
3241+ .hw.init = &(struct clk_init_data){
3242+ .name = "gcc_vfe_tbu_clk",
3243+ .parent_data = &(const struct clk_parent_data){
3244+ .hw = &system_noc_bfdcd_clk_src.clkr.hw,
3245+ },
3246+ .num_parents = 1,
3247+ .flags = CLK_SET_RATE_PARENT,
3248+ .ops = &clk_branch2_ops,
3249+ },
3250+ },
3251+};
3252+
3253+static struct clk_branch gcc_jpeg_tbu_clk = {
3254+ .halt_reg = 0x12034,
3255+ .halt_check = BRANCH_HALT_VOTED,
3256+ .clkr = {
3257+ .enable_reg = 0x4500c,
3258+ .enable_mask = BIT(10),
3259+ .hw.init = &(struct clk_init_data){
3260+ .name = "gcc_jpeg_tbu_clk",
3261+ .parent_data = &(const struct clk_parent_data){
3262+ .hw = &system_noc_bfdcd_clk_src.clkr.hw,
3263+ },
3264+ .num_parents = 1,
3265+ .flags = CLK_SET_RATE_PARENT,
3266+ .ops = &clk_branch2_ops,
3267+ },
3268+ },
3269+};
3270+
3271+static struct clk_branch gcc_smmu_cfg_clk = {
3272+ .halt_reg = 0x12038,
3273+ .halt_check = BRANCH_HALT_VOTED,
3274+ .clkr = {
3275+ .enable_reg = 0x4500c,
3276+ .enable_mask = BIT(12),
3277+ .hw.init = &(struct clk_init_data){
3278+ .name = "gcc_smmu_cfg_clk",
3279+ .parent_data = &(const struct clk_parent_data){
3280+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
3281+ },
3282+ .num_parents = 1,
3283+ .flags = CLK_SET_RATE_PARENT,
3284+ .ops = &clk_branch2_ops,
3285+ },
3286+ },
3287+};
3288+
3289+static struct clk_branch gcc_gtcu_ahb_clk = {
3290+ .halt_reg = 0x12044,
3291+ .halt_check = BRANCH_HALT_VOTED,
3292+ .clkr = {
3293+ .enable_reg = 0x4500c,
3294+ .enable_mask = BIT(13),
3295+ .hw.init = &(struct clk_init_data){
3296+ .name = "gcc_gtcu_ahb_clk",
3297+ .parent_data = &(const struct clk_parent_data){
3298+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
3299+ },
3300+ .num_parents = 1,
3301+ .flags = CLK_SET_RATE_PARENT,
3302+ .ops = &clk_branch2_ops,
3303+ },
3304+ },
3305+};
3306+
3307+static struct clk_branch gcc_cpp_tbu_clk = {
3308+ .halt_reg = 0x12040,
3309+ .halt_check = BRANCH_HALT_VOTED,
3310+ .clkr = {
3311+ .enable_reg = 0x4500c,
3312+ .enable_mask = BIT(14),
3313+ .hw.init = &(struct clk_init_data){
3314+ .name = "gcc_cpp_tbu_clk",
3315+ .parent_data = &(const struct clk_parent_data){
3316+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
3317+ },
3318+ .num_parents = 1,
3319+ .flags = CLK_SET_RATE_PARENT,
3320+ .ops = &clk_branch2_ops,
3321+ },
3322+ },
3323+};
3324+
3325+static struct clk_branch gcc_mdp_rt_tbu_clk = {
3326+ .halt_reg = 0x1201c,
3327+ .halt_check = BRANCH_HALT_VOTED,
3328+ .clkr = {
3329+ .enable_reg = 0x4500c,
3330+ .enable_mask = BIT(15),
3331+ .hw.init = &(struct clk_init_data){
3332+ .name = "gcc_mdp_rt_tbu_clk",
3333+ .parent_data = &(const struct clk_parent_data){
3334+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
3335+ },
3336+ .num_parents = 1,
3337+ .flags = CLK_SET_RATE_PARENT,
3338+ .ops = &clk_branch2_ops,
3339+ },
3340+ },
3341+};
3342+
3343+static struct clk_branch gcc_bimc_gfx_clk = {
3344+ .halt_reg = 0x31024,
3345+ .clkr = {
3346+ .enable_reg = 0x31024,
3347+ .enable_mask = BIT(0),
3348+ .hw.init = &(struct clk_init_data){
3349+ .name = "gcc_bimc_gfx_clk",
3350+ .parent_data = &(const struct clk_parent_data){
3351+ .hw = &bimc_gpu_clk_src.clkr.hw,
3352+ },
3353+ .num_parents = 1,
3354+ .flags = CLK_SET_RATE_PARENT,
3355+ .ops = &clk_branch2_ops,
3356+ },
3357+ },
3358+};
3359+
3360+static struct clk_branch gcc_bimc_gpu_clk = {
3361+ .halt_reg = 0x31040,
3362+ .clkr = {
3363+ .enable_reg = 0x31040,
3364+ .enable_mask = BIT(0),
3365+ .hw.init = &(struct clk_init_data){
3366+ .name = "gcc_bimc_gpu_clk",
3367+ .parent_data = &(const struct clk_parent_data){
3368+ .hw = &bimc_gpu_clk_src.clkr.hw,
3369+ },
3370+ .num_parents = 1,
3371+ .flags = CLK_SET_RATE_PARENT,
3372+ .ops = &clk_branch2_ops,
3373+ },
3374+ },
3375+};
3376+
3377+static struct clk_branch gcc_usb2a_phy_sleep_clk = {
3378+ .halt_reg = 0x4102c,
3379+ .clkr = {
3380+ .enable_reg = 0x4102c,
3381+ .enable_mask = BIT(0),
3382+ .hw.init = &(struct clk_init_data){
3383+ .name = "gcc_usb2a_phy_sleep_clk",
3384+ .ops = &clk_branch2_ops,
3385+ },
3386+ },
3387+};
3388+
3389+static struct clk_branch gcc_usb_fs_ahb_clk = {
3390+ .halt_reg = 0x3f008,
3391+ .clkr = {
3392+ .enable_reg = 0x3f008,
3393+ .enable_mask = BIT(0),
3394+ .hw.init = &(struct clk_init_data){
3395+ .name = "gcc_usb_fs_ahb_clk",
3396+ .parent_data = &(const struct clk_parent_data){
3397+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
3398+ },
3399+ .num_parents = 1,
3400+ .flags = CLK_SET_RATE_PARENT,
3401+ .ops = &clk_branch2_ops,
3402+ },
3403+ },
3404+};
3405+
3406+static struct clk_branch gcc_usb_fs_ic_clk = {
3407+ .halt_reg = 0x3f030,
3408+ .clkr = {
3409+ .enable_reg = 0x3f030,
3410+ .enable_mask = BIT(0),
3411+ .hw.init = &(struct clk_init_data){
3412+ .name = "gcc_usb_fs_ic_clk",
3413+ .parent_data = &(const struct clk_parent_data){
3414+ .hw = &usb_fs_ic_clk_src.clkr.hw,
3415+ },
3416+ .num_parents = 1,
3417+ .flags = CLK_SET_RATE_PARENT,
3418+ .ops = &clk_branch2_ops,
3419+ },
3420+ },
3421+};
3422+
3423+static struct clk_branch gcc_usb_fs_system_clk = {
3424+ .halt_reg = 0x3f004,
3425+ .clkr = {
3426+ .enable_reg = 0x3f004,
3427+ .enable_mask = BIT(0),
3428+ .hw.init = &(struct clk_init_data){
3429+ .name = "gcc_usb_fs_system_clk",
3430+ .parent_data = &(const struct clk_parent_data){
3431+ .hw = &usb_fs_system_clk_src.clkr.hw,
3432+ },
3433+ .num_parents = 1,
3434+ .flags = CLK_SET_RATE_PARENT,
3435+ .ops = &clk_branch2_ops,
3436+ },
3437+ },
3438+};
3439+
3440+static struct clk_branch gcc_usb_hs_ahb_clk = {
3441+ .halt_reg = 0x41008,
3442+ .clkr = {
3443+ .enable_reg = 0x41008,
3444+ .enable_mask = BIT(0),
3445+ .hw.init = &(struct clk_init_data){
3446+ .name = "gcc_usb_hs_ahb_clk",
3447+ .parent_data = &(const struct clk_parent_data){
3448+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
3449+ },
3450+ .num_parents = 1,
3451+ .flags = CLK_SET_RATE_PARENT,
3452+ .ops = &clk_branch2_ops,
3453+ },
3454+ },
3455+};
3456+
3457+static struct clk_branch gcc_usb_hs_system_clk = {
3458+ .halt_reg = 0x41004,
3459+ .clkr = {
3460+ .enable_reg = 0x41004,
3461+ .enable_mask = BIT(0),
3462+ .hw.init = &(struct clk_init_data){
3463+ .name = "gcc_usb_hs_system_clk",
3464+ .parent_data = &(const struct clk_parent_data){
3465+ .hw = &usb_hs_system_clk_src.clkr.hw,
3466+ },
3467+ .num_parents = 1,
3468+ .flags = CLK_SET_RATE_PARENT,
3469+ .ops = &clk_branch2_ops,
3470+ },
3471+ },
3472+};
3473+
3474+static struct clk_branch gcc_venus0_ahb_clk = {
3475+ .halt_reg = 0x4c020,
3476+ .clkr = {
3477+ .enable_reg = 0x4c020,
3478+ .enable_mask = BIT(0),
3479+ .hw.init = &(struct clk_init_data){
3480+ .name = "gcc_venus0_ahb_clk",
3481+ .parent_data = &(const struct clk_parent_data){
3482+ .hw = &pcnoc_bfdcd_clk_src.clkr.hw,
3483+ },
3484+ .num_parents = 1,
3485+ .flags = CLK_SET_RATE_PARENT,
3486+ .ops = &clk_branch2_ops,
3487+ },
3488+ },
3489+};
3490+
3491+static struct clk_branch gcc_venus0_axi_clk = {
3492+ .halt_reg = 0x4c024,
3493+ .clkr = {
3494+ .enable_reg = 0x4c024,
3495+ .enable_mask = BIT(0),
3496+ .hw.init = &(struct clk_init_data){
3497+ .name = "gcc_venus0_axi_clk",
3498+ .parent_data = &(const struct clk_parent_data){
3499+ .hw = &system_noc_bfdcd_clk_src.clkr.hw,
3500+ },
3501+ .num_parents = 1,
3502+ .flags = CLK_SET_RATE_PARENT,
3503+ .ops = &clk_branch2_ops,
3504+ },
3505+ },
3506+};
3507+
3508+static struct clk_branch gcc_venus0_vcodec0_clk = {
3509+ .halt_reg = 0x4c01c,
3510+ .clkr = {
3511+ .enable_reg = 0x4c01c,
3512+ .enable_mask = BIT(0),
3513+ .hw.init = &(struct clk_init_data){
3514+ .name = "gcc_venus0_vcodec0_clk",
3515+ .parent_data = &(const struct clk_parent_data){
3516+ .hw = &vcodec0_clk_src.clkr.hw,
3517+ },
3518+ .num_parents = 1,
3519+ .flags = CLK_SET_RATE_PARENT,
3520+ .ops = &clk_branch2_ops,
3521+ },
3522+ },
3523+};
3524+
3525+static struct clk_branch gcc_venus0_core0_vcodec0_clk = {
3526+ .halt_reg = 0x4c02c,
3527+ .clkr = {
3528+ .enable_reg = 0x4c02c,
3529+ .enable_mask = BIT(0),
3530+ .hw.init = &(struct clk_init_data){
3531+ .name = "gcc_venus0_core0_vcodec0_clk",
3532+ .parent_data = &(const struct clk_parent_data){
3533+ .hw = &vcodec0_clk_src.clkr.hw,
3534+ },
3535+ .num_parents = 1,
3536+ .flags = CLK_SET_RATE_PARENT,
3537+ .ops = &clk_branch2_ops,
3538+ },
3539+ },
3540+};
3541+
3542+static struct clk_branch gcc_venus0_core1_vcodec0_clk = {
3543+ .halt_reg = 0x4c034,
3544+ .clkr = {
3545+ .enable_reg = 0x4c034,
3546+ .enable_mask = BIT(0),
3547+ .hw.init = &(struct clk_init_data){
3548+ .name = "gcc_venus0_core1_vcodec0_clk",
3549+ .parent_data = &(const struct clk_parent_data){
3550+ .hw = &vcodec0_clk_src.clkr.hw,
3551+ },
3552+ .num_parents = 1,
3553+ .flags = CLK_SET_RATE_PARENT,
3554+ .ops = &clk_branch2_ops,
3555+ },
3556+ },
3557+};
3558+
3559+static struct clk_branch gcc_oxili_timer_clk = {
3560+ .halt_reg = 0x59040,
3561+ .clkr = {
3562+ .enable_reg = 0x59040,
3563+ .enable_mask = BIT(0),
3564+ .hw.init = &(struct clk_init_data){
3565+ .name = "gcc_oxili_timer_clk",
3566+ .ops = &clk_branch2_ops,
3567+ },
3568+ },
3569+};
3570+
3571+static struct gdsc venus_gdsc = {
3572+ .gdscr = 0x4c018,
3573+ .pd = {
3574+ .name = "venus",
3575+ },
3576+ .pwrsts = PWRSTS_OFF_ON,
3577+};
3578+
3579+static struct gdsc mdss_gdsc = {
3580+ .gdscr = 0x4d078,
3581+ .pd = {
3582+ .name = "mdss",
3583+ },
3584+ .pwrsts = PWRSTS_OFF_ON,
3585+};
3586+
3587+static struct gdsc jpeg_gdsc = {
3588+ .gdscr = 0x5701c,
3589+ .pd = {
3590+ .name = "jpeg",
3591+ },
3592+ .pwrsts = PWRSTS_OFF_ON,
3593+};
3594+
3595+static struct gdsc vfe_gdsc = {
3596+ .gdscr = 0x58034,
3597+ .pd = {
3598+ .name = "vfe",
3599+ },
3600+ .pwrsts = PWRSTS_OFF_ON,
3601+};
3602+
3603+static struct gdsc oxili_gdsc = {
3604+ .gdscr = 0x5901c,
3605+ .pd = {
3606+ .name = "oxili",
3607+ },
3608+ .pwrsts = PWRSTS_OFF_ON,
3609+};
3610+
3611+static struct gdsc venus_core0_gdsc = {
3612+ .gdscr = 0x4c028,
3613+ .pd = {
3614+ .name = "venus_core0",
3615+ },
3616+ .pwrsts = PWRSTS_OFF_ON,
3617+};
3618+
3619+static struct gdsc venus_core1_gdsc = {
3620+ .gdscr = 0x4c030,
3621+ .pd = {
3622+ .name = "venus_core1",
3623+ },
3624+ .pwrsts = PWRSTS_OFF_ON,
3625+};
3626+
3627+static struct clk_regmap *gcc_msm8939_clocks[] = {
3628+ [GPLL0] = &gpll0.clkr,
3629+ [GPLL0_VOTE] = &gpll0_vote,
3630+ [BIMC_PLL] = &bimc_pll.clkr,
3631+ [BIMC_PLL_VOTE] = &bimc_pll_vote,
3632+ [GPLL1] = &gpll1.clkr,
3633+ [GPLL1_VOTE] = &gpll1_vote,
3634+ [GPLL2] = &gpll2.clkr,
3635+ [GPLL2_VOTE] = &gpll2_vote,
3636+ [PCNOC_BFDCD_CLK_SRC] = &pcnoc_bfdcd_clk_src.clkr,
3637+ [SYSTEM_NOC_BFDCD_CLK_SRC] = &system_noc_bfdcd_clk_src.clkr,
3638+ [CAMSS_AHB_CLK_SRC] = &camss_ahb_clk_src.clkr,
3639+ [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr,
3640+ [CSI0_CLK_SRC] = &csi0_clk_src.clkr,
3641+ [CSI1_CLK_SRC] = &csi1_clk_src.clkr,
3642+ [GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr,
3643+ [VFE0_CLK_SRC] = &vfe0_clk_src.clkr,
3644+ [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
3645+ [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
3646+ [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr,
3647+ [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr,
3648+ [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr,
3649+ [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr,
3650+ [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr,
3651+ [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr,
3652+ [BLSP1_QUP5_I2C_APPS_CLK_SRC] = &blsp1_qup5_i2c_apps_clk_src.clkr,
3653+ [BLSP1_QUP5_SPI_APPS_CLK_SRC] = &blsp1_qup5_spi_apps_clk_src.clkr,
3654+ [BLSP1_QUP6_I2C_APPS_CLK_SRC] = &blsp1_qup6_i2c_apps_clk_src.clkr,
3655+ [BLSP1_QUP6_SPI_APPS_CLK_SRC] = &blsp1_qup6_spi_apps_clk_src.clkr,
3656+ [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr,
3657+ [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr,
3658+ [CCI_CLK_SRC] = &cci_clk_src.clkr,
3659+ [CAMSS_GP0_CLK_SRC] = &camss_gp0_clk_src.clkr,
3660+ [CAMSS_GP1_CLK_SRC] = &camss_gp1_clk_src.clkr,
3661+ [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr,
3662+ [MCLK0_CLK_SRC] = &mclk0_clk_src.clkr,
3663+ [MCLK1_CLK_SRC] = &mclk1_clk_src.clkr,
3664+ [CSI0PHYTIMER_CLK_SRC] = &csi0phytimer_clk_src.clkr,
3665+ [CSI1PHYTIMER_CLK_SRC] = &csi1phytimer_clk_src.clkr,
3666+ [CPP_CLK_SRC] = &cpp_clk_src.clkr,
3667+ [CRYPTO_CLK_SRC] = &crypto_clk_src.clkr,
3668+ [GP1_CLK_SRC] = &gp1_clk_src.clkr,
3669+ [GP2_CLK_SRC] = &gp2_clk_src.clkr,
3670+ [GP3_CLK_SRC] = &gp3_clk_src.clkr,
3671+ [BYTE0_CLK_SRC] = &byte0_clk_src.clkr,
3672+ [ESC0_CLK_SRC] = &esc0_clk_src.clkr,
3673+ [MDP_CLK_SRC] = &mdp_clk_src.clkr,
3674+ [PCLK0_CLK_SRC] = &pclk0_clk_src.clkr,
3675+ [VSYNC_CLK_SRC] = &vsync_clk_src.clkr,
3676+ [PDM2_CLK_SRC] = &pdm2_clk_src.clkr,
3677+ [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr,
3678+ [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr,
3679+ [APSS_TCU_CLK_SRC] = &apss_tcu_clk_src.clkr,
3680+ [USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr,
3681+ [VCODEC0_CLK_SRC] = &vcodec0_clk_src.clkr,
3682+ [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
3683+ [GCC_BLSP1_SLEEP_CLK] = &gcc_blsp1_sleep_clk.clkr,
3684+ [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr,
3685+ [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr,
3686+ [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr,
3687+ [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr,
3688+ [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr,
3689+ [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr,
3690+ [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr,
3691+ [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr,
3692+ [GCC_BLSP1_QUP5_I2C_APPS_CLK] = &gcc_blsp1_qup5_i2c_apps_clk.clkr,
3693+ [GCC_BLSP1_QUP5_SPI_APPS_CLK] = &gcc_blsp1_qup5_spi_apps_clk.clkr,
3694+ [GCC_BLSP1_QUP6_I2C_APPS_CLK] = &gcc_blsp1_qup6_i2c_apps_clk.clkr,
3695+ [GCC_BLSP1_QUP6_SPI_APPS_CLK] = &gcc_blsp1_qup6_spi_apps_clk.clkr,
3696+ [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
3697+ [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,
3698+ [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
3699+ [GCC_CAMSS_CCI_AHB_CLK] = &gcc_camss_cci_ahb_clk.clkr,
3700+ [GCC_CAMSS_CCI_CLK] = &gcc_camss_cci_clk.clkr,
3701+ [GCC_CAMSS_CSI0_AHB_CLK] = &gcc_camss_csi0_ahb_clk.clkr,
3702+ [GCC_CAMSS_CSI0_CLK] = &gcc_camss_csi0_clk.clkr,
3703+ [GCC_CAMSS_CSI0PHY_CLK] = &gcc_camss_csi0phy_clk.clkr,
3704+ [GCC_CAMSS_CSI0PIX_CLK] = &gcc_camss_csi0pix_clk.clkr,
3705+ [GCC_CAMSS_CSI0RDI_CLK] = &gcc_camss_csi0rdi_clk.clkr,
3706+ [GCC_CAMSS_CSI1_AHB_CLK] = &gcc_camss_csi1_ahb_clk.clkr,
3707+ [GCC_CAMSS_CSI1_CLK] = &gcc_camss_csi1_clk.clkr,
3708+ [GCC_CAMSS_CSI1PHY_CLK] = &gcc_camss_csi1phy_clk.clkr,
3709+ [GCC_CAMSS_CSI1PIX_CLK] = &gcc_camss_csi1pix_clk.clkr,
3710+ [GCC_CAMSS_CSI1RDI_CLK] = &gcc_camss_csi1rdi_clk.clkr,
3711+ [GCC_CAMSS_CSI_VFE0_CLK] = &gcc_camss_csi_vfe0_clk.clkr,
3712+ [GCC_CAMSS_GP0_CLK] = &gcc_camss_gp0_clk.clkr,
3713+ [GCC_CAMSS_GP1_CLK] = &gcc_camss_gp1_clk.clkr,
3714+ [GCC_CAMSS_ISPIF_AHB_CLK] = &gcc_camss_ispif_ahb_clk.clkr,
3715+ [GCC_CAMSS_JPEG0_CLK] = &gcc_camss_jpeg0_clk.clkr,
3716+ [GCC_CAMSS_JPEG_AHB_CLK] = &gcc_camss_jpeg_ahb_clk.clkr,
3717+ [GCC_CAMSS_JPEG_AXI_CLK] = &gcc_camss_jpeg_axi_clk.clkr,
3718+ [GCC_CAMSS_MCLK0_CLK] = &gcc_camss_mclk0_clk.clkr,
3719+ [GCC_CAMSS_MCLK1_CLK] = &gcc_camss_mclk1_clk.clkr,
3720+ [GCC_CAMSS_MICRO_AHB_CLK] = &gcc_camss_micro_ahb_clk.clkr,
3721+ [GCC_CAMSS_CSI0PHYTIMER_CLK] = &gcc_camss_csi0phytimer_clk.clkr,
3722+ [GCC_CAMSS_CSI1PHYTIMER_CLK] = &gcc_camss_csi1phytimer_clk.clkr,
3723+ [GCC_CAMSS_AHB_CLK] = &gcc_camss_ahb_clk.clkr,
3724+ [GCC_CAMSS_TOP_AHB_CLK] = &gcc_camss_top_ahb_clk.clkr,
3725+ [GCC_CAMSS_CPP_AHB_CLK] = &gcc_camss_cpp_ahb_clk.clkr,
3726+ [GCC_CAMSS_CPP_CLK] = &gcc_camss_cpp_clk.clkr,
3727+ [GCC_CAMSS_VFE0_CLK] = &gcc_camss_vfe0_clk.clkr,
3728+ [GCC_CAMSS_VFE_AHB_CLK] = &gcc_camss_vfe_ahb_clk.clkr,
3729+ [GCC_CAMSS_VFE_AXI_CLK] = &gcc_camss_vfe_axi_clk.clkr,
3730+ [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr,
3731+ [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr,
3732+ [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr,
3733+ [GCC_OXILI_GMEM_CLK] = &gcc_oxili_gmem_clk.clkr,
3734+ [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
3735+ [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
3736+ [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
3737+ [GCC_MDSS_AHB_CLK] = &gcc_mdss_ahb_clk.clkr,
3738+ [GCC_MDSS_AXI_CLK] = &gcc_mdss_axi_clk.clkr,
3739+ [GCC_MDSS_BYTE0_CLK] = &gcc_mdss_byte0_clk.clkr,
3740+ [GCC_MDSS_ESC0_CLK] = &gcc_mdss_esc0_clk.clkr,
3741+ [GCC_MDSS_MDP_CLK] = &gcc_mdss_mdp_clk.clkr,
3742+ [GCC_MDSS_PCLK0_CLK] = &gcc_mdss_pclk0_clk.clkr,
3743+ [GCC_MDSS_VSYNC_CLK] = &gcc_mdss_vsync_clk.clkr,
3744+ [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr,
3745+ [GCC_OXILI_AHB_CLK] = &gcc_oxili_ahb_clk.clkr,
3746+ [GCC_OXILI_GFX3D_CLK] = &gcc_oxili_gfx3d_clk.clkr,
3747+ [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
3748+ [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
3749+ [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
3750+ [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
3751+ [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
3752+ [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
3753+ [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
3754+ [GCC_GTCU_AHB_CLK] = &gcc_gtcu_ahb_clk.clkr,
3755+ [GCC_JPEG_TBU_CLK] = &gcc_jpeg_tbu_clk.clkr,
3756+ [GCC_MDP_TBU_CLK] = &gcc_mdp_tbu_clk.clkr,
3757+ [GCC_SMMU_CFG_CLK] = &gcc_smmu_cfg_clk.clkr,
3758+ [GCC_VENUS_TBU_CLK] = &gcc_venus_tbu_clk.clkr,
3759+ [GCC_VFE_TBU_CLK] = &gcc_vfe_tbu_clk.clkr,
3760+ [GCC_USB2A_PHY_SLEEP_CLK] = &gcc_usb2a_phy_sleep_clk.clkr,
3761+ [GCC_USB_HS_AHB_CLK] = &gcc_usb_hs_ahb_clk.clkr,
3762+ [GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr,
3763+ [GCC_VENUS0_AHB_CLK] = &gcc_venus0_ahb_clk.clkr,
3764+ [GCC_VENUS0_AXI_CLK] = &gcc_venus0_axi_clk.clkr,
3765+ [GCC_VENUS0_VCODEC0_CLK] = &gcc_venus0_vcodec0_clk.clkr,
3766+ [BIMC_DDR_CLK_SRC] = &bimc_ddr_clk_src.clkr,
3767+ [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr,
3768+ [GCC_GFX_TCU_CLK] = &gcc_gfx_tcu_clk.clkr,
3769+ [BIMC_GPU_CLK_SRC] = &bimc_gpu_clk_src.clkr,
3770+ [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr,
3771+ [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr,
3772+ [ULTAUDIO_AHBFABRIC_CLK_SRC] = &ultaudio_ahbfabric_clk_src.clkr,
3773+ [ULTAUDIO_LPAIF_PRI_I2S_CLK_SRC] = &ultaudio_lpaif_pri_i2s_clk_src.clkr,
3774+ [ULTAUDIO_LPAIF_SEC_I2S_CLK_SRC] = &ultaudio_lpaif_sec_i2s_clk_src.clkr,
3775+ [ULTAUDIO_LPAIF_AUX_I2S_CLK_SRC] = &ultaudio_lpaif_aux_i2s_clk_src.clkr,
3776+ [ULTAUDIO_XO_CLK_SRC] = &ultaudio_xo_clk_src.clkr,
3777+ [CODEC_DIGCODEC_CLK_SRC] = &codec_digcodec_clk_src.clkr,
3778+ [GCC_ULTAUDIO_PCNOC_MPORT_CLK] = &gcc_ultaudio_pcnoc_mport_clk.clkr,
3779+ [GCC_ULTAUDIO_PCNOC_SWAY_CLK] = &gcc_ultaudio_pcnoc_sway_clk.clkr,
3780+ [GCC_ULTAUDIO_AVSYNC_XO_CLK] = &gcc_ultaudio_avsync_xo_clk.clkr,
3781+ [GCC_ULTAUDIO_STC_XO_CLK] = &gcc_ultaudio_stc_xo_clk.clkr,
3782+ [GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK] = &gcc_ultaudio_ahbfabric_ixfabric_clk.clkr,
3783+ [GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_LPM_CLK] = &gcc_ultaudio_ahbfabric_ixfabric_lpm_clk.clkr,
3784+ [GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK] = &gcc_ultaudio_lpaif_pri_i2s_clk.clkr,
3785+ [GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK] = &gcc_ultaudio_lpaif_sec_i2s_clk.clkr,
3786+ [GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK] = &gcc_ultaudio_lpaif_aux_i2s_clk.clkr,
3787+ [GCC_CODEC_DIGCODEC_CLK] = &gcc_codec_digcodec_clk.clkr,
3788+ [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr,
3789+ [GPLL3] = &gpll3.clkr,
3790+ [GPLL3_VOTE] = &gpll3_vote,
3791+ [GPLL4] = &gpll4.clkr,
3792+ [GPLL4_VOTE] = &gpll4_vote,
3793+ [GPLL5] = &gpll5.clkr,
3794+ [GPLL5_VOTE] = &gpll5_vote,
3795+ [GPLL6] = &gpll6.clkr,
3796+ [GPLL6_VOTE] = &gpll6_vote,
3797+ [BYTE1_CLK_SRC] = &byte1_clk_src.clkr,
3798+ [GCC_MDSS_BYTE1_CLK] = &gcc_mdss_byte1_clk.clkr,
3799+ [ESC1_CLK_SRC] = &esc1_clk_src.clkr,
3800+ [GCC_MDSS_ESC1_CLK] = &gcc_mdss_esc1_clk.clkr,
3801+ [PCLK1_CLK_SRC] = &pclk1_clk_src.clkr,
3802+ [GCC_MDSS_PCLK1_CLK] = &gcc_mdss_pclk1_clk.clkr,
3803+ [GCC_GFX_TBU_CLK] = &gcc_gfx_tbu_clk.clkr,
3804+ [GCC_CPP_TBU_CLK] = &gcc_cpp_tbu_clk.clkr,
3805+ [GCC_MDP_RT_TBU_CLK] = &gcc_mdp_rt_tbu_clk.clkr,
3806+ [USB_FS_SYSTEM_CLK_SRC] = &usb_fs_system_clk_src.clkr,
3807+ [USB_FS_IC_CLK_SRC] = &usb_fs_ic_clk_src.clkr,
3808+ [GCC_USB_FS_AHB_CLK] = &gcc_usb_fs_ahb_clk.clkr,
3809+ [GCC_USB_FS_IC_CLK] = &gcc_usb_fs_ic_clk.clkr,
3810+ [GCC_USB_FS_SYSTEM_CLK] = &gcc_usb_fs_system_clk.clkr,
3811+ [GCC_VENUS0_CORE0_VCODEC0_CLK] = &gcc_venus0_core0_vcodec0_clk.clkr,
3812+ [GCC_VENUS0_CORE1_VCODEC0_CLK] = &gcc_venus0_core1_vcodec0_clk.clkr,
3813+ [GCC_OXILI_TIMER_CLK] = &gcc_oxili_timer_clk.clkr,
3814+};
3815+
3816+static struct gdsc *gcc_msm8939_gdscs[] = {
3817+ [VENUS_GDSC] = &venus_gdsc,
3818+ [MDSS_GDSC] = &mdss_gdsc,
3819+ [JPEG_GDSC] = &jpeg_gdsc,
3820+ [VFE_GDSC] = &vfe_gdsc,
3821+ [OXILI_GDSC] = &oxili_gdsc,
3822+ [VENUS_CORE0_GDSC] = &venus_core0_gdsc,
3823+ [VENUS_CORE1_GDSC] = &venus_core1_gdsc,
3824+};
3825+
3826+static const struct qcom_reset_map gcc_msm8939_resets[] = {
3827+ [GCC_BLSP1_BCR] = { 0x01000 },
3828+ [GCC_BLSP1_QUP1_BCR] = { 0x02000 },
3829+ [GCC_BLSP1_UART1_BCR] = { 0x02038 },
3830+ [GCC_BLSP1_QUP2_BCR] = { 0x03008 },
3831+ [GCC_BLSP1_UART2_BCR] = { 0x03028 },
3832+ [GCC_BLSP1_QUP3_BCR] = { 0x04018 },
3833+ [GCC_BLSP1_UART3_BCR] = { 0x04038 },
3834+ [GCC_BLSP1_QUP4_BCR] = { 0x05018 },
3835+ [GCC_BLSP1_QUP5_BCR] = { 0x06018 },
3836+ [GCC_BLSP1_QUP6_BCR] = { 0x07018 },
3837+ [GCC_IMEM_BCR] = { 0x0e000 },
3838+ [GCC_SMMU_BCR] = { 0x12000 },
3839+ [GCC_APSS_TCU_BCR] = { 0x12050 },
3840+ [GCC_SMMU_XPU_BCR] = { 0x12054 },
3841+ [GCC_PCNOC_TBU_BCR] = { 0x12058 },
3842+ [GCC_PRNG_BCR] = { 0x13000 },
3843+ [GCC_BOOT_ROM_BCR] = { 0x13008 },
3844+ [GCC_CRYPTO_BCR] = { 0x16000 },
3845+ [GCC_SEC_CTRL_BCR] = { 0x1a000 },
3846+ [GCC_AUDIO_CORE_BCR] = { 0x1c008 },
3847+ [GCC_ULT_AUDIO_BCR] = { 0x1c0b4 },
3848+ [GCC_DEHR_BCR] = { 0x1f000 },
3849+ [GCC_SYSTEM_NOC_BCR] = { 0x26000 },
3850+ [GCC_PCNOC_BCR] = { 0x27018 },
3851+ [GCC_TCSR_BCR] = { 0x28000 },
3852+ [GCC_QDSS_BCR] = { 0x29000 },
3853+ [GCC_DCD_BCR] = { 0x2a000 },
3854+ [GCC_MSG_RAM_BCR] = { 0x2b000 },
3855+ [GCC_MPM_BCR] = { 0x2c000 },
3856+ [GCC_SPMI_BCR] = { 0x2e000 },
3857+ [GCC_SPDM_BCR] = { 0x2f000 },
3858+ [GCC_MM_SPDM_BCR] = { 0x2f024 },
3859+ [GCC_BIMC_BCR] = { 0x31000 },
3860+ [GCC_RBCPR_BCR] = { 0x33000 },
3861+ [GCC_TLMM_BCR] = { 0x34000 },
3862+ [GCC_CAMSS_CSI2_BCR] = { 0x3c038 },
3863+ [GCC_CAMSS_CSI2PHY_BCR] = { 0x3c044 },
3864+ [GCC_CAMSS_CSI2RDI_BCR] = { 0x3c04c },
3865+ [GCC_CAMSS_CSI2PIX_BCR] = { 0x3c054 },
3866+ [GCC_USB_FS_BCR] = { 0x3f000 },
3867+ [GCC_USB_HS_BCR] = { 0x41000 },
3868+ [GCC_USB2A_PHY_BCR] = { 0x41028 },
3869+ [GCC_SDCC1_BCR] = { 0x42000 },
3870+ [GCC_SDCC2_BCR] = { 0x43000 },
3871+ [GCC_PDM_BCR] = { 0x44000 },
3872+ [GCC_SNOC_BUS_TIMEOUT0_BCR] = { 0x47000 },
3873+ [GCC_PCNOC_BUS_TIMEOUT0_BCR] = { 0x48000 },
3874+ [GCC_PCNOC_BUS_TIMEOUT1_BCR] = { 0x48008 },
3875+ [GCC_PCNOC_BUS_TIMEOUT2_BCR] = { 0x48010 },
3876+ [GCC_PCNOC_BUS_TIMEOUT3_BCR] = { 0x48018 },
3877+ [GCC_PCNOC_BUS_TIMEOUT4_BCR] = { 0x48020 },
3878+ [GCC_PCNOC_BUS_TIMEOUT5_BCR] = { 0x48028 },
3879+ [GCC_PCNOC_BUS_TIMEOUT6_BCR] = { 0x48030 },
3880+ [GCC_PCNOC_BUS_TIMEOUT7_BCR] = { 0x48038 },
3881+ [GCC_PCNOC_BUS_TIMEOUT8_BCR] = { 0x48040 },
3882+ [GCC_PCNOC_BUS_TIMEOUT9_BCR] = { 0x48048 },
3883+ [GCC_MMSS_BCR] = { 0x4b000 },
3884+ [GCC_VENUS0_BCR] = { 0x4c014 },
3885+ [GCC_MDSS_BCR] = { 0x4d074 },
3886+ [GCC_CAMSS_PHY0_BCR] = { 0x4e018 },
3887+ [GCC_CAMSS_CSI0_BCR] = { 0x4e038 },
3888+ [GCC_CAMSS_CSI0PHY_BCR] = { 0x4e044 },
3889+ [GCC_CAMSS_CSI0RDI_BCR] = { 0x4e04c },
3890+ [GCC_CAMSS_CSI0PIX_BCR] = { 0x4e054 },
3891+ [GCC_CAMSS_PHY1_BCR] = { 0x4f018 },
3892+ [GCC_CAMSS_CSI1_BCR] = { 0x4f038 },
3893+ [GCC_CAMSS_CSI1PHY_BCR] = { 0x4f044 },
3894+ [GCC_CAMSS_CSI1RDI_BCR] = { 0x4f04c },
3895+ [GCC_CAMSS_CSI1PIX_BCR] = { 0x4f054 },
3896+ [GCC_CAMSS_ISPIF_BCR] = { 0x50000 },
3897+ [GCC_BLSP1_QUP4_SPI_APPS_CBCR] = { 0x0501c },
3898+ [GCC_CAMSS_CCI_BCR] = { 0x51014 },
3899+ [GCC_CAMSS_MCLK0_BCR] = { 0x52014 },
3900+ [GCC_CAMSS_MCLK1_BCR] = { 0x53014 },
3901+ [GCC_CAMSS_GP0_BCR] = { 0x54014 },
3902+ [GCC_CAMSS_GP1_BCR] = { 0x55014 },
3903+ [GCC_CAMSS_TOP_BCR] = { 0x56000 },
3904+ [GCC_CAMSS_MICRO_BCR] = { 0x56008 },
3905+ [GCC_CAMSS_JPEG_BCR] = { 0x57018 },
3906+ [GCC_CAMSS_VFE_BCR] = { 0x58030 },
3907+ [GCC_CAMSS_CSI_VFE0_BCR] = { 0x5804c },
3908+ [GCC_OXILI_BCR] = { 0x59018 },
3909+ [GCC_GMEM_BCR] = { 0x5902c },
3910+ [GCC_CAMSS_AHB_BCR] = { 0x5a018 },
3911+ [GCC_CAMSS_MCLK2_BCR] = { 0x5c014 },
3912+ [GCC_MDP_TBU_BCR] = { 0x62000 },
3913+ [GCC_GFX_TBU_BCR] = { 0x63000 },
3914+ [GCC_GFX_TCU_BCR] = { 0x64000 },
3915+ [GCC_MSS_TBU_AXI_BCR] = { 0x65000 },
3916+ [GCC_MSS_TBU_GSS_AXI_BCR] = { 0x66000 },
3917+ [GCC_MSS_TBU_Q6_AXI_BCR] = { 0x67000 },
3918+ [GCC_GTCU_AHB_BCR] = { 0x68000 },
3919+ [GCC_SMMU_CFG_BCR] = { 0x69000 },
3920+ [GCC_VFE_TBU_BCR] = { 0x6a000 },
3921+ [GCC_VENUS_TBU_BCR] = { 0x6b000 },
3922+ [GCC_JPEG_TBU_BCR] = { 0x6c000 },
3923+ [GCC_PRONTO_TBU_BCR] = { 0x6d000 },
3924+ [GCC_CPP_TBU_BCR] = { 0x6e000 },
3925+ [GCC_MDP_RT_TBU_BCR] = { 0x6f000 },
3926+ [GCC_SMMU_CATS_BCR] = { 0x7c000 },
3927+};
3928+
3929+static const struct regmap_config gcc_msm8939_regmap_config = {
3930+ .reg_bits = 32,
3931+ .reg_stride = 4,
3932+ .val_bits = 32,
3933+ .max_register = 0x80000,
3934+ .fast_io = true,
3935+};
3936+
3937+static const struct qcom_cc_desc gcc_msm8939_desc = {
3938+ .config = &gcc_msm8939_regmap_config,
3939+ .clks = gcc_msm8939_clocks,
3940+ .num_clks = ARRAY_SIZE(gcc_msm8939_clocks),
3941+ .resets = gcc_msm8939_resets,
3942+ .num_resets = ARRAY_SIZE(gcc_msm8939_resets),
3943+ .gdscs = gcc_msm8939_gdscs,
3944+ .num_gdscs = ARRAY_SIZE(gcc_msm8939_gdscs),
3945+};
3946+
3947+static const struct of_device_id gcc_msm8939_match_table[] = {
3948+ { .compatible = "qcom,gcc-msm8939" },
3949+ { }
3950+};
3951+MODULE_DEVICE_TABLE(of, gcc_msm8939_match_table);
3952+
3953+static int gcc_msm8939_probe(struct platform_device *pdev)
3954+{
3955+ struct regmap *regmap;
3956+
3957+ regmap = qcom_cc_map(pdev, &gcc_msm8939_desc);
3958+ if (IS_ERR(regmap))
3959+ return PTR_ERR(regmap);
3960+
3961+ clk_pll_configure_sr_hpm_lp(&gpll3, regmap, &gpll3_config, true);
3962+ clk_pll_configure_sr_hpm_lp(&gpll4, regmap, &gpll4_config, true);
3963+
3964+ return qcom_cc_really_probe(pdev, &gcc_msm8939_desc, regmap);
3965+}
3966+
3967+static struct platform_driver gcc_msm8939_driver = {
3968+ .probe = gcc_msm8939_probe,
3969+ .driver = {
3970+ .name = "gcc-msm8939",
3971+ .of_match_table = gcc_msm8939_match_table,
3972+ },
3973+};
3974+
3975+static int __init gcc_msm8939_init(void)
3976+{
3977+ return platform_driver_register(&gcc_msm8939_driver);
3978+}
3979+core_initcall(gcc_msm8939_init);
3980+
3981+static void __exit gcc_msm8939_exit(void)
3982+{
3983+ platform_driver_unregister(&gcc_msm8939_driver);
3984+}
3985+module_exit(gcc_msm8939_exit);
3986+
3987+MODULE_DESCRIPTION("Qualcomm GCC MSM8939 Driver");
3988+MODULE_LICENSE("GPL v2");
drivers/clk/qcom/gcc-msm8998.c+27−0
@@ -1110,6 +1110,27 @@ static struct clk_rcg2 ufs_axi_clk_src = { · 1109 unmodified lines
11101110 },
11111111 };
11121112
1113+static const struct freq_tbl ftbl_ufs_unipro_core_clk_src[] = {
1114+ F(37500000, P_GPLL0_OUT_MAIN, 16, 0, 0),
1115+ F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
1116+ F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
1117+ { }
1118+};
1119+
1120+static struct clk_rcg2 ufs_unipro_core_clk_src = {
1121+ .cmd_rcgr = 0x76028,
1122+ .mnd_width = 8,
1123+ .hid_width = 5,
1124+ .parent_map = gcc_parent_map_0,
1125+ .freq_tbl = ftbl_ufs_unipro_core_clk_src,
1126+ .clkr.hw.init = &(struct clk_init_data){
1127+ .name = "ufs_unipro_core_clk_src",
1128+ .parent_names = gcc_parent_names_0,
1129+ .num_parents = 4,
1130+ .ops = &clk_rcg2_ops,
1131+ },
1132+};
1133+
11131134 static const struct freq_tbl ftbl_usb30_master_clk_src[] = {
11141135 F(19200000, P_XO, 1, 0, 0),
11151136 F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
@@ -2549,6 +2570,11 @@ static struct clk_branch gcc_ufs_unipro_core_clk = { · 1433 unmodified lines
25492570 .enable_mask = BIT(0),
25502571 .hw.init = &(struct clk_init_data){
25512572 .name = "gcc_ufs_unipro_core_clk",
2573+ .parent_names = (const char *[]){
2574+ "ufs_unipro_core_clk_src",
2575+ },
2576+ .num_parents = 1,
2577+ .flags = CLK_SET_RATE_PARENT,
25522578 .ops = &clk_branch2_ops,
25532579 },
25542580 },
@@ -2904,6 +2930,7 @@ static struct clk_regmap *gcc_msm8998_clocks[] = { · 349 unmodified lines
29042930 [SDCC4_APPS_CLK_SRC] = &sdcc4_apps_clk_src.clkr,
29052931 [TSIF_REF_CLK_SRC] = &tsif_ref_clk_src.clkr,
29062932 [UFS_AXI_CLK_SRC] = &ufs_axi_clk_src.clkr,
2933+ [UFS_UNIPRO_CORE_CLK_SRC] = &ufs_unipro_core_clk_src.clkr,
29072934 [USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr,
29082935 [USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr,
29092936 [USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr,
drivers/clk/qcom/gcc-sc7180.c+58−36
@@ -390,6 +390,7 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { · 389 unmodified lines
390390 F(29491200, P_GPLL0_OUT_EVEN, 1, 1536, 15625),
391391 F(32000000, P_GPLL0_OUT_EVEN, 1, 8, 75),
392392 F(48000000, P_GPLL0_OUT_EVEN, 1, 4, 25),
393+ F(51200000, P_GPLL6_OUT_MAIN, 7.5, 0, 0),
393394 F(64000000, P_GPLL0_OUT_EVEN, 1, 16, 75),
394395 F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0),
395396 F(80000000, P_GPLL0_OUT_EVEN, 1, 4, 15),
@@ -405,8 +406,8 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { · 9 unmodified lines
405406
406407 static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = {
407408 .name = "gcc_qupv3_wrap0_s0_clk_src",
408− .parent_data = gcc_parent_data_0,
409− .num_parents = 4,
409+ .parent_data = gcc_parent_data_1,
410+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
410411 .ops = &clk_rcg2_ops,
411412 };
412413
@@ -414,15 +415,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { · 1 unmodified line
414415 .cmd_rcgr = 0x17034,
415416 .mnd_width = 16,
416417 .hid_width = 5,
417− .parent_map = gcc_parent_map_0,
418+ .parent_map = gcc_parent_map_1,
418419 .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
419420 .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init,
420421 };
421422
422423 static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = {
423424 .name = "gcc_qupv3_wrap0_s1_clk_src",
424− .parent_data = gcc_parent_data_0,
425− .num_parents = 4,
425+ .parent_data = gcc_parent_data_1,
426+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
426427 .ops = &clk_rcg2_ops,
427428 };
428429
@@ -430,15 +431,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { · 1 unmodified line
430431 .cmd_rcgr = 0x17164,
431432 .mnd_width = 16,
432433 .hid_width = 5,
433− .parent_map = gcc_parent_map_0,
434+ .parent_map = gcc_parent_map_1,
434435 .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
435436 .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init,
436437 };
437438
438439 static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = {
439440 .name = "gcc_qupv3_wrap0_s2_clk_src",
440− .parent_data = gcc_parent_data_0,
441− .num_parents = 4,
441+ .parent_data = gcc_parent_data_1,
442+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
442443 .ops = &clk_rcg2_ops,
443444 };
444445
@@ -446,15 +447,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { · 1 unmodified line
446447 .cmd_rcgr = 0x17294,
447448 .mnd_width = 16,
448449 .hid_width = 5,
449− .parent_map = gcc_parent_map_0,
450+ .parent_map = gcc_parent_map_1,
450451 .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
451452 .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init,
452453 };
453454
454455 static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = {
455456 .name = "gcc_qupv3_wrap0_s3_clk_src",
456− .parent_data = gcc_parent_data_0,
457− .num_parents = 4,
457+ .parent_data = gcc_parent_data_1,
458+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
458459 .ops = &clk_rcg2_ops,
459460 };
460461
@@ -462,15 +463,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { · 1 unmodified line
462463 .cmd_rcgr = 0x173c4,
463464 .mnd_width = 16,
464465 .hid_width = 5,
465− .parent_map = gcc_parent_map_0,
466+ .parent_map = gcc_parent_map_1,
466467 .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
467468 .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init,
468469 };
469470
470471 static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = {
471472 .name = "gcc_qupv3_wrap0_s4_clk_src",
472− .parent_data = gcc_parent_data_0,
473− .num_parents = 4,
473+ .parent_data = gcc_parent_data_1,
474+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
474475 .ops = &clk_rcg2_ops,
475476 };
476477
@@ -478,15 +479,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { · 1 unmodified line
478479 .cmd_rcgr = 0x174f4,
479480 .mnd_width = 16,
480481 .hid_width = 5,
481− .parent_map = gcc_parent_map_0,
482+ .parent_map = gcc_parent_map_1,
482483 .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
483484 .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init,
484485 };
485486
486487 static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = {
487488 .name = "gcc_qupv3_wrap0_s5_clk_src",
488− .parent_data = gcc_parent_data_0,
489− .num_parents = 4,
489+ .parent_data = gcc_parent_data_1,
490+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
490491 .ops = &clk_rcg2_ops,
491492 };
492493
@@ -494,15 +495,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { · 1 unmodified line
494495 .cmd_rcgr = 0x17624,
495496 .mnd_width = 16,
496497 .hid_width = 5,
497− .parent_map = gcc_parent_map_0,
498+ .parent_map = gcc_parent_map_1,
498499 .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
499500 .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init,
500501 };
501502
502503 static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = {
503504 .name = "gcc_qupv3_wrap1_s0_clk_src",
504− .parent_data = gcc_parent_data_0,
505− .num_parents = 4,
505+ .parent_data = gcc_parent_data_1,
506+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
506507 .ops = &clk_rcg2_ops,
507508 };
508509
@@ -510,15 +511,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { · 1 unmodified line
510511 .cmd_rcgr = 0x18018,
511512 .mnd_width = 16,
512513 .hid_width = 5,
513− .parent_map = gcc_parent_map_0,
514+ .parent_map = gcc_parent_map_1,
514515 .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
515516 .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init,
516517 };
517518
518519 static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = {
519520 .name = "gcc_qupv3_wrap1_s1_clk_src",
520− .parent_data = gcc_parent_data_0,
521− .num_parents = 4,
521+ .parent_data = gcc_parent_data_1,
522+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
522523 .ops = &clk_rcg2_ops,
523524 };
524525
@@ -526,15 +527,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { · 1 unmodified line
526527 .cmd_rcgr = 0x18148,
527528 .mnd_width = 16,
528529 .hid_width = 5,
529− .parent_map = gcc_parent_map_0,
530+ .parent_map = gcc_parent_map_1,
530531 .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
531532 .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init,
532533 };
533534
534535 static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = {
535536 .name = "gcc_qupv3_wrap1_s2_clk_src",
536− .parent_data = gcc_parent_data_0,
537− .num_parents = 4,
537+ .parent_data = gcc_parent_data_1,
538+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
538539 .ops = &clk_rcg2_ops,
539540 };
540541
@@ -542,15 +543,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { · 1 unmodified line
542543 .cmd_rcgr = 0x18278,
543544 .mnd_width = 16,
544545 .hid_width = 5,
545− .parent_map = gcc_parent_map_0,
546+ .parent_map = gcc_parent_map_1,
546547 .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
547548 .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init,
548549 };
549550
550551 static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = {
551552 .name = "gcc_qupv3_wrap1_s3_clk_src",
552− .parent_data = gcc_parent_data_0,
553− .num_parents = 4,
553+ .parent_data = gcc_parent_data_1,
554+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
554555 .ops = &clk_rcg2_ops,
555556 };
556557
@@ -558,15 +559,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { · 1 unmodified line
558559 .cmd_rcgr = 0x183a8,
559560 .mnd_width = 16,
560561 .hid_width = 5,
561− .parent_map = gcc_parent_map_0,
562+ .parent_map = gcc_parent_map_1,
562563 .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
563564 .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init,
564565 };
565566
566567 static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = {
567568 .name = "gcc_qupv3_wrap1_s4_clk_src",
568− .parent_data = gcc_parent_data_0,
569− .num_parents = 4,
569+ .parent_data = gcc_parent_data_1,
570+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
570571 .ops = &clk_rcg2_ops,
571572 };
572573
@@ -574,15 +575,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { · 1 unmodified line
574575 .cmd_rcgr = 0x184d8,
575576 .mnd_width = 16,
576577 .hid_width = 5,
577− .parent_map = gcc_parent_map_0,
578+ .parent_map = gcc_parent_map_1,
578579 .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
579580 .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init,
580581 };
581582
582583 static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = {
583584 .name = "gcc_qupv3_wrap1_s5_clk_src",
584− .parent_data = gcc_parent_data_0,
585− .num_parents = 4,
585+ .parent_data = gcc_parent_data_1,
586+ .num_parents = ARRAY_SIZE(gcc_parent_data_1),
586587 .ops = &clk_rcg2_ops,
587588 };
588589
@@ -590,7 +591,7 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { · 1 unmodified line
590591 .cmd_rcgr = 0x18608,
591592 .mnd_width = 16,
592593 .hid_width = 5,
593− .parent_map = gcc_parent_map_0,
594+ .parent_map = gcc_parent_map_1,
594595 .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
595596 .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init,
596597 };
@@ -816,6 +817,26 @@ static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { · 219 unmodified lines
816817 },
817818 };
818819
820+static const struct freq_tbl ftbl_gcc_sec_ctrl_clk_src[] = {
821+ F(4800000, P_BI_TCXO, 4, 0, 0),
822+ F(19200000, P_BI_TCXO, 1, 0, 0),
823+ { }
824+};
825+
826+static struct clk_rcg2 gcc_sec_ctrl_clk_src = {
827+ .cmd_rcgr = 0x3d030,
828+ .mnd_width = 0,
829+ .hid_width = 5,
830+ .parent_map = gcc_parent_map_3,
831+ .freq_tbl = ftbl_gcc_sec_ctrl_clk_src,
832+ .clkr.hw.init = &(struct clk_init_data){
833+ .name = "gcc_sec_ctrl_clk_src",
834+ .parent_data = gcc_parent_data_3,
835+ .num_parents = ARRAY_SIZE(gcc_parent_data_3),
836+ .ops = &clk_rcg2_ops,
837+ },
838+};
839+
819840 static struct clk_branch gcc_aggre_ufs_phy_axi_clk = {
820841 .halt_reg = 0x82024,
821842 .halt_check = BRANCH_HALT_DELAY,
@@ -2406,6 +2427,7 @@ static struct clk_regmap *gcc_sc7180_clocks[] = { · 1584 unmodified lines
24062427 [GCC_MSS_NAV_AXI_CLK] = &gcc_mss_nav_axi_clk.clkr,
24072428 [GCC_MSS_Q6_MEMNOC_AXI_CLK] = &gcc_mss_q6_memnoc_axi_clk.clkr,
24082429 [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr,
2430+ [GCC_SEC_CTRL_CLK_SRC] = &gcc_sec_ctrl_clk_src.clkr,
24092431 };
24102432
24112433 static const struct qcom_reset_map gcc_sc7180_resets[] = {
drivers/clk/qcom/gcc-sm8150.c+148−0
@@ -1616,6 +1616,36 @@ static struct clk_branch gcc_gpu_cfg_ahb_clk = { · 1615 unmodified lines
16161616 },
16171617 };
16181618
1619+static struct clk_branch gcc_gpu_gpll0_clk_src = {
1620+ .clkr = {
1621+ .enable_reg = 0x52004,
1622+ .enable_mask = BIT(15),
1623+ .hw.init = &(struct clk_init_data){
1624+ .name = "gcc_gpu_gpll0_clk_src",
1625+ .parent_hws = (const struct clk_hw *[]){
1626+ &gpll0.clkr.hw },
1627+ .num_parents = 1,
1628+ .flags = CLK_SET_RATE_PARENT,
1629+ .ops = &clk_branch2_ops,
1630+ },
1631+ },
1632+};
1633+
1634+static struct clk_branch gcc_gpu_gpll0_div_clk_src = {
1635+ .clkr = {
1636+ .enable_reg = 0x52004,
1637+ .enable_mask = BIT(16),
1638+ .hw.init = &(struct clk_init_data){
1639+ .name = "gcc_gpu_gpll0_div_clk_src",
1640+ .parent_hws = (const struct clk_hw *[]){
1641+ &gcc_gpu_gpll0_clk_src.clkr.hw },
1642+ .num_parents = 1,
1643+ .flags = CLK_SET_RATE_PARENT,
1644+ .ops = &clk_branch2_ops,
1645+ },
1646+ },
1647+};
1648+
16191649 static struct clk_branch gcc_gpu_iref_clk = {
16201650 .halt_reg = 0x8c010,
16211651 .halt_check = BRANCH_HALT,
@@ -1698,6 +1728,36 @@ static struct clk_branch gcc_npu_cfg_ahb_clk = { · 76 unmodified lines
16981728 },
16991729 };
17001730
1731+static struct clk_branch gcc_npu_gpll0_clk_src = {
1732+ .clkr = {
1733+ .enable_reg = 0x52004,
1734+ .enable_mask = BIT(18),
1735+ .hw.init = &(struct clk_init_data){
1736+ .name = "gcc_npu_gpll0_clk_src",
1737+ .parent_hws = (const struct clk_hw *[]){
1738+ &gpll0.clkr.hw },
1739+ .num_parents = 1,
1740+ .flags = CLK_SET_RATE_PARENT,
1741+ .ops = &clk_branch2_ops,
1742+ },
1743+ },
1744+};
1745+
1746+static struct clk_branch gcc_npu_gpll0_div_clk_src = {
1747+ .clkr = {
1748+ .enable_reg = 0x52004,
1749+ .enable_mask = BIT(19),
1750+ .hw.init = &(struct clk_init_data){
1751+ .name = "gcc_npu_gpll0_div_clk_src",
1752+ .parent_hws = (const struct clk_hw *[]){
1753+ &gcc_npu_gpll0_clk_src.clkr.hw },
1754+ .num_parents = 1,
1755+ .flags = CLK_SET_RATE_PARENT,
1756+ .ops = &clk_branch2_ops,
1757+ },
1758+ },
1759+};
1760+
17011761 static struct clk_branch gcc_npu_trig_clk = {
17021762 .halt_reg = 0x4d00c,
17031763 .halt_check = BRANCH_VOTED,
@@ -2812,6 +2872,45 @@ static struct clk_branch gcc_ufs_card_phy_aux_hw_ctl_clk = { · 1108 unmodified lines
28122872 },
28132873 };
28142874
2875+/* external clocks so add BRANCH_HALT_SKIP */
2876+static struct clk_branch gcc_ufs_card_rx_symbol_0_clk = {
2877+ .halt_check = BRANCH_HALT_SKIP,
2878+ .clkr = {
2879+ .enable_reg = 0x7501c,
2880+ .enable_mask = BIT(0),
2881+ .hw.init = &(struct clk_init_data){
2882+ .name = "gcc_ufs_card_rx_symbol_0_clk",
2883+ .ops = &clk_branch2_ops,
2884+ },
2885+ },
2886+};
2887+
2888+/* external clocks so add BRANCH_HALT_SKIP */
2889+static struct clk_branch gcc_ufs_card_rx_symbol_1_clk = {
2890+ .halt_check = BRANCH_HALT_SKIP,
2891+ .clkr = {
2892+ .enable_reg = 0x750ac,
2893+ .enable_mask = BIT(0),
2894+ .hw.init = &(struct clk_init_data){
2895+ .name = "gcc_ufs_card_rx_symbol_1_clk",
2896+ .ops = &clk_branch2_ops,
2897+ },
2898+ },
2899+};
2900+
2901+/* external clocks so add BRANCH_HALT_SKIP */
2902+static struct clk_branch gcc_ufs_card_tx_symbol_0_clk = {
2903+ .halt_check = BRANCH_HALT_SKIP,
2904+ .clkr = {
2905+ .enable_reg = 0x75018,
2906+ .enable_mask = BIT(0),
2907+ .hw.init = &(struct clk_init_data){
2908+ .name = "gcc_ufs_card_tx_symbol_0_clk",
2909+ .ops = &clk_branch2_ops,
2910+ },
2911+ },
2912+};
2913+
28152914 static struct clk_branch gcc_ufs_card_unipro_core_clk = {
28162915 .halt_reg = 0x75058,
28172916 .halt_check = BRANCH_HALT,
@@ -2992,6 +3091,45 @@ static struct clk_branch gcc_ufs_phy_phy_aux_hw_ctl_clk = { · 174 unmodified lines
29923091 },
29933092 };
29943093
3094+/* external clocks so add BRANCH_HALT_SKIP */
3095+static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = {
3096+ .halt_check = BRANCH_HALT_SKIP,
3097+ .clkr = {
3098+ .enable_reg = 0x7701c,
3099+ .enable_mask = BIT(0),
3100+ .hw.init = &(struct clk_init_data){
3101+ .name = "gcc_ufs_phy_rx_symbol_0_clk",
3102+ .ops = &clk_branch2_ops,
3103+ },
3104+ },
3105+};
3106+
3107+/* external clocks so add BRANCH_HALT_SKIP */
3108+static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = {
3109+ .halt_check = BRANCH_HALT_SKIP,
3110+ .clkr = {
3111+ .enable_reg = 0x770ac,
3112+ .enable_mask = BIT(0),
3113+ .hw.init = &(struct clk_init_data){
3114+ .name = "gcc_ufs_phy_rx_symbol_1_clk",
3115+ .ops = &clk_branch2_ops,
3116+ },
3117+ },
3118+};
3119+
3120+/* external clocks so add BRANCH_HALT_SKIP */
3121+static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = {
3122+ .halt_check = BRANCH_HALT_SKIP,
3123+ .clkr = {
3124+ .enable_reg = 0x77018,
3125+ .enable_mask = BIT(0),
3126+ .hw.init = &(struct clk_init_data){
3127+ .name = "gcc_ufs_phy_tx_symbol_0_clk",
3128+ .ops = &clk_branch2_ops,
3129+ },
3130+ },
3131+};
3132+
29953133 static struct clk_branch gcc_ufs_phy_unipro_core_clk = {
29963134 .halt_reg = 0x77058,
29973135 .halt_check = BRANCH_HALT,
@@ -3374,12 +3512,16 @@ static struct clk_regmap *gcc_sm8150_clocks[] = { · 376 unmodified lines
33743512 [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
33753513 [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr,
33763514 [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr,
3515+ [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr,
3516+ [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr,
33773517 [GCC_GPU_IREF_CLK] = &gcc_gpu_iref_clk.clkr,
33783518 [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr,
33793519 [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr,
33803520 [GCC_NPU_AT_CLK] = &gcc_npu_at_clk.clkr,
33813521 [GCC_NPU_AXI_CLK] = &gcc_npu_axi_clk.clkr,
33823522 [GCC_NPU_CFG_AHB_CLK] = &gcc_npu_cfg_ahb_clk.clkr,
3523+ [GCC_NPU_GPLL0_CLK_SRC] = &gcc_npu_gpll0_clk_src.clkr,
3524+ [GCC_NPU_GPLL0_DIV_CLK_SRC] = &gcc_npu_gpll0_div_clk_src.clkr,
33833525 [GCC_NPU_TRIG_CLK] = &gcc_npu_trig_clk.clkr,
33843526 [GCC_PCIE0_PHY_REFGEN_CLK] = &gcc_pcie0_phy_refgen_clk.clkr,
33853527 [GCC_PCIE1_PHY_REFGEN_CLK] = &gcc_pcie1_phy_refgen_clk.clkr,
@@ -3484,6 +3626,9 @@ static struct clk_regmap *gcc_sm8150_clocks[] = { · 98 unmodified lines
34843626 [GCC_UFS_CARD_PHY_AUX_CLK_SRC] = &gcc_ufs_card_phy_aux_clk_src.clkr,
34853627 [GCC_UFS_CARD_PHY_AUX_HW_CTL_CLK] =
34863628 &gcc_ufs_card_phy_aux_hw_ctl_clk.clkr,
3629+ [GCC_UFS_CARD_RX_SYMBOL_0_CLK] = &gcc_ufs_card_rx_symbol_0_clk.clkr,
3630+ [GCC_UFS_CARD_RX_SYMBOL_1_CLK] = &gcc_ufs_card_rx_symbol_1_clk.clkr,
3631+ [GCC_UFS_CARD_TX_SYMBOL_0_CLK] = &gcc_ufs_card_tx_symbol_0_clk.clkr,
34873632 [GCC_UFS_CARD_UNIPRO_CORE_CLK] = &gcc_ufs_card_unipro_core_clk.clkr,
34883633 [GCC_UFS_CARD_UNIPRO_CORE_CLK_SRC] =
34893634 &gcc_ufs_card_unipro_core_clk_src.clkr,
@@ -3501,6 +3646,9 @@ static struct clk_regmap *gcc_sm8150_clocks[] = { · 11 unmodified lines
35013646 [GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr,
35023647 [GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr,
35033648 [GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK] = &gcc_ufs_phy_phy_aux_hw_ctl_clk.clkr,
3649+ [GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr,
3650+ [GCC_UFS_PHY_RX_SYMBOL_1_CLK] = &gcc_ufs_phy_rx_symbol_1_clk.clkr,
3651+ [GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr,
35043652 [GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr,
35053653 [GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] =
35063654 &gcc_ufs_phy_unipro_core_clk_src.clkr,
drivers/clk/qcom/gdsc.c+23−0
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111 #include <linux/ktime.h>
1212 #include <linux/pm_domain.h>
1313 #include <linux/regmap.h>
14+#include <linux/regulator/consumer.h>
1415 #include <linux/reset-controller.h>
1516 #include <linux/slab.h>
1617 #include "gdsc.h"
@@ -112,6 +113,12 @@ static int gdsc_toggle_logic(struct gdsc *sc, enum gdsc_status status) · 95 unmodified lines
112113 int ret;
113114 u32 val = (status == GDSC_ON) ? 0 : SW_COLLAPSE_MASK;
114115
116+ if (status == GDSC_ON && sc->rsupply) {
117+ ret = regulator_enable(sc->rsupply);
118+ if (ret < 0)
119+ return ret;
120+ }
121+
115122 ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val);
116123 if (ret)
117124 return ret;
@@ -143,6 +150,13 @@ static int gdsc_toggle_logic(struct gdsc *sc, enum gdsc_status status) · 25 unmodified lines
143150
144151 ret = gdsc_poll_status(sc, status);
145152 WARN(ret, "%s status stuck at 'o%s'", sc->pd.name, status ? "ff" : "n");
153+
154+ if (!ret && status == GDSC_OFF && sc->rsupply) {
155+ ret = regulator_disable(sc->rsupply);
156+ if (ret < 0)
157+ return ret;
158+ }
159+
146160 return ret;
147161 }
148162
@@ -371,6 +385,15 @@ int gdsc_register(struct gdsc_desc *desc, · 222 unmodified lines
371385 if (!data->domains)
372386 return -ENOMEM;
373387
388+ for (i = 0; i < num; i++) {
389+ if (!scs[i] || !scs[i]->supply)
390+ continue;
391+
392+ scs[i]->rsupply = devm_regulator_get(dev, scs[i]->supply);
393+ if (IS_ERR(scs[i]->rsupply))
394+ return PTR_ERR(scs[i]->rsupply);
395+ }
396+
374397 data->num_domains = num;
375398 for (i = 0; i < num; i++) {
376399 if (!scs[i])
drivers/clk/qcom/gdsc.h+4−0
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010 #include <linux/pm_domain.h>
1111
1212 struct regmap;
13+struct regulator;
1314 struct reset_controller_dev;
1415
1516 /**
@@ -52,6 +53,9 @@ struct gdsc { · 36 unmodified lines
5253 struct reset_controller_dev *rcdev;
5354 unsigned int *resets;
5455 unsigned int reset_count;
56+
57+ const char *supply;
58+ struct regulator *rsupply;
5559 };
5660
5761 struct gdsc_desc {
drivers/clk/qcom/mmcc-msm8996.c+2−0
@@ -3064,7 +3064,9 @@ static struct gdsc gpu_gx_gdsc = { · 3063 unmodified lines
30643064 .name = "gpu_gx",
30653065 },
30663066 .pwrsts = PWRSTS_OFF_ON,
3067+ .parent = &gpu_gdsc.pd,
30673068 .flags = CLAMP_IO,
3069+ .supply = "vdd-gfx",
30683070 };
30693071
30703072 static struct clk_regmap *mmcc_msm8996_clocks[] = {
drivers/clk/renesas/Kconfig+5−3
@@ -8,6 +8,7 @@ config CLK_RENESAS · 7 unmodified lines
88 select CLK_R7S9210 if ARCH_R7S9210
99 select CLK_R8A73A4 if ARCH_R8A73A4
1010 select CLK_R8A7740 if ARCH_R8A7740
11+ select CLK_R8A7742 if ARCH_R8A7742
1112 select CLK_R8A7743 if ARCH_R8A7743 || ARCH_R8A7744
1213 select CLK_R8A7745 if ARCH_R8A7745
1314 select CLK_R8A77470 if ARCH_R8A77470
@@ -55,6 +56,10 @@ config CLK_R8A7740 · 41 unmodified lines
5556 select CLK_RENESAS_CPG_MSTP
5657 select CLK_RENESAS_DIV6
5758
59+config CLK_R8A7742
60+ bool "RZ/G1H clock support" if COMPILE_TEST
61+ select CLK_RCAR_GEN2_CPG
62+
5863 config CLK_R8A7743
5964 bool "RZ/G1M clock support" if COMPILE_TEST
6065 select CLK_RCAR_GEN2_CPG
@@ -90,12 +95,10 @@ config CLK_R8A7779 · 29 unmodified lines
9095 config CLK_R8A7790
9196 bool "R-Car H2 clock support" if COMPILE_TEST
9297 select CLK_RCAR_GEN2_CPG
93− select CLK_RENESAS_DIV6
9498
9599 config CLK_R8A7791
96100 bool "R-Car M2-W/N clock support" if COMPILE_TEST
97101 select CLK_RCAR_GEN2_CPG
98− select CLK_RENESAS_DIV6
99102
100103 config CLK_R8A7792
101104 bool "R-Car V2H clock support" if COMPILE_TEST
@@ -104,7 +107,6 @@ config CLK_R8A7792 · 2 unmodified lines
104107 config CLK_R8A7794
105108 bool "R-Car E2 clock support" if COMPILE_TEST
106109 select CLK_RCAR_GEN2_CPG
107− select CLK_RENESAS_DIV6
108110
109111 config CLK_R8A7795
110112 bool "R-Car H3 clock support" if COMPILE_TEST
drivers/clk/renesas/Makefile+1−0
@@ -5,6 +5,7 @@ obj-$(CONFIG_CLK_RZA1) += clk-rz.o · 4 unmodified lines
55 obj-$(CONFIG_CLK_R7S9210) += r7s9210-cpg-mssr.o
66 obj-$(CONFIG_CLK_R8A73A4) += clk-r8a73a4.o
77 obj-$(CONFIG_CLK_R8A7740) += clk-r8a7740.o
8+obj-$(CONFIG_CLK_R8A7742) += r8a7742-cpg-mssr.o
89 obj-$(CONFIG_CLK_R8A7743) += r8a7743-cpg-mssr.o
910 obj-$(CONFIG_CLK_R8A7745) += r8a7745-cpg-mssr.o
1011 obj-$(CONFIG_CLK_R8A77470) += r8a77470-cpg-mssr.o
drivers/clk/renesas/r8a7742-cpg-mssr.c+275−0
@@ -0,0 +1,275 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * r8a7742 Clock Pulse Generator / Module Standby and Software Reset
4+ *
5+ * Copyright (C) 2020 Renesas Electronics Corp.
6+ */
7+
8+#include <linux/device.h>
9+#include <linux/init.h>
10+#include <linux/kernel.h>
11+#include <linux/soc/renesas/rcar-rst.h>
12+
13+#include <dt-bindings/clock/r8a7742-cpg-mssr.h>
14+
15+#include "renesas-cpg-mssr.h"
16+#include "rcar-gen2-cpg.h"
17+
18+enum clk_ids {
19+ /* Core Clock Outputs exported to DT */
20+ LAST_DT_CORE_CLK = R8A7742_CLK_OSC,
21+
22+ /* External Input Clocks */
23+ CLK_EXTAL,
24+ CLK_USB_EXTAL,
25+
26+ /* Internal Core Clocks */
27+ CLK_MAIN,
28+ CLK_PLL0,
29+ CLK_PLL1,
30+ CLK_PLL3,
31+ CLK_PLL1_DIV2,
32+
33+ /* Module Clocks */
34+ MOD_CLK_BASE
35+};
36+
37+static const struct cpg_core_clk r8a7742_core_clks[] __initconst = {
38+ /* External Clock Inputs */
39+ DEF_INPUT("extal", CLK_EXTAL),
40+ DEF_INPUT("usb_extal", CLK_USB_EXTAL),
41+
42+ /* Internal Core Clocks */
43+ DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN2_MAIN, CLK_EXTAL),
44+ DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN2_PLL0, CLK_MAIN),
45+ DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN2_PLL1, CLK_MAIN),
46+ DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN2_PLL3, CLK_MAIN),
47+
48+ DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
49+
50+ /* Core Clock Outputs */
51+ DEF_BASE("z", R8A7742_CLK_Z, CLK_TYPE_GEN2_Z, CLK_PLL0),
52+ DEF_BASE("lb", R8A7742_CLK_LB, CLK_TYPE_GEN2_LB, CLK_PLL1),
53+ DEF_BASE("sdh", R8A7742_CLK_SDH, CLK_TYPE_GEN2_SDH, CLK_PLL1),
54+ DEF_BASE("sd0", R8A7742_CLK_SD0, CLK_TYPE_GEN2_SD0, CLK_PLL1),
55+ DEF_BASE("sd1", R8A7742_CLK_SD1, CLK_TYPE_GEN2_SD1, CLK_PLL1),
56+ DEF_BASE("qspi", R8A7742_CLK_QSPI, CLK_TYPE_GEN2_QSPI, CLK_PLL1_DIV2),
57+ DEF_BASE("rcan", R8A7742_CLK_RCAN, CLK_TYPE_GEN2_RCAN, CLK_USB_EXTAL),
58+
59+ DEF_FIXED("z2", R8A7742_CLK_Z2, CLK_PLL1, 2, 1),
60+ DEF_FIXED("zg", R8A7742_CLK_ZG, CLK_PLL1, 3, 1),
61+ DEF_FIXED("zx", R8A7742_CLK_ZX, CLK_PLL1, 3, 1),
62+ DEF_FIXED("zs", R8A7742_CLK_ZS, CLK_PLL1, 6, 1),
63+ DEF_FIXED("hp", R8A7742_CLK_HP, CLK_PLL1, 12, 1),
64+ DEF_FIXED("b", R8A7742_CLK_B, CLK_PLL1, 12, 1),
65+ DEF_FIXED("p", R8A7742_CLK_P, CLK_PLL1, 24, 1),
66+ DEF_FIXED("cl", R8A7742_CLK_CL, CLK_PLL1, 48, 1),
67+ DEF_FIXED("m2", R8A7742_CLK_M2, CLK_PLL1, 8, 1),
68+ DEF_FIXED("zb3", R8A7742_CLK_ZB3, CLK_PLL3, 4, 1),
69+ DEF_FIXED("zb3d2", R8A7742_CLK_ZB3D2, CLK_PLL3, 8, 1),
70+ DEF_FIXED("ddr", R8A7742_CLK_DDR, CLK_PLL3, 8, 1),
71+ DEF_FIXED("mp", R8A7742_CLK_MP, CLK_PLL1_DIV2, 15, 1),
72+ DEF_FIXED("cp", R8A7742_CLK_CP, CLK_EXTAL, 2, 1),
73+ DEF_FIXED("r", R8A7742_CLK_R, CLK_PLL1, 49152, 1),
74+ DEF_FIXED("osc", R8A7742_CLK_OSC, CLK_PLL1, 12288, 1),
75+
76+ DEF_DIV6P1("sd2", R8A7742_CLK_SD2, CLK_PLL1_DIV2, 0x078),
77+ DEF_DIV6P1("sd3", R8A7742_CLK_SD3, CLK_PLL1_DIV2, 0x26c),
78+ DEF_DIV6P1("mmc0", R8A7742_CLK_MMC0, CLK_PLL1_DIV2, 0x240),
79+ DEF_DIV6P1("mmc1", R8A7742_CLK_MMC1, CLK_PLL1_DIV2, 0x244),
80+};
81+
82+static const struct mssr_mod_clk r8a7742_mod_clks[] __initconst = {
83+ DEF_MOD("msiof0", 0, R8A7742_CLK_MP),
84+ DEF_MOD("vcp1", 100, R8A7742_CLK_ZS),
85+ DEF_MOD("vcp0", 101, R8A7742_CLK_ZS),
86+ DEF_MOD("vpc1", 102, R8A7742_CLK_ZS),
87+ DEF_MOD("vpc0", 103, R8A7742_CLK_ZS),
88+ DEF_MOD("tmu1", 111, R8A7742_CLK_P),
89+ DEF_MOD("3dg", 112, R8A7742_CLK_ZG),
90+ DEF_MOD("2d-dmac", 115, R8A7742_CLK_ZS),
91+ DEF_MOD("fdp1-2", 117, R8A7742_CLK_ZS),
92+ DEF_MOD("fdp1-1", 118, R8A7742_CLK_ZS),
93+ DEF_MOD("fdp1-0", 119, R8A7742_CLK_ZS),
94+ DEF_MOD("tmu3", 121, R8A7742_CLK_P),
95+ DEF_MOD("tmu2", 122, R8A7742_CLK_P),
96+ DEF_MOD("cmt0", 124, R8A7742_CLK_R),
97+ DEF_MOD("tmu0", 125, R8A7742_CLK_CP),
98+ DEF_MOD("vsp1du1", 127, R8A7742_CLK_ZS),
99+ DEF_MOD("vsp1du0", 128, R8A7742_CLK_ZS),
100+ DEF_MOD("vsp1-sy", 131, R8A7742_CLK_ZS),
101+ DEF_MOD("scifa2", 202, R8A7742_CLK_MP),
102+ DEF_MOD("scifa1", 203, R8A7742_CLK_MP),
103+ DEF_MOD("scifa0", 204, R8A7742_CLK_MP),
104+ DEF_MOD("msiof2", 205, R8A7742_CLK_MP),
105+ DEF_MOD("scifb0", 206, R8A7742_CLK_MP),
106+ DEF_MOD("scifb1", 207, R8A7742_CLK_MP),
107+ DEF_MOD("msiof1", 208, R8A7742_CLK_MP),
108+ DEF_MOD("msiof3", 215, R8A7742_CLK_MP),
109+ DEF_MOD("scifb2", 216, R8A7742_CLK_MP),
110+ DEF_MOD("sys-dmac1", 218, R8A7742_CLK_ZS),
111+ DEF_MOD("sys-dmac0", 219, R8A7742_CLK_ZS),
112+ DEF_MOD("iic2", 300, R8A7742_CLK_HP),
113+ DEF_MOD("tpu0", 304, R8A7742_CLK_CP),
114+ DEF_MOD("mmcif1", 305, R8A7742_CLK_MMC1),
115+ DEF_MOD("scif2", 310, R8A7742_CLK_P),
116+ DEF_MOD("sdhi3", 311, R8A7742_CLK_SD3),
117+ DEF_MOD("sdhi2", 312, R8A7742_CLK_SD2),
118+ DEF_MOD("sdhi1", 313, R8A7742_CLK_SD1),
119+ DEF_MOD("sdhi0", 314, R8A7742_CLK_SD0),
120+ DEF_MOD("mmcif0", 315, R8A7742_CLK_MMC0),
121+ DEF_MOD("iic0", 318, R8A7742_CLK_HP),
122+ DEF_MOD("pciec", 319, R8A7742_CLK_MP),
123+ DEF_MOD("iic1", 323, R8A7742_CLK_HP),
124+ DEF_MOD("usb3.0", 328, R8A7742_CLK_MP),
125+ DEF_MOD("cmt1", 329, R8A7742_CLK_R),
126+ DEF_MOD("usbhs-dmac0", 330, R8A7742_CLK_HP),
127+ DEF_MOD("usbhs-dmac1", 331, R8A7742_CLK_HP),
128+ DEF_MOD("rwdt", 402, R8A7742_CLK_R),
129+ DEF_MOD("irqc", 407, R8A7742_CLK_CP),
130+ DEF_MOD("intc-sys", 408, R8A7742_CLK_ZS),
131+ DEF_MOD("audio-dmac1", 501, R8A7742_CLK_HP),
132+ DEF_MOD("audio-dmac0", 502, R8A7742_CLK_HP),
133+ DEF_MOD("thermal", 522, CLK_EXTAL),
134+ DEF_MOD("pwm", 523, R8A7742_CLK_P),
135+ DEF_MOD("usb-ehci", 703, R8A7742_CLK_MP),
136+ DEF_MOD("usbhs", 704, R8A7742_CLK_HP),
137+ DEF_MOD("hscif1", 716, R8A7742_CLK_ZS),
138+ DEF_MOD("hscif0", 717, R8A7742_CLK_ZS),
139+ DEF_MOD("scif1", 720, R8A7742_CLK_P),
140+ DEF_MOD("scif0", 721, R8A7742_CLK_P),
141+ DEF_MOD("du2", 722, R8A7742_CLK_ZX),
142+ DEF_MOD("du1", 723, R8A7742_CLK_ZX),
143+ DEF_MOD("du0", 724, R8A7742_CLK_ZX),
144+ DEF_MOD("lvds1", 725, R8A7742_CLK_ZX),
145+ DEF_MOD("lvds0", 726, R8A7742_CLK_ZX),
146+ DEF_MOD("r-gp2d", 807, R8A7742_CLK_ZX),
147+ DEF_MOD("vin3", 808, R8A7742_CLK_ZG),
148+ DEF_MOD("vin2", 809, R8A7742_CLK_ZG),
149+ DEF_MOD("vin1", 810, R8A7742_CLK_ZG),
150+ DEF_MOD("vin0", 811, R8A7742_CLK_ZG),
151+ DEF_MOD("etheravb", 812, R8A7742_CLK_HP),
152+ DEF_MOD("ether", 813, R8A7742_CLK_P),
153+ DEF_MOD("sata1", 814, R8A7742_CLK_ZS),
154+ DEF_MOD("sata0", 815, R8A7742_CLK_ZS),
155+ DEF_MOD("imr-x2-1", 820, R8A7742_CLK_ZG),
156+ DEF_MOD("imr-x2-0", 821, R8A7742_CLK_HP),
157+ DEF_MOD("imr-lsx2-1", 822, R8A7742_CLK_P),
158+ DEF_MOD("imr-lsx2-0", 823, R8A7742_CLK_ZS),
159+ DEF_MOD("gpio5", 907, R8A7742_CLK_CP),
160+ DEF_MOD("gpio4", 908, R8A7742_CLK_CP),
161+ DEF_MOD("gpio3", 909, R8A7742_CLK_CP),
162+ DEF_MOD("gpio2", 910, R8A7742_CLK_CP),
163+ DEF_MOD("gpio1", 911, R8A7742_CLK_CP),
164+ DEF_MOD("gpio0", 912, R8A7742_CLK_CP),
165+ DEF_MOD("can1", 915, R8A7742_CLK_P),
166+ DEF_MOD("can0", 916, R8A7742_CLK_P),
167+ DEF_MOD("qspi_mod", 917, R8A7742_CLK_QSPI),
168+ DEF_MOD("iicdvfs", 926, R8A7742_CLK_CP),
169+ DEF_MOD("i2c3", 928, R8A7742_CLK_HP),
170+ DEF_MOD("i2c2", 929, R8A7742_CLK_HP),
171+ DEF_MOD("i2c1", 930, R8A7742_CLK_HP),
172+ DEF_MOD("i2c0", 931, R8A7742_CLK_HP),
173+ DEF_MOD("ssi-all", 1005, R8A7742_CLK_P),
174+ DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)),
175+ DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)),
176+ DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)),
177+ DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)),
178+ DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)),
179+ DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)),
180+ DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)),
181+ DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)),
182+ DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)),
183+ DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)),
184+ DEF_MOD("scu-all", 1017, R8A7742_CLK_P),
185+ DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)),
186+ DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)),
187+ DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)),
188+ DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)),
189+ DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)),
190+ DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)),
191+ DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)),
192+ DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)),
193+ DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)),
194+ DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)),
195+ DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)),
196+ DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)),
197+ DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)),
198+ DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)),
199+};
200+
201+static const unsigned int r8a7742_crit_mod_clks[] __initconst = {
202+ MOD_CLK_ID(402), /* RWDT */
203+ MOD_CLK_ID(408), /* INTC-SYS (GIC) */
204+};
205+
206+/*
207+ * CPG Clock Data
208+ */
209+
210+/*
211+ * MD EXTAL PLL0 PLL1 PLL3
212+ * 14 13 19 (MHz) *1 *1
213+ *---------------------------------------------------
214+ * 0 0 0 15 x172/2 x208/2 x106
215+ * 0 0 1 15 x172/2 x208/2 x88
216+ * 0 1 0 20 x130/2 x156/2 x80
217+ * 0 1 1 20 x130/2 x156/2 x66
218+ * 1 0 0 26 / 2 x200/2 x240/2 x122
219+ * 1 0 1 26 / 2 x200/2 x240/2 x102
220+ * 1 1 0 30 / 2 x172/2 x208/2 x106
221+ * 1 1 1 30 / 2 x172/2 x208/2 x88
222+ *
223+ * *1 : Table 7.5a indicates VCO output (PLLx = VCO/2)
224+ */
225+#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \
226+ (((md) & BIT(13)) >> 12) | \
227+ (((md) & BIT(19)) >> 19))
228+
229+static const struct rcar_gen2_cpg_pll_config cpg_pll_configs[8] __initconst = {
230+ /* EXTAL div PLL1 mult PLL3 mult */
231+ { 1, 208, 106, },
232+ { 1, 208, 88, },
233+ { 1, 156, 80, },
234+ { 1, 156, 66, },
235+ { 2, 240, 122, },
236+ { 2, 240, 102, },
237+ { 2, 208, 106, },
238+ { 2, 208, 88, },
239+};
240+
241+static int __init r8a7742_cpg_mssr_init(struct device *dev)
242+{
243+ const struct rcar_gen2_cpg_pll_config *cpg_pll_config;
244+ u32 cpg_mode;
245+ int error;
246+
247+ error = rcar_rst_read_mode_pins(&cpg_mode);
248+ if (error)
249+ return error;
250+
251+ cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
252+
253+ return rcar_gen2_cpg_init(cpg_pll_config, 2, cpg_mode);
254+}
255+
256+const struct cpg_mssr_info r8a7742_cpg_mssr_info __initconst = {
257+ /* Core Clocks */
258+ .core_clks = r8a7742_core_clks,
259+ .num_core_clks = ARRAY_SIZE(r8a7742_core_clks),
260+ .last_dt_core_clk = LAST_DT_CORE_CLK,
261+ .num_total_core_clks = MOD_CLK_BASE,
262+
263+ /* Module Clocks */
264+ .mod_clks = r8a7742_mod_clks,
265+ .num_mod_clks = ARRAY_SIZE(r8a7742_mod_clks),
266+ .num_hw_mod_clks = 12 * 32,
267+
268+ /* Critical Module Clocks */
269+ .crit_mod_clks = r8a7742_crit_mod_clks,
270+ .num_crit_mod_clks = ARRAY_SIZE(r8a7742_crit_mod_clks),
271+
272+ /* Callbacks */
273+ .init = r8a7742_cpg_mssr_init,
274+ .cpg_clk_register = rcar_gen2_cpg_clk_register,
275+};
drivers/clk/renesas/r9a06g032-clocks.c+3−3
@@ -1,6 +1,6 @@
11 // SPDX-License-Identifier: GPL-2.0
22 /*
3− * R9A09G032 clock driver
3+ * R9A06G032 clock driver
44 *
55 * Copyright (C) 2018 Renesas Electronics Europe Limited
66 *
@@ -338,8 +338,8 @@ clk_rdesc_get(struct r9a06g032_priv *clocks, · 331 unmodified lines
338338 }
339339
340340 /*
341− * This implements the R9A09G032 clock gate 'driver'. We cannot use the system's
342− * clock gate framework as the gates on the R9A09G032 have a special enabling
341+ * This implements the R9A06G032 clock gate 'driver'. We cannot use the system's
342+ * clock gate framework as the gates on the R9A06G032 have a special enabling
343343 * sequence, therefore we use this little proxy.
344344 */
345345 struct r9a06g032_clk_gate {
drivers/clk/renesas/renesas-cpg-mssr.c+11−3
@@ -673,6 +673,12 @@ static const struct of_device_id cpg_mssr_match[] = { · 672 unmodified lines
673673 .data = &r7s9210_cpg_mssr_info,
674674 },
675675 #endif
676+#ifdef CONFIG_CLK_R8A7742
677+ {
678+ .compatible = "renesas,r8a7742-cpg-mssr",
679+ .data = &r8a7742_cpg_mssr_info,
680+ },
681+#endif
676682 #ifdef CONFIG_CLK_R8A7743
677683 {
678684 .compatible = "renesas,r8a7743-cpg-mssr",
@@ -812,7 +818,8 @@ static int cpg_mssr_suspend_noirq(struct device *dev) · 133 unmodified lines
812818 /* Save module registers with bits under our control */
813819 for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) {
814820 if (priv->smstpcr_saved[reg].mask)
815− priv->smstpcr_saved[reg].val =
821+ priv->smstpcr_saved[reg].val = priv->stbyctrl ?
822+ readb(priv->base + STBCR(reg)) :
816823 readl(priv->base + SMSTPCR(reg));
817824 }
818825
@@ -872,8 +879,9 @@ static int cpg_mssr_resume_noirq(struct device *dev) · 53 unmodified lines
872879 }
873880
874881 if (!i)
875− dev_warn(dev, "Failed to enable SMSTP %p[0x%x]\n",
876− priv->base + SMSTPCR(reg), oldval & mask);
882+ dev_warn(dev, "Failed to enable %s%u[0x%x]\n",
883+ priv->stbyctrl ? "STB" : "SMSTP", reg,
884+ oldval & mask);
877885 }
878886
879887 return 0;
drivers/clk/renesas/renesas-cpg-mssr.h+1−0
@@ -155,6 +155,7 @@ struct cpg_mssr_info { · 154 unmodified lines
155155 };
156156
157157 extern const struct cpg_mssr_info r7s9210_cpg_mssr_info;
158+extern const struct cpg_mssr_info r8a7742_cpg_mssr_info;
158159 extern const struct cpg_mssr_info r8a7743_cpg_mssr_info;
159160 extern const struct cpg_mssr_info r8a7745_cpg_mssr_info;
160161 extern const struct cpg_mssr_info r8a77470_cpg_mssr_info;
drivers/clk/samsung/clk-exynos5420.c+10−8
@@ -540,7 +540,7 @@ static const struct samsung_div_clock exynos5800_div_clks[] __initconst = { · 539 unmodified lines
540540
541541 static const struct samsung_gate_clock exynos5800_gate_clks[] __initconst = {
542542 GATE(CLK_ACLK550_CAM, "aclk550_cam", "mout_user_aclk550_cam",
543− GATE_BUS_TOP, 24, 0, 0),
543+ GATE_BUS_TOP, 24, CLK_IS_CRITICAL, 0),
544544 GATE(CLK_ACLK432_SCALER, "aclk432_scaler", "mout_user_aclk432_scaler",
545545 GATE_BUS_TOP, 27, CLK_IS_CRITICAL, 0),
546546 };
@@ -943,25 +943,25 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = { · 396 unmodified lines
943943 GATE(0, "aclk300_jpeg", "mout_user_aclk300_jpeg",
944944 GATE_BUS_TOP, 4, CLK_IGNORE_UNUSED, 0),
945945 GATE(0, "aclk333_432_isp0", "mout_user_aclk333_432_isp0",
946− GATE_BUS_TOP, 5, 0, 0),
946+ GATE_BUS_TOP, 5, CLK_IS_CRITICAL, 0),
947947 GATE(0, "aclk300_gscl", "mout_user_aclk300_gscl",
948948 GATE_BUS_TOP, 6, CLK_IS_CRITICAL, 0),
949949 GATE(0, "aclk333_432_gscl", "mout_user_aclk333_432_gscl",
950950 GATE_BUS_TOP, 7, CLK_IGNORE_UNUSED, 0),
951951 GATE(0, "aclk333_432_isp", "mout_user_aclk333_432_isp",
952− GATE_BUS_TOP, 8, 0, 0),
952+ GATE_BUS_TOP, 8, CLK_IS_CRITICAL, 0),
953953 GATE(CLK_PCLK66_GPIO, "pclk66_gpio", "mout_user_pclk66_gpio",
954954 GATE_BUS_TOP, 9, CLK_IGNORE_UNUSED, 0),
955955 GATE(0, "aclk66_psgen", "mout_user_aclk66_psgen",
956956 GATE_BUS_TOP, 10, CLK_IGNORE_UNUSED, 0),
957957 GATE(0, "aclk266_isp", "mout_user_aclk266_isp",
958− GATE_BUS_TOP, 13, 0, 0),
958+ GATE_BUS_TOP, 13, CLK_IS_CRITICAL, 0),
959959 GATE(0, "aclk166", "mout_user_aclk166",
960960 GATE_BUS_TOP, 14, CLK_IGNORE_UNUSED, 0),
961961 GATE(CLK_ACLK333, "aclk333", "mout_user_aclk333",
962962 GATE_BUS_TOP, 15, CLK_IS_CRITICAL, 0),
963963 GATE(0, "aclk400_isp", "mout_user_aclk400_isp",
964− GATE_BUS_TOP, 16, 0, 0),
964+ GATE_BUS_TOP, 16, CLK_IS_CRITICAL, 0),
965965 GATE(0, "aclk400_mscl", "mout_user_aclk400_mscl",
966966 GATE_BUS_TOP, 17, CLK_IS_CRITICAL, 0),
967967 GATE(0, "aclk200_disp1", "mout_user_aclk200_disp1",
@@ -1161,9 +1161,11 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = { · 193 unmodified lines
11611161 GATE_IP_GSCL1, 3, 0, 0),
11621162 GATE(CLK_SMMU_FIMCL1, "smmu_fimcl1", "dout_gscl_blk_333",
11631163 GATE_IP_GSCL1, 4, 0, 0),
1164− GATE(CLK_GSCL_WA, "gscl_wa", "sclk_gscl_wa", GATE_IP_GSCL1, 12, 0, 0),
1165− GATE(CLK_GSCL_WB, "gscl_wb", "sclk_gscl_wb", GATE_IP_GSCL1, 13, 0, 0),
1166− GATE(CLK_SMMU_FIMCL3, "smmu_fimcl3,", "dout_gscl_blk_333",
1164+ GATE(CLK_GSCL_WA, "gscl_wa", "sclk_gscl_wa", GATE_IP_GSCL1, 12,
1165+ CLK_IS_CRITICAL, 0),
1166+ GATE(CLK_GSCL_WB, "gscl_wb", "sclk_gscl_wb", GATE_IP_GSCL1, 13,
1167+ CLK_IS_CRITICAL, 0),
1168+ GATE(CLK_SMMU_FIMCL3, "smmu_fimcl3", "dout_gscl_blk_333",
11671169 GATE_IP_GSCL1, 16, 0, 0),
11681170 GATE(CLK_FIMC_LITE3, "fimc_lite3", "aclk333_432_gscl",
11691171 GATE_IP_GSCL1, 17, 0, 0),
drivers/clk/samsung/clk-exynos5433.c+2−1
@@ -1706,7 +1706,8 @@ static const struct samsung_gate_clock peric_gate_clks[] __initconst = { · 1705 unmodified lines
17061706 GATE(CLK_SCLK_PCM1, "sclk_pcm1", "sclk_pcm1_peric",
17071707 ENABLE_SCLK_PERIC, 7, CLK_SET_RATE_PARENT, 0),
17081708 GATE(CLK_SCLK_I2S1, "sclk_i2s1", "sclk_i2s1_peric",
1709− ENABLE_SCLK_PERIC, 6, CLK_SET_RATE_PARENT, 0),
1709+ ENABLE_SCLK_PERIC, 6,
1710+ CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0),
17101711 GATE(CLK_SCLK_SPI2, "sclk_spi2", "sclk_spi2_peric", ENABLE_SCLK_PERIC,
17111712 5, CLK_SET_RATE_PARENT, 0),
17121713 GATE(CLK_SCLK_SPI1, "sclk_spi1", "sclk_spi1_peric", ENABLE_SCLK_PERIC,
drivers/clk/samsung/clk-s3c2443.c+1−1
@@ -387,7 +387,7 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f, · 386 unmodified lines
387387 ARRAY_SIZE(s3c2450_gates));
388388 samsung_clk_register_alias(ctx, s3c2450_aliases,
389389 ARRAY_SIZE(s3c2450_aliases));
390− /* fall through - as s3c2450 extends the s3c2416 clocks */
390+ fallthrough; /* as s3c2450 extends the s3c2416 clocks */
391391 case S3C2416:
392392 samsung_clk_register_div(ctx, s3c2416_dividers,
393393 ARRAY_SIZE(s3c2416_dividers));
drivers/clk/socfpga/Makefile+2−0
@@ -3,3 +3,5 @@ obj-$(CONFIG_ARCH_SOCFPGA) += clk.o clk-gate.o clk-pll.o clk-periph.o · 2 unmodified lines
33 obj-$(CONFIG_ARCH_SOCFPGA) += clk-pll-a10.o clk-periph-a10.o clk-gate-a10.o
44 obj-$(CONFIG_ARCH_STRATIX10) += clk-s10.o
55 obj-$(CONFIG_ARCH_STRATIX10) += clk-pll-s10.o clk-periph-s10.o clk-gate-s10.o
6+obj-$(CONFIG_ARCH_AGILEX) += clk-agilex.o
7+obj-$(CONFIG_ARCH_AGILEX) += clk-pll-s10.o clk-periph-s10.o clk-gate-s10.o
drivers/clk/socfpga/clk-agilex.c+454−0
@@ -0,0 +1,454 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (C) 2019, Intel Corporation
4+ */
5+#include <linux/slab.h>
6+#include <linux/clk-provider.h>
7+#include <linux/of_device.h>
8+#include <linux/of_address.h>
9+#include <linux/platform_device.h>
10+
11+#include <dt-bindings/clock/agilex-clock.h>
12+
13+#include "stratix10-clk.h"
14+
15+static const struct clk_parent_data pll_mux[] = {
16+ { .fw_name = "osc1",
17+ .name = "osc1", },
18+ { .fw_name = "cb-intosc-hs-div2-clk",
19+ .name = "cb-intosc-hs-div2-clk", },
20+ { .fw_name = "f2s-free-clk",
21+ .name = "f2s-free-clk", },
22+};
23+
24+static const struct clk_parent_data cntr_mux[] = {
25+ { .fw_name = "main_pll",
26+ .name = "main_pll", },
27+ { .fw_name = "periph_pll",
28+ .name = "periph_pll", },
29+ { .fw_name = "osc1",
30+ .name = "osc1", },
31+ { .fw_name = "cb-intosc-hs-div2-clk",
32+ .name = "cb-intosc-hs-div2-clk", },
33+ { .fw_name = "f2s-free-clk",
34+ .name = "f2s-free-clk", },
35+};
36+
37+static const struct clk_parent_data boot_mux[] = {
38+ { .fw_name = "osc1",
39+ .name = "osc1", },
40+ { .fw_name = "cb-intosc-hs-div2-clk",
41+ .name = "cb-intosc-hs-div2-clk", },
42+};
43+
44+static const struct clk_parent_data mpu_free_mux[] = {
45+ { .fw_name = "main_pll_c0",
46+ .name = "main_pll_c0", },
47+ { .fw_name = "peri_pll_c0",
48+ .name = "peri_pll_c0", },
49+ { .fw_name = "osc1",
50+ .name = "osc1", },
51+ { .fw_name = "cb-intosc-hs-div2-clk",
52+ .name = "cb-intosc-hs-div2-clk", },
53+ { .fw_name = "f2s-free-clk",
54+ .name = "f2s-free-clk", },
55+};
56+
57+static const struct clk_parent_data noc_free_mux[] = {
58+ { .fw_name = "main_pll_c1",
59+ .name = "main_pll_c1", },
60+ { .fw_name = "peri_pll_c1",
61+ .name = "peri_pll_c1", },
62+ { .fw_name = "osc1",
63+ .name = "osc1", },
64+ { .fw_name = "cb-intosc-hs-div2-clk",
65+ .name = "cb-intosc-hs-div2-clk", },
66+ { .fw_name = "f2s-free-clk",
67+ .name = "f2s-free-clk", },
68+};
69+
70+static const struct clk_parent_data emaca_free_mux[] = {
71+ { .fw_name = "main_pll_c2",
72+ .name = "main_pll_c2", },
73+ { .fw_name = "peri_pll_c2",
74+ .name = "peri_pll_c2", },
75+ { .fw_name = "osc1",
76+ .name = "osc1", },
77+ { .fw_name = "cb-intosc-hs-div2-clk",
78+ .name = "cb-intosc-hs-div2-clk", },
79+ { .fw_name = "f2s-free-clk",
80+ .name = "f2s-free-clk", },
81+};
82+
83+static const struct clk_parent_data emacb_free_mux[] = {
84+ { .fw_name = "main_pll_c3",
85+ .name = "main_pll_c3", },
86+ { .fw_name = "peri_pll_c3",
87+ .name = "peri_pll_c3", },
88+ { .fw_name = "osc1",
89+ .name = "osc1", },
90+ { .fw_name = "cb-intosc-hs-div2-clk",
91+ .name = "cb-intosc-hs-div2-clk", },
92+ { .fw_name = "f2s-free-clk",
93+ .name = "f2s-free-clk", },
94+};
95+
96+static const struct clk_parent_data emac_ptp_free_mux[] = {
97+ { .fw_name = "main_pll_c3",
98+ .name = "main_pll_c3", },
99+ { .fw_name = "peri_pll_c3",
100+ .name = "peri_pll_c3", },
101+ { .fw_name = "osc1",
102+ .name = "osc1", },
103+ { .fw_name = "cb-intosc-hs-div2-clk",
104+ .name = "cb-intosc-hs-div2-clk", },
105+ { .fw_name = "f2s-free-clk",
106+ .name = "f2s-free-clk", },
107+};
108+
109+static const struct clk_parent_data gpio_db_free_mux[] = {
110+ { .fw_name = "main_pll_c3",
111+ .name = "main_pll_c3", },
112+ { .fw_name = "peri_pll_c3",
113+ .name = "peri_pll_c3", },
114+ { .fw_name = "osc1",
115+ .name = "osc1", },
116+ { .fw_name = "cb-intosc-hs-div2-clk",
117+ .name = "cb-intosc-hs-div2-clk", },
118+ { .fw_name = "f2s-free-clk",
119+ .name = "f2s-free-clk", },
120+};
121+
122+static const struct clk_parent_data psi_ref_free_mux[] = {
123+ { .fw_name = "main_pll_c3",
124+ .name = "main_pll_c3", },
125+ { .fw_name = "peri_pll_c3",
126+ .name = "peri_pll_c3", },
127+ { .fw_name = "osc1",
128+ .name = "osc1", },
129+ { .fw_name = "cb-intosc-hs-div2-clk",
130+ .name = "cb-intosc-hs-div2-clk", },
131+ { .fw_name = "f2s-free-clk",
132+ .name = "f2s-free-clk", },
133+};
134+
135+static const struct clk_parent_data sdmmc_free_mux[] = {
136+ { .fw_name = "main_pll_c3",
137+ .name = "main_pll_c3", },
138+ { .fw_name = "peri_pll_c3",
139+ .name = "peri_pll_c3", },
140+ { .fw_name = "osc1",
141+ .name = "osc1", },
142+ { .fw_name = "cb-intosc-hs-div2-clk",
143+ .name = "cb-intosc-hs-div2-clk", },
144+ { .fw_name = "f2s-free-clk",
145+ .name = "f2s-free-clk", },
146+};
147+
148+static const struct clk_parent_data s2f_usr0_free_mux[] = {
149+ { .fw_name = "main_pll_c2",
150+ .name = "main_pll_c2", },
151+ { .fw_name = "peri_pll_c2",
152+ .name = "peri_pll_c2", },
153+ { .fw_name = "osc1",
154+ .name = "osc1", },
155+ { .fw_name = "cb-intosc-hs-div2-clk",
156+ .name = "cb-intosc-hs-div2-clk", },
157+ { .fw_name = "f2s-free-clk",
158+ .name = "f2s-free-clk", },
159+};
160+
161+static const struct clk_parent_data s2f_usr1_free_mux[] = {
162+ { .fw_name = "main_pll_c2",
163+ .name = "main_pll_c2", },
164+ { .fw_name = "peri_pll_c2",
165+ .name = "peri_pll_c2", },
166+ { .fw_name = "osc1",
167+ .name = "osc1", },
168+ { .fw_name = "cb-intosc-hs-div2-clk",
169+ .name = "cb-intosc-hs-div2-clk", },
170+ { .fw_name = "f2s-free-clk",
171+ .name = "f2s-free-clk", },
172+};
173+
174+static const struct clk_parent_data mpu_mux[] = {
175+ { .fw_name = "mpu_free_clk",
176+ .name = "mpu_free_clk", },
177+ { .fw_name = "boot_clk",
178+ .name = "boot_clk", },
179+};
180+
181+static const struct clk_parent_data s2f_usr0_mux[] = {
182+ { .fw_name = "f2s-free-clk",
183+ .name = "f2s-free-clk", },
184+ { .fw_name = "boot_clk",
185+ .name = "boot_clk", },
186+};
187+
188+static const struct clk_parent_data emac_mux[] = {
189+ { .fw_name = "emaca_free_clk",
190+ .name = "emaca_free_clk", },
191+ { .fw_name = "emacb_free_clk",
192+ .name = "emacb_free_clk", },
193+};
194+
195+static const struct clk_parent_data noc_mux[] = {
196+ { .fw_name = "noc_free_clk",
197+ .name = "noc_free_clk", },
198+ { .fw_name = "boot_clk",
199+ .name = "boot_clk", },
200+};
201+
202+/* clocks in AO (always on) controller */
203+static const struct stratix10_pll_clock agilex_pll_clks[] = {
204+ { AGILEX_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0,
205+ 0x0},
206+ { AGILEX_MAIN_PLL_CLK, "main_pll", pll_mux, ARRAY_SIZE(pll_mux),
207+ 0, 0x48},
208+ { AGILEX_PERIPH_PLL_CLK, "periph_pll", pll_mux, ARRAY_SIZE(pll_mux),
209+ 0, 0x9c},
210+};
211+
212+static const struct stratix10_perip_c_clock agilex_main_perip_c_clks[] = {
213+ { AGILEX_MAIN_PLL_C0_CLK, "main_pll_c0", "main_pll", NULL, 1, 0, 0x58},
214+ { AGILEX_MAIN_PLL_C1_CLK, "main_pll_c1", "main_pll", NULL, 1, 0, 0x5C},
215+ { AGILEX_MAIN_PLL_C2_CLK, "main_pll_c2", "main_pll", NULL, 1, 0, 0x64},
216+ { AGILEX_MAIN_PLL_C3_CLK, "main_pll_c3", "main_pll", NULL, 1, 0, 0x68},
217+ { AGILEX_PERIPH_PLL_C0_CLK, "peri_pll_c0", "periph_pll", NULL, 1, 0, 0xAC},
218+ { AGILEX_PERIPH_PLL_C1_CLK, "peri_pll_c1", "periph_pll", NULL, 1, 0, 0xB0},
219+ { AGILEX_PERIPH_PLL_C2_CLK, "peri_pll_c2", "periph_pll", NULL, 1, 0, 0xB8},
220+ { AGILEX_PERIPH_PLL_C3_CLK, "peri_pll_c3", "periph_pll", NULL, 1, 0, 0xBC},
221+};
222+
223+static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = {
224+ { AGILEX_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux),
225+ 0, 0x3C, 0, 0, 0},
226+ { AGILEX_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux),
227+ 0, 0x40, 0, 0, 1},
228+ { AGILEX_L4_SYS_FREE_CLK, "l4_sys_free_clk", "noc_free_clk", NULL, 1, 0,
229+ 0, 4, 0, 0},
230+ { AGILEX_NOC_CLK, "noc_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux),
231+ 0, 0, 0, 0x30, 1},
232+ { AGILEX_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux),
233+ 0, 0xD4, 0, 0x88, 0},
234+ { AGILEX_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux),
235+ 0, 0xD8, 0, 0x88, 1},
236+ { AGILEX_EMAC_PTP_FREE_CLK, "emac_ptp_free_clk", NULL, emac_ptp_free_mux,
237+ ARRAY_SIZE(emac_ptp_free_mux), 0, 0xDC, 0, 0x88, 2},
238+ { AGILEX_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux,
239+ ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3},
240+ { AGILEX_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux,
241+ ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0x88, 4},
242+ { AGILEX_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", NULL, s2f_usr0_free_mux,
243+ ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0, 0},
244+ { AGILEX_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL, s2f_usr1_free_mux,
245+ ARRAY_SIZE(s2f_usr1_free_mux), 0, 0xEC, 0, 0x88, 5},
246+ { AGILEX_PSI_REF_FREE_CLK, "psi_ref_free_clk", NULL, psi_ref_free_mux,
247+ ARRAY_SIZE(psi_ref_free_mux), 0, 0xF0, 0, 0x88, 6},
248+};
249+
250+static const struct stratix10_gate_clock agilex_gate_clks[] = {
251+ { AGILEX_MPU_CLK, "mpu_clk", NULL, mpu_mux, ARRAY_SIZE(mpu_mux), 0, 0x24,
252+ 0, 0, 0, 0, 0x30, 0, 0},
253+ { AGILEX_MPU_PERIPH_CLK, "mpu_periph_clk", "mpu_clk", NULL, 1, 0, 0x24,
254+ 0, 0, 0, 0, 0, 0, 4},
255+ { AGILEX_MPU_L2RAM_CLK, "mpu_l2ram_clk", "mpu_clk", NULL, 1, 0, 0x24,
256+ 0, 0, 0, 0, 0, 0, 2},
257+ { AGILEX_L4_MAIN_CLK, "l4_main_clk", "noc_clk", NULL, 1, 0, 0x24,
258+ 1, 0x44, 0, 2, 0, 0, 0},
259+ { AGILEX_L4_MP_CLK, "l4_mp_clk", "noc_clk", NULL, 1, 0, 0x24,
260+ 2, 0x44, 8, 2, 0, 0, 0},
261+ /*
262+ * The l4_sp_clk feeds a 100 MHz clock to various peripherals, one of them
263+ * being the SP timers, thus cannot get gated.
264+ */
265+ { AGILEX_L4_SP_CLK, "l4_sp_clk", "noc_clk", NULL, 1, CLK_IS_CRITICAL, 0x24,
266+ 3, 0x44, 16, 2, 0, 0, 0},
267+ { AGILEX_CS_AT_CLK, "cs_at_clk", "noc_clk", NULL, 1, 0, 0x24,
268+ 4, 0x44, 24, 2, 0, 0, 0},
269+ { AGILEX_CS_TRACE_CLK, "cs_trace_clk", "noc_clk", NULL, 1, 0, 0x24,
270+ 4, 0x44, 26, 2, 0, 0, 0},
271+ { AGILEX_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x24,
272+ 4, 0x44, 28, 1, 0, 0, 0},
273+ { AGILEX_CS_TIMER_CLK, "cs_timer_clk", "noc_clk", NULL, 1, 0, 0x24,
274+ 5, 0, 0, 0, 0, 0, 0},
275+ { AGILEX_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_usr0_mux, ARRAY_SIZE(s2f_usr0_mux), 0, 0x24,
276+ 6, 0, 0, 0, 0, 0, 0},
277+ { AGILEX_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
278+ 0, 0, 0, 0, 0x94, 26, 0},
279+ { AGILEX_EMAC1_CLK, "emac1_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
280+ 1, 0, 0, 0, 0x94, 27, 0},
281+ { AGILEX_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
282+ 2, 0, 0, 0, 0x94, 28, 0},
283+ { AGILEX_EMAC_PTP_CLK, "emac_ptp_clk", "emac_ptp_free_clk", NULL, 1, 0, 0x7C,
284+ 3, 0, 0, 0, 0, 0, 0},
285+ { AGILEX_GPIO_DB_CLK, "gpio_db_clk", "gpio_db_free_clk", NULL, 1, 0, 0x7C,
286+ 4, 0x98, 0, 16, 0, 0, 0},
287+ { AGILEX_SDMMC_CLK, "sdmmc_clk", "sdmmc_free_clk", NULL, 1, 0, 0x7C,
288+ 5, 0, 0, 0, 0, 0, 4},
289+ { AGILEX_S2F_USER1_CLK, "s2f_user1_clk", "s2f_user1_free_clk", NULL, 1, 0, 0x7C,
290+ 6, 0, 0, 0, 0, 0, 0},
291+ { AGILEX_PSI_REF_CLK, "psi_ref_clk", "psi_ref_free_clk", NULL, 1, 0, 0x7C,
292+ 7, 0, 0, 0, 0, 0, 0},
293+ { AGILEX_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
294+ 8, 0, 0, 0, 0, 0, 0},
295+ { AGILEX_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
296+ 9, 0, 0, 0, 0, 0, 0},
297+ { AGILEX_NAND_CLK, "nand_clk", "l4_main_clk", NULL, 1, 0, 0x7C,
298+ 10, 0, 0, 0, 0, 0, 0},
299+};
300+
301+static int agilex_clk_register_c_perip(const struct stratix10_perip_c_clock *clks,
302+ int nums, struct stratix10_clock_data *data)
303+{
304+ struct clk *clk;
305+ void __iomem *base = data->base;
306+ int i;
307+
308+ for (i = 0; i < nums; i++) {
309+ clk = s10_register_periph(&clks[i], base);
310+ if (IS_ERR(clk)) {
311+ pr_err("%s: failed to register clock %s\n",
312+ __func__, clks[i].name);
313+ continue;
314+ }
315+ data->clk_data.clks[clks[i].id] = clk;
316+ }
317+ return 0;
318+}
319+
320+static int agilex_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock *clks,
321+ int nums, struct stratix10_clock_data *data)
322+{
323+ struct clk *clk;
324+ void __iomem *base = data->base;
325+ int i;
326+
327+ for (i = 0; i < nums; i++) {
328+ clk = s10_register_cnt_periph(&clks[i], base);
329+ if (IS_ERR(clk)) {
330+ pr_err("%s: failed to register clock %s\n",
331+ __func__, clks[i].name);
332+ continue;
333+ }
334+ data->clk_data.clks[clks[i].id] = clk;
335+ }
336+
337+ return 0;
338+}
339+
340+static int agilex_clk_register_gate(const struct stratix10_gate_clock *clks, int nums, struct stratix10_clock_data *data)
341+{
342+ struct clk *clk;
343+ void __iomem *base = data->base;
344+ int i;
345+
346+ for (i = 0; i < nums; i++) {
347+ clk = s10_register_gate(&clks[i], base);
348+ if (IS_ERR(clk)) {
349+ pr_err("%s: failed to register clock %s\n",
350+ __func__, clks[i].name);
351+ continue;
352+ }
353+ data->clk_data.clks[clks[i].id] = clk;
354+ }
355+
356+ return 0;
357+}
358+
359+static int agilex_clk_register_pll(const struct stratix10_pll_clock *clks,
360+ int nums, struct stratix10_clock_data *data)
361+{
362+ struct clk *clk;
363+ void __iomem *base = data->base;
364+ int i;
365+
366+ for (i = 0; i < nums; i++) {
367+ clk = agilex_register_pll(&clks[i], base);
368+ if (IS_ERR(clk)) {
369+ pr_err("%s: failed to register clock %s\n",
370+ __func__, clks[i].name);
371+ continue;
372+ }
373+ data->clk_data.clks[clks[i].id] = clk;
374+ }
375+
376+ return 0;
377+}
378+
379+static struct stratix10_clock_data *__socfpga_agilex_clk_init(struct platform_device *pdev,
380+ int nr_clks)
381+{
382+ struct device_node *np = pdev->dev.of_node;
383+ struct device *dev = &pdev->dev;
384+ struct stratix10_clock_data *clk_data;
385+ struct clk **clk_table;
386+ struct resource *res;
387+ void __iomem *base;
388+ int ret;
389+
390+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
391+ base = devm_ioremap_resource(dev, res);
392+ if (IS_ERR(base))
393+ return ERR_CAST(base);
394+
395+ clk_data = devm_kzalloc(dev, sizeof(*clk_data), GFP_KERNEL);
396+ if (!clk_data)
397+ return ERR_PTR(-ENOMEM);
398+
399+ clk_data->base = base;
400+ clk_table = devm_kcalloc(dev, nr_clks, sizeof(*clk_table), GFP_KERNEL);
401+ if (!clk_table)
402+ return ERR_PTR(-ENOMEM);
403+
404+ clk_data->clk_data.clks = clk_table;
405+ clk_data->clk_data.clk_num = nr_clks;
406+ ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data);
407+ if (ret)
408+ return ERR_PTR(ret);
409+
410+ return clk_data;
411+}
412+
413+static int agilex_clkmgr_probe(struct platform_device *pdev)
414+{
415+ struct stratix10_clock_data *clk_data;
416+
417+ clk_data = __socfpga_agilex_clk_init(pdev, AGILEX_NUM_CLKS);
418+ if (IS_ERR(clk_data))
419+ return PTR_ERR(clk_data);
420+
421+ agilex_clk_register_pll(agilex_pll_clks, ARRAY_SIZE(agilex_pll_clks), clk_data);
422+
423+ agilex_clk_register_c_perip(agilex_main_perip_c_clks,
424+ ARRAY_SIZE(agilex_main_perip_c_clks), clk_data);
425+
426+ agilex_clk_register_cnt_perip(agilex_main_perip_cnt_clks,
427+ ARRAY_SIZE(agilex_main_perip_cnt_clks),
428+ clk_data);
429+
430+ agilex_clk_register_gate(agilex_gate_clks, ARRAY_SIZE(agilex_gate_clks),
431+ clk_data);
432+ return 0;
433+}
434+
435+static const struct of_device_id agilex_clkmgr_match_table[] = {
436+ { .compatible = "intel,agilex-clkmgr",
437+ .data = agilex_clkmgr_probe },
438+ { }
439+};
440+
441+static struct platform_driver agilex_clkmgr_driver = {
442+ .probe = agilex_clkmgr_probe,
443+ .driver = {
444+ .name = "agilex-clkmgr",
445+ .suppress_bind_attrs = true,
446+ .of_match_table = agilex_clkmgr_match_table,
447+ },
448+};
449+
450+static int __init agilex_clk_init(void)
451+{
452+ return platform_driver_register(&agilex_clkmgr_driver);
453+}
454+core_initcall(agilex_clk_init);
drivers/clk/socfpga/clk-gate-s10.c+3−2
@@ -70,7 +70,6 @@ struct clk *s10_register_gate(const struct stratix10_gate_clock *clks, void __io · 69 unmodified lines
7070 struct clk *clk;
7171 struct socfpga_gate_clk *socfpga_clk;
7272 struct clk_init_data init;
73− const char * const *parent_names = clks->parent_names;
7473 const char *parent_name = clks->parent_name;
7574
7675 socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
@@ -108,7 +107,9 @@ struct clk *s10_register_gate(const struct stratix10_gate_clock *clks, void __io · 31 unmodified lines
108107 init.flags = clks->flags;
109108
110109 init.num_parents = clks->num_parents;
111− init.parent_names = parent_names ? parent_names : &parent_name;
110+ init.parent_names = parent_name ? &parent_name : NULL;
111+ if (init.parent_names == NULL)
112+ init.parent_data = clks->parent_data;
112113 socfpga_clk->hw.hw.init = &init;
113114
114115 clk = clk_register(NULL, &socfpga_clk->hw.hw);
drivers/clk/socfpga/clk-periph-s10.c+6−4
@@ -81,7 +81,6 @@ struct clk *s10_register_periph(const struct stratix10_perip_c_clock *clks, · 80 unmodified lines
8181 struct clk_init_data init;
8282 const char *name = clks->name;
8383 const char *parent_name = clks->parent_name;
84− const char * const *parent_names = clks->parent_names;
8584
8685 periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
8786 if (WARN_ON(!periph_clk))
@@ -94,7 +93,9 @@ struct clk *s10_register_periph(const struct stratix10_perip_c_clock *clks, · 6 unmodified lines
9493 init.flags = clks->flags;
9594
9695 init.num_parents = clks->num_parents;
97− init.parent_names = parent_names ? parent_names : &parent_name;
96+ init.parent_names = parent_name ? &parent_name : NULL;
97+ if (init.parent_names == NULL)
98+ init.parent_data = clks->parent_data;
9899
99100 periph_clk->hw.hw.init = &init;
100101
@@ -114,7 +115,6 @@ struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *clks · 13 unmodified lines
114115 struct clk_init_data init;
115116 const char *name = clks->name;
116117 const char *parent_name = clks->parent_name;
117− const char * const *parent_names = clks->parent_names;
118118
119119 periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
120120 if (WARN_ON(!periph_clk))
@@ -137,7 +137,9 @@ struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *clks · 16 unmodified lines
137137 init.flags = clks->flags;
138138
139139 init.num_parents = clks->num_parents;
140− init.parent_names = parent_names ? parent_names : &parent_name;
140+ init.parent_names = parent_name ? &parent_name : NULL;
141+ if (init.parent_names == NULL)
142+ init.parent_data = clks->parent_data;
141143
142144 periph_clk->hw.hw.init = &init;
143145
drivers/clk/socfpga/clk-pll-a10.c+1−3
@@ -58,7 +58,7 @@ static u8 clk_pll_get_parent(struct clk_hw *hwclk) · 57 unmodified lines
5858 CLK_MGR_PLL_CLK_SRC_MASK;
5959 }
6060
61−static struct clk_ops clk_pll_ops = {
61+static const struct clk_ops clk_pll_ops = {
6262 .recalc_rate = clk_pll_recalc_rate,
6363 .get_parent = clk_pll_get_parent,
6464 };
@@ -102,8 +102,6 @@ static struct clk * __init __socfpga_pll_init(struct device_node *node, · 37 unmodified lines
102102 pll_clk->hw.hw.init = &init;
103103
104104 pll_clk->hw.bit_idx = SOCFPGA_PLL_EXT_ENA;
105− clk_pll_ops.enable = clk_gate_ops.enable;
106− clk_pll_ops.disable = clk_gate_ops.disable;
107105
108106 clk = clk_register(NULL, &pll_clk->hw.hw);
109107 if (WARN_ON(IS_ERR(clk))) {
drivers/clk/socfpga/clk-pll-s10.c+72−6
@@ -18,8 +18,12 @@ · 17 unmodified lines
1818 #define SOCFPGA_PLL_RESET_MASK 0x2
1919 #define SOCFPGA_PLL_REFDIV_MASK 0x00003F00
2020 #define SOCFPGA_PLL_REFDIV_SHIFT 8
21+#define SOCFPGA_PLL_AREFDIV_MASK 0x00000F00
22+#define SOCFPGA_PLL_DREFDIV_MASK 0x00003000
23+#define SOCFPGA_PLL_DREFDIV_SHIFT 12
2124 #define SOCFPGA_PLL_MDIV_MASK 0xFF000000
2225 #define SOCFPGA_PLL_MDIV_SHIFT 24
26+#define SOCFPGA_AGILEX_PLL_MDIV_MASK 0x000003FF
2327 #define SWCTRLBTCLKSEL_MASK 0x200
2428 #define SWCTRLBTCLKSEL_SHIFT 9
2529
@@ -27,6 +31,27 @@ · 1 unmodified line
2731
2832 #define to_socfpga_clk(p) container_of(p, struct socfpga_pll, hw.hw)
2933
34+static unsigned long agilex_clk_pll_recalc_rate(struct clk_hw *hwclk,
35+ unsigned long parent_rate)
36+{
37+ struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
38+ unsigned long arefdiv, reg, mdiv;
39+ unsigned long long vco_freq;
40+
41+ /* read VCO1 reg for numerator and denominator */
42+ reg = readl(socfpgaclk->hw.reg);
43+ arefdiv = (reg & SOCFPGA_PLL_AREFDIV_MASK) >> SOCFPGA_PLL_REFDIV_SHIFT;
44+
45+ vco_freq = (unsigned long long)parent_rate / arefdiv;
46+
47+ /* Read mdiv and fdiv from the fdbck register */
48+ reg = readl(socfpgaclk->hw.reg + 0x24);
49+ mdiv = reg & SOCFPGA_AGILEX_PLL_MDIV_MASK;
50+
51+ vco_freq = (unsigned long long)vco_freq * mdiv;
52+ return (unsigned long)vco_freq;
53+}
54+
3055 static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk,
3156 unsigned long parent_rate)
3257 {
@@ -98,13 +123,19 @@ static int clk_pll_prepare(struct clk_hw *hwclk) · 65 unmodified lines
98123 return 0;
99124 }
100125
101−static struct clk_ops clk_pll_ops = {
126+static const struct clk_ops agilex_clk_pll_ops = {
127+ .recalc_rate = agilex_clk_pll_recalc_rate,
128+ .get_parent = clk_pll_get_parent,
129+ .prepare = clk_pll_prepare,
130+};
131+
132+static const struct clk_ops clk_pll_ops = {
102133 .recalc_rate = clk_pll_recalc_rate,
103134 .get_parent = clk_pll_get_parent,
104135 .prepare = clk_pll_prepare,
105136 };
106137
107−static struct clk_ops clk_boot_ops = {
138+static const struct clk_ops clk_boot_ops = {
108139 .recalc_rate = clk_boot_clk_recalc_rate,
109140 .get_parent = clk_boot_get_parent,
110141 .prepare = clk_pll_prepare,
@@ -117,7 +148,6 @@ struct clk *s10_register_pll(const struct stratix10_pll_clock *clks, · 6 unmodified lines
117148 struct socfpga_pll *pll_clk;
118149 struct clk_init_data init;
119150 const char *name = clks->name;
120− const char * const *parent_names = clks->parent_names;
121151
122152 pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
123153 if (WARN_ON(!pll_clk))
@@ -134,12 +164,48 @@ struct clk *s10_register_pll(const struct stratix10_pll_clock *clks, · 10 unmodified lines
134164 init.flags = clks->flags;
135165
136166 init.num_parents = clks->num_parents;
137− init.parent_names = parent_names;
167+ init.parent_names = NULL;
168+ init.parent_data = clks->parent_data;
169+ pll_clk->hw.hw.init = &init;
170+
171+ pll_clk->hw.bit_idx = SOCFPGA_PLL_POWER;
172+
173+ clk = clk_register(NULL, &pll_clk->hw.hw);
174+ if (WARN_ON(IS_ERR(clk))) {
175+ kfree(pll_clk);
176+ return NULL;
177+ }
178+ return clk;
179+}
180+
181+struct clk *agilex_register_pll(const struct stratix10_pll_clock *clks,
182+ void __iomem *reg)
183+{
184+ struct clk *clk;
185+ struct socfpga_pll *pll_clk;
186+ struct clk_init_data init;
187+ const char *name = clks->name;
188+
189+ pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
190+ if (WARN_ON(!pll_clk))
191+ return NULL;
192+
193+ pll_clk->hw.reg = reg + clks->offset;
194+
195+ if (streq(name, SOCFPGA_BOOT_CLK))
196+ init.ops = &clk_boot_ops;
197+ else
198+ init.ops = &agilex_clk_pll_ops;
199+
200+ init.name = name;
201+ init.flags = clks->flags;
202+
203+ init.num_parents = clks->num_parents;
204+ init.parent_names = NULL;
205+ init.parent_data = clks->parent_data;
138206 pll_clk->hw.hw.init = &init;
139207
140208 pll_clk->hw.bit_idx = SOCFPGA_PLL_POWER;
141− clk_pll_ops.enable = clk_gate_ops.enable;
142− clk_pll_ops.disable = clk_gate_ops.disable;
143209
144210 clk = clk_register(NULL, &pll_clk->hw.hw);
145211 if (WARN_ON(IS_ERR(clk))) {
drivers/clk/socfpga/clk-pll.c+1−3
@@ -65,7 +65,7 @@ static u8 clk_pll_get_parent(struct clk_hw *hwclk) · 64 unmodified lines
6565 CLK_MGR_PLL_CLK_SRC_MASK;
6666 }
6767
68−static struct clk_ops clk_pll_ops = {
68+static const struct clk_ops clk_pll_ops = {
6969 .recalc_rate = clk_pll_recalc_rate,
7070 .get_parent = clk_pll_get_parent,
7171 };
@@ -105,8 +105,6 @@ static __init struct clk *__socfpga_pll_init(struct device_node *node, · 33 unmodified lines
105105 pll_clk->hw.hw.init = &init;
106106
107107 pll_clk->hw.bit_idx = SOCFPGA_PLL_EXT_ENA;
108− clk_pll_ops.enable = clk_gate_ops.enable;
109− clk_pll_ops.disable = clk_gate_ops.disable;
110108
111109 clk = clk_register(NULL, &pll_clk->hw.hw);
112110 if (WARN_ON(IS_ERR(clk))) {
drivers/clk/socfpga/clk-s10.c+131−29
@@ -12,35 +12,137 @@ · 11 unmodified lines
1212
1313 #include "stratix10-clk.h"
1414
15−static const char * const pll_mux[] = { "osc1", "cb-intosc-hs-div2-clk",
16− "f2s-free-clk",};
17−static const char * const cntr_mux[] = { "main_pll", "periph_pll",
18− "osc1", "cb-intosc-hs-div2-clk",
19− "f2s-free-clk"};
20−static const char * const boot_mux[] = { "osc1", "cb-intosc-hs-div2-clk",};
21−
22−static const char * const noc_free_mux[] = {"main_noc_base_clk",
23− "peri_noc_base_clk",
24− "osc1", "cb-intosc-hs-div2-clk",
25− "f2s-free-clk"};
26−
27−static const char * const emaca_free_mux[] = {"peri_emaca_clk", "boot_clk"};
28−static const char * const emacb_free_mux[] = {"peri_emacb_clk", "boot_clk"};
29−static const char * const emac_ptp_free_mux[] = {"peri_emac_ptp_clk", "boot_clk"};
30−static const char * const gpio_db_free_mux[] = {"peri_gpio_db_clk", "boot_clk"};
31−static const char * const sdmmc_free_mux[] = {"main_sdmmc_clk", "boot_clk"};
32−static const char * const s2f_usr1_free_mux[] = {"peri_s2f_usr1_clk", "boot_clk"};
33−static const char * const psi_ref_free_mux[] = {"peri_psi_ref_clk", "boot_clk"};
34−static const char * const mpu_mux[] = { "mpu_free_clk", "boot_clk",};
35−
36−static const char * const s2f_usr0_mux[] = {"f2s-free-clk", "boot_clk"};
37−static const char * const emac_mux[] = {"emaca_free_clk", "emacb_free_clk"};
38−static const char * const noc_mux[] = {"noc_free_clk", "boot_clk"};
39−
40−static const char * const mpu_free_mux[] = {"main_mpu_base_clk",
41− "peri_mpu_base_clk",
42− "osc1", "cb-intosc-hs-div2-clk",
43− "f2s-free-clk"};
15+static const struct clk_parent_data pll_mux[] = {
16+ { .fw_name = "osc1",
17+ .name = "osc1" },
18+ { .fw_name = "cb-intosc-hs-div2-clk",
19+ .name = "cb-intosc-hs-div2-clk" },
20+ { .fw_name = "f2s-free-clk",
21+ .name = "f2s-free-clk" },
22+};
23+
24+static const struct clk_parent_data cntr_mux[] = {
25+ { .fw_name = "main_pll",
26+ .name = "main_pll", },
27+ { .fw_name = "periph_pll",
28+ .name = "periph_pll", },
29+ { .fw_name = "osc1",
30+ .name = "osc1", },
31+ { .fw_name = "cb-intosc-hs-div2-clk",
32+ .name = "cb-intosc-hs-div2-clk", },
33+ { .fw_name = "f2s-free-clk",
34+ .name = "f2s-free-clk", },
35+};
36+
37+static const struct clk_parent_data boot_mux[] = {
38+ { .fw_name = "osc1",
39+ .name = "osc1" },
40+ { .fw_name = "cb-intosc-hs-div2-clk",
41+ .name = "cb-intosc-hs-div2-clk" },
42+};
43+
44+static const struct clk_parent_data noc_free_mux[] = {
45+ { .fw_name = "main_noc_base_clk",
46+ .name = "main_noc_base_clk", },
47+ { .fw_name = "peri_noc_base_clk",
48+ .name = "peri_noc_base_clk", },
49+ { .fw_name = "osc1",
50+ .name = "osc1", },
51+ { .fw_name = "cb-intosc-hs-div2-clk",
52+ .name = "cb-intosc-hs-div2-clk", },
53+ { .fw_name = "f2s-free-clk",
54+ .name = "f2s-free-clk", },
55+};
56+
57+static const struct clk_parent_data emaca_free_mux[] = {
58+ { .fw_name = "peri_emaca_clk",
59+ .name = "peri_emaca_clk", },
60+ { .fw_name = "boot_clk",
61+ .name = "boot_clk", },
62+};
63+
64+static const struct clk_parent_data emacb_free_mux[] = {
65+ { .fw_name = "peri_emacb_clk",
66+ .name = "peri_emacb_clk", },
67+ { .fw_name = "boot_clk",
68+ .name = "boot_clk", },
69+};
70+
71+static const struct clk_parent_data emac_ptp_free_mux[] = {
72+ { .fw_name = "peri_emac_ptp_clk",
73+ .name = "peri_emac_ptp_clk", },
74+ { .fw_name = "boot_clk",
75+ .name = "boot_clk", },
76+};
77+
78+static const struct clk_parent_data gpio_db_free_mux[] = {
79+ { .fw_name = "peri_gpio_db_clk",
80+ .name = "peri_gpio_db_clk", },
81+ { .fw_name = "boot_clk",
82+ .name = "boot_clk", },
83+};
84+
85+static const struct clk_parent_data sdmmc_free_mux[] = {
86+ { .fw_name = "main_sdmmc_clk",
87+ .name = "main_sdmmc_clk", },
88+ { .fw_name = "boot_clk",
89+ .name = "boot_clk", },
90+};
91+
92+static const struct clk_parent_data s2f_usr1_free_mux[] = {
93+ { .fw_name = "peri_s2f_usr1_clk",
94+ .name = "peri_s2f_usr1_clk", },
95+ { .fw_name = "boot_clk",
96+ .name = "boot_clk", },
97+};
98+
99+static const struct clk_parent_data psi_ref_free_mux[] = {
100+ { .fw_name = "peri_psi_ref_clk",
101+ .name = "peri_psi_ref_clk", },
102+ { .fw_name = "boot_clk",
103+ .name = "boot_clk", },
104+};
105+
106+static const struct clk_parent_data mpu_mux[] = {
107+ { .fw_name = "mpu_free_clk",
108+ .name = "mpu_free_clk", },
109+ { .fw_name = "boot_clk",
110+ .name = "boot_clk", },
111+};
112+
113+static const struct clk_parent_data s2f_usr0_mux[] = {
114+ { .fw_name = "f2s-free-clk",
115+ .name = "f2s-free-clk", },
116+ { .fw_name = "boot_clk",
117+ .name = "boot_clk", },
118+};
119+
120+static const struct clk_parent_data emac_mux[] = {
121+ { .fw_name = "emaca_free_clk",
122+ .name = "emaca_free_clk", },
123+ { .fw_name = "emacb_free_clk",
124+ .name = "emacb_free_clk", },
125+};
126+
127+static const struct clk_parent_data noc_mux[] = {
128+ { .fw_name = "noc_free_clk",
129+ .name = "noc_free_clk", },
130+ { .fw_name = "boot_clk",
131+ .name = "boot_clk", },
132+};
133+
134+static const struct clk_parent_data mpu_free_mux[] = {
135+ { .fw_name = "main_mpu_base_clk",
136+ .name = "main_mpu_base_clk", },
137+ { .fw_name = "peri_mpu_base_clk",
138+ .name = "peri_mpu_base_clk", },
139+ { .fw_name = "osc1",
140+ .name = "osc1", },
141+ { .fw_name = "cb-intosc-hs-div2-clk",
142+ .name = "cb-intosc-hs-div2-clk", },
143+ { .fw_name = "f2s-free-clk",
144+ .name = "f2s-free-clk", },
145+};
44146
45147 /* clocks in AO (always on) controller */
46148 static const struct stratix10_pll_clock s10_pll_clks[] = {
drivers/clk/socfpga/stratix10-clk.h+6−4
@@ -14,7 +14,7 @@ struct stratix10_clock_data { · 13 unmodified lines
1414 struct stratix10_pll_clock {
1515 unsigned int id;
1616 const char *name;
17− const char *const *parent_names;
17+ const struct clk_parent_data *parent_data;
1818 u8 num_parents;
1919 unsigned long flags;
2020 unsigned long offset;
@@ -24,7 +24,7 @@ struct stratix10_perip_c_clock { · 3 unmodified lines
2424 unsigned int id;
2525 const char *name;
2626 const char *parent_name;
27− const char *const *parent_names;
27+ const struct clk_parent_data *parent_data;
2828 u8 num_parents;
2929 unsigned long flags;
3030 unsigned long offset;
@@ -34,7 +34,7 @@ struct stratix10_perip_cnt_clock { · 3 unmodified lines
3434 unsigned int id;
3535 const char *name;
3636 const char *parent_name;
37− const char *const *parent_names;
37+ const struct clk_parent_data *parent_data;
3838 u8 num_parents;
3939 unsigned long flags;
4040 unsigned long offset;
@@ -47,7 +47,7 @@ struct stratix10_gate_clock { · 6 unmodified lines
4747 unsigned int id;
4848 const char *name;
4949 const char *parent_name;
50− const char *const *parent_names;
50+ const struct clk_parent_data *parent_data;
5151 u8 num_parents;
5252 unsigned long flags;
5353 unsigned long gate_reg;
@@ -62,6 +62,8 @@ struct stratix10_gate_clock { · 8 unmodified lines
6262
6363 struct clk *s10_register_pll(const struct stratix10_pll_clock *,
6464 void __iomem *);
65+struct clk *agilex_register_pll(const struct stratix10_pll_clock *,
66+ void __iomem *);
6567 struct clk *s10_register_periph(const struct stratix10_perip_c_clock *,
6668 void __iomem *);
6769 struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *,
drivers/clk/sprd/gate.c+7−0
@@ -94,8 +94,15 @@ static int sprd_gate_is_enabled(struct clk_hw *hw) · 93 unmodified lines
9494 {
9595 struct sprd_gate *sg = hw_to_sprd_gate(hw);
9696 struct sprd_clk_common *common = &sg->common;
97+ struct clk_hw *parent;
9798 unsigned int reg;
9899
100+ if (sg->flags & SPRD_GATE_NON_AON) {
101+ parent = clk_hw_get_parent(hw);
102+ if (!parent || !clk_hw_is_enabled(parent))
103+ return 0;
104+ }
105+
99106 regmap_read(common->regmap, common->reg, &reg);
100107
101108 if (sg->flags & CLK_GATE_SET_TO_DISABLE)
drivers/clk/sprd/gate.h+9−0
@@ -19,6 +19,15 @@ struct sprd_gate { · 18 unmodified lines
1919 struct sprd_clk_common common;
2020 };
2121
22+/*
23+ * sprd_gate->flags is used for:
24+ * CLK_GATE_SET_TO_DISABLE BIT(0)
25+ * CLK_GATE_HIWORD_MASK BIT(1)
26+ * CLK_GATE_BIG_ENDIAN BIT(2)
27+ * so we define new flags from BIT(3)
28+ */
29+#define SPRD_GATE_NON_AON BIT(3) /* not alway powered on, check before read */
30+
2231 #define SPRD_SC_GATE_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \
2332 _sc_offset, _enable_mask, _flags, \
2433 _gate_flags, _udelay, _ops, _fn) \
drivers/clk/sprd/pll.c+1−1
@@ -106,7 +106,7 @@ static unsigned long _sprd_pll_recalc_rate(const struct sprd_pll *pll, · 105 unmodified lines
106106
107107 cfg = kcalloc(regs_num, sizeof(*cfg), GFP_KERNEL);
108108 if (!cfg)
109− return -ENOMEM;
109+ return parent_rate;
110110
111111 for (i = 0; i < regs_num; i++)
112112 cfg[i] = sprd_pll_read(pll, i);
drivers/clk/sprd/sc9863a-clk.c+48−16
@@ -23,22 +23,22 @@ · 22 unmodified lines
2323 #include "pll.h"
2424
2525 /* mpll*_gate clocks control cpu cores, they were enabled by default */
26−SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll0_gate, "mpll0-gate", "ext-26m", 0x94,
27− 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
28−SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll0_gate, "dpll0-gate", "ext-26m", 0x98,
29− 0x1000, BIT(0), 0, 0, 240);
30−SPRD_PLL_SC_GATE_CLK_FW_NAME(lpll_gate, "lpll-gate", "ext-26m", 0x9c,
31− 0x1000, BIT(0), 0, 0, 240);
32−SPRD_PLL_SC_GATE_CLK_FW_NAME(gpll_gate, "gpll-gate", "ext-26m", 0xa8,
33− 0x1000, BIT(0), 0, 0, 240);
34−SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll1_gate, "dpll1-gate", "ext-26m", 0x1dc,
35− 0x1000, BIT(0), 0, 0, 240);
36−SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll1_gate, "mpll1-gate", "ext-26m", 0x1e0,
37− 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
38−SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll2_gate, "mpll2-gate", "ext-26m", 0x1e4,
39− 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
40−SPRD_PLL_SC_GATE_CLK_FW_NAME(isppll_gate, "isppll-gate", "ext-26m", 0x1e8,
41− 0x1000, BIT(0), 0, 0, 240);
26+static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll0_gate, "mpll0-gate", "ext-26m", 0x94,
27+ 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
28+static SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll0_gate, "dpll0-gate", "ext-26m", 0x98,
29+ 0x1000, BIT(0), 0, 0, 240);
30+static SPRD_PLL_SC_GATE_CLK_FW_NAME(lpll_gate, "lpll-gate", "ext-26m", 0x9c,
31+ 0x1000, BIT(0), 0, 0, 240);
32+static SPRD_PLL_SC_GATE_CLK_FW_NAME(gpll_gate, "gpll-gate", "ext-26m", 0xa8,
33+ 0x1000, BIT(0), 0, 0, 240);
34+static SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll1_gate, "dpll1-gate", "ext-26m", 0x1dc,
35+ 0x1000, BIT(0), 0, 0, 240);
36+static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll1_gate, "mpll1-gate", "ext-26m", 0x1e0,
37+ 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
38+static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll2_gate, "mpll2-gate", "ext-26m", 0x1e4,
39+ 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
40+static SPRD_PLL_SC_GATE_CLK_FW_NAME(isppll_gate, "isppll-gate", "ext-26m",
41+ 0x1e8, 0x1000, BIT(0), 0, 0, 240);
4242
4343 static struct sprd_clk_common *sc9863a_pmu_gate_clks[] = {
4444 /* address base is 0x402b0000 */
@@ -1615,6 +1615,36 @@ static const struct sprd_clk_desc sc9863a_mm_gate_desc = { · 1570 unmodified lines
16151615 .hw_clks = &sc9863a_mm_gate_hws,
16161616 };
16171617
1618+/* camera sensor clocks */
1619+static SPRD_GATE_CLK_HW(mipi_csi_clk, "mipi-csi-clk", &mahb_ckg_eb.common.hw,
1620+ 0x20, BIT(16), 0, SPRD_GATE_NON_AON);
1621+static SPRD_GATE_CLK_HW(mipi_csi_s_clk, "mipi-csi-s-clk", &mahb_ckg_eb.common.hw,
1622+ 0x24, BIT(16), 0, SPRD_GATE_NON_AON);
1623+static SPRD_GATE_CLK_HW(mipi_csi_m_clk, "mipi-csi-m-clk", &mahb_ckg_eb.common.hw,
1624+ 0x28, BIT(16), 0, SPRD_GATE_NON_AON);
1625+
1626+static struct sprd_clk_common *sc9863a_mm_clk_clks[] = {
1627+ /* address base is 0x60900000 */
1628+ &mipi_csi_clk.common,
1629+ &mipi_csi_s_clk.common,
1630+ &mipi_csi_m_clk.common,
1631+};
1632+
1633+static struct clk_hw_onecell_data sc9863a_mm_clk_hws = {
1634+ .hws = {
1635+ [CLK_MIPI_CSI] = &mipi_csi_clk.common.hw,
1636+ [CLK_MIPI_CSI_S] = &mipi_csi_s_clk.common.hw,
1637+ [CLK_MIPI_CSI_M] = &mipi_csi_m_clk.common.hw,
1638+ },
1639+ .num = CLK_MM_CLK_NUM,
1640+};
1641+
1642+static const struct sprd_clk_desc sc9863a_mm_clk_desc = {
1643+ .clk_clks = sc9863a_mm_clk_clks,
1644+ .num_clk_clks = ARRAY_SIZE(sc9863a_mm_clk_clks),
1645+ .hw_clks = &sc9863a_mm_clk_hws,
1646+};
1647+
16181648 static SPRD_SC_GATE_CLK_FW_NAME(sim0_eb, "sim0-eb", "ext-26m", 0x0,
16191649 0x1000, BIT(0), 0, 0);
16201650 static SPRD_SC_GATE_CLK_FW_NAME(iis0_eb, "iis0-eb", "ext-26m", 0x0,
@@ -1738,6 +1768,8 @@ static const struct of_device_id sprd_sc9863a_clk_ids[] = { · 117 unmodified lines
17381768 .data = &sc9863a_aonapb_gate_desc },
17391769 { .compatible = "sprd,sc9863a-mm-gate", /* 0x60800000 */
17401770 .data = &sc9863a_mm_gate_desc },
1771+ { .compatible = "sprd,sc9863a-mm-clk", /* 0x60900000 */
1772+ .data = &sc9863a_mm_clk_desc },
17411773 { .compatible = "sprd,sc9863a-apapb-gate", /* 0x71300000 */
17421774 .data = &sc9863a_apapb_gate_desc },
17431775 { }
drivers/clk/st/clk-flexgen.c+1−0
@@ -375,6 +375,7 @@ static void __init st_of_flexgen_setup(struct device_node *np) · 374 unmodified lines
375375 break;
376376 }
377377
378+ flex_flags &= ~CLK_IS_CRITICAL;
378379 of_clk_detect_critical(np, i, &flex_flags);
379380
380381 /*
drivers/clk/sunxi/clk-sunxi.c+1−1
@@ -90,7 +90,7 @@ static void sun6i_a31_get_pll1_factors(struct factors_request *req) · 89 unmodified lines
9090 * Round down the frequency to the closest multiple of either
9191 * 6 or 16
9292 */
93− u32 round_freq_6 = round_down(freq_mhz, 6);
93+ u32 round_freq_6 = rounddown(freq_mhz, 6);
9494 u32 round_freq_16 = round_down(freq_mhz, 16);
9595
9696 if (round_freq_6 > round_freq_16)
drivers/clk/tegra/Kconfig+0−4
@@ -1,8 +1,4 @@
11 # SPDX-License-Identifier: GPL-2.0-only
2−config TEGRA_CLK_EMC
3− def_bool y
4− depends on TEGRA124_EMC
5−
62 config CLK_TEGRA_BPMP
73 def_bool y
84 depends on TEGRA_BPMP
drivers/clk/tegra/Makefile+3−1
@@ -13,8 +13,8 @@ obj-y += clk-super.o · 12 unmodified lines
1313 obj-y += clk-tegra-audio.o
1414 obj-y += clk-tegra-periph.o
1515 obj-y += clk-tegra-fixed.o
16+obj-y += clk-tegra-super-cclk.o
1617 obj-y += clk-tegra-super-gen4.o
17−obj-$(CONFIG_TEGRA_CLK_EMC) += clk-emc.o
1818 obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o
1919 obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20-emc.o
2020 obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o
@@ -22,8 +22,10 @@ obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra20-emc.o · 1 unmodified line
2222 obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o
2323 obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o
2424 obj-$(CONFIG_TEGRA_CLK_DFLL) += clk-tegra124-dfll-fcpu.o
25+obj-$(CONFIG_TEGRA124_EMC) += clk-tegra124-emc.o
2526 obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124.o
2627 obj-y += cvb.o
2728 obj-$(CONFIG_ARCH_TEGRA_210_SOC) += clk-tegra210.o
29+obj-$(CONFIG_ARCH_TEGRA_210_SOC) += clk-tegra210-emc.o
2830 obj-$(CONFIG_CLK_TEGRA_BPMP) += clk-bpmp.o
2931 obj-y += clk-utils.o
drivers/clk/tegra/clk-pll.c+11−1
@@ -744,13 +744,19 @@ static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, · 743 unmodified lines
744744
745745 state = clk_pll_is_enabled(hw);
746746
747+ if (state && pll->params->pre_rate_change) {
748+ ret = pll->params->pre_rate_change();
749+ if (WARN_ON(ret))
750+ return ret;
751+ }
752+
747753 _get_pll_mnp(pll, &old_cfg);
748754
749755 if (state && pll->params->defaults_set && pll->params->dyn_ramp &&
750756 (cfg->m == old_cfg.m) && (cfg->p == old_cfg.p)) {
751757 ret = pll->params->dyn_ramp(pll, cfg);
752758 if (!ret)
753− return 0;
759+ goto done;
754760 }
755761
756762 if (state) {
@@ -772,6 +778,10 @@ static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, · 15 unmodified lines
772778 pll_clk_start_ss(pll);
773779 }
774780
781+done:
782+ if (state && pll->params->post_rate_change)
783+ pll->params->post_rate_change();
784+
775785 return ret;
776786 }
777787
drivers/clk/tegra/clk-tegra-super-cclk.c+212−0
@@ -0,0 +1,212 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+/*
3+ * Based on clk-super.c
4+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
5+ *
6+ * Based on older tegra20-cpufreq driver by Colin Cross <ccross@google.com>
7+ * Copyright (C) 2010 Google, Inc.
8+ *
9+ * Author: Dmitry Osipenko <digetx@gmail.com>
10+ * Copyright (C) 2019 GRATE-DRIVER project
11+ */
12+
13+#include <linux/bits.h>
14+#include <linux/clk-provider.h>
15+#include <linux/err.h>
16+#include <linux/io.h>
17+#include <linux/kernel.h>
18+#include <linux/slab.h>
19+#include <linux/types.h>
20+
21+#include "clk.h"
22+
23+#define PLLP_INDEX 4
24+#define PLLX_INDEX 8
25+
26+#define SUPER_CDIV_ENB BIT(31)
27+
28+static struct tegra_clk_super_mux *cclk_super;
29+static bool cclk_on_pllx;
30+
31+static u8 cclk_super_get_parent(struct clk_hw *hw)
32+{
33+ return tegra_clk_super_ops.get_parent(hw);
34+}
35+
36+static int cclk_super_set_parent(struct clk_hw *hw, u8 index)
37+{
38+ return tegra_clk_super_ops.set_parent(hw, index);
39+}
40+
41+static int cclk_super_set_rate(struct clk_hw *hw, unsigned long rate,
42+ unsigned long parent_rate)
43+{
44+ return tegra_clk_super_ops.set_rate(hw, rate, parent_rate);
45+}
46+
47+static unsigned long cclk_super_recalc_rate(struct clk_hw *hw,
48+ unsigned long parent_rate)
49+{
50+ if (cclk_super_get_parent(hw) == PLLX_INDEX)
51+ return parent_rate;
52+
53+ return tegra_clk_super_ops.recalc_rate(hw, parent_rate);
54+}
55+
56+static int cclk_super_determine_rate(struct clk_hw *hw,
57+ struct clk_rate_request *req)
58+{
59+ struct clk_hw *pllp_hw = clk_hw_get_parent_by_index(hw, PLLP_INDEX);
60+ struct clk_hw *pllx_hw = clk_hw_get_parent_by_index(hw, PLLX_INDEX);
61+ struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
62+ unsigned long pllp_rate;
63+ long rate = req->rate;
64+
65+ if (WARN_ON_ONCE(!pllp_hw || !pllx_hw))
66+ return -EINVAL;
67+
68+ /*
69+ * Switch parent to PLLP for all CCLK rates that are suitable for PLLP.
70+ * PLLX will be disabled in this case, saving some power.
71+ */
72+ pllp_rate = clk_hw_get_rate(pllp_hw);
73+
74+ if (rate <= pllp_rate) {
75+ if (super->flags & TEGRA20_SUPER_CLK)
76+ rate = pllp_rate;
77+ else
78+ rate = tegra_clk_super_ops.round_rate(hw, rate,
79+ &pllp_rate);
80+
81+ req->best_parent_rate = pllp_rate;
82+ req->best_parent_hw = pllp_hw;
83+ req->rate = rate;
84+ } else {
85+ rate = clk_hw_round_rate(pllx_hw, rate);
86+ req->best_parent_rate = rate;
87+ req->best_parent_hw = pllx_hw;
88+ req->rate = rate;
89+ }
90+
91+ if (WARN_ON_ONCE(rate <= 0))
92+ return -EINVAL;
93+
94+ return 0;
95+}
96+
97+static const struct clk_ops tegra_cclk_super_ops = {
98+ .get_parent = cclk_super_get_parent,
99+ .set_parent = cclk_super_set_parent,
100+ .set_rate = cclk_super_set_rate,
101+ .recalc_rate = cclk_super_recalc_rate,
102+ .determine_rate = cclk_super_determine_rate,
103+};
104+
105+static const struct clk_ops tegra_cclk_super_mux_ops = {
106+ .get_parent = cclk_super_get_parent,
107+ .set_parent = cclk_super_set_parent,
108+ .determine_rate = cclk_super_determine_rate,
109+};
110+
111+struct clk *tegra_clk_register_super_cclk(const char *name,
112+ const char * const *parent_names, u8 num_parents,
113+ unsigned long flags, void __iomem *reg, u8 clk_super_flags,
114+ spinlock_t *lock)
115+{
116+ struct tegra_clk_super_mux *super;
117+ struct clk *clk;
118+ struct clk_init_data init;
119+ u32 val;
120+
121+ if (WARN_ON(cclk_super))
122+ return ERR_PTR(-EBUSY);
123+
124+ super = kzalloc(sizeof(*super), GFP_KERNEL);
125+ if (!super)
126+ return ERR_PTR(-ENOMEM);
127+
128+ init.name = name;
129+ init.flags = flags;
130+ init.parent_names = parent_names;
131+ init.num_parents = num_parents;
132+
133+ super->reg = reg;
134+ super->lock = lock;
135+ super->width = 4;
136+ super->flags = clk_super_flags;
137+ super->hw.init = &init;
138+
139+ if (super->flags & TEGRA20_SUPER_CLK) {
140+ init.ops = &tegra_cclk_super_mux_ops;
141+ } else {
142+ init.ops = &tegra_cclk_super_ops;
143+
144+ super->frac_div.reg = reg + 4;
145+ super->frac_div.shift = 16;
146+ super->frac_div.width = 8;
147+ super->frac_div.frac_width = 1;
148+ super->frac_div.lock = lock;
149+ super->div_ops = &tegra_clk_frac_div_ops;
150+ }
151+
152+ /*
153+ * Tegra30+ has the following CPUG clock topology:
154+ *
155+ * +---+ +-------+ +-+ +-+ +-+
156+ * PLLP+->+ +->+DIVIDER+->+0| +-------->+0| ------------->+0|
157+ * | | +-------+ | | | +---+ | | | | |
158+ * PLLC+->+MUX| | +->+ | S | | +->+ | +->+CPU
159+ * ... | | | | | | K | | | | +-------+ | |
160+ * PLLX+->+-->+------------>+1| +->+ I +->+1| +->+ DIV2 +->+1|
161+ * +---+ +++ | P | +++ |SKIPPER| +++
162+ * ^ | P | ^ +-------+ ^
163+ * | | E | | |
164+ * PLLX_SEL+--+ | R | | OVERHEAT+--+
165+ * +---+ |
166+ * |
167+ * SUPER_CDIV_ENB+--+
168+ *
169+ * Tegra20 is similar, but simpler. It doesn't have the divider and
170+ * thermal DIV2 skipper.
171+ *
172+ * At least for now we're not going to use clock-skipper, hence let's
173+ * ensure that it is disabled.
174+ */
175+ val = readl_relaxed(reg + 4);
176+ val &= ~SUPER_CDIV_ENB;
177+ writel_relaxed(val, reg + 4);
178+
179+ clk = clk_register(NULL, &super->hw);
180+ if (IS_ERR(clk))
181+ kfree(super);
182+ else
183+ cclk_super = super;
184+
185+ return clk;
186+}
187+
188+int tegra_cclk_pre_pllx_rate_change(void)
189+{
190+ if (IS_ERR_OR_NULL(cclk_super))
191+ return -EINVAL;
192+
193+ if (cclk_super_get_parent(&cclk_super->hw) == PLLX_INDEX)
194+ cclk_on_pllx = true;
195+ else
196+ cclk_on_pllx = false;
197+
198+ /*
199+ * CPU needs to be temporarily re-parented away from PLLX if PLLX
200+ * changes its rate. PLLP is a safe parent for CPU on all Tegra SoCs.
201+ */
202+ if (cclk_on_pllx)
203+ cclk_super_set_parent(&cclk_super->hw, PLLP_INDEX);
204+
205+ return 0;
206+}
207+
208+void tegra_cclk_post_pllx_rate_change(void)
209+{
210+ if (cclk_on_pllx)
211+ cclk_super_set_parent(&cclk_super->hw, PLLX_INDEX);
212+}
drivers/clk/tegra/clk-tegra124-emc.crenamed from drivers/clk/tegra/clk-emc.c+0−0

File renamed without changes.

drivers/clk/tegra/clk-tegra20.c+5−2
@@ -391,6 +391,8 @@ static struct tegra_clk_pll_params pll_x_params = { · 390 unmodified lines
391391 .lock_delay = 300,
392392 .freq_table = pll_x_freq_table,
393393 .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_HAS_LOCK_ENABLE,
394+ .pre_rate_change = tegra_cclk_pre_pllx_rate_change,
395+ .post_rate_change = tegra_cclk_post_pllx_rate_change,
394396 };
395397
396398 static struct tegra_clk_pll_params pll_e_params = {
@@ -702,9 +704,10 @@ static void tegra20_super_clk_init(void) · 305 unmodified lines
702704 struct clk *clk;
703705
704706 /* CCLK */
705− clk = tegra_clk_register_super_mux("cclk", cclk_parents,
707+ clk = tegra_clk_register_super_cclk("cclk", cclk_parents,
706708 ARRAY_SIZE(cclk_parents), CLK_SET_RATE_PARENT,
707− clk_base + CCLK_BURST_POLICY, 0, 4, 0, 0, NULL);
709+ clk_base + CCLK_BURST_POLICY, TEGRA20_SUPER_CLK,
710+ NULL);
708711 clks[TEGRA20_CLK_CCLK] = clk;
709712
710713 /* SCLK */
drivers/clk/tegra/clk-tegra210-emc.c+369−0
@@ -0,0 +1,369 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (c) 2015-2020, NVIDIA CORPORATION. All rights reserved.
4+ */
5+
6+#include <linux/bitfield.h>
7+#include <linux/clk.h>
8+#include <linux/clk-provider.h>
9+#include <linux/clk/tegra.h>
10+#include <linux/device.h>
11+#include <linux/module.h>
12+#include <linux/io.h>
13+#include <linux/slab.h>
14+
15+#define CLK_SOURCE_EMC 0x19c
16+#define CLK_SOURCE_EMC_2X_CLK_SRC GENMASK(31, 29)
17+#define CLK_SOURCE_EMC_MC_EMC_SAME_FREQ BIT(16)
18+#define CLK_SOURCE_EMC_2X_CLK_DIVISOR GENMASK(7, 0)
19+
20+#define CLK_SRC_PLLM 0
21+#define CLK_SRC_PLLC 1
22+#define CLK_SRC_PLLP 2
23+#define CLK_SRC_CLK_M 3
24+#define CLK_SRC_PLLM_UD 4
25+#define CLK_SRC_PLLMB_UD 5
26+#define CLK_SRC_PLLMB 6
27+#define CLK_SRC_PLLP_UD 7
28+
29+struct tegra210_clk_emc {
30+ struct clk_hw hw;
31+ void __iomem *regs;
32+
33+ struct tegra210_clk_emc_provider *provider;
34+
35+ struct clk *parents[8];
36+};
37+
38+static inline struct tegra210_clk_emc *
39+to_tegra210_clk_emc(struct clk_hw *hw)
40+{
41+ return container_of(hw, struct tegra210_clk_emc, hw);
42+}
43+
44+static const char *tegra210_clk_emc_parents[] = {
45+ "pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_mb_ud",
46+ "pll_mb", "pll_p_ud",
47+};
48+
49+static u8 tegra210_clk_emc_get_parent(struct clk_hw *hw)
50+{
51+ struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
52+ u32 value;
53+ u8 src;
54+
55+ value = readl_relaxed(emc->regs + CLK_SOURCE_EMC);
56+ src = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_SRC, value);
57+
58+ return src;
59+}
60+
61+static unsigned long tegra210_clk_emc_recalc_rate(struct clk_hw *hw,
62+ unsigned long parent_rate)
63+{
64+ struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
65+ u32 value, div;
66+
67+ /*
68+ * CCF assumes that neither the parent nor its rate will change during
69+ * ->set_rate(), so the parent rate passed in here was cached from the
70+ * parent before the ->set_rate() call.
71+ *
72+ * This can lead to wrong results being reported for the EMC clock if
73+ * the parent and/or parent rate have changed as part of the EMC rate
74+ * change sequence. Fix this by overriding the parent clock with what
75+ * we know to be the correct value after the rate change.
76+ */
77+ parent_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
78+
79+ value = readl_relaxed(emc->regs + CLK_SOURCE_EMC);
80+
81+ div = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_DIVISOR, value);
82+ div += 2;
83+
84+ return DIV_ROUND_UP(parent_rate * 2, div);
85+}
86+
87+static long tegra210_clk_emc_round_rate(struct clk_hw *hw, unsigned long rate,
88+ unsigned long *prate)
89+{
90+ struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
91+ struct tegra210_clk_emc_provider *provider = emc->provider;
92+ unsigned int i;
93+
94+ if (!provider || !provider->configs || provider->num_configs == 0)
95+ return clk_hw_get_rate(hw);
96+
97+ for (i = 0; i < provider->num_configs; i++) {
98+ if (provider->configs[i].rate >= rate)
99+ return provider->configs[i].rate;
100+ }
101+
102+ return provider->configs[i - 1].rate;
103+}
104+
105+static struct clk *tegra210_clk_emc_find_parent(struct tegra210_clk_emc *emc,
106+ u8 index)
107+{
108+ struct clk_hw *parent = clk_hw_get_parent_by_index(&emc->hw, index);
109+ const char *name = clk_hw_get_name(parent);
110+
111+ /* XXX implement cache? */
112+
113+ return __clk_lookup(name);
114+}
115+
116+static int tegra210_clk_emc_set_rate(struct clk_hw *hw, unsigned long rate,
117+ unsigned long parent_rate)
118+{
119+ struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
120+ struct tegra210_clk_emc_provider *provider = emc->provider;
121+ struct tegra210_clk_emc_config *config;
122+ struct device *dev = provider->dev;
123+ struct clk_hw *old, *new, *parent;
124+ u8 old_idx, new_idx, index;
125+ struct clk *clk;
126+ unsigned int i;
127+ int err;
128+
129+ if (!provider || !provider->configs || provider->num_configs == 0)
130+ return -EINVAL;
131+
132+ for (i = 0; i < provider->num_configs; i++) {
133+ if (provider->configs[i].rate >= rate) {
134+ config = &provider->configs[i];
135+ break;
136+ }
137+ }
138+
139+ if (i == provider->num_configs)
140+ config = &provider->configs[i - 1];
141+
142+ old_idx = tegra210_clk_emc_get_parent(hw);
143+ new_idx = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_SRC, config->value);
144+
145+ old = clk_hw_get_parent_by_index(hw, old_idx);
146+ new = clk_hw_get_parent_by_index(hw, new_idx);
147+
148+ /* if the rate has changed... */
149+ if (config->parent_rate != clk_hw_get_rate(old)) {
150+ /* ... but the clock source remains the same ... */
151+ if (new_idx == old_idx) {
152+ /* ... switch to the alternative clock source. */
153+ switch (new_idx) {
154+ case CLK_SRC_PLLM:
155+ new_idx = CLK_SRC_PLLMB;
156+ break;
157+
158+ case CLK_SRC_PLLM_UD:
159+ new_idx = CLK_SRC_PLLMB_UD;
160+ break;
161+
162+ case CLK_SRC_PLLMB_UD:
163+ new_idx = CLK_SRC_PLLM_UD;
164+ break;
165+
166+ case CLK_SRC_PLLMB:
167+ new_idx = CLK_SRC_PLLM;
168+ break;
169+ }
170+
171+ /*
172+ * This should never happen because we can't deal with
173+ * it.
174+ */
175+ if (WARN_ON(new_idx == old_idx))
176+ return -EINVAL;
177+
178+ new = clk_hw_get_parent_by_index(hw, new_idx);
179+ }
180+
181+ index = new_idx;
182+ parent = new;
183+ } else {
184+ index = old_idx;
185+ parent = old;
186+ }
187+
188+ clk = tegra210_clk_emc_find_parent(emc, index);
189+ if (IS_ERR(clk)) {
190+ err = PTR_ERR(clk);
191+ dev_err(dev, "failed to get parent clock for index %u: %d\n",
192+ index, err);
193+ return err;
194+ }
195+
196+ /* set the new parent clock to the required rate */
197+ if (clk_get_rate(clk) != config->parent_rate) {
198+ err = clk_set_rate(clk, config->parent_rate);
199+ if (err < 0) {
200+ dev_err(dev, "failed to set rate %lu Hz for %pC: %d\n",
201+ config->parent_rate, clk, err);
202+ return err;
203+ }
204+ }
205+
206+ /* enable the new parent clock */
207+ if (parent != old) {
208+ err = clk_prepare_enable(clk);
209+ if (err < 0) {
210+ dev_err(dev, "failed to enable parent clock %pC: %d\n",
211+ clk, err);
212+ return err;
213+ }
214+ }
215+
216+ /* update the EMC source configuration to reflect the new parent */
217+ config->value &= ~CLK_SOURCE_EMC_2X_CLK_SRC;
218+ config->value |= FIELD_PREP(CLK_SOURCE_EMC_2X_CLK_SRC, index);
219+
220+ /*
221+ * Finally, switch the EMC programming with both old and new parent
222+ * clocks enabled.
223+ */
224+ err = provider->set_rate(dev, config);
225+ if (err < 0) {
226+ dev_err(dev, "failed to set EMC rate to %lu Hz: %d\n", rate,
227+ err);
228+
229+ /*
230+ * If we're unable to switch to the new EMC frequency, we no
231+ * longer need the new parent to be enabled.
232+ */
233+ if (parent != old)
234+ clk_disable_unprepare(clk);
235+
236+ return err;
237+ }
238+
239+ /* reparent to new parent clock and disable the old parent clock */
240+ if (parent != old) {
241+ clk = tegra210_clk_emc_find_parent(emc, old_idx);
242+ if (IS_ERR(clk)) {
243+ err = PTR_ERR(clk);
244+ dev_err(dev,
245+ "failed to get parent clock for index %u: %d\n",
246+ old_idx, err);
247+ return err;
248+ }
249+
250+ clk_hw_reparent(hw, parent);
251+ clk_disable_unprepare(clk);
252+ }
253+
254+ return err;
255+}
256+
257+static const struct clk_ops tegra210_clk_emc_ops = {
258+ .get_parent = tegra210_clk_emc_get_parent,
259+ .recalc_rate = tegra210_clk_emc_recalc_rate,
260+ .round_rate = tegra210_clk_emc_round_rate,
261+ .set_rate = tegra210_clk_emc_set_rate,
262+};
263+
264+struct clk *tegra210_clk_register_emc(struct device_node *np,
265+ void __iomem *regs)
266+{
267+ struct tegra210_clk_emc *emc;
268+ struct clk_init_data init;
269+ struct clk *clk;
270+
271+ emc = kzalloc(sizeof(*emc), GFP_KERNEL);
272+ if (!emc)
273+ return ERR_PTR(-ENOMEM);
274+
275+ emc->regs = regs;
276+
277+ init.name = "emc";
278+ init.ops = &tegra210_clk_emc_ops;
279+ init.flags = CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE;
280+ init.parent_names = tegra210_clk_emc_parents;
281+ init.num_parents = ARRAY_SIZE(tegra210_clk_emc_parents);
282+ emc->hw.init = &init;
283+
284+ clk = clk_register(NULL, &emc->hw);
285+ if (IS_ERR(clk)) {
286+ kfree(emc);
287+ return clk;
288+ }
289+
290+ return clk;
291+}
292+
293+int tegra210_clk_emc_attach(struct clk *clk,
294+ struct tegra210_clk_emc_provider *provider)
295+{
296+ struct clk_hw *hw = __clk_get_hw(clk);
297+ struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw);
298+ struct device *dev = provider->dev;
299+ unsigned int i;
300+ int err;
301+
302+ if (!try_module_get(provider->owner))
303+ return -ENODEV;
304+
305+ for (i = 0; i < provider->num_configs; i++) {
306+ struct tegra210_clk_emc_config *config = &provider->configs[i];
307+ struct clk_hw *parent;
308+ bool same_freq;
309+ u8 div, src;
310+
311+ div = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_DIVISOR, config->value);
312+ src = FIELD_GET(CLK_SOURCE_EMC_2X_CLK_SRC, config->value);
313+
314+ /* do basic sanity checking on the EMC timings */
315+ if (div & 0x1) {
316+ dev_err(dev, "invalid odd divider %u for rate %lu Hz\n",
317+ div, config->rate);
318+ err = -EINVAL;
319+ goto put;
320+ }
321+
322+ same_freq = config->value & CLK_SOURCE_EMC_MC_EMC_SAME_FREQ;
323+
324+ if (same_freq != config->same_freq) {
325+ dev_err(dev,
326+ "ambiguous EMC to MC ratio for rate %lu Hz\n",
327+ config->rate);
328+ err = -EINVAL;
329+ goto put;
330+ }
331+
332+ parent = clk_hw_get_parent_by_index(hw, src);
333+ config->parent = src;
334+
335+ if (src == CLK_SRC_PLLM || src == CLK_SRC_PLLM_UD) {
336+ config->parent_rate = config->rate * (1 + div / 2);
337+ } else {
338+ unsigned long rate = config->rate * (1 + div / 2);
339+
340+ config->parent_rate = clk_hw_get_rate(parent);
341+
342+ if (config->parent_rate != rate) {
343+ dev_err(dev,
344+ "rate %lu Hz does not match input\n",
345+ config->rate);
346+ err = -EINVAL;
347+ goto put;
348+ }
349+ }
350+ }
351+
352+ emc->provider = provider;
353+
354+ return 0;
355+
356+put:
357+ module_put(provider->owner);
358+ return err;
359+}
360+EXPORT_SYMBOL_GPL(tegra210_clk_emc_attach);
361+
362+void tegra210_clk_emc_detach(struct clk *clk)
363+{
364+ struct tegra210_clk_emc *emc = to_tegra210_clk_emc(__clk_get_hw(clk));
365+
366+ module_put(emc->provider->owner);
367+ emc->provider = NULL;
368+}
369+EXPORT_SYMBOL_GPL(tegra210_clk_emc_detach);
drivers/clk/tegra/clk-tegra210.c+75−19
@@ -37,6 +37,7 @@ · 36 unmodified lines
3737 #define CLK_SOURCE_LA 0x1f8
3838 #define CLK_SOURCE_SDMMC2 0x154
3939 #define CLK_SOURCE_SDMMC4 0x164
40+#define CLK_SOURCE_EMC_DLL 0x664
4041
4142 #define PLLC_BASE 0x80
4243 #define PLLC_OUT 0x84
@@ -227,6 +228,10 @@ · 184 unmodified lines
227228 #define RST_DFLL_DVCO 0x2f4
228229 #define DVFS_DFLL_RESET_SHIFT 0
229230
231+#define CLK_RST_CONTROLLER_CLK_OUT_ENB_X_SET 0x284
232+#define CLK_RST_CONTROLLER_CLK_OUT_ENB_X_CLR 0x288
233+#define CLK_OUT_ENB_X_CLK_ENB_EMC_DLL BIT(14)
234+
230235 #define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8
231236 #define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac
232237 #define CPU_SOFTRST_CTRL 0x380
@@ -314,12 +319,6 @@ static unsigned long tegra210_input_freq[] = { · 81 unmodified lines
314319 [8] = 12000000,
315320 };
316321
317−static const char *mux_pllmcp_clkm[] = {
318− "pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_mb", "pll_mb",
319− "pll_p",
320−};
321−#define mux_pllmcp_clkm_idx NULL
322−
323322 #define PLL_ENABLE (1 << 30)
324323
325324 #define PLLCX_MISC1_IDDQ (1 << 27)
@@ -555,6 +554,27 @@ void tegra210_set_sata_pll_seq_sw(bool state) · 229 unmodified lines
555554 }
556555 EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw);
557556
557+void tegra210_clk_emc_dll_enable(bool flag)
558+{
559+ u32 offset = flag ? CLK_RST_CONTROLLER_CLK_OUT_ENB_X_SET :
560+ CLK_RST_CONTROLLER_CLK_OUT_ENB_X_CLR;
561+
562+ writel_relaxed(CLK_OUT_ENB_X_CLK_ENB_EMC_DLL, clk_base + offset);
563+}
564+EXPORT_SYMBOL_GPL(tegra210_clk_emc_dll_enable);
565+
566+void tegra210_clk_emc_dll_update_setting(u32 emc_dll_src_value)
567+{
568+ writel_relaxed(emc_dll_src_value, clk_base + CLK_SOURCE_EMC_DLL);
569+}
570+EXPORT_SYMBOL_GPL(tegra210_clk_emc_dll_update_setting);
571+
572+void tegra210_clk_emc_update_setting(u32 emc_src_value)
573+{
574+ writel_relaxed(emc_src_value, clk_base + CLK_SOURCE_EMC);
575+}
576+EXPORT_SYMBOL_GPL(tegra210_clk_emc_update_setting);
577+
558578 static void tegra210_generic_mbist_war(struct tegra210_domain_mbist_war *mbist)
559579 {
560580 u32 val;
@@ -2310,7 +2330,6 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { · 1749 unmodified lines
23102330 [tegra_clk_i2c2] = { .dt_id = TEGRA210_CLK_I2C2, .present = true },
23112331 [tegra_clk_uartc_8] = { .dt_id = TEGRA210_CLK_UARTC, .present = true },
23122332 [tegra_clk_mipi_cal] = { .dt_id = TEGRA210_CLK_MIPI_CAL, .present = true },
2313− [tegra_clk_emc] = { .dt_id = TEGRA210_CLK_EMC, .present = true },
23142333 [tegra_clk_usb2] = { .dt_id = TEGRA210_CLK_USB2, .present = true },
23152334 [tegra_clk_bsev] = { .dt_id = TEGRA210_CLK_BSEV, .present = true },
23162335 [tegra_clk_uartd_8] = { .dt_id = TEGRA210_CLK_UARTD, .present = true },
@@ -2953,6 +2972,27 @@ static const char * const sor1_parents[] = { · 636 unmodified lines
29532972
29542973 static u32 sor1_parents_idx[] = { 0, 2, 5, 6 };
29552974
2975+static const struct clk_div_table mc_div_table_tegra210[] = {
2976+ { .val = 0, .div = 2 },
2977+ { .val = 1, .div = 4 },
2978+ { .val = 2, .div = 1 },
2979+ { .val = 3, .div = 2 },
2980+ { .val = 0, .div = 0 },
2981+};
2982+
2983+static void tegra210_clk_register_mc(const char *name,
2984+ const char *parent_name)
2985+{
2986+ struct clk *clk;
2987+
2988+ clk = clk_register_divider_table(NULL, name, parent_name,
2989+ CLK_IS_CRITICAL,
2990+ clk_base + CLK_SOURCE_EMC,
2991+ 15, 2, CLK_DIVIDER_READ_ONLY,
2992+ mc_div_table_tegra210, &emc_lock);
2993+ clks[TEGRA210_CLK_MC] = clk;
2994+}
2995+
29562996 static const char * const sor1_out_parents[] = {
29572997 /*
29582998 * Bit 0 of the mux selects sor1_pad_clkout, irrespective of bit 1, so
@@ -2995,7 +3035,8 @@ static const char * const la_parents[] = { · 36 unmodified lines
29953035 static struct tegra_clk_periph tegra210_la =
29963036 TEGRA_CLK_PERIPH(29, 7, 9, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, 76, 0, NULL, NULL);
29973037
2998−static __init void tegra210_periph_clk_init(void __iomem *clk_base,
3038+static __init void tegra210_periph_clk_init(struct device_node *np,
3039+ void __iomem *clk_base,
29993040 void __iomem *pmc_base)
30003041 {
30013042 struct clk *clk;
@@ -3035,22 +3076,19 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base, · 33 unmodified lines
30353076 periph_clk_enb_refcnt);
30363077 clks[TEGRA210_CLK_DSIB] = clk;
30373078
3079+ /* csi_tpg */
3080+ clk = clk_register_gate(NULL, "csi_tpg", "pll_d",
3081+ CLK_SET_RATE_PARENT, clk_base + PLLD_BASE,
3082+ 23, 0, &pll_d_lock);
3083+ clk_register_clkdev(clk, "csi_tpg", NULL);
3084+ clks[TEGRA210_CLK_CSI_TPG] = clk;
3085+
30383086 /* la */
30393087 clk = tegra_clk_register_periph("la", la_parents,
30403088 ARRAY_SIZE(la_parents), &tegra210_la, clk_base,
30413089 CLK_SOURCE_LA, 0);
30423090 clks[TEGRA210_CLK_LA] = clk;
30433091
3044− /* emc mux */
3045− clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
3046− ARRAY_SIZE(mux_pllmcp_clkm), 0,
3047− clk_base + CLK_SOURCE_EMC,
3048− 29, 3, 0, &emc_lock);
3049−
3050− clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC,
3051− &emc_lock);
3052− clks[TEGRA210_CLK_MC] = clk;
3053−
30543092 /* cml0 */
30553093 clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX,
30563094 0, 0, &pll_e_lock);
@@ -3093,6 +3131,13 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base, · 36 unmodified lines
30933131 }
30943132
30953133 tegra_periph_clk_init(clk_base, pmc_base, tegra210_clks, &pll_p_params);
3134+
3135+ /* emc */
3136+ clk = tegra210_clk_register_emc(np, clk_base);
3137+ clks[TEGRA210_CLK_EMC] = clk;
3138+
3139+ /* mc */
3140+ tegra210_clk_register_mc("mc", "emc");
30963141 }
30973142
30983143 static void __init tegra210_pll_init(void __iomem *clk_base,
@@ -3153,6 +3198,17 @@ static void __init tegra210_pll_init(void __iomem *clk_base, · 54 unmodified lines
31533198 clk_register_clkdev(clk, "pll_m_ud", NULL);
31543199 clks[TEGRA210_CLK_PLL_M_UD] = clk;
31553200
3201+ /* PLLMB_UD */
3202+ clk = clk_register_fixed_factor(NULL, "pll_mb_ud", "pll_mb",
3203+ CLK_SET_RATE_PARENT, 1, 1);
3204+ clk_register_clkdev(clk, "pll_mb_ud", NULL);
3205+ clks[TEGRA210_CLK_PLL_MB_UD] = clk;
3206+
3207+ /* PLLP_UD */
3208+ clk = clk_register_fixed_factor(NULL, "pll_p_ud", "pll_p",
3209+ 0, 1, 1);
3210+ clks[TEGRA210_CLK_PLL_P_UD] = clk;
3211+
31563212 /* PLLU_VCO */
31573213 if (!tegra210_init_pllu()) {
31583214 clk = clk_register_fixed_rate(NULL, "pll_u_vco", "pll_ref", 0,
@@ -3680,7 +3736,7 @@ static void __init tegra210_clock_init(struct device_node *np) · 521 unmodified lines
36803736
36813737 tegra_fixed_clk_init(tegra210_clks);
36823738 tegra210_pll_init(clk_base, pmc_base);
3683− tegra210_periph_clk_init(clk_base, pmc_base);
3739+ tegra210_periph_clk_init(np, clk_base, pmc_base);
36843740 tegra_audio_clk_init(clk_base, pmc_base, tegra210_clks,
36853741 tegra210_audio_plls,
36863742 ARRAY_SIZE(tegra210_audio_plls), 24576000);
drivers/clk/tegra/clk-tegra30.c+4−2
@@ -499,6 +499,8 @@ static struct tegra_clk_pll_params pll_x_params __ro_after_init = { · 498 unmodified lines
499499 .freq_table = pll_x_freq_table,
500500 .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_DCCON |
501501 TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
502+ .pre_rate_change = tegra_cclk_pre_pllx_rate_change,
503+ .post_rate_change = tegra_cclk_post_pllx_rate_change,
502504 };
503505
504506 static struct tegra_clk_pll_params pll_e_params __ro_after_init = {
@@ -926,11 +928,11 @@ static void __init tegra30_super_clk_init(void) · 421 unmodified lines
926928 clk_register_clkdev(clk, "pll_p_out4_cclkg", NULL);
927929
928930 /* CCLKG */
929− clk = tegra_clk_register_super_mux("cclk_g", cclk_g_parents,
931+ clk = tegra_clk_register_super_cclk("cclk_g", cclk_g_parents,
930932 ARRAY_SIZE(cclk_g_parents),
931933 CLK_SET_RATE_PARENT,
932934 clk_base + CCLKG_BURST_POLICY,
933− 0, 4, 0, 0, NULL);
935+ 0, NULL);
934936 clks[TEGRA30_CLK_CCLK_G] = clk;
935937
936938 /*
drivers/clk/tegra/clk.h+21−3
@@ -266,6 +266,10 @@ struct tegra_clk_pll; · 265 unmodified lines
266266 * disabled.
267267 * @dyn_ramp: Callback which can be used to define a custom
268268 * dynamic ramp function for a given PLL.
269+ * @pre_rate_change: Callback which is invoked just before changing
270+ * PLL's rate.
271+ * @post_rate_change: Callback which is invoked right after changing
272+ * PLL's rate.
269273 *
270274 * Flags:
271275 * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for
@@ -342,6 +346,8 @@ struct tegra_clk_pll_params { · 70 unmodified lines
342346 void (*set_defaults)(struct tegra_clk_pll *pll);
343347 int (*dyn_ramp)(struct tegra_clk_pll *pll,
344348 struct tegra_clk_pll_freq_table *cfg);
349+ int (*pre_rate_change)(void);
350+ void (*post_rate_change)(void);
345351 };
346352
347353 #define TEGRA_PLL_USE_LOCK BIT(0)
@@ -729,8 +735,10 @@ struct clk *tegra_clk_register_periph_data(void __iomem *clk_base, · 381 unmodified lines
729735 * TEGRA_DIVIDER_2 - LP cluster has additional divider. This flag indicates
730736 * that this is LP cluster clock.
731737 * TEGRA210_CPU_CLK - This flag is used to identify CPU cluster for gen5
732− * super mux parent using PLLP branches. To use PLLP branches to CPU, need
733− * to configure additional bit PLLP_OUT_CPU in the clock registers.
738+ * super mux parent using PLLP branches. To use PLLP branches to CPU, need
739+ * to configure additional bit PLLP_OUT_CPU in the clock registers.
740+ * TEGRA20_SUPER_CLK - Tegra20 doesn't have a dedicated divider for Super
741+ * clocks, it only has a clock-skipper.
734742 */
735743 struct tegra_clk_super_mux {
736744 struct clk_hw hw;
@@ -748,6 +756,7 @@ struct tegra_clk_super_mux { · 11 unmodified lines
748756
749757 #define TEGRA_DIVIDER_2 BIT(0)
750758 #define TEGRA210_CPU_CLK BIT(1)
759+#define TEGRA20_SUPER_CLK BIT(2)
751760
752761 extern const struct clk_ops tegra_clk_super_ops;
753762 struct clk *tegra_clk_register_super_mux(const char *name,
@@ -758,6 +767,12 @@ struct clk *tegra_clk_register_super_clk(const char *name, · 4 unmodified lines
758767 const char * const *parent_names, u8 num_parents,
759768 unsigned long flags, void __iomem *reg, u8 clk_super_flags,
760769 spinlock_t *lock);
770+struct clk *tegra_clk_register_super_cclk(const char *name,
771+ const char * const *parent_names, u8 num_parents,
772+ unsigned long flags, void __iomem *reg, u8 clk_super_flags,
773+ spinlock_t *lock);
774+int tegra_cclk_pre_pllx_rate_change(void);
775+void tegra_cclk_post_pllx_rate_change(void);
761776
762777 /**
763778 * struct tegra_sdmmc_mux - switch divider with Low Jitter inputs for SDMMC
@@ -866,7 +881,7 @@ void tegra_super_clk_gen5_init(void __iomem *clk_base, · 102 unmodified lines
866881 void __iomem *pmc_base, struct tegra_clk *tegra_clks,
867882 struct tegra_clk_pll_params *pll_params);
868883
869−#ifdef CONFIG_TEGRA_CLK_EMC
884+#ifdef CONFIG_TEGRA124_EMC
870885 struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
871886 spinlock_t *lock);
872887 #else
@@ -907,4 +922,7 @@ void tegra_clk_periph_resume(void); · 34 unmodified lines
907922 bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw);
908923 struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter);
909924
925+struct clk *tegra210_clk_register_emc(struct device_node *np,
926+ void __iomem *regs);
927+
910928 #endif /* TEGRA_CLK_H */
drivers/clk/ti/clk-44xx.c+7−7
@@ -606,13 +606,13 @@ static const struct omap_clkctrl_reg_data omap4_l4_per_clkctrl_regs[] __initcons · 605 unmodified lines
606606
607607 static const struct
608608 omap_clkctrl_reg_data omap4_l4_secure_clkctrl_regs[] __initconst = {
609− { OMAP4_AES1_CLKCTRL, NULL, CLKF_SW_SUP, "" },
610− { OMAP4_AES2_CLKCTRL, NULL, CLKF_SW_SUP, "" },
611− { OMAP4_DES3DES_CLKCTRL, NULL, CLKF_SW_SUP, "" },
612− { OMAP4_PKA_CLKCTRL, NULL, CLKF_SW_SUP, "" },
613− { OMAP4_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
614− { OMAP4_SHA2MD5_CLKCTRL, NULL, CLKF_SW_SUP, "" },
615− { OMAP4_CRYPTODMA_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
609+ { OMAP4_AES1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_div_ck" },
610+ { OMAP4_AES2_CLKCTRL, NULL, CLKF_SW_SUP, "l3_div_ck" },
611+ { OMAP4_DES3DES_CLKCTRL, NULL, CLKF_SW_SUP, "l4_div_ck" },
612+ { OMAP4_PKA_CLKCTRL, NULL, CLKF_SW_SUP, "l4_div_ck" },
613+ { OMAP4_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l4_div_ck" },
614+ { OMAP4_SHA2MD5_CLKCTRL, NULL, CLKF_SW_SUP, "l3_div_ck" },
615+ { OMAP4_CRYPTODMA_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l3_div_ck" },
616616 { 0 },
617617 };
618618
drivers/clk/ti/clk-54xx.c+7−7
@@ -303,13 +303,13 @@ static const struct omap_clkctrl_reg_data omap5_l4per_clkctrl_regs[] __initconst · 302 unmodified lines
303303
304304 static const struct
305305 omap_clkctrl_reg_data omap5_l4_secure_clkctrl_regs[] __initconst = {
306− { OMAP5_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "" },
307− { OMAP5_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "" },
308− { OMAP5_DES3DES_CLKCTRL, NULL, CLKF_HW_SUP, "" },
309− { OMAP5_FPKA_CLKCTRL, NULL, CLKF_SW_SUP, "" },
310− { OMAP5_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
311− { OMAP5_SHA2MD5_CLKCTRL, NULL, CLKF_HW_SUP, "" },
312− { OMAP5_DMA_CRYPTO_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
306+ { OMAP5_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
307+ { OMAP5_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
308+ { OMAP5_DES3DES_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" },
309+ { OMAP5_FPKA_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div" },
310+ { OMAP5_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l4_root_clk_div" },
311+ { OMAP5_SHA2MD5_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
312+ { OMAP5_DMA_CRYPTO_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l3_iclk_div" },
313313 { 0 },
314314 };
315315
drivers/clk/ti/clk-7xx.c+3−12
@@ -312,15 +312,6 @@ static const char * const dra7_gpu_hyd_mux_parents[] __initconst = { · 311 unmodified lines
312312 NULL,
313313 };
314314
315−static const char * const dra7_gpu_sys_clk_parents[] __initconst = {
316− "sys_clkin",
317− NULL,
318−};
319−
320−static const struct omap_clkctrl_div_data dra7_gpu_sys_clk_data __initconst = {
321− .max_div = 2,
322−};
323−
324315 static const struct omap_clkctrl_bit_data dra7_gpu_core_bit_data[] __initconst = {
325316 { 24, TI_CLK_MUX, dra7_gpu_core_mux_parents, NULL, },
326317 { 26, TI_CLK_MUX, dra7_gpu_hyd_mux_parents, NULL, },
@@ -328,7 +319,7 @@ static const struct omap_clkctrl_bit_data dra7_gpu_core_bit_data[] __initconst = · 1 unmodified line
328319 };
329320
330321 static const struct omap_clkctrl_reg_data dra7_gpu_clkctrl_regs[] __initconst = {
331− { DRA7_GPU_CLKCTRL, dra7_gpu_core_bit_data, CLKF_SW_SUP, "gpu_cm:clk:0000:24", },
322+ { DRA7_GPU_CLKCTRL, dra7_gpu_core_bit_data, CLKF_SW_SUP, "gpu-clkctrl:0000:24", },
332323 { 0 },
333324 };
334325
@@ -644,7 +635,7 @@ static const struct omap_clkctrl_reg_data dra7_l4sec_clkctrl_regs[] __initconst · 309 unmodified lines
644635 { DRA7_L4SEC_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
645636 { DRA7_L4SEC_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
646637 { DRA7_L4SEC_DES_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
647− { DRA7_L4SEC_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
638+ { DRA7_L4SEC_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l4_root_clk_div" },
648639 { DRA7_L4SEC_SHAM_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
649640 { 0 },
650641 };
@@ -815,7 +806,7 @@ static const struct omap_clkctrl_reg_data dra7_wkupaon_clkctrl_regs[] __initcons · 164 unmodified lines
815806 { DRA7_WKUPAON_COUNTER_32K_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" },
816807 { DRA7_WKUPAON_UART10_CLKCTRL, dra7_uart10_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0060:24" },
817808 { DRA7_WKUPAON_DCAN1_CLKCTRL, dra7_dcan1_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0068:24" },
818− { DRA7_WKUPAON_ADC_CLKCTRL, NULL, CLKF_SW_SUP, "mcan_clk" },
809+ { DRA7_WKUPAON_ADC_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SOC_DRA76, "mcan_clk" },
819810 { 0 },
820811 };
821812
drivers/clk/ti/composite.c+1−0
@@ -196,6 +196,7 @@ cleanup: · 195 unmodified lines
196196 if (!cclk->comp_clks[i])
197197 continue;
198198 list_del(&cclk->comp_clks[i]->link);
199+ kfree(cclk->comp_clks[i]->parent_names);
199200 kfree(cclk->comp_clks[i]);
200201 }
201202
drivers/clk/versatile/clk-versatile.c+1−1
@@ -56,7 +56,7 @@ static const struct clk_icst_desc versatile_auxosc_desc __initconst = { · 55 unmodified lines
5656 static void __init cm_osc_setup(struct device_node *np,
5757 const struct clk_icst_desc *desc)
5858 {
59− struct clk *clk = ERR_PTR(-EINVAL);
59+ struct clk *clk;
6060 const char *clk_name = np->name;
6161 const char *parent_name;
6262
drivers/clk/x86/Kconfig+8−0
@@ -0,0 +1,8 @@
1+# SPDX-License-Identifier: GPL-2.0-only
2+config CLK_LGM_CGU
3+ depends on OF && HAS_IOMEM && (X86 || COMPILE_TEST)
4+ select OF_EARLY_FLATTREE
5+ bool "Clock driver for Lightning Mountain(LGM) platform"
6+ help
7+ Clock Generation Unit(CGU) driver for Intel Lightning Mountain(LGM)
8+ network processor SoC.
drivers/clk/x86/Makefile+1−0
@@ -3,3 +3,4 @@ obj-$(CONFIG_PMC_ATOM) += clk-pmc-atom.o · 2 unmodified lines
33 obj-$(CONFIG_X86_AMD_PLATFORM_DEVICE) += clk-st.o
44 clk-x86-lpss-objs := clk-lpt.o
55 obj-$(CONFIG_X86_INTEL_LPSS) += clk-x86-lpss.o
6+obj-$(CONFIG_CLK_LGM_CGU) += clk-cgu.o clk-cgu-pll.o clk-lgm.o
drivers/clk/x86/clk-cgu-pll.c+156−0
@@ -0,0 +1,156 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (C) 2020 Intel Corporation.
4+ * Zhu YiXin <yixin.zhu@intel.com>
5+ * Rahul Tanwar <rahul.tanwar@intel.com>
6+ */
7+
8+#include <linux/clk-provider.h>
9+#include <linux/delay.h>
10+#include <linux/device.h>
11+#include <linux/iopoll.h>
12+#include <linux/of.h>
13+
14+#include "clk-cgu.h"
15+
16+#define to_lgm_clk_pll(_hw) container_of(_hw, struct lgm_clk_pll, hw)
17+#define PLL_REF_DIV(x) ((x) + 0x08)
18+
19+/*
20+ * Calculate formula:
21+ * rate = (prate * mult + (prate * frac) / frac_div) / div
22+ */
23+static unsigned long
24+lgm_pll_calc_rate(unsigned long prate, unsigned int mult,
25+ unsigned int div, unsigned int frac, unsigned int frac_div)
26+{
27+ u64 crate, frate, rate64;
28+
29+ rate64 = prate;
30+ crate = rate64 * mult;
31+ frate = rate64 * frac;
32+ do_div(frate, frac_div);
33+ crate += frate;
34+ do_div(crate, div);
35+
36+ return crate;
37+}
38+
39+static unsigned long lgm_pll_recalc_rate(struct clk_hw *hw, unsigned long prate)
40+{
41+ struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
42+ unsigned int div, mult, frac;
43+ unsigned long flags;
44+
45+ spin_lock_irqsave(&pll->lock, flags);
46+ mult = lgm_get_clk_val(pll->membase, PLL_REF_DIV(pll->reg), 0, 12);
47+ div = lgm_get_clk_val(pll->membase, PLL_REF_DIV(pll->reg), 18, 6);
48+ frac = lgm_get_clk_val(pll->membase, pll->reg, 2, 24);
49+ spin_unlock_irqrestore(&pll->lock, flags);
50+
51+ if (pll->type == TYPE_LJPLL)
52+ div *= 4;
53+
54+ return lgm_pll_calc_rate(prate, mult, div, frac, BIT(24));
55+}
56+
57+static int lgm_pll_is_enabled(struct clk_hw *hw)
58+{
59+ struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
60+ unsigned long flags;
61+ unsigned int ret;
62+
63+ spin_lock_irqsave(&pll->lock, flags);
64+ ret = lgm_get_clk_val(pll->membase, pll->reg, 0, 1);
65+ spin_unlock_irqrestore(&pll->lock, flags);
66+
67+ return ret;
68+}
69+
70+static int lgm_pll_enable(struct clk_hw *hw)
71+{
72+ struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
73+ unsigned long flags;
74+ u32 val;
75+ int ret;
76+
77+ spin_lock_irqsave(&pll->lock, flags);
78+ lgm_set_clk_val(pll->membase, pll->reg, 0, 1, 1);
79+ ret = readl_poll_timeout_atomic(pll->membase + pll->reg,
80+ val, (val & 0x1), 1, 100);
81+ spin_unlock_irqrestore(&pll->lock, flags);
82+
83+ return ret;
84+}
85+
86+static void lgm_pll_disable(struct clk_hw *hw)
87+{
88+ struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
89+ unsigned long flags;
90+
91+ spin_lock_irqsave(&pll->lock, flags);
92+ lgm_set_clk_val(pll->membase, pll->reg, 0, 1, 0);
93+ spin_unlock_irqrestore(&pll->lock, flags);
94+}
95+
96+static const struct clk_ops lgm_pll_ops = {
97+ .recalc_rate = lgm_pll_recalc_rate,
98+ .is_enabled = lgm_pll_is_enabled,
99+ .enable = lgm_pll_enable,
100+ .disable = lgm_pll_disable,
101+};
102+
103+static struct clk_hw *
104+lgm_clk_register_pll(struct lgm_clk_provider *ctx,
105+ const struct lgm_pll_clk_data *list)
106+{
107+ struct clk_init_data init = {};
108+ struct lgm_clk_pll *pll;
109+ struct device *dev = ctx->dev;
110+ struct clk_hw *hw;
111+ int ret;
112+
113+ init.ops = &lgm_pll_ops;
114+ init.name = list->name;
115+ init.flags = list->flags;
116+ init.parent_data = list->parent_data;
117+ init.num_parents = list->num_parents;
118+
119+ pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
120+ if (!pll)
121+ return ERR_PTR(-ENOMEM);
122+
123+ pll->membase = ctx->membase;
124+ pll->lock = ctx->lock;
125+ pll->reg = list->reg;
126+ pll->flags = list->flags;
127+ pll->type = list->type;
128+ pll->hw.init = &init;
129+
130+ hw = &pll->hw;
131+ ret = clk_hw_register(dev, hw);
132+ if (ret)
133+ return ERR_PTR(ret);
134+
135+ return hw;
136+}
137+
138+int lgm_clk_register_plls(struct lgm_clk_provider *ctx,
139+ const struct lgm_pll_clk_data *list,
140+ unsigned int nr_clk)
141+{
142+ struct clk_hw *hw;
143+ int i;
144+
145+ for (i = 0; i < nr_clk; i++, list++) {
146+ hw = lgm_clk_register_pll(ctx, list);
147+ if (IS_ERR(hw)) {
148+ dev_err(ctx->dev, "failed to register pll: %s\n",
149+ list->name);
150+ return PTR_ERR(hw);
151+ }
152+ ctx->clk_data.hws[list->id] = hw;
153+ }
154+
155+ return 0;
156+}
drivers/clk/x86/clk-cgu.c+636−0
@@ -0,0 +1,636 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (C) 2020 Intel Corporation.
4+ * Zhu YiXin <yixin.zhu@intel.com>
5+ * Rahul Tanwar <rahul.tanwar@intel.com>
6+ */
7+#include <linux/clk-provider.h>
8+#include <linux/device.h>
9+#include <linux/of.h>
10+
11+#include "clk-cgu.h"
12+
13+#define GATE_HW_REG_STAT(reg) ((reg) + 0x0)
14+#define GATE_HW_REG_EN(reg) ((reg) + 0x4)
15+#define GATE_HW_REG_DIS(reg) ((reg) + 0x8)
16+#define MAX_DDIV_REG 8
17+#define MAX_DIVIDER_VAL 64
18+
19+#define to_lgm_clk_mux(_hw) container_of(_hw, struct lgm_clk_mux, hw)
20+#define to_lgm_clk_divider(_hw) container_of(_hw, struct lgm_clk_divider, hw)
21+#define to_lgm_clk_gate(_hw) container_of(_hw, struct lgm_clk_gate, hw)
22+#define to_lgm_clk_ddiv(_hw) container_of(_hw, struct lgm_clk_ddiv, hw)
23+
24+static struct clk_hw *lgm_clk_register_fixed(struct lgm_clk_provider *ctx,
25+ const struct lgm_clk_branch *list)
26+{
27+ unsigned long flags;
28+
29+ if (list->div_flags & CLOCK_FLAG_VAL_INIT) {
30+ spin_lock_irqsave(&ctx->lock, flags);
31+ lgm_set_clk_val(ctx->membase, list->div_off, list->div_shift,
32+ list->div_width, list->div_val);
33+ spin_unlock_irqrestore(&ctx->lock, flags);
34+ }
35+
36+ return clk_hw_register_fixed_rate(NULL, list->name,
37+ list->parent_data[0].name,
38+ list->flags, list->mux_flags);
39+}
40+
41+static u8 lgm_clk_mux_get_parent(struct clk_hw *hw)
42+{
43+ struct lgm_clk_mux *mux = to_lgm_clk_mux(hw);
44+ unsigned long flags;
45+ u32 val;
46+
47+ spin_lock_irqsave(&mux->lock, flags);
48+ if (mux->flags & MUX_CLK_SW)
49+ val = mux->reg;
50+ else
51+ val = lgm_get_clk_val(mux->membase, mux->reg, mux->shift,
52+ mux->width);
53+ spin_unlock_irqrestore(&mux->lock, flags);
54+ return clk_mux_val_to_index(hw, NULL, mux->flags, val);
55+}
56+
57+static int lgm_clk_mux_set_parent(struct clk_hw *hw, u8 index)
58+{
59+ struct lgm_clk_mux *mux = to_lgm_clk_mux(hw);
60+ unsigned long flags;
61+ u32 val;
62+
63+ val = clk_mux_index_to_val(NULL, mux->flags, index);
64+ spin_lock_irqsave(&mux->lock, flags);
65+ if (mux->flags & MUX_CLK_SW)
66+ mux->reg = val;
67+ else
68+ lgm_set_clk_val(mux->membase, mux->reg, mux->shift,
69+ mux->width, val);
70+ spin_unlock_irqrestore(&mux->lock, flags);
71+
72+ return 0;
73+}
74+
75+static int lgm_clk_mux_determine_rate(struct clk_hw *hw,
76+ struct clk_rate_request *req)
77+{
78+ struct lgm_clk_mux *mux = to_lgm_clk_mux(hw);
79+
80+ return clk_mux_determine_rate_flags(hw, req, mux->flags);
81+}
82+
83+static const struct clk_ops lgm_clk_mux_ops = {
84+ .get_parent = lgm_clk_mux_get_parent,
85+ .set_parent = lgm_clk_mux_set_parent,
86+ .determine_rate = lgm_clk_mux_determine_rate,
87+};
88+
89+static struct clk_hw *
90+lgm_clk_register_mux(struct lgm_clk_provider *ctx,
91+ const struct lgm_clk_branch *list)
92+{
93+ unsigned long flags, cflags = list->mux_flags;
94+ struct device *dev = ctx->dev;
95+ u8 shift = list->mux_shift;
96+ u8 width = list->mux_width;
97+ struct clk_init_data init = {};
98+ struct lgm_clk_mux *mux;
99+ u32 reg = list->mux_off;
100+ struct clk_hw *hw;
101+ int ret;
102+
103+ mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
104+ if (!mux)
105+ return ERR_PTR(-ENOMEM);
106+
107+ init.name = list->name;
108+ init.ops = &lgm_clk_mux_ops;
109+ init.flags = list->flags;
110+ init.parent_data = list->parent_data;
111+ init.num_parents = list->num_parents;
112+
113+ mux->membase = ctx->membase;
114+ mux->lock = ctx->lock;
115+ mux->reg = reg;
116+ mux->shift = shift;
117+ mux->width = width;
118+ mux->flags = cflags;
119+ mux->hw.init = &init;
120+
121+ hw = &mux->hw;
122+ ret = clk_hw_register(dev, hw);
123+ if (ret)
124+ return ERR_PTR(ret);
125+
126+ if (cflags & CLOCK_FLAG_VAL_INIT) {
127+ spin_lock_irqsave(&mux->lock, flags);
128+ lgm_set_clk_val(mux->membase, reg, shift, width, list->mux_val);
129+ spin_unlock_irqrestore(&mux->lock, flags);
130+ }
131+
132+ return hw;
133+}
134+
135+static unsigned long
136+lgm_clk_divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
137+{
138+ struct lgm_clk_divider *divider = to_lgm_clk_divider(hw);
139+ unsigned long flags;
140+ unsigned int val;
141+
142+ spin_lock_irqsave(&divider->lock, flags);
143+ val = lgm_get_clk_val(divider->membase, divider->reg,
144+ divider->shift, divider->width);
145+ spin_unlock_irqrestore(&divider->lock, flags);
146+
147+ return divider_recalc_rate(hw, parent_rate, val, divider->table,
148+ divider->flags, divider->width);
149+}
150+
151+static long
152+lgm_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
153+ unsigned long *prate)
154+{
155+ struct lgm_clk_divider *divider = to_lgm_clk_divider(hw);
156+
157+ return divider_round_rate(hw, rate, prate, divider->table,
158+ divider->width, divider->flags);
159+}
160+
161+static int
162+lgm_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
163+ unsigned long prate)
164+{
165+ struct lgm_clk_divider *divider = to_lgm_clk_divider(hw);
166+ unsigned long flags;
167+ int value;
168+
169+ value = divider_get_val(rate, prate, divider->table,
170+ divider->width, divider->flags);
171+ if (value < 0)
172+ return value;
173+
174+ spin_lock_irqsave(&divider->lock, flags);
175+ lgm_set_clk_val(divider->membase, divider->reg,
176+ divider->shift, divider->width, value);
177+ spin_unlock_irqrestore(&divider->lock, flags);
178+
179+ return 0;
180+}
181+
182+static int lgm_clk_divider_enable_disable(struct clk_hw *hw, int enable)
183+{
184+ struct lgm_clk_divider *div = to_lgm_clk_divider(hw);
185+ unsigned long flags;
186+
187+ spin_lock_irqsave(&div->lock, flags);
188+ lgm_set_clk_val(div->membase, div->reg, div->shift_gate,
189+ div->width_gate, enable);
190+ spin_unlock_irqrestore(&div->lock, flags);
191+ return 0;
192+}
193+
194+static int lgm_clk_divider_enable(struct clk_hw *hw)
195+{
196+ return lgm_clk_divider_enable_disable(hw, 1);
197+}
198+
199+static void lgm_clk_divider_disable(struct clk_hw *hw)
200+{
201+ lgm_clk_divider_enable_disable(hw, 0);
202+}
203+
204+static const struct clk_ops lgm_clk_divider_ops = {
205+ .recalc_rate = lgm_clk_divider_recalc_rate,
206+ .round_rate = lgm_clk_divider_round_rate,
207+ .set_rate = lgm_clk_divider_set_rate,
208+ .enable = lgm_clk_divider_enable,
209+ .disable = lgm_clk_divider_disable,
210+};
211+
212+static struct clk_hw *
213+lgm_clk_register_divider(struct lgm_clk_provider *ctx,
214+ const struct lgm_clk_branch *list)
215+{
216+ unsigned long flags, cflags = list->div_flags;
217+ struct device *dev = ctx->dev;
218+ struct lgm_clk_divider *div;
219+ struct clk_init_data init = {};
220+ u8 shift = list->div_shift;
221+ u8 width = list->div_width;
222+ u8 shift_gate = list->div_shift_gate;
223+ u8 width_gate = list->div_width_gate;
224+ u32 reg = list->div_off;
225+ struct clk_hw *hw;
226+ int ret;
227+
228+ div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL);
229+ if (!div)
230+ return ERR_PTR(-ENOMEM);
231+
232+ init.name = list->name;
233+ init.ops = &lgm_clk_divider_ops;
234+ init.flags = list->flags;
235+ init.parent_data = list->parent_data;
236+ init.num_parents = 1;
237+
238+ div->membase = ctx->membase;
239+ div->lock = ctx->lock;
240+ div->reg = reg;
241+ div->shift = shift;
242+ div->width = width;
243+ div->shift_gate = shift_gate;
244+ div->width_gate = width_gate;
245+ div->flags = cflags;
246+ div->table = list->div_table;
247+ div->hw.init = &init;
248+
249+ hw = &div->hw;
250+ ret = clk_hw_register(dev, hw);
251+ if (ret)
252+ return ERR_PTR(ret);
253+
254+ if (cflags & CLOCK_FLAG_VAL_INIT) {
255+ spin_lock_irqsave(&div->lock, flags);
256+ lgm_set_clk_val(div->membase, reg, shift, width, list->div_val);
257+ spin_unlock_irqrestore(&div->lock, flags);
258+ }
259+
260+ return hw;
261+}
262+
263+static struct clk_hw *
264+lgm_clk_register_fixed_factor(struct lgm_clk_provider *ctx,
265+ const struct lgm_clk_branch *list)
266+{
267+ unsigned long flags;
268+ struct clk_hw *hw;
269+
270+ hw = clk_hw_register_fixed_factor(ctx->dev, list->name,
271+ list->parent_data[0].name, list->flags,
272+ list->mult, list->div);
273+ if (IS_ERR(hw))
274+ return ERR_CAST(hw);
275+
276+ if (list->div_flags & CLOCK_FLAG_VAL_INIT) {
277+ spin_lock_irqsave(&ctx->lock, flags);
278+ lgm_set_clk_val(ctx->membase, list->div_off, list->div_shift,
279+ list->div_width, list->div_val);
280+ spin_unlock_irqrestore(&ctx->lock, flags);
281+ }
282+
283+ return hw;
284+}
285+
286+static int lgm_clk_gate_enable(struct clk_hw *hw)
287+{
288+ struct lgm_clk_gate *gate = to_lgm_clk_gate(hw);
289+ unsigned long flags;
290+ unsigned int reg;
291+
292+ spin_lock_irqsave(&gate->lock, flags);
293+ reg = GATE_HW_REG_EN(gate->reg);
294+ lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1);
295+ spin_unlock_irqrestore(&gate->lock, flags);
296+
297+ return 0;
298+}
299+
300+static void lgm_clk_gate_disable(struct clk_hw *hw)
301+{
302+ struct lgm_clk_gate *gate = to_lgm_clk_gate(hw);
303+ unsigned long flags;
304+ unsigned int reg;
305+
306+ spin_lock_irqsave(&gate->lock, flags);
307+ reg = GATE_HW_REG_DIS(gate->reg);
308+ lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1);
309+ spin_unlock_irqrestore(&gate->lock, flags);
310+}
311+
312+static int lgm_clk_gate_is_enabled(struct clk_hw *hw)
313+{
314+ struct lgm_clk_gate *gate = to_lgm_clk_gate(hw);
315+ unsigned int reg, ret;
316+ unsigned long flags;
317+
318+ spin_lock_irqsave(&gate->lock, flags);
319+ reg = GATE_HW_REG_STAT(gate->reg);
320+ ret = lgm_get_clk_val(gate->membase, reg, gate->shift, 1);
321+ spin_unlock_irqrestore(&gate->lock, flags);
322+
323+ return ret;
324+}
325+
326+static const struct clk_ops lgm_clk_gate_ops = {
327+ .enable = lgm_clk_gate_enable,
328+ .disable = lgm_clk_gate_disable,
329+ .is_enabled = lgm_clk_gate_is_enabled,
330+};
331+
332+static struct clk_hw *
333+lgm_clk_register_gate(struct lgm_clk_provider *ctx,
334+ const struct lgm_clk_branch *list)
335+{
336+ unsigned long flags, cflags = list->gate_flags;
337+ const char *pname = list->parent_data[0].name;
338+ struct device *dev = ctx->dev;
339+ u8 shift = list->gate_shift;
340+ struct clk_init_data init = {};
341+ struct lgm_clk_gate *gate;
342+ u32 reg = list->gate_off;
343+ struct clk_hw *hw;
344+ int ret;
345+
346+ gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
347+ if (!gate)
348+ return ERR_PTR(-ENOMEM);
349+
350+ init.name = list->name;
351+ init.ops = &lgm_clk_gate_ops;
352+ init.flags = list->flags;
353+ init.parent_names = pname ? &pname : NULL;
354+ init.num_parents = pname ? 1 : 0;
355+
356+ gate->membase = ctx->membase;
357+ gate->lock = ctx->lock;
358+ gate->reg = reg;
359+ gate->shift = shift;
360+ gate->flags = cflags;
361+ gate->hw.init = &init;
362+
363+ hw = &gate->hw;
364+ ret = clk_hw_register(dev, hw);
365+ if (ret)
366+ return ERR_PTR(ret);
367+
368+ if (cflags & CLOCK_FLAG_VAL_INIT) {
369+ spin_lock_irqsave(&gate->lock, flags);
370+ lgm_set_clk_val(gate->membase, reg, shift, 1, list->gate_val);
371+ spin_unlock_irqrestore(&gate->lock, flags);
372+ }
373+
374+ return hw;
375+}
376+
377+int lgm_clk_register_branches(struct lgm_clk_provider *ctx,
378+ const struct lgm_clk_branch *list,
379+ unsigned int nr_clk)
380+{
381+ struct clk_hw *hw;
382+ unsigned int idx;
383+
384+ for (idx = 0; idx < nr_clk; idx++, list++) {
385+ switch (list->type) {
386+ case CLK_TYPE_FIXED:
387+ hw = lgm_clk_register_fixed(ctx, list);
388+ break;
389+ case CLK_TYPE_MUX:
390+ hw = lgm_clk_register_mux(ctx, list);
391+ break;
392+ case CLK_TYPE_DIVIDER:
393+ hw = lgm_clk_register_divider(ctx, list);
394+ break;
395+ case CLK_TYPE_FIXED_FACTOR:
396+ hw = lgm_clk_register_fixed_factor(ctx, list);
397+ break;
398+ case CLK_TYPE_GATE:
399+ hw = lgm_clk_register_gate(ctx, list);
400+ break;
401+ default:
402+ dev_err(ctx->dev, "invalid clk type\n");
403+ return -EINVAL;
404+ }
405+
406+ if (IS_ERR(hw)) {
407+ dev_err(ctx->dev,
408+ "register clk: %s, type: %u failed!\n",
409+ list->name, list->type);
410+ return -EIO;
411+ }
412+ ctx->clk_data.hws[list->id] = hw;
413+ }
414+
415+ return 0;
416+}
417+
418+static unsigned long
419+lgm_clk_ddiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
420+{
421+ struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
422+ unsigned int div0, div1, exdiv;
423+ unsigned long flags;
424+ u64 prate;
425+
426+ spin_lock_irqsave(&ddiv->lock, flags);
427+ div0 = lgm_get_clk_val(ddiv->membase, ddiv->reg,
428+ ddiv->shift0, ddiv->width0) + 1;
429+ div1 = lgm_get_clk_val(ddiv->membase, ddiv->reg,
430+ ddiv->shift1, ddiv->width1) + 1;
431+ exdiv = lgm_get_clk_val(ddiv->membase, ddiv->reg,
432+ ddiv->shift2, ddiv->width2);
433+ spin_unlock_irqrestore(&ddiv->lock, flags);
434+
435+ prate = (u64)parent_rate;
436+ do_div(prate, div0);
437+ do_div(prate, div1);
438+
439+ if (exdiv) {
440+ do_div(prate, ddiv->div);
441+ prate *= ddiv->mult;
442+ }
443+
444+ return prate;
445+}
446+
447+static int lgm_clk_ddiv_enable(struct clk_hw *hw)
448+{
449+ struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
450+ unsigned long flags;
451+
452+ spin_lock_irqsave(&ddiv->lock, flags);
453+ lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift_gate,
454+ ddiv->width_gate, 1);
455+ spin_unlock_irqrestore(&ddiv->lock, flags);
456+ return 0;
457+}
458+
459+static void lgm_clk_ddiv_disable(struct clk_hw *hw)
460+{
461+ struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
462+ unsigned long flags;
463+
464+ spin_lock_irqsave(&ddiv->lock, flags);
465+ lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift_gate,
466+ ddiv->width_gate, 0);
467+ spin_unlock_irqrestore(&ddiv->lock, flags);
468+}
469+
470+static int
471+lgm_clk_get_ddiv_val(u32 div, u32 *ddiv1, u32 *ddiv2)
472+{
473+ u32 idx, temp;
474+
475+ *ddiv1 = 1;
476+ *ddiv2 = 1;
477+
478+ if (div > MAX_DIVIDER_VAL)
479+ div = MAX_DIVIDER_VAL;
480+
481+ if (div > 1) {
482+ for (idx = 2; idx <= MAX_DDIV_REG; idx++) {
483+ temp = DIV_ROUND_UP_ULL((u64)div, idx);
484+ if (div % idx == 0 && temp <= MAX_DDIV_REG)
485+ break;
486+ }
487+
488+ if (idx > MAX_DDIV_REG)
489+ return -EINVAL;
490+
491+ *ddiv1 = temp;
492+ *ddiv2 = idx;
493+ }
494+
495+ return 0;
496+}
497+
498+static int
499+lgm_clk_ddiv_set_rate(struct clk_hw *hw, unsigned long rate,
500+ unsigned long prate)
501+{
502+ struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
503+ u32 div, ddiv1, ddiv2;
504+ unsigned long flags;
505+
506+ div = DIV_ROUND_CLOSEST_ULL((u64)prate, rate);
507+
508+ spin_lock_irqsave(&ddiv->lock, flags);
509+ if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
510+ div = DIV_ROUND_CLOSEST_ULL((u64)div, 5);
511+ div = div * 2;
512+ }
513+
514+ if (div <= 0) {
515+ spin_unlock_irqrestore(&ddiv->lock, flags);
516+ return -EINVAL;
517+ }
518+
519+ if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2)) {
520+ spin_unlock_irqrestore(&ddiv->lock, flags);
521+ return -EINVAL;
522+ }
523+
524+ lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift0, ddiv->width0,
525+ ddiv1 - 1);
526+
527+ lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift1, ddiv->width1,
528+ ddiv2 - 1);
529+ spin_unlock_irqrestore(&ddiv->lock, flags);
530+
531+ return 0;
532+}
533+
534+static long
535+lgm_clk_ddiv_round_rate(struct clk_hw *hw, unsigned long rate,
536+ unsigned long *prate)
537+{
538+ struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
539+ u32 div, ddiv1, ddiv2;
540+ unsigned long flags;
541+ u64 rate64;
542+
543+ div = DIV_ROUND_CLOSEST_ULL((u64)*prate, rate);
544+
545+ /* if predivide bit is enabled, modify div by factor of 2.5 */
546+ spin_lock_irqsave(&ddiv->lock, flags);
547+ if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
548+ div = div * 2;
549+ div = DIV_ROUND_CLOSEST_ULL((u64)div, 5);
550+ }
551+
552+ if (div <= 0) {
553+ spin_unlock_irqrestore(&ddiv->lock, flags);
554+ return *prate;
555+ }
556+
557+ if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2) != 0) {
558+ if (lgm_clk_get_ddiv_val(div + 1, &ddiv1, &ddiv2) != 0) {
559+ spin_unlock_irqrestore(&ddiv->lock, flags);
560+ return -EINVAL;
561+ }
562+ }
563+
564+ rate64 = *prate;
565+ do_div(rate64, ddiv1);
566+ do_div(rate64, ddiv2);
567+
568+ /* if predivide bit is enabled, modify rounded rate by factor of 2.5 */
569+ if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
570+ rate64 = rate64 * 2;
571+ rate64 = DIV_ROUND_CLOSEST_ULL(rate64, 5);
572+ }
573+ spin_unlock_irqrestore(&ddiv->lock, flags);
574+
575+ return rate64;
576+}
577+
578+static const struct clk_ops lgm_clk_ddiv_ops = {
579+ .recalc_rate = lgm_clk_ddiv_recalc_rate,
580+ .enable = lgm_clk_ddiv_enable,
581+ .disable = lgm_clk_ddiv_disable,
582+ .set_rate = lgm_clk_ddiv_set_rate,
583+ .round_rate = lgm_clk_ddiv_round_rate,
584+};
585+
586+int lgm_clk_register_ddiv(struct lgm_clk_provider *ctx,
587+ const struct lgm_clk_ddiv_data *list,
588+ unsigned int nr_clk)
589+{
590+ struct device *dev = ctx->dev;
591+ struct clk_init_data init = {};
592+ struct lgm_clk_ddiv *ddiv;
593+ struct clk_hw *hw;
594+ unsigned int idx;
595+ int ret;
596+
597+ for (idx = 0; idx < nr_clk; idx++, list++) {
598+ ddiv = NULL;
599+ ddiv = devm_kzalloc(dev, sizeof(*ddiv), GFP_KERNEL);
600+ if (!ddiv)
601+ return -ENOMEM;
602+
603+ memset(&init, 0, sizeof(init));
604+ init.name = list->name;
605+ init.ops = &lgm_clk_ddiv_ops;
606+ init.flags = list->flags;
607+ init.parent_data = list->parent_data;
608+ init.num_parents = 1;
609+
610+ ddiv->membase = ctx->membase;
611+ ddiv->lock = ctx->lock;
612+ ddiv->reg = list->reg;
613+ ddiv->shift0 = list->shift0;
614+ ddiv->width0 = list->width0;
615+ ddiv->shift1 = list->shift1;
616+ ddiv->width1 = list->width1;
617+ ddiv->shift_gate = list->shift_gate;
618+ ddiv->width_gate = list->width_gate;
619+ ddiv->shift2 = list->ex_shift;
620+ ddiv->width2 = list->ex_width;
621+ ddiv->flags = list->div_flags;
622+ ddiv->mult = 2;
623+ ddiv->div = 5;
624+ ddiv->hw.init = &init;
625+
626+ hw = &ddiv->hw;
627+ ret = clk_hw_register(dev, hw);
628+ if (ret) {
629+ dev_err(dev, "register clk: %s failed!\n", list->name);
630+ return ret;
631+ }
632+ ctx->clk_data.hws[list->id] = hw;
633+ }
634+
635+ return 0;
636+}
drivers/clk/x86/clk-cgu.h+335−0
@@ -0,0 +1,335 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+/*
3+ * Copyright(c) 2020 Intel Corporation.
4+ * Zhu YiXin <yixin.zhu@intel.com>
5+ * Rahul Tanwar <rahul.tanwar@intel.com>
6+ */
7+
8+#ifndef __CLK_CGU_H
9+#define __CLK_CGU_H
10+
11+#include <linux/io.h>
12+
13+struct lgm_clk_mux {
14+ struct clk_hw hw;
15+ void __iomem *membase;
16+ unsigned int reg;
17+ u8 shift;
18+ u8 width;
19+ unsigned long flags;
20+ spinlock_t lock;
21+};
22+
23+struct lgm_clk_divider {
24+ struct clk_hw hw;
25+ void __iomem *membase;
26+ unsigned int reg;
27+ u8 shift;
28+ u8 width;
29+ u8 shift_gate;
30+ u8 width_gate;
31+ unsigned long flags;
32+ const struct clk_div_table *table;
33+ spinlock_t lock;
34+};
35+
36+struct lgm_clk_ddiv {
37+ struct clk_hw hw;
38+ void __iomem *membase;
39+ unsigned int reg;
40+ u8 shift0;
41+ u8 width0;
42+ u8 shift1;
43+ u8 width1;
44+ u8 shift2;
45+ u8 width2;
46+ u8 shift_gate;
47+ u8 width_gate;
48+ unsigned int mult;
49+ unsigned int div;
50+ unsigned long flags;
51+ spinlock_t lock;
52+};
53+
54+struct lgm_clk_gate {
55+ struct clk_hw hw;
56+ void __iomem *membase;
57+ unsigned int reg;
58+ u8 shift;
59+ unsigned long flags;
60+ spinlock_t lock;
61+};
62+
63+enum lgm_clk_type {
64+ CLK_TYPE_FIXED,
65+ CLK_TYPE_MUX,
66+ CLK_TYPE_DIVIDER,
67+ CLK_TYPE_FIXED_FACTOR,
68+ CLK_TYPE_GATE,
69+ CLK_TYPE_NONE,
70+};
71+
72+/**
73+ * struct lgm_clk_provider
74+ * @membase: IO mem base address for CGU.
75+ * @np: device node
76+ * @dev: device
77+ * @clk_data: array of hw clocks and clk number.
78+ */
79+struct lgm_clk_provider {
80+ void __iomem *membase;
81+ struct device_node *np;
82+ struct device *dev;
83+ struct clk_hw_onecell_data clk_data;
84+ spinlock_t lock;
85+};
86+
87+enum pll_type {
88+ TYPE_ROPLL,
89+ TYPE_LJPLL,
90+ TYPE_NONE,
91+};
92+
93+struct lgm_clk_pll {
94+ struct clk_hw hw;
95+ void __iomem *membase;
96+ unsigned int reg;
97+ unsigned long flags;
98+ enum pll_type type;
99+ spinlock_t lock;
100+};
101+
102+/**
103+ * struct lgm_pll_clk_data
104+ * @id: platform specific id of the clock.
105+ * @name: name of this pll clock.
106+ * @parent_data: parent clock data.
107+ * @num_parents: number of parents.
108+ * @flags: optional flags for basic clock.
109+ * @type: platform type of pll.
110+ * @reg: offset of the register.
111+ */
112+struct lgm_pll_clk_data {
113+ unsigned int id;
114+ const char *name;
115+ const struct clk_parent_data *parent_data;
116+ u8 num_parents;
117+ unsigned long flags;
118+ enum pll_type type;
119+ int reg;
120+};
121+
122+#define LGM_PLL(_id, _name, _pdata, _flags, \
123+ _reg, _type) \
124+ { \
125+ .id = _id, \
126+ .name = _name, \
127+ .parent_data = _pdata, \
128+ .num_parents = ARRAY_SIZE(_pdata), \
129+ .flags = _flags, \
130+ .reg = _reg, \
131+ .type = _type, \
132+ }
133+
134+struct lgm_clk_ddiv_data {
135+ unsigned int id;
136+ const char *name;
137+ const struct clk_parent_data *parent_data;
138+ u8 flags;
139+ unsigned long div_flags;
140+ unsigned int reg;
141+ u8 shift0;
142+ u8 width0;
143+ u8 shift1;
144+ u8 width1;
145+ u8 shift_gate;
146+ u8 width_gate;
147+ u8 ex_shift;
148+ u8 ex_width;
149+};
150+
151+#define LGM_DDIV(_id, _name, _pname, _flags, _reg, \
152+ _shft0, _wdth0, _shft1, _wdth1, \
153+ _shft_gate, _wdth_gate, _xshft, _df) \
154+ { \
155+ .id = _id, \
156+ .name = _name, \
157+ .parent_data = &(const struct clk_parent_data){ \
158+ .fw_name = _pname, \
159+ .name = _pname, \
160+ }, \
161+ .flags = _flags, \
162+ .reg = _reg, \
163+ .shift0 = _shft0, \
164+ .width0 = _wdth0, \
165+ .shift1 = _shft1, \
166+ .width1 = _wdth1, \
167+ .shift_gate = _shft_gate, \
168+ .width_gate = _wdth_gate, \
169+ .ex_shift = _xshft, \
170+ .ex_width = 1, \
171+ .div_flags = _df, \
172+ }
173+
174+struct lgm_clk_branch {
175+ unsigned int id;
176+ enum lgm_clk_type type;
177+ const char *name;
178+ const struct clk_parent_data *parent_data;
179+ u8 num_parents;
180+ unsigned long flags;
181+ unsigned int mux_off;
182+ u8 mux_shift;
183+ u8 mux_width;
184+ unsigned long mux_flags;
185+ unsigned int mux_val;
186+ unsigned int div_off;
187+ u8 div_shift;
188+ u8 div_width;
189+ u8 div_shift_gate;
190+ u8 div_width_gate;
191+ unsigned long div_flags;
192+ unsigned int div_val;
193+ const struct clk_div_table *div_table;
194+ unsigned int gate_off;
195+ u8 gate_shift;
196+ unsigned long gate_flags;
197+ unsigned int gate_val;
198+ unsigned int mult;
199+ unsigned int div;
200+};
201+
202+/* clock flags definition */
203+#define CLOCK_FLAG_VAL_INIT BIT(16)
204+#define MUX_CLK_SW BIT(17)
205+
206+#define LGM_MUX(_id, _name, _pdata, _f, _reg, \
207+ _shift, _width, _cf, _v) \
208+ { \
209+ .id = _id, \
210+ .type = CLK_TYPE_MUX, \
211+ .name = _name, \
212+ .parent_data = _pdata, \
213+ .num_parents = ARRAY_SIZE(_pdata), \
214+ .flags = _f, \
215+ .mux_off = _reg, \
216+ .mux_shift = _shift, \
217+ .mux_width = _width, \
218+ .mux_flags = _cf, \
219+ .mux_val = _v, \
220+ }
221+
222+#define LGM_DIV(_id, _name, _pname, _f, _reg, _shift, _width, \
223+ _shift_gate, _width_gate, _cf, _v, _dtable) \
224+ { \
225+ .id = _id, \
226+ .type = CLK_TYPE_DIVIDER, \
227+ .name = _name, \
228+ .parent_data = &(const struct clk_parent_data){ \
229+ .fw_name = _pname, \
230+ .name = _pname, \
231+ }, \
232+ .num_parents = 1, \
233+ .flags = _f, \
234+ .div_off = _reg, \
235+ .div_shift = _shift, \
236+ .div_width = _width, \
237+ .div_shift_gate = _shift_gate, \
238+ .div_width_gate = _width_gate, \
239+ .div_flags = _cf, \
240+ .div_val = _v, \
241+ .div_table = _dtable, \
242+ }
243+
244+#define LGM_GATE(_id, _name, _pname, _f, _reg, \
245+ _shift, _cf, _v) \
246+ { \
247+ .id = _id, \
248+ .type = CLK_TYPE_GATE, \
249+ .name = _name, \
250+ .parent_data = &(const struct clk_parent_data){ \
251+ .fw_name = _pname, \
252+ .name = _pname, \
253+ }, \
254+ .num_parents = !_pname ? 0 : 1, \
255+ .flags = _f, \
256+ .gate_off = _reg, \
257+ .gate_shift = _shift, \
258+ .gate_flags = _cf, \
259+ .gate_val = _v, \
260+ }
261+
262+#define LGM_FIXED(_id, _name, _pname, _f, _reg, \
263+ _shift, _width, _cf, _freq, _v) \
264+ { \
265+ .id = _id, \
266+ .type = CLK_TYPE_FIXED, \
267+ .name = _name, \
268+ .parent_data = &(const struct clk_parent_data){ \
269+ .fw_name = _pname, \
270+ .name = _pname, \
271+ }, \
272+ .num_parents = !_pname ? 0 : 1, \
273+ .flags = _f, \
274+ .div_off = _reg, \
275+ .div_shift = _shift, \
276+ .div_width = _width, \
277+ .div_flags = _cf, \
278+ .div_val = _v, \
279+ .mux_flags = _freq, \
280+ }
281+
282+#define LGM_FIXED_FACTOR(_id, _name, _pname, _f, _reg, \
283+ _shift, _width, _cf, _v, _m, _d) \
284+ { \
285+ .id = _id, \
286+ .type = CLK_TYPE_FIXED_FACTOR, \
287+ .name = _name, \
288+ .parent_data = &(const struct clk_parent_data){ \
289+ .fw_name = _pname, \
290+ .name = _pname, \
291+ }, \
292+ .num_parents = 1, \
293+ .flags = _f, \
294+ .div_off = _reg, \
295+ .div_shift = _shift, \
296+ .div_width = _width, \
297+ .div_flags = _cf, \
298+ .div_val = _v, \
299+ .mult = _m, \
300+ .div = _d, \
301+ }
302+
303+static inline void lgm_set_clk_val(void __iomem *membase, u32 reg,
304+ u8 shift, u8 width, u32 set_val)
305+{
306+ u32 mask = (GENMASK(width - 1, 0) << shift);
307+ u32 regval;
308+
309+ regval = readl(membase + reg);
310+ regval = (regval & ~mask) | ((set_val << shift) & mask);
311+ writel(regval, membase + reg);
312+}
313+
314+static inline u32 lgm_get_clk_val(void __iomem *membase, u32 reg,
315+ u8 shift, u8 width)
316+{
317+ u32 mask = (GENMASK(width - 1, 0) << shift);
318+ u32 val;
319+
320+ val = readl(membase + reg);
321+ val = (val & mask) >> shift;
322+
323+ return val;
324+}
325+
326+int lgm_clk_register_branches(struct lgm_clk_provider *ctx,
327+ const struct lgm_clk_branch *list,
328+ unsigned int nr_clk);
329+int lgm_clk_register_plls(struct lgm_clk_provider *ctx,
330+ const struct lgm_pll_clk_data *list,
331+ unsigned int nr_clk);
332+int lgm_clk_register_ddiv(struct lgm_clk_provider *ctx,
333+ const struct lgm_clk_ddiv_data *list,
334+ unsigned int nr_clk);
335+#endif /* __CLK_CGU_H */
drivers/clk/x86/clk-lgm.c+475−0
@@ -0,0 +1,475 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (C) 2020 Intel Corporation.
4+ * Zhu YiXin <yixin.zhu@intel.com>
5+ * Rahul Tanwar <rahul.tanwar@intel.com>
6+ */
7+#include <linux/clk-provider.h>
8+#include <linux/of.h>
9+#include <linux/platform_device.h>
10+#include <dt-bindings/clock/intel,lgm-clk.h>
11+#include "clk-cgu.h"
12+
13+#define PLL_DIV_WIDTH 4
14+#define PLL_DDIV_WIDTH 3
15+
16+/* Gate0 clock shift */
17+#define G_C55_SHIFT 7
18+#define G_QSPI_SHIFT 9
19+#define G_EIP197_SHIFT 11
20+#define G_VAULT130_SHIFT 12
21+#define G_TOE_SHIFT 13
22+#define G_SDXC_SHIFT 14
23+#define G_EMMC_SHIFT 15
24+#define G_SPIDBG_SHIFT 17
25+#define G_DMA3_SHIFT 28
26+
27+/* Gate1 clock shift */
28+#define G_DMA0_SHIFT 0
29+#define G_LEDC0_SHIFT 1
30+#define G_LEDC1_SHIFT 2
31+#define G_I2S0_SHIFT 3
32+#define G_I2S1_SHIFT 4
33+#define G_EBU_SHIFT 5
34+#define G_PWM_SHIFT 6
35+#define G_I2C0_SHIFT 7
36+#define G_I2C1_SHIFT 8
37+#define G_I2C2_SHIFT 9
38+#define G_I2C3_SHIFT 10
39+
40+#define G_SSC0_SHIFT 12
41+#define G_SSC1_SHIFT 13
42+#define G_SSC2_SHIFT 14
43+#define G_SSC3_SHIFT 15
44+
45+#define G_GPTC0_SHIFT 17
46+#define G_GPTC1_SHIFT 18
47+#define G_GPTC2_SHIFT 19
48+#define G_GPTC3_SHIFT 20
49+
50+#define G_ASC0_SHIFT 22
51+#define G_ASC1_SHIFT 23
52+#define G_ASC2_SHIFT 24
53+#define G_ASC3_SHIFT 25
54+
55+#define G_PCM0_SHIFT 27
56+#define G_PCM1_SHIFT 28
57+#define G_PCM2_SHIFT 29
58+
59+/* Gate2 clock shift */
60+#define G_PCIE10_SHIFT 1
61+#define G_PCIE11_SHIFT 2
62+#define G_PCIE30_SHIFT 3
63+#define G_PCIE31_SHIFT 4
64+#define G_PCIE20_SHIFT 5
65+#define G_PCIE21_SHIFT 6
66+#define G_PCIE40_SHIFT 7
67+#define G_PCIE41_SHIFT 8
68+
69+#define G_XPCS0_SHIFT 10
70+#define G_XPCS1_SHIFT 11
71+#define G_XPCS2_SHIFT 12
72+#define G_XPCS3_SHIFT 13
73+#define G_SATA0_SHIFT 14
74+#define G_SATA1_SHIFT 15
75+#define G_SATA2_SHIFT 16
76+#define G_SATA3_SHIFT 17
77+
78+/* Gate3 clock shift */
79+#define G_ARCEM4_SHIFT 0
80+#define G_IDMAR1_SHIFT 2
81+#define G_IDMAT0_SHIFT 3
82+#define G_IDMAT1_SHIFT 4
83+#define G_IDMAT2_SHIFT 5
84+
85+#define G_PPV4_SHIFT 8
86+#define G_GSWIPO_SHIFT 9
87+#define G_CQEM_SHIFT 10
88+#define G_XPCS5_SHIFT 14
89+#define G_USB1_SHIFT 25
90+#define G_USB2_SHIFT 26
91+
92+
93+/* Register definition */
94+#define CGU_PLL0CZ_CFG0 0x000
95+#define CGU_PLL0CM0_CFG0 0x020
96+#define CGU_PLL0CM1_CFG0 0x040
97+#define CGU_PLL0B_CFG0 0x060
98+#define CGU_PLL1_CFG0 0x080
99+#define CGU_PLL2_CFG0 0x0A0
100+#define CGU_PLLPP_CFG0 0x0C0
101+#define CGU_LJPLL3_CFG0 0x0E0
102+#define CGU_LJPLL4_CFG0 0x100
103+#define CGU_C55_PCMCR 0x18C
104+#define CGU_PCMCR 0x190
105+#define CGU_IF_CLK1 0x1A0
106+#define CGU_IF_CLK2 0x1A4
107+#define CGU_GATE0 0x300
108+#define CGU_GATE1 0x310
109+#define CGU_GATE2 0x320
110+#define CGU_GATE3 0x310
111+
112+#define PLL_DIV(x) ((x) + 0x04)
113+#define PLL_SSC(x) ((x) + 0x10)
114+
115+#define CLK_NR_CLKS (LGM_GCLK_USB2 + 1)
116+
117+/*
118+ * Below table defines the pair's of regval & effective dividers.
119+ * It's more efficient to provide an explicit table due to non-linear
120+ * relation between values.
121+ */
122+static const struct clk_div_table pll_div[] = {
123+ { .val = 0, .div = 1 },
124+ { .val = 1, .div = 2 },
125+ { .val = 2, .div = 3 },
126+ { .val = 3, .div = 4 },
127+ { .val = 4, .div = 5 },
128+ { .val = 5, .div = 6 },
129+ { .val = 6, .div = 8 },
130+ { .val = 7, .div = 10 },
131+ { .val = 8, .div = 12 },
132+ { .val = 9, .div = 16 },
133+ { .val = 10, .div = 20 },
134+ { .val = 11, .div = 24 },
135+ { .val = 12, .div = 32 },
136+ { .val = 13, .div = 40 },
137+ { .val = 14, .div = 48 },
138+ { .val = 15, .div = 64 },
139+ {}
140+};
141+
142+static const struct clk_div_table dcl_div[] = {
143+ { .val = 0, .div = 6 },
144+ { .val = 1, .div = 12 },
145+ { .val = 2, .div = 24 },
146+ { .val = 3, .div = 32 },
147+ { .val = 4, .div = 48 },
148+ { .val = 5, .div = 96 },
149+ {}
150+};
151+
152+static const struct clk_parent_data pll_p[] = {
153+ { .fw_name = "osc", .name = "osc" },
154+};
155+static const struct clk_parent_data pllcm_p[] = {
156+ { .fw_name = "cpu_cm", .name = "cpu_cm" },
157+};
158+static const struct clk_parent_data emmc_p[] = {
159+ { .fw_name = "emmc4", .name = "emmc4" },
160+ { .fw_name = "noc4", .name = "noc4" },
161+};
162+static const struct clk_parent_data sdxc_p[] = {
163+ { .fw_name = "sdxc3", .name = "sdxc3" },
164+ { .fw_name = "sdxc2", .name = "sdxc2" },
165+};
166+static const struct clk_parent_data pcm_p[] = {
167+ { .fw_name = "v_docsis", .name = "v_docsis" },
168+ { .fw_name = "dcl", .name = "dcl" },
169+};
170+static const struct clk_parent_data cbphy_p[] = {
171+ { .fw_name = "dd_serdes", .name = "dd_serdes" },
172+ { .fw_name = "dd_pcie", .name = "dd_pcie" },
173+};
174+
175+static const struct lgm_pll_clk_data lgm_pll_clks[] = {
176+ LGM_PLL(LGM_CLK_PLL0CZ, "pll0cz", pll_p, CLK_IGNORE_UNUSED,
177+ CGU_PLL0CZ_CFG0, TYPE_ROPLL),
178+ LGM_PLL(LGM_CLK_PLL0CM0, "pll0cm0", pllcm_p, CLK_IGNORE_UNUSED,
179+ CGU_PLL0CM0_CFG0, TYPE_ROPLL),
180+ LGM_PLL(LGM_CLK_PLL0CM1, "pll0cm1", pllcm_p, CLK_IGNORE_UNUSED,
181+ CGU_PLL0CM1_CFG0, TYPE_ROPLL),
182+ LGM_PLL(LGM_CLK_PLL0B, "pll0b", pll_p, CLK_IGNORE_UNUSED,
183+ CGU_PLL0B_CFG0, TYPE_ROPLL),
184+ LGM_PLL(LGM_CLK_PLL1, "pll1", pll_p, 0, CGU_PLL1_CFG0, TYPE_ROPLL),
185+ LGM_PLL(LGM_CLK_PLL2, "pll2", pll_p, CLK_IGNORE_UNUSED,
186+ CGU_PLL2_CFG0, TYPE_ROPLL),
187+ LGM_PLL(LGM_CLK_PLLPP, "pllpp", pll_p, 0, CGU_PLLPP_CFG0, TYPE_ROPLL),
188+ LGM_PLL(LGM_CLK_LJPLL3, "ljpll3", pll_p, 0, CGU_LJPLL3_CFG0, TYPE_LJPLL),
189+ LGM_PLL(LGM_CLK_LJPLL4, "ljpll4", pll_p, 0, CGU_LJPLL4_CFG0, TYPE_LJPLL),
190+};
191+
192+static const struct lgm_clk_branch lgm_branch_clks[] = {
193+ LGM_DIV(LGM_CLK_PP_HW, "pp_hw", "pllpp", 0, PLL_DIV(CGU_PLLPP_CFG0),
194+ 0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
195+ LGM_DIV(LGM_CLK_PP_UC, "pp_uc", "pllpp", 0, PLL_DIV(CGU_PLLPP_CFG0),
196+ 4, PLL_DIV_WIDTH, 25, 1, 0, 0, pll_div),
197+ LGM_DIV(LGM_CLK_PP_FXD, "pp_fxd", "pllpp", 0, PLL_DIV(CGU_PLLPP_CFG0),
198+ 8, PLL_DIV_WIDTH, 26, 1, 0, 0, pll_div),
199+ LGM_DIV(LGM_CLK_PP_TBM, "pp_tbm", "pllpp", 0, PLL_DIV(CGU_PLLPP_CFG0),
200+ 12, PLL_DIV_WIDTH, 27, 1, 0, 0, pll_div),
201+ LGM_DIV(LGM_CLK_DDR, "ddr", "pll2", CLK_IGNORE_UNUSED,
202+ PLL_DIV(CGU_PLL2_CFG0), 0, PLL_DIV_WIDTH, 24, 1, 0, 0,
203+ pll_div),
204+ LGM_DIV(LGM_CLK_CM, "cpu_cm", "pll0cz", 0, PLL_DIV(CGU_PLL0CZ_CFG0),
205+ 0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
206+
207+ LGM_DIV(LGM_CLK_IC, "cpu_ic", "pll0cz", CLK_IGNORE_UNUSED,
208+ PLL_DIV(CGU_PLL0CZ_CFG0), 4, PLL_DIV_WIDTH, 25,
209+ 1, 0, 0, pll_div),
210+
211+ LGM_DIV(LGM_CLK_SDXC3, "sdxc3", "pll0cz", 0, PLL_DIV(CGU_PLL0CZ_CFG0),
212+ 8, PLL_DIV_WIDTH, 26, 1, 0, 0, pll_div),
213+
214+ LGM_DIV(LGM_CLK_CPU0, "cm0", "pll0cm0",
215+ CLK_IGNORE_UNUSED, PLL_DIV(CGU_PLL0CM0_CFG0),
216+ 0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
217+ LGM_DIV(LGM_CLK_CPU1, "cm1", "pll0cm1",
218+ CLK_IGNORE_UNUSED, PLL_DIV(CGU_PLL0CM1_CFG0),
219+ 0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
220+
221+ /*
222+ * Marking ngi_clk (next generation interconnect) and noc_clk
223+ * (network on chip peripheral clk) as critical clocks because
224+ * these are shared parent clock sources for many different
225+ * peripherals.
226+ */
227+ LGM_DIV(LGM_CLK_NGI, "ngi", "pll0b",
228+ (CLK_IGNORE_UNUSED|CLK_IS_CRITICAL), PLL_DIV(CGU_PLL0B_CFG0),
229+ 0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
230+ LGM_DIV(LGM_CLK_NOC4, "noc4", "pll0b",
231+ (CLK_IGNORE_UNUSED|CLK_IS_CRITICAL), PLL_DIV(CGU_PLL0B_CFG0),
232+ 4, PLL_DIV_WIDTH, 25, 1, 0, 0, pll_div),
233+ LGM_DIV(LGM_CLK_SW, "switch", "pll0b", 0, PLL_DIV(CGU_PLL0B_CFG0),
234+ 8, PLL_DIV_WIDTH, 26, 1, 0, 0, pll_div),
235+ LGM_DIV(LGM_CLK_QSPI, "qspi", "pll0b", 0, PLL_DIV(CGU_PLL0B_CFG0),
236+ 12, PLL_DIV_WIDTH, 27, 1, 0, 0, pll_div),
237+ LGM_DIV(LGM_CLK_CT, "v_ct", "pll1", 0, PLL_DIV(CGU_PLL1_CFG0),
238+ 0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
239+ LGM_DIV(LGM_CLK_DSP, "v_dsp", "pll1", 0, PLL_DIV(CGU_PLL1_CFG0),
240+ 8, PLL_DIV_WIDTH, 26, 1, 0, 0, pll_div),
241+ LGM_DIV(LGM_CLK_VIF, "v_ifclk", "pll1", 0, PLL_DIV(CGU_PLL1_CFG0),
242+ 12, PLL_DIV_WIDTH, 27, 1, 0, 0, pll_div),
243+
244+ LGM_FIXED_FACTOR(LGM_CLK_EMMC4, "emmc4", "sdxc3", 0, 0,
245+ 0, 0, 0, 0, 1, 4),
246+ LGM_FIXED_FACTOR(LGM_CLK_SDXC2, "sdxc2", "noc4", 0, 0,
247+ 0, 0, 0, 0, 1, 4),
248+ LGM_MUX(LGM_CLK_EMMC, "emmc", emmc_p, 0, CGU_IF_CLK1,
249+ 0, 1, CLK_MUX_ROUND_CLOSEST, 0),
250+ LGM_MUX(LGM_CLK_SDXC, "sdxc", sdxc_p, 0, CGU_IF_CLK1,
251+ 1, 1, CLK_MUX_ROUND_CLOSEST, 0),
252+ LGM_FIXED(LGM_CLK_OSC, "osc", NULL, 0, 0, 0, 0, 0, 40000000, 0),
253+ LGM_FIXED(LGM_CLK_SLIC, "slic", NULL, 0, CGU_IF_CLK1,
254+ 8, 2, CLOCK_FLAG_VAL_INIT, 8192000, 2),
255+ LGM_FIXED(LGM_CLK_DOCSIS, "v_docsis", NULL, 0, 0, 0, 0, 0, 16000000, 0),
256+ LGM_DIV(LGM_CLK_DCL, "dcl", "v_ifclk", 0, CGU_PCMCR,
257+ 25, 3, 0, 0, 0, 0, dcl_div),
258+ LGM_MUX(LGM_CLK_PCM, "pcm", pcm_p, 0, CGU_C55_PCMCR,
259+ 0, 1, CLK_MUX_ROUND_CLOSEST, 0),
260+ LGM_FIXED_FACTOR(LGM_CLK_DDR_PHY, "ddr_phy", "ddr",
261+ CLK_IGNORE_UNUSED, 0,
262+ 0, 0, 0, 0, 2, 1),
263+ LGM_FIXED_FACTOR(LGM_CLK_PONDEF, "pondef", "dd_pool",
264+ CLK_SET_RATE_PARENT, 0, 0, 0, 0, 0, 1, 2),
265+ LGM_MUX(LGM_CLK_CBPHY0, "cbphy0", cbphy_p, 0, 0,
266+ 0, 0, MUX_CLK_SW | CLK_MUX_ROUND_CLOSEST, 0),
267+ LGM_MUX(LGM_CLK_CBPHY1, "cbphy1", cbphy_p, 0, 0,
268+ 0, 0, MUX_CLK_SW | CLK_MUX_ROUND_CLOSEST, 0),
269+ LGM_MUX(LGM_CLK_CBPHY2, "cbphy2", cbphy_p, 0, 0,
270+ 0, 0, MUX_CLK_SW | CLK_MUX_ROUND_CLOSEST, 0),
271+ LGM_MUX(LGM_CLK_CBPHY3, "cbphy3", cbphy_p, 0, 0,
272+ 0, 0, MUX_CLK_SW | CLK_MUX_ROUND_CLOSEST, 0),
273+
274+ LGM_GATE(LGM_GCLK_C55, "g_c55", NULL, 0, CGU_GATE0,
275+ G_C55_SHIFT, 0, 0),
276+ LGM_GATE(LGM_GCLK_QSPI, "g_qspi", "qspi", 0, CGU_GATE0,
277+ G_QSPI_SHIFT, 0, 0),
278+ LGM_GATE(LGM_GCLK_EIP197, "g_eip197", NULL, 0, CGU_GATE0,
279+ G_EIP197_SHIFT, 0, 0),
280+ LGM_GATE(LGM_GCLK_VAULT, "g_vault130", NULL, 0, CGU_GATE0,
281+ G_VAULT130_SHIFT, 0, 0),
282+ LGM_GATE(LGM_GCLK_TOE, "g_toe", NULL, 0, CGU_GATE0,
283+ G_TOE_SHIFT, 0, 0),
284+ LGM_GATE(LGM_GCLK_SDXC, "g_sdxc", "sdxc", 0, CGU_GATE0,
285+ G_SDXC_SHIFT, 0, 0),
286+ LGM_GATE(LGM_GCLK_EMMC, "g_emmc", "emmc", 0, CGU_GATE0,
287+ G_EMMC_SHIFT, 0, 0),
288+ LGM_GATE(LGM_GCLK_SPI_DBG, "g_spidbg", NULL, 0, CGU_GATE0,
289+ G_SPIDBG_SHIFT, 0, 0),
290+ LGM_GATE(LGM_GCLK_DMA3, "g_dma3", NULL, 0, CGU_GATE0,
291+ G_DMA3_SHIFT, 0, 0),
292+
293+ LGM_GATE(LGM_GCLK_DMA0, "g_dma0", NULL, 0, CGU_GATE1,
294+ G_DMA0_SHIFT, 0, 0),
295+ LGM_GATE(LGM_GCLK_LEDC0, "g_ledc0", NULL, 0, CGU_GATE1,
296+ G_LEDC0_SHIFT, 0, 0),
297+ LGM_GATE(LGM_GCLK_LEDC1, "g_ledc1", NULL, 0, CGU_GATE1,
298+ G_LEDC1_SHIFT, 0, 0),
299+ LGM_GATE(LGM_GCLK_I2S0, "g_i2s0", NULL, 0, CGU_GATE1,
300+ G_I2S0_SHIFT, 0, 0),
301+ LGM_GATE(LGM_GCLK_I2S1, "g_i2s1", NULL, 0, CGU_GATE1,
302+ G_I2S1_SHIFT, 0, 0),
303+ LGM_GATE(LGM_GCLK_EBU, "g_ebu", NULL, 0, CGU_GATE1,
304+ G_EBU_SHIFT, 0, 0),
305+ LGM_GATE(LGM_GCLK_PWM, "g_pwm", NULL, 0, CGU_GATE1,
306+ G_PWM_SHIFT, 0, 0),
307+ LGM_GATE(LGM_GCLK_I2C0, "g_i2c0", NULL, 0, CGU_GATE1,
308+ G_I2C0_SHIFT, 0, 0),
309+ LGM_GATE(LGM_GCLK_I2C1, "g_i2c1", NULL, 0, CGU_GATE1,
310+ G_I2C1_SHIFT, 0, 0),
311+ LGM_GATE(LGM_GCLK_I2C2, "g_i2c2", NULL, 0, CGU_GATE1,
312+ G_I2C2_SHIFT, 0, 0),
313+ LGM_GATE(LGM_GCLK_I2C3, "g_i2c3", NULL, 0, CGU_GATE1,
314+ G_I2C3_SHIFT, 0, 0),
315+ LGM_GATE(LGM_GCLK_SSC0, "g_ssc0", "noc4", 0, CGU_GATE1,
316+ G_SSC0_SHIFT, 0, 0),
317+ LGM_GATE(LGM_GCLK_SSC1, "g_ssc1", "noc4", 0, CGU_GATE1,
318+ G_SSC1_SHIFT, 0, 0),
319+ LGM_GATE(LGM_GCLK_SSC2, "g_ssc2", "noc4", 0, CGU_GATE1,
320+ G_SSC2_SHIFT, 0, 0),
321+ LGM_GATE(LGM_GCLK_SSC3, "g_ssc3", "noc4", 0, CGU_GATE1,
322+ G_SSC3_SHIFT, 0, 0),
323+ LGM_GATE(LGM_GCLK_GPTC0, "g_gptc0", "noc4", 0, CGU_GATE1,
324+ G_GPTC0_SHIFT, 0, 0),
325+ LGM_GATE(LGM_GCLK_GPTC1, "g_gptc1", "noc4", 0, CGU_GATE1,
326+ G_GPTC1_SHIFT, 0, 0),
327+ LGM_GATE(LGM_GCLK_GPTC2, "g_gptc2", "noc4", 0, CGU_GATE1,
328+ G_GPTC2_SHIFT, 0, 0),
329+ LGM_GATE(LGM_GCLK_GPTC3, "g_gptc3", "osc", 0, CGU_GATE1,
330+ G_GPTC3_SHIFT, 0, 0),
331+ LGM_GATE(LGM_GCLK_ASC0, "g_asc0", "noc4", 0, CGU_GATE1,
332+ G_ASC0_SHIFT, 0, 0),
333+ LGM_GATE(LGM_GCLK_ASC1, "g_asc1", "noc4", 0, CGU_GATE1,
334+ G_ASC1_SHIFT, 0, 0),
335+ LGM_GATE(LGM_GCLK_ASC2, "g_asc2", "noc4", 0, CGU_GATE1,
336+ G_ASC2_SHIFT, 0, 0),
337+ LGM_GATE(LGM_GCLK_ASC3, "g_asc3", "osc", 0, CGU_GATE1,
338+ G_ASC3_SHIFT, 0, 0),
339+ LGM_GATE(LGM_GCLK_PCM0, "g_pcm0", NULL, 0, CGU_GATE1,
340+ G_PCM0_SHIFT, 0, 0),
341+ LGM_GATE(LGM_GCLK_PCM1, "g_pcm1", NULL, 0, CGU_GATE1,
342+ G_PCM1_SHIFT, 0, 0),
343+ LGM_GATE(LGM_GCLK_PCM2, "g_pcm2", NULL, 0, CGU_GATE1,
344+ G_PCM2_SHIFT, 0, 0),
345+
346+ LGM_GATE(LGM_GCLK_PCIE10, "g_pcie10", NULL, 0, CGU_GATE2,
347+ G_PCIE10_SHIFT, 0, 0),
348+ LGM_GATE(LGM_GCLK_PCIE11, "g_pcie11", NULL, 0, CGU_GATE2,
349+ G_PCIE11_SHIFT, 0, 0),
350+ LGM_GATE(LGM_GCLK_PCIE30, "g_pcie30", NULL, 0, CGU_GATE2,
351+ G_PCIE30_SHIFT, 0, 0),
352+ LGM_GATE(LGM_GCLK_PCIE31, "g_pcie31", NULL, 0, CGU_GATE2,
353+ G_PCIE31_SHIFT, 0, 0),
354+ LGM_GATE(LGM_GCLK_PCIE20, "g_pcie20", NULL, 0, CGU_GATE2,
355+ G_PCIE20_SHIFT, 0, 0),
356+ LGM_GATE(LGM_GCLK_PCIE21, "g_pcie21", NULL, 0, CGU_GATE2,
357+ G_PCIE21_SHIFT, 0, 0),
358+ LGM_GATE(LGM_GCLK_PCIE40, "g_pcie40", NULL, 0, CGU_GATE2,
359+ G_PCIE40_SHIFT, 0, 0),
360+ LGM_GATE(LGM_GCLK_PCIE41, "g_pcie41", NULL, 0, CGU_GATE2,
361+ G_PCIE41_SHIFT, 0, 0),
362+ LGM_GATE(LGM_GCLK_XPCS0, "g_xpcs0", NULL, 0, CGU_GATE2,
363+ G_XPCS0_SHIFT, 0, 0),
364+ LGM_GATE(LGM_GCLK_XPCS1, "g_xpcs1", NULL, 0, CGU_GATE2,
365+ G_XPCS1_SHIFT, 0, 0),
366+ LGM_GATE(LGM_GCLK_XPCS2, "g_xpcs2", NULL, 0, CGU_GATE2,
367+ G_XPCS2_SHIFT, 0, 0),
368+ LGM_GATE(LGM_GCLK_XPCS3, "g_xpcs3", NULL, 0, CGU_GATE2,
369+ G_XPCS3_SHIFT, 0, 0),
370+ LGM_GATE(LGM_GCLK_SATA0, "g_sata0", NULL, 0, CGU_GATE2,
371+ G_SATA0_SHIFT, 0, 0),
372+ LGM_GATE(LGM_GCLK_SATA1, "g_sata1", NULL, 0, CGU_GATE2,
373+ G_SATA1_SHIFT, 0, 0),
374+ LGM_GATE(LGM_GCLK_SATA2, "g_sata2", NULL, 0, CGU_GATE2,
375+ G_SATA2_SHIFT, 0, 0),
376+ LGM_GATE(LGM_GCLK_SATA3, "g_sata3", NULL, 0, CGU_GATE2,
377+ G_SATA3_SHIFT, 0, 0),
378+
379+ LGM_GATE(LGM_GCLK_ARCEM4, "g_arcem4", NULL, 0, CGU_GATE3,
380+ G_ARCEM4_SHIFT, 0, 0),
381+ LGM_GATE(LGM_GCLK_IDMAR1, "g_idmar1", NULL, 0, CGU_GATE3,
382+ G_IDMAR1_SHIFT, 0, 0),
383+ LGM_GATE(LGM_GCLK_IDMAT0, "g_idmat0", NULL, 0, CGU_GATE3,
384+ G_IDMAT0_SHIFT, 0, 0),
385+ LGM_GATE(LGM_GCLK_IDMAT1, "g_idmat1", NULL, 0, CGU_GATE3,
386+ G_IDMAT1_SHIFT, 0, 0),
387+ LGM_GATE(LGM_GCLK_IDMAT2, "g_idmat2", NULL, 0, CGU_GATE3,
388+ G_IDMAT2_SHIFT, 0, 0),
389+ LGM_GATE(LGM_GCLK_PPV4, "g_ppv4", NULL, 0, CGU_GATE3,
390+ G_PPV4_SHIFT, 0, 0),
391+ LGM_GATE(LGM_GCLK_GSWIPO, "g_gswipo", "switch", 0, CGU_GATE3,
392+ G_GSWIPO_SHIFT, 0, 0),
393+ LGM_GATE(LGM_GCLK_CQEM, "g_cqem", "switch", 0, CGU_GATE3,
394+ G_CQEM_SHIFT, 0, 0),
395+ LGM_GATE(LGM_GCLK_XPCS5, "g_xpcs5", NULL, 0, CGU_GATE3,
396+ G_XPCS5_SHIFT, 0, 0),
397+ LGM_GATE(LGM_GCLK_USB1, "g_usb1", NULL, 0, CGU_GATE3,
398+ G_USB1_SHIFT, 0, 0),
399+ LGM_GATE(LGM_GCLK_USB2, "g_usb2", NULL, 0, CGU_GATE3,
400+ G_USB2_SHIFT, 0, 0),
401+};
402+
403+
404+static const struct lgm_clk_ddiv_data lgm_ddiv_clks[] = {
405+ LGM_DDIV(LGM_CLK_CML, "dd_cml", "ljpll3", 0,
406+ PLL_DIV(CGU_LJPLL3_CFG0), 0, PLL_DDIV_WIDTH,
407+ 3, PLL_DDIV_WIDTH, 24, 1, 29, 0),
408+ LGM_DDIV(LGM_CLK_SERDES, "dd_serdes", "ljpll3", 0,
409+ PLL_DIV(CGU_LJPLL3_CFG0), 6, PLL_DDIV_WIDTH,
410+ 9, PLL_DDIV_WIDTH, 25, 1, 28, 0),
411+ LGM_DDIV(LGM_CLK_POOL, "dd_pool", "ljpll3", 0,
412+ PLL_DIV(CGU_LJPLL3_CFG0), 12, PLL_DDIV_WIDTH,
413+ 15, PLL_DDIV_WIDTH, 26, 1, 28, 0),
414+ LGM_DDIV(LGM_CLK_PTP, "dd_ptp", "ljpll3", 0,
415+ PLL_DIV(CGU_LJPLL3_CFG0), 18, PLL_DDIV_WIDTH,
416+ 21, PLL_DDIV_WIDTH, 27, 1, 28, 0),
417+ LGM_DDIV(LGM_CLK_PCIE, "dd_pcie", "ljpll4", 0,
418+ PLL_DIV(CGU_LJPLL4_CFG0), 0, PLL_DDIV_WIDTH,
419+ 3, PLL_DDIV_WIDTH, 24, 1, 29, 0),
420+};
421+
422+static int lgm_cgu_probe(struct platform_device *pdev)
423+{
424+ struct lgm_clk_provider *ctx;
425+ struct device *dev = &pdev->dev;
426+ struct device_node *np = dev->of_node;
427+ int ret;
428+
429+ ctx = devm_kzalloc(dev, struct_size(ctx, clk_data.hws, CLK_NR_CLKS),
430+ GFP_KERNEL);
431+ if (!ctx)
432+ return -ENOMEM;
433+
434+ ctx->clk_data.num = CLK_NR_CLKS;
435+
436+ ctx->membase = devm_platform_ioremap_resource(pdev, 0);
437+ if (IS_ERR(ctx->membase))
438+ return PTR_ERR(ctx->membase);
439+
440+ ctx->np = np;
441+ ctx->dev = dev;
442+ spin_lock_init(&ctx->lock);
443+
444+ ret = lgm_clk_register_plls(ctx, lgm_pll_clks,
445+ ARRAY_SIZE(lgm_pll_clks));
446+ if (ret)
447+ return ret;
448+
449+ ret = lgm_clk_register_branches(ctx, lgm_branch_clks,
450+ ARRAY_SIZE(lgm_branch_clks));
451+ if (ret)
452+ return ret;
453+
454+ ret = lgm_clk_register_ddiv(ctx, lgm_ddiv_clks,
455+ ARRAY_SIZE(lgm_ddiv_clks));
456+ if (ret)
457+ return ret;
458+
459+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
460+ &ctx->clk_data);
461+}
462+
463+static const struct of_device_id of_lgm_cgu_match[] = {
464+ { .compatible = "intel,cgu-lgm" },
465+ {}
466+};
467+
468+static struct platform_driver lgm_cgu_driver = {
469+ .probe = lgm_cgu_probe,
470+ .driver = {
471+ .name = "cgu-lgm",
472+ .of_match_table = of_lgm_cgu_match,
473+ },
474+};
475+builtin_platform_driver(lgm_cgu_driver);
drivers/clk/zynqmp/clk-zynqmp.h+1−0
@@ -30,6 +30,7 @@ struct clock_topology { · 29 unmodified lines
3030 u32 type;
3131 u32 flag;
3232 u32 type_flag;
33+ u8 custom_type_flag;
3334 };
3435
3536 struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id,
drivers/clk/zynqmp/clkc.c+18−6
@@ -84,6 +84,7 @@ struct name_resp { · 83 unmodified lines
8484
8585 struct topology_resp {
8686 #define CLK_TOPOLOGY_TYPE GENMASK(3, 0)
87+#define CLK_TOPOLOGY_CUSTOM_TYPE_FLAGS GENMASK(7, 4)
8788 #define CLK_TOPOLOGY_FLAGS GENMASK(23, 8)
8889 #define CLK_TOPOLOGY_TYPE_FLAGS GENMASK(31, 24)
8990 u32 topology[CLK_GET_TOPOLOGY_RESP_WORDS];
@@ -395,6 +396,9 @@ static int __zynqmp_clock_get_topology(struct clock_topology *topology, · 305 unmodified lines
395396 topology[*nnodes].type_flag =
396397 FIELD_GET(CLK_TOPOLOGY_TYPE_FLAGS,
397398 response->topology[i]);
399+ topology[*nnodes].custom_type_flag =
400+ FIELD_GET(CLK_TOPOLOGY_CUSTOM_TYPE_FLAGS,
401+ response->topology[i]);
398402 (*nnodes)++;
399403 }
400404
@@ -557,7 +561,7 @@ static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name, · 156 unmodified lines
557561 {
558562 int j;
559563 u32 num_nodes, clk_dev_id;
560− char *clk_out = NULL;
564+ char *clk_out[MAX_NODES];
561565 struct clock_topology *nodes;
562566 struct clk_hw *hw = NULL;
563567
@@ -571,16 +575,16 @@ static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name, · 7 unmodified lines
571575 * Intermediate clock names are postfixed with type of clock.
572576 */
573577 if (j != (num_nodes - 1)) {
574− clk_out = kasprintf(GFP_KERNEL, "%s%s", clk_name,
578+ clk_out[j] = kasprintf(GFP_KERNEL, "%s%s", clk_name,
575579 clk_type_postfix[nodes[j].type]);
576580 } else {
577− clk_out = kasprintf(GFP_KERNEL, "%s", clk_name);
581+ clk_out[j] = kasprintf(GFP_KERNEL, "%s", clk_name);
578582 }
579583
580584 if (!clk_topology[nodes[j].type])
581585 continue;
582586
583− hw = (*clk_topology[nodes[j].type])(clk_out, clk_dev_id,
587+ hw = (*clk_topology[nodes[j].type])(clk_out[j], clk_dev_id,
584588 parent_names,
585589 num_parents,
586590 &nodes[j]);
@@ -589,9 +593,12 @@ static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name, · 2 unmodified lines
589593 __func__, clk_dev_id, clk_name,
590594 PTR_ERR(hw));
591595
592− parent_names[0] = clk_out;
596+ parent_names[0] = clk_out[j];
593597 }
594− kfree(clk_out);
598+
599+ for (j = 0; j < num_nodes; j++)
600+ kfree(clk_out[j]);
601+
595602 return hw;
596603 }
597604
@@ -662,6 +669,11 @@ static void zynqmp_get_clock_info(void) · 64 unmodified lines
662669 continue;
663670
664671 clock[i].valid = FIELD_GET(CLK_ATTR_VALID, attr.attr[0]);
672+ /* skip query for Invalid clock */
673+ ret = zynqmp_is_valid_clock(i);
674+ if (ret != CLK_ATTR_VALID)
675+ continue;
676+
665677 clock[i].type = FIELD_GET(CLK_ATTR_TYPE, attr.attr[0]) ?
666678 CLK_TYPE_EXTERNAL : CLK_TYPE_OUTPUT;
667679
drivers/clk/zynqmp/divider.c+19−8
@@ -25,7 +25,8 @@ · 24 unmodified lines
2525 #define to_zynqmp_clk_divider(_hw) \
2626 container_of(_hw, struct zynqmp_clk_divider, hw)
2727
28−#define CLK_FRAC BIT(13) /* has a fractional parent */
28+#define CLK_FRAC BIT(13) /* has a fractional parent */
29+#define CUSTOM_FLAG_CLK_FRAC BIT(0) /* has a fractional parent in custom type flag */
2930
3031 /**
3132 * struct zynqmp_clk_divider - adjustable divider clock
@@ -110,23 +111,30 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw, · 78 unmodified lines
110111
111112 static void zynqmp_get_divider2_val(struct clk_hw *hw,
112113 unsigned long rate,
113− unsigned long parent_rate,
114114 struct zynqmp_clk_divider *divider,
115115 int *bestdiv)
116116 {
117117 int div1;
118118 int div2;
119119 long error = LONG_MAX;
120− struct clk_hw *parent_hw = clk_hw_get_parent(hw);
121− struct zynqmp_clk_divider *pdivider = to_zynqmp_clk_divider(parent_hw);
120+ unsigned long div1_prate;
121+ struct clk_hw *div1_parent_hw;
122+ struct clk_hw *div2_parent_hw = clk_hw_get_parent(hw);
123+ struct zynqmp_clk_divider *pdivider =
124+ to_zynqmp_clk_divider(div2_parent_hw);
122125
123126 if (!pdivider)
124127 return;
125128
129+ div1_parent_hw = clk_hw_get_parent(div2_parent_hw);
130+ if (!div1_parent_hw)
131+ return;
132+
133+ div1_prate = clk_hw_get_rate(div1_parent_hw);
126134 *bestdiv = 1;
127135 for (div1 = 1; div1 <= pdivider->max_div;) {
128136 for (div2 = 1; div2 <= divider->max_div;) {
129− long new_error = ((parent_rate / div1) / div2) - rate;
137+ long new_error = ((div1_prate / div1) / div2) - rate;
130138
131139 if (abs(new_error) < abs(error)) {
132140 *bestdiv = div2;
@@ -190,11 +198,13 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw, · 57 unmodified lines
190198 */
191199 if (div_type == TYPE_DIV2 &&
192200 (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
193− zynqmp_get_divider2_val(hw, rate, *prate, divider, &bestdiv);
201+ zynqmp_get_divider2_val(hw, rate, divider, &bestdiv);
194202 }
195203
196204 if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && divider->is_frac)
197205 bestdiv = rate % *prate ? 1 : bestdiv;
206+
207+ bestdiv = min_t(u32, bestdiv, divider->max_div);
198208 *prate = rate * bestdiv;
199209
200210 return rate;
@@ -253,7 +263,7 @@ static const struct clk_ops zynqmp_clk_divider_ops = { · 52 unmodified lines
253263 * Return: Maximum divisor of a clock if query data is successful
254264 * U16_MAX in case of query data is not success
255265 */
256−u32 zynqmp_clk_get_max_divisor(u32 clk_id, u32 type)
266+static u32 zynqmp_clk_get_max_divisor(u32 clk_id, u32 type)
257267 {
258268 struct zynqmp_pm_query_data qdata = {0};
259269 u32 ret_payload[PAYLOAD_ARG_CNT];
@@ -307,7 +317,8 @@ struct clk_hw *zynqmp_clk_register_divider(const char *name, · 47 unmodified lines
307317 init.num_parents = 1;
308318
309319 /* struct clk_divider assignments */
310− div->is_frac = !!(nodes->flag & CLK_FRAC);
320+ div->is_frac = !!((nodes->flag & CLK_FRAC) |
321+ (nodes->custom_type_flag & CUSTOM_FLAG_CLK_FRAC));
311322 div->flags = nodes->type_flag;
312323 div->hw.init = &init;
313324 div->clk_id = clk_id;
drivers/i2c/busses/i2c-s3c2410.c+1−2
@@ -435,8 +435,7 @@ static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat) · 434 unmodified lines
435435 * fall through to the write state, as we will need to
436436 * send a byte as well
437437 */
438− /* Fall through */
439−
438+ fallthrough;
440439 case STATE_WRITE:
441440 /*
442441 * we are writing data to the device... check for the
drivers/mmc/host/Kconfig+1−1
@@ -436,7 +436,7 @@ config MMC_MESON_MX_SDIO · 435 unmodified lines
436436 tristate "Amlogic Meson6/Meson8/Meson8b SD/MMC Host Controller support"
437437 depends on ARCH_MESON || COMPILE_TEST
438438 depends on COMMON_CLK
439− depends on OF
439+ depends on OF_ADDRESS
440440 help
441441 This selects support for the SD/MMC Host Controller on
442442 Amlogic Meson6, Meson8 and Meson8b SoCs.
include/dt-bindings/clock/agilex-clock.h+70−0
@@ -0,0 +1,70 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+/*
3+ * Copyright (C) 2019, Intel Corporation
4+ */
5+
6+#ifndef __AGILEX_CLOCK_H
7+#define __AGILEX_CLOCK_H
8+
9+/* fixed rate clocks */
10+#define AGILEX_OSC1 0
11+#define AGILEX_CB_INTOSC_HS_DIV2_CLK 1
12+#define AGILEX_CB_INTOSC_LS_CLK 2
13+#define AGILEX_L4_SYS_FREE_CLK 3
14+#define AGILEX_F2S_FREE_CLK 4
15+
16+/* PLL clocks */
17+#define AGILEX_MAIN_PLL_CLK 5
18+#define AGILEX_MAIN_PLL_C0_CLK 6
19+#define AGILEX_MAIN_PLL_C1_CLK 7
20+#define AGILEX_MAIN_PLL_C2_CLK 8
21+#define AGILEX_MAIN_PLL_C3_CLK 9
22+#define AGILEX_PERIPH_PLL_CLK 10
23+#define AGILEX_PERIPH_PLL_C0_CLK 11
24+#define AGILEX_PERIPH_PLL_C1_CLK 12
25+#define AGILEX_PERIPH_PLL_C2_CLK 13
26+#define AGILEX_PERIPH_PLL_C3_CLK 14
27+#define AGILEX_MPU_FREE_CLK 15
28+#define AGILEX_MPU_CCU_CLK 16
29+#define AGILEX_BOOT_CLK 17
30+
31+/* fixed factor clocks */
32+#define AGILEX_L3_MAIN_FREE_CLK 18
33+#define AGILEX_NOC_FREE_CLK 19
34+#define AGILEX_S2F_USR0_CLK 20
35+#define AGILEX_NOC_CLK 21
36+#define AGILEX_EMAC_A_FREE_CLK 22
37+#define AGILEX_EMAC_B_FREE_CLK 23
38+#define AGILEX_EMAC_PTP_FREE_CLK 24
39+#define AGILEX_GPIO_DB_FREE_CLK 25
40+#define AGILEX_SDMMC_FREE_CLK 26
41+#define AGILEX_S2F_USER0_FREE_CLK 27
42+#define AGILEX_S2F_USER1_FREE_CLK 28
43+#define AGILEX_PSI_REF_FREE_CLK 29
44+
45+/* Gate clocks */
46+#define AGILEX_MPU_CLK 30
47+#define AGILEX_MPU_L2RAM_CLK 31
48+#define AGILEX_MPU_PERIPH_CLK 32
49+#define AGILEX_L4_MAIN_CLK 33
50+#define AGILEX_L4_MP_CLK 34
51+#define AGILEX_L4_SP_CLK 35
52+#define AGILEX_CS_AT_CLK 36
53+#define AGILEX_CS_TRACE_CLK 37
54+#define AGILEX_CS_PDBG_CLK 38
55+#define AGILEX_CS_TIMER_CLK 39
56+#define AGILEX_S2F_USER0_CLK 40
57+#define AGILEX_EMAC0_CLK 41
58+#define AGILEX_EMAC1_CLK 43
59+#define AGILEX_EMAC2_CLK 44
60+#define AGILEX_EMAC_PTP_CLK 45
61+#define AGILEX_GPIO_DB_CLK 46
62+#define AGILEX_NAND_CLK 47
63+#define AGILEX_PSI_REF_CLK 48
64+#define AGILEX_S2F_USER1_CLK 49
65+#define AGILEX_SDMMC_CLK 50
66+#define AGILEX_SPI_M_CLK 51
67+#define AGILEX_USB_CLK 52
68+#define AGILEX_NUM_CLKS 53
69+
70+#endif /* __AGILEX_CLOCK_H */
include/dt-bindings/clock/at91.h+4−0
@@ -12,6 +12,7 @@ · 11 unmodified lines
1212 #define PMC_TYPE_SYSTEM 1
1313 #define PMC_TYPE_PERIPHERAL 2
1414 #define PMC_TYPE_GCK 3
15+#define PMC_TYPE_PROGRAMMABLE 4
1516
1617 #define PMC_SLOW 0
1718 #define PMC_MCK 1
@@ -20,6 +21,9 @@ · 2 unmodified lines
2021 #define PMC_MCK2 4
2122 #define PMC_I2S0_MUX 5
2223 #define PMC_I2S1_MUX 6
24+#define PMC_PLLACK 7
25+#define PMC_PLLBCK 8
26+#define PMC_AUDIOPLLCK 9
2327
2428 #ifndef AT91_PMC_MOSCS
2529 #define AT91_PMC_MOSCS 0 /* MOSCS Flag */
include/dt-bindings/clock/bt1-ccu.h+48−0
@@ -0,0 +1,48 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
4+ *
5+ * Baikal-T1 CCU clock indices
6+ */
7+#ifndef __DT_BINDINGS_CLOCK_BT1_CCU_H
8+#define __DT_BINDINGS_CLOCK_BT1_CCU_H
9+
10+#define CCU_CPU_PLL 0
11+#define CCU_SATA_PLL 1
12+#define CCU_DDR_PLL 2
13+#define CCU_PCIE_PLL 3
14+#define CCU_ETH_PLL 4
15+
16+#define CCU_AXI_MAIN_CLK 0
17+#define CCU_AXI_DDR_CLK 1
18+#define CCU_AXI_SATA_CLK 2
19+#define CCU_AXI_GMAC0_CLK 3
20+#define CCU_AXI_GMAC1_CLK 4
21+#define CCU_AXI_XGMAC_CLK 5
22+#define CCU_AXI_PCIE_M_CLK 6
23+#define CCU_AXI_PCIE_S_CLK 7
24+#define CCU_AXI_USB_CLK 8
25+#define CCU_AXI_HWA_CLK 9
26+#define CCU_AXI_SRAM_CLK 10
27+
28+#define CCU_SYS_SATA_REF_CLK 0
29+#define CCU_SYS_APB_CLK 1
30+#define CCU_SYS_GMAC0_TX_CLK 2
31+#define CCU_SYS_GMAC0_PTP_CLK 3
32+#define CCU_SYS_GMAC1_TX_CLK 4
33+#define CCU_SYS_GMAC1_PTP_CLK 5
34+#define CCU_SYS_XGMAC_REF_CLK 6
35+#define CCU_SYS_XGMAC_PTP_CLK 7
36+#define CCU_SYS_USB_CLK 8
37+#define CCU_SYS_PVT_CLK 9
38+#define CCU_SYS_HWA_CLK 10
39+#define CCU_SYS_UART_CLK 11
40+#define CCU_SYS_I2C1_CLK 12
41+#define CCU_SYS_I2C2_CLK 13
42+#define CCU_SYS_GPIO_CLK 14
43+#define CCU_SYS_TIMER0_CLK 15
44+#define CCU_SYS_TIMER1_CLK 16
45+#define CCU_SYS_TIMER2_CLK 17
46+#define CCU_SYS_WDT_CLK 18
47+
48+#endif /* __DT_BINDINGS_CLOCK_BT1_CCU_H */
include/dt-bindings/clock/imx7ulp-clock.h+4−1
@@ -58,7 +58,10 @@ · 57 unmodified lines
5858 #define IMX7ULP_CLK_HSRUN_SYS_SEL 44
5959 #define IMX7ULP_CLK_HSRUN_CORE_DIV 45
6060
61−#define IMX7ULP_CLK_SCG1_END 46
61+#define IMX7ULP_CLK_CORE 46
62+#define IMX7ULP_CLK_HSRUN_CORE 47
63+
64+#define IMX7ULP_CLK_SCG1_END 48
6265
6366 /* PCC2 */
6467 #define IMX7ULP_CLK_DMA1 0
include/dt-bindings/clock/imx8mp-clock.h+89−1
@@ -296,6 +296,94 @@ · 295 unmodified lines
296296 #define IMX8MP_CLK_ARM 287
297297 #define IMX8MP_CLK_A53_CORE 288
298298
299−#define IMX8MP_CLK_END 289
299+#define IMX8MP_SYS_PLL1_40M_CG 289
300+#define IMX8MP_SYS_PLL1_80M_CG 290
301+#define IMX8MP_SYS_PLL1_100M_CG 291
302+#define IMX8MP_SYS_PLL1_133M_CG 292
303+#define IMX8MP_SYS_PLL1_160M_CG 293
304+#define IMX8MP_SYS_PLL1_200M_CG 294
305+#define IMX8MP_SYS_PLL1_266M_CG 295
306+#define IMX8MP_SYS_PLL1_400M_CG 296
307+#define IMX8MP_SYS_PLL2_50M_CG 297
308+#define IMX8MP_SYS_PLL2_100M_CG 298
309+#define IMX8MP_SYS_PLL2_125M_CG 299
310+#define IMX8MP_SYS_PLL2_166M_CG 300
311+#define IMX8MP_SYS_PLL2_200M_CG 301
312+#define IMX8MP_SYS_PLL2_250M_CG 302
313+#define IMX8MP_SYS_PLL2_333M_CG 303
314+#define IMX8MP_SYS_PLL2_500M_CG 304
315+
316+#define IMX8MP_CLK_M7_CORE 305
317+#define IMX8MP_CLK_ML_CORE 306
318+#define IMX8MP_CLK_GPU3D_CORE 307
319+#define IMX8MP_CLK_GPU3D_SHADER_CORE 308
320+#define IMX8MP_CLK_GPU2D_CORE 309
321+#define IMX8MP_CLK_AUDIO_AXI 310
322+#define IMX8MP_CLK_HSIO_AXI 311
323+#define IMX8MP_CLK_MEDIA_ISP 312
324+
325+#define IMX8MP_CLK_END 313
326+
327+#define IMX8MP_CLK_AUDIOMIX_SAI1_IPG 0
328+#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1 1
329+#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK2 2
330+#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK3 3
331+#define IMX8MP_CLK_AUDIOMIX_SAI2_IPG 4
332+#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1 5
333+#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK2 6
334+#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK3 7
335+#define IMX8MP_CLK_AUDIOMIX_SAI3_IPG 8
336+#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1 9
337+#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK2 10
338+#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK3 11
339+#define IMX8MP_CLK_AUDIOMIX_SAI5_IPG 12
340+#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK1 13
341+#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK2 14
342+#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK3 15
343+#define IMX8MP_CLK_AUDIOMIX_SAI6_IPG 16
344+#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK1 17
345+#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK2 18
346+#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK3 19
347+#define IMX8MP_CLK_AUDIOMIX_SAI7_IPG 20
348+#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK1 21
349+#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK2 22
350+#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK3 23
351+#define IMX8MP_CLK_AUDIOMIX_ASRC_IPG 24
352+#define IMX8MP_CLK_AUDIOMIX_PDM_IPG 25
353+#define IMX8MP_CLK_AUDIOMIX_SDMA2_ROOT 26
354+#define IMX8MP_CLK_AUDIOMIX_SDMA3_ROOT 27
355+#define IMX8MP_CLK_AUDIOMIX_SPBA2_ROOT 28
356+#define IMX8MP_CLK_AUDIOMIX_DSP_ROOT 29
357+#define IMX8MP_CLK_AUDIOMIX_DSPDBG_ROOT 30
358+#define IMX8MP_CLK_AUDIOMIX_EARC_IPG 31
359+#define IMX8MP_CLK_AUDIOMIX_OCRAMA_IPG 32
360+#define IMX8MP_CLK_AUDIOMIX_AUD2HTX_IPG 33
361+#define IMX8MP_CLK_AUDIOMIX_EDMA_ROOT 34
362+#define IMX8MP_CLK_AUDIOMIX_AUDPLL_ROOT 35
363+#define IMX8MP_CLK_AUDIOMIX_MU2_ROOT 36
364+#define IMX8MP_CLK_AUDIOMIX_MU3_ROOT 37
365+#define IMX8MP_CLK_AUDIOMIX_EARC_PHY 38
366+#define IMX8MP_CLK_AUDIOMIX_PDM_ROOT 39
367+#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1_SEL 40
368+#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK2_SEL 41
369+#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1_SEL 42
370+#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK2_SEL 43
371+#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1_SEL 44
372+#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK2_SEL 45
373+#define IMX8MP_CLK_AUDIOMIX_SAI4_MCLK1_SEL 46
374+#define IMX8MP_CLK_AUDIOMIX_SAI4_MCLK2_SEL 47
375+#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK1_SEL 48
376+#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK2_SEL 49
377+#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK1_SEL 50
378+#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK2_SEL 51
379+#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK1_SEL 52
380+#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK2_SEL 53
381+#define IMX8MP_CLK_AUDIOMIX_PDM_SEL 54
382+#define IMX8MP_CLK_AUDIOMIX_SAI_PLL_REF_SEL 55
383+#define IMX8MP_CLK_AUDIOMIX_SAI_PLL 56
384+#define IMX8MP_CLK_AUDIOMIX_SAI_PLL_BYPASS 57
385+#define IMX8MP_CLK_AUDIOMIX_SAI_PLL_OUT 58
386+
387+#define IMX8MP_CLK_AUDIOMIX_END 59
300388
301389 #endif
include/dt-bindings/clock/intel,lgm-clk.h+165−0
@@ -0,0 +1,165 @@
1+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
2+/*
3+ * Copyright (C) 2020 Intel Corporation.
4+ * Lei Chuanhua <Chuanhua.lei@intel.com>
5+ * Zhu Yixin <Yixin.zhu@intel.com>
6+ */
7+#ifndef __INTEL_LGM_CLK_H
8+#define __INTEL_LGM_CLK_H
9+
10+/* PLL clocks */
11+#define LGM_CLK_OSC 1
12+#define LGM_CLK_PLLPP 2
13+#define LGM_CLK_PLL2 3
14+#define LGM_CLK_PLL0CZ 4
15+#define LGM_CLK_PLL0B 5
16+#define LGM_CLK_PLL1 6
17+#define LGM_CLK_LJPLL3 7
18+#define LGM_CLK_LJPLL4 8
19+#define LGM_CLK_PLL0CM0 9
20+#define LGM_CLK_PLL0CM1 10
21+
22+/* clocks from PLLs */
23+
24+/* ROPLL clocks */
25+#define LGM_CLK_PP_HW 15
26+#define LGM_CLK_PP_UC 16
27+#define LGM_CLK_PP_FXD 17
28+#define LGM_CLK_PP_TBM 18
29+
30+/* PLL2 clocks */
31+#define LGM_CLK_DDR 20
32+
33+/* PLL0CZ */
34+#define LGM_CLK_CM 25
35+#define LGM_CLK_IC 26
36+#define LGM_CLK_SDXC3 27
37+
38+/* PLL0B */
39+#define LGM_CLK_NGI 30
40+#define LGM_CLK_NOC4 31
41+#define LGM_CLK_SW 32
42+#define LGM_CLK_QSPI 33
43+#define LGM_CLK_CQEM LGM_CLK_SW
44+#define LGM_CLK_EMMC5 LGM_CLK_NOC4
45+
46+/* PLL1 */
47+#define LGM_CLK_CT 35
48+#define LGM_CLK_DSP 36
49+#define LGM_CLK_VIF 37
50+
51+/* LJPLL3 */
52+#define LGM_CLK_CML 40
53+#define LGM_CLK_SERDES 41
54+#define LGM_CLK_POOL 42
55+#define LGM_CLK_PTP 43
56+
57+/* LJPLL4 */
58+#define LGM_CLK_PCIE 45
59+#define LGM_CLK_SATA LGM_CLK_PCIE
60+
61+/* PLL0CM0 */
62+#define LGM_CLK_CPU0 50
63+
64+/* PLL0CM1 */
65+#define LGM_CLK_CPU1 55
66+
67+/* Miscellaneous clocks */
68+#define LGM_CLK_EMMC4 60
69+#define LGM_CLK_SDXC2 61
70+#define LGM_CLK_EMMC 62
71+#define LGM_CLK_SDXC 63
72+#define LGM_CLK_SLIC 64
73+#define LGM_CLK_DCL 65
74+#define LGM_CLK_DOCSIS 66
75+#define LGM_CLK_PCM 67
76+#define LGM_CLK_DDR_PHY 68
77+#define LGM_CLK_PONDEF 69
78+#define LGM_CLK_PL25M 70
79+#define LGM_CLK_PL10M 71
80+#define LGM_CLK_PL1544K 72
81+#define LGM_CLK_PL2048K 73
82+#define LGM_CLK_PL8K 74
83+#define LGM_CLK_PON_NTR 75
84+#define LGM_CLK_SYNC0 76
85+#define LGM_CLK_SYNC1 77
86+#define LGM_CLK_PROGDIV 78
87+#define LGM_CLK_OD0 79
88+#define LGM_CLK_OD1 80
89+#define LGM_CLK_CBPHY0 81
90+#define LGM_CLK_CBPHY1 82
91+#define LGM_CLK_CBPHY2 83
92+#define LGM_CLK_CBPHY3 84
93+
94+/* Gate clocks */
95+/* Gate CLK0 */
96+#define LGM_GCLK_C55 100
97+#define LGM_GCLK_QSPI 101
98+#define LGM_GCLK_EIP197 102
99+#define LGM_GCLK_VAULT 103
100+#define LGM_GCLK_TOE 104
101+#define LGM_GCLK_SDXC 105
102+#define LGM_GCLK_EMMC 106
103+#define LGM_GCLK_SPI_DBG 107
104+#define LGM_GCLK_DMA3 108
105+
106+/* Gate CLK1 */
107+#define LGM_GCLK_DMA0 120
108+#define LGM_GCLK_LEDC0 121
109+#define LGM_GCLK_LEDC1 122
110+#define LGM_GCLK_I2S0 123
111+#define LGM_GCLK_I2S1 124
112+#define LGM_GCLK_EBU 125
113+#define LGM_GCLK_PWM 126
114+#define LGM_GCLK_I2C0 127
115+#define LGM_GCLK_I2C1 128
116+#define LGM_GCLK_I2C2 129
117+#define LGM_GCLK_I2C3 130
118+#define LGM_GCLK_SSC0 131
119+#define LGM_GCLK_SSC1 132
120+#define LGM_GCLK_SSC2 133
121+#define LGM_GCLK_SSC3 134
122+#define LGM_GCLK_GPTC0 135
123+#define LGM_GCLK_GPTC1 136
124+#define LGM_GCLK_GPTC2 137
125+#define LGM_GCLK_GPTC3 138
126+#define LGM_GCLK_ASC0 139
127+#define LGM_GCLK_ASC1 140
128+#define LGM_GCLK_ASC2 141
129+#define LGM_GCLK_ASC3 142
130+#define LGM_GCLK_PCM0 143
131+#define LGM_GCLK_PCM1 144
132+#define LGM_GCLK_PCM2 145
133+
134+/* Gate CLK2 */
135+#define LGM_GCLK_PCIE10 150
136+#define LGM_GCLK_PCIE11 151
137+#define LGM_GCLK_PCIE30 152
138+#define LGM_GCLK_PCIE31 153
139+#define LGM_GCLK_PCIE20 154
140+#define LGM_GCLK_PCIE21 155
141+#define LGM_GCLK_PCIE40 156
142+#define LGM_GCLK_PCIE41 157
143+#define LGM_GCLK_XPCS0 158
144+#define LGM_GCLK_XPCS1 159
145+#define LGM_GCLK_XPCS2 160
146+#define LGM_GCLK_XPCS3 161
147+#define LGM_GCLK_SATA0 162
148+#define LGM_GCLK_SATA1 163
149+#define LGM_GCLK_SATA2 164
150+#define LGM_GCLK_SATA3 165
151+
152+/* Gate CLK3 */
153+#define LGM_GCLK_ARCEM4 170
154+#define LGM_GCLK_IDMAR1 171
155+#define LGM_GCLK_IDMAT0 172
156+#define LGM_GCLK_IDMAT1 173
157+#define LGM_GCLK_IDMAT2 174
158+#define LGM_GCLK_PPV4 175
159+#define LGM_GCLK_GSWIPO 176
160+#define LGM_GCLK_CQEM 177
161+#define LGM_GCLK_XPCS5 178
162+#define LGM_GCLK_USB1 179
163+#define LGM_GCLK_USB2 180
164+
165+#endif /* __INTEL_LGM_CLK_H */
include/dt-bindings/clock/marvell,mmp2-audio.h+10−0
@@ -0,0 +1,10 @@
1+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-2-Clause) */
2+#ifndef __DT_BINDINGS_CLOCK_MARVELL_MMP2_AUDIO_H
3+#define __DT_BINDINGS_CLOCK_MARVELL_MMP2_AUDIO_H
4+
5+#define MMP2_CLK_AUDIO_SYSCLK 0
6+#define MMP2_CLK_AUDIO_SSPA0 1
7+#define MMP2_CLK_AUDIO_SSPA1 2
8+
9+#define MMP2_CLK_AUDIO_NR_CLKS 3
10+#endif
include/dt-bindings/clock/marvell,mmp2.h+3−0
@@ -29,6 +29,8 @@ · 28 unmodified lines
2929 #define MMP3_CLK_PLL1_P 28
3030 #define MMP3_CLK_PLL2_P 29
3131 #define MMP3_CLK_PLL3 30
32+#define MMP2_CLK_I2S0 31
33+#define MMP2_CLK_I2S1 32
3234
3335 /* apb periphrals */
3436 #define MMP2_CLK_TWSI0 60
@@ -87,6 +89,7 @@ · 52 unmodified lines
8789 #define MMP3_CLK_GPU_3D MMP2_CLK_GPU_3D
8890 #define MMP3_CLK_GPU_2D 125
8991 #define MMP3_CLK_SDH4 126
92+#define MMP2_CLK_AUDIO 127
9093
9194 #define MMP2_NR_CLKS 200
9295 #endif
include/dt-bindings/clock/meson8b-clkc.h+1−0
@@ -107,6 +107,7 @@ · 106 unmodified lines
107107 #define CLKID_PERIPH 126
108108 #define CLKID_AXI 128
109109 #define CLKID_L2_DRAM 130
110+#define CLKID_HDMI_SYS 174
110111 #define CLKID_VPU 190
111112 #define CLKID_VDEC_1 196
112113 #define CLKID_VDEC_HCODEC 199
include/dt-bindings/clock/mt6765-clk.h+313−0
@@ -0,0 +1,313 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+
3+#ifndef _DT_BINDINGS_CLK_MT6765_H
4+#define _DT_BINDINGS_CLK_MT6765_H
5+
6+/* FIX Clks */
7+#define CLK_TOP_CLK26M 0
8+
9+/* APMIXEDSYS */
10+#define CLK_APMIXED_ARMPLL_L 0
11+#define CLK_APMIXED_ARMPLL 1
12+#define CLK_APMIXED_CCIPLL 2
13+#define CLK_APMIXED_MAINPLL 3
14+#define CLK_APMIXED_MFGPLL 4
15+#define CLK_APMIXED_MMPLL 5
16+#define CLK_APMIXED_UNIV2PLL 6
17+#define CLK_APMIXED_MSDCPLL 7
18+#define CLK_APMIXED_APLL1 8
19+#define CLK_APMIXED_MPLL 9
20+#define CLK_APMIXED_ULPOSC1 10
21+#define CLK_APMIXED_ULPOSC2 11
22+#define CLK_APMIXED_SSUSB26M 12
23+#define CLK_APMIXED_APPLL26M 13
24+#define CLK_APMIXED_MIPIC0_26M 14
25+#define CLK_APMIXED_MDPLLGP26M 15
26+#define CLK_APMIXED_MMSYS_F26M 16
27+#define CLK_APMIXED_UFS26M 17
28+#define CLK_APMIXED_MIPIC1_26M 18
29+#define CLK_APMIXED_MEMPLL26M 19
30+#define CLK_APMIXED_CLKSQ_LVPLL_26M 20
31+#define CLK_APMIXED_MIPID0_26M 21
32+#define CLK_APMIXED_NR_CLK 22
33+
34+/* TOPCKGEN */
35+#define CLK_TOP_SYSPLL 0
36+#define CLK_TOP_SYSPLL_D2 1
37+#define CLK_TOP_SYSPLL1_D2 2
38+#define CLK_TOP_SYSPLL1_D4 3
39+#define CLK_TOP_SYSPLL1_D8 4
40+#define CLK_TOP_SYSPLL1_D16 5
41+#define CLK_TOP_SYSPLL_D3 6
42+#define CLK_TOP_SYSPLL2_D2 7
43+#define CLK_TOP_SYSPLL2_D4 8
44+#define CLK_TOP_SYSPLL2_D8 9
45+#define CLK_TOP_SYSPLL_D5 10
46+#define CLK_TOP_SYSPLL3_D2 11
47+#define CLK_TOP_SYSPLL3_D4 12
48+#define CLK_TOP_SYSPLL_D7 13
49+#define CLK_TOP_SYSPLL4_D2 14
50+#define CLK_TOP_SYSPLL4_D4 15
51+#define CLK_TOP_USB20_192M 16
52+#define CLK_TOP_USB20_192M_D4 17
53+#define CLK_TOP_USB20_192M_D8 18
54+#define CLK_TOP_USB20_192M_D16 19
55+#define CLK_TOP_USB20_192M_D32 20
56+#define CLK_TOP_UNIVPLL 21
57+#define CLK_TOP_UNIVPLL_D2 22
58+#define CLK_TOP_UNIVPLL1_D2 23
59+#define CLK_TOP_UNIVPLL1_D4 24
60+#define CLK_TOP_UNIVPLL_D3 25
61+#define CLK_TOP_UNIVPLL2_D2 26
62+#define CLK_TOP_UNIVPLL2_D4 27
63+#define CLK_TOP_UNIVPLL2_D8 28
64+#define CLK_TOP_UNIVPLL2_D32 29
65+#define CLK_TOP_UNIVPLL_D5 30
66+#define CLK_TOP_UNIVPLL3_D2 31
67+#define CLK_TOP_UNIVPLL3_D4 32
68+#define CLK_TOP_MMPLL 33
69+#define CLK_TOP_MMPLL_D2 34
70+#define CLK_TOP_MPLL 35
71+#define CLK_TOP_DA_MPLL_104M_DIV 36
72+#define CLK_TOP_DA_MPLL_52M_DIV 37
73+#define CLK_TOP_MFGPLL 38
74+#define CLK_TOP_MSDCPLL 39
75+#define CLK_TOP_MSDCPLL_D2 40
76+#define CLK_TOP_APLL1 41
77+#define CLK_TOP_APLL1_D2 42
78+#define CLK_TOP_APLL1_D4 43
79+#define CLK_TOP_APLL1_D8 44
80+#define CLK_TOP_ULPOSC1 45
81+#define CLK_TOP_ULPOSC1_D2 46
82+#define CLK_TOP_ULPOSC1_D4 47
83+#define CLK_TOP_ULPOSC1_D8 48
84+#define CLK_TOP_ULPOSC1_D16 49
85+#define CLK_TOP_ULPOSC1_D32 50
86+#define CLK_TOP_DMPLL 51
87+#define CLK_TOP_F_FRTC 52
88+#define CLK_TOP_F_F26M 53
89+#define CLK_TOP_AXI 54
90+#define CLK_TOP_MM 55
91+#define CLK_TOP_SCP 56
92+#define CLK_TOP_MFG 57
93+#define CLK_TOP_F_FUART 58
94+#define CLK_TOP_SPI 59
95+#define CLK_TOP_MSDC50_0 60
96+#define CLK_TOP_MSDC30_1 61
97+#define CLK_TOP_AUDIO 62
98+#define CLK_TOP_AUD_1 63
99+#define CLK_TOP_AUD_ENGEN1 64
100+#define CLK_TOP_F_FDISP_PWM 65
101+#define CLK_TOP_SSPM 66
102+#define CLK_TOP_DXCC 67
103+#define CLK_TOP_I2C 68
104+#define CLK_TOP_F_FPWM 69
105+#define CLK_TOP_F_FSENINF 70
106+#define CLK_TOP_AES_FDE 71
107+#define CLK_TOP_F_BIST2FPC 72
108+#define CLK_TOP_ARMPLL_DIVIDER_PLL0 73
109+#define CLK_TOP_ARMPLL_DIVIDER_PLL1 74
110+#define CLK_TOP_ARMPLL_DIVIDER_PLL2 75
111+#define CLK_TOP_DA_USB20_48M_DIV 76
112+#define CLK_TOP_DA_UNIV_48M_DIV 77
113+#define CLK_TOP_APLL12_DIV0 78
114+#define CLK_TOP_APLL12_DIV1 79
115+#define CLK_TOP_APLL12_DIV2 80
116+#define CLK_TOP_APLL12_DIV3 81
117+#define CLK_TOP_ARMPLL_DIVIDER_PLL0_EN 82
118+#define CLK_TOP_ARMPLL_DIVIDER_PLL1_EN 83
119+#define CLK_TOP_ARMPLL_DIVIDER_PLL2_EN 84
120+#define CLK_TOP_FMEM_OCC_DRC_EN 85
121+#define CLK_TOP_USB20_48M_EN 86
122+#define CLK_TOP_UNIVPLL_48M_EN 87
123+#define CLK_TOP_MPLL_104M_EN 88
124+#define CLK_TOP_MPLL_52M_EN 89
125+#define CLK_TOP_F_UFS_MP_SAP_CFG_EN 90
126+#define CLK_TOP_F_BIST2FPC_EN 91
127+#define CLK_TOP_MD_32K 92
128+#define CLK_TOP_MD_26M 93
129+#define CLK_TOP_MD2_32K 94
130+#define CLK_TOP_MD2_26M 95
131+#define CLK_TOP_AXI_SEL 96
132+#define CLK_TOP_MEM_SEL 97
133+#define CLK_TOP_MM_SEL 98
134+#define CLK_TOP_SCP_SEL 99
135+#define CLK_TOP_MFG_SEL 100
136+#define CLK_TOP_ATB_SEL 101
137+#define CLK_TOP_CAMTG_SEL 102
138+#define CLK_TOP_CAMTG1_SEL 103
139+#define CLK_TOP_CAMTG2_SEL 104
140+#define CLK_TOP_CAMTG3_SEL 105
141+#define CLK_TOP_UART_SEL 106
142+#define CLK_TOP_SPI_SEL 107
143+#define CLK_TOP_MSDC50_0_HCLK_SEL 108
144+#define CLK_TOP_MSDC50_0_SEL 109
145+#define CLK_TOP_MSDC30_1_SEL 110
146+#define CLK_TOP_AUDIO_SEL 111
147+#define CLK_TOP_AUD_INTBUS_SEL 112
148+#define CLK_TOP_AUD_1_SEL 113
149+#define CLK_TOP_AUD_ENGEN1_SEL 114
150+#define CLK_TOP_DISP_PWM_SEL 115
151+#define CLK_TOP_SSPM_SEL 116
152+#define CLK_TOP_DXCC_SEL 117
153+#define CLK_TOP_USB_TOP_SEL 118
154+#define CLK_TOP_SPM_SEL 119
155+#define CLK_TOP_I2C_SEL 120
156+#define CLK_TOP_PWM_SEL 121
157+#define CLK_TOP_SENINF_SEL 122
158+#define CLK_TOP_AES_FDE_SEL 123
159+#define CLK_TOP_PWRAP_ULPOSC_SEL 124
160+#define CLK_TOP_CAMTM_SEL 125
161+#define CLK_TOP_NR_CLK 126
162+
163+/* INFRACFG */
164+#define CLK_IFR_ICUSB 0
165+#define CLK_IFR_GCE 1
166+#define CLK_IFR_THERM 2
167+#define CLK_IFR_I2C_AP 3
168+#define CLK_IFR_I2C_CCU 4
169+#define CLK_IFR_I2C_SSPM 5
170+#define CLK_IFR_I2C_RSV 6
171+#define CLK_IFR_PWM_HCLK 7
172+#define CLK_IFR_PWM1 8
173+#define CLK_IFR_PWM2 9
174+#define CLK_IFR_PWM3 10
175+#define CLK_IFR_PWM4 11
176+#define CLK_IFR_PWM5 12
177+#define CLK_IFR_PWM 13
178+#define CLK_IFR_UART0 14
179+#define CLK_IFR_UART1 15
180+#define CLK_IFR_GCE_26M 16
181+#define CLK_IFR_CQ_DMA_FPC 17
182+#define CLK_IFR_BTIF 18
183+#define CLK_IFR_SPI0 19
184+#define CLK_IFR_MSDC0 20
185+#define CLK_IFR_MSDC1 21
186+#define CLK_IFR_TRNG 22
187+#define CLK_IFR_AUXADC 23
188+#define CLK_IFR_CCIF1_AP 24
189+#define CLK_IFR_CCIF1_MD 25
190+#define CLK_IFR_AUXADC_MD 26
191+#define CLK_IFR_AP_DMA 27
192+#define CLK_IFR_DEVICE_APC 28
193+#define CLK_IFR_CCIF_AP 29
194+#define CLK_IFR_AUDIO 30
195+#define CLK_IFR_CCIF_MD 31
196+#define CLK_IFR_RG_PWM_FBCLK6 32
197+#define CLK_IFR_DISP_PWM 33
198+#define CLK_IFR_CLDMA_BCLK 34
199+#define CLK_IFR_AUDIO_26M_BCLK 35
200+#define CLK_IFR_SPI1 36
201+#define CLK_IFR_I2C4 37
202+#define CLK_IFR_SPI2 38
203+#define CLK_IFR_SPI3 39
204+#define CLK_IFR_I2C5 40
205+#define CLK_IFR_I2C5_ARBITER 41
206+#define CLK_IFR_I2C5_IMM 42
207+#define CLK_IFR_I2C1_ARBITER 43
208+#define CLK_IFR_I2C1_IMM 44
209+#define CLK_IFR_I2C2_ARBITER 45
210+#define CLK_IFR_I2C2_IMM 46
211+#define CLK_IFR_SPI4 47
212+#define CLK_IFR_SPI5 48
213+#define CLK_IFR_CQ_DMA 49
214+#define CLK_IFR_FAES_FDE 50
215+#define CLK_IFR_MSDC0_SELF 51
216+#define CLK_IFR_MSDC1_SELF 52
217+#define CLK_IFR_I2C6 53
218+#define CLK_IFR_AP_MSDC0 54
219+#define CLK_IFR_MD_MSDC0 55
220+#define CLK_IFR_MSDC0_SRC 56
221+#define CLK_IFR_MSDC1_SRC 57
222+#define CLK_IFR_AES_TOP0_BCLK 58
223+#define CLK_IFR_MCU_PM_BCLK 59
224+#define CLK_IFR_CCIF2_AP 60
225+#define CLK_IFR_CCIF2_MD 61
226+#define CLK_IFR_CCIF3_AP 62
227+#define CLK_IFR_CCIF3_MD 63
228+#define CLK_IFR_NR_CLK 64
229+
230+/* AUDIO */
231+#define CLK_AUDIO_AFE 0
232+#define CLK_AUDIO_22M 1
233+#define CLK_AUDIO_APLL_TUNER 2
234+#define CLK_AUDIO_ADC 3
235+#define CLK_AUDIO_DAC 4
236+#define CLK_AUDIO_DAC_PREDIS 5
237+#define CLK_AUDIO_TML 6
238+#define CLK_AUDIO_I2S1_BCLK 7
239+#define CLK_AUDIO_I2S2_BCLK 8
240+#define CLK_AUDIO_I2S3_BCLK 9
241+#define CLK_AUDIO_I2S4_BCLK 10
242+#define CLK_AUDIO_NR_CLK 11
243+
244+/* MIPI_RX_ANA_CSI0A */
245+
246+#define CLK_MIPI0A_CSR_CSI_EN_0A 0
247+#define CLK_MIPI0A_NR_CLK 1
248+
249+/* MMSYS_CONFIG */
250+
251+#define CLK_MM_MDP_RDMA0 0
252+#define CLK_MM_MDP_CCORR0 1
253+#define CLK_MM_MDP_RSZ0 2
254+#define CLK_MM_MDP_RSZ1 3
255+#define CLK_MM_MDP_TDSHP0 4
256+#define CLK_MM_MDP_WROT0 5
257+#define CLK_MM_MDP_WDMA0 6
258+#define CLK_MM_DISP_OVL0 7
259+#define CLK_MM_DISP_OVL0_2L 8
260+#define CLK_MM_DISP_RSZ0 9
261+#define CLK_MM_DISP_RDMA0 10
262+#define CLK_MM_DISP_WDMA0 11
263+#define CLK_MM_DISP_COLOR0 12
264+#define CLK_MM_DISP_CCORR0 13
265+#define CLK_MM_DISP_AAL0 14
266+#define CLK_MM_DISP_GAMMA0 15
267+#define CLK_MM_DISP_DITHER0 16
268+#define CLK_MM_DSI0 17
269+#define CLK_MM_FAKE_ENG 18
270+#define CLK_MM_SMI_COMMON 19
271+#define CLK_MM_SMI_LARB0 20
272+#define CLK_MM_SMI_COMM0 21
273+#define CLK_MM_SMI_COMM1 22
274+#define CLK_MM_CAM_MDP 23
275+#define CLK_MM_SMI_IMG 24
276+#define CLK_MM_SMI_CAM 25
277+#define CLK_MM_IMG_DL_RELAY 26
278+#define CLK_MM_IMG_DL_ASYNC_TOP 27
279+#define CLK_MM_DIG_DSI 28
280+#define CLK_MM_F26M_HRTWT 29
281+#define CLK_MM_NR_CLK 30
282+
283+/* IMGSYS */
284+
285+#define CLK_IMG_LARB2 0
286+#define CLK_IMG_DIP 1
287+#define CLK_IMG_FDVT 2
288+#define CLK_IMG_DPE 3
289+#define CLK_IMG_RSC 4
290+#define CLK_IMG_NR_CLK 5
291+
292+/* VENCSYS */
293+
294+#define CLK_VENC_SET0_LARB 0
295+#define CLK_VENC_SET1_VENC 1
296+#define CLK_VENC_SET2_JPGENC 2
297+#define CLK_VENC_SET3_VDEC 3
298+#define CLK_VENC_NR_CLK 4
299+
300+/* CAMSYS */
301+
302+#define CLK_CAM_LARB3 0
303+#define CLK_CAM_DFP_VAD 1
304+#define CLK_CAM 2
305+#define CLK_CAMTG 3
306+#define CLK_CAM_SENINF 4
307+#define CLK_CAMSV0 5
308+#define CLK_CAMSV1 6
309+#define CLK_CAMSV2 7
310+#define CLK_CAM_CCU 8
311+#define CLK_CAM_NR_CLK 9
312+
313+#endif /* _DT_BINDINGS_CLK_MT6765_H */
include/dt-bindings/clock/qcom,gcc-msm8939.h+206−0
@@ -0,0 +1,206 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright 2020 Linaro Limited
4+ */
5+
6+#ifndef _DT_BINDINGS_CLK_MSM_GCC_8939_H
7+#define _DT_BINDINGS_CLK_MSM_GCC_8939_H
8+
9+#define GPLL0 0
10+#define GPLL0_VOTE 1
11+#define BIMC_PLL 2
12+#define BIMC_PLL_VOTE 3
13+#define GPLL1 4
14+#define GPLL1_VOTE 5
15+#define GPLL2 6
16+#define GPLL2_VOTE 7
17+#define PCNOC_BFDCD_CLK_SRC 8
18+#define SYSTEM_NOC_BFDCD_CLK_SRC 9
19+#define CAMSS_AHB_CLK_SRC 10
20+#define APSS_AHB_CLK_SRC 11
21+#define CSI0_CLK_SRC 12
22+#define CSI1_CLK_SRC 13
23+#define GFX3D_CLK_SRC 14
24+#define VFE0_CLK_SRC 15
25+#define BLSP1_QUP1_I2C_APPS_CLK_SRC 16
26+#define BLSP1_QUP1_SPI_APPS_CLK_SRC 17
27+#define BLSP1_QUP2_I2C_APPS_CLK_SRC 18
28+#define BLSP1_QUP2_SPI_APPS_CLK_SRC 19
29+#define BLSP1_QUP3_I2C_APPS_CLK_SRC 20
30+#define BLSP1_QUP3_SPI_APPS_CLK_SRC 21
31+#define BLSP1_QUP4_I2C_APPS_CLK_SRC 22
32+#define BLSP1_QUP4_SPI_APPS_CLK_SRC 23
33+#define BLSP1_QUP5_I2C_APPS_CLK_SRC 24
34+#define BLSP1_QUP5_SPI_APPS_CLK_SRC 25
35+#define BLSP1_QUP6_I2C_APPS_CLK_SRC 26
36+#define BLSP1_QUP6_SPI_APPS_CLK_SRC 27
37+#define BLSP1_UART1_APPS_CLK_SRC 28
38+#define BLSP1_UART2_APPS_CLK_SRC 29
39+#define CCI_CLK_SRC 30
40+#define CAMSS_GP0_CLK_SRC 31
41+#define CAMSS_GP1_CLK_SRC 32
42+#define JPEG0_CLK_SRC 33
43+#define MCLK0_CLK_SRC 34
44+#define MCLK1_CLK_SRC 35
45+#define CSI0PHYTIMER_CLK_SRC 36
46+#define CSI1PHYTIMER_CLK_SRC 37
47+#define CPP_CLK_SRC 38
48+#define CRYPTO_CLK_SRC 39
49+#define GP1_CLK_SRC 40
50+#define GP2_CLK_SRC 41
51+#define GP3_CLK_SRC 42
52+#define BYTE0_CLK_SRC 43
53+#define ESC0_CLK_SRC 44
54+#define MDP_CLK_SRC 45
55+#define PCLK0_CLK_SRC 46
56+#define VSYNC_CLK_SRC 47
57+#define PDM2_CLK_SRC 48
58+#define SDCC1_APPS_CLK_SRC 49
59+#define SDCC2_APPS_CLK_SRC 50
60+#define APSS_TCU_CLK_SRC 51
61+#define USB_HS_SYSTEM_CLK_SRC 52
62+#define VCODEC0_CLK_SRC 53
63+#define GCC_BLSP1_AHB_CLK 54
64+#define GCC_BLSP1_SLEEP_CLK 55
65+#define GCC_BLSP1_QUP1_I2C_APPS_CLK 56
66+#define GCC_BLSP1_QUP1_SPI_APPS_CLK 57
67+#define GCC_BLSP1_QUP2_I2C_APPS_CLK 58
68+#define GCC_BLSP1_QUP2_SPI_APPS_CLK 59
69+#define GCC_BLSP1_QUP3_I2C_APPS_CLK 60
70+#define GCC_BLSP1_QUP3_SPI_APPS_CLK 61
71+#define GCC_BLSP1_QUP4_I2C_APPS_CLK 62
72+#define GCC_BLSP1_QUP4_SPI_APPS_CLK 63
73+#define GCC_BLSP1_QUP5_I2C_APPS_CLK 64
74+#define GCC_BLSP1_QUP5_SPI_APPS_CLK 65
75+#define GCC_BLSP1_QUP6_I2C_APPS_CLK 66
76+#define GCC_BLSP1_QUP6_SPI_APPS_CLK 67
77+#define GCC_BLSP1_UART1_APPS_CLK 68
78+#define GCC_BLSP1_UART2_APPS_CLK 69
79+#define GCC_BOOT_ROM_AHB_CLK 70
80+#define GCC_CAMSS_CCI_AHB_CLK 71
81+#define GCC_CAMSS_CCI_CLK 72
82+#define GCC_CAMSS_CSI0_AHB_CLK 73
83+#define GCC_CAMSS_CSI0_CLK 74
84+#define GCC_CAMSS_CSI0PHY_CLK 75
85+#define GCC_CAMSS_CSI0PIX_CLK 76
86+#define GCC_CAMSS_CSI0RDI_CLK 77
87+#define GCC_CAMSS_CSI1_AHB_CLK 78
88+#define GCC_CAMSS_CSI1_CLK 79
89+#define GCC_CAMSS_CSI1PHY_CLK 80
90+#define GCC_CAMSS_CSI1PIX_CLK 81
91+#define GCC_CAMSS_CSI1RDI_CLK 82
92+#define GCC_CAMSS_CSI_VFE0_CLK 83
93+#define GCC_CAMSS_GP0_CLK 84
94+#define GCC_CAMSS_GP1_CLK 85
95+#define GCC_CAMSS_ISPIF_AHB_CLK 86
96+#define GCC_CAMSS_JPEG0_CLK 87
97+#define GCC_CAMSS_JPEG_AHB_CLK 88
98+#define GCC_CAMSS_JPEG_AXI_CLK 89
99+#define GCC_CAMSS_MCLK0_CLK 90
100+#define GCC_CAMSS_MCLK1_CLK 91
101+#define GCC_CAMSS_MICRO_AHB_CLK 92
102+#define GCC_CAMSS_CSI0PHYTIMER_CLK 93
103+#define GCC_CAMSS_CSI1PHYTIMER_CLK 94
104+#define GCC_CAMSS_AHB_CLK 95
105+#define GCC_CAMSS_TOP_AHB_CLK 96
106+#define GCC_CAMSS_CPP_AHB_CLK 97
107+#define GCC_CAMSS_CPP_CLK 98
108+#define GCC_CAMSS_VFE0_CLK 99
109+#define GCC_CAMSS_VFE_AHB_CLK 100
110+#define GCC_CAMSS_VFE_AXI_CLK 101
111+#define GCC_CRYPTO_AHB_CLK 102
112+#define GCC_CRYPTO_AXI_CLK 103
113+#define GCC_CRYPTO_CLK 104
114+#define GCC_OXILI_GMEM_CLK 105
115+#define GCC_GP1_CLK 106
116+#define GCC_GP2_CLK 107
117+#define GCC_GP3_CLK 108
118+#define GCC_MDSS_AHB_CLK 109
119+#define GCC_MDSS_AXI_CLK 110
120+#define GCC_MDSS_BYTE0_CLK 111
121+#define GCC_MDSS_ESC0_CLK 112
122+#define GCC_MDSS_MDP_CLK 113
123+#define GCC_MDSS_PCLK0_CLK 114
124+#define GCC_MDSS_VSYNC_CLK 115
125+#define GCC_MSS_CFG_AHB_CLK 116
126+#define GCC_OXILI_AHB_CLK 117
127+#define GCC_OXILI_GFX3D_CLK 118
128+#define GCC_PDM2_CLK 119
129+#define GCC_PDM_AHB_CLK 120
130+#define GCC_PRNG_AHB_CLK 121
131+#define GCC_SDCC1_AHB_CLK 122
132+#define GCC_SDCC1_APPS_CLK 123
133+#define GCC_SDCC2_AHB_CLK 124
134+#define GCC_SDCC2_APPS_CLK 125
135+#define GCC_GTCU_AHB_CLK 126
136+#define GCC_JPEG_TBU_CLK 127
137+#define GCC_MDP_TBU_CLK 128
138+#define GCC_SMMU_CFG_CLK 129
139+#define GCC_VENUS_TBU_CLK 130
140+#define GCC_VFE_TBU_CLK 131
141+#define GCC_USB2A_PHY_SLEEP_CLK 132
142+#define GCC_USB_HS_AHB_CLK 133
143+#define GCC_USB_HS_SYSTEM_CLK 134
144+#define GCC_VENUS0_AHB_CLK 135
145+#define GCC_VENUS0_AXI_CLK 136
146+#define GCC_VENUS0_VCODEC0_CLK 137
147+#define BIMC_DDR_CLK_SRC 138
148+#define GCC_APSS_TCU_CLK 139
149+#define GCC_GFX_TCU_CLK 140
150+#define BIMC_GPU_CLK_SRC 141
151+#define GCC_BIMC_GFX_CLK 142
152+#define GCC_BIMC_GPU_CLK 143
153+#define ULTAUDIO_LPAIF_PRI_I2S_CLK_SRC 144
154+#define ULTAUDIO_LPAIF_SEC_I2S_CLK_SRC 145
155+#define ULTAUDIO_LPAIF_AUX_I2S_CLK_SRC 146
156+#define ULTAUDIO_XO_CLK_SRC 147
157+#define ULTAUDIO_AHBFABRIC_CLK_SRC 148
158+#define CODEC_DIGCODEC_CLK_SRC 149
159+#define GCC_ULTAUDIO_PCNOC_MPORT_CLK 150
160+#define GCC_ULTAUDIO_PCNOC_SWAY_CLK 151
161+#define GCC_ULTAUDIO_AVSYNC_XO_CLK 152
162+#define GCC_ULTAUDIO_STC_XO_CLK 153
163+#define GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK 154
164+#define GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_LPM_CLK 155
165+#define GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK 156
166+#define GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK 157
167+#define GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK 158
168+#define GCC_CODEC_DIGCODEC_CLK 159
169+#define GCC_MSS_Q6_BIMC_AXI_CLK 160
170+#define GPLL3 161
171+#define GPLL3_VOTE 162
172+#define GPLL4 163
173+#define GPLL4_VOTE 164
174+#define GPLL5 165
175+#define GPLL5_VOTE 166
176+#define GPLL6 167
177+#define GPLL6_VOTE 168
178+#define BYTE1_CLK_SRC 169
179+#define GCC_MDSS_BYTE1_CLK 170
180+#define ESC1_CLK_SRC 171
181+#define GCC_MDSS_ESC1_CLK 172
182+#define PCLK1_CLK_SRC 173
183+#define GCC_MDSS_PCLK1_CLK 174
184+#define GCC_GFX_TBU_CLK 175
185+#define GCC_CPP_TBU_CLK 176
186+#define GCC_MDP_RT_TBU_CLK 177
187+#define USB_FS_SYSTEM_CLK_SRC 178
188+#define USB_FS_IC_CLK_SRC 179
189+#define GCC_USB_FS_AHB_CLK 180
190+#define GCC_USB_FS_IC_CLK 181
191+#define GCC_USB_FS_SYSTEM_CLK 182
192+#define GCC_VENUS0_CORE0_VCODEC0_CLK 183
193+#define GCC_VENUS0_CORE1_VCODEC0_CLK 184
194+#define GCC_OXILI_TIMER_CLK 185
195+
196+/* Indexes for GDSCs */
197+#define BIMC_GDSC 0
198+#define VENUS_GDSC 1
199+#define MDSS_GDSC 2
200+#define JPEG_GDSC 3
201+#define VFE_GDSC 4
202+#define OXILI_GDSC 5
203+#define VENUS_CORE0_GDSC 6
204+#define VENUS_CORE1_GDSC 7
205+
206+#endif
include/dt-bindings/clock/qcom,gcc-msm8998.h+1−0
@@ -183,6 +183,7 @@ · 182 unmodified lines
183183 #define GCC_MSS_SNOC_AXI_CLK 174
184184 #define GCC_MSS_MNOC_BIMC_AXI_CLK 175
185185 #define GCC_BIMC_GFX_CLK 176
186+#define UFS_UNIPRO_CORE_CLK_SRC 177
186187
187188 #define PCIE_0_GDSC 0
188189 #define UFS_GDSC 1
include/dt-bindings/clock/qcom,gcc-sc7180.h+1−0
@@ -137,6 +137,7 @@ · 136 unmodified lines
137137 #define GCC_MSS_NAV_AXI_CLK 127
138138 #define GCC_MSS_Q6_MEMNOC_AXI_CLK 128
139139 #define GCC_MSS_SNOC_AXI_CLK 129
140+#define GCC_SEC_CTRL_CLK_SRC 130
140141
141142 /* GCC resets */
142143 #define GCC_QUSB2PHY_PRIM_BCR 0
include/dt-bindings/clock/sprd,sc9863a-clk.h+5−0
@@ -308,6 +308,11 @@ · 307 unmodified lines
308308 #define CLK_MCPHY_CFG_EB 14
309309 #define CLK_MM_GATE_NUM (CLK_MCPHY_CFG_EB + 1)
310310
311+#define CLK_MIPI_CSI 0
312+#define CLK_MIPI_CSI_S 1
313+#define CLK_MIPI_CSI_M 2
314+#define CLK_MM_CLK_NUM (CLK_MIPI_CSI_M + 1)
315+
311316 #define CLK_SIM0_EB 0
312317 #define CLK_IIS0_EB 1
313318 #define CLK_IIS1_EB 2
include/dt-bindings/clock/tegra210-car.h+2−2
@@ -351,8 +351,8 @@ · 350 unmodified lines
351351 #define TEGRA210_CLK_PLL_P_OUT_XUSB 317
352352 #define TEGRA210_CLK_XUSB_SSP_SRC 318
353353 #define TEGRA210_CLK_PLL_RE_OUT1 319
354−/* 320 */
355−/* 321 */
354+#define TEGRA210_CLK_PLL_MB_UD 320
355+#define TEGRA210_CLK_PLL_P_UD 321
356356 #define TEGRA210_CLK_ISP 322
357357 #define TEGRA210_CLK_PLL_A_OUT_ADSP 323
358358 #define TEGRA210_CLK_PLL_A_OUT0_OUT_ADSP 324
include/dt-bindings/clock/x1000-cgu.h+36−28
@@ -12,33 +12,41 @@ · 11 unmodified lines
1212 #ifndef __DT_BINDINGS_CLOCK_X1000_CGU_H__
1313 #define __DT_BINDINGS_CLOCK_X1000_CGU_H__
1414
15−#define X1000_CLK_EXCLK 0
16−#define X1000_CLK_RTCLK 1
17−#define X1000_CLK_APLL 2
18−#define X1000_CLK_MPLL 3
19−#define X1000_CLK_SCLKA 4
20−#define X1000_CLK_CPUMUX 5
21−#define X1000_CLK_CPU 6
22−#define X1000_CLK_L2CACHE 7
23−#define X1000_CLK_AHB0 8
24−#define X1000_CLK_AHB2PMUX 9
25−#define X1000_CLK_AHB2 10
26−#define X1000_CLK_PCLK 11
27−#define X1000_CLK_DDR 12
28−#define X1000_CLK_MAC 13
29−#define X1000_CLK_MSCMUX 14
30−#define X1000_CLK_MSC0 15
31−#define X1000_CLK_MSC1 16
32−#define X1000_CLK_SSIPLL 17
33−#define X1000_CLK_SSIMUX 18
34−#define X1000_CLK_SFC 19
35−#define X1000_CLK_I2C0 20
36−#define X1000_CLK_I2C1 21
37−#define X1000_CLK_I2C2 22
38−#define X1000_CLK_UART0 23
39−#define X1000_CLK_UART1 24
40−#define X1000_CLK_UART2 25
41−#define X1000_CLK_SSI 26
42−#define X1000_CLK_PDMA 27
15+#define X1000_CLK_EXCLK 0
16+#define X1000_CLK_RTCLK 1
17+#define X1000_CLK_APLL 2
18+#define X1000_CLK_MPLL 3
19+#define X1000_CLK_OTGPHY 4
20+#define X1000_CLK_SCLKA 5
21+#define X1000_CLK_CPUMUX 6
22+#define X1000_CLK_CPU 7
23+#define X1000_CLK_L2CACHE 8
24+#define X1000_CLK_AHB0 9
25+#define X1000_CLK_AHB2PMUX 10
26+#define X1000_CLK_AHB2 11
27+#define X1000_CLK_PCLK 12
28+#define X1000_CLK_DDR 13
29+#define X1000_CLK_MAC 14
30+#define X1000_CLK_LCD 15
31+#define X1000_CLK_MSCMUX 16
32+#define X1000_CLK_MSC0 17
33+#define X1000_CLK_MSC1 18
34+#define X1000_CLK_OTG 19
35+#define X1000_CLK_SSIPLL 20
36+#define X1000_CLK_SSIPLL_DIV2 21
37+#define X1000_CLK_SSIMUX 22
38+#define X1000_CLK_EMC 23
39+#define X1000_CLK_EFUSE 24
40+#define X1000_CLK_SFC 25
41+#define X1000_CLK_I2C0 26
42+#define X1000_CLK_I2C1 27
43+#define X1000_CLK_I2C2 28
44+#define X1000_CLK_UART0 29
45+#define X1000_CLK_UART1 30
46+#define X1000_CLK_UART2 31
47+#define X1000_CLK_TCU 32
48+#define X1000_CLK_SSI 33
49+#define X1000_CLK_OST 34
50+#define X1000_CLK_PDMA 35
4351
4452 #endif /* __DT_BINDINGS_CLOCK_X1000_CGU_H__ */
include/dt-bindings/clock/x1830-cgu.h+55−0
@@ -0,0 +1,55 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+/*
3+ * This header provides clock numbers for the ingenic,x1830-cgu DT binding.
4+ *
5+ * They are roughly ordered as:
6+ * - external clocks
7+ * - PLLs
8+ * - muxes/dividers in the order they appear in the x1830 programmers manual
9+ * - gates in order of their bit in the CLKGR* registers
10+ */
11+
12+#ifndef __DT_BINDINGS_CLOCK_X1830_CGU_H__
13+#define __DT_BINDINGS_CLOCK_X1830_CGU_H__
14+
15+#define X1830_CLK_EXCLK 0
16+#define X1830_CLK_RTCLK 1
17+#define X1830_CLK_APLL 2
18+#define X1830_CLK_MPLL 3
19+#define X1830_CLK_EPLL 4
20+#define X1830_CLK_VPLL 5
21+#define X1830_CLK_OTGPHY 6
22+#define X1830_CLK_SCLKA 7
23+#define X1830_CLK_CPUMUX 8
24+#define X1830_CLK_CPU 9
25+#define X1830_CLK_L2CACHE 10
26+#define X1830_CLK_AHB0 11
27+#define X1830_CLK_AHB2PMUX 12
28+#define X1830_CLK_AHB2 13
29+#define X1830_CLK_PCLK 14
30+#define X1830_CLK_DDR 15
31+#define X1830_CLK_MAC 16
32+#define X1830_CLK_LCD 17
33+#define X1830_CLK_MSCMUX 18
34+#define X1830_CLK_MSC0 19
35+#define X1830_CLK_MSC1 20
36+#define X1830_CLK_SSIPLL 21
37+#define X1830_CLK_SSIPLL_DIV2 22
38+#define X1830_CLK_SSIMUX 23
39+#define X1830_CLK_EMC 24
40+#define X1830_CLK_EFUSE 25
41+#define X1830_CLK_OTG 26
42+#define X1830_CLK_SSI0 27
43+#define X1830_CLK_SMB0 28
44+#define X1830_CLK_SMB1 29
45+#define X1830_CLK_SMB2 30
46+#define X1830_CLK_UART0 31
47+#define X1830_CLK_UART1 32
48+#define X1830_CLK_SSI1 33
49+#define X1830_CLK_SFC 34
50+#define X1830_CLK_PDMA 35
51+#define X1830_CLK_TCU 36
52+#define X1830_CLK_DTRNG 37
53+#define X1830_CLK_OST 38
54+
55+#endif /* __DT_BINDINGS_CLOCK_X1830_CGU_H__ */
include/dt-bindings/power/marvell,mmp2.h+11−0
@@ -0,0 +1,11 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+#ifndef __DTS_MARVELL_MMP2_POWER_H
3+#define __DTS_MARVELL_MMP2_POWER_H
4+
5+#define MMP2_POWER_DOMAIN_GPU 0
6+#define MMP2_POWER_DOMAIN_AUDIO 1
7+#define MMP3_POWER_DOMAIN_CAMERA 2
8+
9+#define MMP2_NR_POWER_DOMAINS 3
10+
11+#endif
include/dt-bindings/reset/bt1-ccu.h+25−0
@@ -0,0 +1,25 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
4+ *
5+ * Baikal-T1 CCU reset indices
6+ */
7+#ifndef __DT_BINDINGS_RESET_BT1_CCU_H
8+#define __DT_BINDINGS_RESET_BT1_CCU_H
9+
10+#define CCU_AXI_MAIN_RST 0
11+#define CCU_AXI_DDR_RST 1
12+#define CCU_AXI_SATA_RST 2
13+#define CCU_AXI_GMAC0_RST 3
14+#define CCU_AXI_GMAC1_RST 4
15+#define CCU_AXI_XGMAC_RST 5
16+#define CCU_AXI_PCIE_M_RST 6
17+#define CCU_AXI_PCIE_S_RST 7
18+#define CCU_AXI_USB_RST 8
19+#define CCU_AXI_HWA_RST 9
20+#define CCU_AXI_SRAM_RST 10
21+
22+#define CCU_SYS_SATA_REF_RST 0
23+#define CCU_SYS_APB_RST 1
24+
25+#endif /* __DT_BINDINGS_RESET_BT1_CCU_H */
include/dt-bindings/reset/qcom,gcc-msm8939.h+110−0
@@ -0,0 +1,110 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright 2020 Linaro Limited
4+ */
5+
6+#ifndef _DT_BINDINGS_RESET_MSM_GCC_8939_H
7+#define _DT_BINDINGS_RESET_MSM_GCC_8939_H
8+
9+#define GCC_BLSP1_BCR 0
10+#define GCC_BLSP1_QUP1_BCR 1
11+#define GCC_BLSP1_UART1_BCR 2
12+#define GCC_BLSP1_QUP2_BCR 3
13+#define GCC_BLSP1_UART2_BCR 4
14+#define GCC_BLSP1_QUP3_BCR 5
15+#define GCC_BLSP1_QUP4_BCR 6
16+#define GCC_BLSP1_QUP5_BCR 7
17+#define GCC_BLSP1_QUP6_BCR 8
18+#define GCC_IMEM_BCR 9
19+#define GCC_SMMU_BCR 10
20+#define GCC_APSS_TCU_BCR 11
21+#define GCC_SMMU_XPU_BCR 12
22+#define GCC_PCNOC_TBU_BCR 13
23+#define GCC_PRNG_BCR 14
24+#define GCC_BOOT_ROM_BCR 15
25+#define GCC_CRYPTO_BCR 16
26+#define GCC_SEC_CTRL_BCR 17
27+#define GCC_AUDIO_CORE_BCR 18
28+#define GCC_ULT_AUDIO_BCR 19
29+#define GCC_DEHR_BCR 20
30+#define GCC_SYSTEM_NOC_BCR 21
31+#define GCC_PCNOC_BCR 22
32+#define GCC_TCSR_BCR 23
33+#define GCC_QDSS_BCR 24
34+#define GCC_DCD_BCR 25
35+#define GCC_MSG_RAM_BCR 26
36+#define GCC_MPM_BCR 27
37+#define GCC_SPMI_BCR 28
38+#define GCC_SPDM_BCR 29
39+#define GCC_MM_SPDM_BCR 30
40+#define GCC_BIMC_BCR 31
41+#define GCC_RBCPR_BCR 32
42+#define GCC_TLMM_BCR 33
43+#define GCC_USB_HS_BCR 34
44+#define GCC_USB2A_PHY_BCR 35
45+#define GCC_SDCC1_BCR 36
46+#define GCC_SDCC2_BCR 37
47+#define GCC_PDM_BCR 38
48+#define GCC_SNOC_BUS_TIMEOUT0_BCR 39
49+#define GCC_PCNOC_BUS_TIMEOUT0_BCR 40
50+#define GCC_PCNOC_BUS_TIMEOUT1_BCR 41
51+#define GCC_PCNOC_BUS_TIMEOUT2_BCR 42
52+#define GCC_PCNOC_BUS_TIMEOUT3_BCR 43
53+#define GCC_PCNOC_BUS_TIMEOUT4_BCR 44
54+#define GCC_PCNOC_BUS_TIMEOUT5_BCR 45
55+#define GCC_PCNOC_BUS_TIMEOUT6_BCR 46
56+#define GCC_PCNOC_BUS_TIMEOUT7_BCR 47
57+#define GCC_PCNOC_BUS_TIMEOUT8_BCR 48
58+#define GCC_PCNOC_BUS_TIMEOUT9_BCR 49
59+#define GCC_MMSS_BCR 50
60+#define GCC_VENUS0_BCR 51
61+#define GCC_MDSS_BCR 52
62+#define GCC_CAMSS_PHY0_BCR 53
63+#define GCC_CAMSS_CSI0_BCR 54
64+#define GCC_CAMSS_CSI0PHY_BCR 55
65+#define GCC_CAMSS_CSI0RDI_BCR 56
66+#define GCC_CAMSS_CSI0PIX_BCR 57
67+#define GCC_CAMSS_PHY1_BCR 58
68+#define GCC_CAMSS_CSI1_BCR 59
69+#define GCC_CAMSS_CSI1PHY_BCR 60
70+#define GCC_CAMSS_CSI1RDI_BCR 61
71+#define GCC_CAMSS_CSI1PIX_BCR 62
72+#define GCC_CAMSS_ISPIF_BCR 63
73+#define GCC_CAMSS_CCI_BCR 64
74+#define GCC_CAMSS_MCLK0_BCR 65
75+#define GCC_CAMSS_MCLK1_BCR 66
76+#define GCC_CAMSS_GP0_BCR 67
77+#define GCC_CAMSS_GP1_BCR 68
78+#define GCC_CAMSS_TOP_BCR 69
79+#define GCC_CAMSS_MICRO_BCR 70
80+#define GCC_CAMSS_JPEG_BCR 71
81+#define GCC_CAMSS_VFE_BCR 72
82+#define GCC_CAMSS_CSI_VFE0_BCR 73
83+#define GCC_OXILI_BCR 74
84+#define GCC_GMEM_BCR 75
85+#define GCC_CAMSS_AHB_BCR 76
86+#define GCC_MDP_TBU_BCR 77
87+#define GCC_GFX_TBU_BCR 78
88+#define GCC_GFX_TCU_BCR 79
89+#define GCC_MSS_TBU_AXI_BCR 80
90+#define GCC_MSS_TBU_GSS_AXI_BCR 81
91+#define GCC_MSS_TBU_Q6_AXI_BCR 82
92+#define GCC_GTCU_AHB_BCR 83
93+#define GCC_SMMU_CFG_BCR 84
94+#define GCC_VFE_TBU_BCR 85
95+#define GCC_VENUS_TBU_BCR 86
96+#define GCC_JPEG_TBU_BCR 87
97+#define GCC_PRONTO_TBU_BCR 88
98+#define GCC_SMMU_CATS_BCR 89
99+#define GCC_BLSP1_UART3_BCR 90
100+#define GCC_CAMSS_CSI2_BCR 91
101+#define GCC_CAMSS_CSI2PHY_BCR 92
102+#define GCC_CAMSS_CSI2RDI_BCR 93
103+#define GCC_CAMSS_CSI2PIX_BCR 94
104+#define GCC_USB_FS_BCR 95
105+#define GCC_BLSP1_QUP4_SPI_APPS_CBCR 96
106+#define GCC_CAMSS_MCLK2_BCR 97
107+#define GCC_CPP_TBU_BCR 98
108+#define GCC_MDP_RT_TBU_BCR 99
109+
110+#endif
include/linux/clk/tegra.h+27−0
@@ -131,6 +131,9 @@ extern void tegra210_set_sata_pll_seq_sw(bool state); · 130 unmodified lines
131131 extern void tegra210_put_utmipll_in_iddq(void);
132132 extern void tegra210_put_utmipll_out_iddq(void);
133133 extern int tegra210_clk_handle_mbist_war(unsigned int id);
134+extern void tegra210_clk_emc_dll_enable(bool flag);
135+extern void tegra210_clk_emc_dll_update_setting(u32 emc_dll_src_value);
136+extern void tegra210_clk_emc_update_setting(u32 emc_src_value);
134137
135138 struct clk;
136139
@@ -143,4 +146,28 @@ void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb, · 6 unmodified lines
143146 void *cb_arg);
144147 int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same);
145148
149+struct tegra210_clk_emc_config {
150+ unsigned long rate;
151+ bool same_freq;
152+ u32 value;
153+
154+ unsigned long parent_rate;
155+ u8 parent;
156+};
157+
158+struct tegra210_clk_emc_provider {
159+ struct module *owner;
160+ struct device *dev;
161+
162+ struct tegra210_clk_emc_config *configs;
163+ unsigned int num_configs;
164+
165+ int (*set_rate)(struct device *dev,
166+ const struct tegra210_clk_emc_config *config);
167+};
168+
169+int tegra210_clk_emc_attach(struct clk *clk,

4 more lines aren’t shown here.

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