aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-14 11:46:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-14 11:46:17 -0400
commitdc2535be1fd547fbd56aff091370280007b0a1af (patch)
tree32925778081ed71e19684d8cb459e07890f0e62c
parentfa3d493f7a573b4e4e2538486e912093a0161c1b (diff)
parent010d5166bbe95523e8584f3caca9f1bbeac9ea6e (diff)
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk subsystem updates from Stephen Boyd: "We have a fairly balanced mix of clk driver updates and clk framework updates this time around. It's the usual pile of new drivers for new hardware out there and the normal small fixes and updates, but then we have some core framework changes too. In the core framework, we introduce support for a clk_get_optional() API to get clks that may not always be populated and a way to devm manage clkdev lookups registered by provider drivers. We also do some refactoring to simplify the interface between clkdev and the common clk framework so we can reuse the DT parsing and clk_get() path in provider drivers in the future. This work will continue in the next few cycles while we convert how providers specify clk parents. On the driver side, the biggest part of the dirstat is the Amlogic clk driver that got support for the G12A SoC. It dominates with almost half the overall diff, while the second largest part of the diff is in the i.MX clk driver that gained support for imx8mm SoCs. After that, we have the Actions Semiconductor and Qualcomm drivers rounding out the big part of the dirstat because they both got new hardware support for SoCs. The rest is just various updates and non-critical fixes for existing drivers. Core: - Convert a few clk bindings to JSON schema format - Add a {devm_}clk_get_optional() API - Add devm_clk_hw_register_clkdev() API to manage clkdev lookups - Start rewriting clk parent registration and supporting device links by moving around code that supports clk_get() and DT parsing of the 'clocks' property New Drivers: - Add Qualcomm MSM8998 RPM managed clks - IPA clk support on Qualcomm RPMh clk controllers - Actions Semi S500 SoC clk support - Support for fixed rate clks populated from an MMIO register - Add RPC (QSPI/HyperFLASH) clocks on Renesas R-Car V3H - Add TMU (timer) clocks on Renesas RZ/G2E - Add Amlogic G12A Always-On Clock Controller - Add 32k clock generation for Amlogic AXG - Add support for the Mali GPU clocks on Amlogic Meson8 - Add Amlogic G12A EE clock controller driver - Add missing CANFD clocks on Renesas RZ/G2M and RZ/G2E - Add i.MX8MM SoC clk driver support Removed Drivers: - Remove clps711x driver as the board support is gone Updates: - 3rd ECO fix for Mediatek MT2712 SoCs - Updates for Qualcomm MSM8998 GCC clks - Random static analysis fixes for clk drivers - Support for sleeping gpios in the clk-gpio type - Minor fixes for STM32MP1 clk driver (parents, critical flag, etc.) - Split LCDC into two clks on the Marvell MMP2 SoC - Various DT of_node refcount fixes - Get rid of CLK_IS_BASIC from TI code (yay!) - TI Autoidle clk support - Fix Amlogic Meson8 APB clock ID name - Claim input clocks through DT for Amlogic AXG and GXBB - Correct the DU (display unit) parent clock on Renesas RZ/G2E - Exynos5433 IMEM CMU crypto clk support (SlimSS) - Fix for the PLL-MIPI on the Allwinner A23 - Fix Rockchip rk3328 PLL rate calculation - Add SET_RATE_PARENT flag on display clk of Rockhip rk3066 - i.MX SCU clk driver clk_set_parent() and cpufreq support" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (150 commits) dt-bindings: clock: imx8mq: Fix numbering overlaps and gaps clk: ti: clkctrl: Fix clkdm_name regression for TI_CLK_CLKCTRL_COMPAT clk: fixup default index for of_clk_get_by_name() clk: Move of_clk_*() APIs into clk.c from clkdev.c clk: Inform the core about consumer devices clk: Introduce of_clk_get_hw_from_clkspec() clk: core: clarify the check for runtime PM clk: Combine __clk_get() and __clk_create_clk() clk: imx8mq: add GPIO clocks to clock tree clk: mediatek: correct cpu clock name for MT8173 SoC clk: imx: Refactor entire sccg pll clk clk: imx: scu: add cpu frequency scaling support clk: mediatek: Mark bus and DRAM related clocks as critical clk: mediatek: Add flags to mtk_gate clk: mediatek: Add MUX_FLAGS macro clk: qcom: gcc-sdm845: Define parent of PCIe PIPE clocks clk: ingenic: Remove set but not used variable 'enable' clk: at91: programmable: remove unneeded register read clk: mediatek: using CLK_MUX_ROUND_CLOSEST for the clock of dpi1_sel clk: mediatek: add MUX_GATE_FLAGS_2 ...
-rw-r--r--Documentation/devicetree/bindings/clock/actions,owl-cmu.txt7
-rw-r--r--Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt1
-rw-r--r--Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt1
-rw-r--r--Documentation/devicetree/bindings/clock/exynos5433-clock.txt23
-rw-r--r--Documentation/devicetree/bindings/clock/fixed-clock.txt23
-rw-r--r--Documentation/devicetree/bindings/clock/fixed-clock.yaml44
-rw-r--r--Documentation/devicetree/bindings/clock/fixed-factor-clock.txt28
-rw-r--r--Documentation/devicetree/bindings/clock/fixed-factor-clock.yaml56
-rw-r--r--Documentation/devicetree/bindings/clock/fixed-mmio-clock.txt24
-rw-r--r--Documentation/devicetree/bindings/clock/imx8mm-clock.txt29
-rw-r--r--Documentation/devicetree/bindings/clock/qcom,rpmcc.txt1
-rw-r--r--Documentation/driver-model/devres.txt2
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c16
-rw-r--r--drivers/acpi/acpi_lpss.c2
-rw-r--r--drivers/clk/Kconfig6
-rw-r--r--drivers/clk/Makefile3
-rw-r--r--drivers/clk/actions/Kconfig5
-rw-r--r--drivers/clk/actions/Makefile1
-rw-r--r--drivers/clk/actions/owl-pll.c2
-rw-r--r--drivers/clk/actions/owl-pll.h30
-rw-r--r--drivers/clk/actions/owl-s500.c525
-rw-r--r--drivers/clk/at91/clk-audio-pll.c9
-rw-r--r--drivers/clk/at91/clk-programmable.c3
-rw-r--r--drivers/clk/at91/sama5d2.c3
-rw-r--r--drivers/clk/clk-clps711x.c61
-rw-r--r--drivers/clk/clk-devres.c11
-rw-r--r--drivers/clk/clk-fixed-mmio.c101
-rw-r--r--drivers/clk/clk-fractional-divider.c2
-rw-r--r--drivers/clk/clk-gpio.c39
-rw-r--r--drivers/clk/clk-highbank.c1
-rw-r--r--drivers/clk/clk-max77686.c28
-rw-r--r--drivers/clk/clk-qoriq.c5
-rw-r--r--drivers/clk/clk-stm32mp1.c37
-rw-r--r--drivers/clk/clk-twl6040.c53
-rw-r--r--drivers/clk/clk.c262
-rw-r--r--drivers/clk/clk.h23
-rw-r--r--drivers/clk/clkdev.c231
-rw-r--r--drivers/clk/imx/Kconfig6
-rw-r--r--drivers/clk/imx/Makefile4
-rw-r--r--drivers/clk/imx/clk-composite-8m.c2
-rw-r--r--drivers/clk/imx/clk-imx51-imx53.c1
-rw-r--r--drivers/clk/imx/clk-imx6q.c1
-rw-r--r--drivers/clk/imx/clk-imx6sx.c1
-rw-r--r--drivers/clk/imx/clk-imx7d.c1
-rw-r--r--drivers/clk/imx/clk-imx7ulp.c16
-rw-r--r--drivers/clk/imx/clk-imx8mm.c675
-rw-r--r--drivers/clk/imx/clk-imx8mq.c254
-rw-r--r--drivers/clk/imx/clk-imx8qxp.c1
-rw-r--r--drivers/clk/imx/clk-pll14xx.c392
-rw-r--r--drivers/clk/imx/clk-sccg-pll.c514
-rw-r--r--drivers/clk/imx/clk-scu.c123
-rw-r--r--drivers/clk/imx/clk-scu.h16
-rw-r--r--drivers/clk/imx/clk-vf610.c1
-rw-r--r--drivers/clk/imx/clk.h38
-rw-r--r--drivers/clk/ingenic/cgu.c13
-rw-r--r--drivers/clk/ingenic/cgu.h2
-rw-r--r--drivers/clk/ingenic/jz4740-cgu.c2
-rw-r--r--drivers/clk/mediatek/clk-gate.c4
-rw-r--r--drivers/clk/mediatek/clk-gate.h3
-rw-r--r--drivers/clk/mediatek/clk-mt2701.c4
-rw-r--r--drivers/clk/mediatek/clk-mt2712.c9
-rw-r--r--drivers/clk/mediatek/clk-mt6797.c68
-rw-r--r--drivers/clk/mediatek/clk-mt8173.c4
-rw-r--r--drivers/clk/mediatek/clk-mtk.c4
-rw-r--r--drivers/clk/mediatek/clk-mtk.h29
-rw-r--r--drivers/clk/meson/Kconfig101
-rw-r--r--drivers/clk/meson/Makefile29
-rw-r--r--drivers/clk/meson/axg-aoclk.c193
-rw-r--r--drivers/clk/meson/axg-aoclk.h13
-rw-r--r--drivers/clk/meson/axg-audio.c5
-rw-r--r--drivers/clk/meson/axg.c69
-rw-r--r--drivers/clk/meson/clk-dualdiv.c138
-rw-r--r--drivers/clk/meson/clk-dualdiv.h33
-rw-r--r--drivers/clk/meson/clk-input.c7
-rw-r--r--drivers/clk/meson/clk-input.h19
-rw-r--r--drivers/clk/meson/clk-mpll.c12
-rw-r--r--drivers/clk/meson/clk-mpll.h30
-rw-r--r--drivers/clk/meson/clk-phase.c75
-rw-r--r--drivers/clk/meson/clk-phase.h26
-rw-r--r--drivers/clk/meson/clk-pll.c216
-rw-r--r--drivers/clk/meson/clk-pll.h49
-rw-r--r--drivers/clk/meson/clk-regmap.c5
-rw-r--r--drivers/clk/meson/clk-regmap.h20
-rw-r--r--drivers/clk/meson/clk-triphase.c68
-rw-r--r--drivers/clk/meson/clkc.h127
-rw-r--r--drivers/clk/meson/g12a-aoclk.c454
-rw-r--r--drivers/clk/meson/g12a-aoclk.h34
-rw-r--r--drivers/clk/meson/g12a.c2359
-rw-r--r--drivers/clk/meson/g12a.h175
-rw-r--r--drivers/clk/meson/gxbb-aoclk-32k.c193
-rw-r--r--drivers/clk/meson/gxbb-aoclk.c268
-rw-r--r--drivers/clk/meson/gxbb-aoclk.h20
-rw-r--r--drivers/clk/meson/gxbb.c296
-rw-r--r--drivers/clk/meson/meson-aoclk.c54
-rw-r--r--drivers/clk/meson/meson-aoclk.h13
-rw-r--r--drivers/clk/meson/meson-eeclk.c63
-rw-r--r--drivers/clk/meson/meson-eeclk.h25
-rw-r--r--drivers/clk/meson/meson8b.c374
-rw-r--r--drivers/clk/meson/meson8b.h11
-rw-r--r--drivers/clk/meson/parm.h46
-rw-r--r--drivers/clk/meson/sclk-div.c10
-rw-r--r--drivers/clk/meson/sclk-div.h (renamed from drivers/clk/meson/clkc-audio.h)16
-rw-r--r--drivers/clk/meson/vid-pll-div.c10
-rw-r--r--drivers/clk/meson/vid-pll-div.h20
-rw-r--r--drivers/clk/mmp/clk-of-mmp2.c5
-rw-r--r--drivers/clk/mvebu/armada-370.c4
-rw-r--r--drivers/clk/mvebu/armada-xp.c4
-rw-r--r--drivers/clk/mvebu/dove.c8
-rw-r--r--drivers/clk/mvebu/kirkwood.c2
-rw-r--r--drivers/clk/mvebu/mv98dx3236.c4
-rw-r--r--drivers/clk/qcom/clk-rcg.h5
-rw-r--r--drivers/clk/qcom/clk-rcg2.c24
-rw-r--r--drivers/clk/qcom/clk-rpmh.c146
-rw-r--r--drivers/clk/qcom/clk-smd-rpm.c63
-rw-r--r--drivers/clk/qcom/common.c8
-rw-r--r--drivers/clk/qcom/common.h2
-rw-r--r--drivers/clk/qcom/gcc-ipq8074.c10
-rw-r--r--drivers/clk/qcom/gcc-mdm9615.c11
-rw-r--r--drivers/clk/qcom/gcc-msm8996.c10
-rw-r--r--drivers/clk/qcom/gcc-msm8998.c61
-rw-r--r--drivers/clk/qcom/gcc-qcs404.c10
-rw-r--r--drivers/clk/qcom/gcc-sdm660.c11
-rw-r--r--drivers/clk/qcom/gcc-sdm845.c5
-rw-r--r--drivers/clk/qcom/mmcc-msm8996.c10
-rw-r--r--drivers/clk/renesas/r8a774a1-cpg-mssr.c4
-rw-r--r--drivers/clk/renesas/r8a774c0-cpg-mssr.c15
-rw-r--r--drivers/clk/renesas/r8a77980-cpg-mssr.c8
-rw-r--r--drivers/clk/renesas/rcar-gen3-cpg.c147
-rw-r--r--drivers/clk/renesas/rcar-gen3-cpg.h4
-rw-r--r--drivers/clk/rockchip/clk-rk3188.c4
-rw-r--r--drivers/clk/rockchip/clk-rk3328.c12
-rw-r--r--drivers/clk/samsung/clk-exynos4.c1
-rw-r--r--drivers/clk/samsung/clk-exynos5-subcmu.c13
-rw-r--r--drivers/clk/samsung/clk-exynos5433.c38
-rw-r--r--drivers/clk/samsung/clk-s3c2443.c2
-rw-r--r--drivers/clk/samsung/clk.h2
-rw-r--r--drivers/clk/socfpga/clk-gate.c22
-rw-r--r--drivers/clk/socfpga/clk-pll-a10.c1
-rw-r--r--drivers/clk/socfpga/clk-pll.c1
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-a23.c2
-rw-r--r--drivers/clk/tegra/clk-dfll.c18
-rw-r--r--drivers/clk/ti/adpll.c2
-rw-r--r--drivers/clk/ti/apll.c4
-rw-r--r--drivers/clk/ti/autoidle.c101
-rw-r--r--drivers/clk/ti/clk.c80
-rw-r--r--drivers/clk/ti/clkctrl.c4
-rw-r--r--drivers/clk/ti/clock.h5
-rw-r--r--drivers/clk/ti/clockdomain.c2
-rw-r--r--drivers/clk/ti/divider.c2
-rw-r--r--drivers/clk/ti/dpll.c11
-rw-r--r--drivers/clk/ti/dpll3xxx.c2
-rw-r--r--drivers/clk/ti/gate.c2
-rw-r--r--drivers/clk/ti/interface.c4
-rw-r--r--drivers/clk/ti/mux.c2
-rw-r--r--drivers/clk/uniphier/clk-uniphier-cpugear.c2
-rw-r--r--drivers/clk/x86/clk-lpt.c2
-rw-r--r--drivers/clk/x86/clk-st.c3
-rw-r--r--include/dt-bindings/clock/actions,s500-cmu.h78
-rw-r--r--include/dt-bindings/clock/axg-aoclkc.h7
-rw-r--r--include/dt-bindings/clock/exynos5433.h8
-rw-r--r--include/dt-bindings/clock/g12a-aoclkc.h34
-rw-r--r--include/dt-bindings/clock/g12a-clkc.h135
-rw-r--r--include/dt-bindings/clock/gxbb-aoclkc.h7
-rw-r--r--include/dt-bindings/clock/imx5-clock.h3
-rw-r--r--include/dt-bindings/clock/imx8mm-clock.h244
-rw-r--r--include/dt-bindings/clock/imx8mq-clock.h215
-rw-r--r--include/dt-bindings/clock/marvell,mmp2.h1
-rw-r--r--include/dt-bindings/clock/meson8b-clkc.h1
-rw-r--r--include/dt-bindings/clock/mt2712-clk.h3
-rw-r--r--include/dt-bindings/clock/mt8173-clk.h3
-rw-r--r--include/dt-bindings/clock/qcom,rpmcc.h10
-rw-r--r--include/dt-bindings/clock/qcom,rpmh.h1
-rw-r--r--include/dt-bindings/clock/r8a774a1-cpg-mssr.h1
-rw-r--r--include/dt-bindings/clock/r8a774c0-cpg-mssr.h1
-rw-r--r--include/dt-bindings/clock/stm32mp1-clks.h3
-rw-r--r--include/dt-bindings/reset/g12a-aoclkc.h18
-rw-r--r--include/linux/clk-provider.h3
-rw-r--r--include/linux/clk.h36
-rw-r--r--include/linux/clk/ti.h1
-rw-r--r--include/linux/clkdev.h4
-rw-r--r--include/linux/platform_data/x86/clk-lpss.h (renamed from include/linux/platform_data/clk-lpss.h)0
181 files changed, 9562 insertions, 1742 deletions
diff --git a/Documentation/devicetree/bindings/clock/actions,owl-cmu.txt b/Documentation/devicetree/bindings/clock/actions,owl-cmu.txt
index 2ef86ae96df8..d19885b7c73f 100644
--- a/Documentation/devicetree/bindings/clock/actions,owl-cmu.txt
+++ b/Documentation/devicetree/bindings/clock/actions,owl-cmu.txt
@@ -2,13 +2,14 @@
2 2
3The Actions Semi Owl Clock Management Unit generates and supplies clock 3The Actions Semi Owl Clock Management Unit generates and supplies clock
4to various controllers within the SoC. The clock binding described here is 4to various controllers within the SoC. The clock binding described here is
5applicable to S900 and S700 SoC's. 5applicable to S900, S700 and S500 SoC's.
6 6
7Required Properties: 7Required Properties:
8 8
9- compatible: should be one of the following, 9- compatible: should be one of the following,
10 "actions,s900-cmu" 10 "actions,s900-cmu"
11 "actions,s700-cmu" 11 "actions,s700-cmu"
12 "actions,s500-cmu"
12- reg: physical base address of the controller and length of memory mapped 13- reg: physical base address of the controller and length of memory mapped
13 region. 14 region.
14- clocks: Reference to the parent clocks ("hosc", "losc") 15- clocks: Reference to the parent clocks ("hosc", "losc")
@@ -19,8 +20,8 @@ Each clock is assigned an identifier, and client nodes can use this identifier
19to specify the clock which they consume. 20to specify the clock which they consume.
20 21
21All available clocks are defined as preprocessor macros in corresponding 22All available clocks are defined as preprocessor macros in corresponding
22dt-bindings/clock/actions,s900-cmu.h or actions,s700-cmu.h header and can be 23dt-bindings/clock/actions,s900-cmu.h or actions,s700-cmu.h or
23used in device tree sources. 24actions,s500-cmu.h header and can be used in device tree sources.
24 25
25External clocks: 26External clocks:
26 27
diff --git a/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt
index 79511d7bb321..c41f0be5d438 100644
--- a/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt
+++ b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt
@@ -10,6 +10,7 @@ Required Properties:
10 - GXL (S905X, S905D) : "amlogic,meson-gxl-aoclkc" 10 - GXL (S905X, S905D) : "amlogic,meson-gxl-aoclkc"
11 - GXM (S912) : "amlogic,meson-gxm-aoclkc" 11 - GXM (S912) : "amlogic,meson-gxm-aoclkc"
12 - AXG (A113D, A113X) : "amlogic,meson-axg-aoclkc" 12 - AXG (A113D, A113X) : "amlogic,meson-axg-aoclkc"
13 - G12A (S905X2, S905D2, S905Y2) : "amlogic,meson-g12a-aoclkc"
13 followed by the common "amlogic,meson-gx-aoclkc" 14 followed by the common "amlogic,meson-gx-aoclkc"
14- clocks: list of clock phandle, one for each entry clock-names. 15- clocks: list of clock phandle, one for each entry clock-names.
15- clock-names: should contain the following: 16- clock-names: should contain the following:
diff --git a/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt
index a6871953bf04..5c8b105be4d6 100644
--- a/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt
+++ b/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt
@@ -9,6 +9,7 @@ Required Properties:
9 "amlogic,gxbb-clkc" for GXBB SoC, 9 "amlogic,gxbb-clkc" for GXBB SoC,
10 "amlogic,gxl-clkc" for GXL and GXM SoC, 10 "amlogic,gxl-clkc" for GXL and GXM SoC,
11 "amlogic,axg-clkc" for AXG SoC. 11 "amlogic,axg-clkc" for AXG SoC.
12 "amlogic,g12a-clkc" for G12A SoC.
12- clocks : list of clock phandle, one for each entry clock-names. 13- clocks : list of clock phandle, one for each entry clock-names.
13- clock-names : should contain the following: 14- clock-names : should contain the following:
14 * "xtal": the platform xtal 15 * "xtal": the platform xtal
diff --git a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt
index 50d5897c9849..183c327a7d6b 100644
--- a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt
+++ b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt
@@ -50,6 +50,8 @@ Required Properties:
50 IPs. 50 IPs.
51 - "samsung,exynos5433-cmu-cam1" - clock controller compatible for CMU_CAM1 51 - "samsung,exynos5433-cmu-cam1" - clock controller compatible for CMU_CAM1
52 which generates clocks for Cortex-A5/MIPI_CSIS2/FIMC-LITE_C/FIMC-FD IPs. 52 which generates clocks for Cortex-A5/MIPI_CSIS2/FIMC-LITE_C/FIMC-FD IPs.
53 - "samsung,exynos5433-cmu-imem" - clock controller compatible for CMU_IMEM
54 which generates clocks for SSS (Security SubSystem) and SlimSSS IPs.
53 55
54- reg: physical base address of the controller and length of memory mapped 56- reg: physical base address of the controller and length of memory mapped
55 region. 57 region.
@@ -168,6 +170,12 @@ Required Properties:
168 - aclk_cam1_400 170 - aclk_cam1_400
169 - aclk_cam1_552 171 - aclk_cam1_552
170 172
173 Input clocks for imem clock controller:
174 - oscclk
175 - aclk_imem_sssx_266
176 - aclk_imem_266
177 - aclk_imem_200
178
171Optional properties: 179Optional properties:
172 - power-domains: a phandle to respective power domain node as described by 180 - power-domains: a phandle to respective power domain node as described by
173 generic PM domain bindings (see power/power_domain.txt for more 181 generic PM domain bindings (see power/power_domain.txt for more
@@ -469,6 +477,21 @@ Example 2: Examples of clock controller nodes are listed below.
469 power-domains = <&pd_cam1>; 477 power-domains = <&pd_cam1>;
470 }; 478 };
471 479
480 cmu_imem: clock-controller@11060000 {
481 compatible = "samsung,exynos5433-cmu-imem";
482 reg = <0x11060000 0x1000>;
483 #clock-cells = <1>;
484
485 clock-names = "oscclk",
486 "aclk_imem_sssx_266",
487 "aclk_imem_266",
488 "aclk_imem_200";
489 clocks = <&xxti>,
490 <&cmu_top CLK_DIV_ACLK_IMEM_SSSX_266>,
491 <&cmu_top CLK_DIV_ACLK_IMEM_266>,
492 <&cmu_top CLK_DIV_ACLK_IMEM_200>;
493 };
494
472Example 3: UART controller node that consumes the clock generated by the clock 495Example 3: UART controller node that consumes the clock generated by the clock
473 controller. 496 controller.
474 497
diff --git a/Documentation/devicetree/bindings/clock/fixed-clock.txt b/Documentation/devicetree/bindings/clock/fixed-clock.txt
deleted file mode 100644
index 0641a663ad69..000000000000
--- a/Documentation/devicetree/bindings/clock/fixed-clock.txt
+++ /dev/null
@@ -1,23 +0,0 @@
1Binding for simple fixed-rate clock sources.
2
3This binding uses the common clock binding[1].
4
5[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
6
7Required properties:
8- compatible : shall be "fixed-clock".
9- #clock-cells : from common clock binding; shall be set to 0.
10- clock-frequency : frequency of clock in Hz. Should be a single cell.
11
12Optional properties:
13- clock-accuracy : accuracy of clock in ppb (parts per billion).
14 Should be a single cell.
15- clock-output-names : From common clock binding.
16
17Example:
18 clock {
19 compatible = "fixed-clock";
20 #clock-cells = <0>;
21 clock-frequency = <1000000000>;
22 clock-accuracy = <100>;
23 };
diff --git a/Documentation/devicetree/bindings/clock/fixed-clock.yaml b/Documentation/devicetree/bindings/clock/fixed-clock.yaml
new file mode 100644
index 000000000000..b657ecd0ef1c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/fixed-clock.yaml
@@ -0,0 +1,44 @@
1# SPDX-License-Identifier: GPL-2.0
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/clock/fixed-clock.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Binding for simple fixed-rate clock sources
8
9maintainers:
10 - Michael Turquette <mturquette@baylibre.com>
11 - Stephen Boyd <sboyd@kernel.org>
12
13properties:
14 compatible:
15 const: fixed-clock
16
17 "#clock-cells":
18 const: 0
19
20 clock-frequency: true
21
22 clock-accuracy:
23 description: accuracy of clock in ppb (parts per billion).
24 $ref: /schemas/types.yaml#/definitions/uint32
25
26 clock-output-names:
27 maxItems: 1
28
29required:
30 - compatible
31 - "#clock-cells"
32 - clock-frequency
33
34additionalProperties: false
35
36examples:
37 - |
38 clock {
39 compatible = "fixed-clock";
40 #clock-cells = <0>;
41 clock-frequency = <1000000000>;
42 clock-accuracy = <100>;
43 };
44...
diff --git a/Documentation/devicetree/bindings/clock/fixed-factor-clock.txt b/Documentation/devicetree/bindings/clock/fixed-factor-clock.txt
deleted file mode 100644
index 189467a7188a..000000000000
--- a/Documentation/devicetree/bindings/clock/fixed-factor-clock.txt
+++ /dev/null
@@ -1,28 +0,0 @@
1Binding for simple fixed factor rate clock sources.
2
3This binding uses the common clock binding[1].
4
5[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
6
7Required properties:
8- compatible : shall be "fixed-factor-clock".
9- #clock-cells : from common clock binding; shall be set to 0.
10- clock-div: fixed divider.
11- clock-mult: fixed multiplier.
12- clocks: parent clock.
13
14Optional properties:
15- clock-output-names : From common clock binding.
16
17Some clocks that require special treatments are also handled by that
18driver, with the compatibles:
19 - allwinner,sun4i-a10-pll3-2x-clk
20
21Example:
22 clock {
23 compatible = "fixed-factor-clock";
24 clocks = <&parentclk>;
25 #clock-cells = <0>;
26 clock-div = <2>;
27 clock-mult = <1>;
28 };
diff --git a/Documentation/devicetree/bindings/clock/fixed-factor-clock.yaml b/Documentation/devicetree/bindings/clock/fixed-factor-clock.yaml
new file mode 100644
index 000000000000..b567f8092f8c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/fixed-factor-clock.yaml
@@ -0,0 +1,56 @@
1# SPDX-License-Identifier: GPL-2.0
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/clock/fixed-factor-clock.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Binding for simple fixed factor rate clock sources
8
9maintainers:
10 - Michael Turquette <mturquette@baylibre.com>
11 - Stephen Boyd <sboyd@kernel.org>
12
13properties:
14 compatible:
15 enum:
16 - allwinner,sun4i-a10-pll3-2x-clk
17 - fixed-factor-clock
18
19 "#clock-cells":
20 const: 0
21
22 clocks:
23 maxItems: 1
24
25 clock-div:
26 description: Fixed divider
27 allOf:
28 - $ref: /schemas/types.yaml#/definitions/uint32
29 - minimum: 1
30
31 clock-mult:
32 description: Fixed multiplier
33 $ref: /schemas/types.yaml#/definitions/uint32
34
35 clock-output-names:
36 maxItems: 1
37
38required:
39 - compatible
40 - clocks
41 - "#clock-cells"
42 - clock-div
43 - clock-mult
44
45additionalProperties: false
46
47examples:
48 - |
49 clock {
50 compatible = "fixed-factor-clock";
51 clocks = <&parentclk>;
52 #clock-cells = <0>;
53 clock-div = <2>;
54 clock-mult = <1>;
55 };
56...
diff --git a/Documentation/devicetree/bindings/clock/fixed-mmio-clock.txt b/Documentation/devicetree/bindings/clock/fixed-mmio-clock.txt
new file mode 100644
index 000000000000..c359367fd1a9
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/fixed-mmio-clock.txt
@@ -0,0 +1,24 @@
1Binding for simple memory mapped io fixed-rate clock sources.
2The driver reads a clock frequency value from a single 32-bit memory mapped
3I/O register and registers it as a fixed rate clock.
4
5It was designed for test systems, like FPGA, not for complete, finished SoCs.
6
7This binding uses the common clock binding[1].
8
9[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
10
11Required properties:
12- compatible : shall be "fixed-mmio-clock".
13- #clock-cells : from common clock binding; shall be set to 0.
14- reg : Address and length of the clock value register set.
15
16Optional properties:
17- clock-output-names : From common clock binding.
18
19Example:
20sysclock: sysclock@fd020004 {
21 #clock-cells = <0>;
22 compatible = "fixed-mmio-clock";
23 reg = <0xfd020004 0x4>;
24};
diff --git a/Documentation/devicetree/bindings/clock/imx8mm-clock.txt b/Documentation/devicetree/bindings/clock/imx8mm-clock.txt
new file mode 100644
index 000000000000..8e4ab9e619a1
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx8mm-clock.txt
@@ -0,0 +1,29 @@
1* Clock bindings for NXP i.MX8M Mini
2
3Required properties:
4- compatible: Should be "fsl,imx8mm-ccm"
5- reg: Address and length of the register set
6- #clock-cells: Should be <1>
7- clocks: list of clock specifiers, must contain an entry for each required
8 entry in clock-names
9- clock-names: should include the following entries:
10 - "osc_32k"
11 - "osc_24m"
12 - "clk_ext1"
13 - "clk_ext2"
14 - "clk_ext3"
15 - "clk_ext4"
16
17clk: clock-controller@30380000 {
18 compatible = "fsl,imx8mm-ccm";
19 reg = <0x0 0x30380000 0x0 0x10000>;
20 #clock-cells = <1>;
21 clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
22 <&clk_ext3>, <&clk_ext4>;
23 clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
24 "clk_ext3", "clk_ext4";
25};
26
27The clock consumer should specify the desired clock by having the clock
28ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8mm-clock.h
29for the full list of i.MX8M Mini clock IDs.
diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
index 87b4949e9bc8..944719bd586f 100644
--- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
@@ -16,6 +16,7 @@ Required properties :
16 "qcom,rpmcc-msm8974", "qcom,rpmcc" 16 "qcom,rpmcc-msm8974", "qcom,rpmcc"
17 "qcom,rpmcc-apq8064", "qcom,rpmcc" 17 "qcom,rpmcc-apq8064", "qcom,rpmcc"
18 "qcom,rpmcc-msm8996", "qcom,rpmcc" 18 "qcom,rpmcc-msm8996", "qcom,rpmcc"
19 "qcom,rpmcc-msm8998", "qcom,rpmcc"
19 "qcom,rpmcc-qcs404", "qcom,rpmcc" 20 "qcom,rpmcc-qcs404", "qcom,rpmcc"
20 21
21- #clock-cells : shall contain 1 22- #clock-cells : shall contain 1
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index b277cafce71e..d7d6f01e81ff 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -242,9 +242,11 @@ certainly invest a bit more effort into libata core layer).
242 242
243CLOCK 243CLOCK
244 devm_clk_get() 244 devm_clk_get()
245 devm_clk_get_optional()
245 devm_clk_put() 246 devm_clk_put()
246 devm_clk_hw_register() 247 devm_clk_hw_register()
247 devm_of_clk_add_hw_provider() 248 devm_of_clk_add_hw_provider()
249 devm_clk_hw_register_clkdev()
248 250
249DMA 251DMA
250 dmaenginem_async_device_register() 252 dmaenginem_async_device_register()
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index b5531dd3ae9c..3a04c73ac03c 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1002,8 +1002,10 @@ static int _enable_clocks(struct omap_hwmod *oh)
1002 clk_enable(oh->_clk); 1002 clk_enable(oh->_clk);
1003 1003
1004 list_for_each_entry(os, &oh->slave_ports, node) { 1004 list_for_each_entry(os, &oh->slave_ports, node) {
1005 if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) 1005 if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) {
1006 omap2_clk_deny_idle(os->_clk);
1006 clk_enable(os->_clk); 1007 clk_enable(os->_clk);
1008 }
1007 } 1009 }
1008 1010
1009 /* The opt clocks are controlled by the device driver. */ 1011 /* The opt clocks are controlled by the device driver. */
@@ -1055,8 +1057,10 @@ static int _disable_clocks(struct omap_hwmod *oh)
1055 clk_disable(oh->_clk); 1057 clk_disable(oh->_clk);
1056 1058
1057 list_for_each_entry(os, &oh->slave_ports, node) { 1059 list_for_each_entry(os, &oh->slave_ports, node) {
1058 if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) 1060 if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) {
1059 clk_disable(os->_clk); 1061 clk_disable(os->_clk);
1062 omap2_clk_allow_idle(os->_clk);
1063 }
1060 } 1064 }
1061 1065
1062 if (oh->flags & HWMOD_OPT_CLKS_NEEDED) 1066 if (oh->flags & HWMOD_OPT_CLKS_NEEDED)
@@ -2436,9 +2440,13 @@ static void _setup_iclk_autoidle(struct omap_hwmod *oh)
2436 continue; 2440 continue;
2437 2441
2438 if (os->flags & OCPIF_SWSUP_IDLE) { 2442 if (os->flags & OCPIF_SWSUP_IDLE) {
2439 /* XXX omap_iclk_deny_idle(c); */ 2443 /*
2444 * we might have multiple users of one iclk with
2445 * different requirements, disable autoidle when
2446 * the module is enabled, e.g. dss iclk
2447 */
2440 } else { 2448 } else {
2441 /* XXX omap_iclk_allow_idle(c); */ 2449 /* we are enabling autoidle afterwards anyways */
2442 clk_enable(os->_clk); 2450 clk_enable(os->_clk);
2443 } 2451 }
2444 } 2452 }
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 5f94c35d165f..1e2a10a06b9d 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -18,7 +18,7 @@
18#include <linux/mutex.h> 18#include <linux/mutex.h>
19#include <linux/pci.h> 19#include <linux/pci.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/platform_data/clk-lpss.h> 21#include <linux/platform_data/x86/clk-lpss.h>
22#include <linux/platform_data/x86/pmc_atom.h> 22#include <linux/platform_data/x86/pmc_atom.h>
23#include <linux/pm_domain.h> 23#include <linux/pm_domain.h>
24#include <linux/pm_runtime.h> 24#include <linux/pm_runtime.h>
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index d2f0bb5ba47e..e705aab9e38b 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -290,6 +290,12 @@ config COMMON_CLK_BD718XX
290 This driver supports ROHM BD71837 and ROHM BD71847 290 This driver supports ROHM BD71837 and ROHM BD71847
291 PMICs clock gates. 291 PMICs clock gates.
292 292
293config COMMON_CLK_FIXED_MMIO
294 bool "Clock driver for Memory Mapped Fixed values"
295 depends on COMMON_CLK && OF
296 help
297 Support for Memory Mapped IO Fixed clocks
298
293source "drivers/clk/actions/Kconfig" 299source "drivers/clk/actions/Kconfig"
294source "drivers/clk/bcm/Kconfig" 300source "drivers/clk/bcm/Kconfig"
295source "drivers/clk/hisilicon/Kconfig" 301source "drivers/clk/hisilicon/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 8a9440a97500..1db133652f0c 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o
27obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o 27obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
28obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o 28obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o
29obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o 29obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
30obj-$(CONFIG_COMMON_CLK_FIXED_MMIO) += clk-fixed-mmio.o
30obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o 31obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o
31obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o 32obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o
32obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o 33obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
@@ -78,7 +79,7 @@ obj-$(CONFIG_ARCH_K3) += keystone/
78obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ 79obj-$(CONFIG_ARCH_KEYSTONE) += keystone/
79obj-$(CONFIG_MACH_LOONGSON32) += loongson1/ 80obj-$(CONFIG_MACH_LOONGSON32) += loongson1/
80obj-y += mediatek/ 81obj-y += mediatek/
81obj-$(CONFIG_COMMON_CLK_AMLOGIC) += meson/ 82obj-$(CONFIG_ARCH_MESON) += meson/
82obj-$(CONFIG_MACH_PIC32) += microchip/ 83obj-$(CONFIG_MACH_PIC32) += microchip/
83ifeq ($(CONFIG_COMMON_CLK), y) 84ifeq ($(CONFIG_COMMON_CLK), y)
84obj-$(CONFIG_ARCH_MMP) += mmp/ 85obj-$(CONFIG_ARCH_MMP) += mmp/
diff --git a/drivers/clk/actions/Kconfig b/drivers/clk/actions/Kconfig
index 04f0a6355726..5b45ca35757e 100644
--- a/drivers/clk/actions/Kconfig
+++ b/drivers/clk/actions/Kconfig
@@ -9,6 +9,11 @@ if CLK_ACTIONS
9 9
10# SoC Drivers 10# SoC Drivers
11 11
12config CLK_OWL_S500
13 bool "Support for the Actions Semi OWL S500 clocks"
14 depends on ARCH_ACTIONS || COMPILE_TEST
15 default ARCH_ACTIONS
16
12config CLK_OWL_S700 17config CLK_OWL_S700
13 bool "Support for the Actions Semi OWL S700 clocks" 18 bool "Support for the Actions Semi OWL S700 clocks"
14 depends on (ARM64 && ARCH_ACTIONS) || COMPILE_TEST 19 depends on (ARM64 && ARCH_ACTIONS) || COMPILE_TEST
diff --git a/drivers/clk/actions/Makefile b/drivers/clk/actions/Makefile
index ccfdf9781cef..a2588e55c790 100644
--- a/drivers/clk/actions/Makefile
+++ b/drivers/clk/actions/Makefile
@@ -10,5 +10,6 @@ clk-owl-y += owl-pll.o
10clk-owl-y += owl-reset.o 10clk-owl-y += owl-reset.o
11 11
12# SoC support 12# SoC support
13obj-$(CONFIG_CLK_OWL_S500) += owl-s500.o
13obj-$(CONFIG_CLK_OWL_S700) += owl-s700.o 14obj-$(CONFIG_CLK_OWL_S700) += owl-s700.o
14obj-$(CONFIG_CLK_OWL_S900) += owl-s900.o 15obj-$(CONFIG_CLK_OWL_S900) += owl-s900.o
diff --git a/drivers/clk/actions/owl-pll.c b/drivers/clk/actions/owl-pll.c
index 058e06d7099f..02437bdedf4d 100644
--- a/drivers/clk/actions/owl-pll.c
+++ b/drivers/clk/actions/owl-pll.c
@@ -179,7 +179,7 @@ static int owl_pll_set_rate(struct clk_hw *hw, unsigned long rate,
179 179
180 regmap_write(common->regmap, pll_hw->reg, reg); 180 regmap_write(common->regmap, pll_hw->reg, reg);
181 181
182 udelay(PLL_STABILITY_WAIT_US); 182 udelay(pll_hw->delay);
183 183
184 return 0; 184 return 0;
185} 185}
diff --git a/drivers/clk/actions/owl-pll.h b/drivers/clk/actions/owl-pll.h
index 0aae30abd5dc..6fb0d45bb088 100644
--- a/drivers/clk/actions/owl-pll.h
+++ b/drivers/clk/actions/owl-pll.h
@@ -13,6 +13,8 @@
13 13
14#include "owl-common.h" 14#include "owl-common.h"
15 15
16#define OWL_PLL_DEF_DELAY 50
17
16/* last entry should have rate = 0 */ 18/* last entry should have rate = 0 */
17struct clk_pll_table { 19struct clk_pll_table {
18 unsigned int val; 20 unsigned int val;
@@ -27,6 +29,7 @@ struct owl_pll_hw {
27 u8 width; 29 u8 width;
28 u8 min_mul; 30 u8 min_mul;
29 u8 max_mul; 31 u8 max_mul;
32 u8 delay;
30 const struct clk_pll_table *table; 33 const struct clk_pll_table *table;
31}; 34};
32 35
@@ -36,7 +39,7 @@ struct owl_pll {
36}; 39};
37 40
38#define OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \ 41#define OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \
39 _width, _min_mul, _max_mul, _table) \ 42 _width, _min_mul, _max_mul, _delay, _table) \
40 { \ 43 { \
41 .reg = _reg, \ 44 .reg = _reg, \
42 .bfreq = _bfreq, \ 45 .bfreq = _bfreq, \
@@ -45,6 +48,7 @@ struct owl_pll {
45 .width = _width, \ 48 .width = _width, \
46 .min_mul = _min_mul, \ 49 .min_mul = _min_mul, \
47 .max_mul = _max_mul, \ 50 .max_mul = _max_mul, \
51 .delay = _delay, \
48 .table = _table, \ 52 .table = _table, \
49 } 53 }
50 54
@@ -52,8 +56,8 @@ struct owl_pll {
52 _shift, _width, _min_mul, _max_mul, _table, _flags) \ 56 _shift, _width, _min_mul, _max_mul, _table, _flags) \
53 struct owl_pll _struct = { \ 57 struct owl_pll _struct = { \
54 .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \ 58 .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \
55 _width, _min_mul, \ 59 _width, _min_mul, _max_mul, \
56 _max_mul, _table), \ 60 OWL_PLL_DEF_DELAY, _table), \
57 .common = { \ 61 .common = { \
58 .regmap = NULL, \ 62 .regmap = NULL, \
59 .hw.init = CLK_HW_INIT(_name, \ 63 .hw.init = CLK_HW_INIT(_name, \
@@ -67,8 +71,23 @@ struct owl_pll {
67 _shift, _width, _min_mul, _max_mul, _table, _flags) \ 71 _shift, _width, _min_mul, _max_mul, _table, _flags) \
68 struct owl_pll _struct = { \ 72 struct owl_pll _struct = { \
69 .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \ 73 .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \
70 _width, _min_mul, \ 74 _width, _min_mul, _max_mul, \
71 _max_mul, _table), \ 75 OWL_PLL_DEF_DELAY, _table), \
76 .common = { \
77 .regmap = NULL, \
78 .hw.init = CLK_HW_INIT_NO_PARENT(_name, \
79 &owl_pll_ops, \
80 _flags), \
81 }, \
82 }
83
84#define OWL_PLL_NO_PARENT_DELAY(_struct, _name, _reg, _bfreq, _bit_idx, \
85 _shift, _width, _min_mul, _max_mul, _delay, _table, \
86 _flags) \
87 struct owl_pll _struct = { \
88 .pll_hw = OWL_PLL_HW(_reg, _bfreq, _bit_idx, _shift, \
89 _width, _min_mul, _max_mul, \
90 _delay, _table), \
72 .common = { \ 91 .common = { \
73 .regmap = NULL, \ 92 .regmap = NULL, \
74 .hw.init = CLK_HW_INIT_NO_PARENT(_name, \ 93 .hw.init = CLK_HW_INIT_NO_PARENT(_name, \
@@ -78,7 +97,6 @@ struct owl_pll {
78 } 97 }
79 98
80#define mul_mask(m) ((1 << ((m)->width)) - 1) 99#define mul_mask(m) ((1 << ((m)->width)) - 1)
81#define PLL_STABILITY_WAIT_US (50)
82 100
83static inline struct owl_pll *hw_to_owl_pll(const struct clk_hw *hw) 101static inline struct owl_pll *hw_to_owl_pll(const struct clk_hw *hw)
84{ 102{
diff --git a/drivers/clk/actions/owl-s500.c b/drivers/clk/actions/owl-s500.c
new file mode 100644
index 000000000000..e2007ac4d235
--- /dev/null
+++ b/drivers/clk/actions/owl-s500.c
@@ -0,0 +1,525 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Actions Semi Owl S500 SoC clock driver
4 *
5 * Copyright (c) 2014 Actions Semi Inc.
6 * Author: David Liu <liuwei@actions-semi.com>
7 *
8 * Copyright (c) 2018 Linaro Ltd.
9 * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
10 *
11 * Copyright (c) 2018 LSI-TEC - Caninos Loucos
12 * Author: Edgar Bernardi Righi <edgar.righi@lsitec.org.br>
13 */
14
15#include <linux/clk-provider.h>
16#include <linux/platform_device.h>
17
18#include "owl-common.h"
19#include "owl-composite.h"
20#include "owl-divider.h"
21#include "owl-factor.h"
22#include "owl-fixed-factor.h"
23#include "owl-gate.h"
24#include "owl-mux.h"
25#include "owl-pll.h"
26
27#include <dt-bindings/clock/actions,s500-cmu.h>
28
29#define CMU_COREPLL (0x0000)
30#define CMU_DEVPLL (0x0004)
31#define CMU_DDRPLL (0x0008)
32#define CMU_NANDPLL (0x000C)
33#define CMU_DISPLAYPLL (0x0010)
34#define CMU_AUDIOPLL (0x0014)
35#define CMU_TVOUTPLL (0x0018)
36#define CMU_BUSCLK (0x001C)
37#define CMU_SENSORCLK (0x0020)
38#define CMU_LCDCLK (0x0024)
39#define CMU_DSICLK (0x0028)
40#define CMU_CSICLK (0x002C)
41#define CMU_DECLK (0x0030)
42#define CMU_BISPCLK (0x0034)
43#define CMU_BUSCLK1 (0x0038)
44#define CMU_VDECLK (0x0040)
45#define CMU_VCECLK (0x0044)
46#define CMU_NANDCCLK (0x004C)
47#define CMU_SD0CLK (0x0050)
48#define CMU_SD1CLK (0x0054)
49#define CMU_SD2CLK (0x0058)
50#define CMU_UART0CLK (0x005C)
51#define CMU_UART1CLK (0x0060)
52#define CMU_UART2CLK (0x0064)
53#define CMU_PWM4CLK (0x0068)
54#define CMU_PWM5CLK (0x006C)
55#define CMU_PWM0CLK (0x0070)
56#define CMU_PWM1CLK (0x0074)
57#define CMU_PWM2CLK (0x0078)
58#define CMU_PWM3CLK (0x007C)
59#define CMU_USBPLL (0x0080)
60#define CMU_ETHERNETPLL (0x0084)
61#define CMU_CVBSPLL (0x0088)
62#define CMU_LENSCLK (0x008C)
63#define CMU_GPU3DCLK (0x0090)
64#define CMU_CORECTL (0x009C)
65#define CMU_DEVCLKEN0 (0x00A0)
66#define CMU_DEVCLKEN1 (0x00A4)
67#define CMU_DEVRST0 (0x00A8)
68#define CMU_DEVRST1 (0x00AC)
69#define CMU_UART3CLK (0x00B0)
70#define CMU_UART4CLK (0x00B4)
71#define CMU_UART5CLK (0x00B8)
72#define CMU_UART6CLK (0x00BC)
73#define CMU_SSCLK (0x00C0)
74#define CMU_DIGITALDEBUG (0x00D0)
75#define CMU_ANALOGDEBUG (0x00D4)
76#define CMU_COREPLLDEBUG (0x00D8)
77#define CMU_DEVPLLDEBUG (0x00DC)
78#define CMU_DDRPLLDEBUG (0x00E0)
79#define CMU_NANDPLLDEBUG (0x00E4)
80#define CMU_DISPLAYPLLDEBUG (0x00E8)
81#define CMU_TVOUTPLLDEBUG (0x00EC)
82#define CMU_DEEPCOLORPLLDEBUG (0x00F4)
83#define CMU_AUDIOPLL_ETHPLLDEBUG (0x00F8)
84#define CMU_CVBSPLLDEBUG (0x00FC)
85
86#define OWL_S500_COREPLL_DELAY (150)
87#define OWL_S500_DDRPLL_DELAY (63)
88#define OWL_S500_DEVPLL_DELAY (28)
89#define OWL_S500_NANDPLL_DELAY (44)
90#define OWL_S500_DISPLAYPLL_DELAY (57)
91#define OWL_S500_ETHERNETPLL_DELAY (25)
92#define OWL_S500_AUDIOPLL_DELAY (100)
93
94static const struct clk_pll_table clk_audio_pll_table[] = {
95 { 0, 45158400 }, { 1, 49152000 },
96 { 0, 0 },
97};
98
99/* pll clocks */
100static OWL_PLL_NO_PARENT_DELAY(ethernet_pll_clk, "ethernet_pll_clk", CMU_ETHERNETPLL, 500000000, 0, 0, 0, 0, 0, OWL_S500_ETHERNETPLL_DELAY, NULL, CLK_IGNORE_UNUSED);
101static OWL_PLL_NO_PARENT_DELAY(core_pll_clk, "core_pll_clk", CMU_COREPLL, 12000000, 9, 0, 8, 4, 134, OWL_S500_COREPLL_DELAY, NULL, CLK_IGNORE_UNUSED);
102static OWL_PLL_NO_PARENT_DELAY(ddr_pll_clk, "ddr_pll_clk", CMU_DDRPLL, 12000000, 8, 0, 8, 1, 67, OWL_S500_DDRPLL_DELAY, NULL, CLK_IGNORE_UNUSED);
103static OWL_PLL_NO_PARENT_DELAY(nand_pll_clk, "nand_pll_clk", CMU_NANDPLL, 6000000, 8, 0, 7, 2, 86, OWL_S500_NANDPLL_DELAY, NULL, CLK_IGNORE_UNUSED);
104static OWL_PLL_NO_PARENT_DELAY(display_pll_clk, "display_pll_clk", CMU_DISPLAYPLL, 6000000, 8, 0, 8, 2, 126, OWL_S500_DISPLAYPLL_DELAY, NULL, CLK_IGNORE_UNUSED);
105static OWL_PLL_NO_PARENT_DELAY(dev_pll_clk, "dev_pll_clk", CMU_DEVPLL, 6000000, 8, 0, 7, 8, 126, OWL_S500_DEVPLL_DELAY, NULL, CLK_IGNORE_UNUSED);
106static OWL_PLL_NO_PARENT_DELAY(audio_pll_clk, "audio_pll_clk", CMU_AUDIOPLL, 0, 4, 0, 1, 0, 0, OWL_S500_AUDIOPLL_DELAY, clk_audio_pll_table, CLK_IGNORE_UNUSED);
107
108static const char * const dev_clk_mux_p[] = { "hosc", "dev_pll_clk" };
109static const char * const bisp_clk_mux_p[] = { "display_pll_clk", "dev_clk" };
110static const char * const sensor_clk_mux_p[] = { "hosc", "bisp_clk" };
111static const char * const sd_clk_mux_p[] = { "dev_clk", "nand_pll_clk" };
112static const char * const pwm_clk_mux_p[] = { "losc", "hosc" };
113static const char * const ahbprediv_clk_mux_p[] = { "dev_clk", "display_pll_clk", "nand_pll_clk", "ddr_pll_clk" };
114static const char * const uart_clk_mux_p[] = { "hosc", "dev_pll_clk" };
115static const char * const de_clk_mux_p[] = { "display_pll_clk", "dev_clk" };
116static const char * const i2s_clk_mux_p[] = { "audio_pll_clk" };
117static const char * const hde_clk_mux_p[] = { "dev_clk", "display_pll_clk", "nand_pll_clk", "ddr_pll_clk" };
118static const char * const nand_clk_mux_p[] = { "nand_pll_clk", "display_pll_clk", "dev_clk", "ddr_pll_clk" };
119
120static struct clk_factor_table sd_factor_table[] = {
121 /* bit0 ~ 4 */
122 { 0, 1, 1 }, { 1, 1, 2 }, { 2, 1, 3 }, { 3, 1, 4 },
123 { 4, 1, 5 }, { 5, 1, 6 }, { 6, 1, 7 }, { 7, 1, 8 },
124 { 8, 1, 9 }, { 9, 1, 10 }, { 10, 1, 11 }, { 11, 1, 12 },
125 { 12, 1, 13 }, { 13, 1, 14 }, { 14, 1, 15 }, { 15, 1, 16 },
126 { 16, 1, 17 }, { 17, 1, 18 }, { 18, 1, 19 }, { 19, 1, 20 },
127 { 20, 1, 21 }, { 21, 1, 22 }, { 22, 1, 23 }, { 23, 1, 24 },
128 { 24, 1, 25 }, { 25, 1, 26 }, { 26, 1, 27 }, { 27, 1, 28 },
129 { 28, 1, 29 }, { 29, 1, 30 }, { 30, 1, 31 }, { 31, 1, 32 },
130
131 /* bit8: /128 */
132 { 256, 1, 1 * 128 }, { 257, 1, 2 * 128 }, { 258, 1, 3 * 128 }, { 259, 1, 4 * 128 },
133 { 260, 1, 5 * 128 }, { 261, 1, 6 * 128 }, { 262, 1, 7 * 128 }, { 263, 1, 8 * 128 },
134 { 264, 1, 9 * 128 }, { 265, 1, 10 * 128 }, { 266, 1, 11 * 128 }, { 267, 1, 12 * 128 },
135 { 268, 1, 13 * 128 }, { 269, 1, 14 * 128 }, { 270, 1, 15 * 128 }, { 271, 1, 16 * 128 },
136 { 272, 1, 17 * 128 }, { 273, 1, 18 * 128 }, { 274, 1, 19 * 128 }, { 275, 1, 20 * 128 },
137 { 276, 1, 21 * 128 }, { 277, 1, 22 * 128 }, { 278, 1, 23 * 128 }, { 279, 1, 24 * 128 },
138 { 280, 1, 25 * 128 }, { 281, 1, 26 * 128 }, { 282, 1, 27 * 128 }, { 283, 1, 28 * 128 },
139 { 284, 1, 29 * 128 }, { 285, 1, 30 * 128 }, { 286, 1, 31 * 128 }, { 287, 1, 32 * 128 },
140 { 0, 0, 0 },
141};
142
143static struct clk_factor_table bisp_factor_table[] = {
144 { 0, 1, 1 }, { 1, 1, 2 }, { 2, 1, 3 }, { 3, 1, 4 },
145 { 4, 1, 5 }, { 5, 1, 6 }, { 6, 1, 7 }, { 7, 1, 8 },
146 { 0, 0, 0 },
147};
148
149static struct clk_factor_table ahb_factor_table[] = {
150 { 1, 1, 2 }, { 2, 1, 3 },
151 { 0, 0, 0 },
152};
153
154static struct clk_div_table rmii_ref_div_table[] = {
155 { 0, 4 }, { 1, 10 },
156 { 0, 0 },
157};
158
159static struct clk_div_table i2s_div_table[] = {
160 { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
161 { 4, 6 }, { 5, 8 }, { 6, 12 }, { 7, 16 },
162 { 8, 24 },
163 { 0, 0 },
164};
165
166static struct clk_div_table nand_div_table[] = {
167 { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 6 },
168 { 4, 8 }, { 5, 10 }, { 6, 12 }, { 7, 14 },
169 { 8, 16 }, { 9, 18 }, { 10, 20 }, { 11, 22 },
170 { 0, 0 },
171};
172
173/* mux clock */
174static OWL_MUX(dev_clk, "dev_clk", dev_clk_mux_p, CMU_DEVPLL, 12, 1, CLK_SET_RATE_PARENT);
175static OWL_MUX(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p, CMU_BUSCLK1, 8, 3, CLK_SET_RATE_PARENT);
176
177/* gate clocks */
178static OWL_GATE(spi0_clk, "spi0_clk", "ahb_clk", CMU_DEVCLKEN1, 10, 0, CLK_IGNORE_UNUSED);
179static OWL_GATE(spi1_clk, "spi1_clk", "ahb_clk", CMU_DEVCLKEN1, 11, 0, CLK_IGNORE_UNUSED);
180static OWL_GATE(spi2_clk, "spi2_clk", "ahb_clk", CMU_DEVCLKEN1, 12, 0, CLK_IGNORE_UNUSED);
181static OWL_GATE(spi3_clk, "spi3_clk", "ahb_clk", CMU_DEVCLKEN1, 13, 0, CLK_IGNORE_UNUSED);
182static OWL_GATE(timer_clk, "timer_clk", "hosc", CMU_DEVCLKEN1, 27, 0, 0);
183static OWL_GATE(hdmi_clk, "hdmi_clk", "hosc", CMU_DEVCLKEN1, 3, 0, 0);
184
185/* divider clocks */
186static OWL_DIVIDER(h_clk, "h_clk", "ahbprevdiv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0);
187static OWL_DIVIDER(rmii_ref_clk, "rmii_ref_clk", "ethernet_pll_clk", CMU_ETHERNETPLL, 1, 1, rmii_ref_div_table, 0, 0);
188
189/* factor clocks */
190static OWL_FACTOR(ahb_clk, "ahb_clk", "h_clk", CMU_BUSCLK1, 2, 2, ahb_factor_table, 0, 0);
191static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 3, bisp_factor_table, 0, 0);
192static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 3, bisp_factor_table, 0, 0);
193
194/* composite clocks */
195static OWL_COMP_FACTOR(vce_clk, "vce_clk", hde_clk_mux_p,
196 OWL_MUX_HW(CMU_VCECLK, 4, 2),
197 OWL_GATE_HW(CMU_DEVCLKEN0, 26, 0),
198 OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, bisp_factor_table),
199 0);
200
201static OWL_COMP_FACTOR(vde_clk, "vde_clk", hde_clk_mux_p,
202 OWL_MUX_HW(CMU_VDECLK, 4, 2),
203 OWL_GATE_HW(CMU_DEVCLKEN0, 25, 0),
204 OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, bisp_factor_table),
205 0);
206
207static OWL_COMP_FACTOR(bisp_clk, "bisp_clk", bisp_clk_mux_p,
208 OWL_MUX_HW(CMU_BISPCLK, 4, 1),
209 OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0),
210 OWL_FACTOR_HW(CMU_BISPCLK, 0, 3, 0, bisp_factor_table),
211 0);
212
213static OWL_COMP_FACTOR(sensor0_clk, "sensor0_clk", sensor_clk_mux_p,
214 OWL_MUX_HW(CMU_SENSORCLK, 4, 1),
215 OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0),
216 OWL_FACTOR_HW(CMU_SENSORCLK, 0, 3, 0, bisp_factor_table),
217 CLK_IGNORE_UNUSED);
218
219static OWL_COMP_FACTOR(sensor1_clk, "sensor1_clk", sensor_clk_mux_p,
220 OWL_MUX_HW(CMU_SENSORCLK, 4, 1),
221 OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0),
222 OWL_FACTOR_HW(CMU_SENSORCLK, 8, 3, 0, bisp_factor_table),
223 CLK_IGNORE_UNUSED);
224
225static OWL_COMP_FACTOR(sd0_clk, "sd0_clk", sd_clk_mux_p,
226 OWL_MUX_HW(CMU_SD0CLK, 9, 1),
227 OWL_GATE_HW(CMU_DEVCLKEN0, 5, 0),
228 OWL_FACTOR_HW(CMU_SD0CLK, 0, 9, 0, sd_factor_table),
229 0);
230
231static OWL_COMP_FACTOR(sd1_clk, "sd1_clk", sd_clk_mux_p,
232 OWL_MUX_HW(CMU_SD1CLK, 9, 1),
233 OWL_GATE_HW(CMU_DEVCLKEN0, 6, 0),
234 OWL_FACTOR_HW(CMU_SD1CLK, 0, 9, 0, sd_factor_table),
235 0);
236
237static OWL_COMP_FACTOR(sd2_clk, "sd2_clk", sd_clk_mux_p,
238 OWL_MUX_HW(CMU_SD2CLK, 9, 1),
239 OWL_GATE_HW(CMU_DEVCLKEN0, 7, 0),
240 OWL_FACTOR_HW(CMU_SD2CLK, 0, 9, 0, sd_factor_table),
241 0);
242
243static OWL_COMP_DIV(pwm0_clk, "pwm0_clk", pwm_clk_mux_p,
244 OWL_MUX_HW(CMU_PWM0CLK, 12, 1),
245 OWL_GATE_HW(CMU_DEVCLKEN1, 23, 0),
246 OWL_DIVIDER_HW(CMU_PWM0CLK, 0, 10, 0, NULL),
247 0);
248
249static OWL_COMP_DIV(pwm1_clk, "pwm1_clk", pwm_clk_mux_p,
250 OWL_MUX_HW(CMU_PWM1CLK, 12, 1),
251 OWL_GATE_HW(CMU_DEVCLKEN1, 24, 0),
252 OWL_DIVIDER_HW(CMU_PWM1CLK, 0, 10, 0, NULL),
253 0);
254
255static OWL_COMP_DIV(pwm2_clk, "pwm2_clk", pwm_clk_mux_p,
256 OWL_MUX_HW(CMU_PWM2CLK, 12, 1),
257 OWL_GATE_HW(CMU_DEVCLKEN1, 25, 0),
258 OWL_DIVIDER_HW(CMU_PWM2CLK, 0, 10, 0, NULL),
259 0);
260
261static OWL_COMP_DIV(pwm3_clk, "pwm3_clk", pwm_clk_mux_p,
262 OWL_MUX_HW(CMU_PWM3CLK, 12, 1),
263 OWL_GATE_HW(CMU_DEVCLKEN1, 26, 0),
264 OWL_DIVIDER_HW(CMU_PWM3CLK, 0, 10, 0, NULL),
265 0);
266
267static OWL_COMP_DIV(pwm4_clk, "pwm4_clk", pwm_clk_mux_p,
268 OWL_MUX_HW(CMU_PWM4CLK, 12, 1),
269 OWL_GATE_HW(CMU_DEVCLKEN0, 11, 0),
270 OWL_DIVIDER_HW(CMU_PWM4CLK, 0, 10, 0, NULL),
271 0);
272
273static OWL_COMP_DIV(pwm5_clk, "pwm5_clk", pwm_clk_mux_p,
274 OWL_MUX_HW(CMU_PWM5CLK, 12, 1),
275 OWL_GATE_HW(CMU_DEVCLKEN0, 0, 0),
276 OWL_DIVIDER_HW(CMU_PWM5CLK, 0, 10, 0, NULL),
277 0);
278
279static OWL_COMP_PASS(de_clk, "de_clk", de_clk_mux_p,
280 OWL_MUX_HW(CMU_DECLK, 12, 1),
281 OWL_GATE_HW(CMU_DEVCLKEN0, 8, 0),
282 0);
283
284static OWL_COMP_FIXED_FACTOR(i2c0_clk, "i2c0_clk", "ethernet_pll_clk",
285 OWL_GATE_HW(CMU_DEVCLKEN1, 14, 0),
286 1, 5, 0);
287
288static OWL_COMP_FIXED_FACTOR(i2c1_clk, "i2c1_clk", "ethernet_pll_clk",
289 OWL_GATE_HW(CMU_DEVCLKEN1, 15, 0),
290 1, 5, 0);
291
292static OWL_COMP_FIXED_FACTOR(i2c2_clk, "i2c2_clk", "ethernet_pll_clk",
293 OWL_GATE_HW(CMU_DEVCLKEN1, 30, 0),
294 1, 5, 0);
295
296static OWL_COMP_FIXED_FACTOR(i2c3_clk, "i2c3_clk", "ethernet_pll_clk",
297 OWL_GATE_HW(CMU_DEVCLKEN1, 31, 0),
298 1, 5, 0);
299
300static OWL_COMP_DIV(uart0_clk, "uart0_clk", uart_clk_mux_p,
301 OWL_MUX_HW(CMU_UART0CLK, 16, 1),
302 OWL_GATE_HW(CMU_DEVCLKEN1, 6, 0),
303 OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
304 CLK_IGNORE_UNUSED);
305
306static OWL_COMP_DIV(uart1_clk, "uart1_clk", uart_clk_mux_p,
307 OWL_MUX_HW(CMU_UART1CLK, 16, 1),
308 OWL_GATE_HW(CMU_DEVCLKEN1, 7, 0),
309 OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
310 CLK_IGNORE_UNUSED);
311
312static OWL_COMP_DIV(uart2_clk, "uart2_clk", uart_clk_mux_p,
313 OWL_MUX_HW(CMU_UART2CLK, 16, 1),
314 OWL_GATE_HW(CMU_DEVCLKEN1, 8, 0),
315 OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
316 CLK_IGNORE_UNUSED);
317
318static OWL_COMP_DIV(uart3_clk, "uart3_clk", uart_clk_mux_p,
319 OWL_MUX_HW(CMU_UART3CLK, 16, 1),
320 OWL_GATE_HW(CMU_DEVCLKEN1, 19, 0),
321 OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
322 CLK_IGNORE_UNUSED);
323
324static OWL_COMP_DIV(uart4_clk, "uart4_clk", uart_clk_mux_p,
325 OWL_MUX_HW(CMU_UART4CLK, 16, 1),
326 OWL_GATE_HW(CMU_DEVCLKEN1, 20, 0),
327 OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
328 CLK_IGNORE_UNUSED);
329
330static OWL_COMP_DIV(uart5_clk, "uart5_clk", uart_clk_mux_p,
331 OWL_MUX_HW(CMU_UART5CLK, 16, 1),
332 OWL_GATE_HW(CMU_DEVCLKEN1, 21, 0),
333 OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
334 CLK_IGNORE_UNUSED);
335
336static OWL_COMP_DIV(uart6_clk, "uart6_clk", uart_clk_mux_p,
337 OWL_MUX_HW(CMU_UART6CLK, 16, 1),
338 OWL_GATE_HW(CMU_DEVCLKEN1, 18, 0),
339 OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
340 CLK_IGNORE_UNUSED);
341
342static OWL_COMP_DIV(i2srx_clk, "i2srx_clk", i2s_clk_mux_p,
343 OWL_MUX_HW(CMU_AUDIOPLL, 24, 1),
344 OWL_GATE_HW(CMU_DEVCLKEN0, 21, 0),
345 OWL_DIVIDER_HW(CMU_AUDIOPLL, 20, 4, 0, i2s_div_table),
346 0);
347
348static OWL_COMP_DIV(i2stx_clk, "i2stx_clk", i2s_clk_mux_p,
349 OWL_MUX_HW(CMU_AUDIOPLL, 24, 1),
350 OWL_GATE_HW(CMU_DEVCLKEN0, 20, 0),
351 OWL_DIVIDER_HW(CMU_AUDIOPLL, 16, 4, 0, i2s_div_table),
352 0);
353
354static OWL_COMP_DIV(hdmia_clk, "hdmia_clk", i2s_clk_mux_p,
355 OWL_MUX_HW(CMU_AUDIOPLL, 24, 1),
356 OWL_GATE_HW(CMU_DEVCLKEN0, 22, 0),
357 OWL_DIVIDER_HW(CMU_AUDIOPLL, 24, 4, 0, i2s_div_table),
358 0);
359
360static OWL_COMP_DIV(spdif_clk, "spdif_clk", i2s_clk_mux_p,
361 OWL_MUX_HW(CMU_AUDIOPLL, 24, 1),
362 OWL_GATE_HW(CMU_DEVCLKEN0, 23, 0),
363 OWL_DIVIDER_HW(CMU_AUDIOPLL, 28, 4, 0, i2s_div_table),
364 0);
365
366static OWL_COMP_DIV(nand_clk, "nand_clk", nand_clk_mux_p,
367 OWL_MUX_HW(CMU_NANDCCLK, 8, 2),
368 OWL_GATE_HW(CMU_DEVCLKEN0, 4, 0),
369 OWL_DIVIDER_HW(CMU_NANDCCLK, 0, 3, 0, nand_div_table),
370 CLK_SET_RATE_PARENT);
371
372static OWL_COMP_DIV(ecc_clk, "ecc_clk", nand_clk_mux_p,
373 OWL_MUX_HW(CMU_NANDCCLK, 8, 2),
374 OWL_GATE_HW(CMU_DEVCLKEN0, 4, 0),
375 OWL_DIVIDER_HW(CMU_NANDCCLK, 4, 3, 0, nand_div_table),
376 CLK_SET_RATE_PARENT);
377
378static struct owl_clk_common *s500_clks[] = {
379 &ethernet_pll_clk.common,
380 &core_pll_clk.common,
381 &ddr_pll_clk.common,
382 &dev_pll_clk.common,
383 &nand_pll_clk.common,
384 &audio_pll_clk.common,
385 &display_pll_clk.common,
386 &dev_clk.common,
387 &timer_clk.common,
388 &i2c0_clk.common,
389 &i2c1_clk.common,
390 &i2c2_clk.common,
391 &i2c3_clk.common,
392 &uart0_clk.common,
393 &uart1_clk.common,
394 &uart2_clk.common,
395 &uart3_clk.common,
396 &uart4_clk.common,
397 &uart5_clk.common,
398 &uart6_clk.common,
399 &pwm0_clk.common,
400 &pwm1_clk.common,
401 &pwm2_clk.common,
402 &pwm3_clk.common,
403 &pwm4_clk.common,
404 &pwm5_clk.common,
405 &sensor0_clk.common,
406 &sensor1_clk.common,
407 &sd0_clk.common,
408 &sd1_clk.common,
409 &sd2_clk.common,
410 &bisp_clk.common,
411 &ahb_clk.common,
412 &ahbprediv_clk.common,
413 &h_clk.common,
414 &spi0_clk.common,
415 &spi1_clk.common,
416 &spi2_clk.common,
417 &spi3_clk.common,
418 &rmii_ref_clk.common,
419 &de_clk.common,
420 &de1_clk.common,
421 &de2_clk.common,
422 &i2srx_clk.common,
423 &i2stx_clk.common,
424 &hdmia_clk.common,
425 &hdmi_clk.common,
426 &vce_clk.common,
427 &vde_clk.common,
428 &spdif_clk.common,
429 &nand_clk.common,
430 &ecc_clk.common,
431};
432
433static struct clk_hw_onecell_data s500_hw_clks = {
434 .hws = {
435 [CLK_ETHERNET_PLL] = &ethernet_pll_clk.common.hw,
436 [CLK_CORE_PLL] = &core_pll_clk.common.hw,
437 [CLK_DDR_PLL] = &ddr_pll_clk.common.hw,
438 [CLK_NAND_PLL] = &nand_pll_clk.common.hw,
439 [CLK_DISPLAY_PLL] = &display_pll_clk.common.hw,
440 [CLK_DEV_PLL] = &dev_pll_clk.common.hw,
441 [CLK_AUDIO_PLL] = &audio_pll_clk.common.hw,
442 [CLK_TIMER] = &timer_clk.common.hw,
443 [CLK_DEV] = &dev_clk.common.hw,
444 [CLK_DE] = &de_clk.common.hw,
445 [CLK_DE1] = &de1_clk.common.hw,
446 [CLK_DE2] = &de2_clk.common.hw,
447 [CLK_I2C0] = &i2c0_clk.common.hw,
448 [CLK_I2C1] = &i2c1_clk.common.hw,
449 [CLK_I2C2] = &i2c2_clk.common.hw,
450 [CLK_I2C3] = &i2c3_clk.common.hw,
451 [CLK_I2SRX] = &i2srx_clk.common.hw,
452 [CLK_I2STX] = &i2stx_clk.common.hw,
453 [CLK_UART0] = &uart0_clk.common.hw,
454 [CLK_UART1] = &uart1_clk.common.hw,
455 [CLK_UART2] = &uart2_clk.common.hw,
456 [CLK_UART3] = &uart3_clk.common.hw,
457 [CLK_UART4] = &uart4_clk.common.hw,
458 [CLK_UART5] = &uart5_clk.common.hw,
459 [CLK_UART6] = &uart6_clk.common.hw,
460 [CLK_PWM0] = &pwm0_clk.common.hw,
461 [CLK_PWM1] = &pwm1_clk.common.hw,
462 [CLK_PWM2] = &pwm2_clk.common.hw,
463 [CLK_PWM3] = &pwm3_clk.common.hw,
464 [CLK_PWM4] = &pwm4_clk.common.hw,
465 [CLK_PWM5] = &pwm5_clk.common.hw,
466 [CLK_SENSOR0] = &sensor0_clk.common.hw,
467 [CLK_SENSOR1] = &sensor1_clk.common.hw,
468 [CLK_SD0] = &sd0_clk.common.hw,
469 [CLK_SD1] = &sd1_clk.common.hw,
470 [CLK_SD2] = &sd2_clk.common.hw,
471 [CLK_BISP] = &bisp_clk.common.hw,
472 [CLK_SPI0] = &spi0_clk.common.hw,
473 [CLK_SPI1] = &spi1_clk.common.hw,
474 [CLK_SPI2] = &spi2_clk.common.hw,
475 [CLK_SPI3] = &spi3_clk.common.hw,
476 [CLK_AHB] = &ahb_clk.common.hw,
477 [CLK_H] = &h_clk.common.hw,
478 [CLK_AHBPREDIV] = &ahbprediv_clk.common.hw,
479 [CLK_RMII_REF] = &rmii_ref_clk.common.hw,
480 [CLK_HDMI_AUDIO] = &hdmia_clk.common.hw,
481 [CLK_HDMI] = &hdmi_clk.common.hw,
482 [CLK_VDE] = &vde_clk.common.hw,
483 [CLK_VCE] = &vce_clk.common.hw,
484 [CLK_SPDIF] = &spdif_clk.common.hw,
485 [CLK_NAND] = &nand_clk.common.hw,
486 [CLK_ECC] = &ecc_clk.common.hw,
487 },
488 .num = CLK_NR_CLKS,
489};
490
491static struct owl_clk_desc s500_clk_desc = {
492 .clks = s500_clks,
493 .num_clks = ARRAY_SIZE(s500_clks),
494
495 .hw_clks = &s500_hw_clks,
496};
497
498static int s500_clk_probe(struct platform_device *pdev)
499{
500 struct owl_clk_desc *desc;
501
502 desc = &s500_clk_desc;
503 owl_clk_regmap_init(pdev, desc);
504
505 return owl_clk_probe(&pdev->dev, desc->hw_clks);
506}
507
508static const struct of_device_id s500_clk_of_match[] = {
509 { .compatible = "actions,s500-cmu", },
510 { /* sentinel */ }
511};
512
513static struct platform_driver s500_clk_driver = {
514 .probe = s500_clk_probe,
515 .driver = {
516 .name = "s500-cmu",
517 .of_match_table = s500_clk_of_match,
518 },
519};
520
521static int __init s500_clk_init(void)
522{
523 return platform_driver_register(&s500_clk_driver);
524}
525core_initcall(s500_clk_init);
diff --git a/drivers/clk/at91/clk-audio-pll.c b/drivers/clk/at91/clk-audio-pll.c
index 36d77146a3bd..3cc4a82f4e9f 100644
--- a/drivers/clk/at91/clk-audio-pll.c
+++ b/drivers/clk/at91/clk-audio-pll.c
@@ -340,7 +340,12 @@ static long clk_audio_pll_pmc_round_rate(struct clk_hw *hw, unsigned long rate,
340 pr_debug("A PLL/PMC: %s, rate = %lu (parent_rate = %lu)\n", __func__, 340 pr_debug("A PLL/PMC: %s, rate = %lu (parent_rate = %lu)\n", __func__,
341 rate, *parent_rate); 341 rate, *parent_rate);
342 342
343 for (div = 1; div <= AUDIO_PLL_QDPMC_MAX; div++) { 343 if (!rate)
344 return 0;
345
346 best_parent_rate = clk_round_rate(pclk->clk, 1);
347 div = max(best_parent_rate / rate, 1UL);
348 for (; div <= AUDIO_PLL_QDPMC_MAX; div++) {
344 best_parent_rate = clk_round_rate(pclk->clk, rate * div); 349 best_parent_rate = clk_round_rate(pclk->clk, rate * div);
345 tmp_rate = best_parent_rate / div; 350 tmp_rate = best_parent_rate / div;
346 tmp_diff = abs(rate - tmp_rate); 351 tmp_diff = abs(rate - tmp_rate);
@@ -350,6 +355,8 @@ static long clk_audio_pll_pmc_round_rate(struct clk_hw *hw, unsigned long rate,
350 best_rate = tmp_rate; 355 best_rate = tmp_rate;
351 best_diff = tmp_diff; 356 best_diff = tmp_diff;
352 tmp_qd = div; 357 tmp_qd = div;
358 if (!best_diff)
359 break; /* got exact match */
353 } 360 }
354 } 361 }
355 362
diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c
index 5bc68b9c5498..89d6f3736dbf 100644
--- a/drivers/clk/at91/clk-programmable.c
+++ b/drivers/clk/at91/clk-programmable.c
@@ -132,11 +132,8 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate,
132 struct clk_programmable *prog = to_clk_programmable(hw); 132 struct clk_programmable *prog = to_clk_programmable(hw);
133 const struct clk_programmable_layout *layout = prog->layout; 133 const struct clk_programmable_layout *layout = prog->layout;
134 unsigned long div = parent_rate / rate; 134 unsigned long div = parent_rate / rate;
135 unsigned int pckr;
136 int shift = 0; 135 int shift = 0;
137 136
138 regmap_read(prog->regmap, AT91_PMC_PCKR(prog->id), &pckr);
139
140 if (!div) 137 if (!div)
141 return -EINVAL; 138 return -EINVAL;
142 139
diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c
index cd0ef7274fdb..1f70cb164b06 100644
--- a/drivers/clk/at91/sama5d2.c
+++ b/drivers/clk/at91/sama5d2.c
@@ -241,13 +241,14 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
241 parent_names[2] = "plladivck"; 241 parent_names[2] = "plladivck";
242 parent_names[3] = "utmick"; 242 parent_names[3] = "utmick";
243 parent_names[4] = "masterck"; 243 parent_names[4] = "masterck";
244 parent_names[5] = "audiopll_pmcck";
244 for (i = 0; i < 3; i++) { 245 for (i = 0; i < 3; i++) {
245 char name[6]; 246 char name[6];
246 247
247 snprintf(name, sizeof(name), "prog%d", i); 248 snprintf(name, sizeof(name), "prog%d", i);
248 249
249 hw = at91_clk_register_programmable(regmap, name, 250 hw = at91_clk_register_programmable(regmap, name,
250 parent_names, 5, i, 251 parent_names, 6, i,
251 &at91sam9x5_programmable_layout); 252 &at91sam9x5_programmable_layout);
252 if (IS_ERR(hw)) 253 if (IS_ERR(hw))
253 goto err_free; 254 goto err_free;
diff --git a/drivers/clk/clk-clps711x.c b/drivers/clk/clk-clps711x.c
index 2c04396402ab..c36c47bdba02 100644
--- a/drivers/clk/clk-clps711x.c
+++ b/drivers/clk/clk-clps711x.c
@@ -44,21 +44,21 @@ struct clps711x_clk {
44 struct clk_hw_onecell_data clk_data; 44 struct clk_hw_onecell_data clk_data;
45}; 45};
46 46
47static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base, 47static void __init clps711x_clk_init_dt(struct device_node *np)
48 u32 fref)
49{ 48{
50 u32 tmp, f_cpu, f_pll, f_bus, f_tim, f_pwm, f_spi; 49 u32 tmp, f_cpu, f_pll, f_bus, f_tim, f_pwm, f_spi, fref = 0;
51 struct clps711x_clk *clps711x_clk; 50 struct clps711x_clk *clps711x_clk;
52 unsigned i; 51 void __iomem *base;
52
53 WARN_ON(of_property_read_u32(np, "startup-frequency", &fref));
53 54
54 if (!base) 55 base = of_iomap(np, 0);
55 return ERR_PTR(-ENOMEM); 56 BUG_ON(!base);
56 57
57 clps711x_clk = kzalloc(struct_size(clps711x_clk, clk_data.hws, 58 clps711x_clk = kzalloc(struct_size(clps711x_clk, clk_data.hws,
58 CLPS711X_CLK_MAX), 59 CLPS711X_CLK_MAX),
59 GFP_KERNEL); 60 GFP_KERNEL);
60 if (!clps711x_clk) 61 BUG_ON(!clps711x_clk);
61 return ERR_PTR(-ENOMEM);
62 62
63 spin_lock_init(&clps711x_clk->lock); 63 spin_lock_init(&clps711x_clk->lock);
64 64
@@ -137,52 +137,13 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
137 clk_hw_register_fixed_factor(NULL, "uart", "bus", 0, 1, 10); 137 clk_hw_register_fixed_factor(NULL, "uart", "bus", 0, 1, 10);
138 clps711x_clk->clk_data.hws[CLPS711X_CLK_TICK] = 138 clps711x_clk->clk_data.hws[CLPS711X_CLK_TICK] =
139 clk_hw_register_fixed_rate(NULL, "tick", NULL, 0, 64); 139 clk_hw_register_fixed_rate(NULL, "tick", NULL, 0, 64);
140 for (i = 0; i < CLPS711X_CLK_MAX; i++) 140 for (tmp = 0; tmp < CLPS711X_CLK_MAX; tmp++)
141 if (IS_ERR(clps711x_clk->clk_data.hws[i])) 141 if (IS_ERR(clps711x_clk->clk_data.hws[tmp]))
142 pr_err("clk %i: register failed with %ld\n", 142 pr_err("clk %i: register failed with %ld\n",
143 i, PTR_ERR(clps711x_clk->clk_data.hws[i])); 143 tmp, PTR_ERR(clps711x_clk->clk_data.hws[tmp]));
144
145 return clps711x_clk;
146}
147
148void __init clps711x_clk_init(void __iomem *base)
149{
150 struct clps711x_clk *clps711x_clk;
151
152 clps711x_clk = _clps711x_clk_init(base, 73728000);
153
154 BUG_ON(IS_ERR(clps711x_clk));
155
156 /* Clocksource */
157 clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER1],
158 NULL, "clps711x-timer.0");
159 clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER2],
160 NULL, "clps711x-timer.1");
161
162 /* Drivers */
163 clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_PWM],
164 NULL, "clps711x-pwm");
165 clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_UART],
166 NULL, "clps711x-uart.0");
167 clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_UART],
168 NULL, "clps711x-uart.1");
169}
170
171#ifdef CONFIG_OF
172static void __init clps711x_clk_init_dt(struct device_node *np)
173{
174 void __iomem *base = of_iomap(np, 0);
175 struct clps711x_clk *clps711x_clk;
176 u32 fref = 0;
177
178 WARN_ON(of_property_read_u32(np, "startup-frequency", &fref));
179
180 clps711x_clk = _clps711x_clk_init(base, fref);
181 BUG_ON(IS_ERR(clps711x_clk));
182 144
183 clps711x_clk->clk_data.num = CLPS711X_CLK_MAX; 145 clps711x_clk->clk_data.num = CLPS711X_CLK_MAX;
184 of_clk_add_hw_provider(np, of_clk_hw_onecell_get, 146 of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
185 &clps711x_clk->clk_data); 147 &clps711x_clk->clk_data);
186} 148}
187CLK_OF_DECLARE(clps711x, "cirrus,ep7209-clk", clps711x_clk_init_dt); 149CLK_OF_DECLARE(clps711x, "cirrus,ep7209-clk", clps711x_clk_init_dt);
188#endif
diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index c9a86156ced8..daa1fc8fba53 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -29,6 +29,17 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
29} 29}
30EXPORT_SYMBOL(devm_clk_get); 30EXPORT_SYMBOL(devm_clk_get);
31 31
32struct clk *devm_clk_get_optional(struct device *dev, const char *id)
33{
34 struct clk *clk = devm_clk_get(dev, id);
35
36 if (clk == ERR_PTR(-ENOENT))
37 return NULL;
38
39 return clk;
40}
41EXPORT_SYMBOL(devm_clk_get_optional);
42
32struct clk_bulk_devres { 43struct clk_bulk_devres {
33 struct clk_bulk_data *clks; 44 struct clk_bulk_data *clks;
34 int num_clks; 45 int num_clks;
diff --git a/drivers/clk/clk-fixed-mmio.c b/drivers/clk/clk-fixed-mmio.c
new file mode 100644
index 000000000000..d1a97d971183
--- /dev/null
+++ b/drivers/clk/clk-fixed-mmio.c
@@ -0,0 +1,101 @@
1// SPDX-License-Identifier: GPL-2.0
2
3/*
4 * Memory Mapped IO Fixed clock driver
5 *
6 * Copyright (C) 2018 Cadence Design Systems, Inc.
7 *
8 * Authors:
9 * Jan Kotas <jank@cadence.com>
10 */
11
12#include <linux/clk-provider.h>
13#include <linux/of_address.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16
17static struct clk_hw *fixed_mmio_clk_setup(struct device_node *node)
18{
19 struct clk_hw *clk;
20 const char *clk_name = node->name;
21 void __iomem *base;
22 u32 freq;
23 int ret;
24
25 base = of_iomap(node, 0);
26 if (!base) {
27 pr_err("%pOFn: failed to map address\n", node);
28 return ERR_PTR(-EIO);
29 }
30
31 freq = readl(base);
32 iounmap(base);
33 of_property_read_string(node, "clock-output-names", &clk_name);
34
35 clk = clk_hw_register_fixed_rate(NULL, clk_name, NULL, 0, freq);
36 if (IS_ERR(clk)) {
37 pr_err("%pOFn: failed to register fixed rate clock\n", node);
38 return clk;
39 }
40
41 ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, clk);
42 if (ret) {
43 pr_err("%pOFn: failed to add clock provider\n", node);
44 clk_hw_unregister(clk);
45 clk = ERR_PTR(ret);
46 }
47
48 return clk;
49}
50
51static void __init of_fixed_mmio_clk_setup(struct device_node *node)
52{
53 fixed_mmio_clk_setup(node);
54}
55CLK_OF_DECLARE(fixed_mmio_clk, "fixed-mmio-clock", of_fixed_mmio_clk_setup);
56
57/**
58 * This is not executed when of_fixed_mmio_clk_setup succeeded.
59 */
60static int of_fixed_mmio_clk_probe(struct platform_device *pdev)
61{
62 struct clk_hw *clk;
63
64 clk = fixed_mmio_clk_setup(pdev->dev.of_node);
65 if (IS_ERR(clk))
66 return PTR_ERR(clk);
67
68 platform_set_drvdata(pdev, clk);
69
70 return 0;
71}
72
73static int of_fixed_mmio_clk_remove(struct platform_device *pdev)
74{
75 struct clk_hw *clk = platform_get_drvdata(pdev);
76
77 of_clk_del_provider(pdev->dev.of_node);
78 clk_hw_unregister_fixed_rate(clk);
79
80 return 0;
81}
82
83static const struct of_device_id of_fixed_mmio_clk_ids[] = {
84 { .compatible = "fixed-mmio-clock" },
85 { }
86};
87MODULE_DEVICE_TABLE(of, of_fixed_mmio_clk_ids);
88
89static struct platform_driver of_fixed_mmio_clk_driver = {
90 .driver = {
91 .name = "of_fixed_mmio_clk",
92 .of_match_table = of_fixed_mmio_clk_ids,
93 },
94 .probe = of_fixed_mmio_clk_probe,
95 .remove = of_fixed_mmio_clk_remove,
96};
97module_platform_driver(of_fixed_mmio_clk_driver);
98
99MODULE_AUTHOR("Jan Kotas <jank@cadence.com>");
100MODULE_DESCRIPTION("Memory Mapped IO Fixed clock driver");
101MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index 545dceec0bbf..fdfe2e423d15 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -79,7 +79,7 @@ static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
79 unsigned long m, n; 79 unsigned long m, n;
80 u64 ret; 80 u64 ret;
81 81
82 if (!rate || rate >= *parent_rate) 82 if (!rate || (!clk_hw_can_set_rate_parent(hw) && rate >= *parent_rate))
83 return *parent_rate; 83 return *parent_rate;
84 84
85 if (fd->approximation) 85 if (fd->approximation)
diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
index 25eed3e0251f..c2f07f0d077c 100644
--- a/drivers/clk/clk-gpio.c
+++ b/drivers/clk/clk-gpio.c
@@ -58,6 +58,35 @@ const struct clk_ops clk_gpio_gate_ops = {
58}; 58};
59EXPORT_SYMBOL_GPL(clk_gpio_gate_ops); 59EXPORT_SYMBOL_GPL(clk_gpio_gate_ops);
60 60
61static int clk_sleeping_gpio_gate_prepare(struct clk_hw *hw)
62{
63 struct clk_gpio *clk = to_clk_gpio(hw);
64
65 gpiod_set_value_cansleep(clk->gpiod, 1);
66
67 return 0;
68}
69
70static void clk_sleeping_gpio_gate_unprepare(struct clk_hw *hw)
71{
72 struct clk_gpio *clk = to_clk_gpio(hw);
73
74 gpiod_set_value_cansleep(clk->gpiod, 0);
75}
76
77static int clk_sleeping_gpio_gate_is_prepared(struct clk_hw *hw)
78{
79 struct clk_gpio *clk = to_clk_gpio(hw);
80
81 return gpiod_get_value_cansleep(clk->gpiod);
82}
83
84static const struct clk_ops clk_sleeping_gpio_gate_ops = {
85 .prepare = clk_sleeping_gpio_gate_prepare,
86 .unprepare = clk_sleeping_gpio_gate_unprepare,
87 .is_prepared = clk_sleeping_gpio_gate_is_prepared,
88};
89
61/** 90/**
62 * DOC: basic clock multiplexer which can be controlled with a gpio output 91 * DOC: basic clock multiplexer which can be controlled with a gpio output
63 * Traits of this clock: 92 * Traits of this clock:
@@ -144,10 +173,16 @@ struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
144 const char *parent_name, struct gpio_desc *gpiod, 173 const char *parent_name, struct gpio_desc *gpiod,
145 unsigned long flags) 174 unsigned long flags)
146{ 175{
176 const struct clk_ops *ops;
177
178 if (gpiod_cansleep(gpiod))
179 ops = &clk_sleeping_gpio_gate_ops;
180 else
181 ops = &clk_gpio_gate_ops;
182
147 return clk_register_gpio(dev, name, 183 return clk_register_gpio(dev, name,
148 (parent_name ? &parent_name : NULL), 184 (parent_name ? &parent_name : NULL),
149 (parent_name ? 1 : 0), gpiod, flags, 185 (parent_name ? 1 : 0), gpiod, flags, ops);
150 &clk_gpio_gate_ops);
151} 186}
152EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate); 187EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate);
153 188
diff --git a/drivers/clk/clk-highbank.c b/drivers/clk/clk-highbank.c
index 727ed8e1bb72..8e4581004695 100644
--- a/drivers/clk/clk-highbank.c
+++ b/drivers/clk/clk-highbank.c
@@ -293,6 +293,7 @@ static __init struct clk *hb_clk_init(struct device_node *node, const struct clk
293 /* Map system registers */ 293 /* Map system registers */
294 srnp = of_find_compatible_node(NULL, NULL, "calxeda,hb-sregs"); 294 srnp = of_find_compatible_node(NULL, NULL, "calxeda,hb-sregs");
295 hb_clk->reg = of_iomap(srnp, 0); 295 hb_clk->reg = of_iomap(srnp, 0);
296 of_node_put(srnp);
296 BUG_ON(!hb_clk->reg); 297 BUG_ON(!hb_clk->reg);
297 hb_clk->reg += reg; 298 hb_clk->reg += reg;
298 299
diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c
index 22c937644c93..3727d5472450 100644
--- a/drivers/clk/clk-max77686.c
+++ b/drivers/clk/clk-max77686.c
@@ -235,8 +235,9 @@ static int max77686_clk_probe(struct platform_device *pdev)
235 return ret; 235 return ret;
236 } 236 }
237 237
238 ret = clk_hw_register_clkdev(&max_clk_data->hw, 238 ret = devm_clk_hw_register_clkdev(dev, &max_clk_data->hw,
239 max_clk_data->clk_idata.name, NULL); 239 max_clk_data->clk_idata.name,
240 NULL);
240 if (ret < 0) { 241 if (ret < 0) {
241 dev_err(dev, "Failed to clkdev register: %d\n", ret); 242 dev_err(dev, "Failed to clkdev register: %d\n", ret);
242 return ret; 243 return ret;
@@ -244,8 +245,8 @@ static int max77686_clk_probe(struct platform_device *pdev)
244 } 245 }
245 246
246 if (parent->of_node) { 247 if (parent->of_node) {
247 ret = of_clk_add_hw_provider(parent->of_node, of_clk_max77686_get, 248 ret = devm_of_clk_add_hw_provider(dev, of_clk_max77686_get,
248 drv_data); 249 drv_data);
249 250
250 if (ret < 0) { 251 if (ret < 0) {
251 dev_err(dev, "Failed to register OF clock provider: %d\n", 252 dev_err(dev, "Failed to register OF clock provider: %d\n",
@@ -261,27 +262,11 @@ static int max77686_clk_probe(struct platform_device *pdev)
261 1 << MAX77802_CLOCK_LOW_JITTER_SHIFT); 262 1 << MAX77802_CLOCK_LOW_JITTER_SHIFT);
262 if (ret < 0) { 263 if (ret < 0) {
263 dev_err(dev, "Failed to config low-jitter: %d\n", ret); 264 dev_err(dev, "Failed to config low-jitter: %d\n", ret);
264 goto remove_of_clk_provider; 265 return ret;
265 } 266 }
266 } 267 }
267 268
268 return 0; 269 return 0;
269
270remove_of_clk_provider:
271 if (parent->of_node)
272 of_clk_del_provider(parent->of_node);
273
274 return ret;
275}
276
277static int max77686_clk_remove(struct platform_device *pdev)
278{
279 struct device *parent = pdev->dev.parent;
280
281 if (parent->of_node)
282 of_clk_del_provider(parent->of_node);
283
284 return 0;
285} 270}
286 271
287static const struct platform_device_id max77686_clk_id[] = { 272static const struct platform_device_id max77686_clk_id[] = {
@@ -297,7 +282,6 @@ static struct platform_driver max77686_clk_driver = {
297 .name = "max77686-clk", 282 .name = "max77686-clk",
298 }, 283 },
299 .probe = max77686_clk_probe, 284 .probe = max77686_clk_probe,
300 .remove = max77686_clk_remove,
301 .id_table = max77686_clk_id, 285 .id_table = max77686_clk_id,
302}; 286};
303 287
diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
index 5baa9e051110..1212a9be7e80 100644
--- a/drivers/clk/clk-qoriq.c
+++ b/drivers/clk/clk-qoriq.c
@@ -1148,8 +1148,8 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
1148 pll->div[i].clk = clk; 1148 pll->div[i].clk = clk;
1149 ret = clk_register_clkdev(clk, pll->div[i].name, NULL); 1149 ret = clk_register_clkdev(clk, pll->div[i].name, NULL);
1150 if (ret != 0) 1150 if (ret != 0)
1151 pr_err("%s: %s: register to lookup table failed %ld\n", 1151 pr_err("%s: %s: register to lookup table failed %d\n",
1152 __func__, pll->div[i].name, PTR_ERR(clk)); 1152 __func__, pll->div[i].name, ret);
1153 1153
1154 } 1154 }
1155} 1155}
@@ -1389,6 +1389,7 @@ static void __init clockgen_init(struct device_node *np)
1389 pr_err("%s: Couldn't map %pOF regs\n", __func__, 1389 pr_err("%s: Couldn't map %pOF regs\n", __func__,
1390 guts); 1390 guts);
1391 } 1391 }
1392 of_node_put(guts);
1392 } 1393 }
1393 1394
1394 } 1395 }
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 6a31f7f434ce..a0ae8dc16909 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -121,7 +121,7 @@ static const char * const cpu_src[] = {
121}; 121};
122 122
123static const char * const axi_src[] = { 123static const char * const axi_src[] = {
124 "ck_hsi", "ck_hse", "pll2_p", "pll3_p" 124 "ck_hsi", "ck_hse", "pll2_p"
125}; 125};
126 126
127static const char * const per_src[] = { 127static const char * const per_src[] = {
@@ -225,19 +225,19 @@ static const char * const usart6_src[] = {
225}; 225};
226 226
227static const char * const fdcan_src[] = { 227static const char * const fdcan_src[] = {
228 "ck_hse", "pll3_q", "pll4_q" 228 "ck_hse", "pll3_q", "pll4_q", "pll4_r"
229}; 229};
230 230
231static const char * const sai_src[] = { 231static const char * const sai_src[] = {
232 "pll4_q", "pll3_q", "i2s_ckin", "ck_per" 232 "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "pll3_r"
233}; 233};
234 234
235static const char * const sai2_src[] = { 235static const char * const sai2_src[] = {
236 "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "spdif_ck_symb" 236 "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "spdif_ck_symb", "pll3_r"
237}; 237};
238 238
239static const char * const adc12_src[] = { 239static const char * const adc12_src[] = {
240 "pll4_q", "ck_per" 240 "pll4_r", "ck_per", "pll3_q"
241}; 241};
242 242
243static const char * const dsi_src[] = { 243static const char * const dsi_src[] = {
@@ -269,7 +269,7 @@ static const struct clk_div_table axi_div_table[] = {
269static const struct clk_div_table mcu_div_table[] = { 269static const struct clk_div_table mcu_div_table[] = {
270 { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, 270 { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
271 { 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 }, 271 { 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 },
272 { 8, 512 }, { 9, 512 }, { 10, 512}, { 11, 512 }, 272 { 8, 256 }, { 9, 512 }, { 10, 512}, { 11, 512 },
273 { 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 }, 273 { 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 },
274 { 0 }, 274 { 0 },
275}; 275};
@@ -1286,10 +1286,11 @@ _clk_stm32_register_composite(struct device *dev,
1286 MGATE_MP1(_id, _name, _parent, _flags, _mgate) 1286 MGATE_MP1(_id, _name, _parent, _flags, _mgate)
1287 1287
1288#define KCLK(_id, _name, _parents, _flags, _mgate, _mmux)\ 1288#define KCLK(_id, _name, _parents, _flags, _mgate, _mmux)\
1289 COMPOSITE(_id, _name, _parents, CLK_OPS_PARENT_ENABLE | _flags,\ 1289 COMPOSITE(_id, _name, _parents, CLK_OPS_PARENT_ENABLE |\
1290 _MGATE_MP1(_mgate),\ 1290 CLK_SET_RATE_NO_REPARENT | _flags,\
1291 _MMUX(_mmux),\ 1291 _MGATE_MP1(_mgate),\
1292 _NO_DIV) 1292 _MMUX(_mmux),\
1293 _NO_DIV)
1293 1294
1294enum { 1295enum {
1295 G_SAI1, 1296 G_SAI1,
@@ -1655,12 +1656,14 @@ static const struct stm32_mux_cfg ker_mux_cfg[M_LAST] = {
1655 1656
1656static const struct clock_config stm32mp1_clock_cfg[] = { 1657static const struct clock_config stm32mp1_clock_cfg[] = {
1657 /* Oscillator divider */ 1658 /* Oscillator divider */
1658 DIV(NO_ID, "clk-hsi-div", "clk-hsi", 0, RCC_HSICFGR, 0, 2, 1659 DIV(NO_ID, "clk-hsi-div", "clk-hsi", CLK_DIVIDER_POWER_OF_TWO,
1659 CLK_DIVIDER_READ_ONLY), 1660 RCC_HSICFGR, 0, 2, CLK_DIVIDER_READ_ONLY),
1660 1661
1661 /* External / Internal Oscillators */ 1662 /* External / Internal Oscillators */
1662 GATE_MP1(CK_HSE, "ck_hse", "clk-hse", 0, RCC_OCENSETR, 8, 0), 1663 GATE_MP1(CK_HSE, "ck_hse", "clk-hse", 0, RCC_OCENSETR, 8, 0),
1663 GATE_MP1(CK_CSI, "ck_csi", "clk-csi", 0, RCC_OCENSETR, 4, 0), 1664 /* ck_csi is used by IO compensation and should be critical */
1665 GATE_MP1(CK_CSI, "ck_csi", "clk-csi", CLK_IS_CRITICAL,
1666 RCC_OCENSETR, 4, 0),
1664 GATE_MP1(CK_HSI, "ck_hsi", "clk-hsi-div", 0, RCC_OCENSETR, 0, 0), 1667 GATE_MP1(CK_HSI, "ck_hsi", "clk-hsi-div", 0, RCC_OCENSETR, 0, 0),
1665 GATE(CK_LSI, "ck_lsi", "clk-lsi", 0, RCC_RDLSICR, 0, 0), 1668 GATE(CK_LSI, "ck_lsi", "clk-lsi", 0, RCC_RDLSICR, 0, 0),
1666 GATE(CK_LSE, "ck_lse", "clk-lse", 0, RCC_BDCR, 0, 0), 1669 GATE(CK_LSE, "ck_lse", "clk-lse", 0, RCC_BDCR, 0, 0),
@@ -1952,14 +1955,14 @@ static const struct clock_config stm32mp1_clock_cfg[] = {
1952 MGATE_MP1(GPU_K, "gpu_k", "pll2_q", 0, G_GPU), 1955 MGATE_MP1(GPU_K, "gpu_k", "pll2_q", 0, G_GPU),
1953 MGATE_MP1(DAC12_K, "dac12_k", "ck_lsi", 0, G_DAC12), 1956 MGATE_MP1(DAC12_K, "dac12_k", "ck_lsi", 0, G_DAC12),
1954 1957
1955 COMPOSITE(ETHPTP_K, "ethptp_k", eth_src, CLK_OPS_PARENT_ENABLE, 1958 COMPOSITE(ETHPTP_K, "ethptp_k", eth_src, CLK_OPS_PARENT_ENABLE |
1959 CLK_SET_RATE_NO_REPARENT,
1956 _NO_GATE, 1960 _NO_GATE,
1957 _MMUX(M_ETHCK), 1961 _MMUX(M_ETHCK),
1958 _DIV(RCC_ETHCKSELR, 4, 4, CLK_DIVIDER_ALLOW_ZERO, NULL)), 1962 _DIV(RCC_ETHCKSELR, 4, 4, 0, NULL)),
1959 1963
1960 /* RTC clock */ 1964 /* RTC clock */
1961 DIV(NO_ID, "ck_hse_rtc", "ck_hse", 0, RCC_RTCDIVR, 0, 7, 1965 DIV(NO_ID, "ck_hse_rtc", "ck_hse", 0, RCC_RTCDIVR, 0, 6, 0),
1962 CLK_DIVIDER_ALLOW_ZERO),
1963 1966
1964 COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE | 1967 COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE |
1965 CLK_SET_RATE_PARENT, 1968 CLK_SET_RATE_PARENT,
diff --git a/drivers/clk/clk-twl6040.c b/drivers/clk/clk-twl6040.c
index ea846f77750b..0cad5748bf0e 100644
--- a/drivers/clk/clk-twl6040.c
+++ b/drivers/clk/clk-twl6040.c
@@ -41,6 +41,43 @@ static int twl6040_pdmclk_is_prepared(struct clk_hw *hw)
41 return pdmclk->enabled; 41 return pdmclk->enabled;
42} 42}
43 43
44static int twl6040_pdmclk_reset_one_clock(struct twl6040_pdmclk *pdmclk,
45 unsigned int reg)
46{
47 const u8 reset_mask = TWL6040_HPLLRST; /* Same for HPPLL and LPPLL */
48 int ret;
49
50 ret = twl6040_set_bits(pdmclk->twl6040, reg, reset_mask);
51 if (ret < 0)
52 return ret;
53
54 ret = twl6040_clear_bits(pdmclk->twl6040, reg, reset_mask);
55 if (ret < 0)
56 return ret;
57
58 return 0;
59}
60
61/*
62 * TWL6040A2 Phoenix Audio IC erratum #6: "PDM Clock Generation Issue At
63 * Cold Temperature". This affects cold boot and deeper idle states it
64 * seems. The workaround consists of resetting HPPLL and LPPLL.
65 */
66static int twl6040_pdmclk_quirk_reset_clocks(struct twl6040_pdmclk *pdmclk)
67{
68 int ret;
69
70 ret = twl6040_pdmclk_reset_one_clock(pdmclk, TWL6040_REG_HPPLLCTL);
71 if (ret)
72 return ret;
73
74 ret = twl6040_pdmclk_reset_one_clock(pdmclk, TWL6040_REG_LPPLLCTL);
75 if (ret)
76 return ret;
77
78 return 0;
79}
80
44static int twl6040_pdmclk_prepare(struct clk_hw *hw) 81static int twl6040_pdmclk_prepare(struct clk_hw *hw)
45{ 82{
46 struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk, 83 struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk,
@@ -48,8 +85,20 @@ static int twl6040_pdmclk_prepare(struct clk_hw *hw)
48 int ret; 85 int ret;
49 86
50 ret = twl6040_power(pdmclk->twl6040, 1); 87 ret = twl6040_power(pdmclk->twl6040, 1);
51 if (!ret) 88 if (ret)
52 pdmclk->enabled = 1; 89 return ret;
90
91 ret = twl6040_pdmclk_quirk_reset_clocks(pdmclk);
92 if (ret)
93 goto out_err;
94
95 pdmclk->enabled = 1;
96
97 return 0;
98
99out_err:
100 dev_err(pdmclk->dev, "%s: error %i\n", __func__, ret);
101 twl6040_power(pdmclk->twl6040, 0);
53 102
54 return ret; 103 return ret;
55} 104}
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index d2477a5058ac..96053a96fe2f 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -57,6 +57,7 @@ struct clk_core {
57 struct clk_core *new_child; 57 struct clk_core *new_child;
58 unsigned long flags; 58 unsigned long flags;
59 bool orphan; 59 bool orphan;
60 bool rpm_enabled;
60 unsigned int enable_count; 61 unsigned int enable_count;
61 unsigned int prepare_count; 62 unsigned int prepare_count;
62 unsigned int protect_count; 63 unsigned int protect_count;
@@ -81,6 +82,7 @@ struct clk_core {
81 82
82struct clk { 83struct clk {
83 struct clk_core *core; 84 struct clk_core *core;
85 struct device *dev;
84 const char *dev_id; 86 const char *dev_id;
85 const char *con_id; 87 const char *con_id;
86 unsigned long min_rate; 88 unsigned long min_rate;
@@ -92,9 +94,9 @@ struct clk {
92/*** runtime pm ***/ 94/*** runtime pm ***/
93static int clk_pm_runtime_get(struct clk_core *core) 95static int clk_pm_runtime_get(struct clk_core *core)
94{ 96{
95 int ret = 0; 97 int ret;
96 98
97 if (!core->dev) 99 if (!core->rpm_enabled)
98 return 0; 100 return 0;
99 101
100 ret = pm_runtime_get_sync(core->dev); 102 ret = pm_runtime_get_sync(core->dev);
@@ -103,7 +105,7 @@ static int clk_pm_runtime_get(struct clk_core *core)
103 105
104static void clk_pm_runtime_put(struct clk_core *core) 106static void clk_pm_runtime_put(struct clk_core *core)
105{ 107{
106 if (!core->dev) 108 if (!core->rpm_enabled)
107 return; 109 return;
108 110
109 pm_runtime_put_sync(core->dev); 111 pm_runtime_put_sync(core->dev);
@@ -223,7 +225,7 @@ static bool clk_core_is_enabled(struct clk_core *core)
223 * taking enable spinlock, but the below check is needed if one tries 225 * taking enable spinlock, but the below check is needed if one tries
224 * to call it from other places. 226 * to call it from other places.
225 */ 227 */
226 if (core->dev) { 228 if (core->rpm_enabled) {
227 pm_runtime_get_noresume(core->dev); 229 pm_runtime_get_noresume(core->dev);
228 if (!pm_runtime_active(core->dev)) { 230 if (!pm_runtime_active(core->dev)) {
229 ret = false; 231 ret = false;
@@ -233,7 +235,7 @@ static bool clk_core_is_enabled(struct clk_core *core)
233 235
234 ret = core->ops->is_enabled(core->hw); 236 ret = core->ops->is_enabled(core->hw);
235done: 237done:
236 if (core->dev) 238 if (core->rpm_enabled)
237 pm_runtime_put(core->dev); 239 pm_runtime_put(core->dev);
238 240
239 return ret; 241 return ret;
@@ -394,16 +396,19 @@ bool clk_hw_is_prepared(const struct clk_hw *hw)
394{ 396{
395 return clk_core_is_prepared(hw->core); 397 return clk_core_is_prepared(hw->core);
396} 398}
399EXPORT_SYMBOL_GPL(clk_hw_is_prepared);
397 400
398bool clk_hw_rate_is_protected(const struct clk_hw *hw) 401bool clk_hw_rate_is_protected(const struct clk_hw *hw)
399{ 402{
400 return clk_core_rate_is_protected(hw->core); 403 return clk_core_rate_is_protected(hw->core);
401} 404}
405EXPORT_SYMBOL_GPL(clk_hw_rate_is_protected);
402 406
403bool clk_hw_is_enabled(const struct clk_hw *hw) 407bool clk_hw_is_enabled(const struct clk_hw *hw)
404{ 408{
405 return clk_core_is_enabled(hw->core); 409 return clk_core_is_enabled(hw->core);
406} 410}
411EXPORT_SYMBOL_GPL(clk_hw_is_enabled);
407 412
408bool __clk_is_enabled(struct clk *clk) 413bool __clk_is_enabled(struct clk *clk)
409{ 414{
@@ -3209,43 +3214,106 @@ unlock:
3209 return ret; 3214 return ret;
3210} 3215}
3211 3216
3212struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id, 3217/**
3218 * clk_core_link_consumer - Add a clk consumer to the list of consumers in a clk_core
3219 * @core: clk to add consumer to
3220 * @clk: consumer to link to a clk
3221 */
3222static void clk_core_link_consumer(struct clk_core *core, struct clk *clk)
3223{
3224 clk_prepare_lock();
3225 hlist_add_head(&clk->clks_node, &core->clks);
3226 clk_prepare_unlock();
3227}
3228
3229/**
3230 * clk_core_unlink_consumer - Remove a clk consumer from the list of consumers in a clk_core
3231 * @clk: consumer to unlink
3232 */
3233static void clk_core_unlink_consumer(struct clk *clk)
3234{
3235 lockdep_assert_held(&prepare_lock);
3236 hlist_del(&clk->clks_node);
3237}
3238
3239/**
3240 * alloc_clk - Allocate a clk consumer, but leave it unlinked to the clk_core
3241 * @core: clk to allocate a consumer for
3242 * @dev_id: string describing device name
3243 * @con_id: connection ID string on device
3244 *
3245 * Returns: clk consumer left unlinked from the consumer list
3246 */
3247static struct clk *alloc_clk(struct clk_core *core, const char *dev_id,
3213 const char *con_id) 3248 const char *con_id)
3214{ 3249{
3215 struct clk *clk; 3250 struct clk *clk;
3216 3251
3217 /* This is to allow this function to be chained to others */
3218 if (IS_ERR_OR_NULL(hw))
3219 return ERR_CAST(hw);
3220
3221 clk = kzalloc(sizeof(*clk), GFP_KERNEL); 3252 clk = kzalloc(sizeof(*clk), GFP_KERNEL);
3222 if (!clk) 3253 if (!clk)
3223 return ERR_PTR(-ENOMEM); 3254 return ERR_PTR(-ENOMEM);
3224 3255
3225 clk->core = hw->core; 3256 clk->core = core;
3226 clk->dev_id = dev_id; 3257 clk->dev_id = dev_id;
3227 clk->con_id = kstrdup_const(con_id, GFP_KERNEL); 3258 clk->con_id = kstrdup_const(con_id, GFP_KERNEL);
3228 clk->max_rate = ULONG_MAX; 3259 clk->max_rate = ULONG_MAX;
3229 3260
3230 clk_prepare_lock();
3231 hlist_add_head(&clk->clks_node, &hw->core->clks);
3232 clk_prepare_unlock();
3233
3234 return clk; 3261 return clk;
3235} 3262}
3236 3263
3237/* keep in sync with __clk_put */ 3264/**
3238void __clk_free_clk(struct clk *clk) 3265 * free_clk - Free a clk consumer
3266 * @clk: clk consumer to free
3267 *
3268 * Note, this assumes the clk has been unlinked from the clk_core consumer
3269 * list.
3270 */
3271static void free_clk(struct clk *clk)
3239{ 3272{
3240 clk_prepare_lock();
3241 hlist_del(&clk->clks_node);
3242 clk_prepare_unlock();
3243
3244 kfree_const(clk->con_id); 3273 kfree_const(clk->con_id);
3245 kfree(clk); 3274 kfree(clk);
3246} 3275}
3247 3276
3248/** 3277/**
3278 * clk_hw_create_clk: Allocate and link a clk consumer to a clk_core given
3279 * a clk_hw
3280 * @dev: clk consumer device
3281 * @hw: clk_hw associated with the clk being consumed
3282 * @dev_id: string describing device name
3283 * @con_id: connection ID string on device
3284 *
3285 * This is the main function used to create a clk pointer for use by clk
3286 * consumers. It connects a consumer to the clk_core and clk_hw structures
3287 * used by the framework and clk provider respectively.
3288 */
3289struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
3290 const char *dev_id, const char *con_id)
3291{
3292 struct clk *clk;
3293 struct clk_core *core;
3294
3295 /* This is to allow this function to be chained to others */
3296 if (IS_ERR_OR_NULL(hw))
3297 return ERR_CAST(hw);
3298
3299 core = hw->core;
3300 clk = alloc_clk(core, dev_id, con_id);
3301 if (IS_ERR(clk))
3302 return clk;
3303 clk->dev = dev;
3304
3305 if (!try_module_get(core->owner)) {
3306 free_clk(clk);
3307 return ERR_PTR(-ENOENT);
3308 }
3309
3310 kref_get(&core->ref);
3311 clk_core_link_consumer(core, clk);
3312
3313 return clk;
3314}
3315
3316/**
3249 * clk_register - allocate a new clock, register it and return an opaque cookie 3317 * clk_register - allocate a new clock, register it and return an opaque cookie
3250 * @dev: device that is registering this clock 3318 * @dev: device that is registering this clock
3251 * @hw: link to hardware-specific clock data 3319 * @hw: link to hardware-specific clock data
@@ -3280,7 +3348,8 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
3280 core->ops = hw->init->ops; 3348 core->ops = hw->init->ops;
3281 3349
3282 if (dev && pm_runtime_enabled(dev)) 3350 if (dev && pm_runtime_enabled(dev))
3283 core->dev = dev; 3351 core->rpm_enabled = true;
3352 core->dev = dev;
3284 if (dev && dev->driver) 3353 if (dev && dev->driver)
3285 core->owner = dev->driver->owner; 3354 core->owner = dev->driver->owner;
3286 core->hw = hw; 3355 core->hw = hw;
@@ -3320,17 +3389,27 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
3320 3389
3321 INIT_HLIST_HEAD(&core->clks); 3390 INIT_HLIST_HEAD(&core->clks);
3322 3391
3323 hw->clk = __clk_create_clk(hw, NULL, NULL); 3392 /*
3393 * Don't call clk_hw_create_clk() here because that would pin the
3394 * provider module to itself and prevent it from ever being removed.
3395 */
3396 hw->clk = alloc_clk(core, NULL, NULL);
3324 if (IS_ERR(hw->clk)) { 3397 if (IS_ERR(hw->clk)) {
3325 ret = PTR_ERR(hw->clk); 3398 ret = PTR_ERR(hw->clk);
3326 goto fail_parents; 3399 goto fail_parents;
3327 } 3400 }
3328 3401
3402 clk_core_link_consumer(hw->core, hw->clk);
3403
3329 ret = __clk_core_init(core); 3404 ret = __clk_core_init(core);
3330 if (!ret) 3405 if (!ret)
3331 return hw->clk; 3406 return hw->clk;
3332 3407
3333 __clk_free_clk(hw->clk); 3408 clk_prepare_lock();
3409 clk_core_unlink_consumer(hw->clk);
3410 clk_prepare_unlock();
3411
3412 free_clk(hw->clk);
3334 hw->clk = NULL; 3413 hw->clk = NULL;
3335 3414
3336fail_parents: 3415fail_parents:
@@ -3601,20 +3680,7 @@ EXPORT_SYMBOL_GPL(devm_clk_hw_unregister);
3601/* 3680/*
3602 * clkdev helpers 3681 * clkdev helpers
3603 */ 3682 */
3604int __clk_get(struct clk *clk)
3605{
3606 struct clk_core *core = !clk ? NULL : clk->core;
3607
3608 if (core) {
3609 if (!try_module_get(core->owner))
3610 return 0;
3611 3683
3612 kref_get(&core->ref);
3613 }
3614 return 1;
3615}
3616
3617/* keep in sync with __clk_free_clk */
3618void __clk_put(struct clk *clk) 3684void __clk_put(struct clk *clk)
3619{ 3685{
3620 struct module *owner; 3686 struct module *owner;
@@ -3648,8 +3714,7 @@ void __clk_put(struct clk *clk)
3648 3714
3649 module_put(owner); 3715 module_put(owner);
3650 3716
3651 kfree_const(clk->con_id); 3717 free_clk(clk);
3652 kfree(clk);
3653} 3718}
3654 3719
3655/*** clk rate change notifiers ***/ 3720/*** clk rate change notifiers ***/
@@ -4006,6 +4071,49 @@ void devm_of_clk_del_provider(struct device *dev)
4006} 4071}
4007EXPORT_SYMBOL(devm_of_clk_del_provider); 4072EXPORT_SYMBOL(devm_of_clk_del_provider);
4008 4073
4074/*
4075 * Beware the return values when np is valid, but no clock provider is found.
4076 * If name == NULL, the function returns -ENOENT.
4077 * If name != NULL, the function returns -EINVAL. This is because
4078 * of_parse_phandle_with_args() is called even if of_property_match_string()
4079 * returns an error.
4080 */
4081static int of_parse_clkspec(const struct device_node *np, int index,
4082 const char *name, struct of_phandle_args *out_args)
4083{
4084 int ret = -ENOENT;
4085
4086 /* Walk up the tree of devices looking for a clock property that matches */
4087 while (np) {
4088 /*
4089 * For named clocks, first look up the name in the
4090 * "clock-names" property. If it cannot be found, then index
4091 * will be an error code and of_parse_phandle_with_args() will
4092 * return -EINVAL.
4093 */
4094 if (name)
4095 index = of_property_match_string(np, "clock-names", name);
4096 ret = of_parse_phandle_with_args(np, "clocks", "#clock-cells",
4097 index, out_args);
4098 if (!ret)
4099 break;
4100 if (name && index >= 0)
4101 break;
4102
4103 /*
4104 * No matching clock found on this node. If the parent node
4105 * has a "clock-ranges" property, then we can try one of its
4106 * clocks.
4107 */
4108 np = np->parent;
4109 if (np && !of_get_property(np, "clock-ranges", NULL))
4110 break;
4111 index = 0;
4112 }
4113
4114 return ret;
4115}
4116
4009static struct clk_hw * 4117static struct clk_hw *
4010__of_clk_get_hw_from_provider(struct of_clk_provider *provider, 4118__of_clk_get_hw_from_provider(struct of_clk_provider *provider,
4011 struct of_phandle_args *clkspec) 4119 struct of_phandle_args *clkspec)
@@ -4021,36 +4129,26 @@ __of_clk_get_hw_from_provider(struct of_clk_provider *provider,
4021 return __clk_get_hw(clk); 4129 return __clk_get_hw(clk);
4022} 4130}
4023 4131
4024struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, 4132static struct clk_hw *
4025 const char *dev_id, const char *con_id) 4133of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec)
4026{ 4134{
4027 struct of_clk_provider *provider; 4135 struct of_clk_provider *provider;
4028 struct clk *clk = ERR_PTR(-EPROBE_DEFER); 4136 struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
4029 struct clk_hw *hw;
4030 4137
4031 if (!clkspec) 4138 if (!clkspec)
4032 return ERR_PTR(-EINVAL); 4139 return ERR_PTR(-EINVAL);
4033 4140
4034 /* Check if we have such a provider in our array */
4035 mutex_lock(&of_clk_mutex); 4141 mutex_lock(&of_clk_mutex);
4036 list_for_each_entry(provider, &of_clk_providers, link) { 4142 list_for_each_entry(provider, &of_clk_providers, link) {
4037 if (provider->node == clkspec->np) { 4143 if (provider->node == clkspec->np) {
4038 hw = __of_clk_get_hw_from_provider(provider, clkspec); 4144 hw = __of_clk_get_hw_from_provider(provider, clkspec);
4039 clk = __clk_create_clk(hw, dev_id, con_id); 4145 if (!IS_ERR(hw))
4040 } 4146 break;
4041
4042 if (!IS_ERR(clk)) {
4043 if (!__clk_get(clk)) {
4044 __clk_free_clk(clk);
4045 clk = ERR_PTR(-ENOENT);
4046 }
4047
4048 break;
4049 } 4147 }
4050 } 4148 }
4051 mutex_unlock(&of_clk_mutex); 4149 mutex_unlock(&of_clk_mutex);
4052 4150
4053 return clk; 4151 return hw;
4054} 4152}
4055 4153
4056/** 4154/**
@@ -4063,10 +4161,62 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
4063 */ 4161 */
4064struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) 4162struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
4065{ 4163{
4066 return __of_clk_get_from_provider(clkspec, NULL, __func__); 4164 struct clk_hw *hw = of_clk_get_hw_from_clkspec(clkspec);
4165
4166 return clk_hw_create_clk(NULL, hw, NULL, __func__);
4067} 4167}
4068EXPORT_SYMBOL_GPL(of_clk_get_from_provider); 4168EXPORT_SYMBOL_GPL(of_clk_get_from_provider);
4069 4169
4170struct clk_hw *of_clk_get_hw(struct device_node *np, int index,
4171 const char *con_id)
4172{
4173 int ret;
4174 struct clk_hw *hw;
4175 struct of_phandle_args clkspec;
4176
4177 ret = of_parse_clkspec(np, index, con_id, &clkspec);
4178 if (ret)
4179 return ERR_PTR(ret);
4180
4181 hw = of_clk_get_hw_from_clkspec(&clkspec);
4182 of_node_put(clkspec.np);
4183
4184 return hw;
4185}
4186
4187static struct clk *__of_clk_get(struct device_node *np,
4188 int index, const char *dev_id,
4189 const char *con_id)
4190{
4191 struct clk_hw *hw = of_clk_get_hw(np, index, con_id);
4192
4193 return clk_hw_create_clk(NULL, hw, dev_id, con_id);
4194}
4195
4196struct clk *of_clk_get(struct device_node *np, int index)
4197{
4198 return __of_clk_get(np, index, np->full_name, NULL);
4199}
4200EXPORT_SYMBOL(of_clk_get);
4201
4202/**
4203 * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node
4204 * @np: pointer to clock consumer node
4205 * @name: name of consumer's clock input, or NULL for the first clock reference
4206 *
4207 * This function parses the clocks and clock-names properties,
4208 * and uses them to look up the struct clk from the registered list of clock
4209 * providers.
4210 */
4211struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
4212{
4213 if (!np)
4214 return ERR_PTR(-ENOENT);
4215
4216 return __of_clk_get(np, 0, np->full_name, name);
4217}
4218EXPORT_SYMBOL(of_clk_get_by_name);
4219
4070/** 4220/**
4071 * of_clk_get_parent_count() - Count the number of clocks a device node has 4221 * of_clk_get_parent_count() - Count the number of clocks a device node has
4072 * @np: device node to count 4222 * @np: device node to count
diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h
index b02f5e604e69..553f531cc232 100644
--- a/drivers/clk/clk.h
+++ b/drivers/clk/clk.h
@@ -5,31 +5,36 @@
5 */ 5 */
6 6
7struct clk_hw; 7struct clk_hw;
8struct device;
9struct of_phandle_args;
8 10
9#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) 11#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
10struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, 12struct clk_hw *of_clk_get_hw(struct device_node *np,
11 const char *dev_id, const char *con_id); 13 int index, const char *con_id);
14#else /* !CONFIG_COMMON_CLK || !CONFIG_OF */
15static inline struct clk_hw *of_clk_get_hw(struct device_node *np,
16 int index, const char *con_id)
17{
18 return ERR_PTR(-ENOENT);
19}
12#endif 20#endif
13 21
14#ifdef CONFIG_COMMON_CLK 22#ifdef CONFIG_COMMON_CLK
15struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id, 23struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
16 const char *con_id); 24 const char *dev_id, const char *con_id);
17void __clk_free_clk(struct clk *clk);
18int __clk_get(struct clk *clk);
19void __clk_put(struct clk *clk); 25void __clk_put(struct clk *clk);
20#else 26#else
21/* All these casts to avoid ifdefs in clkdev... */ 27/* All these casts to avoid ifdefs in clkdev... */
22static inline struct clk * 28static inline struct clk *
23__clk_create_clk(struct clk_hw *hw, const char *dev_id, const char *con_id) 29clk_hw_create_clk(struct device *dev, struct clk_hw *hw, const char *dev_id,
30 const char *con_id)
24{ 31{
25 return (struct clk *)hw; 32 return (struct clk *)hw;
26} 33}
27static inline void __clk_free_clk(struct clk *clk) { }
28static struct clk_hw *__clk_get_hw(struct clk *clk) 34static struct clk_hw *__clk_get_hw(struct clk *clk)
29{ 35{
30 return (struct clk_hw *)clk; 36 return (struct clk_hw *)clk;
31} 37}
32static inline int __clk_get(struct clk *clk) { return 1; }
33static inline void __clk_put(struct clk *clk) { } 38static inline void __clk_put(struct clk *clk) { }
34 39
35#endif 40#endif
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 9ab3db8b3988..8c4435c53f09 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -27,99 +27,6 @@
27static LIST_HEAD(clocks); 27static LIST_HEAD(clocks);
28static DEFINE_MUTEX(clocks_mutex); 28static DEFINE_MUTEX(clocks_mutex);
29 29
30#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
31static struct clk *__of_clk_get(struct device_node *np, int index,
32 const char *dev_id, const char *con_id)
33{
34 struct of_phandle_args clkspec;
35 struct clk *clk;
36 int rc;
37
38 rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index,
39 &clkspec);
40 if (rc)
41 return ERR_PTR(rc);
42
43 clk = __of_clk_get_from_provider(&clkspec, dev_id, con_id);
44 of_node_put(clkspec.np);
45
46 return clk;
47}
48
49struct clk *of_clk_get(struct device_node *np, int index)
50{
51 return __of_clk_get(np, index, np->full_name, NULL);
52}
53EXPORT_SYMBOL(of_clk_get);
54
55static struct clk *__of_clk_get_by_name(struct device_node *np,
56 const char *dev_id,
57 const char *name)
58{
59 struct clk *clk = ERR_PTR(-ENOENT);
60
61 /* Walk up the tree of devices looking for a clock that matches */
62 while (np) {
63 int index = 0;
64
65 /*
66 * For named clocks, first look up the name in the
67 * "clock-names" property. If it cannot be found, then
68 * index will be an error code, and of_clk_get() will fail.
69 */
70 if (name)
71 index = of_property_match_string(np, "clock-names", name);
72 clk = __of_clk_get(np, index, dev_id, name);
73 if (!IS_ERR(clk)) {
74 break;
75 } else if (name && index >= 0) {
76 if (PTR_ERR(clk) != -EPROBE_DEFER)
77 pr_err("ERROR: could not get clock %pOF:%s(%i)\n",
78 np, name ? name : "", index);
79 return clk;
80 }
81
82 /*
83 * No matching clock found on this node. If the parent node
84 * has a "clock-ranges" property, then we can try one of its
85 * clocks.
86 */
87 np = np->parent;
88 if (np && !of_get_property(np, "clock-ranges", NULL))
89 break;
90 }
91
92 return clk;
93}
94
95/**
96 * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node
97 * @np: pointer to clock consumer node
98 * @name: name of consumer's clock input, or NULL for the first clock reference
99 *
100 * This function parses the clocks and clock-names properties,
101 * and uses them to look up the struct clk from the registered list of clock
102 * providers.
103 */
104struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
105{
106 if (!np)
107 return ERR_PTR(-ENOENT);
108
109 return __of_clk_get_by_name(np, np->full_name, name);
110}
111EXPORT_SYMBOL(of_clk_get_by_name);
112
113#else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
114
115static struct clk *__of_clk_get_by_name(struct device_node *np,
116 const char *dev_id,
117 const char *name)
118{
119 return ERR_PTR(-ENOENT);
120}
121#endif
122
123/* 30/*
124 * Find the correct struct clk for the device and connection ID. 31 * Find the correct struct clk for the device and connection ID.
125 * We do slightly fuzzy matching here: 32 * We do slightly fuzzy matching here:
@@ -163,7 +70,8 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id)
163 return cl; 70 return cl;
164} 71}
165 72
166struct clk *clk_get_sys(const char *dev_id, const char *con_id) 73static struct clk *__clk_get_sys(struct device *dev, const char *dev_id,
74 const char *con_id)
167{ 75{
168 struct clk_lookup *cl; 76 struct clk_lookup *cl;
169 struct clk *clk = NULL; 77 struct clk *clk = NULL;
@@ -174,35 +82,33 @@ struct clk *clk_get_sys(const char *dev_id, const char *con_id)
174 if (!cl) 82 if (!cl)
175 goto out; 83 goto out;
176 84
177 clk = __clk_create_clk(cl->clk_hw, dev_id, con_id); 85 clk = clk_hw_create_clk(dev, cl->clk_hw, dev_id, con_id);
178 if (IS_ERR(clk)) 86 if (IS_ERR(clk))
179 goto out;
180
181 if (!__clk_get(clk)) {
182 __clk_free_clk(clk);
183 cl = NULL; 87 cl = NULL;
184 goto out;
185 }
186
187out: 88out:
188 mutex_unlock(&clocks_mutex); 89 mutex_unlock(&clocks_mutex);
189 90
190 return cl ? clk : ERR_PTR(-ENOENT); 91 return cl ? clk : ERR_PTR(-ENOENT);
191} 92}
93
94struct clk *clk_get_sys(const char *dev_id, const char *con_id)
95{
96 return __clk_get_sys(NULL, dev_id, con_id);
97}
192EXPORT_SYMBOL(clk_get_sys); 98EXPORT_SYMBOL(clk_get_sys);
193 99
194struct clk *clk_get(struct device *dev, const char *con_id) 100struct clk *clk_get(struct device *dev, const char *con_id)
195{ 101{
196 const char *dev_id = dev ? dev_name(dev) : NULL; 102 const char *dev_id = dev ? dev_name(dev) : NULL;
197 struct clk *clk; 103 struct clk_hw *hw;
198 104
199 if (dev && dev->of_node) { 105 if (dev && dev->of_node) {
200 clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id); 106 hw = of_clk_get_hw(dev->of_node, 0, con_id);
201 if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER) 107 if (!IS_ERR(hw) || PTR_ERR(hw) == -EPROBE_DEFER)
202 return clk; 108 return clk_hw_create_clk(dev, hw, dev_id, con_id);
203 } 109 }
204 110
205 return clk_get_sys(dev_id, con_id); 111 return __clk_get_sys(dev, dev_id, con_id);
206} 112}
207EXPORT_SYMBOL(clk_get); 113EXPORT_SYMBOL(clk_get);
208 114
@@ -401,6 +307,23 @@ static struct clk_lookup *__clk_register_clkdev(struct clk_hw *hw,
401 return cl; 307 return cl;
402} 308}
403 309
310static int do_clk_register_clkdev(struct clk_hw *hw,
311 struct clk_lookup **cl, const char *con_id, const char *dev_id)
312{
313 if (IS_ERR(hw))
314 return PTR_ERR(hw);
315 /*
316 * Since dev_id can be NULL, and NULL is handled specially, we must
317 * pass it as either a NULL format string, or with "%s".
318 */
319 if (dev_id)
320 *cl = __clk_register_clkdev(hw, con_id, "%s", dev_id);
321 else
322 *cl = __clk_register_clkdev(hw, con_id, NULL);
323
324 return *cl ? 0 : -ENOMEM;
325}
326
404/** 327/**
405 * clk_register_clkdev - register one clock lookup for a struct clk 328 * clk_register_clkdev - register one clock lookup for a struct clk
406 * @clk: struct clk to associate with all clk_lookups 329 * @clk: struct clk to associate with all clk_lookups
@@ -423,17 +346,8 @@ int clk_register_clkdev(struct clk *clk, const char *con_id,
423 if (IS_ERR(clk)) 346 if (IS_ERR(clk))
424 return PTR_ERR(clk); 347 return PTR_ERR(clk);
425 348
426 /* 349 return do_clk_register_clkdev(__clk_get_hw(clk), &cl, con_id,
427 * Since dev_id can be NULL, and NULL is handled specially, we must 350 dev_id);
428 * pass it as either a NULL format string, or with "%s".
429 */
430 if (dev_id)
431 cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, "%s",
432 dev_id);
433 else
434 cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, NULL);
435
436 return cl ? 0 : -ENOMEM;
437} 351}
438EXPORT_SYMBOL(clk_register_clkdev); 352EXPORT_SYMBOL(clk_register_clkdev);
439 353
@@ -456,18 +370,75 @@ int clk_hw_register_clkdev(struct clk_hw *hw, const char *con_id,
456{ 370{
457 struct clk_lookup *cl; 371 struct clk_lookup *cl;
458 372
459 if (IS_ERR(hw)) 373 return do_clk_register_clkdev(hw, &cl, con_id, dev_id);
460 return PTR_ERR(hw); 374}
375EXPORT_SYMBOL(clk_hw_register_clkdev);
461 376
462 /* 377static void devm_clkdev_release(struct device *dev, void *res)
463 * Since dev_id can be NULL, and NULL is handled specially, we must 378{
464 * pass it as either a NULL format string, or with "%s". 379 clkdev_drop(*(struct clk_lookup **)res);
465 */ 380}
466 if (dev_id) 381
467 cl = __clk_register_clkdev(hw, con_id, "%s", dev_id); 382static int devm_clk_match_clkdev(struct device *dev, void *res, void *data)
468 else 383{
469 cl = __clk_register_clkdev(hw, con_id, NULL); 384 struct clk_lookup **l = res;
470 385
471 return cl ? 0 : -ENOMEM; 386 return *l == data;
472} 387}
473EXPORT_SYMBOL(clk_hw_register_clkdev); 388
389/**
390 * devm_clk_release_clkdev - Resource managed clkdev lookup release
391 * @dev: device this lookup is bound
392 * @con_id: connection ID string on device
393 * @dev_id: format string describing device name
394 *
395 * Drop the clkdev lookup created with devm_clk_hw_register_clkdev.
396 * Normally this function will not need to be called and the resource
397 * management code will ensure that the resource is freed.
398 */
399void devm_clk_release_clkdev(struct device *dev, const char *con_id,
400 const char *dev_id)
401{
402 struct clk_lookup *cl;
403 int rval;
404
405 cl = clk_find(dev_id, con_id);
406 WARN_ON(!cl);
407 rval = devres_release(dev, devm_clkdev_release,
408 devm_clk_match_clkdev, cl);
409 WARN_ON(rval);
410}
411EXPORT_SYMBOL(devm_clk_release_clkdev);
412
413/**
414 * devm_clk_hw_register_clkdev - managed clk lookup registration for clk_hw
415 * @dev: device this lookup is bound
416 * @hw: struct clk_hw to associate with all clk_lookups
417 * @con_id: connection ID string on device
418 * @dev_id: format string describing device name
419 *
420 * con_id or dev_id may be NULL as a wildcard, just as in the rest of
421 * clkdev.
422 *
423 * To make things easier for mass registration, we detect error clk_hws
424 * from a previous clk_hw_register_*() call, and return the error code for
425 * those. This is to permit this function to be called immediately
426 * after clk_hw_register_*().
427 */
428int devm_clk_hw_register_clkdev(struct device *dev, struct clk_hw *hw,
429 const char *con_id, const char *dev_id)
430{
431 int rval = -ENOMEM;
432 struct clk_lookup **cl;
433
434 cl = devres_alloc(devm_clkdev_release, sizeof(*cl), GFP_KERNEL);
435 if (cl) {
436 rval = do_clk_register_clkdev(hw, cl, con_id, dev_id);
437 if (!rval)
438 devres_add(dev, cl);
439 else
440 devres_free(cl);
441 }
442 return rval;
443}
444EXPORT_SYMBOL(devm_clk_hw_register_clkdev);
diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index 4aae31a23449..0eaf41848280 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -8,6 +8,12 @@ config MXC_CLK_SCU
8 bool 8 bool
9 depends on IMX_SCU 9 depends on IMX_SCU
10 10
11config CLK_IMX8MM
12 bool "IMX8MM CCM Clock Driver"
13 depends on ARCH_MXC && ARM64
14 help
15 Build the driver for i.MX8MM CCM Clock Driver
16
11config CLK_IMX8MQ 17config CLK_IMX8MQ
12 bool "IMX8MQ CCM Clock Driver" 18 bool "IMX8MQ CCM Clock Driver"
13 depends on ARCH_MXC && ARM64 19 depends on ARCH_MXC && ARM64
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 73119fbfa547..0d5180fbe988 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -18,12 +18,14 @@ obj-$(CONFIG_MXC_CLK) += \
18 clk-pllv2.o \ 18 clk-pllv2.o \
19 clk-pllv3.o \ 19 clk-pllv3.o \
20 clk-pllv4.o \ 20 clk-pllv4.o \
21 clk-sccg-pll.o 21 clk-sccg-pll.o \
22 clk-pll14xx.o
22 23
23obj-$(CONFIG_MXC_CLK_SCU) += \ 24obj-$(CONFIG_MXC_CLK_SCU) += \
24 clk-scu.o \ 25 clk-scu.o \
25 clk-lpcg-scu.o 26 clk-lpcg-scu.o
26 27
28obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
27obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o 29obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
28obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o 30obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
29 31
diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c
index 527ade1d6933..574fac1a169f 100644
--- a/drivers/clk/imx/clk-composite-8m.c
+++ b/drivers/clk/imx/clk-composite-8m.c
@@ -123,7 +123,7 @@ static const struct clk_ops imx8m_clk_composite_divider_ops = {
123}; 123};
124 124
125struct clk *imx8m_clk_composite_flags(const char *name, 125struct clk *imx8m_clk_composite_flags(const char *name,
126 const char **parent_names, 126 const char * const *parent_names,
127 int num_parents, void __iomem *reg, 127 int num_parents, void __iomem *reg,
128 unsigned long flags) 128 unsigned long flags)
129{ 129{
diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c
index fc8e782d817b..e91c826bce70 100644
--- a/drivers/clk/imx/clk-imx51-imx53.c
+++ b/drivers/clk/imx/clk-imx51-imx53.c
@@ -428,6 +428,7 @@ static void __init mx51_clocks_init(struct device_node *np)
428 clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); 428 clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
429 clk[IMX5_CLK_USB_PHY_GATE] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0); 429 clk[IMX5_CLK_USB_PHY_GATE] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0);
430 clk[IMX5_CLK_HSI2C_GATE] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22); 430 clk[IMX5_CLK_HSI2C_GATE] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22);
431 clk[IMX5_CLK_SCC2_IPG_GATE] = imx_clk_gate2("scc2_gate", "ipg", MXC_CCM_CCGR1, 30);
431 clk[IMX5_CLK_MIPI_HSC1_GATE] = imx_clk_gate2_flags("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6, CLK_IS_CRITICAL); 432 clk[IMX5_CLK_MIPI_HSC1_GATE] = imx_clk_gate2_flags("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6, CLK_IS_CRITICAL);
432 clk[IMX5_CLK_MIPI_HSC2_GATE] = imx_clk_gate2_flags("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8, CLK_IS_CRITICAL); 433 clk[IMX5_CLK_MIPI_HSC2_GATE] = imx_clk_gate2_flags("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8, CLK_IS_CRITICAL);
433 clk[IMX5_CLK_MIPI_ESC_GATE] = imx_clk_gate2_flags("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10, CLK_IS_CRITICAL); 434 clk[IMX5_CLK_MIPI_ESC_GATE] = imx_clk_gate2_flags("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10, CLK_IS_CRITICAL);
diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index 716eac3136b4..708e7c5590dd 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -471,6 +471,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
471 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); 471 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
472 anatop_base = base = of_iomap(np, 0); 472 anatop_base = base = of_iomap(np, 0);
473 WARN_ON(!base); 473 WARN_ON(!base);
474 of_node_put(np);
474 475
475 /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */ 476 /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */
476 if (clk_on_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) { 477 if (clk_on_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) {
diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c
index 18527a335ace..91558b09bf9e 100644
--- a/drivers/clk/imx/clk-imx6sx.c
+++ b/drivers/clk/imx/clk-imx6sx.c
@@ -151,6 +151,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
151 np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-anatop"); 151 np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-anatop");
152 base = of_iomap(np, 0); 152 base = of_iomap(np, 0);
153 WARN_ON(!base); 153 WARN_ON(!base);
154 of_node_put(np);
154 155
155 clks[IMX6SX_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); 156 clks[IMX6SX_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
156 clks[IMX6SX_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); 157 clks[IMX6SX_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
index 06c105d580a4..cfbd8d4edb85 100644
--- a/drivers/clk/imx/clk-imx7d.c
+++ b/drivers/clk/imx/clk-imx7d.c
@@ -404,6 +404,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
404 np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-anatop"); 404 np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-anatop");
405 base = of_iomap(np, 0); 405 base = of_iomap(np, 0);
406 WARN_ON(!base); 406 WARN_ON(!base);
407 of_node_put(np);
407 408
408 clks[IMX7D_PLL_ARM_MAIN_SRC] = imx_clk_mux("pll_arm_main_src", base + 0x60, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); 409 clks[IMX7D_PLL_ARM_MAIN_SRC] = imx_clk_mux("pll_arm_main_src", base + 0x60, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
409 clks[IMX7D_PLL_DRAM_MAIN_SRC] = imx_clk_mux("pll_dram_main_src", base + 0x70, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel)); 410 clks[IMX7D_PLL_DRAM_MAIN_SRC] = imx_clk_mux("pll_dram_main_src", base + 0x70, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
diff --git a/drivers/clk/imx/clk-imx7ulp.c b/drivers/clk/imx/clk-imx7ulp.c
index 4e18f629f823..ce306631e844 100644
--- a/drivers/clk/imx/clk-imx7ulp.c
+++ b/drivers/clk/imx/clk-imx7ulp.c
@@ -48,8 +48,8 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np)
48 struct clk_hw **clks; 48 struct clk_hw **clks;
49 void __iomem *base; 49 void __iomem *base;
50 50
51 clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws) * 51 clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_SCG1_END),
52 IMX7ULP_CLK_SCG1_END, GFP_KERNEL); 52 GFP_KERNEL);
53 if (!clk_data) 53 if (!clk_data)
54 return; 54 return;
55 55
@@ -136,8 +136,8 @@ static void __init imx7ulp_clk_pcc2_init(struct device_node *np)
136 struct clk_hw **clks; 136 struct clk_hw **clks;
137 void __iomem *base; 137 void __iomem *base;
138 138
139 clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws) * 139 clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_PCC2_END),
140 IMX7ULP_CLK_PCC2_END, GFP_KERNEL); 140 GFP_KERNEL);
141 if (!clk_data) 141 if (!clk_data)
142 return; 142 return;
143 143
@@ -183,8 +183,8 @@ static void __init imx7ulp_clk_pcc3_init(struct device_node *np)
183 struct clk_hw **clks; 183 struct clk_hw **clks;
184 void __iomem *base; 184 void __iomem *base;
185 185
186 clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws) * 186 clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_PCC3_END),
187 IMX7ULP_CLK_PCC3_END, GFP_KERNEL); 187 GFP_KERNEL);
188 if (!clk_data) 188 if (!clk_data)
189 return; 189 return;
190 190
@@ -228,8 +228,8 @@ static void __init imx7ulp_clk_smc1_init(struct device_node *np)
228 struct clk_hw **clks; 228 struct clk_hw **clks;
229 void __iomem *base; 229 void __iomem *base;
230 230
231 clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws) * 231 clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_SMC1_END),
232 IMX7ULP_CLK_SMC1_END, GFP_KERNEL); 232 GFP_KERNEL);
233 if (!clk_data) 233 if (!clk_data)
234 return; 234 return;
235 235
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
new file mode 100644
index 000000000000..1ef8438e3d6d
--- /dev/null
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -0,0 +1,675 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2017-2018 NXP.
4 */
5
6#include <dt-bindings/clock/imx8mm-clock.h>
7#include <linux/clk.h>
8#include <linux/err.h>
9#include <linux/init.h>
10#include <linux/io.h>
11#include <linux/module.h>
12#include <linux/of.h>
13#include <linux/of_address.h>
14#include <linux/platform_device.h>
15#include <linux/types.h>
16
17#include "clk.h"
18
19static u32 share_count_sai1;
20static u32 share_count_sai2;
21static u32 share_count_sai3;
22static u32 share_count_sai4;
23static u32 share_count_sai5;
24static u32 share_count_sai6;
25static u32 share_count_dcss;
26static u32 share_count_pdm;
27static u32 share_count_nand;
28
29#define PLL_1416X_RATE(_rate, _m, _p, _s) \
30 { \
31 .rate = (_rate), \
32 .mdiv = (_m), \
33 .pdiv = (_p), \
34 .sdiv = (_s), \
35 }
36
37#define PLL_1443X_RATE(_rate, _m, _p, _s, _k) \
38 { \
39 .rate = (_rate), \
40 .mdiv = (_m), \
41 .pdiv = (_p), \
42 .sdiv = (_s), \
43 .kdiv = (_k), \
44 }
45
46static const struct imx_pll14xx_rate_table imx8mm_pll1416x_tbl[] = {
47 PLL_1416X_RATE(1800000000U, 225, 3, 0),
48 PLL_1416X_RATE(1600000000U, 200, 3, 0),
49 PLL_1416X_RATE(1200000000U, 300, 3, 1),
50 PLL_1416X_RATE(1000000000U, 250, 3, 1),
51 PLL_1416X_RATE(800000000U, 200, 3, 1),
52 PLL_1416X_RATE(750000000U, 250, 2, 2),
53 PLL_1416X_RATE(700000000U, 350, 3, 2),
54 PLL_1416X_RATE(600000000U, 300, 3, 2),
55};
56
57static const struct imx_pll14xx_rate_table imx8mm_audiopll_tbl[] = {
58 PLL_1443X_RATE(786432000U, 655, 5, 2, 23593),
59 PLL_1443X_RATE(722534400U, 301, 5, 1, 3670),
60};
61
62static const struct imx_pll14xx_rate_table imx8mm_videopll_tbl[] = {
63 PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
64 PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
65};
66
67static const struct imx_pll14xx_rate_table imx8mm_drampll_tbl[] = {
68 PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
69};
70
71static struct imx_pll14xx_clk imx8mm_audio_pll __initdata = {
72 .type = PLL_1443X,
73 .rate_table = imx8mm_audiopll_tbl,
74 .rate_count = ARRAY_SIZE(imx8mm_audiopll_tbl),
75};
76
77static struct imx_pll14xx_clk imx8mm_video_pll __initdata = {
78 .type = PLL_1443X,
79 .rate_table = imx8mm_videopll_tbl,
80 .rate_count = ARRAY_SIZE(imx8mm_videopll_tbl),
81};
82
83static struct imx_pll14xx_clk imx8mm_dram_pll __initdata = {
84 .type = PLL_1443X,
85 .rate_table = imx8mm_drampll_tbl,
86 .rate_count = ARRAY_SIZE(imx8mm_drampll_tbl),
87};
88
89static struct imx_pll14xx_clk imx8mm_arm_pll __initdata = {
90 .type = PLL_1416X,
91 .rate_table = imx8mm_pll1416x_tbl,
92 .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
93};
94
95static struct imx_pll14xx_clk imx8mm_gpu_pll __initdata = {
96 .type = PLL_1416X,
97 .rate_table = imx8mm_pll1416x_tbl,
98 .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
99};
100
101static struct imx_pll14xx_clk imx8mm_vpu_pll __initdata = {
102 .type = PLL_1416X,
103 .rate_table = imx8mm_pll1416x_tbl,
104 .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
105};
106
107static struct imx_pll14xx_clk imx8mm_sys_pll __initdata = {
108 .type = PLL_1416X,
109 .rate_table = imx8mm_pll1416x_tbl,
110 .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl),
111};
112
113static const char *pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
114static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
115static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
116static const char *video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
117static const char *dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
118static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
119static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
120static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
121static const char *sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", };
122static const char *sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
123static const char *sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
124
125/* CCM ROOT */
126static const char *imx8mm_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m",
127 "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "sys_pll3_out", };
128
129static const char *imx8mm_m4_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "sys_pll1_266m",
130 "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
131
132static const char *imx8mm_vpu_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m",
133 "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "vpu_pll_out", };
134
135static const char *imx8mm_gpu3d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
136 "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
137
138static const char *imx8mm_gpu2d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out",
139 "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
140
141static const char *imx8mm_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m", "sys_pll2_250m",
142 "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "sys_pll1_100m",};
143
144static const char *imx8mm_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m",
145 "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
146
147static const char *imx8mm_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m",
148 "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", };
149
150static const char *imx8mm_vpu_bus_sels[] = {"osc_24m", "sys_pll1_800m", "vpu_pll_out", "audio_pll2_out",
151 "sys_pll3_out", "sys_pll2_1000m", "sys_pll2_200m", "sys_pll1_100m", };
152
153static const char *imx8mm_disp_axi_sels[] = {"osc_24m", "sys_pll2_1000m", "sys_pll1_800m", "sys_pll3_out",
154 "sys_pll1_40m", "audio_pll2_out", "clk_ext1", "clk_ext4", };
155
156static const char *imx8mm_disp_apb_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll1_800m", "sys_pll3_out",
157 "sys_pll1_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", };
158
159static const char *imx8mm_disp_rtrm_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll2_1000m",
160 "audio_pll1_out", "video_pll1_out", "clk_ext2", "clk_ext3", };
161
162static const char *imx8mm_usb_bus_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_100m",
163 "sys_pll2_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", };
164
165static const char *imx8mm_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
166 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
167
168static const char *imx8mm_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m",
169 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
170
171static const char *imx8mm_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_1000m", "sys_pll2_500m",
172 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
173
174static const char *imx8mm_noc_apb_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll3_out", "sys_pll2_333m", "sys_pll2_200m",
175 "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", };
176
177static const char *imx8mm_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m", "sys_pll1_400m",
178 "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
179
180static const char *imx8mm_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_1000m",
181 "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", };
182
183static const char *imx8mm_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m", "sys_pll2_500m",
184 "sys_pll2_1000m", "sys_pll3_out", "audio_pll1_out", "sys_pll1_266m", };
185
186static const char *imx8mm_dram_apb_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
187 "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
188
189static const char *imx8mm_vpu_g1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
190 "sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
191
192static const char *imx8mm_vpu_g2_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
193 "sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", };
194
195static const char *imx8mm_disp_dtrc_sels[] = {"osc_24m", "video_pll2_out", "sys_pll1_800m", "sys_pll2_1000m",
196 "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
197
198static const char *imx8mm_disp_dc8000_sels[] = {"osc_24m", "video_pll2_out", "sys_pll1_800m", "sys_pll2_1000m",
199 "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", };
200
201static const char *imx8mm_pcie1_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m",
202 "sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", };
203
204static const char *imx8mm_pcie1_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m", "clk_ext1", "clk_ext2",
205 "clk_ext3", "clk_ext4", "sys_pll1_400m", };
206
207static const char *imx8mm_pcie1_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out",
208 "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", };
209
210static const char *imx8mm_dc_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
211 "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
212
213static const char *imx8mm_lcdif_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out",
214 "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
215
216static const char *imx8mm_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
217 "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
218
219static const char *imx8mm_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
220 "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
221
222static const char *imx8mm_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
223 "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
224
225static const char *imx8mm_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
226 "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", };
227
228static const char *imx8mm_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
229 "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
230
231static const char *imx8mm_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
232 "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
233
234static const char *imx8mm_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
235 "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", };
236
237static const char *imx8mm_spdif2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out",
238 "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", };
239
240static const char *imx8mm_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m",
241 "sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
242
243static const char *imx8mm_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "clk_ext1", "clk_ext2",
244 "clk_ext3", "clk_ext4", "video_pll1_out", };
245
246static const char *imx8mm_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m", "sys_pll2_200m",
247 "sys_pll2_500m", "video_pll1_out", "audio_pll2_out", };
248
249static const char *imx8mm_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out", "sys_pll1_400m",
250 "audio_pll2_out", "sys_pll3_out", "sys_pll2_250m", "video_pll1_out", };
251
252static const char *imx8mm_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
253 "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", };
254
255static const char *imx8mm_usdhc1_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
256 "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
257
258static const char *imx8mm_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
259 "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
260
261static const char *imx8mm_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
262 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
263
264static const char *imx8mm_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
265 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
266
267static const char *imx8mm_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
268 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
269
270static const char *imx8mm_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out",
271 "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", };
272
273static const char *imx8mm_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
274 "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
275
276static const char *imx8mm_uart2_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
277 "sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
278
279static const char *imx8mm_uart3_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
280 "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
281
282static const char *imx8mm_uart4_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m",
283 "sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
284
285static const char *imx8mm_usb_core_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m",
286 "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
287
288static const char *imx8mm_usb_phy_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m",
289 "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
290
291static const char *imx8mm_ecspi1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
292 "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
293
294static const char *imx8mm_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
295 "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
296
297static const char *imx8mm_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
298 "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
299
300static const char *imx8mm_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
301 "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", };
302
303static const char *imx8mm_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
304 "sys3_pll2_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
305
306static const char *imx8mm_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m",
307 "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", };
308
309static const char *imx8mm_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", "sys_pll1_40m",
310 "video_pll1_out", "sys_pll1_800m", "audio_pll1_out", "clk_ext1" };
311
312static const char *imx8mm_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m", "vpu_pll_out",
313 "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m", };
314
315static const char *imx8mm_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_out", "sys_pll3_out", "sys_pll2_200m",
316 "sys_pll1_266m", "sys_pll2_500m", "sys_pll1_100m", };
317
318static const char *imx8mm_dsi_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
319 "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
320
321static const char *imx8mm_dsi_phy_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_100m", "sys_pll1_800m",
322 "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
323
324static const char *imx8mm_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_100m", "sys_pll1_800m",
325 "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
326
327static const char *imx8mm_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
328 "sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", };
329
330static const char *imx8mm_csi1_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
331 "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
332
333static const char *imx8mm_csi1_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
334 "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
335
336static const char *imx8mm_csi1_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
337 "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
338
339static const char *imx8mm_csi2_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m",
340 "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", };
341
342static const char *imx8mm_csi2_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m",
343 "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
344
345static const char *imx8mm_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m",
346 "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
347
348static const char *imx8mm_pcie2_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m",
349 "sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", };
350
351static const char *imx8mm_pcie2_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m", "clk_ext1",
352 "clk_ext2", "clk_ext3", "clk_ext4", "sys_pll1_400m", };
353
354static const char *imx8mm_pcie2_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out",
355 "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", };
356
357static const char *imx8mm_ecspi3_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m",
358 "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", };
359
360static const char *imx8mm_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "sys_pll1_800m",
361 "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
362
363static const char *imx8mm_vpu_h1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m",
364 "audio_pll2_clk", "sys_pll2_125m", "sys_pll3_clk", "audio_pll1_out", };
365
366static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
367
368static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m", "sys_pll1_200m", "audio_pll2_clk",
369 "vpu_pll", "sys_pll1_80m", };
370
371static struct clk *clks[IMX8MM_CLK_END];
372static struct clk_onecell_data clk_data;
373
374static struct clk ** const uart_clks[] __initconst = {
375 &clks[IMX8MM_CLK_UART1_ROOT],
376 &clks[IMX8MM_CLK_UART2_ROOT],
377 &clks[IMX8MM_CLK_UART3_ROOT],
378 &clks[IMX8MM_CLK_UART4_ROOT],
379 NULL
380};
381
382static int __init imx8mm_clocks_init(struct device_node *ccm_node)
383{
384 struct device_node *np;
385 void __iomem *base;
386 int ret;
387
388 clks[IMX8MM_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
389 clks[IMX8MM_CLK_24M] = of_clk_get_by_name(ccm_node, "osc_24m");
390 clks[IMX8MM_CLK_32K] = of_clk_get_by_name(ccm_node, "osc_32k");
391 clks[IMX8MM_CLK_EXT1] = of_clk_get_by_name(ccm_node, "clk_ext1");
392 clks[IMX8MM_CLK_EXT2] = of_clk_get_by_name(ccm_node, "clk_ext2");
393 clks[IMX8MM_CLK_EXT3] = of_clk_get_by_name(ccm_node, "clk_ext3");
394 clks[IMX8MM_CLK_EXT4] = of_clk_get_by_name(ccm_node, "clk_ext4");
395
396 np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop");
397 base = of_iomap(np, 0);
398 if (WARN_ON(!base))
399 return -ENOMEM;
400
401 clks[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
402 clks[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
403 clks[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
404 clks[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
405 clks[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
406 clks[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
407 clks[IMX8MM_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
408 clks[IMX8MM_SYS_PLL1_REF_SEL] = imx_clk_mux("sys_pll1_ref_sel", base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
409 clks[IMX8MM_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
410 clks[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
411
412 clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx8mm_audio_pll);
413 clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mm_audio_pll);
414 clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mm_video_pll);
415 clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mm_dram_pll);
416 clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mm_gpu_pll);
417 clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mm_vpu_pll);
418 clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mm_arm_pll);
419 clks[IMX8MM_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mm_sys_pll);
420 clks[IMX8MM_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mm_sys_pll);
421 clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mm_sys_pll);
422
423 /* PLL bypass out */
424 clks[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 4, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
425 clks[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 4, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
426 clks[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 4, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
427 clks[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 4, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
428 clks[IMX8MM_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 4, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
429 clks[IMX8MM_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 4, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
430 clks[IMX8MM_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 4, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
431 clks[IMX8MM_SYS_PLL1_BYPASS] = imx_clk_mux_flags("sys_pll1_bypass", base + 0x94, 4, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
432 clks[IMX8MM_SYS_PLL2_BYPASS] = imx_clk_mux_flags("sys_pll2_bypass", base + 0x104, 4, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
433 clks[IMX8MM_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 4, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
434
435 /* unbypass all the plls */
436 clk_set_parent(clks[IMX8MM_AUDIO_PLL1_BYPASS], clks[IMX8MM_AUDIO_PLL1]);
437 clk_set_parent(clks[IMX8MM_AUDIO_PLL2_BYPASS], clks[IMX8MM_AUDIO_PLL2]);
438 clk_set_parent(clks[IMX8MM_VIDEO_PLL1_BYPASS], clks[IMX8MM_VIDEO_PLL1]);
439 clk_set_parent(clks[IMX8MM_DRAM_PLL_BYPASS], clks[IMX8MM_DRAM_PLL]);
440 clk_set_parent(clks[IMX8MM_GPU_PLL_BYPASS], clks[IMX8MM_GPU_PLL]);
441 clk_set_parent(clks[IMX8MM_VPU_PLL_BYPASS], clks[IMX8MM_VPU_PLL]);
442 clk_set_parent(clks[IMX8MM_ARM_PLL_BYPASS], clks[IMX8MM_ARM_PLL]);
443 clk_set_parent(clks[IMX8MM_SYS_PLL1_BYPASS], clks[IMX8MM_SYS_PLL1]);
444 clk_set_parent(clks[IMX8MM_SYS_PLL2_BYPASS], clks[IMX8MM_SYS_PLL2]);
445 clk_set_parent(clks[IMX8MM_SYS_PLL3_BYPASS], clks[IMX8MM_SYS_PLL3]);
446
447 /* PLL out gate */
448 clks[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
449 clks[IMX8MM_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
450 clks[IMX8MM_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
451 clks[IMX8MM_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
452 clks[IMX8MM_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 13);
453 clks[IMX8MM_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 13);
454 clks[IMX8MM_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 13);
455 clks[IMX8MM_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1_bypass", base + 0x94, 13);
456 clks[IMX8MM_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2_bypass", base + 0x104, 13);
457 clks[IMX8MM_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 13);
458
459 /* SYS PLL fixed output */
460 clks[IMX8MM_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
461 clks[IMX8MM_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
462 clks[IMX8MM_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
463 clks[IMX8MM_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
464 clks[IMX8MM_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
465 clks[IMX8MM_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
466 clks[IMX8MM_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
467 clks[IMX8MM_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
468 clks[IMX8MM_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
469
470 clks[IMX8MM_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
471 clks[IMX8MM_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
472 clks[IMX8MM_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
473 clks[IMX8MM_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
474 clks[IMX8MM_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
475 clks[IMX8MM_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
476 clks[IMX8MM_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
477 clks[IMX8MM_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
478 clks[IMX8MM_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
479
480 np = ccm_node;
481 base = of_iomap(np, 0);
482 if (WARN_ON(!base))
483 return -ENOMEM;
484
485 /* Core Slice */
486 clks[IMX8MM_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels));
487 clks[IMX8MM_CLK_M4_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mm_m4_sels, ARRAY_SIZE(imx8mm_m4_sels));
488 clks[IMX8MM_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mm_vpu_sels, ARRAY_SIZE(imx8mm_vpu_sels));
489 clks[IMX8MM_CLK_GPU3D_SRC] = imx_clk_mux2("gpu3d_src", base + 0x8180, 24, 3, imx8mm_gpu3d_sels, ARRAY_SIZE(imx8mm_gpu3d_sels));
490 clks[IMX8MM_CLK_GPU2D_SRC] = imx_clk_mux2("gpu2d_src", base + 0x8200, 24, 3, imx8mm_gpu2d_sels, ARRAY_SIZE(imx8mm_gpu2d_sels));
491 clks[IMX8MM_CLK_A53_CG] = imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
492 clks[IMX8MM_CLK_M4_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
493 clks[IMX8MM_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
494 clks[IMX8MM_CLK_GPU3D_CG] = imx_clk_gate3("gpu3d_cg", "gpu3d_src", base + 0x8180, 28);
495 clks[IMX8MM_CLK_GPU2D_CG] = imx_clk_gate3("gpu2d_cg", "gpu2d_src", base + 0x8200, 28);
496 clks[IMX8MM_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
497 clks[IMX8MM_CLK_M4_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
498 clks[IMX8MM_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
499 clks[IMX8MM_CLK_GPU3D_DIV] = imx_clk_divider2("gpu3d_div", "gpu3d_cg", base + 0x8180, 0, 3);
500 clks[IMX8MM_CLK_GPU2D_DIV] = imx_clk_divider2("gpu2d_div", "gpu2d_cg", base + 0x8200, 0, 3);
501
502 /* BUS */
503 clks[IMX8MM_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mm_main_axi_sels, base + 0x8800);
504 clks[IMX8MM_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mm_enet_axi_sels, base + 0x8880);
505 clks[IMX8MM_CLK_NAND_USDHC_BUS] = imx8m_clk_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900);
506 clks[IMX8MM_CLK_VPU_BUS] = imx8m_clk_composite("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980);
507 clks[IMX8MM_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00);
508 clks[IMX8MM_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80);
509 clks[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_composite("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00);
510 clks[IMX8MM_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80);
511 clks[IMX8MM_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00);
512 clks[IMX8MM_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80);
513 clks[IMX8MM_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mm_noc_sels, base + 0x8d00);
514 clks[IMX8MM_CLK_NOC_APB] = imx8m_clk_composite_critical("noc_apb", imx8mm_noc_apb_sels, base + 0x8d80);
515
516 /* AHB */
517 clks[IMX8MM_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mm_ahb_sels, base + 0x9000);
518 clks[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100);
519
520 /* IPG */
521 clks[IMX8MM_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
522 clks[IMX8MM_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
523
524 /* IP */
525 clks[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000);
526 clks[IMX8MM_CLK_DRAM_APB] = imx8m_clk_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080);
527 clks[IMX8MM_CLK_VPU_G1] = imx8m_clk_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100);
528 clks[IMX8MM_CLK_VPU_G2] = imx8m_clk_composite("vpu_g2", imx8mm_vpu_g2_sels, base + 0xa180);
529 clks[IMX8MM_CLK_DISP_DTRC] = imx8m_clk_composite("disp_dtrc", imx8mm_disp_dtrc_sels, base + 0xa200);
530 clks[IMX8MM_CLK_DISP_DC8000] = imx8m_clk_composite("disp_dc8000", imx8mm_disp_dc8000_sels, base + 0xa280);
531 clks[IMX8MM_CLK_PCIE1_CTRL] = imx8m_clk_composite("pcie1_ctrl", imx8mm_pcie1_ctrl_sels, base + 0xa300);
532 clks[IMX8MM_CLK_PCIE1_PHY] = imx8m_clk_composite("pcie1_phy", imx8mm_pcie1_phy_sels, base + 0xa380);
533 clks[IMX8MM_CLK_PCIE1_AUX] = imx8m_clk_composite("pcie1_aux", imx8mm_pcie1_aux_sels, base + 0xa400);
534 clks[IMX8MM_CLK_DC_PIXEL] = imx8m_clk_composite("dc_pixel", imx8mm_dc_pixel_sels, base + 0xa480);
535 clks[IMX8MM_CLK_LCDIF_PIXEL] = imx8m_clk_composite("lcdif_pixel", imx8mm_lcdif_pixel_sels, base + 0xa500);
536 clks[IMX8MM_CLK_SAI1] = imx8m_clk_composite("sai1", imx8mm_sai1_sels, base + 0xa580);
537 clks[IMX8MM_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mm_sai2_sels, base + 0xa600);
538 clks[IMX8MM_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mm_sai3_sels, base + 0xa680);
539 clks[IMX8MM_CLK_SAI4] = imx8m_clk_composite("sai4", imx8mm_sai4_sels, base + 0xa700);
540 clks[IMX8MM_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mm_sai5_sels, base + 0xa780);
541 clks[IMX8MM_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mm_sai6_sels, base + 0xa800);
542 clks[IMX8MM_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mm_spdif1_sels, base + 0xa880);
543 clks[IMX8MM_CLK_SPDIF2] = imx8m_clk_composite("spdif2", imx8mm_spdif2_sels, base + 0xa900);
544 clks[IMX8MM_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mm_enet_ref_sels, base + 0xa980);
545 clks[IMX8MM_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mm_enet_timer_sels, base + 0xaa00);
546 clks[IMX8MM_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mm_enet_phy_sels, base + 0xaa80);
547 clks[IMX8MM_CLK_NAND] = imx8m_clk_composite("nand", imx8mm_nand_sels, base + 0xab00);
548 clks[IMX8MM_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mm_qspi_sels, base + 0xab80);
549 clks[IMX8MM_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mm_usdhc1_sels, base + 0xac00);
550 clks[IMX8MM_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mm_usdhc2_sels, base + 0xac80);
551 clks[IMX8MM_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mm_i2c1_sels, base + 0xad00);
552 clks[IMX8MM_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mm_i2c2_sels, base + 0xad80);
553 clks[IMX8MM_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mm_i2c3_sels, base + 0xae00);
554 clks[IMX8MM_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mm_i2c4_sels, base + 0xae80);
555 clks[IMX8MM_CLK_UART1] = imx8m_clk_composite("uart1", imx8mm_uart1_sels, base + 0xaf00);
556 clks[IMX8MM_CLK_UART2] = imx8m_clk_composite("uart2", imx8mm_uart2_sels, base + 0xaf80);
557 clks[IMX8MM_CLK_UART3] = imx8m_clk_composite("uart3", imx8mm_uart3_sels, base + 0xb000);
558 clks[IMX8MM_CLK_UART4] = imx8m_clk_composite("uart4", imx8mm_uart4_sels, base + 0xb080);
559 clks[IMX8MM_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100);
560 clks[IMX8MM_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180);
561 clks[IMX8MM_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280);
562 clks[IMX8MM_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300);
563 clks[IMX8MM_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380);
564 clks[IMX8MM_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mm_pwm2_sels, base + 0xb400);
565 clks[IMX8MM_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mm_pwm3_sels, base + 0xb480);
566 clks[IMX8MM_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mm_pwm4_sels, base + 0xb500);
567 clks[IMX8MM_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mm_gpt1_sels, base + 0xb580);
568 clks[IMX8MM_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mm_wdog_sels, base + 0xb900);
569 clks[IMX8MM_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mm_wrclk_sels, base + 0xb980);
570 clks[IMX8MM_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mm_clko1_sels, base + 0xba00);
571 clks[IMX8MM_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mm_dsi_core_sels, base + 0xbb00);
572 clks[IMX8MM_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mm_dsi_phy_sels, base + 0xbb80);
573 clks[IMX8MM_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mm_dsi_dbi_sels, base + 0xbc00);
574 clks[IMX8MM_CLK_USDHC3] = imx8m_clk_composite("usdhc3", imx8mm_usdhc3_sels, base + 0xbc80);
575 clks[IMX8MM_CLK_CSI1_CORE] = imx8m_clk_composite("csi1_core", imx8mm_csi1_core_sels, base + 0xbd00);
576 clks[IMX8MM_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mm_csi1_phy_sels, base + 0xbd80);
577 clks[IMX8MM_CLK_CSI1_ESC] = imx8m_clk_composite("csi1_esc", imx8mm_csi1_esc_sels, base + 0xbe00);
578 clks[IMX8MM_CLK_CSI2_CORE] = imx8m_clk_composite("csi2_core", imx8mm_csi2_core_sels, base + 0xbe80);
579 clks[IMX8MM_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mm_csi2_phy_sels, base + 0xbf00);
580 clks[IMX8MM_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mm_csi2_esc_sels, base + 0xbf80);
581 clks[IMX8MM_CLK_PCIE2_CTRL] = imx8m_clk_composite("pcie2_ctrl", imx8mm_pcie2_ctrl_sels, base + 0xc000);
582 clks[IMX8MM_CLK_PCIE2_PHY] = imx8m_clk_composite("pcie2_phy", imx8mm_pcie2_phy_sels, base + 0xc080);
583 clks[IMX8MM_CLK_PCIE2_AUX] = imx8m_clk_composite("pcie2_aux", imx8mm_pcie2_aux_sels, base + 0xc100);
584 clks[IMX8MM_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mm_ecspi3_sels, base + 0xc180);
585 clks[IMX8MM_CLK_PDM] = imx8m_clk_composite("pdm", imx8mm_pdm_sels, base + 0xc200);
586 clks[IMX8MM_CLK_VPU_H1] = imx8m_clk_composite("vpu_h1", imx8mm_vpu_h1_sels, base + 0xc280);
587
588 /* CCGR */
589 clks[IMX8MM_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
590 clks[IMX8MM_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
591 clks[IMX8MM_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
592 clks[IMX8MM_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
593 clks[IMX8MM_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
594 clks[IMX8MM_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
595 clks[IMX8MM_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
596 clks[IMX8MM_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
597 clks[IMX8MM_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
598 clks[IMX8MM_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
599 clks[IMX8MM_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
600 clks[IMX8MM_CLK_PCIE1_ROOT] = imx_clk_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0);
601 clks[IMX8MM_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
602 clks[IMX8MM_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
603 clks[IMX8MM_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
604 clks[IMX8MM_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
605 clks[IMX8MM_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
606 clks[IMX8MM_CLK_NAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
607 clks[IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
608 clks[IMX8MM_CLK_SAI1_ROOT] = imx_clk_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1);
609 clks[IMX8MM_CLK_SAI1_IPG] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1);
610 clks[IMX8MM_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
611 clks[IMX8MM_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2);
612 clks[IMX8MM_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
613 clks[IMX8MM_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3);
614 clks[IMX8MM_CLK_SAI4_ROOT] = imx_clk_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4);
615 clks[IMX8MM_CLK_SAI4_IPG] = imx_clk_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4);
616 clks[IMX8MM_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
617 clks[IMX8MM_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
618 clks[IMX8MM_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
619 clks[IMX8MM_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
620 clks[IMX8MM_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
621 clks[IMX8MM_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
622 clks[IMX8MM_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
623 clks[IMX8MM_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
624 clks[IMX8MM_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref", base + 0x44d0, 0);
625 clks[IMX8MM_CLK_GPU3D_ROOT] = imx_clk_gate4("gpu3d_root_clk", "gpu3d_div", base + 0x44f0, 0);
626 clks[IMX8MM_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
627 clks[IMX8MM_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
628 clks[IMX8MM_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
629 clks[IMX8MM_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
630 clks[IMX8MM_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
631 clks[IMX8MM_CLK_VPU_G1_ROOT] = imx_clk_gate4("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0);
632 clks[IMX8MM_CLK_GPU_BUS_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0);
633 clks[IMX8MM_CLK_VPU_H1_ROOT] = imx_clk_gate4("vpu_h1_root_clk", "vpu_h1", base + 0x4590, 0);
634 clks[IMX8MM_CLK_VPU_G2_ROOT] = imx_clk_gate4("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0);
635 clks[IMX8MM_CLK_PDM_ROOT] = imx_clk_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm);
636 clks[IMX8MM_CLK_PDM_IPG] = imx_clk_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
637 clks[IMX8MM_CLK_DISP_ROOT] = imx_clk_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_dcss);
638 clks[IMX8MM_CLK_DISP_AXI_ROOT] = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss);
639 clks[IMX8MM_CLK_DISP_APB_ROOT] = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss);
640 clks[IMX8MM_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss);
641 clks[IMX8MM_CLK_USDHC3_ROOT] = imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0);
642 clks[IMX8MM_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
643 clks[IMX8MM_CLK_VPU_DEC_ROOT] = imx_clk_gate4("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0);
644 clks[IMX8MM_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
645 clks[IMX8MM_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
646 clks[IMX8MM_CLK_SDMA3_ROOT] = imx_clk_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
647 clks[IMX8MM_CLK_GPU2D_ROOT] = imx_clk_gate4("gpu2d_root_clk", "gpu2d_div", base + 0x4660, 0);
648 clks[IMX8MM_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
649
650 clks[IMX8MM_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc_24m", 1, 8);
651
652 clks[IMX8MM_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
653 clks[IMX8MM_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mm_dram_core_sels, ARRAY_SIZE(imx8mm_dram_core_sels), CLK_IS_CRITICAL);
654
655 clks[IMX8MM_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
656 clks[IMX8MM_CLK_A53_DIV],
657 clks[IMX8MM_CLK_A53_SRC],
658 clks[IMX8MM_ARM_PLL_OUT],
659 clks[IMX8MM_CLK_24M]);
660
661 imx_check_clocks(clks, ARRAY_SIZE(clks));
662
663 clk_data.clks = clks;
664 clk_data.clk_num = ARRAY_SIZE(clks);
665 ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
666 if (ret < 0) {
667 pr_err("failed to register clks for i.MX8MM\n");
668 return -EINVAL;
669 }
670
671 imx_register_uart_clocks(uart_clks);
672
673 return 0;
674}
675CLK_OF_DECLARE_DRIVER(imx8mm, "fsl,imx8mm-ccm", imx8mm_clocks_init);
diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
index 26b57f43ccc3..a9b3888aef0c 100644
--- a/drivers/clk/imx/clk-imx8mq.c
+++ b/drivers/clk/imx/clk-imx8mq.c
@@ -26,246 +26,246 @@ static u32 share_count_nand;
26 26
27static struct clk *clks[IMX8MQ_CLK_END]; 27static struct clk *clks[IMX8MQ_CLK_END];
28 28
29static const char *pll_ref_sels[] = { "osc_25m", "osc_27m", "dummy", "dummy", }; 29static const char * const pll_ref_sels[] = { "osc_25m", "osc_27m", "dummy", "dummy", };
30static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", }; 30static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
31static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", }; 31static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
32static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", }; 32static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
33static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", }; 33static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
34static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", }; 34static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
35static const char *video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", }; 35static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
36 36
37static const char *sys1_pll1_out_sels[] = {"sys1_pll1", "sys1_pll1_ref_sel", }; 37static const char * const sys1_pll_out_sels[] = {"sys1_pll1_ref_sel", };
38static const char *sys2_pll1_out_sels[] = {"sys2_pll1", "sys1_pll1_ref_sel", }; 38static const char * const sys2_pll_out_sels[] = {"sys1_pll1_ref_sel", "sys2_pll1_ref_sel", };
39static const char *sys3_pll1_out_sels[] = {"sys3_pll1", "sys3_pll1_ref_sel", }; 39static const char * const sys3_pll_out_sels[] = {"sys3_pll1_ref_sel", "sys2_pll1_ref_sel", };
40static const char *dram_pll1_out_sels[] = {"dram_pll1", "dram_pll1_ref_sel", }; 40static const char * const dram_pll_out_sels[] = {"dram_pll1_ref_sel", };
41
42static const char *sys1_pll2_out_sels[] = {"sys1_pll2_div", "sys1_pll1_ref_sel", };
43static const char *sys2_pll2_out_sels[] = {"sys2_pll2_div", "sys2_pll1_ref_sel", };
44static const char *sys3_pll2_out_sels[] = {"sys3_pll2_div", "sys2_pll1_ref_sel", };
45static const char *dram_pll2_out_sels[] = {"dram_pll2_div", "dram_pll1_ref_sel", };
46 41
47/* CCM ROOT */ 42/* CCM ROOT */
48static const char *imx8mq_a53_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m", 43static const char * const imx8mq_a53_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m",
49 "sys1_pll_800m", "sys1_pll_400m", "audio_pll1_out", "sys3_pll2_out", }; 44 "sys1_pll_800m", "sys1_pll_400m", "audio_pll1_out", "sys3_pll2_out", };
50 45
51static const char *imx8mq_vpu_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m", 46static const char * const imx8mq_arm_m4_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_250m", "sys1_pll_266m",
47 "sys1_pll_800m", "audio_pll1_out", "video_pll1_out", "sys3_pll2_out", };
48
49static const char * const imx8mq_vpu_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m",
52 "sys1_pll_800m", "sys1_pll_400m", "audio_pll1_out", "vpu_pll_out", }; 50 "sys1_pll_800m", "sys1_pll_400m", "audio_pll1_out", "vpu_pll_out", };
53 51
54static const char *imx8mq_gpu_core_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll2_out", 52static const char * const imx8mq_gpu_core_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll2_out",
55 "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; 53 "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
56 54
57static const char *imx8mq_gpu_shader_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll2_out", 55static const char * const imx8mq_gpu_shader_sels[] = {"osc_25m", "gpu_pll_out", "sys1_pll_800m", "sys3_pll2_out",
58 "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; 56 "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
59 57
60static const char *imx8mq_main_axi_sels[] = {"osc_25m", "sys2_pll_333m", "sys1_pll_800m", "sys2_pll_250m", 58static const char * const imx8mq_main_axi_sels[] = {"osc_25m", "sys2_pll_333m", "sys1_pll_800m", "sys2_pll_250m",
61 "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "sys1_pll_100m",}; 59 "sys2_pll_1000m", "audio_pll1_out", "video_pll1_out", "sys1_pll_100m",};
62 60
63static const char *imx8mq_enet_axi_sels[] = {"osc_25m", "sys1_pll_266m", "sys1_pll_800m", "sys2_pll_250m", 61static const char * const imx8mq_enet_axi_sels[] = {"osc_25m", "sys1_pll_266m", "sys1_pll_800m", "sys2_pll_250m",
64 "sys2_pll_200m", "audio_pll1_out", "video_pll1_out", "sys3_pll2_out", }; 62 "sys2_pll_200m", "audio_pll1_out", "video_pll1_out", "sys3_pll2_out", };
65 63
66static const char *imx8mq_nand_usdhc_sels[] = {"osc_25m", "sys1_pll_266m", "sys1_pll_800m", "sys2_pll_200m", 64static const char * const imx8mq_nand_usdhc_sels[] = {"osc_25m", "sys1_pll_266m", "sys1_pll_800m", "sys2_pll_200m",
67 "sys1_pll_133m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll1_out", }; 65 "sys1_pll_133m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll1_out", };
68 66
69static const char *imx8mq_vpu_bus_sels[] = {"osc_25m", "sys1_pll_800m", "vpu_pll_out", "audio_pll2_out", "sys3_pll2_out", "sys2_pll_1000m", "sys2_pll_200m", "sys1_pll_100m", }; 67static const char * const imx8mq_vpu_bus_sels[] = {"osc_25m", "sys1_pll_800m", "vpu_pll_out", "audio_pll2_out", "sys3_pll2_out", "sys2_pll_1000m", "sys2_pll_200m", "sys1_pll_100m", };
70 68
71static const char *imx8mq_disp_axi_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll2_out", "sys1_pll_400m", "audio_pll2_out", "clk_ext1", "clk_ext4", }; 69static const char * const imx8mq_disp_axi_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll2_out", "sys1_pll_400m", "audio_pll2_out", "clk_ext1", "clk_ext4", };
72 70
73static const char *imx8mq_disp_apb_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll2_out", 71static const char * const imx8mq_disp_apb_sels[] = {"osc_25m", "sys2_pll_125m", "sys1_pll_800m", "sys3_pll2_out",
74 "sys1_pll_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", }; 72 "sys1_pll_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", };
75 73
76static const char *imx8mq_disp_rtrm_sels[] = {"osc_25m", "sys1_pll_800m", "sys2_pll_200m", "sys1_pll_400m", 74static const char * const imx8mq_disp_rtrm_sels[] = {"osc_25m", "sys1_pll_800m", "sys2_pll_200m", "sys1_pll_400m",
77 "audio_pll1_out", "video_pll1_out", "clk_ext2", "clk_ext3", }; 75 "audio_pll1_out", "video_pll1_out", "clk_ext2", "clk_ext3", };
78 76
79static const char *imx8mq_usb_bus_sels[] = {"osc_25m", "sys2_pll_500m", "sys1_pll_800m", "sys2_pll_100m", 77static const char * const imx8mq_usb_bus_sels[] = {"osc_25m", "sys2_pll_500m", "sys1_pll_800m", "sys2_pll_100m",
80 "sys2_pll_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", }; 78 "sys2_pll_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", };
81 79
82static const char *imx8mq_gpu_axi_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll2_out", "sys2_pll_1000m", 80static const char * const imx8mq_gpu_axi_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll2_out", "sys2_pll_1000m",
83 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; 81 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
84 82
85static const char *imx8mq_gpu_ahb_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll2_out", "sys2_pll_1000m", 83static const char * const imx8mq_gpu_ahb_sels[] = {"osc_25m", "sys1_pll_800m", "gpu_pll_out", "sys3_pll2_out", "sys2_pll_1000m",
86 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; 84 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
87 85
88static const char *imx8mq_noc_sels[] = {"osc_25m", "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_1000m", "sys2_pll_500m", 86static const char * const imx8mq_noc_sels[] = {"osc_25m", "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_1000m", "sys2_pll_500m",
89 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; 87 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
90 88
91static const char *imx8mq_noc_apb_sels[] = {"osc_25m", "sys1_pll_400m", "sys3_pll2_out", "sys2_pll_333m", "sys2_pll_200m", 89static const char * const imx8mq_noc_apb_sels[] = {"osc_25m", "sys1_pll_400m", "sys3_pll2_out", "sys2_pll_333m", "sys2_pll_200m",
92 "sys1_pll_800m", "audio_pll1_out", "video_pll1_out", }; 90 "sys1_pll_800m", "audio_pll1_out", "video_pll1_out", };
93 91
94static const char *imx8mq_ahb_sels[] = {"osc_25m", "sys1_pll_133m", "sys1_pll_800m", "sys1_pll_400m", 92static const char * const imx8mq_ahb_sels[] = {"osc_25m", "sys1_pll_133m", "sys1_pll_800m", "sys1_pll_400m",
95 "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", }; 93 "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", };
96 94
97static const char *imx8mq_audio_ahb_sels[] = {"osc_25m", "sys2_pll_500m", "sys1_pll_800m", "sys2_pll_1000m", 95static const char * const imx8mq_audio_ahb_sels[] = {"osc_25m", "sys2_pll_500m", "sys1_pll_800m", "sys2_pll_1000m",
98 "sys2_pll_166m", "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", }; 96 "sys2_pll_166m", "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", };
99 97
100static const char *imx8mq_dsi_ahb_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m", 98static const char * const imx8mq_dsi_ahb_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
101 "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out"}; 99 "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out"};
102 100
103static const char *imx8mq_dram_alt_sels[] = {"osc_25m", "sys1_pll_800m", "sys1_pll_100m", "sys2_pll_500m", 101static const char * const imx8mq_dram_alt_sels[] = {"osc_25m", "sys1_pll_800m", "sys1_pll_100m", "sys2_pll_500m",
104 "sys2_pll_250m", "sys1_pll_400m", "audio_pll1_out", "sys1_pll_266m", }; 102 "sys2_pll_250m", "sys1_pll_400m", "audio_pll1_out", "sys1_pll_266m", };
105 103
106static const char *imx8mq_dram_apb_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m", 104static const char * const imx8mq_dram_apb_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
107 "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", }; 105 "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
108 106
109static const char *imx8mq_vpu_g1_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_100m", "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", }; 107static const char * const imx8mq_vpu_g1_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_100m", "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", };
110 108
111static const char *imx8mq_vpu_g2_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_100m", "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", }; 109static const char * const imx8mq_vpu_g2_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_100m", "sys2_pll_125m", "sys3_pll2_out", "audio_pll1_out", };
112 110
113static const char *imx8mq_disp_dtrc_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", "sys2_pll_100m", "sys3_pll2_out", "audio_pll2_out", }; 111static const char * const imx8mq_disp_dtrc_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", "sys2_pll_100m", "sys3_pll2_out", "audio_pll2_out", };
114 112
115static const char *imx8mq_disp_dc8000_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", "sys2_pll_100m", "sys3_pll2_out", "audio_pll2_out", }; 113static const char * const imx8mq_disp_dc8000_sels[] = {"osc_25m", "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", "sys2_pll_100m", "sys3_pll2_out", "audio_pll2_out", };
116 114
117static const char *imx8mq_pcie1_ctrl_sels[] = {"osc_25m", "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m", 115static const char * const imx8mq_pcie1_ctrl_sels[] = {"osc_25m", "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m",
118 "sys1_pll_800m", "sys2_pll_500m", "sys2_pll_250m", "sys3_pll2_out", }; 116 "sys1_pll_800m", "sys2_pll_500m", "sys2_pll_250m", "sys3_pll2_out", };
119 117
120static const char *imx8mq_pcie1_phy_sels[] = {"osc_25m", "sys2_pll_100m", "sys2_pll_500m", "clk_ext1", "clk_ext2", 118static const char * const imx8mq_pcie1_phy_sels[] = {"osc_25m", "sys2_pll_100m", "sys2_pll_500m", "clk_ext1", "clk_ext2",
121 "clk_ext3", "clk_ext4", }; 119 "clk_ext3", "clk_ext4", };
122 120
123static const char *imx8mq_pcie1_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_500m", "sys3_pll2_out", 121static const char * const imx8mq_pcie1_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_500m", "sys3_pll2_out",
124 "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_160m", "sys1_pll_200m", }; 122 "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_160m", "sys1_pll_200m", };
125 123
126static const char *imx8mq_dc_pixel_sels[] = {"osc_25m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", "sys2_pll_1000m", "sys3_pll2_out", "clk_ext4", }; 124static const char * const imx8mq_dc_pixel_sels[] = {"osc_25m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", "sys2_pll_1000m", "sys3_pll2_out", "clk_ext4", };
127 125
128static const char *imx8mq_lcdif_pixel_sels[] = {"osc_25m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", "sys2_pll_1000m", "sys3_pll2_out", "clk_ext4", }; 126static const char * const imx8mq_lcdif_pixel_sels[] = {"osc_25m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", "sys2_pll_1000m", "sys3_pll2_out", "clk_ext4", };
129 127
130static const char *imx8mq_sai1_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext1", "clk_ext2", }; 128static const char * const imx8mq_sai1_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext1", "clk_ext2", };
131 129
132static const char *imx8mq_sai2_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", }; 130static const char * const imx8mq_sai2_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", };
133 131
134static const char *imx8mq_sai3_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", }; 132static const char * const imx8mq_sai3_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", };
135 133
136static const char *imx8mq_sai4_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext1", "clk_ext2", }; 134static const char * const imx8mq_sai4_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext1", "clk_ext2", };
137 135
138static const char *imx8mq_sai5_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", }; 136static const char * const imx8mq_sai5_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", };
139 137
140static const char *imx8mq_sai6_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", }; 138static const char * const imx8mq_sai6_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", };
141 139
142static const char *imx8mq_spdif1_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", }; 140static const char * const imx8mq_spdif1_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext2", "clk_ext3", };
143 141
144static const char *imx8mq_spdif2_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", }; 142static const char * const imx8mq_spdif2_sels[] = {"osc_25m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys1_pll_133m", "osc_27m", "clk_ext3", "clk_ext4", };
145 143
146static const char *imx8mq_enet_ref_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_500m", "sys2_pll_100m", 144static const char * const imx8mq_enet_ref_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_500m", "sys2_pll_100m",
147 "sys1_pll_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", }; 145 "sys1_pll_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
148 146
149static const char *imx8mq_enet_timer_sels[] = {"osc_25m", "sys2_pll_100m", "audio_pll1_out", "clk_ext1", "clk_ext2", 147static const char * const imx8mq_enet_timer_sels[] = {"osc_25m", "sys2_pll_100m", "audio_pll1_out", "clk_ext1", "clk_ext2",
150 "clk_ext3", "clk_ext4", "video_pll1_out", }; 148 "clk_ext3", "clk_ext4", "video_pll1_out", };
151 149
152static const char *imx8mq_enet_phy_sels[] = {"osc_25m", "sys2_pll_50m", "sys2_pll_125m", "sys2_pll_500m", 150static const char * const imx8mq_enet_phy_sels[] = {"osc_25m", "sys2_pll_50m", "sys2_pll_125m", "sys2_pll_500m",
153 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; 151 "audio_pll1_out", "video_pll1_out", "audio_pll2_out", };
154 152
155static const char *imx8mq_nand_sels[] = {"osc_25m", "sys2_pll_500m", "audio_pll1_out", "sys1_pll_400m", 153static const char * const imx8mq_nand_sels[] = {"osc_25m", "sys2_pll_500m", "audio_pll1_out", "sys1_pll_400m",
156 "audio_pll2_out", "sys3_pll2_out", "sys2_pll_250m", "video_pll1_out", }; 154 "audio_pll2_out", "sys3_pll2_out", "sys2_pll_250m", "video_pll1_out", };
157 155
158static const char *imx8mq_qspi_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m", 156static const char * const imx8mq_qspi_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
159 "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", }; 157 "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", };
160 158
161static const char *imx8mq_usdhc1_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m", 159static const char * const imx8mq_usdhc1_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
162 "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", }; 160 "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", };
163 161
164static const char *imx8mq_usdhc2_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m", 162static const char * const imx8mq_usdhc2_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
165 "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", }; 163 "audio_pll2_out", "sys1_pll_266m", "sys3_pll2_out", "sys1_pll_100m", };
166 164
167static const char *imx8mq_i2c1_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out", 165static const char * const imx8mq_i2c1_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
168 "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", }; 166 "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
169 167
170static const char *imx8mq_i2c2_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out", 168static const char * const imx8mq_i2c2_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
171 "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", }; 169 "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
172 170
173static const char *imx8mq_i2c3_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out", 171static const char * const imx8mq_i2c3_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
174 "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", }; 172 "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
175 173
176static const char *imx8mq_i2c4_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out", 174static const char * const imx8mq_i2c4_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll2_out", "audio_pll1_out",
177 "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", }; 175 "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
178 176
179static const char *imx8mq_uart1_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m", 177static const char * const imx8mq_uart1_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
180 "sys3_pll2_out", "clk_ext2", "clk_ext4", "audio_pll2_out", }; 178 "sys3_pll2_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
181 179
182static const char *imx8mq_uart2_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m", 180static const char * const imx8mq_uart2_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
183 "sys3_pll2_out", "clk_ext2", "clk_ext3", "audio_pll2_out", }; 181 "sys3_pll2_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
184 182
185static const char *imx8mq_uart3_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m", 183static const char * const imx8mq_uart3_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
186 "sys3_pll2_out", "clk_ext2", "clk_ext4", "audio_pll2_out", }; 184 "sys3_pll2_out", "clk_ext2", "clk_ext4", "audio_pll2_out", };
187 185
188static const char *imx8mq_uart4_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m", 186static const char * const imx8mq_uart4_sels[] = {"osc_25m", "sys1_pll_80m", "sys2_pll_200m", "sys2_pll_100m",
189 "sys3_pll2_out", "clk_ext2", "clk_ext3", "audio_pll2_out", }; 187 "sys3_pll2_out", "clk_ext2", "clk_ext3", "audio_pll2_out", };
190 188
191static const char *imx8mq_usb_core_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m", 189static const char * const imx8mq_usb_core_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m",
192 "sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; 190 "sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
193 191
194static const char *imx8mq_usb_phy_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m", 192static const char * const imx8mq_usb_phy_sels[] = {"osc_25m", "sys1_pll_100m", "sys1_pll_40m", "sys2_pll_100m",
195 "sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; 193 "sys2_pll_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
196 194
197static const char *imx8mq_ecspi1_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m", 195static const char * const imx8mq_ecspi1_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
198 "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", }; 196 "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
199 197
200static const char *imx8mq_ecspi2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m", 198static const char * const imx8mq_ecspi2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
201 "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", }; 199 "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
202 200
203static const char *imx8mq_pwm1_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m", 201static const char * const imx8mq_pwm1_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
204 "sys3_pll2_out", "clk_ext1", "sys1_pll_80m", "video_pll1_out", }; 202 "sys3_pll2_out", "clk_ext1", "sys1_pll_80m", "video_pll1_out", };
205 203
206static const char *imx8mq_pwm2_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m", 204static const char * const imx8mq_pwm2_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
207 "sys3_pll2_out", "clk_ext1", "sys1_pll_80m", "video_pll1_out", }; 205 "sys3_pll2_out", "clk_ext1", "sys1_pll_80m", "video_pll1_out", };
208 206
209static const char *imx8mq_pwm3_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m", 207static const char * const imx8mq_pwm3_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
210 "sys3_pll2_out", "clk_ext2", "sys1_pll_80m", "video_pll1_out", }; 208 "sys3_pll2_out", "clk_ext2", "sys1_pll_80m", "video_pll1_out", };
211 209
212static const char *imx8mq_pwm4_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m", 210static const char * const imx8mq_pwm4_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_160m", "sys1_pll_40m",
213 "sys3_pll2_out", "clk_ext2", "sys1_pll_80m", "video_pll1_out", }; 211 "sys3_pll2_out", "clk_ext2", "sys1_pll_80m", "video_pll1_out", };
214 212
215static const char *imx8mq_gpt1_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_400m", "sys1_pll_40m", 213static const char * const imx8mq_gpt1_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_400m", "sys1_pll_40m",
216 "sys1_pll_80m", "audio_pll1_out", "clk_ext1", }; 214 "sys1_pll_80m", "audio_pll1_out", "clk_ext1", };
217 215
218static const char *imx8mq_wdog_sels[] = {"osc_25m", "sys1_pll_133m", "sys1_pll_160m", "vpu_pll_out", 216static const char * const imx8mq_wdog_sels[] = {"osc_25m", "sys1_pll_133m", "sys1_pll_160m", "vpu_pll_out",
219 "sys2_pll_125m", "sys3_pll2_out", "sys1_pll_80m", "sys2_pll_166m", }; 217 "sys2_pll_125m", "sys3_pll2_out", "sys1_pll_80m", "sys2_pll_166m", };
220 218
221static const char *imx8mq_wrclk_sels[] = {"osc_25m", "sys1_pll_40m", "vpu_pll_out", "sys3_pll2_out", "sys2_pll_200m", 219static const char * const imx8mq_wrclk_sels[] = {"osc_25m", "sys1_pll_40m", "vpu_pll_out", "sys3_pll2_out", "sys2_pll_200m",
222 "sys1_pll_266m", "sys2_pll_500m", "sys1_pll_100m", }; 220 "sys1_pll_266m", "sys2_pll_500m", "sys1_pll_100m", };
223 221
224static const char *imx8mq_dsi_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m", 222static const char * const imx8mq_dsi_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
225 "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", }; 223 "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
226 224
227static const char *imx8mq_dsi_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m", 225static const char * const imx8mq_dsi_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
228 "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", }; 226 "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
229 227
230static const char *imx8mq_dsi_dbi_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_100m", "sys1_pll_800m", 228static const char * const imx8mq_dsi_dbi_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_100m", "sys1_pll_800m",
231 "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", }; 229 "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
232 230
233static const char *imx8mq_dsi_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m", 231static const char * const imx8mq_dsi_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
234 "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", }; 232 "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", };
235 233
236static const char *imx8mq_csi1_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m", 234static const char * const imx8mq_csi1_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
237 "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", }; 235 "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
238 236
239static const char *imx8mq_csi1_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m", 237static const char * const imx8mq_csi1_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
240 "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", }; 238 "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
241 239
242static const char *imx8mq_csi1_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m", 240static const char * const imx8mq_csi1_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
243 "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", }; 241 "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", };
244 242
245static const char *imx8mq_csi2_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m", 243static const char * const imx8mq_csi2_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
246 "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", }; 244 "sys2_pll_1000m", "sys3_pll2_out", "audio_pll2_out", "video_pll1_out", };
247 245
248static const char *imx8mq_csi2_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m", 246static const char * const imx8mq_csi2_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
249 "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", }; 247 "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
250 248
251static const char *imx8mq_csi2_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m", 249static const char * const imx8mq_csi2_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
252 "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", }; 250 "sys2_pll_1000m", "sys3_pll2_out", "clk_ext3", "audio_pll2_out", };
253 251
254static const char *imx8mq_pcie2_ctrl_sels[] = {"osc_25m", "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m", 252static const char * const imx8mq_pcie2_ctrl_sels[] = {"osc_25m", "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m",
255 "sys1_pll_800m", "sys2_pll_500m", "sys2_pll_333m", "sys3_pll2_out", }; 253 "sys1_pll_800m", "sys2_pll_500m", "sys2_pll_333m", "sys3_pll2_out", };
256 254
257static const char *imx8mq_pcie2_phy_sels[] = {"osc_25m", "sys2_pll_100m", "sys2_pll_500m", "clk_ext1", 255static const char * const imx8mq_pcie2_phy_sels[] = {"osc_25m", "sys2_pll_100m", "sys2_pll_500m", "clk_ext1",
258 "clk_ext2", "clk_ext3", "clk_ext4", "sys1_pll_400m", }; 256 "clk_ext2", "clk_ext3", "clk_ext4", "sys1_pll_400m", };
259 257
260static const char *imx8mq_pcie2_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_50m", "sys3_pll2_out", 258static const char * const imx8mq_pcie2_aux_sels[] = {"osc_25m", "sys2_pll_200m", "sys2_pll_50m", "sys3_pll2_out",
261 "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_160m", "sys1_pll_200m", }; 259 "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_160m", "sys1_pll_200m", };
262 260
263static const char *imx8mq_ecspi3_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m", 261static const char * const imx8mq_ecspi3_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_40m", "sys1_pll_160m",
264 "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", }; 262 "sys1_pll_800m", "sys3_pll2_out", "sys2_pll_250m", "audio_pll2_out", };
265static const char *imx8mq_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; 263static const char * const imx8mq_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
266 264
267static const char *imx8mq_clko2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_400m", "sys2_pll_166m", "audio_pll1_out", 265static const char * const imx8mq_clko1_sels[] = {"osc_25m", "sys1_pll_800m", "osc_27m", "sys1_pll_200m",
268 "video_pll1_out", "ckil", }; 266 "audio_pll2_out", "sys2_pll_500m", "vpu_pll_out", "sys1_pll_80m", };
267static const char * const imx8mq_clko2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_400m", "sys2_pll_166m",
268 "sys3_pll2_out", "audio_pll1_out", "video_pll1_out", "ckil", };
269 269
270static struct clk_onecell_data clk_data; 270static struct clk_onecell_data clk_data;
271 271
@@ -308,10 +308,6 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
308 clks[IMX8MQ_AUDIO_PLL1_REF_DIV] = imx_clk_divider("audio_pll1_ref_div", "audio_pll1_ref_sel", base + 0x0, 5, 6); 308 clks[IMX8MQ_AUDIO_PLL1_REF_DIV] = imx_clk_divider("audio_pll1_ref_div", "audio_pll1_ref_sel", base + 0x0, 5, 6);
309 clks[IMX8MQ_AUDIO_PLL2_REF_DIV] = imx_clk_divider("audio_pll2_ref_div", "audio_pll2_ref_sel", base + 0x8, 5, 6); 309 clks[IMX8MQ_AUDIO_PLL2_REF_DIV] = imx_clk_divider("audio_pll2_ref_div", "audio_pll2_ref_sel", base + 0x8, 5, 6);
310 clks[IMX8MQ_VIDEO_PLL1_REF_DIV] = imx_clk_divider("video_pll1_ref_div", "video_pll1_ref_sel", base + 0x10, 5, 6); 310 clks[IMX8MQ_VIDEO_PLL1_REF_DIV] = imx_clk_divider("video_pll1_ref_div", "video_pll1_ref_sel", base + 0x10, 5, 6);
311 clks[IMX8MQ_SYS1_PLL1_REF_DIV] = imx_clk_divider("sys1_pll1_ref_div", "sys1_pll1_ref_sel", base + 0x38, 25, 3);
312 clks[IMX8MQ_SYS2_PLL1_REF_DIV] = imx_clk_divider("sys2_pll1_ref_div", "sys2_pll1_ref_sel", base + 0x44, 25, 3);
313 clks[IMX8MQ_SYS3_PLL1_REF_DIV] = imx_clk_divider("sys3_pll1_ref_div", "sys3_pll1_ref_sel", base + 0x50, 25, 3);
314 clks[IMX8MQ_DRAM_PLL1_REF_DIV] = imx_clk_divider("dram_pll1_ref_div", "dram_pll1_ref_sel", base + 0x68, 25, 3);
315 311
316 clks[IMX8MQ_ARM_PLL] = imx_clk_frac_pll("arm_pll", "arm_pll_ref_div", base + 0x28); 312 clks[IMX8MQ_ARM_PLL] = imx_clk_frac_pll("arm_pll", "arm_pll_ref_div", base + 0x28);
317 clks[IMX8MQ_GPU_PLL] = imx_clk_frac_pll("gpu_pll", "gpu_pll_ref_div", base + 0x18); 313 clks[IMX8MQ_GPU_PLL] = imx_clk_frac_pll("gpu_pll", "gpu_pll_ref_div", base + 0x18);
@@ -319,43 +315,15 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
319 clks[IMX8MQ_AUDIO_PLL1] = imx_clk_frac_pll("audio_pll1", "audio_pll1_ref_div", base + 0x0); 315 clks[IMX8MQ_AUDIO_PLL1] = imx_clk_frac_pll("audio_pll1", "audio_pll1_ref_div", base + 0x0);
320 clks[IMX8MQ_AUDIO_PLL2] = imx_clk_frac_pll("audio_pll2", "audio_pll2_ref_div", base + 0x8); 316 clks[IMX8MQ_AUDIO_PLL2] = imx_clk_frac_pll("audio_pll2", "audio_pll2_ref_div", base + 0x8);
321 clks[IMX8MQ_VIDEO_PLL1] = imx_clk_frac_pll("video_pll1", "video_pll1_ref_div", base + 0x10); 317 clks[IMX8MQ_VIDEO_PLL1] = imx_clk_frac_pll("video_pll1", "video_pll1_ref_div", base + 0x10);
322 clks[IMX8MQ_SYS1_PLL1] = imx_clk_sccg_pll("sys1_pll1", "sys1_pll1_ref_div", base + 0x30, SCCG_PLL1);
323 clks[IMX8MQ_SYS2_PLL1] = imx_clk_sccg_pll("sys2_pll1", "sys2_pll1_ref_div", base + 0x3c, SCCG_PLL1);
324 clks[IMX8MQ_SYS3_PLL1] = imx_clk_sccg_pll("sys3_pll1", "sys3_pll1_ref_div", base + 0x48, SCCG_PLL1);
325 clks[IMX8MQ_DRAM_PLL1] = imx_clk_sccg_pll("dram_pll1", "dram_pll1_ref_div", base + 0x60, SCCG_PLL1);
326
327 clks[IMX8MQ_SYS1_PLL2] = imx_clk_sccg_pll("sys1_pll2", "sys1_pll1_out_div", base + 0x30, SCCG_PLL2);
328 clks[IMX8MQ_SYS2_PLL2] = imx_clk_sccg_pll("sys2_pll2", "sys2_pll1_out_div", base + 0x3c, SCCG_PLL2);
329 clks[IMX8MQ_SYS3_PLL2] = imx_clk_sccg_pll("sys3_pll2", "sys3_pll1_out_div", base + 0x48, SCCG_PLL2);
330 clks[IMX8MQ_DRAM_PLL2] = imx_clk_sccg_pll("dram_pll2", "dram_pll1_out_div", base + 0x60, SCCG_PLL2);
331
332 /* PLL divs */
333 clks[IMX8MQ_SYS1_PLL1_OUT_DIV] = imx_clk_divider("sys1_pll1_out_div", "sys1_pll1_out", base + 0x38, 19, 6);
334 clks[IMX8MQ_SYS2_PLL1_OUT_DIV] = imx_clk_divider("sys2_pll1_out_div", "sys2_pll1_out", base + 0x44, 19, 6);
335 clks[IMX8MQ_SYS3_PLL1_OUT_DIV] = imx_clk_divider("sys3_pll1_out_div", "sys3_pll1_out", base + 0x50, 19, 6);
336 clks[IMX8MQ_DRAM_PLL1_OUT_DIV] = imx_clk_divider("dram_pll1_out_div", "dram_pll1_out", base + 0x68, 19, 6);
337 clks[IMX8MQ_SYS1_PLL2_DIV] = imx_clk_divider("sys1_pll2_div", "sys1_pll2", base + 0x38, 1, 6);
338 clks[IMX8MQ_SYS2_PLL2_DIV] = imx_clk_divider("sys2_pll2_div", "sys2_pll2", base + 0x44, 1, 6);
339 clks[IMX8MQ_SYS3_PLL2_DIV] = imx_clk_divider("sys3_pll2_div", "sys3_pll2", base + 0x50, 1, 6);
340 clks[IMX8MQ_DRAM_PLL2_DIV] = imx_clk_divider("dram_pll2_div", "dram_pll2", base + 0x68, 1, 6);
341 318
342 /* PLL bypass out */ 319 /* PLL bypass out */
343 clks[IMX8MQ_ARM_PLL_BYPASS] = imx_clk_mux("arm_pll_bypass", base + 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels)); 320 clks[IMX8MQ_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
344 clks[IMX8MQ_GPU_PLL_BYPASS] = imx_clk_mux("gpu_pll_bypass", base + 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels)); 321 clks[IMX8MQ_GPU_PLL_BYPASS] = imx_clk_mux("gpu_pll_bypass", base + 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels));
345 clks[IMX8MQ_VPU_PLL_BYPASS] = imx_clk_mux("vpu_pll_bypass", base + 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels)); 322 clks[IMX8MQ_VPU_PLL_BYPASS] = imx_clk_mux("vpu_pll_bypass", base + 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels));
346 clks[IMX8MQ_AUDIO_PLL1_BYPASS] = imx_clk_mux("audio_pll1_bypass", base + 0x0, 14, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels)); 323 clks[IMX8MQ_AUDIO_PLL1_BYPASS] = imx_clk_mux("audio_pll1_bypass", base + 0x0, 14, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels));
347 clks[IMX8MQ_AUDIO_PLL2_BYPASS] = imx_clk_mux("audio_pll2_bypass", base + 0x8, 14, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels)); 324 clks[IMX8MQ_AUDIO_PLL2_BYPASS] = imx_clk_mux("audio_pll2_bypass", base + 0x8, 14, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels));
348 clks[IMX8MQ_VIDEO_PLL1_BYPASS] = imx_clk_mux("video_pll1_bypass", base + 0x10, 14, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels)); 325 clks[IMX8MQ_VIDEO_PLL1_BYPASS] = imx_clk_mux("video_pll1_bypass", base + 0x10, 14, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels));
349 326
350 clks[IMX8MQ_SYS1_PLL1_OUT] = imx_clk_mux("sys1_pll1_out", base + 0x30, 5, 1, sys1_pll1_out_sels, ARRAY_SIZE(sys1_pll1_out_sels));
351 clks[IMX8MQ_SYS2_PLL1_OUT] = imx_clk_mux("sys2_pll1_out", base + 0x3c, 5, 1, sys2_pll1_out_sels, ARRAY_SIZE(sys2_pll1_out_sels));
352 clks[IMX8MQ_SYS3_PLL1_OUT] = imx_clk_mux("sys3_pll1_out", base + 0x48, 5, 1, sys3_pll1_out_sels, ARRAY_SIZE(sys3_pll1_out_sels));
353 clks[IMX8MQ_DRAM_PLL1_OUT] = imx_clk_mux("dram_pll1_out", base + 0x60, 5, 1, dram_pll1_out_sels, ARRAY_SIZE(dram_pll1_out_sels));
354 clks[IMX8MQ_SYS1_PLL2_OUT] = imx_clk_mux("sys1_pll2_out", base + 0x30, 4, 1, sys1_pll2_out_sels, ARRAY_SIZE(sys1_pll2_out_sels));
355 clks[IMX8MQ_SYS2_PLL2_OUT] = imx_clk_mux("sys2_pll2_out", base + 0x3c, 4, 1, sys2_pll2_out_sels, ARRAY_SIZE(sys2_pll2_out_sels));
356 clks[IMX8MQ_SYS3_PLL2_OUT] = imx_clk_mux("sys3_pll2_out", base + 0x48, 4, 1, sys3_pll2_out_sels, ARRAY_SIZE(sys3_pll2_out_sels));
357 clks[IMX8MQ_DRAM_PLL2_OUT] = imx_clk_mux("dram_pll2_out", base + 0x60, 4, 1, dram_pll2_out_sels, ARRAY_SIZE(dram_pll2_out_sels));
358
359 /* PLL OUT GATE */ 327 /* PLL OUT GATE */
360 clks[IMX8MQ_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x28, 21); 328 clks[IMX8MQ_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x28, 21);
361 clks[IMX8MQ_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x18, 21); 329 clks[IMX8MQ_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x18, 21);
@@ -363,11 +331,11 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
363 clks[IMX8MQ_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base + 0x0, 21); 331 clks[IMX8MQ_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base + 0x0, 21);
364 clks[IMX8MQ_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x8, 21); 332 clks[IMX8MQ_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x8, 21);
365 clks[IMX8MQ_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x10, 21); 333 clks[IMX8MQ_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x10, 21);
366 clks[IMX8MQ_SYS1_PLL_OUT] = imx_clk_gate("sys1_pll_out", "sys1_pll2_out", base + 0x30, 9);
367 clks[IMX8MQ_SYS2_PLL_OUT] = imx_clk_gate("sys2_pll_out", "sys2_pll2_out", base + 0x3c, 9);
368 clks[IMX8MQ_SYS3_PLL_OUT] = imx_clk_gate("sys3_pll_out", "sys3_pll2_out", base + 0x48, 9);
369 clks[IMX8MQ_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll2_out", base + 0x60, 9);
370 334
335 clks[IMX8MQ_SYS1_PLL_OUT] = imx_clk_sccg_pll("sys1_pll_out", sys1_pll_out_sels, ARRAY_SIZE(sys1_pll_out_sels), 0, 0, 0, base + 0x30, CLK_IS_CRITICAL);
336 clks[IMX8MQ_SYS2_PLL_OUT] = imx_clk_sccg_pll("sys2_pll_out", sys2_pll_out_sels, ARRAY_SIZE(sys2_pll_out_sels), 0, 0, 1, base + 0x3c, CLK_IS_CRITICAL);
337 clks[IMX8MQ_SYS3_PLL_OUT] = imx_clk_sccg_pll("sys3_pll_out", sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 1, base + 0x48, CLK_IS_CRITICAL);
338 clks[IMX8MQ_DRAM_PLL_OUT] = imx_clk_sccg_pll("dram_pll_out", dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, base + 0x60, CLK_IS_CRITICAL);
371 /* SYS PLL fixed output */ 339 /* SYS PLL fixed output */
372 clks[IMX8MQ_SYS1_PLL_40M] = imx_clk_fixed_factor("sys1_pll_40m", "sys1_pll_out", 1, 20); 340 clks[IMX8MQ_SYS1_PLL_40M] = imx_clk_fixed_factor("sys1_pll_40m", "sys1_pll_out", 1, 20);
373 clks[IMX8MQ_SYS1_PLL_80M] = imx_clk_fixed_factor("sys1_pll_80m", "sys1_pll_out", 1, 10); 341 clks[IMX8MQ_SYS1_PLL_80M] = imx_clk_fixed_factor("sys1_pll_80m", "sys1_pll_out", 1, 10);
@@ -396,15 +364,19 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
396 364
397 /* CORE */ 365 /* CORE */
398 clks[IMX8MQ_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels)); 366 clks[IMX8MQ_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels));
367 clks[IMX8MQ_CLK_M4_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mq_arm_m4_sels, ARRAY_SIZE(imx8mq_arm_m4_sels));
399 clks[IMX8MQ_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mq_vpu_sels, ARRAY_SIZE(imx8mq_vpu_sels)); 368 clks[IMX8MQ_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mq_vpu_sels, ARRAY_SIZE(imx8mq_vpu_sels));
400 clks[IMX8MQ_CLK_GPU_CORE_SRC] = imx_clk_mux2("gpu_core_src", base + 0x8180, 24, 3, imx8mq_gpu_core_sels, ARRAY_SIZE(imx8mq_gpu_core_sels)); 369 clks[IMX8MQ_CLK_GPU_CORE_SRC] = imx_clk_mux2("gpu_core_src", base + 0x8180, 24, 3, imx8mq_gpu_core_sels, ARRAY_SIZE(imx8mq_gpu_core_sels));
401 clks[IMX8MQ_CLK_GPU_SHADER_SRC] = imx_clk_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mq_gpu_shader_sels, ARRAY_SIZE(imx8mq_gpu_shader_sels)); 370 clks[IMX8MQ_CLK_GPU_SHADER_SRC] = imx_clk_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mq_gpu_shader_sels, ARRAY_SIZE(imx8mq_gpu_shader_sels));
371
402 clks[IMX8MQ_CLK_A53_CG] = imx_clk_gate3_flags("arm_a53_cg", "arm_a53_src", base + 0x8000, 28, CLK_IS_CRITICAL); 372 clks[IMX8MQ_CLK_A53_CG] = imx_clk_gate3_flags("arm_a53_cg", "arm_a53_src", base + 0x8000, 28, CLK_IS_CRITICAL);
373 clks[IMX8MQ_CLK_M4_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
403 clks[IMX8MQ_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28); 374 clks[IMX8MQ_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
404 clks[IMX8MQ_CLK_GPU_CORE_CG] = imx_clk_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28); 375 clks[IMX8MQ_CLK_GPU_CORE_CG] = imx_clk_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28);
405 clks[IMX8MQ_CLK_GPU_SHADER_CG] = imx_clk_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28); 376 clks[IMX8MQ_CLK_GPU_SHADER_CG] = imx_clk_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28);
406 377
407 clks[IMX8MQ_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3); 378 clks[IMX8MQ_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
379 clks[IMX8MQ_CLK_M4_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
408 clks[IMX8MQ_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3); 380 clks[IMX8MQ_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
409 clks[IMX8MQ_CLK_GPU_CORE_DIV] = imx_clk_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3); 381 clks[IMX8MQ_CLK_GPU_CORE_DIV] = imx_clk_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3);
410 clks[IMX8MQ_CLK_GPU_SHADER_DIV] = imx_clk_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3); 382 clks[IMX8MQ_CLK_GPU_SHADER_DIV] = imx_clk_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3);
@@ -479,6 +451,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
479 clks[IMX8MQ_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mq_gpt1_sels, base + 0xb580); 451 clks[IMX8MQ_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mq_gpt1_sels, base + 0xb580);
480 clks[IMX8MQ_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mq_wdog_sels, base + 0xb900); 452 clks[IMX8MQ_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mq_wdog_sels, base + 0xb900);
481 clks[IMX8MQ_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mq_wrclk_sels, base + 0xb980); 453 clks[IMX8MQ_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mq_wrclk_sels, base + 0xb980);
454 clks[IMX8MQ_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mq_clko1_sels, base + 0xba00);
482 clks[IMX8MQ_CLK_CLKO2] = imx8m_clk_composite("clko2", imx8mq_clko2_sels, base + 0xba80); 455 clks[IMX8MQ_CLK_CLKO2] = imx8m_clk_composite("clko2", imx8mq_clko2_sels, base + 0xba80);
483 clks[IMX8MQ_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mq_dsi_core_sels, base + 0xbb00); 456 clks[IMX8MQ_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mq_dsi_core_sels, base + 0xbb00);
484 clks[IMX8MQ_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mq_dsi_phy_sels, base + 0xbb80); 457 clks[IMX8MQ_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mq_dsi_phy_sels, base + 0xbb80);
@@ -500,6 +473,11 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
500 clks[IMX8MQ_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0); 473 clks[IMX8MQ_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
501 clks[IMX8MQ_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0); 474 clks[IMX8MQ_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
502 clks[IMX8MQ_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0); 475 clks[IMX8MQ_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
476 clks[IMX8MQ_CLK_GPIO1_ROOT] = imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
477 clks[IMX8MQ_CLK_GPIO2_ROOT] = imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
478 clks[IMX8MQ_CLK_GPIO3_ROOT] = imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
479 clks[IMX8MQ_CLK_GPIO4_ROOT] = imx_clk_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
480 clks[IMX8MQ_CLK_GPIO5_ROOT] = imx_clk_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
503 clks[IMX8MQ_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0); 481 clks[IMX8MQ_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
504 clks[IMX8MQ_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0); 482 clks[IMX8MQ_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
505 clks[IMX8MQ_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0); 483 clks[IMX8MQ_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
@@ -558,6 +536,12 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
558 clks[IMX8MQ_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc_25m", 1, 8); 536 clks[IMX8MQ_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc_25m", 1, 8);
559 clks[IMX8MQ_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4); 537 clks[IMX8MQ_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
560 538
539 clks[IMX8MQ_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
540 clks[IMX8MQ_CLK_A53_DIV],
541 clks[IMX8MQ_CLK_A53_SRC],
542 clks[IMX8MQ_ARM_PLL_OUT],
543 clks[IMX8MQ_SYS1_PLL_800M]);
544
561 for (i = 0; i < IMX8MQ_CLK_END; i++) 545 for (i = 0; i < IMX8MQ_CLK_END; i++)
562 if (IS_ERR(clks[i])) 546 if (IS_ERR(clks[i]))
563 pr_err("i.MX8mq clk %u register failed with %ld\n", 547 pr_err("i.MX8mq clk %u register failed with %ld\n",
diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c
index 83e2ef96d81d..5e2903efc488 100644
--- a/drivers/clk/imx/clk-imx8qxp.c
+++ b/drivers/clk/imx/clk-imx8qxp.c
@@ -138,6 +138,7 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
138} 138}
139 139
140static const struct of_device_id imx8qxp_match[] = { 140static const struct of_device_id imx8qxp_match[] = {
141 { .compatible = "fsl,scu-clk", },
141 { .compatible = "fsl,imx8qxp-clk", }, 142 { .compatible = "fsl,imx8qxp-clk", },
142 { /* sentinel */ } 143 { /* sentinel */ }
143}; 144};
diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
new file mode 100644
index 000000000000..1acfa3e3cfb4
--- /dev/null
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -0,0 +1,392 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2017-2018 NXP.
4 */
5
6#include <linux/bitops.h>
7#include <linux/clk-provider.h>
8#include <linux/err.h>
9#include <linux/io.h>
10#include <linux/iopoll.h>
11#include <linux/slab.h>
12#include <linux/jiffies.h>
13
14#include "clk.h"
15
16#define GNRL_CTL 0x0
17#define DIV_CTL 0x4
18#define LOCK_STATUS BIT(31)
19#define LOCK_SEL_MASK BIT(29)
20#define CLKE_MASK BIT(11)
21#define RST_MASK BIT(9)
22#define BYPASS_MASK BIT(4)
23#define MDIV_SHIFT 12
24#define MDIV_MASK GENMASK(21, 12)
25#define PDIV_SHIFT 4
26#define PDIV_MASK GENMASK(9, 4)
27#define SDIV_SHIFT 0
28#define SDIV_MASK GENMASK(2, 0)
29#define KDIV_SHIFT 0
30#define KDIV_MASK GENMASK(15, 0)
31
32#define LOCK_TIMEOUT_US 10000
33
34struct clk_pll14xx {
35 struct clk_hw hw;
36 void __iomem *base;
37 enum imx_pll14xx_type type;
38 const struct imx_pll14xx_rate_table *rate_table;
39 int rate_count;
40};
41
42#define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
43
44static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
45 struct clk_pll14xx *pll, unsigned long rate)
46{
47 const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
48 int i;
49
50 for (i = 0; i < pll->rate_count; i++)
51 if (rate == rate_table[i].rate)
52 return &rate_table[i];
53
54 return NULL;
55}
56
57static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate,
58 unsigned long *prate)
59{
60 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
61 const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
62 int i;
63
64 /* Assumming rate_table is in descending order */
65 for (i = 0; i < pll->rate_count; i++)
66 if (rate >= rate_table[i].rate)
67 return rate_table[i].rate;
68
69 /* return minimum supported value */
70 return rate_table[i - 1].rate;
71}
72
73static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw,
74 unsigned long parent_rate)
75{
76 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
77 u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div;
78 u64 fvco = parent_rate;
79
80 pll_gnrl = readl_relaxed(pll->base);
81 pll_div = readl_relaxed(pll->base + 4);
82 mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
83 pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
84 sdiv = (pll_div & SDIV_MASK) >> SDIV_SHIFT;
85
86 fvco *= mdiv;
87 do_div(fvco, pdiv << sdiv);
88
89 return fvco;
90}
91
92static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw,
93 unsigned long parent_rate)
94{
95 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
96 u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div_ctl0, pll_div_ctl1;
97 short int kdiv;
98 u64 fvco = parent_rate;
99
100 pll_gnrl = readl_relaxed(pll->base);
101 pll_div_ctl0 = readl_relaxed(pll->base + 4);
102 pll_div_ctl1 = readl_relaxed(pll->base + 8);
103 mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT;
104 pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT;
105 sdiv = (pll_div_ctl0 & SDIV_MASK) >> SDIV_SHIFT;
106 kdiv = pll_div_ctl1 & KDIV_MASK;
107
108 /* fvco = (m * 65536 + k) * Fin / (p * 65536) */
109 fvco *= (mdiv * 65536 + kdiv);
110 pdiv *= 65536;
111
112 do_div(fvco, pdiv << sdiv);
113
114 return fvco;
115}
116
117static inline bool clk_pll1416x_mp_change(const struct imx_pll14xx_rate_table *rate,
118 u32 pll_div)
119{
120 u32 old_mdiv, old_pdiv;
121
122 old_mdiv = (pll_div >> MDIV_SHIFT) & MDIV_MASK;
123 old_pdiv = (pll_div >> PDIV_SHIFT) & PDIV_MASK;
124
125 return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv;
126}
127
128static inline bool clk_pll1443x_mpk_change(const struct imx_pll14xx_rate_table *rate,
129 u32 pll_div_ctl0, u32 pll_div_ctl1)
130{
131 u32 old_mdiv, old_pdiv, old_kdiv;
132
133 old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
134 old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
135 old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
136
137 return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
138 rate->kdiv != old_kdiv;
139}
140
141static inline bool clk_pll1443x_mp_change(const struct imx_pll14xx_rate_table *rate,
142 u32 pll_div_ctl0, u32 pll_div_ctl1)
143{
144 u32 old_mdiv, old_pdiv, old_kdiv;
145
146 old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK;
147 old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK;
148 old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK;
149
150 return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
151 rate->kdiv != old_kdiv;
152}
153
154static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll)
155{
156 u32 val;
157
158 return readl_poll_timeout(pll->base, val, val & LOCK_TIMEOUT_US, 0,
159 LOCK_TIMEOUT_US);
160}
161
162static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,
163 unsigned long prate)
164{
165 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
166 const struct imx_pll14xx_rate_table *rate;
167 u32 tmp, div_val;
168 int ret;
169
170 rate = imx_get_pll_settings(pll, drate);
171 if (!rate) {
172 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
173 drate, clk_hw_get_name(hw));
174 return -EINVAL;
175 }
176
177 tmp = readl_relaxed(pll->base + 4);
178
179 if (!clk_pll1416x_mp_change(rate, tmp)) {
180 tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
181 tmp |= rate->sdiv << SDIV_SHIFT;
182 writel_relaxed(tmp, pll->base + 4);
183
184 return 0;
185 }
186
187 /* Bypass clock and set lock to pll output lock */
188 tmp = readl_relaxed(pll->base);
189 tmp |= LOCK_SEL_MASK;
190 writel_relaxed(tmp, pll->base);
191
192 /* Enable RST */
193 tmp &= ~RST_MASK;
194 writel_relaxed(tmp, pll->base);
195
196 div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
197 (rate->sdiv << SDIV_SHIFT);
198 writel_relaxed(div_val, pll->base + 0x4);
199
200 /*
201 * According to SPEC, t3 - t2 need to be greater than
202 * 1us and 1/FREF, respectively.
203 * FREF is FIN / Prediv, the prediv is [1, 63], so choose
204 * 3us.
205 */
206 udelay(3);
207
208 /* Disable RST */
209 tmp |= RST_MASK;
210 writel_relaxed(tmp, pll->base);
211
212 /* Wait Lock */
213 ret = clk_pll14xx_wait_lock(pll);
214 if (ret)
215 return ret;
216
217 /* Bypass */
218 tmp &= ~BYPASS_MASK;
219 writel_relaxed(tmp, pll->base);
220
221 return 0;
222}
223
224static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
225 unsigned long prate)
226{
227 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
228 const struct imx_pll14xx_rate_table *rate;
229 u32 tmp, div_val;
230 int ret;
231
232 rate = imx_get_pll_settings(pll, drate);
233 if (!rate) {
234 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
235 drate, clk_hw_get_name(hw));
236 return -EINVAL;
237 }
238
239 tmp = readl_relaxed(pll->base + 4);
240 div_val = readl_relaxed(pll->base + 8);
241
242 if (!clk_pll1443x_mpk_change(rate, tmp, div_val)) {
243 tmp &= ~(SDIV_MASK) << SDIV_SHIFT;
244 tmp |= rate->sdiv << SDIV_SHIFT;
245 writel_relaxed(tmp, pll->base + 4);
246
247 return 0;
248 }
249
250 /* Enable RST */
251 tmp = readl_relaxed(pll->base);
252 tmp &= ~RST_MASK;
253 writel_relaxed(tmp, pll->base);
254
255 div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) |
256 (rate->sdiv << SDIV_SHIFT);
257 writel_relaxed(div_val, pll->base + 0x4);
258 writel_relaxed(rate->kdiv << KDIV_SHIFT, pll->base + 0x8);
259
260 /*
261 * According to SPEC, t3 - t2 need to be greater than
262 * 1us and 1/FREF, respectively.
263 * FREF is FIN / Prediv, the prediv is [1, 63], so choose
264 * 3us.
265 */
266 udelay(3);
267
268 /* Disable RST */
269 tmp |= RST_MASK;
270 writel_relaxed(tmp, pll->base);
271
272 /* Wait Lock*/
273 ret = clk_pll14xx_wait_lock(pll);
274 if (ret)
275 return ret;
276
277 /* Bypass */
278 tmp &= ~BYPASS_MASK;
279 writel_relaxed(tmp, pll->base);
280
281 return 0;
282}
283
284static int clk_pll14xx_prepare(struct clk_hw *hw)
285{
286 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
287 u32 val;
288
289 /*
290 * RESETB = 1 from 0, PLL starts its normal
291 * operation after lock time
292 */
293 val = readl_relaxed(pll->base + GNRL_CTL);
294 val |= RST_MASK;
295 writel_relaxed(val, pll->base + GNRL_CTL);
296
297 return clk_pll14xx_wait_lock(pll);
298}
299
300static int clk_pll14xx_is_prepared(struct clk_hw *hw)
301{
302 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
303 u32 val;
304
305 val = readl_relaxed(pll->base + GNRL_CTL);
306
307 return (val & RST_MASK) ? 1 : 0;
308}
309
310static void clk_pll14xx_unprepare(struct clk_hw *hw)
311{
312 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
313 u32 val;
314
315 /*
316 * Set RST to 0, power down mode is enabled and
317 * every digital block is reset
318 */
319 val = readl_relaxed(pll->base + GNRL_CTL);
320 val &= ~RST_MASK;
321 writel_relaxed(val, pll->base + GNRL_CTL);
322}
323
324static const struct clk_ops clk_pll1416x_ops = {
325 .prepare = clk_pll14xx_prepare,
326 .unprepare = clk_pll14xx_unprepare,
327 .is_prepared = clk_pll14xx_is_prepared,
328 .recalc_rate = clk_pll1416x_recalc_rate,
329 .round_rate = clk_pll14xx_round_rate,
330 .set_rate = clk_pll1416x_set_rate,
331};
332
333static const struct clk_ops clk_pll1416x_min_ops = {
334 .recalc_rate = clk_pll1416x_recalc_rate,
335};
336
337static const struct clk_ops clk_pll1443x_ops = {
338 .prepare = clk_pll14xx_prepare,
339 .unprepare = clk_pll14xx_unprepare,
340 .is_prepared = clk_pll14xx_is_prepared,
341 .recalc_rate = clk_pll1443x_recalc_rate,
342 .round_rate = clk_pll14xx_round_rate,
343 .set_rate = clk_pll1443x_set_rate,
344};
345
346struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
347 void __iomem *base,
348 const struct imx_pll14xx_clk *pll_clk)
349{
350 struct clk_pll14xx *pll;
351 struct clk *clk;
352 struct clk_init_data init;
353
354 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
355 if (!pll)
356 return ERR_PTR(-ENOMEM);
357
358 init.name = name;
359 init.flags = pll_clk->flags;
360 init.parent_names = &parent_name;
361 init.num_parents = 1;
362
363 switch (pll_clk->type) {
364 case PLL_1416X:
365 if (!pll->rate_table)
366 init.ops = &clk_pll1416x_min_ops;
367 else
368 init.ops = &clk_pll1416x_ops;
369 break;
370 case PLL_1443X:
371 init.ops = &clk_pll1443x_ops;
372 break;
373 default:
374 pr_err("%s: Unknown pll type for pll clk %s\n",
375 __func__, name);
376 };
377
378 pll->base = base;
379 pll->hw.init = &init;
380 pll->type = pll_clk->type;
381 pll->rate_table = pll_clk->rate_table;
382 pll->rate_count = pll_clk->rate_count;
383
384 clk = clk_register(NULL, &pll->hw);
385 if (IS_ERR(clk)) {
386 pr_err("%s: failed to register pll %s %lu\n",
387 __func__, name, PTR_ERR(clk));
388 kfree(pll);
389 }
390
391 return clk;
392}
diff --git a/drivers/clk/imx/clk-sccg-pll.c b/drivers/clk/imx/clk-sccg-pll.c
index ee7752bace89..9dfd03a95557 100644
--- a/drivers/clk/imx/clk-sccg-pll.c
+++ b/drivers/clk/imx/clk-sccg-pll.c
@@ -25,87 +25,292 @@
25#define PLL_DIVF2_MASK GENMASK(12, 7) 25#define PLL_DIVF2_MASK GENMASK(12, 7)
26#define PLL_DIVR1_MASK GENMASK(27, 25) 26#define PLL_DIVR1_MASK GENMASK(27, 25)
27#define PLL_DIVR2_MASK GENMASK(24, 19) 27#define PLL_DIVR2_MASK GENMASK(24, 19)
28#define PLL_DIVQ_MASK GENMASK(6, 1)
28#define PLL_REF_MASK GENMASK(2, 0) 29#define PLL_REF_MASK GENMASK(2, 0)
29 30
30#define PLL_LOCK_MASK BIT(31) 31#define PLL_LOCK_MASK BIT(31)
31#define PLL_PD_MASK BIT(7) 32#define PLL_PD_MASK BIT(7)
32 33
33#define OSC_25M 25000000 34/* These are the specification limits for the SSCG PLL */
34#define OSC_27M 27000000 35#define PLL_REF_MIN_FREQ 25000000UL
36#define PLL_REF_MAX_FREQ 235000000UL
35 37
36#define PLL_SCCG_LOCK_TIMEOUT 70 38#define PLL_STAGE1_MIN_FREQ 1600000000UL
39#define PLL_STAGE1_MAX_FREQ 2400000000UL
40
41#define PLL_STAGE1_REF_MIN_FREQ 25000000UL
42#define PLL_STAGE1_REF_MAX_FREQ 54000000UL
43
44#define PLL_STAGE2_MIN_FREQ 1200000000UL
45#define PLL_STAGE2_MAX_FREQ 2400000000UL
46
47#define PLL_STAGE2_REF_MIN_FREQ 54000000UL
48#define PLL_STAGE2_REF_MAX_FREQ 75000000UL
49
50#define PLL_OUT_MIN_FREQ 20000000UL
51#define PLL_OUT_MAX_FREQ 1200000000UL
52
53#define PLL_DIVR1_MAX 7
54#define PLL_DIVR2_MAX 63
55#define PLL_DIVF1_MAX 63
56#define PLL_DIVF2_MAX 63
57#define PLL_DIVQ_MAX 63
58
59#define PLL_BYPASS_NONE 0x0
60#define PLL_BYPASS1 0x2
61#define PLL_BYPASS2 0x1
62
63#define SSCG_PLL_BYPASS1_MASK BIT(5)
64#define SSCG_PLL_BYPASS2_MASK BIT(4)
65#define SSCG_PLL_BYPASS_MASK GENMASK(5, 4)
66
67#define PLL_SCCG_LOCK_TIMEOUT 70
68
69struct clk_sccg_pll_setup {
70 int divr1, divf1;
71 int divr2, divf2;
72 int divq;
73 int bypass;
74
75 uint64_t vco1;
76 uint64_t vco2;
77 uint64_t fout;
78 uint64_t ref;
79 uint64_t ref_div1;
80 uint64_t ref_div2;
81 uint64_t fout_request;
82 int fout_error;
83};
37 84
38struct clk_sccg_pll { 85struct clk_sccg_pll {
39 struct clk_hw hw; 86 struct clk_hw hw;
40 void __iomem *base; 87 const struct clk_ops ops;
88
89 void __iomem *base;
90
91 struct clk_sccg_pll_setup setup;
92
93 u8 parent;
94 u8 bypass1;
95 u8 bypass2;
41}; 96};
42 97
43#define to_clk_sccg_pll(_hw) container_of(_hw, struct clk_sccg_pll, hw) 98#define to_clk_sccg_pll(_hw) container_of(_hw, struct clk_sccg_pll, hw)
44 99
45static int clk_pll_wait_lock(struct clk_sccg_pll *pll) 100static int clk_sccg_pll_wait_lock(struct clk_sccg_pll *pll)
46{ 101{
47 u32 val; 102 u32 val;
48 103
49 return readl_poll_timeout(pll->base, val, val & PLL_LOCK_MASK, 0, 104 val = readl_relaxed(pll->base + PLL_CFG0);
50 PLL_SCCG_LOCK_TIMEOUT); 105
106 /* don't wait for lock if all plls are bypassed */
107 if (!(val & SSCG_PLL_BYPASS2_MASK))
108 return readl_poll_timeout(pll->base, val, val & PLL_LOCK_MASK,
109 0, PLL_SCCG_LOCK_TIMEOUT);
110
111 return 0;
51} 112}
52 113
53static int clk_pll1_is_prepared(struct clk_hw *hw) 114static int clk_sccg_pll2_check_match(struct clk_sccg_pll_setup *setup,
115 struct clk_sccg_pll_setup *temp_setup)
54{ 116{
55 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); 117 int new_diff = temp_setup->fout - temp_setup->fout_request;
56 u32 val; 118 int diff = temp_setup->fout_error;
57 119
58 val = readl_relaxed(pll->base + PLL_CFG0); 120 if (abs(diff) > abs(new_diff)) {
59 return (val & PLL_PD_MASK) ? 0 : 1; 121 temp_setup->fout_error = new_diff;
122 memcpy(setup, temp_setup, sizeof(struct clk_sccg_pll_setup));
123
124 if (temp_setup->fout_request == temp_setup->fout)
125 return 0;
126 }
127 return -1;
60} 128}
61 129
62static unsigned long clk_pll1_recalc_rate(struct clk_hw *hw, 130static int clk_sccg_divq_lookup(struct clk_sccg_pll_setup *setup,
63 unsigned long parent_rate) 131 struct clk_sccg_pll_setup *temp_setup)
64{ 132{
65 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); 133 int ret = -EINVAL;
66 u32 val, divf; 134
135 for (temp_setup->divq = 0; temp_setup->divq <= PLL_DIVQ_MAX;
136 temp_setup->divq++) {
137 temp_setup->vco2 = temp_setup->vco1;
138 do_div(temp_setup->vco2, temp_setup->divr2 + 1);
139 temp_setup->vco2 *= 2;
140 temp_setup->vco2 *= temp_setup->divf2 + 1;
141 if (temp_setup->vco2 >= PLL_STAGE2_MIN_FREQ &&
142 temp_setup->vco2 <= PLL_STAGE2_MAX_FREQ) {
143 temp_setup->fout = temp_setup->vco2;
144 do_div(temp_setup->fout, 2 * (temp_setup->divq + 1));
145
146 ret = clk_sccg_pll2_check_match(setup, temp_setup);
147 if (!ret) {
148 temp_setup->bypass = PLL_BYPASS1;
149 return ret;
150 }
151 }
152 }
67 153
68 val = readl_relaxed(pll->base + PLL_CFG2); 154 return ret;
69 divf = FIELD_GET(PLL_DIVF1_MASK, val); 155}
156
157static int clk_sccg_divf2_lookup(struct clk_sccg_pll_setup *setup,
158 struct clk_sccg_pll_setup *temp_setup)
159{
160 int ret = -EINVAL;
161
162 for (temp_setup->divf2 = 0; temp_setup->divf2 <= PLL_DIVF2_MAX;
163 temp_setup->divf2++) {
164 ret = clk_sccg_divq_lookup(setup, temp_setup);
165 if (!ret)
166 return ret;
167 }
70 168
71 return parent_rate * 2 * (divf + 1); 169 return ret;
72} 170}
73 171
74static long clk_pll1_round_rate(struct clk_hw *hw, unsigned long rate, 172static int clk_sccg_divr2_lookup(struct clk_sccg_pll_setup *setup,
75 unsigned long *prate) 173 struct clk_sccg_pll_setup *temp_setup)
76{ 174{
77 unsigned long parent_rate = *prate; 175 int ret = -EINVAL;
78 u32 div; 176
177 for (temp_setup->divr2 = 0; temp_setup->divr2 <= PLL_DIVR2_MAX;
178 temp_setup->divr2++) {
179 temp_setup->ref_div2 = temp_setup->vco1;
180 do_div(temp_setup->ref_div2, temp_setup->divr2 + 1);
181 if (temp_setup->ref_div2 >= PLL_STAGE2_REF_MIN_FREQ &&
182 temp_setup->ref_div2 <= PLL_STAGE2_REF_MAX_FREQ) {
183 ret = clk_sccg_divf2_lookup(setup, temp_setup);
184 if (!ret)
185 return ret;
186 }
187 }
188
189 return ret;
190}
191
192static int clk_sccg_pll2_find_setup(struct clk_sccg_pll_setup *setup,
193 struct clk_sccg_pll_setup *temp_setup,
194 uint64_t ref)
195{
196
197 int ret = -EINVAL;
79 198
80 if (!parent_rate) 199 if (ref < PLL_STAGE1_MIN_FREQ || ref > PLL_STAGE1_MAX_FREQ)
81 return 0; 200 return ret;
82 201
83 div = rate / (parent_rate * 2); 202 temp_setup->vco1 = ref;
84 203
85 return parent_rate * div * 2; 204 ret = clk_sccg_divr2_lookup(setup, temp_setup);
205 return ret;
86} 206}
87 207
88static int clk_pll1_set_rate(struct clk_hw *hw, unsigned long rate, 208static int clk_sccg_divf1_lookup(struct clk_sccg_pll_setup *setup,
89 unsigned long parent_rate) 209 struct clk_sccg_pll_setup *temp_setup)
90{ 210{
91 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); 211 int ret = -EINVAL;
92 u32 val;
93 u32 divf;
94 212
95 if (!parent_rate) 213 for (temp_setup->divf1 = 0; temp_setup->divf1 <= PLL_DIVF1_MAX;
96 return -EINVAL; 214 temp_setup->divf1++) {
215 uint64_t vco1 = temp_setup->ref;
97 216
98 divf = rate / (parent_rate * 2); 217 do_div(vco1, temp_setup->divr1 + 1);
218 vco1 *= 2;
219 vco1 *= temp_setup->divf1 + 1;
99 220
100 val = readl_relaxed(pll->base + PLL_CFG2); 221 ret = clk_sccg_pll2_find_setup(setup, temp_setup, vco1);
101 val &= ~PLL_DIVF1_MASK; 222 if (!ret) {
102 val |= FIELD_PREP(PLL_DIVF1_MASK, divf - 1); 223 temp_setup->bypass = PLL_BYPASS_NONE;
103 writel_relaxed(val, pll->base + PLL_CFG2); 224 return ret;
225 }
226 }
227
228 return ret;
229}
230
231static int clk_sccg_divr1_lookup(struct clk_sccg_pll_setup *setup,
232 struct clk_sccg_pll_setup *temp_setup)
233{
234 int ret = -EINVAL;
235
236 for (temp_setup->divr1 = 0; temp_setup->divr1 <= PLL_DIVR1_MAX;
237 temp_setup->divr1++) {
238 temp_setup->ref_div1 = temp_setup->ref;
239 do_div(temp_setup->ref_div1, temp_setup->divr1 + 1);
240 if (temp_setup->ref_div1 >= PLL_STAGE1_REF_MIN_FREQ &&
241 temp_setup->ref_div1 <= PLL_STAGE1_REF_MAX_FREQ) {
242 ret = clk_sccg_divf1_lookup(setup, temp_setup);
243 if (!ret)
244 return ret;
245 }
246 }
247
248 return ret;
249}
250
251static int clk_sccg_pll1_find_setup(struct clk_sccg_pll_setup *setup,
252 struct clk_sccg_pll_setup *temp_setup,
253 uint64_t ref)
254{
255
256 int ret = -EINVAL;
257
258 if (ref < PLL_REF_MIN_FREQ || ref > PLL_REF_MAX_FREQ)
259 return ret;
260
261 temp_setup->ref = ref;
262
263 ret = clk_sccg_divr1_lookup(setup, temp_setup);
264
265 return ret;
266}
267
268static int clk_sccg_pll_find_setup(struct clk_sccg_pll_setup *setup,
269 uint64_t prate,
270 uint64_t rate, int try_bypass)
271{
272 struct clk_sccg_pll_setup temp_setup;
273 int ret = -EINVAL;
274
275 memset(&temp_setup, 0, sizeof(struct clk_sccg_pll_setup));
276 memset(setup, 0, sizeof(struct clk_sccg_pll_setup));
277
278 temp_setup.fout_error = PLL_OUT_MAX_FREQ;
279 temp_setup.fout_request = rate;
280
281 switch (try_bypass) {
104 282
105 return clk_pll_wait_lock(pll); 283 case PLL_BYPASS2:
284 if (prate == rate) {
285 setup->bypass = PLL_BYPASS2;
286 setup->fout = rate;
287 ret = 0;
288 }
289 break;
290
291 case PLL_BYPASS1:
292 ret = clk_sccg_pll2_find_setup(setup, &temp_setup, prate);
293 break;
294
295 case PLL_BYPASS_NONE:
296 ret = clk_sccg_pll1_find_setup(setup, &temp_setup, prate);
297 break;
298 }
299
300 return ret;
301}
302
303
304static int clk_sccg_pll_is_prepared(struct clk_hw *hw)
305{
306 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
307
308 u32 val = readl_relaxed(pll->base + PLL_CFG0);
309
310 return (val & PLL_PD_MASK) ? 0 : 1;
106} 311}
107 312
108static int clk_pll1_prepare(struct clk_hw *hw) 313static int clk_sccg_pll_prepare(struct clk_hw *hw)
109{ 314{
110 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); 315 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
111 u32 val; 316 u32 val;
@@ -114,10 +319,10 @@ static int clk_pll1_prepare(struct clk_hw *hw)
114 val &= ~PLL_PD_MASK; 319 val &= ~PLL_PD_MASK;
115 writel_relaxed(val, pll->base + PLL_CFG0); 320 writel_relaxed(val, pll->base + PLL_CFG0);
116 321
117 return clk_pll_wait_lock(pll); 322 return clk_sccg_pll_wait_lock(pll);
118} 323}
119 324
120static void clk_pll1_unprepare(struct clk_hw *hw) 325static void clk_sccg_pll_unprepare(struct clk_hw *hw)
121{ 326{
122 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); 327 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
123 u32 val; 328 u32 val;
@@ -125,121 +330,208 @@ static void clk_pll1_unprepare(struct clk_hw *hw)
125 val = readl_relaxed(pll->base + PLL_CFG0); 330 val = readl_relaxed(pll->base + PLL_CFG0);
126 val |= PLL_PD_MASK; 331 val |= PLL_PD_MASK;
127 writel_relaxed(val, pll->base + PLL_CFG0); 332 writel_relaxed(val, pll->base + PLL_CFG0);
128
129} 333}
130 334
131static unsigned long clk_pll2_recalc_rate(struct clk_hw *hw, 335static unsigned long clk_sccg_pll_recalc_rate(struct clk_hw *hw,
132 unsigned long parent_rate) 336 unsigned long parent_rate)
133{ 337{
134 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); 338 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
135 u32 val, ref, divr1, divf1, divr2, divf2; 339 u32 val, divr1, divf1, divr2, divf2, divq;
136 u64 temp64; 340 u64 temp64;
137 341
138 val = readl_relaxed(pll->base + PLL_CFG0);
139 switch (FIELD_GET(PLL_REF_MASK, val)) {
140 case 0:
141 ref = OSC_25M;
142 break;
143 case 1:
144 ref = OSC_27M;
145 break;
146 default:
147 ref = OSC_25M;
148 break;
149 }
150
151 val = readl_relaxed(pll->base + PLL_CFG2); 342 val = readl_relaxed(pll->base + PLL_CFG2);
152 divr1 = FIELD_GET(PLL_DIVR1_MASK, val); 343 divr1 = FIELD_GET(PLL_DIVR1_MASK, val);
153 divr2 = FIELD_GET(PLL_DIVR2_MASK, val); 344 divr2 = FIELD_GET(PLL_DIVR2_MASK, val);
154 divf1 = FIELD_GET(PLL_DIVF1_MASK, val); 345 divf1 = FIELD_GET(PLL_DIVF1_MASK, val);
155 divf2 = FIELD_GET(PLL_DIVF2_MASK, val); 346 divf2 = FIELD_GET(PLL_DIVF2_MASK, val);
156 347 divq = FIELD_GET(PLL_DIVQ_MASK, val);
157 temp64 = ref * 2; 348
158 temp64 *= (divf1 + 1) * (divf2 + 1); 349 temp64 = parent_rate;
159 350
160 do_div(temp64, (divr1 + 1) * (divr2 + 1)); 351 val = clk_readl(pll->base + PLL_CFG0);
352 if (val & SSCG_PLL_BYPASS2_MASK) {
353 temp64 = parent_rate;
354 } else if (val & SSCG_PLL_BYPASS1_MASK) {
355 temp64 *= divf2;
356 do_div(temp64, (divr2 + 1) * (divq + 1));
357 } else {
358 temp64 *= 2;
359 temp64 *= (divf1 + 1) * (divf2 + 1);
360 do_div(temp64, (divr1 + 1) * (divr2 + 1) * (divq + 1));
361 }
161 362
162 return temp64; 363 return temp64;
163} 364}
164 365
165static long clk_pll2_round_rate(struct clk_hw *hw, unsigned long rate, 366static int clk_sccg_pll_set_rate(struct clk_hw *hw, unsigned long rate,
166 unsigned long *prate) 367 unsigned long parent_rate)
167{ 368{
168 u32 div; 369 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
169 unsigned long parent_rate = *prate; 370 struct clk_sccg_pll_setup *setup = &pll->setup;
371 u32 val;
170 372
171 if (!parent_rate) 373 /* set bypass here too since the parent might be the same */
172 return 0; 374 val = clk_readl(pll->base + PLL_CFG0);
375 val &= ~SSCG_PLL_BYPASS_MASK;
376 val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, setup->bypass);
377 clk_writel(val, pll->base + PLL_CFG0);
173 378
174 div = rate / parent_rate; 379 val = readl_relaxed(pll->base + PLL_CFG2);
380 val &= ~(PLL_DIVF1_MASK | PLL_DIVF2_MASK);
381 val &= ~(PLL_DIVR1_MASK | PLL_DIVR2_MASK | PLL_DIVQ_MASK);
382 val |= FIELD_PREP(PLL_DIVF1_MASK, setup->divf1);
383 val |= FIELD_PREP(PLL_DIVF2_MASK, setup->divf2);
384 val |= FIELD_PREP(PLL_DIVR1_MASK, setup->divr1);
385 val |= FIELD_PREP(PLL_DIVR2_MASK, setup->divr2);
386 val |= FIELD_PREP(PLL_DIVQ_MASK, setup->divq);
387 writel_relaxed(val, pll->base + PLL_CFG2);
175 388
176 return parent_rate * div; 389 return clk_sccg_pll_wait_lock(pll);
177} 390}
178 391
179static int clk_pll2_set_rate(struct clk_hw *hw, unsigned long rate, 392static u8 clk_sccg_pll_get_parent(struct clk_hw *hw)
180 unsigned long parent_rate)
181{ 393{
394 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
182 u32 val; 395 u32 val;
183 u32 divf; 396 u8 ret = pll->parent;
397
398 val = clk_readl(pll->base + PLL_CFG0);
399 if (val & SSCG_PLL_BYPASS2_MASK)
400 ret = pll->bypass2;
401 else if (val & SSCG_PLL_BYPASS1_MASK)
402 ret = pll->bypass1;
403 return ret;
404}
405
406static int clk_sccg_pll_set_parent(struct clk_hw *hw, u8 index)
407{
184 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); 408 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
409 u32 val;
185 410
186 if (!parent_rate) 411 val = clk_readl(pll->base + PLL_CFG0);
187 return -EINVAL; 412 val &= ~SSCG_PLL_BYPASS_MASK;
413 val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, pll->setup.bypass);
414 clk_writel(val, pll->base + PLL_CFG0);
188 415
189 divf = rate / parent_rate; 416 return clk_sccg_pll_wait_lock(pll);
417}
190 418
191 val = readl_relaxed(pll->base + PLL_CFG2); 419static int __clk_sccg_pll_determine_rate(struct clk_hw *hw,
192 val &= ~PLL_DIVF2_MASK; 420 struct clk_rate_request *req,
193 val |= FIELD_PREP(PLL_DIVF2_MASK, divf - 1); 421 uint64_t min,
194 writel_relaxed(val, pll->base + PLL_CFG2); 422 uint64_t max,
423 uint64_t rate,
424 int bypass)
425{
426 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
427 struct clk_sccg_pll_setup *setup = &pll->setup;
428 struct clk_hw *parent_hw = NULL;
429 int bypass_parent_index;
430 int ret = -EINVAL;
431
432 req->max_rate = max;
433 req->min_rate = min;
434
435 switch (bypass) {
436 case PLL_BYPASS2:
437 bypass_parent_index = pll->bypass2;
438 break;
439 case PLL_BYPASS1:
440 bypass_parent_index = pll->bypass1;
441 break;
442 default:
443 bypass_parent_index = pll->parent;
444 break;
445 }
446
447 parent_hw = clk_hw_get_parent_by_index(hw, bypass_parent_index);
448 ret = __clk_determine_rate(parent_hw, req);
449 if (!ret) {
450 ret = clk_sccg_pll_find_setup(setup, req->rate,
451 rate, bypass);
452 }
453
454 req->best_parent_hw = parent_hw;
455 req->best_parent_rate = req->rate;
456 req->rate = setup->fout;
195 457
196 return clk_pll_wait_lock(pll); 458 return ret;
197} 459}
198 460
199static const struct clk_ops clk_sccg_pll1_ops = { 461static int clk_sccg_pll_determine_rate(struct clk_hw *hw,
200 .is_prepared = clk_pll1_is_prepared, 462 struct clk_rate_request *req)
201 .recalc_rate = clk_pll1_recalc_rate, 463{
202 .round_rate = clk_pll1_round_rate, 464 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
203 .set_rate = clk_pll1_set_rate, 465 struct clk_sccg_pll_setup *setup = &pll->setup;
204}; 466 uint64_t rate = req->rate;
467 uint64_t min = req->min_rate;
468 uint64_t max = req->max_rate;
469 int ret = -EINVAL;
470
471 if (rate < PLL_OUT_MIN_FREQ || rate > PLL_OUT_MAX_FREQ)
472 return ret;
473
474 ret = __clk_sccg_pll_determine_rate(hw, req, req->rate, req->rate,
475 rate, PLL_BYPASS2);
476 if (!ret)
477 return ret;
478
479 ret = __clk_sccg_pll_determine_rate(hw, req, PLL_STAGE1_REF_MIN_FREQ,
480 PLL_STAGE1_REF_MAX_FREQ, rate,
481 PLL_BYPASS1);
482 if (!ret)
483 return ret;
484
485 ret = __clk_sccg_pll_determine_rate(hw, req, PLL_REF_MIN_FREQ,
486 PLL_REF_MAX_FREQ, rate,
487 PLL_BYPASS_NONE);
488 if (!ret)
489 return ret;
490
491 if (setup->fout >= min && setup->fout <= max)
492 ret = 0;
493
494 return ret;
495}
205 496
206static const struct clk_ops clk_sccg_pll2_ops = { 497static const struct clk_ops clk_sccg_pll_ops = {
207 .prepare = clk_pll1_prepare, 498 .prepare = clk_sccg_pll_prepare,
208 .unprepare = clk_pll1_unprepare, 499 .unprepare = clk_sccg_pll_unprepare,
209 .recalc_rate = clk_pll2_recalc_rate, 500 .is_prepared = clk_sccg_pll_is_prepared,
210 .round_rate = clk_pll2_round_rate, 501 .recalc_rate = clk_sccg_pll_recalc_rate,
211 .set_rate = clk_pll2_set_rate, 502 .set_rate = clk_sccg_pll_set_rate,
503 .set_parent = clk_sccg_pll_set_parent,
504 .get_parent = clk_sccg_pll_get_parent,
505 .determine_rate = clk_sccg_pll_determine_rate,
212}; 506};
213 507
214struct clk *imx_clk_sccg_pll(const char *name, 508struct clk *imx_clk_sccg_pll(const char *name,
215 const char *parent_name, 509 const char * const *parent_names,
510 u8 num_parents,
511 u8 parent, u8 bypass1, u8 bypass2,
216 void __iomem *base, 512 void __iomem *base,
217 enum imx_sccg_pll_type pll_type) 513 unsigned long flags)
218{ 514{
219 struct clk_sccg_pll *pll; 515 struct clk_sccg_pll *pll;
220 struct clk_init_data init; 516 struct clk_init_data init;
221 struct clk_hw *hw; 517 struct clk_hw *hw;
222 int ret; 518 int ret;
223 519
224 switch (pll_type) {
225 case SCCG_PLL1:
226 init.ops = &clk_sccg_pll1_ops;
227 break;
228 case SCCG_PLL2:
229 init.ops = &clk_sccg_pll2_ops;
230 break;
231 default:
232 return ERR_PTR(-EINVAL);
233 }
234
235 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 520 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
236 if (!pll) 521 if (!pll)
237 return ERR_PTR(-ENOMEM); 522 return ERR_PTR(-ENOMEM);
238 523
524 pll->parent = parent;
525 pll->bypass1 = bypass1;
526 pll->bypass2 = bypass2;
527
528 pll->base = base;
239 init.name = name; 529 init.name = name;
240 init.flags = 0; 530 init.ops = &clk_sccg_pll_ops;
241 init.parent_names = &parent_name; 531
242 init.num_parents = 1; 532 init.flags = flags;
533 init.parent_names = parent_names;
534 init.num_parents = num_parents;
243 535
244 pll->base = base; 536 pll->base = base;
245 pll->hw.init = &init; 537 pll->hw.init = &init;
diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
index 7ccf7edfe11c..fbef740704d0 100644
--- a/drivers/clk/imx/clk-scu.c
+++ b/drivers/clk/imx/clk-scu.c
@@ -4,12 +4,17 @@
4 * Dong Aisheng <aisheng.dong@nxp.com> 4 * Dong Aisheng <aisheng.dong@nxp.com>
5 */ 5 */
6 6
7#include <dt-bindings/firmware/imx/rsrc.h>
8#include <linux/arm-smccc.h>
7#include <linux/clk-provider.h> 9#include <linux/clk-provider.h>
8#include <linux/err.h> 10#include <linux/err.h>
9#include <linux/slab.h> 11#include <linux/slab.h>
10 12
11#include "clk-scu.h" 13#include "clk-scu.h"
12 14
15#define IMX_SIP_CPUFREQ 0xC2000001
16#define IMX_SIP_SET_CPUFREQ 0x00
17
13static struct imx_sc_ipc *ccm_ipc_handle; 18static struct imx_sc_ipc *ccm_ipc_handle;
14 19
15/* 20/*
@@ -66,6 +71,41 @@ struct imx_sc_msg_get_clock_rate {
66}; 71};
67 72
68/* 73/*
74 * struct imx_sc_msg_get_clock_parent - clock get parent protocol
75 * @hdr: SCU protocol header
76 * @req: get parent request protocol
77 * @resp: get parent response protocol
78 *
79 * This structure describes the SCU protocol of clock get parent
80 */
81struct imx_sc_msg_get_clock_parent {
82 struct imx_sc_rpc_msg hdr;
83 union {
84 struct req_get_clock_parent {
85 __le16 resource;
86 u8 clk;
87 } __packed req;
88 struct resp_get_clock_parent {
89 u8 parent;
90 } resp;
91 } data;
92};
93
94/*
95 * struct imx_sc_msg_set_clock_parent - clock set parent protocol
96 * @hdr: SCU protocol header
97 * @req: set parent request protocol
98 *
99 * This structure describes the SCU protocol of clock set parent
100 */
101struct imx_sc_msg_set_clock_parent {
102 struct imx_sc_rpc_msg hdr;
103 __le16 resource;
104 u8 clk;
105 u8 parent;
106} __packed;
107
108/*
69 * struct imx_sc_msg_req_clock_enable - clock gate protocol 109 * struct imx_sc_msg_req_clock_enable - clock gate protocol
70 * @hdr: SCU protocol header 110 * @hdr: SCU protocol header
71 * @resource: clock resource to gate 111 * @resource: clock resource to gate
@@ -145,6 +185,25 @@ static long clk_scu_round_rate(struct clk_hw *hw, unsigned long rate,
145 return rate; 185 return rate;
146} 186}
147 187
188static int clk_scu_atf_set_cpu_rate(struct clk_hw *hw, unsigned long rate,
189 unsigned long parent_rate)
190{
191 struct clk_scu *clk = to_clk_scu(hw);
192 struct arm_smccc_res res;
193 unsigned long cluster_id;
194
195 if (clk->rsrc_id == IMX_SC_R_A35)
196 cluster_id = 0;
197 else
198 return -EINVAL;
199
200 /* CPU frequency scaling can ONLY be done by ARM-Trusted-Firmware */
201 arm_smccc_smc(IMX_SIP_CPUFREQ, IMX_SIP_SET_CPUFREQ,
202 cluster_id, rate, 0, 0, 0, 0, &res);
203
204 return 0;
205}
206
148/* 207/*
149 * clk_scu_set_rate - Set rate for a SCU clock 208 * clk_scu_set_rate - Set rate for a SCU clock
150 * @hw: clock to change rate for 209 * @hw: clock to change rate for
@@ -173,6 +232,49 @@ static int clk_scu_set_rate(struct clk_hw *hw, unsigned long rate,
173 return imx_scu_call_rpc(ccm_ipc_handle, &msg, true); 232 return imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
174} 233}
175 234
235static u8 clk_scu_get_parent(struct clk_hw *hw)
236{
237 struct clk_scu *clk = to_clk_scu(hw);
238 struct imx_sc_msg_get_clock_parent msg;
239 struct imx_sc_rpc_msg *hdr = &msg.hdr;
240 int ret;
241
242 hdr->ver = IMX_SC_RPC_VERSION;
243 hdr->svc = IMX_SC_RPC_SVC_PM;
244 hdr->func = IMX_SC_PM_FUNC_GET_CLOCK_PARENT;
245 hdr->size = 2;
246
247 msg.data.req.resource = cpu_to_le16(clk->rsrc_id);
248 msg.data.req.clk = clk->clk_type;
249
250 ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
251 if (ret) {
252 pr_err("%s: failed to get clock parent %d\n",
253 clk_hw_get_name(hw), ret);
254 return 0;
255 }
256
257 return msg.data.resp.parent;
258}
259
260static int clk_scu_set_parent(struct clk_hw *hw, u8 index)
261{
262 struct clk_scu *clk = to_clk_scu(hw);
263 struct imx_sc_msg_set_clock_parent msg;
264 struct imx_sc_rpc_msg *hdr = &msg.hdr;
265
266 hdr->ver = IMX_SC_RPC_VERSION;
267 hdr->svc = IMX_SC_RPC_SVC_PM;
268 hdr->func = IMX_SC_PM_FUNC_SET_CLOCK_PARENT;
269 hdr->size = 2;
270
271 msg.resource = cpu_to_le16(clk->rsrc_id);
272 msg.clk = clk->clk_type;
273 msg.parent = index;
274
275 return imx_scu_call_rpc(ccm_ipc_handle, &msg, true);
276}
277
176static int sc_pm_clock_enable(struct imx_sc_ipc *ipc, u16 resource, 278static int sc_pm_clock_enable(struct imx_sc_ipc *ipc, u16 resource,
177 u8 clk, bool enable, bool autog) 279 u8 clk, bool enable, bool autog)
178{ 280{
@@ -228,11 +330,22 @@ static const struct clk_ops clk_scu_ops = {
228 .recalc_rate = clk_scu_recalc_rate, 330 .recalc_rate = clk_scu_recalc_rate,
229 .round_rate = clk_scu_round_rate, 331 .round_rate = clk_scu_round_rate,
230 .set_rate = clk_scu_set_rate, 332 .set_rate = clk_scu_set_rate,
333 .get_parent = clk_scu_get_parent,
334 .set_parent = clk_scu_set_parent,
335 .prepare = clk_scu_prepare,
336 .unprepare = clk_scu_unprepare,
337};
338
339static const struct clk_ops clk_scu_cpu_ops = {
340 .recalc_rate = clk_scu_recalc_rate,
341 .round_rate = clk_scu_round_rate,
342 .set_rate = clk_scu_atf_set_cpu_rate,
231 .prepare = clk_scu_prepare, 343 .prepare = clk_scu_prepare,
232 .unprepare = clk_scu_unprepare, 344 .unprepare = clk_scu_unprepare,
233}; 345};
234 346
235struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type) 347struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents,
348 int num_parents, u32 rsrc_id, u8 clk_type)
236{ 349{
237 struct clk_init_data init; 350 struct clk_init_data init;
238 struct clk_scu *clk; 351 struct clk_scu *clk;
@@ -248,7 +361,13 @@ struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type)
248 361
249 init.name = name; 362 init.name = name;
250 init.ops = &clk_scu_ops; 363 init.ops = &clk_scu_ops;
251 init.num_parents = 0; 364 if (rsrc_id == IMX_SC_R_A35)
365 init.ops = &clk_scu_cpu_ops;
366 else
367 init.ops = &clk_scu_ops;
368 init.parent_names = parents;
369 init.num_parents = num_parents;
370
252 /* 371 /*
253 * Note on MX8, the clocks are tightly coupled with power domain 372 * Note on MX8, the clocks are tightly coupled with power domain
254 * that once the power domain is off, the clock status may be 373 * that once the power domain is off, the clock status may be
diff --git a/drivers/clk/imx/clk-scu.h b/drivers/clk/imx/clk-scu.h
index 52c1746ec988..2bcfaf06a458 100644
--- a/drivers/clk/imx/clk-scu.h
+++ b/drivers/clk/imx/clk-scu.h
@@ -10,7 +10,21 @@
10#include <linux/firmware/imx/sci.h> 10#include <linux/firmware/imx/sci.h>
11 11
12int imx_clk_scu_init(void); 12int imx_clk_scu_init(void);
13struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type); 13
14struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents,
15 int num_parents, u32 rsrc_id, u8 clk_type);
16
17static inline struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id,
18 u8 clk_type)
19{
20 return __imx_clk_scu(name, NULL, 0, rsrc_id, clk_type);
21}
22
23static inline struct clk_hw *imx_clk_scu2(const char *name, const char * const *parents,
24 int num_parents, u32 rsrc_id, u8 clk_type)
25{
26 return __imx_clk_scu(name, parents, num_parents, rsrc_id, clk_type);
27}
14 28
15struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name, 29struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name,
16 unsigned long flags, void __iomem *reg, 30 unsigned long flags, void __iomem *reg,
diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
index 6dae54325a91..a334667c450a 100644
--- a/drivers/clk/imx/clk-vf610.c
+++ b/drivers/clk/imx/clk-vf610.c
@@ -203,6 +203,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
203 np = of_find_compatible_node(NULL, NULL, "fsl,vf610-anatop"); 203 np = of_find_compatible_node(NULL, NULL, "fsl,vf610-anatop");
204 anatop_base = of_iomap(np, 0); 204 anatop_base = of_iomap(np, 0);
205 BUG_ON(!anatop_base); 205 BUG_ON(!anatop_base);
206 of_node_put(np);
206 207
207 np = ccm_node; 208 np = ccm_node;
208 ccm_base = of_iomap(np, 0); 209 ccm_base = of_iomap(np, 0);
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 028312de21b8..5748ec8673e4 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -27,6 +27,30 @@ enum imx_sccg_pll_type {
27 SCCG_PLL2, 27 SCCG_PLL2,
28}; 28};
29 29
30enum imx_pll14xx_type {
31 PLL_1416X,
32 PLL_1443X,
33};
34
35/* NOTE: Rate table should be kept sorted in descending order. */
36struct imx_pll14xx_rate_table {
37 unsigned int rate;
38 unsigned int pdiv;
39 unsigned int mdiv;
40 unsigned int sdiv;
41 unsigned int kdiv;
42};
43
44struct imx_pll14xx_clk {
45 enum imx_pll14xx_type type;
46 const struct imx_pll14xx_rate_table *rate_table;
47 int rate_count;
48 int flags;
49};
50
51struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
52 void __iomem *base, const struct imx_pll14xx_clk *pll_clk);
53
30struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name, 54struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
31 const char *parent, void __iomem *base); 55 const char *parent, void __iomem *base);
32 56
@@ -36,9 +60,12 @@ struct clk *imx_clk_pllv2(const char *name, const char *parent,
36struct clk *imx_clk_frac_pll(const char *name, const char *parent_name, 60struct clk *imx_clk_frac_pll(const char *name, const char *parent_name,
37 void __iomem *base); 61 void __iomem *base);
38 62
39struct clk *imx_clk_sccg_pll(const char *name, const char *parent_name, 63struct clk *imx_clk_sccg_pll(const char *name,
40 void __iomem *base, 64 const char * const *parent_names,
41 enum imx_sccg_pll_type pll_type); 65 u8 num_parents,
66 u8 parent, u8 bypass1, u8 bypass2,
67 void __iomem *base,
68 unsigned long flags);
42 69
43enum imx_pllv3_type { 70enum imx_pllv3_type {
44 IMX_PLLV3_GENERIC, 71 IMX_PLLV3_GENERIC,
@@ -329,7 +356,8 @@ static inline struct clk *imx_clk_mux_flags(const char *name,
329} 356}
330 357
331static inline struct clk *imx_clk_mux2_flags(const char *name, 358static inline struct clk *imx_clk_mux2_flags(const char *name,
332 void __iomem *reg, u8 shift, u8 width, const char **parents, 359 void __iomem *reg, u8 shift, u8 width,
360 const char * const *parents,
333 int num_parents, unsigned long flags) 361 int num_parents, unsigned long flags)
334{ 362{
335 return clk_register_mux(NULL, name, parents, num_parents, 363 return clk_register_mux(NULL, name, parents, num_parents,
@@ -354,7 +382,7 @@ struct clk *imx_clk_cpu(const char *name, const char *parent_name,
354 struct clk *step); 382 struct clk *step);
355 383
356struct clk *imx8m_clk_composite_flags(const char *name, 384struct clk *imx8m_clk_composite_flags(const char *name,
357 const char **parent_names, 385 const char * const *parent_names,
358 int num_parents, void __iomem *reg, 386 int num_parents, void __iomem *reg,
359 unsigned long flags); 387 unsigned long flags);
360 388
diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
index 5ef7d9ba2195..510b685212d3 100644
--- a/drivers/clk/ingenic/cgu.c
+++ b/drivers/clk/ingenic/cgu.c
@@ -83,7 +83,7 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
83 const struct ingenic_cgu_clk_info *clk_info; 83 const struct ingenic_cgu_clk_info *clk_info;
84 const struct ingenic_cgu_pll_info *pll_info; 84 const struct ingenic_cgu_pll_info *pll_info;
85 unsigned m, n, od_enc, od; 85 unsigned m, n, od_enc, od;
86 bool bypass, enable; 86 bool bypass;
87 unsigned long flags; 87 unsigned long flags;
88 u32 ctl; 88 u32 ctl;
89 89
@@ -103,7 +103,6 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
103 od_enc &= GENMASK(pll_info->od_bits - 1, 0); 103 od_enc &= GENMASK(pll_info->od_bits - 1, 0);
104 bypass = !pll_info->no_bypass_bit && 104 bypass = !pll_info->no_bypass_bit &&
105 !!(ctl & BIT(pll_info->bypass_bit)); 105 !!(ctl & BIT(pll_info->bypass_bit));
106 enable = !!(ctl & BIT(pll_info->enable_bit));
107 106
108 if (bypass) 107 if (bypass)
109 return parent_rate; 108 return parent_rate;
@@ -426,16 +425,16 @@ ingenic_clk_round_rate(struct clk_hw *hw, unsigned long req_rate,
426 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw); 425 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
427 struct ingenic_cgu *cgu = ingenic_clk->cgu; 426 struct ingenic_cgu *cgu = ingenic_clk->cgu;
428 const struct ingenic_cgu_clk_info *clk_info; 427 const struct ingenic_cgu_clk_info *clk_info;
429 long rate = *parent_rate; 428 unsigned int div = 1;
430 429
431 clk_info = &cgu->clock_info[ingenic_clk->idx]; 430 clk_info = &cgu->clock_info[ingenic_clk->idx];
432 431
433 if (clk_info->type & CGU_CLK_DIV) 432 if (clk_info->type & CGU_CLK_DIV)
434 rate /= ingenic_clk_calc_div(clk_info, *parent_rate, req_rate); 433 div = ingenic_clk_calc_div(clk_info, *parent_rate, req_rate);
435 else if (clk_info->type & CGU_CLK_FIXDIV) 434 else if (clk_info->type & CGU_CLK_FIXDIV)
436 rate /= clk_info->fixdiv.div; 435 div = clk_info->fixdiv.div;
437 436
438 return rate; 437 return DIV_ROUND_UP(*parent_rate, div);
439} 438}
440 439
441static int 440static int
@@ -455,7 +454,7 @@ ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate,
455 454
456 if (clk_info->type & CGU_CLK_DIV) { 455 if (clk_info->type & CGU_CLK_DIV) {
457 div = ingenic_clk_calc_div(clk_info, parent_rate, req_rate); 456 div = ingenic_clk_calc_div(clk_info, parent_rate, req_rate);
458 rate = parent_rate / div; 457 rate = DIV_ROUND_UP(parent_rate, div);
459 458
460 if (rate != req_rate) 459 if (rate != req_rate)
461 return -EINVAL; 460 return -EINVAL;
diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h
index 502bcbb61b04..e12716d8ce3c 100644
--- a/drivers/clk/ingenic/cgu.h
+++ b/drivers/clk/ingenic/cgu.h
@@ -80,7 +80,7 @@ struct ingenic_cgu_mux_info {
80 * @reg: offset of the divider control register within the CGU 80 * @reg: offset of the divider control register within the CGU
81 * @shift: number of bits to left shift the divide value by (ie. the index of 81 * @shift: number of bits to left shift the divide value by (ie. the index of
82 * the lowest bit of the divide value within its control register) 82 * the lowest bit of the divide value within its control register)
83 * @div: number of bits to divide the divider value by (i.e. if the 83 * @div: number to divide the divider value by (i.e. if the
84 * effective divider value is the value written to the register 84 * effective divider value is the value written to the register
85 * multiplied by some constant) 85 * multiplied by some constant)
86 * @bits: the size of the divide value in bits 86 * @bits: the size of the divide value in bits
diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c
index 4479c102e899..b86edd328249 100644
--- a/drivers/clk/ingenic/jz4740-cgu.c
+++ b/drivers/clk/ingenic/jz4740-cgu.c
@@ -165,7 +165,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
165 .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 }, 165 .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 },
166 .mux = { CGU_REG_CPCCR, 29, 1 }, 166 .mux = { CGU_REG_CPCCR, 29, 1 },
167 .div = { CGU_REG_CPCCR, 23, 1, 6, -1, -1, -1 }, 167 .div = { CGU_REG_CPCCR, 23, 1, 6, -1, -1, -1 },
168 .gate = { CGU_REG_SCR, 6 }, 168 .gate = { CGU_REG_SCR, 6, true },
169 }, 169 },
170 170
171 /* Gate-only clocks */ 171 /* Gate-only clocks */
diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
index 934bf0e45e26..9628d4e7690b 100644
--- a/drivers/clk/mediatek/clk-gate.c
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -157,7 +157,8 @@ struct clk *mtk_clk_register_gate(
157 int clr_ofs, 157 int clr_ofs,
158 int sta_ofs, 158 int sta_ofs,
159 u8 bit, 159 u8 bit,
160 const struct clk_ops *ops) 160 const struct clk_ops *ops,
161 unsigned long flags)
161{ 162{
162 struct mtk_clk_gate *cg; 163 struct mtk_clk_gate *cg;
163 struct clk *clk; 164 struct clk *clk;
@@ -172,6 +173,7 @@ struct clk *mtk_clk_register_gate(
172 init.parent_names = parent_name ? &parent_name : NULL; 173 init.parent_names = parent_name ? &parent_name : NULL;
173 init.num_parents = parent_name ? 1 : 0; 174 init.num_parents = parent_name ? 1 : 0;
174 init.ops = ops; 175 init.ops = ops;
176 init.flags = flags;
175 177
176 cg->regmap = regmap; 178 cg->regmap = regmap;
177 cg->set_ofs = set_ofs; 179 cg->set_ofs = set_ofs;
diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h
index 72ef89b3ad7b..9f766dfe1d57 100644
--- a/drivers/clk/mediatek/clk-gate.h
+++ b/drivers/clk/mediatek/clk-gate.h
@@ -47,6 +47,7 @@ struct clk *mtk_clk_register_gate(
47 int clr_ofs, 47 int clr_ofs,
48 int sta_ofs, 48 int sta_ofs,
49 u8 bit, 49 u8 bit,
50 const struct clk_ops *ops); 50 const struct clk_ops *ops,
51 unsigned long flags);
51 52
52#endif /* __DRV_CLK_GATE_H */ 53#endif /* __DRV_CLK_GATE_H */
diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c
index ab6ab07f53e6..905a2316f6a7 100644
--- a/drivers/clk/mediatek/clk-mt2701.c
+++ b/drivers/clk/mediatek/clk-mt2701.c
@@ -535,8 +535,8 @@ static const struct mtk_composite top_muxes[] = {
535 0x0080, 8, 2, 15), 535 0x0080, 8, 2, 15),
536 MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents, 536 MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents,
537 0x0080, 16, 3, 23), 537 0x0080, 16, 3, 23),
538 MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 538 MUX_GATE_FLAGS_2(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents,
539 0x0080, 24, 2, 31), 539 0x0080, 24, 2, 31, 0, CLK_MUX_ROUND_CLOSEST),
540 540
541 MUX_GATE(CLK_TOP_TVE_SEL, "tve_sel", tve_parents, 541 MUX_GATE(CLK_TOP_TVE_SEL, "tve_sel", tve_parents,
542 0x0090, 0, 3, 7), 542 0x0090, 0, 3, 7),
diff --git a/drivers/clk/mediatek/clk-mt2712.c b/drivers/clk/mediatek/clk-mt2712.c
index 991d4093726e..b09cb3d99f66 100644
--- a/drivers/clk/mediatek/clk-mt2712.c
+++ b/drivers/clk/mediatek/clk-mt2712.c
@@ -223,6 +223,8 @@ static const struct mtk_fixed_factor top_divs[] = {
223 4), 223 4),
224 FACTOR(CLK_TOP_APLL1_D3, "apll1_d3", "apll1_ck", 1, 224 FACTOR(CLK_TOP_APLL1_D3, "apll1_d3", "apll1_ck", 1,
225 3), 225 3),
226 FACTOR(CLK_TOP_APLL2_D3, "apll2_d3", "apll2_ck", 1,
227 3),
226}; 228};
227 229
228static const char * const axi_parents[] = { 230static const char * const axi_parents[] = {
@@ -594,7 +596,8 @@ static const char * const a1sys_hp_parents[] = {
594 "apll1_ck", 596 "apll1_ck",
595 "apll1_d2", 597 "apll1_d2",
596 "apll1_d4", 598 "apll1_d4",
597 "apll1_d8" 599 "apll1_d8",
600 "apll1_d3"
598}; 601};
599 602
600static const char * const a2sys_hp_parents[] = { 603static const char * const a2sys_hp_parents[] = {
@@ -602,7 +605,8 @@ static const char * const a2sys_hp_parents[] = {
602 "apll2_ck", 605 "apll2_ck",
603 "apll2_d2", 606 "apll2_d2",
604 "apll2_d4", 607 "apll2_d4",
605 "apll2_d8" 608 "apll2_d8",
609 "apll2_d3"
606}; 610};
607 611
608static const char * const asm_l_parents[] = { 612static const char * const asm_l_parents[] = {
@@ -1463,7 +1467,6 @@ static struct platform_driver clk_mt2712_drv = {
1463 .probe = clk_mt2712_probe, 1467 .probe = clk_mt2712_probe,
1464 .driver = { 1468 .driver = {
1465 .name = "clk-mt2712", 1469 .name = "clk-mt2712",
1466 .owner = THIS_MODULE,
1467 .of_match_table = of_match_clk_mt2712, 1470 .of_match_table = of_match_clk_mt2712,
1468 }, 1471 },
1469}; 1472};
diff --git a/drivers/clk/mediatek/clk-mt6797.c b/drivers/clk/mediatek/clk-mt6797.c
index 5702bc974ed9..c2b46b184b9a 100644
--- a/drivers/clk/mediatek/clk-mt6797.c
+++ b/drivers/clk/mediatek/clk-mt6797.c
@@ -324,6 +324,10 @@ static const char * const anc_md32_parents[] = {
324 "univpll_d5", 324 "univpll_d5",
325}; 325};
326 326
327/*
328 * Clock mux ddrphycfg is needed by the DRAM controller. We mark it as
329 * critical as otherwise the system will hang after boot.
330 */
327static const struct mtk_composite top_muxes[] = { 331static const struct mtk_composite top_muxes[] = {
328 MUX(CLK_TOP_MUX_ULPOSC_AXI_CK_MUX_PRE, "ulposc_axi_ck_mux_pre", 332 MUX(CLK_TOP_MUX_ULPOSC_AXI_CK_MUX_PRE, "ulposc_axi_ck_mux_pre",
329 ulposc_axi_ck_mux_pre_parents, 0x0040, 3, 1), 333 ulposc_axi_ck_mux_pre_parents, 0x0040, 3, 1),
@@ -331,8 +335,8 @@ static const struct mtk_composite top_muxes[] = {
331 ulposc_axi_ck_mux_parents, 0x0040, 2, 1), 335 ulposc_axi_ck_mux_parents, 0x0040, 2, 1),
332 MUX(CLK_TOP_MUX_AXI, "axi_sel", axi_parents, 336 MUX(CLK_TOP_MUX_AXI, "axi_sel", axi_parents,
333 0x0040, 0, 2), 337 0x0040, 0, 2),
334 MUX(CLK_TOP_MUX_DDRPHYCFG, "ddrphycfg_sel", ddrphycfg_parents, 338 MUX_FLAGS(CLK_TOP_MUX_DDRPHYCFG, "ddrphycfg_sel", ddrphycfg_parents,
335 0x0040, 16, 2), 339 0x0040, 16, 2, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
336 MUX(CLK_TOP_MUX_MM, "mm_sel", mm_parents, 340 MUX(CLK_TOP_MUX_MM, "mm_sel", mm_parents,
337 0x0040, 24, 2), 341 0x0040, 24, 2),
338 MUX_GATE(CLK_TOP_MUX_PWM, "pwm_sel", pwm_parents, 0x0050, 0, 3, 7), 342 MUX_GATE(CLK_TOP_MUX_PWM, "pwm_sel", pwm_parents, 0x0050, 0, 3, 7),
@@ -424,33 +428,45 @@ static const struct mtk_gate_regs infra2_cg_regs = {
424 .sta_ofs = 0x00b0, 428 .sta_ofs = 0x00b0,
425}; 429};
426 430
427#define GATE_ICG0(_id, _name, _parent, _shift) { \ 431#define GATE_ICG0(_id, _name, _parent, _shift) { \
428 .id = _id, \ 432 .id = _id, \
429 .name = _name, \ 433 .name = _name, \
430 .parent_name = _parent, \ 434 .parent_name = _parent, \
431 .regs = &infra0_cg_regs, \ 435 .regs = &infra0_cg_regs, \
432 .shift = _shift, \ 436 .shift = _shift, \
433 .ops = &mtk_clk_gate_ops_setclr, \ 437 .ops = &mtk_clk_gate_ops_setclr, \
434} 438}
435 439
436#define GATE_ICG1(_id, _name, _parent, _shift) { \ 440#define GATE_ICG1(_id, _name, _parent, _shift) \
437 .id = _id, \ 441 GATE_ICG1_FLAGS(_id, _name, _parent, _shift, 0)
438 .name = _name, \ 442
439 .parent_name = _parent, \ 443#define GATE_ICG1_FLAGS(_id, _name, _parent, _shift, _flags) { \
440 .regs = &infra1_cg_regs, \ 444 .id = _id, \
441 .shift = _shift, \ 445 .name = _name, \
442 .ops = &mtk_clk_gate_ops_setclr, \ 446 .parent_name = _parent, \
447 .regs = &infra1_cg_regs, \
448 .shift = _shift, \
449 .ops = &mtk_clk_gate_ops_setclr, \
450 .flags = _flags, \
443} 451}
444 452
445#define GATE_ICG2(_id, _name, _parent, _shift) { \ 453#define GATE_ICG2(_id, _name, _parent, _shift) \
446 .id = _id, \ 454 GATE_ICG2_FLAGS(_id, _name, _parent, _shift, 0)
447 .name = _name, \ 455
448 .parent_name = _parent, \ 456#define GATE_ICG2_FLAGS(_id, _name, _parent, _shift, _flags) { \
449 .regs = &infra2_cg_regs, \ 457 .id = _id, \
450 .shift = _shift, \ 458 .name = _name, \
451 .ops = &mtk_clk_gate_ops_setclr, \ 459 .parent_name = _parent, \
460 .regs = &infra2_cg_regs, \
461 .shift = _shift, \
462 .ops = &mtk_clk_gate_ops_setclr, \
463 .flags = _flags, \
452} 464}
453 465
466/*
467 * Clock gates dramc and dramc_b are needed by the DRAM controller.
468 * We mark them as critical as otherwise the system will hang after boot.
469 */
454static const struct mtk_gate infra_clks[] = { 470static const struct mtk_gate infra_clks[] = {
455 GATE_ICG0(CLK_INFRA_PMIC_TMR, "infra_pmic_tmr", "ulposc", 0), 471 GATE_ICG0(CLK_INFRA_PMIC_TMR, "infra_pmic_tmr", "ulposc", 0),
456 GATE_ICG0(CLK_INFRA_PMIC_AP, "infra_pmic_ap", "pmicspi_sel", 1), 472 GATE_ICG0(CLK_INFRA_PMIC_AP, "infra_pmic_ap", "pmicspi_sel", 1),
@@ -505,7 +521,8 @@ static const struct mtk_gate infra_clks[] = {
505 GATE_ICG1(CLK_INFRA_CCIF_AP, "infra_ccif_ap", "axi_sel", 23), 521 GATE_ICG1(CLK_INFRA_CCIF_AP, "infra_ccif_ap", "axi_sel", 23),
506 GATE_ICG1(CLK_INFRA_AUDIO, "infra_audio", "axi_sel", 25), 522 GATE_ICG1(CLK_INFRA_AUDIO, "infra_audio", "axi_sel", 25),
507 GATE_ICG1(CLK_INFRA_CCIF_MD, "infra_ccif_md", "axi_sel", 26), 523 GATE_ICG1(CLK_INFRA_CCIF_MD, "infra_ccif_md", "axi_sel", 26),
508 GATE_ICG1(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m", "clk26m", 31), 524 GATE_ICG1_FLAGS(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m",
525 "clk26m", 31, CLK_IS_CRITICAL),
509 GATE_ICG2(CLK_INFRA_I2C4, "infra_i2c4", "axi_sel", 0), 526 GATE_ICG2(CLK_INFRA_I2C4, "infra_i2c4", "axi_sel", 0),
510 GATE_ICG2(CLK_INFRA_I2C_APPM, "infra_i2c_appm", "axi_sel", 1), 527 GATE_ICG2(CLK_INFRA_I2C_APPM, "infra_i2c_appm", "axi_sel", 1),
511 GATE_ICG2(CLK_INFRA_I2C_GPUPM, "infra_i2c_gpupm", "axi_sel", 2), 528 GATE_ICG2(CLK_INFRA_I2C_GPUPM, "infra_i2c_gpupm", "axi_sel", 2),
@@ -516,7 +533,8 @@ static const struct mtk_gate infra_clks[] = {
516 GATE_ICG2(CLK_INFRA_I2C5, "infra_i2c5", "axi_sel", 7), 533 GATE_ICG2(CLK_INFRA_I2C5, "infra_i2c5", "axi_sel", 7),
517 GATE_ICG2(CLK_INFRA_SYS_CIRQ, "infra_sys_cirq", "axi_sel", 8), 534 GATE_ICG2(CLK_INFRA_SYS_CIRQ, "infra_sys_cirq", "axi_sel", 8),
518 GATE_ICG2(CLK_INFRA_SPI1, "infra_spi1", "spi_sel", 10), 535 GATE_ICG2(CLK_INFRA_SPI1, "infra_spi1", "spi_sel", 10),
519 GATE_ICG2(CLK_INFRA_DRAMC_B_F26M, "infra_dramc_b_f26m", "clk26m", 11), 536 GATE_ICG2_FLAGS(CLK_INFRA_DRAMC_B_F26M, "infra_dramc_b_f26m",
537 "clk26m", 11, CLK_IS_CRITICAL),
520 GATE_ICG2(CLK_INFRA_ANC_MD32, "infra_anc_md32", "anc_md32_sel", 12), 538 GATE_ICG2(CLK_INFRA_ANC_MD32, "infra_anc_md32", "anc_md32_sel", 12),
521 GATE_ICG2(CLK_INFRA_ANC_MD32_32K, "infra_anc_md32_32k", "clk26m", 13), 539 GATE_ICG2(CLK_INFRA_ANC_MD32_32K, "infra_anc_md32_32k", "clk26m", 13),
522 GATE_ICG2(CLK_INFRA_DVFS_SPM1, "infra_dvfs_spm1", "axi_sel", 15), 540 GATE_ICG2(CLK_INFRA_DVFS_SPM1, "infra_dvfs_spm1", "axi_sel", 15),
diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 96c292c3e440..deedeb3ea33b 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -533,7 +533,7 @@ static const char * const ca53_parents[] __initconst = {
533 "univpll" 533 "univpll"
534}; 534};
535 535
536static const char * const ca57_parents[] __initconst = { 536static const char * const ca72_parents[] __initconst = {
537 "clk26m", 537 "clk26m",
538 "armca15pll", 538 "armca15pll",
539 "mainpll", 539 "mainpll",
@@ -542,7 +542,7 @@ static const char * const ca57_parents[] __initconst = {
542 542
543static const struct mtk_composite cpu_muxes[] __initconst = { 543static const struct mtk_composite cpu_muxes[] __initconst = {
544 MUX(CLK_INFRA_CA53SEL, "infra_ca53_sel", ca53_parents, 0x0000, 0, 2), 544 MUX(CLK_INFRA_CA53SEL, "infra_ca53_sel", ca53_parents, 0x0000, 0, 2),
545 MUX(CLK_INFRA_CA57SEL, "infra_ca57_sel", ca57_parents, 0x0000, 2, 2), 545 MUX(CLK_INFRA_CA72SEL, "infra_ca72_sel", ca72_parents, 0x0000, 2, 2),
546}; 546};
547 547
548static const struct mtk_composite top_muxes[] __initconst = { 548static const struct mtk_composite top_muxes[] __initconst = {
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 9c0ae4278a94..5531dd2e496d 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -130,7 +130,7 @@ int mtk_clk_register_gates(struct device_node *node,
130 gate->regs->set_ofs, 130 gate->regs->set_ofs,
131 gate->regs->clr_ofs, 131 gate->regs->clr_ofs,
132 gate->regs->sta_ofs, 132 gate->regs->sta_ofs,
133 gate->shift, gate->ops); 133 gate->shift, gate->ops, gate->flags);
134 134
135 if (IS_ERR(clk)) { 135 if (IS_ERR(clk)) {
136 pr_err("Failed to register clk %s: %ld\n", 136 pr_err("Failed to register clk %s: %ld\n",
@@ -167,7 +167,7 @@ struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
167 mux->mask = BIT(mc->mux_width) - 1; 167 mux->mask = BIT(mc->mux_width) - 1;
168 mux->shift = mc->mux_shift; 168 mux->shift = mc->mux_shift;
169 mux->lock = lock; 169 mux->lock = lock;
170 170 mux->flags = mc->mux_flags;
171 mux_hw = &mux->hw; 171 mux_hw = &mux->hw;
172 mux_ops = &clk_mux_ops; 172 mux_ops = &clk_mux_ops;
173 173
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index f83c2bbb677e..fb27b5bf30d9 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -81,15 +81,13 @@ struct mtk_composite {
81 signed char divider_shift; 81 signed char divider_shift;
82 signed char divider_width; 82 signed char divider_width;
83 83
84 u8 mux_flags;
85
84 signed char num_parents; 86 signed char num_parents;
85}; 87};
86 88
87/* 89#define MUX_GATE_FLAGS_2(_id, _name, _parents, _reg, _shift, \
88 * In case the rate change propagation to parent clocks is undesirable, 90 _width, _gate, _flags, _muxflags) { \
89 * this macro allows to specify the clock flags manually.
90 */
91#define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, \
92 _gate, _flags) { \
93 .id = _id, \ 91 .id = _id, \
94 .name = _name, \ 92 .name = _name, \
95 .mux_reg = _reg, \ 93 .mux_reg = _reg, \
@@ -101,9 +99,19 @@ struct mtk_composite {
101 .parent_names = _parents, \ 99 .parent_names = _parents, \
102 .num_parents = ARRAY_SIZE(_parents), \ 100 .num_parents = ARRAY_SIZE(_parents), \
103 .flags = _flags, \ 101 .flags = _flags, \
102 .mux_flags = _muxflags, \
104 } 103 }
105 104
106/* 105/*
106 * In case the rate change propagation to parent clocks is undesirable,
107 * this macro allows to specify the clock flags manually.
108 */
109#define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, \
110 _gate, _flags) \
111 MUX_GATE_FLAGS_2(_id, _name, _parents, _reg, \
112 _shift, _width, _gate, _flags, 0)
113
114/*
107 * Unless necessary, all MUX_GATE clocks propagate rate changes to their 115 * Unless necessary, all MUX_GATE clocks propagate rate changes to their
108 * parent clock by default. 116 * parent clock by default.
109 */ 117 */
@@ -111,7 +119,11 @@ struct mtk_composite {
111 MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, \ 119 MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, \
112 _gate, CLK_SET_RATE_PARENT) 120 _gate, CLK_SET_RATE_PARENT)
113 121
114#define MUX(_id, _name, _parents, _reg, _shift, _width) { \ 122#define MUX(_id, _name, _parents, _reg, _shift, _width) \
123 MUX_FLAGS(_id, _name, _parents, _reg, \
124 _shift, _width, CLK_SET_RATE_PARENT)
125
126#define MUX_FLAGS(_id, _name, _parents, _reg, _shift, _width, _flags) { \
115 .id = _id, \ 127 .id = _id, \
116 .name = _name, \ 128 .name = _name, \
117 .mux_reg = _reg, \ 129 .mux_reg = _reg, \
@@ -121,7 +133,7 @@ struct mtk_composite {
121 .divider_shift = -1, \ 133 .divider_shift = -1, \
122 .parent_names = _parents, \ 134 .parent_names = _parents, \
123 .num_parents = ARRAY_SIZE(_parents), \ 135 .num_parents = ARRAY_SIZE(_parents), \
124 .flags = CLK_SET_RATE_PARENT, \ 136 .flags = _flags, \
125 } 137 }
126 138
127#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, \ 139#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, \
@@ -158,6 +170,7 @@ struct mtk_gate {
158 const struct mtk_gate_regs *regs; 170 const struct mtk_gate_regs *regs;
159 int shift; 171 int shift;
160 const struct clk_ops *ops; 172 const struct clk_ops *ops;
173 unsigned long flags;
161}; 174};
162 175
163int mtk_clk_register_gates(struct device_node *node, 176int mtk_clk_register_gates(struct device_node *node,
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index efaa70f682b4..3858747f5438 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -1,27 +1,52 @@
1config COMMON_CLK_AMLOGIC 1config COMMON_CLK_MESON_INPUT
2 bool 2 tristate
3 depends on ARCH_MESON || COMPILE_TEST
4 select COMMON_CLK_REGMAP_MESON
5 3
6config COMMON_CLK_AMLOGIC_AUDIO 4config COMMON_CLK_MESON_REGMAP
7 bool 5 tristate
8 depends on ARCH_MESON || COMPILE_TEST 6 select REGMAP
9 select COMMON_CLK_AMLOGIC
10 7
11config COMMON_CLK_MESON_AO 8config COMMON_CLK_MESON_DUALDIV
12 bool 9 tristate
13 depends on OF 10 select COMMON_CLK_MESON_REGMAP
14 depends on ARCH_MESON || COMPILE_TEST 11
15 select COMMON_CLK_REGMAP_MESON 12config COMMON_CLK_MESON_MPLL
13 tristate
14 select COMMON_CLK_MESON_REGMAP
15
16config COMMON_CLK_MESON_PHASE
17 tristate
18 select COMMON_CLK_MESON_REGMAP
19
20config COMMON_CLK_MESON_PLL
21 tristate
22 select COMMON_CLK_MESON_REGMAP
23
24config COMMON_CLK_MESON_SCLK_DIV
25 tristate
26 select COMMON_CLK_MESON_REGMAP
27
28config COMMON_CLK_MESON_VID_PLL_DIV
29 tristate
30 select COMMON_CLK_MESON_REGMAP
31
32config COMMON_CLK_MESON_AO_CLKC
33 tristate
34 select COMMON_CLK_MESON_REGMAP
35 select COMMON_CLK_MESON_INPUT
16 select RESET_CONTROLLER 36 select RESET_CONTROLLER
17 37
18config COMMON_CLK_REGMAP_MESON 38config COMMON_CLK_MESON_EE_CLKC
19 bool 39 tristate
20 select REGMAP 40 select COMMON_CLK_MESON_REGMAP
41 select COMMON_CLK_MESON_INPUT
21 42
22config COMMON_CLK_MESON8B 43config COMMON_CLK_MESON8B
23 bool 44 bool
24 select COMMON_CLK_AMLOGIC 45 depends on ARCH_MESON
46 select COMMON_CLK_MESON_REGMAP
47 select COMMON_CLK_MESON_MPLL
48 select COMMON_CLK_MESON_PLL
49 select MFD_SYSCON
25 select RESET_CONTROLLER 50 select RESET_CONTROLLER
26 help 51 help
27 Support for the clock controller on AmLogic S802 (Meson8), 52 Support for the clock controller on AmLogic S802 (Meson8),
@@ -30,8 +55,14 @@ config COMMON_CLK_MESON8B
30 55
31config COMMON_CLK_GXBB 56config COMMON_CLK_GXBB
32 bool 57 bool
33 select COMMON_CLK_AMLOGIC 58 depends on ARCH_MESON
34 select COMMON_CLK_MESON_AO 59 select COMMON_CLK_MESON_REGMAP
60 select COMMON_CLK_MESON_DUALDIV
61 select COMMON_CLK_MESON_VID_PLL_DIV
62 select COMMON_CLK_MESON_MPLL
63 select COMMON_CLK_MESON_PLL
64 select COMMON_CLK_MESON_AO_CLKC
65 select COMMON_CLK_MESON_EE_CLKC
35 select MFD_SYSCON 66 select MFD_SYSCON
36 help 67 help
37 Support for the clock controller on AmLogic S905 devices, aka gxbb. 68 Support for the clock controller on AmLogic S905 devices, aka gxbb.
@@ -39,8 +70,13 @@ config COMMON_CLK_GXBB
39 70
40config COMMON_CLK_AXG 71config COMMON_CLK_AXG
41 bool 72 bool
42 select COMMON_CLK_AMLOGIC 73 depends on ARCH_MESON
43 select COMMON_CLK_MESON_AO 74 select COMMON_CLK_MESON_REGMAP
75 select COMMON_CLK_MESON_DUALDIV
76 select COMMON_CLK_MESON_MPLL
77 select COMMON_CLK_MESON_PLL
78 select COMMON_CLK_MESON_AO_CLKC
79 select COMMON_CLK_MESON_EE_CLKC
44 select MFD_SYSCON 80 select MFD_SYSCON
45 help 81 help
46 Support for the clock controller on AmLogic A113D devices, aka axg. 82 Support for the clock controller on AmLogic A113D devices, aka axg.
@@ -48,9 +84,26 @@ config COMMON_CLK_AXG
48 84
49config COMMON_CLK_AXG_AUDIO 85config COMMON_CLK_AXG_AUDIO
50 tristate "Meson AXG Audio Clock Controller Driver" 86 tristate "Meson AXG Audio Clock Controller Driver"
51 depends on COMMON_CLK_AXG 87 depends on ARCH_MESON
52 select COMMON_CLK_AMLOGIC_AUDIO 88 select COMMON_CLK_MESON_INPUT
53 select MFD_SYSCON 89 select COMMON_CLK_MESON_REGMAP
90 select COMMON_CLK_MESON_PHASE
91 select COMMON_CLK_MESON_SCLK_DIV
92 select REGMAP_MMIO
54 help 93 help
55 Support for the audio clock controller on AmLogic A113D devices, 94 Support for the audio clock controller on AmLogic A113D devices,
56 aka axg, Say Y if you want audio subsystem to work. 95 aka axg, Say Y if you want audio subsystem to work.
96
97config COMMON_CLK_G12A
98 bool
99 depends on ARCH_MESON
100 select COMMON_CLK_MESON_REGMAP
101 select COMMON_CLK_MESON_DUALDIV
102 select COMMON_CLK_MESON_MPLL
103 select COMMON_CLK_MESON_PLL
104 select COMMON_CLK_MESON_AO_CLKC
105 select COMMON_CLK_MESON_EE_CLKC
106 select MFD_SYSCON
107 help
108 Support for the clock controller on Amlogic S905D2, S905X2 and S905Y2
109 devices, aka g12a. Say Y if you want peripherals to work.
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index a849aa809825..021fc290e749 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -1,13 +1,20 @@
1# 1# Amlogic clock drivers
2# Makefile for Meson specific clk
3#
4 2
5obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-phase.o vid-pll-div.o 3obj-$(CONFIG_COMMON_CLK_MESON_AO_CLKC) += meson-aoclk.o
6obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-input.o 4obj-$(CONFIG_COMMON_CLK_MESON_DUALDIV) += clk-dualdiv.o
7obj-$(CONFIG_COMMON_CLK_AMLOGIC_AUDIO) += clk-triphase.o sclk-div.o 5obj-$(CONFIG_COMMON_CLK_MESON_EE_CLKC) += meson-eeclk.o
8obj-$(CONFIG_COMMON_CLK_MESON_AO) += meson-aoclk.o 6obj-$(CONFIG_COMMON_CLK_MESON_INPUT) += clk-input.o
7obj-$(CONFIG_COMMON_CLK_MESON_MPLL) += clk-mpll.o
8obj-$(CONFIG_COMMON_CLK_MESON_PHASE) += clk-phase.o
9obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o
10obj-$(CONFIG_COMMON_CLK_MESON_REGMAP) += clk-regmap.o
11obj-$(CONFIG_COMMON_CLK_MESON_SCLK_DIV) += sclk-div.o
12obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
13
14# Amlogic Clock controllers
15
16obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
17obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
18obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
19obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
9obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o 20obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o
10obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o
11obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
12obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
13obj-$(CONFIG_COMMON_CLK_REGMAP_MESON) += clk-regmap.o
diff --git a/drivers/clk/meson/axg-aoclk.c b/drivers/clk/meson/axg-aoclk.c
index 29e088542387..0086f31288eb 100644
--- a/drivers/clk/meson/axg-aoclk.c
+++ b/drivers/clk/meson/axg-aoclk.c
@@ -12,10 +12,27 @@
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <linux/reset-controller.h> 13#include <linux/reset-controller.h>
14#include <linux/mfd/syscon.h> 14#include <linux/mfd/syscon.h>
15#include "clk-regmap.h"
16#include "meson-aoclk.h" 15#include "meson-aoclk.h"
17#include "axg-aoclk.h" 16#include "axg-aoclk.h"
18 17
18#include "clk-regmap.h"
19#include "clk-dualdiv.h"
20
21#define IN_PREFIX "ao-in-"
22
23/*
24 * AO Configuration Clock registers offsets
25 * Register offsets from the data sheet must be multiplied by 4.
26 */
27#define AO_RTI_PWR_CNTL_REG1 0x0C
28#define AO_RTI_PWR_CNTL_REG0 0x10
29#define AO_RTI_GEN_CNTL_REG0 0x40
30#define AO_OSCIN_CNTL 0x58
31#define AO_CRT_CLK_CNTL1 0x68
32#define AO_SAR_CLK 0x90
33#define AO_RTC_ALT_CLK_CNTL0 0x94
34#define AO_RTC_ALT_CLK_CNTL1 0x98
35
19#define AXG_AO_GATE(_name, _bit) \ 36#define AXG_AO_GATE(_name, _bit) \
20static struct clk_regmap axg_aoclk_##_name = { \ 37static struct clk_regmap axg_aoclk_##_name = { \
21 .data = &(struct clk_regmap_gate_data) { \ 38 .data = &(struct clk_regmap_gate_data) { \
@@ -25,7 +42,7 @@ static struct clk_regmap axg_aoclk_##_name = { \
25 .hw.init = &(struct clk_init_data) { \ 42 .hw.init = &(struct clk_init_data) { \
26 .name = "axg_ao_" #_name, \ 43 .name = "axg_ao_" #_name, \
27 .ops = &clk_regmap_gate_ops, \ 44 .ops = &clk_regmap_gate_ops, \
28 .parent_names = (const char *[]){ "clk81" }, \ 45 .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \
29 .num_parents = 1, \ 46 .num_parents = 1, \
30 .flags = CLK_IGNORE_UNUSED, \ 47 .flags = CLK_IGNORE_UNUSED, \
31 }, \ 48 }, \
@@ -39,17 +56,141 @@ AXG_AO_GATE(uart2, 5);
39AXG_AO_GATE(ir_blaster, 6); 56AXG_AO_GATE(ir_blaster, 6);
40AXG_AO_GATE(saradc, 7); 57AXG_AO_GATE(saradc, 7);
41 58
59static struct clk_regmap axg_aoclk_cts_oscin = {
60 .data = &(struct clk_regmap_gate_data){
61 .offset = AO_RTI_PWR_CNTL_REG0,
62 .bit_idx = 14,
63 },
64 .hw.init = &(struct clk_init_data){
65 .name = "cts_oscin",
66 .ops = &clk_regmap_gate_ro_ops,
67 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
68 .num_parents = 1,
69 },
70};
71
72static struct clk_regmap axg_aoclk_32k_pre = {
73 .data = &(struct clk_regmap_gate_data){
74 .offset = AO_RTC_ALT_CLK_CNTL0,
75 .bit_idx = 31,
76 },
77 .hw.init = &(struct clk_init_data){
78 .name = "axg_ao_32k_pre",
79 .ops = &clk_regmap_gate_ops,
80 .parent_names = (const char *[]){ "cts_oscin" },
81 .num_parents = 1,
82 },
83};
84
85static const struct meson_clk_dualdiv_param axg_32k_div_table[] = {
86 {
87 .dual = 1,
88 .n1 = 733,
89 .m1 = 8,
90 .n2 = 732,
91 .m2 = 11,
92 }, {}
93};
94
95static struct clk_regmap axg_aoclk_32k_div = {
96 .data = &(struct meson_clk_dualdiv_data){
97 .n1 = {
98 .reg_off = AO_RTC_ALT_CLK_CNTL0,
99 .shift = 0,
100 .width = 12,
101 },
102 .n2 = {
103 .reg_off = AO_RTC_ALT_CLK_CNTL0,
104 .shift = 12,
105 .width = 12,
106 },
107 .m1 = {
108 .reg_off = AO_RTC_ALT_CLK_CNTL1,
109 .shift = 0,
110 .width = 12,
111 },
112 .m2 = {
113 .reg_off = AO_RTC_ALT_CLK_CNTL1,
114 .shift = 12,
115 .width = 12,
116 },
117 .dual = {
118 .reg_off = AO_RTC_ALT_CLK_CNTL0,
119 .shift = 28,
120 .width = 1,
121 },
122 .table = axg_32k_div_table,
123 },
124 .hw.init = &(struct clk_init_data){
125 .name = "axg_ao_32k_div",
126 .ops = &meson_clk_dualdiv_ops,
127 .parent_names = (const char *[]){ "axg_ao_32k_pre" },
128 .num_parents = 1,
129 },
130};
131
132static struct clk_regmap axg_aoclk_32k_sel = {
133 .data = &(struct clk_regmap_mux_data) {
134 .offset = AO_RTC_ALT_CLK_CNTL1,
135 .mask = 0x1,
136 .shift = 24,
137 .flags = CLK_MUX_ROUND_CLOSEST,
138 },
139 .hw.init = &(struct clk_init_data){
140 .name = "axg_ao_32k_sel",
141 .ops = &clk_regmap_mux_ops,
142 .parent_names = (const char *[]){ "axg_ao_32k_div",
143 "axg_ao_32k_pre" },
144 .num_parents = 2,
145 .flags = CLK_SET_RATE_PARENT,
146 },
147};
148
149static struct clk_regmap axg_aoclk_32k = {
150 .data = &(struct clk_regmap_gate_data){
151 .offset = AO_RTC_ALT_CLK_CNTL0,
152 .bit_idx = 30,
153 },
154 .hw.init = &(struct clk_init_data){
155 .name = "axg_ao_32k",
156 .ops = &clk_regmap_gate_ops,
157 .parent_names = (const char *[]){ "axg_ao_32k_sel" },
158 .num_parents = 1,
159 .flags = CLK_SET_RATE_PARENT,
160 },
161};
162
163static struct clk_regmap axg_aoclk_cts_rtc_oscin = {
164 .data = &(struct clk_regmap_mux_data) {
165 .offset = AO_RTI_PWR_CNTL_REG0,
166 .mask = 0x1,
167 .shift = 10,
168 .flags = CLK_MUX_ROUND_CLOSEST,
169 },
170 .hw.init = &(struct clk_init_data){
171 .name = "axg_ao_cts_rtc_oscin",
172 .ops = &clk_regmap_mux_ops,
173 .parent_names = (const char *[]){ "axg_ao_32k",
174 IN_PREFIX "ext_32k-0" },
175 .num_parents = 2,
176 .flags = CLK_SET_RATE_PARENT,
177 },
178};
179
42static struct clk_regmap axg_aoclk_clk81 = { 180static struct clk_regmap axg_aoclk_clk81 = {
43 .data = &(struct clk_regmap_mux_data) { 181 .data = &(struct clk_regmap_mux_data) {
44 .offset = AO_RTI_PWR_CNTL_REG0, 182 .offset = AO_RTI_PWR_CNTL_REG0,
45 .mask = 0x1, 183 .mask = 0x1,
46 .shift = 8, 184 .shift = 8,
185 .flags = CLK_MUX_ROUND_CLOSEST,
47 }, 186 },
48 .hw.init = &(struct clk_init_data){ 187 .hw.init = &(struct clk_init_data){
49 .name = "axg_ao_clk81", 188 .name = "axg_ao_clk81",
50 .ops = &clk_regmap_mux_ro_ops, 189 .ops = &clk_regmap_mux_ro_ops,
51 .parent_names = (const char *[]){ "clk81", "ao_alt_xtal"}, 190 .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk",
191 "axg_ao_cts_rtc_oscin"},
52 .num_parents = 2, 192 .num_parents = 2,
193 .flags = CLK_SET_RATE_PARENT,
53 }, 194 },
54}; 195};
55 196
@@ -62,7 +203,8 @@ static struct clk_regmap axg_aoclk_saradc_mux = {
62 .hw.init = &(struct clk_init_data){ 203 .hw.init = &(struct clk_init_data){
63 .name = "axg_ao_saradc_mux", 204 .name = "axg_ao_saradc_mux",
64 .ops = &clk_regmap_mux_ops, 205 .ops = &clk_regmap_mux_ops,
65 .parent_names = (const char *[]){ "xtal", "axg_ao_clk81" }, 206 .parent_names = (const char *[]){ IN_PREFIX "xtal",
207 "axg_ao_clk81" },
66 .num_parents = 2, 208 .num_parents = 2,
67 }, 209 },
68}; 210};
@@ -106,17 +248,23 @@ static const unsigned int axg_aoclk_reset[] = {
106}; 248};
107 249
108static struct clk_regmap *axg_aoclk_regmap[] = { 250static struct clk_regmap *axg_aoclk_regmap[] = {
109 [CLKID_AO_REMOTE] = &axg_aoclk_remote, 251 &axg_aoclk_remote,
110 [CLKID_AO_I2C_MASTER] = &axg_aoclk_i2c_master, 252 &axg_aoclk_i2c_master,
111 [CLKID_AO_I2C_SLAVE] = &axg_aoclk_i2c_slave, 253 &axg_aoclk_i2c_slave,
112 [CLKID_AO_UART1] = &axg_aoclk_uart1, 254 &axg_aoclk_uart1,
113 [CLKID_AO_UART2] = &axg_aoclk_uart2, 255 &axg_aoclk_uart2,
114 [CLKID_AO_IR_BLASTER] = &axg_aoclk_ir_blaster, 256 &axg_aoclk_ir_blaster,
115 [CLKID_AO_SAR_ADC] = &axg_aoclk_saradc, 257 &axg_aoclk_saradc,
116 [CLKID_AO_CLK81] = &axg_aoclk_clk81, 258 &axg_aoclk_cts_oscin,
117 [CLKID_AO_SAR_ADC_SEL] = &axg_aoclk_saradc_mux, 259 &axg_aoclk_32k_pre,
118 [CLKID_AO_SAR_ADC_DIV] = &axg_aoclk_saradc_div, 260 &axg_aoclk_32k_div,
119 [CLKID_AO_SAR_ADC_CLK] = &axg_aoclk_saradc_gate, 261 &axg_aoclk_32k_sel,
262 &axg_aoclk_32k,
263 &axg_aoclk_cts_rtc_oscin,
264 &axg_aoclk_clk81,
265 &axg_aoclk_saradc_mux,
266 &axg_aoclk_saradc_div,
267 &axg_aoclk_saradc_gate,
120}; 268};
121 269
122static const struct clk_hw_onecell_data axg_aoclk_onecell_data = { 270static const struct clk_hw_onecell_data axg_aoclk_onecell_data = {
@@ -132,10 +280,22 @@ static const struct clk_hw_onecell_data axg_aoclk_onecell_data = {
132 [CLKID_AO_SAR_ADC_SEL] = &axg_aoclk_saradc_mux.hw, 280 [CLKID_AO_SAR_ADC_SEL] = &axg_aoclk_saradc_mux.hw,
133 [CLKID_AO_SAR_ADC_DIV] = &axg_aoclk_saradc_div.hw, 281 [CLKID_AO_SAR_ADC_DIV] = &axg_aoclk_saradc_div.hw,
134 [CLKID_AO_SAR_ADC_CLK] = &axg_aoclk_saradc_gate.hw, 282 [CLKID_AO_SAR_ADC_CLK] = &axg_aoclk_saradc_gate.hw,
283 [CLKID_AO_CTS_OSCIN] = &axg_aoclk_cts_oscin.hw,
284 [CLKID_AO_32K_PRE] = &axg_aoclk_32k_pre.hw,
285 [CLKID_AO_32K_DIV] = &axg_aoclk_32k_div.hw,
286 [CLKID_AO_32K_SEL] = &axg_aoclk_32k_sel.hw,
287 [CLKID_AO_32K] = &axg_aoclk_32k.hw,
288 [CLKID_AO_CTS_RTC_OSCIN] = &axg_aoclk_cts_rtc_oscin.hw,
135 }, 289 },
136 .num = NR_CLKS, 290 .num = NR_CLKS,
137}; 291};
138 292
293static const struct meson_aoclk_input axg_aoclk_inputs[] = {
294 { .name = "xtal", .required = true },
295 { .name = "mpeg-clk", .required = true },
296 { .name = "ext-32k-0", .required = false },
297};
298
139static const struct meson_aoclk_data axg_aoclkc_data = { 299static const struct meson_aoclk_data axg_aoclkc_data = {
140 .reset_reg = AO_RTI_GEN_CNTL_REG0, 300 .reset_reg = AO_RTI_GEN_CNTL_REG0,
141 .num_reset = ARRAY_SIZE(axg_aoclk_reset), 301 .num_reset = ARRAY_SIZE(axg_aoclk_reset),
@@ -143,6 +303,9 @@ static const struct meson_aoclk_data axg_aoclkc_data = {
143 .num_clks = ARRAY_SIZE(axg_aoclk_regmap), 303 .num_clks = ARRAY_SIZE(axg_aoclk_regmap),
144 .clks = axg_aoclk_regmap, 304 .clks = axg_aoclk_regmap,
145 .hw_data = &axg_aoclk_onecell_data, 305 .hw_data = &axg_aoclk_onecell_data,
306 .inputs = axg_aoclk_inputs,
307 .num_inputs = ARRAY_SIZE(axg_aoclk_inputs),
308 .input_prefix = IN_PREFIX,
146}; 309};
147 310
148static const struct of_device_id axg_aoclkc_match_table[] = { 311static const struct of_device_id axg_aoclkc_match_table[] = {
diff --git a/drivers/clk/meson/axg-aoclk.h b/drivers/clk/meson/axg-aoclk.h
index 91384d8dd844..3cc27e85170f 100644
--- a/drivers/clk/meson/axg-aoclk.h
+++ b/drivers/clk/meson/axg-aoclk.h
@@ -10,18 +10,7 @@
10#ifndef __AXG_AOCLKC_H 10#ifndef __AXG_AOCLKC_H
11#define __AXG_AOCLKC_H 11#define __AXG_AOCLKC_H
12 12
13#define NR_CLKS 11 13#define NR_CLKS 17
14/* AO Configuration Clock registers offsets
15 * Register offsets from the data sheet must be multiplied by 4.
16 */
17#define AO_RTI_PWR_CNTL_REG1 0x0C
18#define AO_RTI_PWR_CNTL_REG0 0x10
19#define AO_RTI_GEN_CNTL_REG0 0x40
20#define AO_OSCIN_CNTL 0x58
21#define AO_CRT_CLK_CNTL1 0x68
22#define AO_SAR_CLK 0x90
23#define AO_RTC_ALT_CLK_CNTL0 0x94
24#define AO_RTC_ALT_CLK_CNTL1 0x98
25 14
26#include <dt-bindings/clock/axg-aoclkc.h> 15#include <dt-bindings/clock/axg-aoclkc.h>
27#include <dt-bindings/reset/axg-aoclkc.h> 16#include <dt-bindings/reset/axg-aoclkc.h>
diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c
index 8ac3a2295473..7ab200b6c3bf 100644
--- a/drivers/clk/meson/axg-audio.c
+++ b/drivers/clk/meson/axg-audio.c
@@ -14,8 +14,11 @@
14#include <linux/reset.h> 14#include <linux/reset.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16 16
17#include "clkc-audio.h"
18#include "axg-audio.h" 17#include "axg-audio.h"
18#include "clk-input.h"
19#include "clk-regmap.h"
20#include "clk-phase.h"
21#include "sclk-div.h"
19 22
20#define AXG_MST_IN_COUNT 8 23#define AXG_MST_IN_COUNT 8
21#define AXG_SLV_SCLK_COUNT 10 24#define AXG_SLV_SCLK_COUNT 10
diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
index 792735d7e46e..7a8ef80e5f2c 100644
--- a/drivers/clk/meson/axg.c
+++ b/drivers/clk/meson/axg.c
@@ -9,16 +9,17 @@
9 * Author: Qiufang Dai <qiufang.dai@amlogic.com> 9 * Author: Qiufang Dai <qiufang.dai@amlogic.com>
10 */ 10 */
11 11
12#include <linux/clk.h>
13#include <linux/clk-provider.h> 12#include <linux/clk-provider.h>
14#include <linux/init.h> 13#include <linux/init.h>
15#include <linux/of_device.h> 14#include <linux/of_device.h>
16#include <linux/mfd/syscon.h>
17#include <linux/platform_device.h> 15#include <linux/platform_device.h>
18#include <linux/regmap.h>
19 16
20#include "clkc.h" 17#include "clk-input.h"
18#include "clk-regmap.h"
19#include "clk-pll.h"
20#include "clk-mpll.h"
21#include "axg.h" 21#include "axg.h"
22#include "meson-eeclk.h"
22 23
23static DEFINE_SPINLOCK(meson_clk_lock); 24static DEFINE_SPINLOCK(meson_clk_lock);
24 25
@@ -58,7 +59,7 @@ static struct clk_regmap axg_fixed_pll_dco = {
58 .hw.init = &(struct clk_init_data){ 59 .hw.init = &(struct clk_init_data){
59 .name = "fixed_pll_dco", 60 .name = "fixed_pll_dco",
60 .ops = &meson_clk_pll_ro_ops, 61 .ops = &meson_clk_pll_ro_ops,
61 .parent_names = (const char *[]){ "xtal" }, 62 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
62 .num_parents = 1, 63 .num_parents = 1,
63 }, 64 },
64}; 65};
@@ -113,7 +114,7 @@ static struct clk_regmap axg_sys_pll_dco = {
113 .hw.init = &(struct clk_init_data){ 114 .hw.init = &(struct clk_init_data){
114 .name = "sys_pll_dco", 115 .name = "sys_pll_dco",
115 .ops = &meson_clk_pll_ro_ops, 116 .ops = &meson_clk_pll_ro_ops,
116 .parent_names = (const char *[]){ "xtal" }, 117 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
117 .num_parents = 1, 118 .num_parents = 1,
118 }, 119 },
119}; 120};
@@ -214,7 +215,7 @@ static struct clk_regmap axg_gp0_pll_dco = {
214 .hw.init = &(struct clk_init_data){ 215 .hw.init = &(struct clk_init_data){
215 .name = "gp0_pll_dco", 216 .name = "gp0_pll_dco",
216 .ops = &meson_clk_pll_ops, 217 .ops = &meson_clk_pll_ops,
217 .parent_names = (const char *[]){ "xtal" }, 218 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
218 .num_parents = 1, 219 .num_parents = 1,
219 }, 220 },
220}; 221};
@@ -283,7 +284,7 @@ static struct clk_regmap axg_hifi_pll_dco = {
283 .hw.init = &(struct clk_init_data){ 284 .hw.init = &(struct clk_init_data){
284 .name = "hifi_pll_dco", 285 .name = "hifi_pll_dco",
285 .ops = &meson_clk_pll_ops, 286 .ops = &meson_clk_pll_ops,
286 .parent_names = (const char *[]){ "xtal" }, 287 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
287 .num_parents = 1, 288 .num_parents = 1,
288 }, 289 },
289}; 290};
@@ -701,7 +702,7 @@ static struct clk_regmap axg_pcie_pll_dco = {
701 .hw.init = &(struct clk_init_data){ 702 .hw.init = &(struct clk_init_data){
702 .name = "pcie_pll_dco", 703 .name = "pcie_pll_dco",
703 .ops = &meson_clk_pll_ops, 704 .ops = &meson_clk_pll_ops,
704 .parent_names = (const char *[]){ "xtal" }, 705 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
705 .num_parents = 1, 706 .num_parents = 1,
706 }, 707 },
707}; 708};
@@ -803,7 +804,7 @@ static struct clk_regmap axg_pcie_cml_en1 = {
803 804
804static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; 805static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 };
805static const char * const clk81_parent_names[] = { 806static const char * const clk81_parent_names[] = {
806 "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4", 807 IN_PREFIX "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
807 "fclk_div3", "fclk_div5" 808 "fclk_div3", "fclk_div5"
808}; 809};
809 810
@@ -852,7 +853,7 @@ static struct clk_regmap axg_clk81 = {
852}; 853};
853 854
854static const char * const axg_sd_emmc_clk0_parent_names[] = { 855static const char * const axg_sd_emmc_clk0_parent_names[] = {
855 "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7", 856 IN_PREFIX "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
856 857
857 /* 858 /*
858 * Following these parent clocks, we should also have had mpll2, mpll3 859 * Following these parent clocks, we should also have had mpll2, mpll3
@@ -957,7 +958,7 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = {
957static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8, 958static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8,
958 9, 10, 11, 13, 14, }; 959 9, 10, 11, 13, 14, };
959static const char * const gen_clk_parent_names[] = { 960static const char * const gen_clk_parent_names[] = {
960 "xtal", "hifi_pll", "mpll0", "mpll1", "mpll2", "mpll3", 961 IN_PREFIX "xtal", "hifi_pll", "mpll0", "mpll1", "mpll2", "mpll3",
961 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll", 962 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll",
962}; 963};
963 964
@@ -1255,46 +1256,20 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
1255 &axg_pcie_pll_od, 1256 &axg_pcie_pll_od,
1256}; 1257};
1257 1258
1259static const struct meson_eeclkc_data axg_clkc_data = {
1260 .regmap_clks = axg_clk_regmaps,
1261 .regmap_clk_num = ARRAY_SIZE(axg_clk_regmaps),
1262 .hw_onecell_data = &axg_hw_onecell_data,
1263};
1264
1265
1258static const struct of_device_id clkc_match_table[] = { 1266static const struct of_device_id clkc_match_table[] = {
1259 { .compatible = "amlogic,axg-clkc" }, 1267 { .compatible = "amlogic,axg-clkc", .data = &axg_clkc_data },
1260 {} 1268 {}
1261}; 1269};
1262 1270
1263static int axg_clkc_probe(struct platform_device *pdev)
1264{
1265 struct device *dev = &pdev->dev;
1266 struct regmap *map;
1267 int ret, i;
1268
1269 /* Get the hhi system controller node if available */
1270 map = syscon_node_to_regmap(of_get_parent(dev->of_node));
1271 if (IS_ERR(map)) {
1272 dev_err(dev, "failed to get HHI regmap\n");
1273 return PTR_ERR(map);
1274 }
1275
1276 /* Populate regmap for the regmap backed clocks */
1277 for (i = 0; i < ARRAY_SIZE(axg_clk_regmaps); i++)
1278 axg_clk_regmaps[i]->map = map;
1279
1280 for (i = 0; i < axg_hw_onecell_data.num; i++) {
1281 /* array might be sparse */
1282 if (!axg_hw_onecell_data.hws[i])
1283 continue;
1284
1285 ret = devm_clk_hw_register(dev, axg_hw_onecell_data.hws[i]);
1286 if (ret) {
1287 dev_err(dev, "Clock registration failed\n");
1288 return ret;
1289 }
1290 }
1291
1292 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
1293 &axg_hw_onecell_data);
1294}
1295
1296static struct platform_driver axg_driver = { 1271static struct platform_driver axg_driver = {
1297 .probe = axg_clkc_probe, 1272 .probe = meson_eeclkc_probe,
1298 .driver = { 1273 .driver = {
1299 .name = "axg-clkc", 1274 .name = "axg-clkc",
1300 .of_match_table = clkc_match_table, 1275 .of_match_table = clkc_match_table,
diff --git a/drivers/clk/meson/clk-dualdiv.c b/drivers/clk/meson/clk-dualdiv.c
new file mode 100644
index 000000000000..c5ca23a5e3e8
--- /dev/null
+++ b/drivers/clk/meson/clk-dualdiv.c
@@ -0,0 +1,138 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2017 BayLibre, SAS
4 * Author: Neil Armstrong <narmstrong@baylibre.com>
5 * Author: Jerome Brunet <jbrunet@baylibre.com>
6 */
7
8/*
9 * The AO Domain embeds a dual/divider to generate a more precise
10 * 32,768KHz clock for low-power suspend mode and CEC.
11 * ______ ______
12 * | | | |
13 * | Div1 |-| Cnt1 |
14 * /|______| |______|\
15 * -| ______ ______ X--> Out
16 * \| | | |/
17 * | Div2 |-| Cnt2 |
18 * |______| |______|
19 *
20 * The dividing can be switched to single or dual, with a counter
21 * for each divider to set when the switching is done.
22 */
23
24#include <linux/clk-provider.h>
25#include <linux/module.h>
26
27#include "clk-regmap.h"
28#include "clk-dualdiv.h"
29
30static inline struct meson_clk_dualdiv_data *
31meson_clk_dualdiv_data(struct clk_regmap *clk)
32{
33 return (struct meson_clk_dualdiv_data *)clk->data;
34}
35
36static unsigned long
37__dualdiv_param_to_rate(unsigned long parent_rate,
38 const struct meson_clk_dualdiv_param *p)
39{
40 if (!p->dual)
41 return DIV_ROUND_CLOSEST(parent_rate, p->n1);
42
43 return DIV_ROUND_CLOSEST(parent_rate * (p->m1 + p->m2),
44 p->n1 * p->m1 + p->n2 * p->m2);
45}
46
47static unsigned long meson_clk_dualdiv_recalc_rate(struct clk_hw *hw,
48 unsigned long parent_rate)
49{
50 struct clk_regmap *clk = to_clk_regmap(hw);
51 struct meson_clk_dualdiv_data *dualdiv = meson_clk_dualdiv_data(clk);
52 struct meson_clk_dualdiv_param setting;
53
54 setting.dual = meson_parm_read(clk->map, &dualdiv->dual);
55 setting.n1 = meson_parm_read(clk->map, &dualdiv->n1) + 1;
56 setting.m1 = meson_parm_read(clk->map, &dualdiv->m1) + 1;
57 setting.n2 = meson_parm_read(clk->map, &dualdiv->n2) + 1;
58 setting.m2 = meson_parm_read(clk->map, &dualdiv->m2) + 1;
59
60 return __dualdiv_param_to_rate(parent_rate, &setting);
61}
62
63static const struct meson_clk_dualdiv_param *
64__dualdiv_get_setting(unsigned long rate, unsigned long parent_rate,
65 struct meson_clk_dualdiv_data *dualdiv)
66{
67 const struct meson_clk_dualdiv_param *table = dualdiv->table;
68 unsigned long best = 0, now = 0;
69 unsigned int i, best_i = 0;
70
71 if (!table)
72 return NULL;
73
74 for (i = 0; table[i].n1; i++) {
75 now = __dualdiv_param_to_rate(parent_rate, &table[i]);
76
77 /* If we get an exact match, don't bother any further */
78 if (now == rate) {
79 return &table[i];
80 } else if (abs(now - rate) < abs(best - rate)) {
81 best = now;
82 best_i = i;
83 }
84 }
85
86 return (struct meson_clk_dualdiv_param *)&table[best_i];
87}
88
89static long meson_clk_dualdiv_round_rate(struct clk_hw *hw, unsigned long rate,
90 unsigned long *parent_rate)
91{
92 struct clk_regmap *clk = to_clk_regmap(hw);
93 struct meson_clk_dualdiv_data *dualdiv = meson_clk_dualdiv_data(clk);
94 const struct meson_clk_dualdiv_param *setting =
95 __dualdiv_get_setting(rate, *parent_rate, dualdiv);
96
97 if (!setting)
98 return meson_clk_dualdiv_recalc_rate(hw, *parent_rate);
99
100 return __dualdiv_param_to_rate(*parent_rate, setting);
101}
102
103static int meson_clk_dualdiv_set_rate(struct clk_hw *hw, unsigned long rate,
104 unsigned long parent_rate)
105{
106 struct clk_regmap *clk = to_clk_regmap(hw);
107 struct meson_clk_dualdiv_data *dualdiv = meson_clk_dualdiv_data(clk);
108 const struct meson_clk_dualdiv_param *setting =
109 __dualdiv_get_setting(rate, parent_rate, dualdiv);
110
111 if (!setting)
112 return -EINVAL;
113
114 meson_parm_write(clk->map, &dualdiv->dual, setting->dual);
115 meson_parm_write(clk->map, &dualdiv->n1, setting->n1 - 1);
116 meson_parm_write(clk->map, &dualdiv->m1, setting->m1 - 1);
117 meson_parm_write(clk->map, &dualdiv->n2, setting->n2 - 1);
118 meson_parm_write(clk->map, &dualdiv->m2, setting->m2 - 1);
119
120 return 0;
121}
122
123const struct clk_ops meson_clk_dualdiv_ops = {
124 .recalc_rate = meson_clk_dualdiv_recalc_rate,
125 .round_rate = meson_clk_dualdiv_round_rate,
126 .set_rate = meson_clk_dualdiv_set_rate,
127};
128EXPORT_SYMBOL_GPL(meson_clk_dualdiv_ops);
129
130const struct clk_ops meson_clk_dualdiv_ro_ops = {
131 .recalc_rate = meson_clk_dualdiv_recalc_rate,
132};
133EXPORT_SYMBOL_GPL(meson_clk_dualdiv_ro_ops);
134
135MODULE_DESCRIPTION("Amlogic dual divider driver");
136MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
137MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
138MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-dualdiv.h b/drivers/clk/meson/clk-dualdiv.h
new file mode 100644
index 000000000000..4aa939018012
--- /dev/null
+++ b/drivers/clk/meson/clk-dualdiv.h
@@ -0,0 +1,33 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2019 BayLibre, SAS.
4 * Author: Jerome Brunet <jbrunet@baylibre.com>
5 */
6
7#ifndef __MESON_CLK_DUALDIV_H
8#define __MESON_CLK_DUALDIV_H
9
10#include <linux/clk-provider.h>
11#include "parm.h"
12
13struct meson_clk_dualdiv_param {
14 unsigned int n1;
15 unsigned int n2;
16 unsigned int m1;
17 unsigned int m2;
18 unsigned int dual;
19};
20
21struct meson_clk_dualdiv_data {
22 struct parm n1;
23 struct parm n2;
24 struct parm m1;
25 struct parm m2;
26 struct parm dual;
27 const struct meson_clk_dualdiv_param *table;
28};
29
30extern const struct clk_ops meson_clk_dualdiv_ops;
31extern const struct clk_ops meson_clk_dualdiv_ro_ops;
32
33#endif /* __MESON_CLK_DUALDIV_H */
diff --git a/drivers/clk/meson/clk-input.c b/drivers/clk/meson/clk-input.c
index 06b3e3bb6a66..086226e9dba6 100644
--- a/drivers/clk/meson/clk-input.c
+++ b/drivers/clk/meson/clk-input.c
@@ -7,7 +7,8 @@
7#include <linux/clk.h> 7#include <linux/clk.h>
8#include <linux/clk-provider.h> 8#include <linux/clk-provider.h>
9#include <linux/device.h> 9#include <linux/device.h>
10#include "clkc.h" 10#include <linux/module.h>
11#include "clk-input.h"
11 12
12static const struct clk_ops meson_clk_no_ops = {}; 13static const struct clk_ops meson_clk_no_ops = {};
13 14
@@ -42,3 +43,7 @@ struct clk_hw *meson_clk_hw_register_input(struct device *dev,
42 return ret ? ERR_PTR(ret) : hw; 43 return ret ? ERR_PTR(ret) : hw;
43} 44}
44EXPORT_SYMBOL_GPL(meson_clk_hw_register_input); 45EXPORT_SYMBOL_GPL(meson_clk_hw_register_input);
46
47MODULE_DESCRIPTION("Amlogic clock input helper");
48MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
49MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-input.h b/drivers/clk/meson/clk-input.h
new file mode 100644
index 000000000000..4a541b9685a6
--- /dev/null
+++ b/drivers/clk/meson/clk-input.h
@@ -0,0 +1,19 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2019 BayLibre, SAS.
4 * Author: Jerome Brunet <jbrunet@baylibre.com>
5 */
6
7#ifndef __MESON_CLK_INPUT_H
8#define __MESON_CLK_INPUT_H
9
10#include <linux/clk-provider.h>
11
12struct device;
13
14struct clk_hw *meson_clk_hw_register_input(struct device *dev,
15 const char *of_name,
16 const char *clk_name,
17 unsigned long flags);
18
19#endif /* __MESON_CLK_INPUT_H */
diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c
index 650f75cc15a9..f76850d99e59 100644
--- a/drivers/clk/meson/clk-mpll.c
+++ b/drivers/clk/meson/clk-mpll.c
@@ -12,7 +12,11 @@
12 */ 12 */
13 13
14#include <linux/clk-provider.h> 14#include <linux/clk-provider.h>
15#include "clkc.h" 15#include <linux/module.h>
16#include <linux/spinlock.h>
17
18#include "clk-regmap.h"
19#include "clk-mpll.h"
16 20
17#define SDM_DEN 16384 21#define SDM_DEN 16384
18#define N2_MIN 4 22#define N2_MIN 4
@@ -138,9 +142,15 @@ const struct clk_ops meson_clk_mpll_ro_ops = {
138 .recalc_rate = mpll_recalc_rate, 142 .recalc_rate = mpll_recalc_rate,
139 .round_rate = mpll_round_rate, 143 .round_rate = mpll_round_rate,
140}; 144};
145EXPORT_SYMBOL_GPL(meson_clk_mpll_ro_ops);
141 146
142const struct clk_ops meson_clk_mpll_ops = { 147const struct clk_ops meson_clk_mpll_ops = {
143 .recalc_rate = mpll_recalc_rate, 148 .recalc_rate = mpll_recalc_rate,
144 .round_rate = mpll_round_rate, 149 .round_rate = mpll_round_rate,
145 .set_rate = mpll_set_rate, 150 .set_rate = mpll_set_rate,
146}; 151};
152EXPORT_SYMBOL_GPL(meson_clk_mpll_ops);
153
154MODULE_DESCRIPTION("Amlogic MPLL driver");
155MODULE_AUTHOR("Michael Turquette <mturquette@baylibre.com>");
156MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-mpll.h b/drivers/clk/meson/clk-mpll.h
new file mode 100644
index 000000000000..cf79340006dd
--- /dev/null
+++ b/drivers/clk/meson/clk-mpll.h
@@ -0,0 +1,30 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2019 BayLibre, SAS.
4 * Author: Jerome Brunet <jbrunet@baylibre.com>
5 */
6
7#ifndef __MESON_CLK_MPLL_H
8#define __MESON_CLK_MPLL_H
9
10#include <linux/clk-provider.h>
11#include <linux/spinlock.h>
12
13#include "parm.h"
14
15struct meson_clk_mpll_data {
16 struct parm sdm;
17 struct parm sdm_en;
18 struct parm n2;
19 struct parm ssen;
20 struct parm misc;
21 spinlock_t *lock;
22 u8 flags;
23};
24
25#define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0)
26
27extern const struct clk_ops meson_clk_mpll_ro_ops;
28extern const struct clk_ops meson_clk_mpll_ops;
29
30#endif /* __MESON_CLK_MPLL_H */
diff --git a/drivers/clk/meson/clk-phase.c b/drivers/clk/meson/clk-phase.c
index cba43748ce3d..80c3ada193a4 100644
--- a/drivers/clk/meson/clk-phase.c
+++ b/drivers/clk/meson/clk-phase.c
@@ -5,7 +5,10 @@
5 */ 5 */
6 6
7#include <linux/clk-provider.h> 7#include <linux/clk-provider.h>
8#include "clkc.h" 8#include <linux/module.h>
9
10#include "clk-regmap.h"
11#include "clk-phase.h"
9 12
10#define phase_step(_width) (360 / (1 << (_width))) 13#define phase_step(_width) (360 / (1 << (_width)))
11 14
@@ -15,13 +18,12 @@ meson_clk_phase_data(struct clk_regmap *clk)
15 return (struct meson_clk_phase_data *)clk->data; 18 return (struct meson_clk_phase_data *)clk->data;
16} 19}
17 20
18int meson_clk_degrees_from_val(unsigned int val, unsigned int width) 21static int meson_clk_degrees_from_val(unsigned int val, unsigned int width)
19{ 22{
20 return phase_step(width) * val; 23 return phase_step(width) * val;
21} 24}
22EXPORT_SYMBOL_GPL(meson_clk_degrees_from_val);
23 25
24unsigned int meson_clk_degrees_to_val(int degrees, unsigned int width) 26static unsigned int meson_clk_degrees_to_val(int degrees, unsigned int width)
25{ 27{
26 unsigned int val = DIV_ROUND_CLOSEST(degrees, phase_step(width)); 28 unsigned int val = DIV_ROUND_CLOSEST(degrees, phase_step(width));
27 29
@@ -31,7 +33,6 @@ unsigned int meson_clk_degrees_to_val(int degrees, unsigned int width)
31 */ 33 */
32 return val % (1 << width); 34 return val % (1 << width);
33} 35}
34EXPORT_SYMBOL_GPL(meson_clk_degrees_to_val);
35 36
36static int meson_clk_phase_get_phase(struct clk_hw *hw) 37static int meson_clk_phase_get_phase(struct clk_hw *hw)
37{ 38{
@@ -61,3 +62,67 @@ const struct clk_ops meson_clk_phase_ops = {
61 .set_phase = meson_clk_phase_set_phase, 62 .set_phase = meson_clk_phase_set_phase,
62}; 63};
63EXPORT_SYMBOL_GPL(meson_clk_phase_ops); 64EXPORT_SYMBOL_GPL(meson_clk_phase_ops);
65
66/*
67 * This is a special clock for the audio controller.
68 * The phase of mst_sclk clock output can be controlled independently
69 * for the outside world (ph0), the tdmout (ph1) and tdmin (ph2).
70 * Controlling these 3 phases as just one makes things simpler and
71 * give the same clock view to all the element on the i2s bus.
72 * If necessary, we can still control the phase in the tdm block
73 * which makes these independent control redundant.
74 */
75static inline struct meson_clk_triphase_data *
76meson_clk_triphase_data(struct clk_regmap *clk)
77{
78 return (struct meson_clk_triphase_data *)clk->data;
79}
80
81static void meson_clk_triphase_sync(struct clk_hw *hw)
82{
83 struct clk_regmap *clk = to_clk_regmap(hw);
84 struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
85 unsigned int val;
86
87 /* Get phase 0 and sync it to phase 1 and 2 */
88 val = meson_parm_read(clk->map, &tph->ph0);
89 meson_parm_write(clk->map, &tph->ph1, val);
90 meson_parm_write(clk->map, &tph->ph2, val);
91}
92
93static int meson_clk_triphase_get_phase(struct clk_hw *hw)
94{
95 struct clk_regmap *clk = to_clk_regmap(hw);
96 struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
97 unsigned int val;
98
99 /* Phase are in sync, reading phase 0 is enough */
100 val = meson_parm_read(clk->map, &tph->ph0);
101
102 return meson_clk_degrees_from_val(val, tph->ph0.width);
103}
104
105static int meson_clk_triphase_set_phase(struct clk_hw *hw, int degrees)
106{
107 struct clk_regmap *clk = to_clk_regmap(hw);
108 struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
109 unsigned int val;
110
111 val = meson_clk_degrees_to_val(degrees, tph->ph0.width);
112 meson_parm_write(clk->map, &tph->ph0, val);
113 meson_parm_write(clk->map, &tph->ph1, val);
114 meson_parm_write(clk->map, &tph->ph2, val);
115
116 return 0;
117}
118
119const struct clk_ops meson_clk_triphase_ops = {
120 .init = meson_clk_triphase_sync,
121 .get_phase = meson_clk_triphase_get_phase,
122 .set_phase = meson_clk_triphase_set_phase,
123};
124EXPORT_SYMBOL_GPL(meson_clk_triphase_ops);
125
126MODULE_DESCRIPTION("Amlogic phase driver");
127MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
128MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-phase.h b/drivers/clk/meson/clk-phase.h
new file mode 100644
index 000000000000..5579f9ced142
--- /dev/null
+++ b/drivers/clk/meson/clk-phase.h
@@ -0,0 +1,26 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2019 BayLibre, SAS.
4 * Author: Jerome Brunet <jbrunet@baylibre.com>
5 */
6
7#ifndef __MESON_CLK_PHASE_H
8#define __MESON_CLK_PHASE_H
9
10#include <linux/clk-provider.h>
11#include "parm.h"
12
13struct meson_clk_phase_data {
14 struct parm ph;
15};
16
17struct meson_clk_triphase_data {
18 struct parm ph0;
19 struct parm ph1;
20 struct parm ph2;
21};
22
23extern const struct clk_ops meson_clk_phase_ops;
24extern const struct clk_ops meson_clk_triphase_ops;
25
26#endif /* __MESON_CLK_PHASE_H */
diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
index afffc1547e20..41e16dd7272a 100644
--- a/drivers/clk/meson/clk-pll.c
+++ b/drivers/clk/meson/clk-pll.c
@@ -32,11 +32,10 @@
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/math64.h> 33#include <linux/math64.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/of_address.h> 35#include <linux/rational.h>
36#include <linux/slab.h>
37#include <linux/string.h>
38 36
39#include "clkc.h" 37#include "clk-regmap.h"
38#include "clk-pll.h"
40 39
41static inline struct meson_clk_pll_data * 40static inline struct meson_clk_pll_data *
42meson_clk_pll_data(struct clk_regmap *clk) 41meson_clk_pll_data(struct clk_regmap *clk)
@@ -44,12 +43,21 @@ meson_clk_pll_data(struct clk_regmap *clk)
44 return (struct meson_clk_pll_data *)clk->data; 43 return (struct meson_clk_pll_data *)clk->data;
45} 44}
46 45
46static int __pll_round_closest_mult(struct meson_clk_pll_data *pll)
47{
48 if ((pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) &&
49 !MESON_PARM_APPLICABLE(&pll->frac))
50 return 1;
51
52 return 0;
53}
54
47static unsigned long __pll_params_to_rate(unsigned long parent_rate, 55static unsigned long __pll_params_to_rate(unsigned long parent_rate,
48 const struct pll_params_table *pllt, 56 unsigned int m, unsigned int n,
49 u16 frac, 57 unsigned int frac,
50 struct meson_clk_pll_data *pll) 58 struct meson_clk_pll_data *pll)
51{ 59{
52 u64 rate = (u64)parent_rate * pllt->m; 60 u64 rate = (u64)parent_rate * m;
53 61
54 if (frac && MESON_PARM_APPLICABLE(&pll->frac)) { 62 if (frac && MESON_PARM_APPLICABLE(&pll->frac)) {
55 u64 frac_rate = (u64)parent_rate * frac; 63 u64 frac_rate = (u64)parent_rate * frac;
@@ -58,7 +66,7 @@ static unsigned long __pll_params_to_rate(unsigned long parent_rate,
58 (1 << pll->frac.width)); 66 (1 << pll->frac.width));
59 } 67 }
60 68
61 return DIV_ROUND_UP_ULL(rate, pllt->n); 69 return DIV_ROUND_UP_ULL(rate, n);
62} 70}
63 71
64static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw, 72static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
@@ -66,35 +74,39 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
66{ 74{
67 struct clk_regmap *clk = to_clk_regmap(hw); 75 struct clk_regmap *clk = to_clk_regmap(hw);
68 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); 76 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
69 struct pll_params_table pllt; 77 unsigned int m, n, frac;
70 u16 frac;
71 78
72 pllt.n = meson_parm_read(clk->map, &pll->n); 79 n = meson_parm_read(clk->map, &pll->n);
73 pllt.m = meson_parm_read(clk->map, &pll->m); 80 m = meson_parm_read(clk->map, &pll->m);
74 81
75 frac = MESON_PARM_APPLICABLE(&pll->frac) ? 82 frac = MESON_PARM_APPLICABLE(&pll->frac) ?
76 meson_parm_read(clk->map, &pll->frac) : 83 meson_parm_read(clk->map, &pll->frac) :
77 0; 84 0;
78 85
79 return __pll_params_to_rate(parent_rate, &pllt, frac, pll); 86 return __pll_params_to_rate(parent_rate, m, n, frac, pll);
80} 87}
81 88
82static u16 __pll_params_with_frac(unsigned long rate, 89static unsigned int __pll_params_with_frac(unsigned long rate,
83 unsigned long parent_rate, 90 unsigned long parent_rate,
84 const struct pll_params_table *pllt, 91 unsigned int m,
85 struct meson_clk_pll_data *pll) 92 unsigned int n,
93 struct meson_clk_pll_data *pll)
86{ 94{
87 u16 frac_max = (1 << pll->frac.width); 95 unsigned int frac_max = (1 << pll->frac.width);
88 u64 val = (u64)rate * pllt->n; 96 u64 val = (u64)rate * n;
97
98 /* Bail out if we are already over the requested rate */
99 if (rate < parent_rate * m / n)
100 return 0;
89 101
90 if (pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) 102 if (pll->flags & CLK_MESON_PLL_ROUND_CLOSEST)
91 val = DIV_ROUND_CLOSEST_ULL(val * frac_max, parent_rate); 103 val = DIV_ROUND_CLOSEST_ULL(val * frac_max, parent_rate);
92 else 104 else
93 val = div_u64(val * frac_max, parent_rate); 105 val = div_u64(val * frac_max, parent_rate);
94 106
95 val -= pllt->m * frac_max; 107 val -= m * frac_max;
96 108
97 return min((u16)val, (u16)(frac_max - 1)); 109 return min((unsigned int)val, (frac_max - 1));
98} 110}
99 111
100static bool meson_clk_pll_is_better(unsigned long rate, 112static bool meson_clk_pll_is_better(unsigned long rate,
@@ -102,45 +114,123 @@ static bool meson_clk_pll_is_better(unsigned long rate,
102 unsigned long now, 114 unsigned long now,
103 struct meson_clk_pll_data *pll) 115 struct meson_clk_pll_data *pll)
104{ 116{
105 if (!(pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) || 117 if (__pll_round_closest_mult(pll)) {
106 MESON_PARM_APPLICABLE(&pll->frac)) {
107 /* Round down */
108 if (now < rate && best < now)
109 return true;
110 } else {
111 /* Round Closest */ 118 /* Round Closest */
112 if (abs(now - rate) < abs(best - rate)) 119 if (abs(now - rate) < abs(best - rate))
113 return true; 120 return true;
121 } else {
122 /* Round down */
123 if (now < rate && best < now)
124 return true;
114 } 125 }
115 126
116 return false; 127 return false;
117} 128}
118 129
119static const struct pll_params_table * 130static int meson_clk_get_pll_table_index(unsigned int index,
120meson_clk_get_pll_settings(unsigned long rate, 131 unsigned int *m,
121 unsigned long parent_rate, 132 unsigned int *n,
122 struct meson_clk_pll_data *pll) 133 struct meson_clk_pll_data *pll)
123{ 134{
124 const struct pll_params_table *table = pll->table; 135 if (!pll->table[index].n)
125 unsigned long best = 0, now = 0; 136 return -EINVAL;
126 unsigned int i, best_i = 0; 137
138 *m = pll->table[index].m;
139 *n = pll->table[index].n;
140
141 return 0;
142}
143
144static unsigned int meson_clk_get_pll_range_m(unsigned long rate,
145 unsigned long parent_rate,
146 unsigned int n,
147 struct meson_clk_pll_data *pll)
148{
149 u64 val = (u64)rate * n;
127 150
128 if (!table) 151 if (__pll_round_closest_mult(pll))
129 return NULL; 152 return DIV_ROUND_CLOSEST_ULL(val, parent_rate);
130 153
131 for (i = 0; table[i].n; i++) { 154 return div_u64(val, parent_rate);
132 now = __pll_params_to_rate(parent_rate, &table[i], 0, pll); 155}
133 156
134 /* If we get an exact match, don't bother any further */ 157static int meson_clk_get_pll_range_index(unsigned long rate,
135 if (now == rate) { 158 unsigned long parent_rate,
136 return &table[i]; 159 unsigned int index,
137 } else if (meson_clk_pll_is_better(rate, best, now, pll)) { 160 unsigned int *m,
161 unsigned int *n,
162 struct meson_clk_pll_data *pll)
163{
164 *n = index + 1;
165
166 /* Check the predivider range */
167 if (*n >= (1 << pll->n.width))
168 return -EINVAL;
169
170 if (*n == 1) {
171 /* Get the boundaries out the way */
172 if (rate <= pll->range->min * parent_rate) {
173 *m = pll->range->min;
174 return -ENODATA;
175 } else if (rate >= pll->range->max * parent_rate) {
176 *m = pll->range->max;
177 return -ENODATA;
178 }
179 }
180
181 *m = meson_clk_get_pll_range_m(rate, parent_rate, *n, pll);
182
183 /* the pre-divider gives a multiplier too big - stop */
184 if (*m >= (1 << pll->m.width))
185 return -EINVAL;
186
187 return 0;
188}
189
190static int meson_clk_get_pll_get_index(unsigned long rate,
191 unsigned long parent_rate,
192 unsigned int index,
193 unsigned int *m,
194 unsigned int *n,
195 struct meson_clk_pll_data *pll)
196{
197 if (pll->range)
198 return meson_clk_get_pll_range_index(rate, parent_rate,
199 index, m, n, pll);
200 else if (pll->table)
201 return meson_clk_get_pll_table_index(index, m, n, pll);
202
203 return -EINVAL;
204}
205
206static int meson_clk_get_pll_settings(unsigned long rate,
207 unsigned long parent_rate,
208 unsigned int *best_m,
209 unsigned int *best_n,
210 struct meson_clk_pll_data *pll)
211{
212 unsigned long best = 0, now = 0;
213 unsigned int i, m, n;
214 int ret;
215
216 for (i = 0, ret = 0; !ret; i++) {
217 ret = meson_clk_get_pll_get_index(rate, parent_rate,
218 i, &m, &n, pll);
219 if (ret == -EINVAL)
220 break;
221
222 now = __pll_params_to_rate(parent_rate, m, n, 0, pll);
223 if (meson_clk_pll_is_better(rate, best, now, pll)) {
138 best = now; 224 best = now;
139 best_i = i; 225 *best_m = m;
226 *best_n = n;
227
228 if (now == rate)
229 break;
140 } 230 }
141 } 231 }
142 232
143 return (struct pll_params_table *)&table[best_i]; 233 return best ? 0 : -EINVAL;
144} 234}
145 235
146static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, 236static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -148,15 +238,15 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
148{ 238{
149 struct clk_regmap *clk = to_clk_regmap(hw); 239 struct clk_regmap *clk = to_clk_regmap(hw);
150 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); 240 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
151 const struct pll_params_table *pllt = 241 unsigned int m, n, frac;
152 meson_clk_get_pll_settings(rate, *parent_rate, pll);
153 unsigned long round; 242 unsigned long round;
154 u16 frac; 243 int ret;
155 244
156 if (!pllt) 245 ret = meson_clk_get_pll_settings(rate, *parent_rate, &m, &n, pll);
246 if (ret)
157 return meson_clk_pll_recalc_rate(hw, *parent_rate); 247 return meson_clk_pll_recalc_rate(hw, *parent_rate);
158 248
159 round = __pll_params_to_rate(*parent_rate, pllt, 0, pll); 249 round = __pll_params_to_rate(*parent_rate, m, n, 0, pll);
160 250
161 if (!MESON_PARM_APPLICABLE(&pll->frac) || rate == round) 251 if (!MESON_PARM_APPLICABLE(&pll->frac) || rate == round)
162 return round; 252 return round;
@@ -165,9 +255,9 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
165 * The rate provided by the setting is not an exact match, let's 255 * The rate provided by the setting is not an exact match, let's
166 * try to improve the result using the fractional parameter 256 * try to improve the result using the fractional parameter
167 */ 257 */
168 frac = __pll_params_with_frac(rate, *parent_rate, pllt, pll); 258 frac = __pll_params_with_frac(rate, *parent_rate, m, n, pll);
169 259
170 return __pll_params_to_rate(*parent_rate, pllt, frac, pll); 260 return __pll_params_to_rate(*parent_rate, m, n, frac, pll);
171} 261}
172 262
173static int meson_clk_pll_wait_lock(struct clk_hw *hw) 263static int meson_clk_pll_wait_lock(struct clk_hw *hw)
@@ -254,30 +344,27 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
254{ 344{
255 struct clk_regmap *clk = to_clk_regmap(hw); 345 struct clk_regmap *clk = to_clk_regmap(hw);
256 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); 346 struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
257 const struct pll_params_table *pllt; 347 unsigned int enabled, m, n, frac = 0, ret;
258 unsigned int enabled;
259 unsigned long old_rate; 348 unsigned long old_rate;
260 u16 frac = 0;
261 349
262 if (parent_rate == 0 || rate == 0) 350 if (parent_rate == 0 || rate == 0)
263 return -EINVAL; 351 return -EINVAL;
264 352
265 old_rate = rate; 353 old_rate = rate;
266 354
267 pllt = meson_clk_get_pll_settings(rate, parent_rate, pll); 355 ret = meson_clk_get_pll_settings(rate, parent_rate, &m, &n, pll);
268 if (!pllt) 356 if (ret)
269 return -EINVAL; 357 return ret;
270 358
271 enabled = meson_parm_read(clk->map, &pll->en); 359 enabled = meson_parm_read(clk->map, &pll->en);
272 if (enabled) 360 if (enabled)
273 meson_clk_pll_disable(hw); 361 meson_clk_pll_disable(hw);
274 362
275 meson_parm_write(clk->map, &pll->n, pllt->n); 363 meson_parm_write(clk->map, &pll->n, n);
276 meson_parm_write(clk->map, &pll->m, pllt->m); 364 meson_parm_write(clk->map, &pll->m, m);
277
278 365
279 if (MESON_PARM_APPLICABLE(&pll->frac)) { 366 if (MESON_PARM_APPLICABLE(&pll->frac)) {
280 frac = __pll_params_with_frac(rate, parent_rate, pllt, pll); 367 frac = __pll_params_with_frac(rate, parent_rate, m, n, pll);
281 meson_parm_write(clk->map, &pll->frac, frac); 368 meson_parm_write(clk->map, &pll->frac, frac);
282 } 369 }
283 370
@@ -309,8 +396,15 @@ const struct clk_ops meson_clk_pll_ops = {
309 .enable = meson_clk_pll_enable, 396 .enable = meson_clk_pll_enable,
310 .disable = meson_clk_pll_disable 397 .disable = meson_clk_pll_disable
311}; 398};
399EXPORT_SYMBOL_GPL(meson_clk_pll_ops);
312 400
313const struct clk_ops meson_clk_pll_ro_ops = { 401const struct clk_ops meson_clk_pll_ro_ops = {
314 .recalc_rate = meson_clk_pll_recalc_rate, 402 .recalc_rate = meson_clk_pll_recalc_rate,
315 .is_enabled = meson_clk_pll_is_enabled, 403 .is_enabled = meson_clk_pll_is_enabled,
316}; 404};
405EXPORT_SYMBOL_GPL(meson_clk_pll_ro_ops);
406
407MODULE_DESCRIPTION("Amlogic PLL driver");
408MODULE_AUTHOR("Carlo Caione <carlo@endlessm.com>");
409MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
410MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-pll.h b/drivers/clk/meson/clk-pll.h
new file mode 100644
index 000000000000..55af2e285b1b
--- /dev/null
+++ b/drivers/clk/meson/clk-pll.h
@@ -0,0 +1,49 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2019 BayLibre, SAS.
4 * Author: Jerome Brunet <jbrunet@baylibre.com>
5 */
6
7#ifndef __MESON_CLK_PLL_H
8#define __MESON_CLK_PLL_H
9
10#include <linux/clk-provider.h>
11#include <linux/regmap.h>
12#include "parm.h"
13
14struct pll_params_table {
15 unsigned int m;
16 unsigned int n;
17};
18
19struct pll_mult_range {
20 unsigned int min;
21 unsigned int max;
22};
23
24#define PLL_PARAMS(_m, _n) \
25 { \
26 .m = (_m), \
27 .n = (_n), \
28 }
29
30#define CLK_MESON_PLL_ROUND_CLOSEST BIT(0)
31
32struct meson_clk_pll_data {
33 struct parm en;
34 struct parm m;
35 struct parm n;
36 struct parm frac;
37 struct parm l;
38 struct parm rst;
39 const struct reg_sequence *init_regs;
40 unsigned int init_count;
41 const struct pll_params_table *table;
42 const struct pll_mult_range *range;
43 u8 flags;
44};
45
46extern const struct clk_ops meson_clk_pll_ro_ops;
47extern const struct clk_ops meson_clk_pll_ops;
48
49#endif /* __MESON_CLK_PLL_H */
diff --git a/drivers/clk/meson/clk-regmap.c b/drivers/clk/meson/clk-regmap.c
index c515f67322a3..dcd1757cc5df 100644
--- a/drivers/clk/meson/clk-regmap.c
+++ b/drivers/clk/meson/clk-regmap.c
@@ -4,6 +4,7 @@
4 * Author: Jerome Brunet <jbrunet@baylibre.com> 4 * Author: Jerome Brunet <jbrunet@baylibre.com>
5 */ 5 */
6 6
7#include <linux/module.h>
7#include "clk-regmap.h" 8#include "clk-regmap.h"
8 9
9static int clk_regmap_gate_endisable(struct clk_hw *hw, int enable) 10static int clk_regmap_gate_endisable(struct clk_hw *hw, int enable)
@@ -180,3 +181,7 @@ const struct clk_ops clk_regmap_mux_ro_ops = {
180 .get_parent = clk_regmap_mux_get_parent, 181 .get_parent = clk_regmap_mux_get_parent,
181}; 182};
182EXPORT_SYMBOL_GPL(clk_regmap_mux_ro_ops); 183EXPORT_SYMBOL_GPL(clk_regmap_mux_ro_ops);
184
185MODULE_DESCRIPTION("Amlogic regmap backed clock driver");
186MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
187MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-regmap.h b/drivers/clk/meson/clk-regmap.h
index e9c5728d40eb..1dd0abe3ba91 100644
--- a/drivers/clk/meson/clk-regmap.h
+++ b/drivers/clk/meson/clk-regmap.h
@@ -111,4 +111,24 @@ clk_get_regmap_mux_data(struct clk_regmap *clk)
111extern const struct clk_ops clk_regmap_mux_ops; 111extern const struct clk_ops clk_regmap_mux_ops;
112extern const struct clk_ops clk_regmap_mux_ro_ops; 112extern const struct clk_ops clk_regmap_mux_ro_ops;
113 113
114#define __MESON_GATE(_name, _reg, _bit, _ops) \
115struct clk_regmap _name = { \
116 .data = &(struct clk_regmap_gate_data){ \
117 .offset = (_reg), \
118 .bit_idx = (_bit), \
119 }, \
120 .hw.init = &(struct clk_init_data) { \
121 .name = #_name, \
122 .ops = _ops, \
123 .parent_names = (const char *[]){ "clk81" }, \
124 .num_parents = 1, \
125 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
126 }, \
127}
128
129#define MESON_GATE(_name, _reg, _bit) \
130 __MESON_GATE(_name, _reg, _bit, &clk_regmap_gate_ops)
131
132#define MESON_GATE_RO(_name, _reg, _bit) \
133 __MESON_GATE(_name, _reg, _bit, &clk_regmap_gate_ro_ops)
114#endif /* __CLK_REGMAP_H */ 134#endif /* __CLK_REGMAP_H */
diff --git a/drivers/clk/meson/clk-triphase.c b/drivers/clk/meson/clk-triphase.c
deleted file mode 100644
index 4a59936251e5..000000000000
--- a/drivers/clk/meson/clk-triphase.c
+++ /dev/null
@@ -1,68 +0,0 @@
1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2/*
3 * Copyright (c) 2018 BayLibre, SAS.
4 * Author: Jerome Brunet <jbrunet@baylibre.com>
5 */
6
7#include <linux/clk-provider.h>
8#include "clkc-audio.h"
9
10/*
11 * This is a special clock for the audio controller.
12 * The phase of mst_sclk clock output can be controlled independently
13 * for the outside world (ph0), the tdmout (ph1) and tdmin (ph2).
14 * Controlling these 3 phases as just one makes things simpler and
15 * give the same clock view to all the element on the i2s bus.
16 * If necessary, we can still control the phase in the tdm block
17 * which makes these independent control redundant.
18 */
19static inline struct meson_clk_triphase_data *
20meson_clk_triphase_data(struct clk_regmap *clk)
21{
22 return (struct meson_clk_triphase_data *)clk->data;
23}
24
25static void meson_clk_triphase_sync(struct clk_hw *hw)
26{
27 struct clk_regmap *clk = to_clk_regmap(hw);
28 struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
29 unsigned int val;
30
31 /* Get phase 0 and sync it to phase 1 and 2 */
32 val = meson_parm_read(clk->map, &tph->ph0);
33 meson_parm_write(clk->map, &tph->ph1, val);
34 meson_parm_write(clk->map, &tph->ph2, val);
35}
36
37static int meson_clk_triphase_get_phase(struct clk_hw *hw)
38{
39 struct clk_regmap *clk = to_clk_regmap(hw);
40 struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
41 unsigned int val;
42
43 /* Phase are in sync, reading phase 0 is enough */
44 val = meson_parm_read(clk->map, &tph->ph0);
45
46 return meson_clk_degrees_from_val(val, tph->ph0.width);
47}
48
49static int meson_clk_triphase_set_phase(struct clk_hw *hw, int degrees)
50{
51 struct clk_regmap *clk = to_clk_regmap(hw);
52 struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
53 unsigned int val;
54
55 val = meson_clk_degrees_to_val(degrees, tph->ph0.width);
56 meson_parm_write(clk->map, &tph->ph0, val);
57 meson_parm_write(clk->map, &tph->ph1, val);
58 meson_parm_write(clk->map, &tph->ph2, val);
59
60 return 0;
61}
62
63const struct clk_ops meson_clk_triphase_ops = {
64 .init = meson_clk_triphase_sync,
65 .get_phase = meson_clk_triphase_get_phase,
66 .set_phase = meson_clk_triphase_set_phase,
67};
68EXPORT_SYMBOL_GPL(meson_clk_triphase_ops);
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
deleted file mode 100644
index 6183b22c4bf2..000000000000
--- a/drivers/clk/meson/clkc.h
+++ /dev/null
@@ -1,127 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2015 Endless Mobile, Inc.
4 * Author: Carlo Caione <carlo@endlessm.com>
5 */
6
7#ifndef __CLKC_H
8#define __CLKC_H
9
10#include <linux/clk-provider.h>
11#include "clk-regmap.h"
12
13#define PMASK(width) GENMASK(width - 1, 0)
14#define SETPMASK(width, shift) GENMASK(shift + width - 1, shift)
15#define CLRPMASK(width, shift) (~SETPMASK(width, shift))
16
17#define PARM_GET(width, shift, reg) \
18 (((reg) & SETPMASK(width, shift)) >> (shift))
19#define PARM_SET(width, shift, reg, val) \
20 (((reg) & CLRPMASK(width, shift)) | ((val) << (shift)))
21
22#define MESON_PARM_APPLICABLE(p) (!!((p)->width))
23
24struct parm {
25 u16 reg_off;
26 u8 shift;
27 u8 width;
28};
29
30static inline unsigned int meson_parm_read(struct regmap *map, struct parm *p)
31{
32 unsigned int val;
33
34 regmap_read(map, p->reg_off, &val);
35 return PARM_GET(p->width, p->shift, val);
36}
37
38static inline void meson_parm_write(struct regmap *map, struct parm *p,
39 unsigned int val)
40{
41 regmap_update_bits(map, p->reg_off, SETPMASK(p->width, p->shift),
42 val << p->shift);
43}
44
45
46struct pll_params_table {
47 u16 m;
48 u16 n;
49};
50
51#define PLL_PARAMS(_m, _n) \
52 { \
53 .m = (_m), \
54 .n = (_n), \
55 }
56
57#define CLK_MESON_PLL_ROUND_CLOSEST BIT(0)
58
59struct meson_clk_pll_data {
60 struct parm en;
61 struct parm m;
62 struct parm n;
63 struct parm frac;
64 struct parm l;
65 struct parm rst;
66 const struct reg_sequence *init_regs;
67 unsigned int init_count;
68 const struct pll_params_table *table;
69 u8 flags;
70};
71
72#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
73
74struct meson_clk_mpll_data {
75 struct parm sdm;
76 struct parm sdm_en;
77 struct parm n2;
78 struct parm ssen;
79 struct parm misc;
80 spinlock_t *lock;
81 u8 flags;
82};
83
84#define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0)
85
86struct meson_clk_phase_data {
87 struct parm ph;
88};
89
90int meson_clk_degrees_from_val(unsigned int val, unsigned int width);
91unsigned int meson_clk_degrees_to_val(int degrees, unsigned int width);
92
93struct meson_vid_pll_div_data {
94 struct parm val;
95 struct parm sel;
96};
97
98#define MESON_GATE(_name, _reg, _bit) \
99struct clk_regmap _name = { \
100 .data = &(struct clk_regmap_gate_data){ \
101 .offset = (_reg), \
102 .bit_idx = (_bit), \
103 }, \
104 .hw.init = &(struct clk_init_data) { \
105 .name = #_name, \
106 .ops = &clk_regmap_gate_ops, \
107 .parent_names = (const char *[]){ "clk81" }, \
108 .num_parents = 1, \
109 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
110 }, \
111};
112
113/* clk_ops */
114extern const struct clk_ops meson_clk_pll_ro_ops;
115extern const struct clk_ops meson_clk_pll_ops;
116extern const struct clk_ops meson_clk_cpu_ops;
117extern const struct clk_ops meson_clk_mpll_ro_ops;
118extern const struct clk_ops meson_clk_mpll_ops;
119extern const struct clk_ops meson_clk_phase_ops;
120extern const struct clk_ops meson_vid_pll_div_ro_ops;
121
122struct clk_hw *meson_clk_hw_register_input(struct device *dev,
123 const char *of_name,
124 const char *clk_name,
125 unsigned long flags);
126
127#endif /* __CLKC_H */
diff --git a/drivers/clk/meson/g12a-aoclk.c b/drivers/clk/meson/g12a-aoclk.c
new file mode 100644
index 000000000000..1994e735396b
--- /dev/null
+++ b/drivers/clk/meson/g12a-aoclk.c
@@ -0,0 +1,454 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Amlogic Meson-AXG Clock Controller Driver
4 *
5 * Copyright (c) 2016 Baylibre SAS.
6 * Author: Michael Turquette <mturquette@baylibre.com>
7 *
8 * Copyright (c) 2019 Baylibre SAS.
9 * Author: Neil Armstrong <narmstrong@baylibre.com>
10 */
11#include <linux/clk-provider.h>
12#include <linux/platform_device.h>
13#include <linux/reset-controller.h>
14#include <linux/mfd/syscon.h>
15#include "meson-aoclk.h"
16#include "g12a-aoclk.h"
17
18#include "clk-regmap.h"
19#include "clk-dualdiv.h"
20
21#define IN_PREFIX "ao-in-"
22
23/*
24 * AO Configuration Clock registers offsets
25 * Register offsets from the data sheet must be multiplied by 4.
26 */
27#define AO_RTI_STATUS_REG3 0x0C
28#define AO_RTI_PWR_CNTL_REG0 0x10
29#define AO_RTI_GEN_CNTL_REG0 0x40
30#define AO_CLK_GATE0 0x4c
31#define AO_CLK_GATE0_SP 0x50
32#define AO_OSCIN_CNTL 0x58
33#define AO_CEC_CLK_CNTL_REG0 0x74
34#define AO_CEC_CLK_CNTL_REG1 0x78
35#define AO_SAR_CLK 0x90
36#define AO_RTC_ALT_CLK_CNTL0 0x94
37#define AO_RTC_ALT_CLK_CNTL1 0x98
38
39/*
40 * Like every other peripheral clock gate in Amlogic Clock drivers,
41 * we are using CLK_IGNORE_UNUSED here, so we keep the state of the
42 * bootloader. The goal is to remove this flag at some point.
43 * Actually removing it will require some extensive test to be done safely.
44 */
45#define AXG_AO_GATE(_name, _reg, _bit) \
46static struct clk_regmap g12a_aoclk_##_name = { \
47 .data = &(struct clk_regmap_gate_data) { \
48 .offset = (_reg), \
49 .bit_idx = (_bit), \
50 }, \
51 .hw.init = &(struct clk_init_data) { \
52 .name = "g12a_ao_" #_name, \
53 .ops = &clk_regmap_gate_ops, \
54 .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \
55 .num_parents = 1, \
56 .flags = CLK_IGNORE_UNUSED, \
57 }, \
58}
59
60AXG_AO_GATE(ahb, AO_CLK_GATE0, 0);
61AXG_AO_GATE(ir_in, AO_CLK_GATE0, 1);
62AXG_AO_GATE(i2c_m0, AO_CLK_GATE0, 2);
63AXG_AO_GATE(i2c_s0, AO_CLK_GATE0, 3);
64AXG_AO_GATE(uart, AO_CLK_GATE0, 4);
65AXG_AO_GATE(prod_i2c, AO_CLK_GATE0, 5);
66AXG_AO_GATE(uart2, AO_CLK_GATE0, 6);
67AXG_AO_GATE(ir_out, AO_CLK_GATE0, 7);
68AXG_AO_GATE(saradc, AO_CLK_GATE0, 8);
69AXG_AO_GATE(mailbox, AO_CLK_GATE0_SP, 0);
70AXG_AO_GATE(m3, AO_CLK_GATE0_SP, 1);
71AXG_AO_GATE(ahb_sram, AO_CLK_GATE0_SP, 2);
72AXG_AO_GATE(rti, AO_CLK_GATE0_SP, 3);
73AXG_AO_GATE(m4_fclk, AO_CLK_GATE0_SP, 4);
74AXG_AO_GATE(m4_hclk, AO_CLK_GATE0_SP, 5);
75
76static struct clk_regmap g12a_aoclk_cts_oscin = {
77 .data = &(struct clk_regmap_gate_data){
78 .offset = AO_RTI_PWR_CNTL_REG0,
79 .bit_idx = 14,
80 },
81 .hw.init = &(struct clk_init_data){
82 .name = "cts_oscin",
83 .ops = &clk_regmap_gate_ro_ops,
84 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
85 .num_parents = 1,
86 },
87};
88
89static const struct meson_clk_dualdiv_param g12a_32k_div_table[] = {
90 {
91 .dual = 1,
92 .n1 = 733,
93 .m1 = 8,
94 .n2 = 732,
95 .m2 = 11,
96 }, {}
97};
98
99/* 32k_by_oscin clock */
100
101static struct clk_regmap g12a_aoclk_32k_by_oscin_pre = {
102 .data = &(struct clk_regmap_gate_data){
103 .offset = AO_RTC_ALT_CLK_CNTL0,
104 .bit_idx = 31,
105 },
106 .hw.init = &(struct clk_init_data){
107 .name = "g12a_ao_32k_by_oscin_pre",
108 .ops = &clk_regmap_gate_ops,
109 .parent_names = (const char *[]){ "cts_oscin" },
110 .num_parents = 1,
111 },
112};
113
114static struct clk_regmap g12a_aoclk_32k_by_oscin_div = {
115 .data = &(struct meson_clk_dualdiv_data){
116 .n1 = {
117 .reg_off = AO_RTC_ALT_CLK_CNTL0,
118 .shift = 0,
119 .width = 12,
120 },
121 .n2 = {
122 .reg_off = AO_RTC_ALT_CLK_CNTL0,
123 .shift = 12,
124 .width = 12,
125 },
126 .m1 = {
127 .reg_off = AO_RTC_ALT_CLK_CNTL1,
128 .shift = 0,
129 .width = 12,
130 },
131 .m2 = {
132 .reg_off = AO_RTC_ALT_CLK_CNTL1,
133 .shift = 12,
134 .width = 12,
135 },
136 .dual = {
137 .reg_off = AO_RTC_ALT_CLK_CNTL0,
138 .shift = 28,
139 .width = 1,
140 },
141 .table = g12a_32k_div_table,
142 },
143 .hw.init = &(struct clk_init_data){
144 .name = "g12a_ao_32k_by_oscin_div",
145 .ops = &meson_clk_dualdiv_ops,
146 .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_pre" },
147 .num_parents = 1,
148 },
149};
150
151static struct clk_regmap g12a_aoclk_32k_by_oscin_sel = {
152 .data = &(struct clk_regmap_mux_data) {
153 .offset = AO_RTC_ALT_CLK_CNTL1,
154 .mask = 0x1,
155 .shift = 24,
156 .flags = CLK_MUX_ROUND_CLOSEST,
157 },
158 .hw.init = &(struct clk_init_data){
159 .name = "g12a_ao_32k_by_oscin_sel",
160 .ops = &clk_regmap_mux_ops,
161 .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_div",
162 "g12a_ao_32k_by_oscin_pre" },
163 .num_parents = 2,
164 .flags = CLK_SET_RATE_PARENT,
165 },
166};
167
168static struct clk_regmap g12a_aoclk_32k_by_oscin = {
169 .data = &(struct clk_regmap_gate_data){
170 .offset = AO_RTC_ALT_CLK_CNTL0,
171 .bit_idx = 30,
172 },
173 .hw.init = &(struct clk_init_data){
174 .name = "g12a_ao_32k_by_oscin",
175 .ops = &clk_regmap_gate_ops,
176 .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_sel" },
177 .num_parents = 1,
178 .flags = CLK_SET_RATE_PARENT,
179 },
180};
181
182/* cec clock */
183
184static struct clk_regmap g12a_aoclk_cec_pre = {
185 .data = &(struct clk_regmap_gate_data){
186 .offset = AO_CEC_CLK_CNTL_REG0,
187 .bit_idx = 31,
188 },
189 .hw.init = &(struct clk_init_data){
190 .name = "g12a_ao_cec_pre",
191 .ops = &clk_regmap_gate_ops,
192 .parent_names = (const char *[]){ "cts_oscin" },
193 .num_parents = 1,
194 },
195};
196
197static struct clk_regmap g12a_aoclk_cec_div = {
198 .data = &(struct meson_clk_dualdiv_data){
199 .n1 = {
200 .reg_off = AO_CEC_CLK_CNTL_REG0,
201 .shift = 0,
202 .width = 12,
203 },
204 .n2 = {
205 .reg_off = AO_CEC_CLK_CNTL_REG0,
206 .shift = 12,
207 .width = 12,
208 },
209 .m1 = {
210 .reg_off = AO_CEC_CLK_CNTL_REG1,
211 .shift = 0,
212 .width = 12,
213 },
214 .m2 = {
215 .reg_off = AO_CEC_CLK_CNTL_REG1,
216 .shift = 12,
217 .width = 12,
218 },
219 .dual = {
220 .reg_off = AO_CEC_CLK_CNTL_REG0,
221 .shift = 28,
222 .width = 1,
223 },
224 .table = g12a_32k_div_table,
225 },
226 .hw.init = &(struct clk_init_data){
227 .name = "g12a_ao_cec_div",
228 .ops = &meson_clk_dualdiv_ops,
229 .parent_names = (const char *[]){ "g12a_ao_cec_pre" },
230 .num_parents = 1,
231 },
232};
233
234static struct clk_regmap g12a_aoclk_cec_sel = {
235 .data = &(struct clk_regmap_mux_data) {
236 .offset = AO_CEC_CLK_CNTL_REG1,
237 .mask = 0x1,
238 .shift = 24,
239 .flags = CLK_MUX_ROUND_CLOSEST,
240 },
241 .hw.init = &(struct clk_init_data){
242 .name = "g12a_ao_cec_sel",
243 .ops = &clk_regmap_mux_ops,
244 .parent_names = (const char *[]){ "g12a_ao_cec_div",
245 "g12a_ao_cec_pre" },
246 .num_parents = 2,
247 .flags = CLK_SET_RATE_PARENT,
248 },
249};
250
251static struct clk_regmap g12a_aoclk_cec = {
252 .data = &(struct clk_regmap_gate_data){
253 .offset = AO_CEC_CLK_CNTL_REG0,
254 .bit_idx = 30,
255 },
256 .hw.init = &(struct clk_init_data){
257 .name = "g12a_ao_cec",
258 .ops = &clk_regmap_gate_ops,
259 .parent_names = (const char *[]){ "g12a_ao_cec_sel" },
260 .num_parents = 1,
261 .flags = CLK_SET_RATE_PARENT,
262 },
263};
264
265static struct clk_regmap g12a_aoclk_cts_rtc_oscin = {
266 .data = &(struct clk_regmap_mux_data) {
267 .offset = AO_RTI_PWR_CNTL_REG0,
268 .mask = 0x1,
269 .shift = 10,
270 .flags = CLK_MUX_ROUND_CLOSEST,
271 },
272 .hw.init = &(struct clk_init_data){
273 .name = "g12a_ao_cts_rtc_oscin",
274 .ops = &clk_regmap_mux_ops,
275 .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin",
276 IN_PREFIX "ext_32k-0" },
277 .num_parents = 2,
278 .flags = CLK_SET_RATE_PARENT,
279 },
280};
281
282static struct clk_regmap g12a_aoclk_clk81 = {
283 .data = &(struct clk_regmap_mux_data) {
284 .offset = AO_RTI_PWR_CNTL_REG0,
285 .mask = 0x1,
286 .shift = 8,
287 .flags = CLK_MUX_ROUND_CLOSEST,
288 },
289 .hw.init = &(struct clk_init_data){
290 .name = "g12a_ao_clk81",
291 .ops = &clk_regmap_mux_ro_ops,
292 .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk",
293 "g12a_ao_cts_rtc_oscin"},
294 .num_parents = 2,
295 .flags = CLK_SET_RATE_PARENT,
296 },
297};
298
299static struct clk_regmap g12a_aoclk_saradc_mux = {
300 .data = &(struct clk_regmap_mux_data) {
301 .offset = AO_SAR_CLK,
302 .mask = 0x3,
303 .shift = 9,
304 },
305 .hw.init = &(struct clk_init_data){
306 .name = "g12a_ao_saradc_mux",
307 .ops = &clk_regmap_mux_ops,
308 .parent_names = (const char *[]){ IN_PREFIX "xtal",
309 "g12a_ao_clk81" },
310 .num_parents = 2,
311 },
312};
313
314static struct clk_regmap g12a_aoclk_saradc_div = {
315 .data = &(struct clk_regmap_div_data) {
316 .offset = AO_SAR_CLK,
317 .shift = 0,
318 .width = 8,
319 },
320 .hw.init = &(struct clk_init_data){
321 .name = "g12a_ao_saradc_div",
322 .ops = &clk_regmap_divider_ops,
323 .parent_names = (const char *[]){ "g12a_ao_saradc_mux" },
324 .num_parents = 1,
325 .flags = CLK_SET_RATE_PARENT,
326 },
327};
328
329static struct clk_regmap g12a_aoclk_saradc_gate = {
330 .data = &(struct clk_regmap_gate_data) {
331 .offset = AO_SAR_CLK,
332 .bit_idx = 8,
333 },
334 .hw.init = &(struct clk_init_data){
335 .name = "g12a_ao_saradc_gate",
336 .ops = &clk_regmap_gate_ops,
337 .parent_names = (const char *[]){ "g12a_ao_saradc_div" },
338 .num_parents = 1,
339 .flags = CLK_SET_RATE_PARENT,
340 },
341};
342
343static const unsigned int g12a_aoclk_reset[] = {
344 [RESET_AO_IR_IN] = 16,
345 [RESET_AO_UART] = 17,
346 [RESET_AO_I2C_M] = 18,
347 [RESET_AO_I2C_S] = 19,
348 [RESET_AO_SAR_ADC] = 20,
349 [RESET_AO_UART2] = 22,
350 [RESET_AO_IR_OUT] = 23,
351};
352
353static struct clk_regmap *g12a_aoclk_regmap[] = {
354 &g12a_aoclk_ahb,
355 &g12a_aoclk_ir_in,
356 &g12a_aoclk_i2c_m0,
357 &g12a_aoclk_i2c_s0,
358 &g12a_aoclk_uart,
359 &g12a_aoclk_prod_i2c,
360 &g12a_aoclk_uart2,
361 &g12a_aoclk_ir_out,
362 &g12a_aoclk_saradc,
363 &g12a_aoclk_mailbox,
364 &g12a_aoclk_m3,
365 &g12a_aoclk_ahb_sram,
366 &g12a_aoclk_rti,
367 &g12a_aoclk_m4_fclk,
368 &g12a_aoclk_m4_hclk,
369 &g12a_aoclk_cts_oscin,
370 &g12a_aoclk_32k_by_oscin_pre,
371 &g12a_aoclk_32k_by_oscin_div,
372 &g12a_aoclk_32k_by_oscin_sel,
373 &g12a_aoclk_32k_by_oscin,
374 &g12a_aoclk_cec_pre,
375 &g12a_aoclk_cec_div,
376 &g12a_aoclk_cec_sel,
377 &g12a_aoclk_cec,
378 &g12a_aoclk_cts_rtc_oscin,
379 &g12a_aoclk_clk81,
380 &g12a_aoclk_saradc_mux,
381 &g12a_aoclk_saradc_div,
382 &g12a_aoclk_saradc_gate,
383};
384
385static const struct clk_hw_onecell_data g12a_aoclk_onecell_data = {
386 .hws = {
387 [CLKID_AO_AHB] = &g12a_aoclk_ahb.hw,
388 [CLKID_AO_IR_IN] = &g12a_aoclk_ir_in.hw,
389 [CLKID_AO_I2C_M0] = &g12a_aoclk_i2c_m0.hw,
390 [CLKID_AO_I2C_S0] = &g12a_aoclk_i2c_s0.hw,
391 [CLKID_AO_UART] = &g12a_aoclk_uart.hw,
392 [CLKID_AO_PROD_I2C] = &g12a_aoclk_prod_i2c.hw,
393 [CLKID_AO_UART2] = &g12a_aoclk_uart2.hw,
394 [CLKID_AO_IR_OUT] = &g12a_aoclk_ir_out.hw,
395 [CLKID_AO_SAR_ADC] = &g12a_aoclk_saradc.hw,
396 [CLKID_AO_MAILBOX] = &g12a_aoclk_mailbox.hw,
397 [CLKID_AO_M3] = &g12a_aoclk_m3.hw,
398 [CLKID_AO_AHB_SRAM] = &g12a_aoclk_ahb_sram.hw,
399 [CLKID_AO_RTI] = &g12a_aoclk_rti.hw,
400 [CLKID_AO_M4_FCLK] = &g12a_aoclk_m4_fclk.hw,
401 [CLKID_AO_M4_HCLK] = &g12a_aoclk_m4_hclk.hw,
402 [CLKID_AO_CLK81] = &g12a_aoclk_clk81.hw,
403 [CLKID_AO_SAR_ADC_SEL] = &g12a_aoclk_saradc_mux.hw,
404 [CLKID_AO_SAR_ADC_DIV] = &g12a_aoclk_saradc_div.hw,
405 [CLKID_AO_SAR_ADC_CLK] = &g12a_aoclk_saradc_gate.hw,
406 [CLKID_AO_CTS_OSCIN] = &g12a_aoclk_cts_oscin.hw,
407 [CLKID_AO_32K_PRE] = &g12a_aoclk_32k_by_oscin_pre.hw,
408 [CLKID_AO_32K_DIV] = &g12a_aoclk_32k_by_oscin_div.hw,
409 [CLKID_AO_32K_SEL] = &g12a_aoclk_32k_by_oscin_sel.hw,
410 [CLKID_AO_32K] = &g12a_aoclk_32k_by_oscin.hw,
411 [CLKID_AO_CEC_PRE] = &g12a_aoclk_cec_pre.hw,
412 [CLKID_AO_CEC_DIV] = &g12a_aoclk_cec_div.hw,
413 [CLKID_AO_CEC_SEL] = &g12a_aoclk_cec_sel.hw,
414 [CLKID_AO_CEC] = &g12a_aoclk_cec.hw,
415 [CLKID_AO_CTS_RTC_OSCIN] = &g12a_aoclk_cts_rtc_oscin.hw,
416 },
417 .num = NR_CLKS,
418};
419
420static const struct meson_aoclk_input g12a_aoclk_inputs[] = {
421 { .name = "xtal", .required = true },
422 { .name = "mpeg-clk", .required = true },
423 { .name = "ext-32k-0", .required = false },
424};
425
426static const struct meson_aoclk_data g12a_aoclkc_data = {
427 .reset_reg = AO_RTI_GEN_CNTL_REG0,
428 .num_reset = ARRAY_SIZE(g12a_aoclk_reset),
429 .reset = g12a_aoclk_reset,
430 .num_clks = ARRAY_SIZE(g12a_aoclk_regmap),
431 .clks = g12a_aoclk_regmap,
432 .hw_data = &g12a_aoclk_onecell_data,
433 .inputs = g12a_aoclk_inputs,
434 .num_inputs = ARRAY_SIZE(g12a_aoclk_inputs),
435 .input_prefix = IN_PREFIX,
436};
437
438static const struct of_device_id g12a_aoclkc_match_table[] = {
439 {
440 .compatible = "amlogic,meson-g12a-aoclkc",
441 .data = &g12a_aoclkc_data,
442 },
443 { }
444};
445
446static struct platform_driver g12a_aoclkc_driver = {
447 .probe = meson_aoclkc_probe,
448 .driver = {
449 .name = "g12a-aoclkc",
450 .of_match_table = g12a_aoclkc_match_table,
451 },
452};
453
454builtin_platform_driver(g12a_aoclkc_driver);
diff --git a/drivers/clk/meson/g12a-aoclk.h b/drivers/clk/meson/g12a-aoclk.h
new file mode 100644
index 000000000000..04b0d5506641
--- /dev/null
+++ b/drivers/clk/meson/g12a-aoclk.h
@@ -0,0 +1,34 @@
1/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
2/*
3 * Copyright (c) 2019 BayLibre, SAS
4 * Author: Neil Armstrong <narmstrong@baylibre.com>
5 */
6
7#ifndef __G12A_AOCLKC_H
8#define __G12A_AOCLKC_H
9
10/*
11 * CLKID index values
12 *
13 * These indices are entirely contrived and do not map onto the hardware.
14 * It has now been decided to expose everything by default in the DT header:
15 * include/dt-bindings/clock/g12a-aoclkc.h. Only the clocks ids we don't want
16 * to expose, such as the internal muxes and dividers of composite clocks,
17 * will remain defined here.
18 */
19#define CLKID_AO_SAR_ADC_SEL 16
20#define CLKID_AO_SAR_ADC_DIV 17
21#define CLKID_AO_CTS_OSCIN 19
22#define CLKID_AO_32K_PRE 20
23#define CLKID_AO_32K_DIV 21
24#define CLKID_AO_32K_SEL 22
25#define CLKID_AO_CEC_PRE 24
26#define CLKID_AO_CEC_DIV 25
27#define CLKID_AO_CEC_SEL 26
28
29#define NR_CLKS 29
30
31#include <dt-bindings/clock/g12a-aoclkc.h>
32#include <dt-bindings/reset/g12a-aoclkc.h>
33
34#endif /* __G12A_AOCLKC_H */
diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
new file mode 100644
index 000000000000..0e1ce8c03259
--- /dev/null
+++ b/drivers/clk/meson/g12a.c
@@ -0,0 +1,2359 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Amlogic Meson-G12A Clock Controller Driver
4 *
5 * Copyright (c) 2016 Baylibre SAS.
6 * Author: Michael Turquette <mturquette@baylibre.com>
7 *
8 * Copyright (c) 2018 Amlogic, inc.
9 * Author: Qiufang Dai <qiufang.dai@amlogic.com>
10 * Author: Jian Hu <jian.hu@amlogic.com>
11 */
12
13#include <linux/clk-provider.h>
14#include <linux/init.h>
15#include <linux/of_device.h>
16#include <linux/platform_device.h>
17
18#include "clk-input.h"
19#include "clk-mpll.h"
20#include "clk-pll.h"
21#include "clk-regmap.h"
22#include "vid-pll-div.h"
23#include "meson-eeclk.h"
24#include "g12a.h"
25
26static DEFINE_SPINLOCK(meson_clk_lock);
27
28static struct clk_regmap g12a_fixed_pll_dco = {
29 .data = &(struct meson_clk_pll_data){
30 .en = {
31 .reg_off = HHI_FIX_PLL_CNTL0,
32 .shift = 28,
33 .width = 1,
34 },
35 .m = {
36 .reg_off = HHI_FIX_PLL_CNTL0,
37 .shift = 0,
38 .width = 8,
39 },
40 .n = {
41 .reg_off = HHI_FIX_PLL_CNTL0,
42 .shift = 10,
43 .width = 5,
44 },
45 .frac = {
46 .reg_off = HHI_FIX_PLL_CNTL1,
47 .shift = 0,
48 .width = 17,
49 },
50 .l = {
51 .reg_off = HHI_FIX_PLL_CNTL0,
52 .shift = 31,
53 .width = 1,
54 },
55 .rst = {
56 .reg_off = HHI_FIX_PLL_CNTL0,
57 .shift = 29,
58 .width = 1,
59 },
60 },
61 .hw.init = &(struct clk_init_data){
62 .name = "fixed_pll_dco",
63 .ops = &meson_clk_pll_ro_ops,
64 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
65 .num_parents = 1,
66 },
67};
68
69static struct clk_regmap g12a_fixed_pll = {
70 .data = &(struct clk_regmap_div_data){
71 .offset = HHI_FIX_PLL_CNTL0,
72 .shift = 16,
73 .width = 2,
74 .flags = CLK_DIVIDER_POWER_OF_TWO,
75 },
76 .hw.init = &(struct clk_init_data){
77 .name = "fixed_pll",
78 .ops = &clk_regmap_divider_ro_ops,
79 .parent_names = (const char *[]){ "fixed_pll_dco" },
80 .num_parents = 1,
81 /*
82 * This clock won't ever change at runtime so
83 * CLK_SET_RATE_PARENT is not required
84 */
85 },
86};
87
88/*
89 * Internal sys pll emulation configuration parameters
90 */
91static const struct reg_sequence g12a_sys_init_regs[] = {
92 { .reg = HHI_SYS_PLL_CNTL1, .def = 0x00000000 },
93 { .reg = HHI_SYS_PLL_CNTL2, .def = 0x00000000 },
94 { .reg = HHI_SYS_PLL_CNTL3, .def = 0x48681c00 },
95 { .reg = HHI_SYS_PLL_CNTL4, .def = 0x88770290 },
96 { .reg = HHI_SYS_PLL_CNTL5, .def = 0x39272000 },
97 { .reg = HHI_SYS_PLL_CNTL6, .def = 0x56540000 },
98};
99
100static struct clk_regmap g12a_sys_pll_dco = {
101 .data = &(struct meson_clk_pll_data){
102 .en = {
103 .reg_off = HHI_SYS_PLL_CNTL0,
104 .shift = 28,
105 .width = 1,
106 },
107 .m = {
108 .reg_off = HHI_SYS_PLL_CNTL0,
109 .shift = 0,
110 .width = 8,
111 },
112 .n = {
113 .reg_off = HHI_SYS_PLL_CNTL0,
114 .shift = 10,
115 .width = 5,
116 },
117 .l = {
118 .reg_off = HHI_SYS_PLL_CNTL0,
119 .shift = 31,
120 .width = 1,
121 },
122 .rst = {
123 .reg_off = HHI_SYS_PLL_CNTL0,
124 .shift = 29,
125 .width = 1,
126 },
127 .init_regs = g12a_sys_init_regs,
128 .init_count = ARRAY_SIZE(g12a_sys_init_regs),
129 },
130 .hw.init = &(struct clk_init_data){
131 .name = "sys_pll_dco",
132 .ops = &meson_clk_pll_ro_ops,
133 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
134 .num_parents = 1,
135 },
136};
137
138static struct clk_regmap g12a_sys_pll = {
139 .data = &(struct clk_regmap_div_data){
140 .offset = HHI_SYS_PLL_CNTL0,
141 .shift = 16,
142 .width = 3,
143 .flags = CLK_DIVIDER_POWER_OF_TWO,
144 },
145 .hw.init = &(struct clk_init_data){
146 .name = "sys_pll",
147 .ops = &clk_regmap_divider_ro_ops,
148 .parent_names = (const char *[]){ "sys_pll_dco" },
149 .num_parents = 1,
150 },
151};
152
153static const struct pll_mult_range g12a_gp0_pll_mult_range = {
154 .min = 55,
155 .max = 255,
156};
157
158/*
159 * Internal gp0 pll emulation configuration parameters
160 */
161static const struct reg_sequence g12a_gp0_init_regs[] = {
162 { .reg = HHI_GP0_PLL_CNTL1, .def = 0x00000000 },
163 { .reg = HHI_GP0_PLL_CNTL2, .def = 0x00000000 },
164 { .reg = HHI_GP0_PLL_CNTL3, .def = 0x48681c00 },
165 { .reg = HHI_GP0_PLL_CNTL4, .def = 0x33771290 },
166 { .reg = HHI_GP0_PLL_CNTL5, .def = 0x39272000 },
167 { .reg = HHI_GP0_PLL_CNTL6, .def = 0x56540000 },
168};
169
170static struct clk_regmap g12a_gp0_pll_dco = {
171 .data = &(struct meson_clk_pll_data){
172 .en = {
173 .reg_off = HHI_GP0_PLL_CNTL0,
174 .shift = 28,
175 .width = 1,
176 },
177 .m = {
178 .reg_off = HHI_GP0_PLL_CNTL0,
179 .shift = 0,
180 .width = 8,
181 },
182 .n = {
183 .reg_off = HHI_GP0_PLL_CNTL0,
184 .shift = 10,
185 .width = 5,
186 },
187 .frac = {
188 .reg_off = HHI_GP0_PLL_CNTL1,
189 .shift = 0,
190 .width = 17,
191 },
192 .l = {
193 .reg_off = HHI_GP0_PLL_CNTL0,
194 .shift = 31,
195 .width = 1,
196 },
197 .rst = {
198 .reg_off = HHI_GP0_PLL_CNTL0,
199 .shift = 29,
200 .width = 1,
201 },
202 .range = &g12a_gp0_pll_mult_range,
203 .init_regs = g12a_gp0_init_regs,
204 .init_count = ARRAY_SIZE(g12a_gp0_init_regs),
205 },
206 .hw.init = &(struct clk_init_data){
207 .name = "gp0_pll_dco",
208 .ops = &meson_clk_pll_ops,
209 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
210 .num_parents = 1,
211 },
212};
213
214static struct clk_regmap g12a_gp0_pll = {
215 .data = &(struct clk_regmap_div_data){
216 .offset = HHI_GP0_PLL_CNTL0,
217 .shift = 16,
218 .width = 3,
219 .flags = (CLK_DIVIDER_POWER_OF_TWO |
220 CLK_DIVIDER_ROUND_CLOSEST),
221 },
222 .hw.init = &(struct clk_init_data){
223 .name = "gp0_pll",
224 .ops = &clk_regmap_divider_ops,
225 .parent_names = (const char *[]){ "gp0_pll_dco" },
226 .num_parents = 1,
227 .flags = CLK_SET_RATE_PARENT,
228 },
229};
230
231/*
232 * Internal hifi pll emulation configuration parameters
233 */
234static const struct reg_sequence g12a_hifi_init_regs[] = {
235 { .reg = HHI_HIFI_PLL_CNTL1, .def = 0x00000000 },
236 { .reg = HHI_HIFI_PLL_CNTL2, .def = 0x00000000 },
237 { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x6a285c00 },
238 { .reg = HHI_HIFI_PLL_CNTL4, .def = 0x65771290 },
239 { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x39272000 },
240 { .reg = HHI_HIFI_PLL_CNTL6, .def = 0x56540000 },
241};
242
243static struct clk_regmap g12a_hifi_pll_dco = {
244 .data = &(struct meson_clk_pll_data){
245 .en = {
246 .reg_off = HHI_HIFI_PLL_CNTL0,
247 .shift = 28,
248 .width = 1,
249 },
250 .m = {
251 .reg_off = HHI_HIFI_PLL_CNTL0,
252 .shift = 0,
253 .width = 8,
254 },
255 .n = {
256 .reg_off = HHI_HIFI_PLL_CNTL0,
257 .shift = 10,
258 .width = 5,
259 },
260 .frac = {
261 .reg_off = HHI_HIFI_PLL_CNTL1,
262 .shift = 0,
263 .width = 17,
264 },
265 .l = {
266 .reg_off = HHI_HIFI_PLL_CNTL0,
267 .shift = 31,
268 .width = 1,
269 },
270 .rst = {
271 .reg_off = HHI_HIFI_PLL_CNTL0,
272 .shift = 29,
273 .width = 1,
274 },
275 .range = &g12a_gp0_pll_mult_range,
276 .init_regs = g12a_hifi_init_regs,
277 .init_count = ARRAY_SIZE(g12a_hifi_init_regs),
278 .flags = CLK_MESON_PLL_ROUND_CLOSEST,
279 },
280 .hw.init = &(struct clk_init_data){
281 .name = "hifi_pll_dco",
282 .ops = &meson_clk_pll_ops,
283 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
284 .num_parents = 1,
285 },
286};
287
288static struct clk_regmap g12a_hifi_pll = {
289 .data = &(struct clk_regmap_div_data){
290 .offset = HHI_HIFI_PLL_CNTL0,
291 .shift = 16,
292 .width = 2,
293 .flags = (CLK_DIVIDER_POWER_OF_TWO |
294 CLK_DIVIDER_ROUND_CLOSEST),
295 },
296 .hw.init = &(struct clk_init_data){
297 .name = "hifi_pll",
298 .ops = &clk_regmap_divider_ops,
299 .parent_names = (const char *[]){ "hifi_pll_dco" },
300 .num_parents = 1,
301 .flags = CLK_SET_RATE_PARENT,
302 },
303};
304
305static struct clk_regmap g12a_hdmi_pll_dco = {
306 .data = &(struct meson_clk_pll_data){
307 .en = {
308 .reg_off = HHI_HDMI_PLL_CNTL0,
309 .shift = 28,
310 .width = 1,
311 },
312 .m = {
313 .reg_off = HHI_HDMI_PLL_CNTL0,
314 .shift = 0,
315 .width = 8,
316 },
317 .n = {
318 .reg_off = HHI_HDMI_PLL_CNTL0,
319 .shift = 10,
320 .width = 5,
321 },
322 .frac = {
323 .reg_off = HHI_HDMI_PLL_CNTL1,
324 .shift = 0,
325 .width = 16,
326 },
327 .l = {
328 .reg_off = HHI_HDMI_PLL_CNTL0,
329 .shift = 30,
330 .width = 1,
331 },
332 .rst = {
333 .reg_off = HHI_HDMI_PLL_CNTL0,
334 .shift = 29,
335 .width = 1,
336 },
337 },
338 .hw.init = &(struct clk_init_data){
339 .name = "hdmi_pll_dco",
340 .ops = &meson_clk_pll_ro_ops,
341 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
342 .num_parents = 1,
343 /*
344 * Display directly handle hdmi pll registers ATM, we need
345 * NOCACHE to keep our view of the clock as accurate as possible
346 */
347 .flags = CLK_GET_RATE_NOCACHE,
348 },
349};
350
351static struct clk_regmap g12a_hdmi_pll_od = {
352 .data = &(struct clk_regmap_div_data){
353 .offset = HHI_HDMI_PLL_CNTL0,
354 .shift = 16,
355 .width = 2,
356 .flags = CLK_DIVIDER_POWER_OF_TWO,
357 },
358 .hw.init = &(struct clk_init_data){
359 .name = "hdmi_pll_od",
360 .ops = &clk_regmap_divider_ro_ops,
361 .parent_names = (const char *[]){ "hdmi_pll_dco" },
362 .num_parents = 1,
363 .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
364 },
365};
366
367static struct clk_regmap g12a_hdmi_pll_od2 = {
368 .data = &(struct clk_regmap_div_data){
369 .offset = HHI_HDMI_PLL_CNTL0,
370 .shift = 18,
371 .width = 2,
372 .flags = CLK_DIVIDER_POWER_OF_TWO,
373 },
374 .hw.init = &(struct clk_init_data){
375 .name = "hdmi_pll_od2",
376 .ops = &clk_regmap_divider_ro_ops,
377 .parent_names = (const char *[]){ "hdmi_pll_od" },
378 .num_parents = 1,
379 .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
380 },
381};
382
383static struct clk_regmap g12a_hdmi_pll = {
384 .data = &(struct clk_regmap_div_data){
385 .offset = HHI_HDMI_PLL_CNTL0,
386 .shift = 20,
387 .width = 2,
388 .flags = CLK_DIVIDER_POWER_OF_TWO,
389 },
390 .hw.init = &(struct clk_init_data){
391 .name = "hdmi_pll",
392 .ops = &clk_regmap_divider_ro_ops,
393 .parent_names = (const char *[]){ "hdmi_pll_od2" },
394 .num_parents = 1,
395 .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
396 },
397};
398
399static struct clk_fixed_factor g12a_fclk_div2_div = {
400 .mult = 1,
401 .div = 2,
402 .hw.init = &(struct clk_init_data){
403 .name = "fclk_div2_div",
404 .ops = &clk_fixed_factor_ops,
405 .parent_names = (const char *[]){ "fixed_pll" },
406 .num_parents = 1,
407 },
408};
409
410static struct clk_regmap g12a_fclk_div2 = {
411 .data = &(struct clk_regmap_gate_data){
412 .offset = HHI_FIX_PLL_CNTL1,
413 .bit_idx = 24,
414 },
415 .hw.init = &(struct clk_init_data){
416 .name = "fclk_div2",
417 .ops = &clk_regmap_gate_ops,
418 .parent_names = (const char *[]){ "fclk_div2_div" },
419 .num_parents = 1,
420 },
421};
422
423static struct clk_fixed_factor g12a_fclk_div3_div = {
424 .mult = 1,
425 .div = 3,
426 .hw.init = &(struct clk_init_data){
427 .name = "fclk_div3_div",
428 .ops = &clk_fixed_factor_ops,
429 .parent_names = (const char *[]){ "fixed_pll" },
430 .num_parents = 1,
431 },
432};
433
434static struct clk_regmap g12a_fclk_div3 = {
435 .data = &(struct clk_regmap_gate_data){
436 .offset = HHI_FIX_PLL_CNTL1,
437 .bit_idx = 20,
438 },
439 .hw.init = &(struct clk_init_data){
440 .name = "fclk_div3",
441 .ops = &clk_regmap_gate_ops,
442 .parent_names = (const char *[]){ "fclk_div3_div" },
443 .num_parents = 1,
444 },
445};
446
447static struct clk_fixed_factor g12a_fclk_div4_div = {
448 .mult = 1,
449 .div = 4,
450 .hw.init = &(struct clk_init_data){
451 .name = "fclk_div4_div",
452 .ops = &clk_fixed_factor_ops,
453 .parent_names = (const char *[]){ "fixed_pll" },
454 .num_parents = 1,
455 },
456};
457
458static struct clk_regmap g12a_fclk_div4 = {
459 .data = &(struct clk_regmap_gate_data){
460 .offset = HHI_FIX_PLL_CNTL1,
461 .bit_idx = 21,
462 },
463 .hw.init = &(struct clk_init_data){
464 .name = "fclk_div4",
465 .ops = &clk_regmap_gate_ops,
466 .parent_names = (const char *[]){ "fclk_div4_div" },
467 .num_parents = 1,
468 },
469};
470
471static struct clk_fixed_factor g12a_fclk_div5_div = {
472 .mult = 1,
473 .div = 5,
474 .hw.init = &(struct clk_init_data){
475 .name = "fclk_div5_div",
476 .ops = &clk_fixed_factor_ops,
477 .parent_names = (const char *[]){ "fixed_pll" },
478 .num_parents = 1,
479 },
480};
481
482static struct clk_regmap g12a_fclk_div5 = {
483 .data = &(struct clk_regmap_gate_data){
484 .offset = HHI_FIX_PLL_CNTL1,
485 .bit_idx = 22,
486 },
487 .hw.init = &(struct clk_init_data){
488 .name = "fclk_div5",
489 .ops = &clk_regmap_gate_ops,
490 .parent_names = (const char *[]){ "fclk_div5_div" },
491 .num_parents = 1,
492 },
493};
494
495static struct clk_fixed_factor g12a_fclk_div7_div = {
496 .mult = 1,
497 .div = 7,
498 .hw.init = &(struct clk_init_data){
499 .name = "fclk_div7_div",
500 .ops = &clk_fixed_factor_ops,
501 .parent_names = (const char *[]){ "fixed_pll" },
502 .num_parents = 1,
503 },
504};
505
506static struct clk_regmap g12a_fclk_div7 = {
507 .data = &(struct clk_regmap_gate_data){
508 .offset = HHI_FIX_PLL_CNTL1,
509 .bit_idx = 23,
510 },
511 .hw.init = &(struct clk_init_data){
512 .name = "fclk_div7",
513 .ops = &clk_regmap_gate_ops,
514 .parent_names = (const char *[]){ "fclk_div7_div" },
515 .num_parents = 1,
516 },
517};
518
519static struct clk_fixed_factor g12a_fclk_div2p5_div = {
520 .mult = 1,
521 .div = 5,
522 .hw.init = &(struct clk_init_data){
523 .name = "fclk_div2p5_div",
524 .ops = &clk_fixed_factor_ops,
525 .parent_names = (const char *[]){ "fixed_pll_dco" },
526 .num_parents = 1,
527 },
528};
529
530static struct clk_regmap g12a_fclk_div2p5 = {
531 .data = &(struct clk_regmap_gate_data){
532 .offset = HHI_FIX_PLL_CNTL1,
533 .bit_idx = 25,
534 },
535 .hw.init = &(struct clk_init_data){
536 .name = "fclk_div2p5",
537 .ops = &clk_regmap_gate_ops,
538 .parent_names = (const char *[]){ "fclk_div2p5_div" },
539 .num_parents = 1,
540 },
541};
542
543static struct clk_fixed_factor g12a_mpll_50m_div = {
544 .mult = 1,
545 .div = 80,
546 .hw.init = &(struct clk_init_data){
547 .name = "mpll_50m_div",
548 .ops = &clk_fixed_factor_ops,
549 .parent_names = (const char *[]){ "fixed_pll_dco" },
550 .num_parents = 1,
551 },
552};
553
554static struct clk_regmap g12a_mpll_50m = {
555 .data = &(struct clk_regmap_mux_data){
556 .offset = HHI_FIX_PLL_CNTL3,
557 .mask = 0x1,
558 .shift = 5,
559 },
560 .hw.init = &(struct clk_init_data){
561 .name = "mpll_50m",
562 .ops = &clk_regmap_mux_ro_ops,
563 .parent_names = (const char *[]){ IN_PREFIX "xtal",
564 "mpll_50m_div" },
565 .num_parents = 2,
566 },
567};
568
569static struct clk_fixed_factor g12a_mpll_prediv = {
570 .mult = 1,
571 .div = 2,
572 .hw.init = &(struct clk_init_data){
573 .name = "mpll_prediv",
574 .ops = &clk_fixed_factor_ops,
575 .parent_names = (const char *[]){ "fixed_pll_dco" },
576 .num_parents = 1,
577 },
578};
579
580static struct clk_regmap g12a_mpll0_div = {
581 .data = &(struct meson_clk_mpll_data){
582 .sdm = {
583 .reg_off = HHI_MPLL_CNTL1,
584 .shift = 0,
585 .width = 14,
586 },
587 .sdm_en = {
588 .reg_off = HHI_MPLL_CNTL1,
589 .shift = 30,
590 .width = 1,
591 },
592 .n2 = {
593 .reg_off = HHI_MPLL_CNTL1,
594 .shift = 20,
595 .width = 9,
596 },
597 .ssen = {
598 .reg_off = HHI_MPLL_CNTL1,
599 .shift = 29,
600 .width = 1,
601 },
602 .lock = &meson_clk_lock,
603 },
604 .hw.init = &(struct clk_init_data){
605 .name = "mpll0_div",
606 .ops = &meson_clk_mpll_ops,
607 .parent_names = (const char *[]){ "mpll_prediv" },
608 .num_parents = 1,
609 },
610};
611
612static struct clk_regmap g12a_mpll0 = {
613 .data = &(struct clk_regmap_gate_data){
614 .offset = HHI_MPLL_CNTL1,
615 .bit_idx = 31,
616 },
617 .hw.init = &(struct clk_init_data){
618 .name = "mpll0",
619 .ops = &clk_regmap_gate_ops,
620 .parent_names = (const char *[]){ "mpll0_div" },
621 .num_parents = 1,
622 .flags = CLK_SET_RATE_PARENT,
623 },
624};
625
626static struct clk_regmap g12a_mpll1_div = {
627 .data = &(struct meson_clk_mpll_data){
628 .sdm = {
629 .reg_off = HHI_MPLL_CNTL3,
630 .shift = 0,
631 .width = 14,
632 },
633 .sdm_en = {
634 .reg_off = HHI_MPLL_CNTL3,
635 .shift = 30,
636 .width = 1,
637 },
638 .n2 = {
639 .reg_off = HHI_MPLL_CNTL3,
640 .shift = 20,
641 .width = 9,
642 },
643 .ssen = {
644 .reg_off = HHI_MPLL_CNTL3,
645 .shift = 29,
646 .width = 1,
647 },
648 .lock = &meson_clk_lock,
649 },
650 .hw.init = &(struct clk_init_data){
651 .name = "mpll1_div",
652 .ops = &meson_clk_mpll_ops,
653 .parent_names = (const char *[]){ "mpll_prediv" },
654 .num_parents = 1,
655 },
656};
657
658static struct clk_regmap g12a_mpll1 = {
659 .data = &(struct clk_regmap_gate_data){
660 .offset = HHI_MPLL_CNTL3,
661 .bit_idx = 31,
662 },
663 .hw.init = &(struct clk_init_data){
664 .name = "mpll1",
665 .ops = &clk_regmap_gate_ops,
666 .parent_names = (const char *[]){ "mpll1_div" },
667 .num_parents = 1,
668 .flags = CLK_SET_RATE_PARENT,
669 },
670};
671
672static struct clk_regmap g12a_mpll2_div = {
673 .data = &(struct meson_clk_mpll_data){
674 .sdm = {
675 .reg_off = HHI_MPLL_CNTL5,
676 .shift = 0,
677 .width = 14,
678 },
679 .sdm_en = {
680 .reg_off = HHI_MPLL_CNTL5,
681 .shift = 30,
682 .width = 1,
683 },
684 .n2 = {
685 .reg_off = HHI_MPLL_CNTL5,
686 .shift = 20,
687 .width = 9,
688 },
689 .ssen = {
690 .reg_off = HHI_MPLL_CNTL5,
691 .shift = 29,
692 .width = 1,
693 },
694 .lock = &meson_clk_lock,
695 },
696 .hw.init = &(struct clk_init_data){
697 .name = "mpll2_div",
698 .ops = &meson_clk_mpll_ops,
699 .parent_names = (const char *[]){ "mpll_prediv" },
700 .num_parents = 1,
701 },
702};
703
704static struct clk_regmap g12a_mpll2 = {
705 .data = &(struct clk_regmap_gate_data){
706 .offset = HHI_MPLL_CNTL5,
707 .bit_idx = 31,
708 },
709 .hw.init = &(struct clk_init_data){
710 .name = "mpll2",
711 .ops = &clk_regmap_gate_ops,
712 .parent_names = (const char *[]){ "mpll2_div" },
713 .num_parents = 1,
714 .flags = CLK_SET_RATE_PARENT,
715 },
716};
717
718static struct clk_regmap g12a_mpll3_div = {
719 .data = &(struct meson_clk_mpll_data){
720 .sdm = {
721 .reg_off = HHI_MPLL_CNTL7,
722 .shift = 0,
723 .width = 14,
724 },
725 .sdm_en = {
726 .reg_off = HHI_MPLL_CNTL7,
727 .shift = 30,
728 .width = 1,
729 },
730 .n2 = {
731 .reg_off = HHI_MPLL_CNTL7,
732 .shift = 20,
733 .width = 9,
734 },
735 .ssen = {
736 .reg_off = HHI_MPLL_CNTL7,
737 .shift = 29,
738 .width = 1,
739 },
740 .lock = &meson_clk_lock,
741 },
742 .hw.init = &(struct clk_init_data){
743 .name = "mpll3_div",
744 .ops = &meson_clk_mpll_ops,
745 .parent_names = (const char *[]){ "mpll_prediv" },
746 .num_parents = 1,
747 },
748};
749
750static struct clk_regmap g12a_mpll3 = {
751 .data = &(struct clk_regmap_gate_data){
752 .offset = HHI_MPLL_CNTL7,
753 .bit_idx = 31,
754 },
755 .hw.init = &(struct clk_init_data){
756 .name = "mpll3",
757 .ops = &clk_regmap_gate_ops,
758 .parent_names = (const char *[]){ "mpll3_div" },
759 .num_parents = 1,
760 .flags = CLK_SET_RATE_PARENT,
761 },
762};
763
764static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 };
765static const char * const clk81_parent_names[] = {
766 IN_PREFIX "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
767 "fclk_div3", "fclk_div5"
768};
769
770static struct clk_regmap g12a_mpeg_clk_sel = {
771 .data = &(struct clk_regmap_mux_data){
772 .offset = HHI_MPEG_CLK_CNTL,
773 .mask = 0x7,
774 .shift = 12,
775 .table = mux_table_clk81,
776 },
777 .hw.init = &(struct clk_init_data){
778 .name = "mpeg_clk_sel",
779 .ops = &clk_regmap_mux_ro_ops,
780 .parent_names = clk81_parent_names,
781 .num_parents = ARRAY_SIZE(clk81_parent_names),
782 },
783};
784
785static struct clk_regmap g12a_mpeg_clk_div = {
786 .data = &(struct clk_regmap_div_data){
787 .offset = HHI_MPEG_CLK_CNTL,
788 .shift = 0,
789 .width = 7,
790 },
791 .hw.init = &(struct clk_init_data){
792 .name = "mpeg_clk_div",
793 .ops = &clk_regmap_divider_ops,
794 .parent_names = (const char *[]){ "mpeg_clk_sel" },
795 .num_parents = 1,
796 .flags = CLK_SET_RATE_PARENT,
797 },
798};
799
800static struct clk_regmap g12a_clk81 = {
801 .data = &(struct clk_regmap_gate_data){
802 .offset = HHI_MPEG_CLK_CNTL,
803 .bit_idx = 7,
804 },
805 .hw.init = &(struct clk_init_data){
806 .name = "clk81",
807 .ops = &clk_regmap_gate_ops,
808 .parent_names = (const char *[]){ "mpeg_clk_div" },
809 .num_parents = 1,
810 .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
811 },
812};
813
814static const char * const g12a_sd_emmc_clk0_parent_names[] = {
815 IN_PREFIX "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
816
817 /*
818 * Following these parent clocks, we should also have had mpll2, mpll3
819 * and gp0_pll but these clocks are too precious to be used here. All
820 * the necessary rates for MMC and NAND operation can be acheived using
821 * g12a_ee_core or fclk_div clocks
822 */
823};
824
825/* SDIO clock */
826static struct clk_regmap g12a_sd_emmc_a_clk0_sel = {
827 .data = &(struct clk_regmap_mux_data){
828 .offset = HHI_SD_EMMC_CLK_CNTL,
829 .mask = 0x7,
830 .shift = 9,
831 },
832 .hw.init = &(struct clk_init_data) {
833 .name = "sd_emmc_a_clk0_sel",
834 .ops = &clk_regmap_mux_ops,
835 .parent_names = g12a_sd_emmc_clk0_parent_names,
836 .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_names),
837 .flags = CLK_SET_RATE_PARENT,
838 },
839};
840
841static struct clk_regmap g12a_sd_emmc_a_clk0_div = {
842 .data = &(struct clk_regmap_div_data){
843 .offset = HHI_SD_EMMC_CLK_CNTL,
844 .shift = 0,
845 .width = 7,
846 },
847 .hw.init = &(struct clk_init_data) {
848 .name = "sd_emmc_a_clk0_div",
849 .ops = &clk_regmap_divider_ops,
850 .parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" },
851 .num_parents = 1,
852 .flags = CLK_SET_RATE_PARENT,
853 },
854};
855
856static struct clk_regmap g12a_sd_emmc_a_clk0 = {
857 .data = &(struct clk_regmap_gate_data){
858 .offset = HHI_SD_EMMC_CLK_CNTL,
859 .bit_idx = 7,
860 },
861 .hw.init = &(struct clk_init_data){
862 .name = "sd_emmc_a_clk0",
863 .ops = &clk_regmap_gate_ops,
864 .parent_names = (const char *[]){ "sd_emmc_a_clk0_div" },
865 .num_parents = 1,
866 .flags = CLK_SET_RATE_PARENT,
867 },
868};
869
870/* SDcard clock */
871static struct clk_regmap g12a_sd_emmc_b_clk0_sel = {
872 .data = &(struct clk_regmap_mux_data){
873 .offset = HHI_SD_EMMC_CLK_CNTL,
874 .mask = 0x7,
875 .shift = 25,
876 },
877 .hw.init = &(struct clk_init_data) {
878 .name = "sd_emmc_b_clk0_sel",
879 .ops = &clk_regmap_mux_ops,
880 .parent_names = g12a_sd_emmc_clk0_parent_names,
881 .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_names),
882 .flags = CLK_SET_RATE_PARENT,
883 },
884};
885
886static struct clk_regmap g12a_sd_emmc_b_clk0_div = {
887 .data = &(struct clk_regmap_div_data){
888 .offset = HHI_SD_EMMC_CLK_CNTL,
889 .shift = 16,
890 .width = 7,
891 },
892 .hw.init = &(struct clk_init_data) {
893 .name = "sd_emmc_b_clk0_div",
894 .ops = &clk_regmap_divider_ops,
895 .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
896 .num_parents = 1,
897 .flags = CLK_SET_RATE_PARENT,
898 },
899};
900
901static struct clk_regmap g12a_sd_emmc_b_clk0 = {
902 .data = &(struct clk_regmap_gate_data){
903 .offset = HHI_SD_EMMC_CLK_CNTL,
904 .bit_idx = 23,
905 },
906 .hw.init = &(struct clk_init_data){
907 .name = "sd_emmc_b_clk0",
908 .ops = &clk_regmap_gate_ops,
909 .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
910 .num_parents = 1,
911 .flags = CLK_SET_RATE_PARENT,
912 },
913};
914
915/* EMMC/NAND clock */
916static struct clk_regmap g12a_sd_emmc_c_clk0_sel = {
917 .data = &(struct clk_regmap_mux_data){
918 .offset = HHI_NAND_CLK_CNTL,
919 .mask = 0x7,
920 .shift = 9,
921 },
922 .hw.init = &(struct clk_init_data) {
923 .name = "sd_emmc_c_clk0_sel",
924 .ops = &clk_regmap_mux_ops,
925 .parent_names = g12a_sd_emmc_clk0_parent_names,
926 .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_names),
927 .flags = CLK_SET_RATE_PARENT,
928 },
929};
930
931static struct clk_regmap g12a_sd_emmc_c_clk0_div = {
932 .data = &(struct clk_regmap_div_data){
933 .offset = HHI_NAND_CLK_CNTL,
934 .shift = 0,
935 .width = 7,
936 },
937 .hw.init = &(struct clk_init_data) {
938 .name = "sd_emmc_c_clk0_div",
939 .ops = &clk_regmap_divider_ops,
940 .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
941 .num_parents = 1,
942 .flags = CLK_SET_RATE_PARENT,
943 },
944};
945
946static struct clk_regmap g12a_sd_emmc_c_clk0 = {
947 .data = &(struct clk_regmap_gate_data){
948 .offset = HHI_NAND_CLK_CNTL,
949 .bit_idx = 7,
950 },
951 .hw.init = &(struct clk_init_data){
952 .name = "sd_emmc_c_clk0",
953 .ops = &clk_regmap_gate_ops,
954 .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
955 .num_parents = 1,
956 .flags = CLK_SET_RATE_PARENT,
957 },
958};
959
960/* VPU Clock */
961
962static const char * const g12a_vpu_parent_names[] = {
963 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7",
964 "mpll1", "vid_pll", "hifi_pll", "gp0_pll",
965};
966
967static struct clk_regmap g12a_vpu_0_sel = {
968 .data = &(struct clk_regmap_mux_data){
969 .offset = HHI_VPU_CLK_CNTL,
970 .mask = 0x3,
971 .shift = 9,
972 },
973 .hw.init = &(struct clk_init_data){
974 .name = "vpu_0_sel",
975 .ops = &clk_regmap_mux_ops,
976 .parent_names = g12a_vpu_parent_names,
977 .num_parents = ARRAY_SIZE(g12a_vpu_parent_names),
978 .flags = CLK_SET_RATE_NO_REPARENT,
979 },
980};
981
982static struct clk_regmap g12a_vpu_0_div = {
983 .data = &(struct clk_regmap_div_data){
984 .offset = HHI_VPU_CLK_CNTL,
985 .shift = 0,
986 .width = 7,
987 },
988 .hw.init = &(struct clk_init_data){
989 .name = "vpu_0_div",
990 .ops = &clk_regmap_divider_ops,
991 .parent_names = (const char *[]){ "vpu_0_sel" },
992 .num_parents = 1,
993 .flags = CLK_SET_RATE_PARENT,
994 },
995};
996
997static struct clk_regmap g12a_vpu_0 = {
998 .data = &(struct clk_regmap_gate_data){
999 .offset = HHI_VPU_CLK_CNTL,
1000 .bit_idx = 8,
1001 },
1002 .hw.init = &(struct clk_init_data) {
1003 .name = "vpu_0",
1004 .ops = &clk_regmap_gate_ops,
1005 .parent_names = (const char *[]){ "vpu_0_div" },
1006 .num_parents = 1,
1007 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1008 },
1009};
1010
1011static struct clk_regmap g12a_vpu_1_sel = {
1012 .data = &(struct clk_regmap_mux_data){
1013 .offset = HHI_VPU_CLK_CNTL,
1014 .mask = 0x3,
1015 .shift = 25,
1016 },
1017 .hw.init = &(struct clk_init_data){
1018 .name = "vpu_1_sel",
1019 .ops = &clk_regmap_mux_ops,
1020 .parent_names = g12a_vpu_parent_names,
1021 .num_parents = ARRAY_SIZE(g12a_vpu_parent_names),
1022 .flags = CLK_SET_RATE_NO_REPARENT,
1023 },
1024};
1025
1026static struct clk_regmap g12a_vpu_1_div = {
1027 .data = &(struct clk_regmap_div_data){
1028 .offset = HHI_VPU_CLK_CNTL,
1029 .shift = 16,
1030 .width = 7,
1031 },
1032 .hw.init = &(struct clk_init_data){
1033 .name = "vpu_1_div",
1034 .ops = &clk_regmap_divider_ops,
1035 .parent_names = (const char *[]){ "vpu_1_sel" },
1036 .num_parents = 1,
1037 .flags = CLK_SET_RATE_PARENT,
1038 },
1039};
1040
1041static struct clk_regmap g12a_vpu_1 = {
1042 .data = &(struct clk_regmap_gate_data){
1043 .offset = HHI_VPU_CLK_CNTL,
1044 .bit_idx = 24,
1045 },
1046 .hw.init = &(struct clk_init_data) {
1047 .name = "vpu_1",
1048 .ops = &clk_regmap_gate_ops,
1049 .parent_names = (const char *[]){ "vpu_1_div" },
1050 .num_parents = 1,
1051 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1052 },
1053};
1054
1055static struct clk_regmap g12a_vpu = {
1056 .data = &(struct clk_regmap_mux_data){
1057 .offset = HHI_VPU_CLK_CNTL,
1058 .mask = 1,
1059 .shift = 31,
1060 },
1061 .hw.init = &(struct clk_init_data){
1062 .name = "vpu",
1063 .ops = &clk_regmap_mux_ops,
1064 /*
1065 * bit 31 selects from 2 possible parents:
1066 * vpu_0 or vpu_1
1067 */
1068 .parent_names = (const char *[]){ "vpu_0", "vpu_1" },
1069 .num_parents = 2,
1070 .flags = CLK_SET_RATE_NO_REPARENT,
1071 },
1072};
1073
1074/* VAPB Clock */
1075
1076static const char * const g12a_vapb_parent_names[] = {
1077 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7",
1078 "mpll1", "vid_pll", "mpll2", "fclk_div2p5",
1079};
1080
1081static struct clk_regmap g12a_vapb_0_sel = {
1082 .data = &(struct clk_regmap_mux_data){
1083 .offset = HHI_VAPBCLK_CNTL,
1084 .mask = 0x3,
1085 .shift = 9,
1086 },
1087 .hw.init = &(struct clk_init_data){
1088 .name = "vapb_0_sel",
1089 .ops = &clk_regmap_mux_ops,
1090 .parent_names = g12a_vapb_parent_names,
1091 .num_parents = ARRAY_SIZE(g12a_vapb_parent_names),
1092 .flags = CLK_SET_RATE_NO_REPARENT,
1093 },
1094};
1095
1096static struct clk_regmap g12a_vapb_0_div = {
1097 .data = &(struct clk_regmap_div_data){
1098 .offset = HHI_VAPBCLK_CNTL,
1099 .shift = 0,
1100 .width = 7,
1101 },
1102 .hw.init = &(struct clk_init_data){
1103 .name = "vapb_0_div",
1104 .ops = &clk_regmap_divider_ops,
1105 .parent_names = (const char *[]){ "vapb_0_sel" },
1106 .num_parents = 1,
1107 .flags = CLK_SET_RATE_PARENT,
1108 },
1109};
1110
1111static struct clk_regmap g12a_vapb_0 = {
1112 .data = &(struct clk_regmap_gate_data){
1113 .offset = HHI_VAPBCLK_CNTL,
1114 .bit_idx = 8,
1115 },
1116 .hw.init = &(struct clk_init_data) {
1117 .name = "vapb_0",
1118 .ops = &clk_regmap_gate_ops,
1119 .parent_names = (const char *[]){ "vapb_0_div" },
1120 .num_parents = 1,
1121 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1122 },
1123};
1124
1125static struct clk_regmap g12a_vapb_1_sel = {
1126 .data = &(struct clk_regmap_mux_data){
1127 .offset = HHI_VAPBCLK_CNTL,
1128 .mask = 0x3,
1129 .shift = 25,
1130 },
1131 .hw.init = &(struct clk_init_data){
1132 .name = "vapb_1_sel",
1133 .ops = &clk_regmap_mux_ops,
1134 .parent_names = g12a_vapb_parent_names,
1135 .num_parents = ARRAY_SIZE(g12a_vapb_parent_names),
1136 .flags = CLK_SET_RATE_NO_REPARENT,
1137 },
1138};
1139
1140static struct clk_regmap g12a_vapb_1_div = {
1141 .data = &(struct clk_regmap_div_data){
1142 .offset = HHI_VAPBCLK_CNTL,
1143 .shift = 16,
1144 .width = 7,
1145 },
1146 .hw.init = &(struct clk_init_data){
1147 .name = "vapb_1_div",
1148 .ops = &clk_regmap_divider_ops,
1149 .parent_names = (const char *[]){ "vapb_1_sel" },
1150 .num_parents = 1,
1151 .flags = CLK_SET_RATE_PARENT,
1152 },
1153};
1154
1155static struct clk_regmap g12a_vapb_1 = {
1156 .data = &(struct clk_regmap_gate_data){
1157 .offset = HHI_VAPBCLK_CNTL,
1158 .bit_idx = 24,
1159 },
1160 .hw.init = &(struct clk_init_data) {
1161 .name = "vapb_1",
1162 .ops = &clk_regmap_gate_ops,
1163 .parent_names = (const char *[]){ "vapb_1_div" },
1164 .num_parents = 1,
1165 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1166 },
1167};
1168
1169static struct clk_regmap g12a_vapb_sel = {
1170 .data = &(struct clk_regmap_mux_data){
1171 .offset = HHI_VAPBCLK_CNTL,
1172 .mask = 1,
1173 .shift = 31,
1174 },
1175 .hw.init = &(struct clk_init_data){
1176 .name = "vapb_sel",
1177 .ops = &clk_regmap_mux_ops,
1178 /*
1179 * bit 31 selects from 2 possible parents:
1180 * vapb_0 or vapb_1
1181 */
1182 .parent_names = (const char *[]){ "vapb_0", "vapb_1" },
1183 .num_parents = 2,
1184 .flags = CLK_SET_RATE_NO_REPARENT,
1185 },
1186};
1187
1188static struct clk_regmap g12a_vapb = {
1189 .data = &(struct clk_regmap_gate_data){
1190 .offset = HHI_VAPBCLK_CNTL,
1191 .bit_idx = 30,
1192 },
1193 .hw.init = &(struct clk_init_data) {
1194 .name = "vapb",
1195 .ops = &clk_regmap_gate_ops,
1196 .parent_names = (const char *[]){ "vapb_sel" },
1197 .num_parents = 1,
1198 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1199 },
1200};
1201
1202/* Video Clocks */
1203
1204static struct clk_regmap g12a_vid_pll_div = {
1205 .data = &(struct meson_vid_pll_div_data){
1206 .val = {
1207 .reg_off = HHI_VID_PLL_CLK_DIV,
1208 .shift = 0,
1209 .width = 15,
1210 },
1211 .sel = {
1212 .reg_off = HHI_VID_PLL_CLK_DIV,
1213 .shift = 16,
1214 .width = 2,
1215 },
1216 },
1217 .hw.init = &(struct clk_init_data) {
1218 .name = "vid_pll_div",
1219 .ops = &meson_vid_pll_div_ro_ops,
1220 .parent_names = (const char *[]){ "hdmi_pll" },
1221 .num_parents = 1,
1222 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
1223 },
1224};
1225
1226static const char * const g12a_vid_pll_parent_names[] = { "vid_pll_div",
1227 "hdmi_pll" };
1228
1229static struct clk_regmap g12a_vid_pll_sel = {
1230 .data = &(struct clk_regmap_mux_data){
1231 .offset = HHI_VID_PLL_CLK_DIV,
1232 .mask = 0x1,
1233 .shift = 18,
1234 },
1235 .hw.init = &(struct clk_init_data){
1236 .name = "vid_pll_sel",
1237 .ops = &clk_regmap_mux_ops,
1238 /*
1239 * bit 18 selects from 2 possible parents:
1240 * vid_pll_div or hdmi_pll
1241 */
1242 .parent_names = g12a_vid_pll_parent_names,
1243 .num_parents = ARRAY_SIZE(g12a_vid_pll_parent_names),
1244 .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
1245 },
1246};
1247
1248static struct clk_regmap g12a_vid_pll = {
1249 .data = &(struct clk_regmap_gate_data){
1250 .offset = HHI_VID_PLL_CLK_DIV,
1251 .bit_idx = 19,
1252 },
1253 .hw.init = &(struct clk_init_data) {
1254 .name = "vid_pll",
1255 .ops = &clk_regmap_gate_ops,
1256 .parent_names = (const char *[]){ "vid_pll_sel" },
1257 .num_parents = 1,
1258 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1259 },
1260};
1261
1262static const char * const g12a_vclk_parent_names[] = {
1263 "vid_pll", "gp0_pll", "hifi_pll", "mpll1", "fclk_div3", "fclk_div4",
1264 "fclk_div5", "fclk_div7"
1265};
1266
1267static struct clk_regmap g12a_vclk_sel = {
1268 .data = &(struct clk_regmap_mux_data){
1269 .offset = HHI_VID_CLK_CNTL,
1270 .mask = 0x7,
1271 .shift = 16,
1272 },
1273 .hw.init = &(struct clk_init_data){
1274 .name = "vclk_sel",
1275 .ops = &clk_regmap_mux_ops,
1276 .parent_names = g12a_vclk_parent_names,
1277 .num_parents = ARRAY_SIZE(g12a_vclk_parent_names),
1278 .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
1279 },
1280};
1281
1282static struct clk_regmap g12a_vclk2_sel = {
1283 .data = &(struct clk_regmap_mux_data){
1284 .offset = HHI_VIID_CLK_CNTL,
1285 .mask = 0x7,
1286 .shift = 16,
1287 },
1288 .hw.init = &(struct clk_init_data){
1289 .name = "vclk2_sel",
1290 .ops = &clk_regmap_mux_ops,
1291 .parent_names = g12a_vclk_parent_names,
1292 .num_parents = ARRAY_SIZE(g12a_vclk_parent_names),
1293 .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
1294 },
1295};
1296
1297static struct clk_regmap g12a_vclk_input = {
1298 .data = &(struct clk_regmap_gate_data){
1299 .offset = HHI_VID_CLK_DIV,
1300 .bit_idx = 16,
1301 },
1302 .hw.init = &(struct clk_init_data) {
1303 .name = "vclk_input",
1304 .ops = &clk_regmap_gate_ops,
1305 .parent_names = (const char *[]){ "vclk_sel" },
1306 .num_parents = 1,
1307 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1308 },
1309};
1310
1311static struct clk_regmap g12a_vclk2_input = {
1312 .data = &(struct clk_regmap_gate_data){
1313 .offset = HHI_VIID_CLK_DIV,
1314 .bit_idx = 16,
1315 },
1316 .hw.init = &(struct clk_init_data) {
1317 .name = "vclk2_input",
1318 .ops = &clk_regmap_gate_ops,
1319 .parent_names = (const char *[]){ "vclk2_sel" },
1320 .num_parents = 1,
1321 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1322 },
1323};
1324
1325static struct clk_regmap g12a_vclk_div = {
1326 .data = &(struct clk_regmap_div_data){
1327 .offset = HHI_VID_CLK_DIV,
1328 .shift = 0,
1329 .width = 8,
1330 },
1331 .hw.init = &(struct clk_init_data){
1332 .name = "vclk_div",
1333 .ops = &clk_regmap_divider_ops,
1334 .parent_names = (const char *[]){ "vclk_input" },
1335 .num_parents = 1,
1336 .flags = CLK_GET_RATE_NOCACHE,
1337 },
1338};
1339
1340static struct clk_regmap g12a_vclk2_div = {
1341 .data = &(struct clk_regmap_div_data){
1342 .offset = HHI_VIID_CLK_DIV,
1343 .shift = 0,
1344 .width = 8,
1345 },
1346 .hw.init = &(struct clk_init_data){
1347 .name = "vclk2_div",
1348 .ops = &clk_regmap_divider_ops,
1349 .parent_names = (const char *[]){ "vclk2_input" },
1350 .num_parents = 1,
1351 .flags = CLK_GET_RATE_NOCACHE,
1352 },
1353};
1354
1355static struct clk_regmap g12a_vclk = {
1356 .data = &(struct clk_regmap_gate_data){
1357 .offset = HHI_VID_CLK_CNTL,
1358 .bit_idx = 19,
1359 },
1360 .hw.init = &(struct clk_init_data) {
1361 .name = "vclk",
1362 .ops = &clk_regmap_gate_ops,
1363 .parent_names = (const char *[]){ "vclk_div" },
1364 .num_parents = 1,
1365 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1366 },
1367};
1368
1369static struct clk_regmap g12a_vclk2 = {
1370 .data = &(struct clk_regmap_gate_data){
1371 .offset = HHI_VIID_CLK_CNTL,
1372 .bit_idx = 19,
1373 },
1374 .hw.init = &(struct clk_init_data) {
1375 .name = "vclk2",
1376 .ops = &clk_regmap_gate_ops,
1377 .parent_names = (const char *[]){ "vclk2_div" },
1378 .num_parents = 1,
1379 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1380 },
1381};
1382
1383static struct clk_regmap g12a_vclk_div1 = {
1384 .data = &(struct clk_regmap_gate_data){
1385 .offset = HHI_VID_CLK_CNTL,
1386 .bit_idx = 0,
1387 },
1388 .hw.init = &(struct clk_init_data) {
1389 .name = "vclk_div1",
1390 .ops = &clk_regmap_gate_ops,
1391 .parent_names = (const char *[]){ "vclk" },
1392 .num_parents = 1,
1393 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1394 },
1395};
1396
1397static struct clk_regmap g12a_vclk_div2_en = {
1398 .data = &(struct clk_regmap_gate_data){
1399 .offset = HHI_VID_CLK_CNTL,
1400 .bit_idx = 1,
1401 },
1402 .hw.init = &(struct clk_init_data) {
1403 .name = "vclk_div2_en",
1404 .ops = &clk_regmap_gate_ops,
1405 .parent_names = (const char *[]){ "vclk" },
1406 .num_parents = 1,
1407 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1408 },
1409};
1410
1411static struct clk_regmap g12a_vclk_div4_en = {
1412 .data = &(struct clk_regmap_gate_data){
1413 .offset = HHI_VID_CLK_CNTL,
1414 .bit_idx = 2,
1415 },
1416 .hw.init = &(struct clk_init_data) {
1417 .name = "vclk_div4_en",
1418 .ops = &clk_regmap_gate_ops,
1419 .parent_names = (const char *[]){ "vclk" },
1420 .num_parents = 1,
1421 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1422 },
1423};
1424
1425static struct clk_regmap g12a_vclk_div6_en = {
1426 .data = &(struct clk_regmap_gate_data){
1427 .offset = HHI_VID_CLK_CNTL,
1428 .bit_idx = 3,
1429 },
1430 .hw.init = &(struct clk_init_data) {
1431 .name = "vclk_div6_en",
1432 .ops = &clk_regmap_gate_ops,
1433 .parent_names = (const char *[]){ "vclk" },
1434 .num_parents = 1,
1435 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1436 },
1437};
1438
1439static struct clk_regmap g12a_vclk_div12_en = {
1440 .data = &(struct clk_regmap_gate_data){
1441 .offset = HHI_VID_CLK_CNTL,
1442 .bit_idx = 4,
1443 },
1444 .hw.init = &(struct clk_init_data) {
1445 .name = "vclk_div12_en",
1446 .ops = &clk_regmap_gate_ops,
1447 .parent_names = (const char *[]){ "vclk" },
1448 .num_parents = 1,
1449 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1450 },
1451};
1452
1453static struct clk_regmap g12a_vclk2_div1 = {
1454 .data = &(struct clk_regmap_gate_data){
1455 .offset = HHI_VIID_CLK_CNTL,
1456 .bit_idx = 0,
1457 },
1458 .hw.init = &(struct clk_init_data) {
1459 .name = "vclk2_div1",
1460 .ops = &clk_regmap_gate_ops,
1461 .parent_names = (const char *[]){ "vclk2" },
1462 .num_parents = 1,
1463 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1464 },
1465};
1466
1467static struct clk_regmap g12a_vclk2_div2_en = {
1468 .data = &(struct clk_regmap_gate_data){
1469 .offset = HHI_VIID_CLK_CNTL,
1470 .bit_idx = 1,
1471 },
1472 .hw.init = &(struct clk_init_data) {
1473 .name = "vclk2_div2_en",
1474 .ops = &clk_regmap_gate_ops,
1475 .parent_names = (const char *[]){ "vclk2" },
1476 .num_parents = 1,
1477 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1478 },
1479};
1480
1481static struct clk_regmap g12a_vclk2_div4_en = {
1482 .data = &(struct clk_regmap_gate_data){
1483 .offset = HHI_VIID_CLK_CNTL,
1484 .bit_idx = 2,
1485 },
1486 .hw.init = &(struct clk_init_data) {
1487 .name = "vclk2_div4_en",
1488 .ops = &clk_regmap_gate_ops,
1489 .parent_names = (const char *[]){ "vclk2" },
1490 .num_parents = 1,
1491 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1492 },
1493};
1494
1495static struct clk_regmap g12a_vclk2_div6_en = {
1496 .data = &(struct clk_regmap_gate_data){
1497 .offset = HHI_VIID_CLK_CNTL,
1498 .bit_idx = 3,
1499 },
1500 .hw.init = &(struct clk_init_data) {
1501 .name = "vclk2_div6_en",
1502 .ops = &clk_regmap_gate_ops,
1503 .parent_names = (const char *[]){ "vclk2" },
1504 .num_parents = 1,
1505 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1506 },
1507};
1508
1509static struct clk_regmap g12a_vclk2_div12_en = {
1510 .data = &(struct clk_regmap_gate_data){
1511 .offset = HHI_VIID_CLK_CNTL,
1512 .bit_idx = 4,
1513 },
1514 .hw.init = &(struct clk_init_data) {
1515 .name = "vclk2_div12_en",
1516 .ops = &clk_regmap_gate_ops,
1517 .parent_names = (const char *[]){ "vclk2" },
1518 .num_parents = 1,
1519 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1520 },
1521};
1522
1523static struct clk_fixed_factor g12a_vclk_div2 = {
1524 .mult = 1,
1525 .div = 2,
1526 .hw.init = &(struct clk_init_data){
1527 .name = "vclk_div2",
1528 .ops = &clk_fixed_factor_ops,
1529 .parent_names = (const char *[]){ "vclk_div2_en" },
1530 .num_parents = 1,
1531 },
1532};
1533
1534static struct clk_fixed_factor g12a_vclk_div4 = {
1535 .mult = 1,
1536 .div = 4,
1537 .hw.init = &(struct clk_init_data){
1538 .name = "vclk_div4",
1539 .ops = &clk_fixed_factor_ops,
1540 .parent_names = (const char *[]){ "vclk_div4_en" },
1541 .num_parents = 1,
1542 },
1543};
1544
1545static struct clk_fixed_factor g12a_vclk_div6 = {
1546 .mult = 1,
1547 .div = 6,
1548 .hw.init = &(struct clk_init_data){
1549 .name = "vclk_div6",
1550 .ops = &clk_fixed_factor_ops,
1551 .parent_names = (const char *[]){ "vclk_div6_en" },
1552 .num_parents = 1,
1553 },
1554};
1555
1556static struct clk_fixed_factor g12a_vclk_div12 = {
1557 .mult = 1,
1558 .div = 12,
1559 .hw.init = &(struct clk_init_data){
1560 .name = "vclk_div12",
1561 .ops = &clk_fixed_factor_ops,
1562 .parent_names = (const char *[]){ "vclk_div12_en" },
1563 .num_parents = 1,
1564 },
1565};
1566
1567static struct clk_fixed_factor g12a_vclk2_div2 = {
1568 .mult = 1,
1569 .div = 2,
1570 .hw.init = &(struct clk_init_data){
1571 .name = "vclk2_div2",
1572 .ops = &clk_fixed_factor_ops,
1573 .parent_names = (const char *[]){ "vclk2_div2_en" },
1574 .num_parents = 1,
1575 },
1576};
1577
1578static struct clk_fixed_factor g12a_vclk2_div4 = {
1579 .mult = 1,
1580 .div = 4,
1581 .hw.init = &(struct clk_init_data){
1582 .name = "vclk2_div4",
1583 .ops = &clk_fixed_factor_ops,
1584 .parent_names = (const char *[]){ "vclk2_div4_en" },
1585 .num_parents = 1,
1586 },
1587};
1588
1589static struct clk_fixed_factor g12a_vclk2_div6 = {
1590 .mult = 1,
1591 .div = 6,
1592 .hw.init = &(struct clk_init_data){
1593 .name = "vclk2_div6",
1594 .ops = &clk_fixed_factor_ops,
1595 .parent_names = (const char *[]){ "vclk2_div6_en" },
1596 .num_parents = 1,
1597 },
1598};
1599
1600static struct clk_fixed_factor g12a_vclk2_div12 = {
1601 .mult = 1,
1602 .div = 12,
1603 .hw.init = &(struct clk_init_data){
1604 .name = "vclk2_div12",
1605 .ops = &clk_fixed_factor_ops,
1606 .parent_names = (const char *[]){ "vclk2_div12_en" },
1607 .num_parents = 1,
1608 },
1609};
1610
1611static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
1612static const char * const g12a_cts_parent_names[] = {
1613 "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6",
1614 "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4",
1615 "vclk2_div6", "vclk2_div12"
1616};
1617
1618static struct clk_regmap g12a_cts_enci_sel = {
1619 .data = &(struct clk_regmap_mux_data){
1620 .offset = HHI_VID_CLK_DIV,
1621 .mask = 0xf,
1622 .shift = 28,
1623 .table = mux_table_cts_sel,
1624 },
1625 .hw.init = &(struct clk_init_data){
1626 .name = "cts_enci_sel",
1627 .ops = &clk_regmap_mux_ops,
1628 .parent_names = g12a_cts_parent_names,
1629 .num_parents = ARRAY_SIZE(g12a_cts_parent_names),
1630 .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
1631 },
1632};
1633
1634static struct clk_regmap g12a_cts_encp_sel = {
1635 .data = &(struct clk_regmap_mux_data){
1636 .offset = HHI_VID_CLK_DIV,
1637 .mask = 0xf,
1638 .shift = 20,
1639 .table = mux_table_cts_sel,
1640 },
1641 .hw.init = &(struct clk_init_data){
1642 .name = "cts_encp_sel",
1643 .ops = &clk_regmap_mux_ops,
1644 .parent_names = g12a_cts_parent_names,
1645 .num_parents = ARRAY_SIZE(g12a_cts_parent_names),
1646 .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
1647 },
1648};
1649
1650static struct clk_regmap g12a_cts_vdac_sel = {
1651 .data = &(struct clk_regmap_mux_data){
1652 .offset = HHI_VIID_CLK_DIV,
1653 .mask = 0xf,
1654 .shift = 28,
1655 .table = mux_table_cts_sel,
1656 },
1657 .hw.init = &(struct clk_init_data){
1658 .name = "cts_vdac_sel",
1659 .ops = &clk_regmap_mux_ops,
1660 .parent_names = g12a_cts_parent_names,
1661 .num_parents = ARRAY_SIZE(g12a_cts_parent_names),
1662 .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
1663 },
1664};
1665
1666/* TOFIX: add support for cts_tcon */
1667static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
1668static const char * const g12a_cts_hdmi_tx_parent_names[] = {
1669 "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6",
1670 "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4",
1671 "vclk2_div6", "vclk2_div12"
1672};
1673
1674static struct clk_regmap g12a_hdmi_tx_sel = {
1675 .data = &(struct clk_regmap_mux_data){
1676 .offset = HHI_HDMI_CLK_CNTL,
1677 .mask = 0xf,
1678 .shift = 16,
1679 .table = mux_table_hdmi_tx_sel,
1680 },
1681 .hw.init = &(struct clk_init_data){
1682 .name = "hdmi_tx_sel",
1683 .ops = &clk_regmap_mux_ops,
1684 .parent_names = g12a_cts_hdmi_tx_parent_names,
1685 .num_parents = ARRAY_SIZE(g12a_cts_hdmi_tx_parent_names),
1686 .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
1687 },
1688};
1689
1690static struct clk_regmap g12a_cts_enci = {
1691 .data = &(struct clk_regmap_gate_data){
1692 .offset = HHI_VID_CLK_CNTL2,
1693 .bit_idx = 0,
1694 },
1695 .hw.init = &(struct clk_init_data) {
1696 .name = "cts_enci",
1697 .ops = &clk_regmap_gate_ops,
1698 .parent_names = (const char *[]){ "cts_enci_sel" },
1699 .num_parents = 1,
1700 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1701 },
1702};
1703
1704static struct clk_regmap g12a_cts_encp = {
1705 .data = &(struct clk_regmap_gate_data){
1706 .offset = HHI_VID_CLK_CNTL2,
1707 .bit_idx = 2,
1708 },
1709 .hw.init = &(struct clk_init_data) {
1710 .name = "cts_encp",
1711 .ops = &clk_regmap_gate_ops,
1712 .parent_names = (const char *[]){ "cts_encp_sel" },
1713 .num_parents = 1,
1714 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1715 },
1716};
1717
1718static struct clk_regmap g12a_cts_vdac = {
1719 .data = &(struct clk_regmap_gate_data){
1720 .offset = HHI_VID_CLK_CNTL2,
1721 .bit_idx = 4,
1722 },
1723 .hw.init = &(struct clk_init_data) {
1724 .name = "cts_vdac",
1725 .ops = &clk_regmap_gate_ops,
1726 .parent_names = (const char *[]){ "cts_vdac_sel" },
1727 .num_parents = 1,
1728 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1729 },
1730};
1731
1732static struct clk_regmap g12a_hdmi_tx = {
1733 .data = &(struct clk_regmap_gate_data){
1734 .offset = HHI_VID_CLK_CNTL2,
1735 .bit_idx = 5,
1736 },
1737 .hw.init = &(struct clk_init_data) {
1738 .name = "hdmi_tx",
1739 .ops = &clk_regmap_gate_ops,
1740 .parent_names = (const char *[]){ "hdmi_tx_sel" },
1741 .num_parents = 1,
1742 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1743 },
1744};
1745
1746/* HDMI Clocks */
1747
1748static const char * const g12a_hdmi_parent_names[] = {
1749 IN_PREFIX "xtal", "fclk_div4", "fclk_div3", "fclk_div5"
1750};
1751
1752static struct clk_regmap g12a_hdmi_sel = {
1753 .data = &(struct clk_regmap_mux_data){
1754 .offset = HHI_HDMI_CLK_CNTL,
1755 .mask = 0x3,
1756 .shift = 9,
1757 .flags = CLK_MUX_ROUND_CLOSEST,
1758 },
1759 .hw.init = &(struct clk_init_data){
1760 .name = "hdmi_sel",
1761 .ops = &clk_regmap_mux_ops,
1762 .parent_names = g12a_hdmi_parent_names,
1763 .num_parents = ARRAY_SIZE(g12a_hdmi_parent_names),
1764 .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
1765 },
1766};
1767
1768static struct clk_regmap g12a_hdmi_div = {
1769 .data = &(struct clk_regmap_div_data){
1770 .offset = HHI_HDMI_CLK_CNTL,
1771 .shift = 0,
1772 .width = 7,
1773 },
1774 .hw.init = &(struct clk_init_data){
1775 .name = "hdmi_div",
1776 .ops = &clk_regmap_divider_ops,
1777 .parent_names = (const char *[]){ "hdmi_sel" },
1778 .num_parents = 1,
1779 .flags = CLK_GET_RATE_NOCACHE,
1780 },
1781};
1782
1783static struct clk_regmap g12a_hdmi = {
1784 .data = &(struct clk_regmap_gate_data){
1785 .offset = HHI_HDMI_CLK_CNTL,
1786 .bit_idx = 8,
1787 },
1788 .hw.init = &(struct clk_init_data) {
1789 .name = "hdmi",
1790 .ops = &clk_regmap_gate_ops,
1791 .parent_names = (const char *[]){ "hdmi_div" },
1792 .num_parents = 1,
1793 .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1794 },
1795};
1796
1797/*
1798 * The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
1799 * muxed by a glitch-free switch.
1800 */
1801
1802static const char * const g12a_mali_0_1_parent_names[] = {
1803 IN_PREFIX "xtal", "gp0_pll", "hihi_pll", "fclk_div2p5",
1804 "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7"
1805};
1806
1807static struct clk_regmap g12a_mali_0_sel = {
1808 .data = &(struct clk_regmap_mux_data){
1809 .offset = HHI_MALI_CLK_CNTL,
1810 .mask = 0x7,
1811 .shift = 9,
1812 },
1813 .hw.init = &(struct clk_init_data){
1814 .name = "mali_0_sel",
1815 .ops = &clk_regmap_mux_ops,
1816 .parent_names = g12a_mali_0_1_parent_names,
1817 .num_parents = 8,
1818 .flags = CLK_SET_RATE_NO_REPARENT,
1819 },
1820};
1821
1822static struct clk_regmap g12a_mali_0_div = {
1823 .data = &(struct clk_regmap_div_data){
1824 .offset = HHI_MALI_CLK_CNTL,
1825 .shift = 0,
1826 .width = 7,
1827 },
1828 .hw.init = &(struct clk_init_data){
1829 .name = "mali_0_div",
1830 .ops = &clk_regmap_divider_ops,
1831 .parent_names = (const char *[]){ "mali_0_sel" },
1832 .num_parents = 1,
1833 .flags = CLK_SET_RATE_NO_REPARENT,
1834 },
1835};
1836
1837static struct clk_regmap g12a_mali_0 = {
1838 .data = &(struct clk_regmap_gate_data){
1839 .offset = HHI_MALI_CLK_CNTL,
1840 .bit_idx = 8,
1841 },
1842 .hw.init = &(struct clk_init_data){
1843 .name = "mali_0",
1844 .ops = &clk_regmap_gate_ops,
1845 .parent_names = (const char *[]){ "mali_0_div" },
1846 .num_parents = 1,
1847 .flags = CLK_SET_RATE_PARENT,
1848 },
1849};
1850
1851static struct clk_regmap g12a_mali_1_sel = {
1852 .data = &(struct clk_regmap_mux_data){
1853 .offset = HHI_MALI_CLK_CNTL,
1854 .mask = 0x7,
1855 .shift = 25,
1856 },
1857 .hw.init = &(struct clk_init_data){
1858 .name = "mali_1_sel",
1859 .ops = &clk_regmap_mux_ops,
1860 .parent_names = g12a_mali_0_1_parent_names,
1861 .num_parents = 8,
1862 .flags = CLK_SET_RATE_NO_REPARENT,
1863 },
1864};
1865
1866static struct clk_regmap g12a_mali_1_div = {
1867 .data = &(struct clk_regmap_div_data){
1868 .offset = HHI_MALI_CLK_CNTL,
1869 .shift = 16,
1870 .width = 7,
1871 },
1872 .hw.init = &(struct clk_init_data){
1873 .name = "mali_1_div",
1874 .ops = &clk_regmap_divider_ops,
1875 .parent_names = (const char *[]){ "mali_1_sel" },
1876 .num_parents = 1,
1877 .flags = CLK_SET_RATE_NO_REPARENT,
1878 },
1879};
1880
1881static struct clk_regmap g12a_mali_1 = {
1882 .data = &(struct clk_regmap_gate_data){
1883 .offset = HHI_MALI_CLK_CNTL,
1884 .bit_idx = 24,
1885 },
1886 .hw.init = &(struct clk_init_data){
1887 .name = "mali_1",
1888 .ops = &clk_regmap_gate_ops,
1889 .parent_names = (const char *[]){ "mali_1_div" },
1890 .num_parents = 1,
1891 .flags = CLK_SET_RATE_PARENT,
1892 },
1893};
1894
1895static const char * const g12a_mali_parent_names[] = {
1896 "mali_0", "mali_1"
1897};
1898
1899static struct clk_regmap g12a_mali = {
1900 .data = &(struct clk_regmap_mux_data){
1901 .offset = HHI_MALI_CLK_CNTL,
1902 .mask = 1,
1903 .shift = 31,
1904 },
1905 .hw.init = &(struct clk_init_data){
1906 .name = "mali",
1907 .ops = &clk_regmap_mux_ops,
1908 .parent_names = g12a_mali_parent_names,
1909 .num_parents = 2,
1910 .flags = CLK_SET_RATE_NO_REPARENT,
1911 },
1912};
1913
1914/* Everything Else (EE) domain gates */
1915static MESON_GATE(g12a_ddr, HHI_GCLK_MPEG0, 0);
1916static MESON_GATE(g12a_dos, HHI_GCLK_MPEG0, 1);
1917static MESON_GATE(g12a_audio_locker, HHI_GCLK_MPEG0, 2);
1918static MESON_GATE(g12a_mipi_dsi_host, HHI_GCLK_MPEG0, 3);
1919static MESON_GATE(g12a_eth_phy, HHI_GCLK_MPEG0, 4);
1920static MESON_GATE(g12a_isa, HHI_GCLK_MPEG0, 5);
1921static MESON_GATE(g12a_pl301, HHI_GCLK_MPEG0, 6);
1922static MESON_GATE(g12a_periphs, HHI_GCLK_MPEG0, 7);
1923static MESON_GATE(g12a_spicc_0, HHI_GCLK_MPEG0, 8);
1924static MESON_GATE(g12a_i2c, HHI_GCLK_MPEG0, 9);
1925static MESON_GATE(g12a_sana, HHI_GCLK_MPEG0, 10);
1926static MESON_GATE(g12a_sd, HHI_GCLK_MPEG0, 11);
1927static MESON_GATE(g12a_rng0, HHI_GCLK_MPEG0, 12);
1928static MESON_GATE(g12a_uart0, HHI_GCLK_MPEG0, 13);
1929static MESON_GATE(g12a_spicc_1, HHI_GCLK_MPEG0, 14);
1930static MESON_GATE(g12a_hiu_reg, HHI_GCLK_MPEG0, 19);
1931static MESON_GATE(g12a_mipi_dsi_phy, HHI_GCLK_MPEG0, 20);
1932static MESON_GATE(g12a_assist_misc, HHI_GCLK_MPEG0, 23);
1933static MESON_GATE(g12a_emmc_a, HHI_GCLK_MPEG0, 4);
1934static MESON_GATE(g12a_emmc_b, HHI_GCLK_MPEG0, 25);
1935static MESON_GATE(g12a_emmc_c, HHI_GCLK_MPEG0, 26);
1936static MESON_GATE(g12a_audio_codec, HHI_GCLK_MPEG0, 28);
1937
1938static MESON_GATE(g12a_audio, HHI_GCLK_MPEG1, 0);
1939static MESON_GATE(g12a_eth_core, HHI_GCLK_MPEG1, 3);
1940static MESON_GATE(g12a_demux, HHI_GCLK_MPEG1, 4);
1941static MESON_GATE(g12a_audio_ififo, HHI_GCLK_MPEG1, 11);
1942static MESON_GATE(g12a_adc, HHI_GCLK_MPEG1, 13);
1943static MESON_GATE(g12a_uart1, HHI_GCLK_MPEG1, 16);
1944static MESON_GATE(g12a_g2d, HHI_GCLK_MPEG1, 20);
1945static MESON_GATE(g12a_reset, HHI_GCLK_MPEG1, 23);
1946static MESON_GATE(g12a_pcie_comb, HHI_GCLK_MPEG1, 24);
1947static MESON_GATE(g12a_parser, HHI_GCLK_MPEG1, 25);
1948static MESON_GATE(g12a_usb_general, HHI_GCLK_MPEG1, 26);
1949static MESON_GATE(g12a_pcie_phy, HHI_GCLK_MPEG1, 27);
1950static MESON_GATE(g12a_ahb_arb0, HHI_GCLK_MPEG1, 29);
1951
1952static MESON_GATE(g12a_ahb_data_bus, HHI_GCLK_MPEG2, 1);
1953static MESON_GATE(g12a_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2);
1954static MESON_GATE(g12a_htx_hdcp22, HHI_GCLK_MPEG2, 3);
1955static MESON_GATE(g12a_htx_pclk, HHI_GCLK_MPEG2, 4);
1956static MESON_GATE(g12a_bt656, HHI_GCLK_MPEG2, 6);
1957static MESON_GATE(g12a_usb1_to_ddr, HHI_GCLK_MPEG2, 8);
1958static MESON_GATE(g12a_mmc_pclk, HHI_GCLK_MPEG2, 11);
1959static MESON_GATE(g12a_uart2, HHI_GCLK_MPEG2, 15);
1960static MESON_GATE(g12a_vpu_intr, HHI_GCLK_MPEG2, 25);
1961static MESON_GATE(g12a_gic, HHI_GCLK_MPEG2, 30);
1962
1963static MESON_GATE(g12a_vclk2_venci0, HHI_GCLK_OTHER, 1);
1964static MESON_GATE(g12a_vclk2_venci1, HHI_GCLK_OTHER, 2);
1965static MESON_GATE(g12a_vclk2_vencp0, HHI_GCLK_OTHER, 3);
1966static MESON_GATE(g12a_vclk2_vencp1, HHI_GCLK_OTHER, 4);
1967static MESON_GATE(g12a_vclk2_venct0, HHI_GCLK_OTHER, 5);
1968static MESON_GATE(g12a_vclk2_venct1, HHI_GCLK_OTHER, 6);
1969static MESON_GATE(g12a_vclk2_other, HHI_GCLK_OTHER, 7);
1970static MESON_GATE(g12a_vclk2_enci, HHI_GCLK_OTHER, 8);
1971static MESON_GATE(g12a_vclk2_encp, HHI_GCLK_OTHER, 9);
1972static MESON_GATE(g12a_dac_clk, HHI_GCLK_OTHER, 10);
1973static MESON_GATE(g12a_aoclk_gate, HHI_GCLK_OTHER, 14);
1974static MESON_GATE(g12a_iec958_gate, HHI_GCLK_OTHER, 16);
1975static MESON_GATE(g12a_enc480p, HHI_GCLK_OTHER, 20);
1976static MESON_GATE(g12a_rng1, HHI_GCLK_OTHER, 21);
1977static MESON_GATE(g12a_vclk2_enct, HHI_GCLK_OTHER, 22);
1978static MESON_GATE(g12a_vclk2_encl, HHI_GCLK_OTHER, 23);
1979static MESON_GATE(g12a_vclk2_venclmmc, HHI_GCLK_OTHER, 24);
1980static MESON_GATE(g12a_vclk2_vencl, HHI_GCLK_OTHER, 25);
1981static MESON_GATE(g12a_vclk2_other1, HHI_GCLK_OTHER, 26);
1982
1983static MESON_GATE_RO(g12a_dma, HHI_GCLK_OTHER2, 0);
1984static MESON_GATE_RO(g12a_efuse, HHI_GCLK_OTHER2, 1);
1985static MESON_GATE_RO(g12a_rom_boot, HHI_GCLK_OTHER2, 2);
1986static MESON_GATE_RO(g12a_reset_sec, HHI_GCLK_OTHER2, 3);
1987static MESON_GATE_RO(g12a_sec_ahb_apb3, HHI_GCLK_OTHER2, 4);
1988
1989/* Array of all clocks provided by this provider */
1990static struct clk_hw_onecell_data g12a_hw_onecell_data = {
1991 .hws = {
1992 [CLKID_SYS_PLL] = &g12a_sys_pll.hw,
1993 [CLKID_FIXED_PLL] = &g12a_fixed_pll.hw,
1994 [CLKID_FCLK_DIV2] = &g12a_fclk_div2.hw,
1995 [CLKID_FCLK_DIV3] = &g12a_fclk_div3.hw,
1996 [CLKID_FCLK_DIV4] = &g12a_fclk_div4.hw,
1997 [CLKID_FCLK_DIV5] = &g12a_fclk_div5.hw,
1998 [CLKID_FCLK_DIV7] = &g12a_fclk_div7.hw,
1999 [CLKID_FCLK_DIV2P5] = &g12a_fclk_div2p5.hw,
2000 [CLKID_GP0_PLL] = &g12a_gp0_pll.hw,
2001 [CLKID_MPEG_SEL] = &g12a_mpeg_clk_sel.hw,
2002 [CLKID_MPEG_DIV] = &g12a_mpeg_clk_div.hw,
2003 [CLKID_CLK81] = &g12a_clk81.hw,
2004 [CLKID_MPLL0] = &g12a_mpll0.hw,
2005 [CLKID_MPLL1] = &g12a_mpll1.hw,
2006 [CLKID_MPLL2] = &g12a_mpll2.hw,
2007 [CLKID_MPLL3] = &g12a_mpll3.hw,
2008 [CLKID_DDR] = &g12a_ddr.hw,
2009 [CLKID_DOS] = &g12a_dos.hw,
2010 [CLKID_AUDIO_LOCKER] = &g12a_audio_locker.hw,
2011 [CLKID_MIPI_DSI_HOST] = &g12a_mipi_dsi_host.hw,
2012 [CLKID_ETH_PHY] = &g12a_eth_phy.hw,
2013 [CLKID_ISA] = &g12a_isa.hw,
2014 [CLKID_PL301] = &g12a_pl301.hw,
2015 [CLKID_PERIPHS] = &g12a_periphs.hw,
2016 [CLKID_SPICC0] = &g12a_spicc_0.hw,
2017 [CLKID_I2C] = &g12a_i2c.hw,
2018 [CLKID_SANA] = &g12a_sana.hw,
2019 [CLKID_SD] = &g12a_sd.hw,
2020 [CLKID_RNG0] = &g12a_rng0.hw,
2021 [CLKID_UART0] = &g12a_uart0.hw,
2022 [CLKID_SPICC1] = &g12a_spicc_1.hw,
2023 [CLKID_HIU_IFACE] = &g12a_hiu_reg.hw,
2024 [CLKID_MIPI_DSI_PHY] = &g12a_mipi_dsi_phy.hw,
2025 [CLKID_ASSIST_MISC] = &g12a_assist_misc.hw,
2026 [CLKID_SD_EMMC_A] = &g12a_emmc_a.hw,
2027 [CLKID_SD_EMMC_B] = &g12a_emmc_b.hw,
2028 [CLKID_SD_EMMC_C] = &g12a_emmc_c.hw,
2029 [CLKID_AUDIO_CODEC] = &g12a_audio_codec.hw,
2030 [CLKID_AUDIO] = &g12a_audio.hw,
2031 [CLKID_ETH] = &g12a_eth_core.hw,
2032 [CLKID_DEMUX] = &g12a_demux.hw,
2033 [CLKID_AUDIO_IFIFO] = &g12a_audio_ififo.hw,
2034 [CLKID_ADC] = &g12a_adc.hw,
2035 [CLKID_UART1] = &g12a_uart1.hw,
2036 [CLKID_G2D] = &g12a_g2d.hw,
2037 [CLKID_RESET] = &g12a_reset.hw,
2038 [CLKID_PCIE_COMB] = &g12a_pcie_comb.hw,
2039 [CLKID_PARSER] = &g12a_parser.hw,
2040 [CLKID_USB] = &g12a_usb_general.hw,
2041 [CLKID_PCIE_PHY] = &g12a_pcie_phy.hw,
2042 [CLKID_AHB_ARB0] = &g12a_ahb_arb0.hw,
2043 [CLKID_AHB_DATA_BUS] = &g12a_ahb_data_bus.hw,
2044 [CLKID_AHB_CTRL_BUS] = &g12a_ahb_ctrl_bus.hw,
2045 [CLKID_HTX_HDCP22] = &g12a_htx_hdcp22.hw,
2046 [CLKID_HTX_PCLK] = &g12a_htx_pclk.hw,
2047 [CLKID_BT656] = &g12a_bt656.hw,
2048 [CLKID_USB1_DDR_BRIDGE] = &g12a_usb1_to_ddr.hw,
2049 [CLKID_MMC_PCLK] = &g12a_mmc_pclk.hw,
2050 [CLKID_UART2] = &g12a_uart2.hw,
2051 [CLKID_VPU_INTR] = &g12a_vpu_intr.hw,
2052 [CLKID_GIC] = &g12a_gic.hw,
2053 [CLKID_SD_EMMC_A_CLK0_SEL] = &g12a_sd_emmc_a_clk0_sel.hw,
2054 [CLKID_SD_EMMC_A_CLK0_DIV] = &g12a_sd_emmc_a_clk0_div.hw,
2055 [CLKID_SD_EMMC_A_CLK0] = &g12a_sd_emmc_a_clk0.hw,
2056 [CLKID_SD_EMMC_B_CLK0_SEL] = &g12a_sd_emmc_b_clk0_sel.hw,
2057 [CLKID_SD_EMMC_B_CLK0_DIV] = &g12a_sd_emmc_b_clk0_div.hw,
2058 [CLKID_SD_EMMC_B_CLK0] = &g12a_sd_emmc_b_clk0.hw,
2059 [CLKID_SD_EMMC_C_CLK0_SEL] = &g12a_sd_emmc_c_clk0_sel.hw,
2060 [CLKID_SD_EMMC_C_CLK0_DIV] = &g12a_sd_emmc_c_clk0_div.hw,
2061 [CLKID_SD_EMMC_C_CLK0] = &g12a_sd_emmc_c_clk0.hw,
2062 [CLKID_MPLL0_DIV] = &g12a_mpll0_div.hw,
2063 [CLKID_MPLL1_DIV] = &g12a_mpll1_div.hw,
2064 [CLKID_MPLL2_DIV] = &g12a_mpll2_div.hw,
2065 [CLKID_MPLL3_DIV] = &g12a_mpll3_div.hw,
2066 [CLKID_FCLK_DIV2_DIV] = &g12a_fclk_div2_div.hw,
2067 [CLKID_FCLK_DIV3_DIV] = &g12a_fclk_div3_div.hw,
2068 [CLKID_FCLK_DIV4_DIV] = &g12a_fclk_div4_div.hw,
2069 [CLKID_FCLK_DIV5_DIV] = &g12a_fclk_div5_div.hw,
2070 [CLKID_FCLK_DIV7_DIV] = &g12a_fclk_div7_div.hw,
2071 [CLKID_FCLK_DIV2P5_DIV] = &g12a_fclk_div2p5_div.hw,
2072 [CLKID_HIFI_PLL] = &g12a_hifi_pll.hw,
2073 [CLKID_VCLK2_VENCI0] = &g12a_vclk2_venci0.hw,
2074 [CLKID_VCLK2_VENCI1] = &g12a_vclk2_venci1.hw,
2075 [CLKID_VCLK2_VENCP0] = &g12a_vclk2_vencp0.hw,
2076 [CLKID_VCLK2_VENCP1] = &g12a_vclk2_vencp1.hw,
2077 [CLKID_VCLK2_VENCT0] = &g12a_vclk2_venct0.hw,
2078 [CLKID_VCLK2_VENCT1] = &g12a_vclk2_venct1.hw,
2079 [CLKID_VCLK2_OTHER] = &g12a_vclk2_other.hw,
2080 [CLKID_VCLK2_ENCI] = &g12a_vclk2_enci.hw,
2081 [CLKID_VCLK2_ENCP] = &g12a_vclk2_encp.hw,
2082 [CLKID_DAC_CLK] = &g12a_dac_clk.hw,
2083 [CLKID_AOCLK] = &g12a_aoclk_gate.hw,
2084 [CLKID_IEC958] = &g12a_iec958_gate.hw,
2085 [CLKID_ENC480P] = &g12a_enc480p.hw,
2086 [CLKID_RNG1] = &g12a_rng1.hw,
2087 [CLKID_VCLK2_ENCT] = &g12a_vclk2_enct.hw,
2088 [CLKID_VCLK2_ENCL] = &g12a_vclk2_encl.hw,
2089 [CLKID_VCLK2_VENCLMMC] = &g12a_vclk2_venclmmc.hw,
2090 [CLKID_VCLK2_VENCL] = &g12a_vclk2_vencl.hw,
2091 [CLKID_VCLK2_OTHER1] = &g12a_vclk2_other1.hw,
2092 [CLKID_FIXED_PLL_DCO] = &g12a_fixed_pll_dco.hw,
2093 [CLKID_SYS_PLL_DCO] = &g12a_sys_pll_dco.hw,
2094 [CLKID_GP0_PLL_DCO] = &g12a_gp0_pll_dco.hw,
2095 [CLKID_HIFI_PLL_DCO] = &g12a_hifi_pll_dco.hw,
2096 [CLKID_DMA] = &g12a_dma.hw,
2097 [CLKID_EFUSE] = &g12a_efuse.hw,
2098 [CLKID_ROM_BOOT] = &g12a_rom_boot.hw,
2099 [CLKID_RESET_SEC] = &g12a_reset_sec.hw,
2100 [CLKID_SEC_AHB_APB3] = &g12a_sec_ahb_apb3.hw,
2101 [CLKID_MPLL_PREDIV] = &g12a_mpll_prediv.hw,
2102 [CLKID_VPU_0_SEL] = &g12a_vpu_0_sel.hw,
2103 [CLKID_VPU_0_DIV] = &g12a_vpu_0_div.hw,
2104 [CLKID_VPU_0] = &g12a_vpu_0.hw,
2105 [CLKID_VPU_1_SEL] = &g12a_vpu_1_sel.hw,
2106 [CLKID_VPU_1_DIV] = &g12a_vpu_1_div.hw,
2107 [CLKID_VPU_1] = &g12a_vpu_1.hw,
2108 [CLKID_VPU] = &g12a_vpu.hw,
2109 [CLKID_VAPB_0_SEL] = &g12a_vapb_0_sel.hw,
2110 [CLKID_VAPB_0_DIV] = &g12a_vapb_0_div.hw,
2111 [CLKID_VAPB_0] = &g12a_vapb_0.hw,
2112 [CLKID_VAPB_1_SEL] = &g12a_vapb_1_sel.hw,
2113 [CLKID_VAPB_1_DIV] = &g12a_vapb_1_div.hw,
2114 [CLKID_VAPB_1] = &g12a_vapb_1.hw,
2115 [CLKID_VAPB_SEL] = &g12a_vapb_sel.hw,
2116 [CLKID_VAPB] = &g12a_vapb.hw,
2117 [CLKID_HDMI_PLL_DCO] = &g12a_hdmi_pll_dco.hw,
2118 [CLKID_HDMI_PLL_OD] = &g12a_hdmi_pll_od.hw,
2119 [CLKID_HDMI_PLL_OD2] = &g12a_hdmi_pll_od2.hw,
2120 [CLKID_HDMI_PLL] = &g12a_hdmi_pll.hw,
2121 [CLKID_VID_PLL] = &g12a_vid_pll_div.hw,
2122 [CLKID_VID_PLL_SEL] = &g12a_vid_pll_sel.hw,
2123 [CLKID_VID_PLL_DIV] = &g12a_vid_pll.hw,
2124 [CLKID_VCLK_SEL] = &g12a_vclk_sel.hw,
2125 [CLKID_VCLK2_SEL] = &g12a_vclk2_sel.hw,
2126 [CLKID_VCLK_INPUT] = &g12a_vclk_input.hw,
2127 [CLKID_VCLK2_INPUT] = &g12a_vclk2_input.hw,
2128 [CLKID_VCLK_DIV] = &g12a_vclk_div.hw,
2129 [CLKID_VCLK2_DIV] = &g12a_vclk2_div.hw,
2130 [CLKID_VCLK] = &g12a_vclk.hw,
2131 [CLKID_VCLK2] = &g12a_vclk2.hw,
2132 [CLKID_VCLK_DIV1] = &g12a_vclk_div1.hw,
2133 [CLKID_VCLK_DIV2_EN] = &g12a_vclk_div2_en.hw,
2134 [CLKID_VCLK_DIV4_EN] = &g12a_vclk_div4_en.hw,
2135 [CLKID_VCLK_DIV6_EN] = &g12a_vclk_div6_en.hw,
2136 [CLKID_VCLK_DIV12_EN] = &g12a_vclk_div12_en.hw,
2137 [CLKID_VCLK2_DIV1] = &g12a_vclk2_div1.hw,
2138 [CLKID_VCLK2_DIV2_EN] = &g12a_vclk2_div2_en.hw,
2139 [CLKID_VCLK2_DIV4_EN] = &g12a_vclk2_div4_en.hw,
2140 [CLKID_VCLK2_DIV6_EN] = &g12a_vclk2_div6_en.hw,
2141 [CLKID_VCLK2_DIV12_EN] = &g12a_vclk2_div12_en.hw,
2142 [CLKID_VCLK_DIV2] = &g12a_vclk_div2.hw,
2143 [CLKID_VCLK_DIV4] = &g12a_vclk_div4.hw,
2144 [CLKID_VCLK_DIV6] = &g12a_vclk_div6.hw,
2145 [CLKID_VCLK_DIV12] = &g12a_vclk_div12.hw,
2146 [CLKID_VCLK2_DIV2] = &g12a_vclk2_div2.hw,
2147 [CLKID_VCLK2_DIV4] = &g12a_vclk2_div4.hw,
2148 [CLKID_VCLK2_DIV6] = &g12a_vclk2_div6.hw,
2149 [CLKID_VCLK2_DIV12] = &g12a_vclk2_div12.hw,
2150 [CLKID_CTS_ENCI_SEL] = &g12a_cts_enci_sel.hw,
2151 [CLKID_CTS_ENCP_SEL] = &g12a_cts_encp_sel.hw,
2152 [CLKID_CTS_VDAC_SEL] = &g12a_cts_vdac_sel.hw,
2153 [CLKID_HDMI_TX_SEL] = &g12a_hdmi_tx_sel.hw,
2154 [CLKID_CTS_ENCI] = &g12a_cts_enci.hw,
2155 [CLKID_CTS_ENCP] = &g12a_cts_encp.hw,
2156 [CLKID_CTS_VDAC] = &g12a_cts_vdac.hw,
2157 [CLKID_HDMI_TX] = &g12a_hdmi_tx.hw,
2158 [CLKID_HDMI_SEL] = &g12a_hdmi_sel.hw,
2159 [CLKID_HDMI_DIV] = &g12a_hdmi_div.hw,
2160 [CLKID_HDMI] = &g12a_hdmi.hw,
2161 [CLKID_MALI_0_SEL] = &g12a_mali_0_sel.hw,
2162 [CLKID_MALI_0_DIV] = &g12a_mali_0_div.hw,
2163 [CLKID_MALI_0] = &g12a_mali_0.hw,
2164 [CLKID_MALI_1_SEL] = &g12a_mali_1_sel.hw,
2165 [CLKID_MALI_1_DIV] = &g12a_mali_1_div.hw,
2166 [CLKID_MALI_1] = &g12a_mali_1.hw,
2167 [CLKID_MALI] = &g12a_mali.hw,
2168 [CLKID_MPLL_5OM_DIV] = &g12a_mpll_50m_div.hw,
2169 [CLKID_MPLL_5OM] = &g12a_mpll_50m.hw,
2170 [NR_CLKS] = NULL,
2171 },
2172 .num = NR_CLKS,
2173};
2174
2175/* Convenience table to populate regmap in .probe */
2176static struct clk_regmap *const g12a_clk_regmaps[] = {
2177 &g12a_clk81,
2178 &g12a_dos,
2179 &g12a_ddr,
2180 &g12a_audio_locker,
2181 &g12a_mipi_dsi_host,
2182 &g12a_eth_phy,
2183 &g12a_isa,
2184 &g12a_pl301,
2185 &g12a_periphs,
2186 &g12a_spicc_0,
2187 &g12a_i2c,
2188 &g12a_sana,
2189 &g12a_sd,
2190 &g12a_rng0,
2191 &g12a_uart0,
2192 &g12a_spicc_1,
2193 &g12a_hiu_reg,
2194 &g12a_mipi_dsi_phy,
2195 &g12a_assist_misc,
2196 &g12a_emmc_a,
2197 &g12a_emmc_b,
2198 &g12a_emmc_c,
2199 &g12a_audio_codec,
2200 &g12a_audio,
2201 &g12a_eth_core,
2202 &g12a_demux,
2203 &g12a_audio_ififo,
2204 &g12a_adc,
2205 &g12a_uart1,
2206 &g12a_g2d,
2207 &g12a_reset,
2208 &g12a_pcie_comb,
2209 &g12a_parser,
2210 &g12a_usb_general,
2211 &g12a_pcie_phy,
2212 &g12a_ahb_arb0,
2213 &g12a_ahb_data_bus,
2214 &g12a_ahb_ctrl_bus,
2215 &g12a_htx_hdcp22,
2216 &g12a_htx_pclk,
2217 &g12a_bt656,
2218 &g12a_usb1_to_ddr,
2219 &g12a_mmc_pclk,
2220 &g12a_vpu_intr,
2221 &g12a_gic,
2222 &g12a_sd_emmc_a_clk0,
2223 &g12a_sd_emmc_b_clk0,
2224 &g12a_sd_emmc_c_clk0,
2225 &g12a_mpeg_clk_div,
2226 &g12a_sd_emmc_a_clk0_div,
2227 &g12a_sd_emmc_b_clk0_div,
2228 &g12a_sd_emmc_c_clk0_div,
2229 &g12a_mpeg_clk_sel,
2230 &g12a_sd_emmc_a_clk0_sel,
2231 &g12a_sd_emmc_b_clk0_sel,
2232 &g12a_sd_emmc_c_clk0_sel,
2233 &g12a_mpll0,
2234 &g12a_mpll1,
2235 &g12a_mpll2,
2236 &g12a_mpll3,
2237 &g12a_mpll0_div,
2238 &g12a_mpll1_div,
2239 &g12a_mpll2_div,
2240 &g12a_mpll3_div,
2241 &g12a_fixed_pll,
2242 &g12a_sys_pll,
2243 &g12a_gp0_pll,
2244 &g12a_hifi_pll,
2245 &g12a_vclk2_venci0,
2246 &g12a_vclk2_venci1,
2247 &g12a_vclk2_vencp0,
2248 &g12a_vclk2_vencp1,
2249 &g12a_vclk2_venct0,
2250 &g12a_vclk2_venct1,
2251 &g12a_vclk2_other,
2252 &g12a_vclk2_enci,
2253 &g12a_vclk2_encp,
2254 &g12a_dac_clk,
2255 &g12a_aoclk_gate,
2256 &g12a_iec958_gate,
2257 &g12a_enc480p,
2258 &g12a_rng1,
2259 &g12a_vclk2_enct,
2260 &g12a_vclk2_encl,
2261 &g12a_vclk2_venclmmc,
2262 &g12a_vclk2_vencl,
2263 &g12a_vclk2_other1,
2264 &g12a_fixed_pll_dco,
2265 &g12a_sys_pll_dco,
2266 &g12a_gp0_pll_dco,
2267 &g12a_hifi_pll_dco,
2268 &g12a_fclk_div2,
2269 &g12a_fclk_div3,
2270 &g12a_fclk_div4,
2271 &g12a_fclk_div5,
2272 &g12a_fclk_div7,
2273 &g12a_fclk_div2p5,
2274 &g12a_dma,
2275 &g12a_efuse,
2276 &g12a_rom_boot,
2277 &g12a_reset_sec,
2278 &g12a_sec_ahb_apb3,
2279 &g12a_vpu_0_sel,
2280 &g12a_vpu_0_div,
2281 &g12a_vpu_0,
2282 &g12a_vpu_1_sel,
2283 &g12a_vpu_1_div,
2284 &g12a_vpu_1,
2285 &g12a_vpu,
2286 &g12a_vapb_0_sel,
2287 &g12a_vapb_0_div,
2288 &g12a_vapb_0,
2289 &g12a_vapb_1_sel,
2290 &g12a_vapb_1_div,
2291 &g12a_vapb_1,
2292 &g12a_vapb_sel,
2293 &g12a_vapb,
2294 &g12a_hdmi_pll_dco,
2295 &g12a_hdmi_pll_od,
2296 &g12a_hdmi_pll_od2,
2297 &g12a_hdmi_pll,
2298 &g12a_vid_pll_div,
2299 &g12a_vid_pll_sel,
2300 &g12a_vid_pll,
2301 &g12a_vclk_sel,
2302 &g12a_vclk2_sel,
2303 &g12a_vclk_input,
2304 &g12a_vclk2_input,
2305 &g12a_vclk_div,
2306 &g12a_vclk2_div,
2307 &g12a_vclk,
2308 &g12a_vclk2,
2309 &g12a_vclk_div1,
2310 &g12a_vclk_div2_en,
2311 &g12a_vclk_div4_en,
2312 &g12a_vclk_div6_en,
2313 &g12a_vclk_div12_en,
2314 &g12a_vclk2_div1,
2315 &g12a_vclk2_div2_en,
2316 &g12a_vclk2_div4_en,
2317 &g12a_vclk2_div6_en,
2318 &g12a_vclk2_div12_en,
2319 &g12a_cts_enci_sel,
2320 &g12a_cts_encp_sel,
2321 &g12a_cts_vdac_sel,
2322 &g12a_hdmi_tx_sel,
2323 &g12a_cts_enci,
2324 &g12a_cts_encp,
2325 &g12a_cts_vdac,
2326 &g12a_hdmi_tx,
2327 &g12a_hdmi_sel,
2328 &g12a_hdmi_div,
2329 &g12a_hdmi,
2330 &g12a_mali_0_sel,
2331 &g12a_mali_0_div,
2332 &g12a_mali_0,
2333 &g12a_mali_1_sel,
2334 &g12a_mali_1_div,
2335 &g12a_mali_1,
2336 &g12a_mali,
2337 &g12a_mpll_50m,
2338};
2339
2340static const struct meson_eeclkc_data g12a_clkc_data = {
2341 .regmap_clks = g12a_clk_regmaps,
2342 .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
2343 .hw_onecell_data = &g12a_hw_onecell_data
2344};
2345
2346static const struct of_device_id clkc_match_table[] = {
2347 { .compatible = "amlogic,g12a-clkc", .data = &g12a_clkc_data },
2348 {}
2349};
2350
2351static struct platform_driver g12a_driver = {
2352 .probe = meson_eeclkc_probe,
2353 .driver = {
2354 .name = "g12a-clkc",
2355 .of_match_table = clkc_match_table,
2356 },
2357};
2358
2359builtin_platform_driver(g12a_driver);
diff --git a/drivers/clk/meson/g12a.h b/drivers/clk/meson/g12a.h
new file mode 100644
index 000000000000..f399dfe1401c
--- /dev/null
+++ b/drivers/clk/meson/g12a.h
@@ -0,0 +1,175 @@
1/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
2/*
3 * Copyright (c) 2016 Amlogic, Inc.
4 * Author: Michael Turquette <mturquette@baylibre.com>
5 *
6 * Copyright (c) 2018 Amlogic, inc.
7 * Author: Qiufang Dai <qiufang.dai@amlogic.com>
8 * Author: Jian Hu <jian.hu@amlogic.com>
9 *
10 */
11#ifndef __G12A_H
12#define __G12A_H
13
14/*
15 * Clock controller register offsets
16 *
17 * Register offsets from the data sheet must be multiplied by 4 before
18 * adding them to the base address to get the right value.
19 */
20#define HHI_MIPI_CNTL0 0x000
21#define HHI_MIPI_CNTL1 0x004
22#define HHI_MIPI_CNTL2 0x008
23#define HHI_MIPI_STS 0x00C
24#define HHI_GP0_PLL_CNTL0 0x040
25#define HHI_GP0_PLL_CNTL1 0x044
26#define HHI_GP0_PLL_CNTL2 0x048
27#define HHI_GP0_PLL_CNTL3 0x04C
28#define HHI_GP0_PLL_CNTL4 0x050
29#define HHI_GP0_PLL_CNTL5 0x054
30#define HHI_GP0_PLL_CNTL6 0x058
31#define HHI_GP0_PLL_STS 0x05C
32#define HHI_PCIE_PLL_CNTL0 0x098
33#define HHI_PCIE_PLL_CNTL1 0x09C
34#define HHI_PCIE_PLL_CNTL2 0x0A0
35#define HHI_PCIE_PLL_CNTL3 0x0A4
36#define HHI_PCIE_PLL_CNTL4 0x0A8
37#define HHI_PCIE_PLL_CNTL5 0x0AC
38#define HHI_PCIE_PLL_STS 0x0B8
39#define HHI_HIFI_PLL_CNTL0 0x0D8
40#define HHI_HIFI_PLL_CNTL1 0x0DC
41#define HHI_HIFI_PLL_CNTL2 0x0E0
42#define HHI_HIFI_PLL_CNTL3 0x0E4
43#define HHI_HIFI_PLL_CNTL4 0x0E8
44#define HHI_HIFI_PLL_CNTL5 0x0EC
45#define HHI_HIFI_PLL_CNTL6 0x0F0
46#define HHI_VIID_CLK_DIV 0x128
47#define HHI_VIID_CLK_CNTL 0x12C
48#define HHI_GCLK_MPEG0 0x140
49#define HHI_GCLK_MPEG1 0x144
50#define HHI_GCLK_MPEG2 0x148
51#define HHI_GCLK_OTHER 0x150
52#define HHI_GCLK_OTHER2 0x154
53#define HHI_VID_CLK_DIV 0x164
54#define HHI_MPEG_CLK_CNTL 0x174
55#define HHI_AUD_CLK_CNTL 0x178
56#define HHI_VID_CLK_CNTL 0x17c
57#define HHI_TS_CLK_CNTL 0x190
58#define HHI_VID_CLK_CNTL2 0x194
59#define HHI_SYS_CPU_CLK_CNTL0 0x19c
60#define HHI_VID_PLL_CLK_DIV 0x1A0
61#define HHI_MALI_CLK_CNTL 0x1b0
62#define HHI_VPU_CLKC_CNTL 0x1b4
63#define HHI_VPU_CLK_CNTL 0x1bC
64#define HHI_HDMI_CLK_CNTL 0x1CC
65#define HHI_VDEC_CLK_CNTL 0x1E0
66#define HHI_VDEC2_CLK_CNTL 0x1E4
67#define HHI_VDEC3_CLK_CNTL 0x1E8
68#define HHI_VDEC4_CLK_CNTL 0x1EC
69#define HHI_HDCP22_CLK_CNTL 0x1F0
70#define HHI_VAPBCLK_CNTL 0x1F4
71#define HHI_VPU_CLKB_CNTL 0x20C
72#define HHI_GEN_CLK_CNTL 0x228
73#define HHI_VDIN_MEAS_CLK_CNTL 0x250
74#define HHI_MIPIDSI_PHY_CLK_CNTL 0x254
75#define HHI_NAND_CLK_CNTL 0x25C
76#define HHI_SD_EMMC_CLK_CNTL 0x264
77#define HHI_MPLL_CNTL0 0x278
78#define HHI_MPLL_CNTL1 0x27C
79#define HHI_MPLL_CNTL2 0x280
80#define HHI_MPLL_CNTL3 0x284
81#define HHI_MPLL_CNTL4 0x288
82#define HHI_MPLL_CNTL5 0x28c
83#define HHI_MPLL_CNTL6 0x290
84#define HHI_MPLL_CNTL7 0x294
85#define HHI_MPLL_CNTL8 0x298
86#define HHI_FIX_PLL_CNTL0 0x2A0
87#define HHI_FIX_PLL_CNTL1 0x2A4
88#define HHI_FIX_PLL_CNTL3 0x2AC
89#define HHI_SYS_PLL_CNTL0 0x2f4
90#define HHI_SYS_PLL_CNTL1 0x2f8
91#define HHI_SYS_PLL_CNTL2 0x2fc
92#define HHI_SYS_PLL_CNTL3 0x300
93#define HHI_SYS_PLL_CNTL4 0x304
94#define HHI_SYS_PLL_CNTL5 0x308
95#define HHI_SYS_PLL_CNTL6 0x30c
96#define HHI_HDMI_PLL_CNTL0 0x320
97#define HHI_HDMI_PLL_CNTL1 0x324
98#define HHI_HDMI_PLL_CNTL2 0x328
99#define HHI_HDMI_PLL_CNTL3 0x32c
100#define HHI_HDMI_PLL_CNTL4 0x330
101#define HHI_HDMI_PLL_CNTL5 0x334
102#define HHI_HDMI_PLL_CNTL6 0x338
103#define HHI_SPICC_CLK_CNTL 0x3dc
104
105/*
106 * CLKID index values
107 *
108 * These indices are entirely contrived and do not map onto the hardware.
109 * It has now been decided to expose everything by default in the DT header:
110 * include/dt-bindings/clock/g12a-clkc.h. Only the clocks ids we don't want
111 * to expose, such as the internal muxes and dividers of composite clocks,
112 * will remain defined here.
113 */
114#define CLKID_MPEG_SEL 8
115#define CLKID_MPEG_DIV 9
116#define CLKID_SD_EMMC_A_CLK0_SEL 63
117#define CLKID_SD_EMMC_A_CLK0_DIV 64
118#define CLKID_SD_EMMC_B_CLK0_SEL 65
119#define CLKID_SD_EMMC_B_CLK0_DIV 66
120#define CLKID_SD_EMMC_C_CLK0_SEL 67
121#define CLKID_SD_EMMC_C_CLK0_DIV 68
122#define CLKID_MPLL0_DIV 69
123#define CLKID_MPLL1_DIV 70
124#define CLKID_MPLL2_DIV 71
125#define CLKID_MPLL3_DIV 72
126#define CLKID_MPLL_PREDIV 73
127#define CLKID_FCLK_DIV2_DIV 75
128#define CLKID_FCLK_DIV3_DIV 76
129#define CLKID_FCLK_DIV4_DIV 77
130#define CLKID_FCLK_DIV5_DIV 78
131#define CLKID_FCLK_DIV7_DIV 79
132#define CLKID_FCLK_DIV2P5_DIV 100
133#define CLKID_FIXED_PLL_DCO 101
134#define CLKID_SYS_PLL_DCO 102
135#define CLKID_GP0_PLL_DCO 103
136#define CLKID_HIFI_PLL_DCO 104
137#define CLKID_VPU_0_DIV 111
138#define CLKID_VPU_1_DIV 114
139#define CLKID_VAPB_0_DIV 118
140#define CLKID_VAPB_1_DIV 121
141#define CLKID_HDMI_PLL_DCO 125
142#define CLKID_HDMI_PLL_OD 126
143#define CLKID_HDMI_PLL_OD2 127
144#define CLKID_VID_PLL_SEL 130
145#define CLKID_VID_PLL_DIV 131
146#define CLKID_VCLK_SEL 132
147#define CLKID_VCLK2_SEL 133
148#define CLKID_VCLK_INPUT 134
149#define CLKID_VCLK2_INPUT 135
150#define CLKID_VCLK_DIV 136
151#define CLKID_VCLK2_DIV 137
152#define CLKID_VCLK_DIV2_EN 140
153#define CLKID_VCLK_DIV4_EN 141
154#define CLKID_VCLK_DIV6_EN 142
155#define CLKID_VCLK_DIV12_EN 143
156#define CLKID_VCLK2_DIV2_EN 144
157#define CLKID_VCLK2_DIV4_EN 145
158#define CLKID_VCLK2_DIV6_EN 146
159#define CLKID_VCLK2_DIV12_EN 147
160#define CLKID_CTS_ENCI_SEL 158
161#define CLKID_CTS_ENCP_SEL 159
162#define CLKID_CTS_VDAC_SEL 160
163#define CLKID_HDMI_TX_SEL 161
164#define CLKID_HDMI_SEL 166
165#define CLKID_HDMI_DIV 167
166#define CLKID_MALI_0_DIV 170
167#define CLKID_MALI_1_DIV 173
168#define CLKID_MPLL_5OM_DIV 176
169
170#define NR_CLKS 178
171
172/* include the CLKIDs that have been made part of the DT binding */
173#include <dt-bindings/clock/g12a-clkc.h>
174
175#endif /* __G12A_H */
diff --git a/drivers/clk/meson/gxbb-aoclk-32k.c b/drivers/clk/meson/gxbb-aoclk-32k.c
deleted file mode 100644
index 680467141a1d..000000000000
--- a/drivers/clk/meson/gxbb-aoclk-32k.c
+++ /dev/null
@@ -1,193 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2017 BayLibre, SAS.
4 * Author: Neil Armstrong <narmstrong@baylibre.com>
5 */
6
7#include <linux/clk-provider.h>
8#include <linux/bitfield.h>
9#include <linux/regmap.h>
10#include "gxbb-aoclk.h"
11
12/*
13 * The AO Domain embeds a dual/divider to generate a more precise
14 * 32,768KHz clock for low-power suspend mode and CEC.
15 * ______ ______
16 * | | | |
17 * ______ | Div1 |-| Cnt1 | ______
18 * | | /|______| |______|\ | |
19 * Xtal-->| Gate |---| ______ ______ X-X--| Gate |-->
20 * |______| | \| | | |/ | |______|
21 * | | Div2 |-| Cnt2 | |
22 * | |______| |______| |
23 * |_______________________|
24 *
25 * The dividing can be switched to single or dual, with a counter
26 * for each divider to set when the switching is done.
27 * The entire dividing mechanism can be also bypassed.
28 */
29
30#define CLK_CNTL0_N1_MASK GENMASK(11, 0)
31#define CLK_CNTL0_N2_MASK GENMASK(23, 12)
32#define CLK_CNTL0_DUALDIV_EN BIT(28)
33#define CLK_CNTL0_OUT_GATE_EN BIT(30)
34#define CLK_CNTL0_IN_GATE_EN BIT(31)
35
36#define CLK_CNTL1_M1_MASK GENMASK(11, 0)
37#define CLK_CNTL1_M2_MASK GENMASK(23, 12)
38#define CLK_CNTL1_BYPASS_EN BIT(24)
39#define CLK_CNTL1_SELECT_OSC BIT(27)
40
41#define PWR_CNTL_ALT_32K_SEL GENMASK(13, 10)
42
43struct cec_32k_freq_table {
44 unsigned long parent_rate;
45 unsigned long target_rate;
46 bool dualdiv;
47 unsigned int n1;
48 unsigned int n2;
49 unsigned int m1;
50 unsigned int m2;
51};
52
53static const struct cec_32k_freq_table aoclk_cec_32k_table[] = {
54 [0] = {
55 .parent_rate = 24000000,
56 .target_rate = 32768,
57 .dualdiv = true,
58 .n1 = 733,
59 .n2 = 732,
60 .m1 = 8,
61 .m2 = 11,
62 },
63};
64
65/*
66 * If CLK_CNTL0_DUALDIV_EN == 0
67 * - will use N1 divider only
68 * If CLK_CNTL0_DUALDIV_EN == 1
69 * - hold M1 cycles of N1 divider then changes to N2
70 * - hold M2 cycles of N2 divider then changes to N1
71 * Then we can get more accurate division.
72 */
73static unsigned long aoclk_cec_32k_recalc_rate(struct clk_hw *hw,
74 unsigned long parent_rate)
75{
76 struct aoclk_cec_32k *cec_32k = to_aoclk_cec_32k(hw);
77 unsigned long n1;
78 u32 reg0, reg1;
79
80 regmap_read(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0, &reg0);
81 regmap_read(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL1, &reg1);
82
83 if (reg1 & CLK_CNTL1_BYPASS_EN)
84 return parent_rate;
85
86 if (reg0 & CLK_CNTL0_DUALDIV_EN) {
87 unsigned long n2, m1, m2, f1, f2, p1, p2;
88
89 n1 = FIELD_GET(CLK_CNTL0_N1_MASK, reg0) + 1;
90 n2 = FIELD_GET(CLK_CNTL0_N2_MASK, reg0) + 1;
91
92 m1 = FIELD_GET(CLK_CNTL1_M1_MASK, reg1) + 1;
93 m2 = FIELD_GET(CLK_CNTL1_M2_MASK, reg1) + 1;
94
95 f1 = DIV_ROUND_CLOSEST(parent_rate, n1);
96 f2 = DIV_ROUND_CLOSEST(parent_rate, n2);
97
98 p1 = DIV_ROUND_CLOSEST(100000000 * m1, f1 * (m1 + m2));
99 p2 = DIV_ROUND_CLOSEST(100000000 * m2, f2 * (m1 + m2));
100
101 return DIV_ROUND_UP(100000000, p1 + p2);
102 }
103
104 n1 = FIELD_GET(CLK_CNTL0_N1_MASK, reg0) + 1;
105
106 return DIV_ROUND_CLOSEST(parent_rate, n1);
107}
108
109static const struct cec_32k_freq_table *find_cec_32k_freq(unsigned long rate,
110 unsigned long prate)
111{
112 int i;
113
114 for (i = 0 ; i < ARRAY_SIZE(aoclk_cec_32k_table) ; ++i)
115 if (aoclk_cec_32k_table[i].parent_rate == prate &&
116 aoclk_cec_32k_table[i].target_rate == rate)
117 return &aoclk_cec_32k_table[i];
118
119 return NULL;
120}
121
122static long aoclk_cec_32k_round_rate(struct clk_hw *hw, unsigned long rate,
123 unsigned long *prate)
124{
125 const struct cec_32k_freq_table *freq = find_cec_32k_freq(rate,
126 *prate);
127
128 /* If invalid return first one */
129 if (!freq)
130 return aoclk_cec_32k_table[0].target_rate;
131
132 return freq->target_rate;
133}
134
135/*
136 * From the Amlogic init procedure, the IN and OUT gates needs to be handled
137 * in the init procedure to avoid any glitches.
138 */
139
140static int aoclk_cec_32k_set_rate(struct clk_hw *hw, unsigned long rate,
141 unsigned long parent_rate)
142{
143 const struct cec_32k_freq_table *freq = find_cec_32k_freq(rate,
144 parent_rate);
145 struct aoclk_cec_32k *cec_32k = to_aoclk_cec_32k(hw);
146 u32 reg = 0;
147
148 if (!freq)
149 return -EINVAL;
150
151 /* Disable clock */
152 regmap_update_bits(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0,
153 CLK_CNTL0_IN_GATE_EN | CLK_CNTL0_OUT_GATE_EN, 0);
154
155 reg = FIELD_PREP(CLK_CNTL0_N1_MASK, freq->n1 - 1);
156 if (freq->dualdiv)
157 reg |= CLK_CNTL0_DUALDIV_EN |
158 FIELD_PREP(CLK_CNTL0_N2_MASK, freq->n2 - 1);
159
160 regmap_write(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0, reg);
161
162 reg = FIELD_PREP(CLK_CNTL1_M1_MASK, freq->m1 - 1);
163 if (freq->dualdiv)
164 reg |= FIELD_PREP(CLK_CNTL1_M2_MASK, freq->m2 - 1);
165
166 regmap_write(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL1, reg);
167
168 /* Enable clock */
169 regmap_update_bits(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0,
170 CLK_CNTL0_IN_GATE_EN, CLK_CNTL0_IN_GATE_EN);
171
172 udelay(200);
173
174 regmap_update_bits(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0,
175 CLK_CNTL0_OUT_GATE_EN, CLK_CNTL0_OUT_GATE_EN);
176
177 regmap_update_bits(cec_32k->regmap, AO_CRT_CLK_CNTL1,
178 CLK_CNTL1_SELECT_OSC, CLK_CNTL1_SELECT_OSC);
179
180 /* Select 32k from XTAL */
181 regmap_update_bits(cec_32k->regmap,
182 AO_RTI_PWR_CNTL_REG0,
183 PWR_CNTL_ALT_32K_SEL,
184 FIELD_PREP(PWR_CNTL_ALT_32K_SEL, 4));
185
186 return 0;
187}
188
189const struct clk_ops meson_aoclk_cec_32k_ops = {
190 .recalc_rate = aoclk_cec_32k_recalc_rate,
191 .round_rate = aoclk_cec_32k_round_rate,
192 .set_rate = aoclk_cec_32k_set_rate,
193};
diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c
index 42ed61d3c3fb..449f6ac189d8 100644
--- a/drivers/clk/meson/gxbb-aoclk.c
+++ b/drivers/clk/meson/gxbb-aoclk.c
@@ -5,10 +5,23 @@
5 */ 5 */
6#include <linux/platform_device.h> 6#include <linux/platform_device.h>
7#include <linux/mfd/syscon.h> 7#include <linux/mfd/syscon.h>
8#include "clk-regmap.h"
9#include "meson-aoclk.h" 8#include "meson-aoclk.h"
10#include "gxbb-aoclk.h" 9#include "gxbb-aoclk.h"
11 10
11#include "clk-regmap.h"
12#include "clk-dualdiv.h"
13
14#define IN_PREFIX "ao-in-"
15
16/* AO Configuration Clock registers offsets */
17#define AO_RTI_PWR_CNTL_REG1 0x0c
18#define AO_RTI_PWR_CNTL_REG0 0x10
19#define AO_RTI_GEN_CNTL_REG0 0x40
20#define AO_OSCIN_CNTL 0x58
21#define AO_CRT_CLK_CNTL1 0x68
22#define AO_RTC_ALT_CLK_CNTL0 0x94
23#define AO_RTC_ALT_CLK_CNTL1 0x98
24
12#define GXBB_AO_GATE(_name, _bit) \ 25#define GXBB_AO_GATE(_name, _bit) \
13static struct clk_regmap _name##_ao = { \ 26static struct clk_regmap _name##_ao = { \
14 .data = &(struct clk_regmap_gate_data) { \ 27 .data = &(struct clk_regmap_gate_data) { \
@@ -18,7 +31,7 @@ static struct clk_regmap _name##_ao = { \
18 .hw.init = &(struct clk_init_data) { \ 31 .hw.init = &(struct clk_init_data) { \
19 .name = #_name "_ao", \ 32 .name = #_name "_ao", \
20 .ops = &clk_regmap_gate_ops, \ 33 .ops = &clk_regmap_gate_ops, \
21 .parent_names = (const char *[]){ "clk81" }, \ 34 .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \
22 .num_parents = 1, \ 35 .num_parents = 1, \
23 .flags = CLK_IGNORE_UNUSED, \ 36 .flags = CLK_IGNORE_UNUSED, \
24 }, \ 37 }, \
@@ -31,13 +44,174 @@ GXBB_AO_GATE(uart1, 3);
31GXBB_AO_GATE(uart2, 5); 44GXBB_AO_GATE(uart2, 5);
32GXBB_AO_GATE(ir_blaster, 6); 45GXBB_AO_GATE(ir_blaster, 6);
33 46
34static struct aoclk_cec_32k cec_32k_ao = { 47static struct clk_regmap ao_cts_oscin = {
35 .hw.init = &(struct clk_init_data) { 48 .data = &(struct clk_regmap_gate_data){
36 .name = "cec_32k_ao", 49 .offset = AO_RTI_PWR_CNTL_REG0,
37 .ops = &meson_aoclk_cec_32k_ops, 50 .bit_idx = 6,
38 .parent_names = (const char *[]){ "xtal" }, 51 },
52 .hw.init = &(struct clk_init_data){
53 .name = "ao_cts_oscin",
54 .ops = &clk_regmap_gate_ro_ops,
55 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
56 .num_parents = 1,
57 },
58};
59
60static struct clk_regmap ao_32k_pre = {
61 .data = &(struct clk_regmap_gate_data){
62 .offset = AO_RTC_ALT_CLK_CNTL0,
63 .bit_idx = 31,
64 },
65 .hw.init = &(struct clk_init_data){
66 .name = "ao_32k_pre",
67 .ops = &clk_regmap_gate_ops,
68 .parent_names = (const char *[]){ "ao_cts_oscin" },
69 .num_parents = 1,
70 },
71};
72
73static const struct meson_clk_dualdiv_param gxbb_32k_div_table[] = {
74 {
75 .dual = 1,
76 .n1 = 733,
77 .m1 = 8,
78 .n2 = 732,
79 .m2 = 11,
80 }, {}
81};
82
83static struct clk_regmap ao_32k_div = {
84 .data = &(struct meson_clk_dualdiv_data){
85 .n1 = {
86 .reg_off = AO_RTC_ALT_CLK_CNTL0,
87 .shift = 0,
88 .width = 12,
89 },
90 .n2 = {
91 .reg_off = AO_RTC_ALT_CLK_CNTL0,
92 .shift = 12,
93 .width = 12,
94 },
95 .m1 = {
96 .reg_off = AO_RTC_ALT_CLK_CNTL1,
97 .shift = 0,
98 .width = 12,
99 },
100 .m2 = {
101 .reg_off = AO_RTC_ALT_CLK_CNTL1,
102 .shift = 12,
103 .width = 12,
104 },
105 .dual = {
106 .reg_off = AO_RTC_ALT_CLK_CNTL0,
107 .shift = 28,
108 .width = 1,
109 },
110 .table = gxbb_32k_div_table,
111 },
112 .hw.init = &(struct clk_init_data){
113 .name = "ao_32k_div",
114 .ops = &meson_clk_dualdiv_ops,
115 .parent_names = (const char *[]){ "ao_32k_pre" },
116 .num_parents = 1,
117 },
118};
119
120static struct clk_regmap ao_32k_sel = {
121 .data = &(struct clk_regmap_mux_data) {
122 .offset = AO_RTC_ALT_CLK_CNTL1,
123 .mask = 0x1,
124 .shift = 24,
125 .flags = CLK_MUX_ROUND_CLOSEST,
126 },
127 .hw.init = &(struct clk_init_data){
128 .name = "ao_32k_sel",
129 .ops = &clk_regmap_mux_ops,
130 .parent_names = (const char *[]){ "ao_32k_div",
131 "ao_32k_pre" },
132 .num_parents = 2,
133 .flags = CLK_SET_RATE_PARENT,
134 },
135};
136
137static struct clk_regmap ao_32k = {
138 .data = &(struct clk_regmap_gate_data){
139 .offset = AO_RTC_ALT_CLK_CNTL0,
140 .bit_idx = 30,
141 },
142 .hw.init = &(struct clk_init_data){
143 .name = "ao_32k",
144 .ops = &clk_regmap_gate_ops,
145 .parent_names = (const char *[]){ "ao_32k_sel" },
39 .num_parents = 1, 146 .num_parents = 1,
40 .flags = CLK_IGNORE_UNUSED, 147 .flags = CLK_SET_RATE_PARENT,
148 },
149};
150
151static struct clk_regmap ao_cts_rtc_oscin = {
152 .data = &(struct clk_regmap_mux_data) {
153 .offset = AO_RTI_PWR_CNTL_REG0,
154 .mask = 0x7,
155 .shift = 10,
156 .table = (u32[]){ 1, 2, 3, 4 },
157 .flags = CLK_MUX_ROUND_CLOSEST,
158 },
159 .hw.init = &(struct clk_init_data){
160 .name = "ao_cts_rtc_oscin",
161 .ops = &clk_regmap_mux_ops,
162 .parent_names = (const char *[]){ IN_PREFIX "ext-32k-0",
163 IN_PREFIX "ext-32k-1",
164 IN_PREFIX "ext-32k-2",
165 "ao_32k" },
166 .num_parents = 4,
167 .flags = CLK_SET_RATE_PARENT,
168 },
169};
170
171static struct clk_regmap ao_clk81 = {
172 .data = &(struct clk_regmap_mux_data) {
173 .offset = AO_RTI_PWR_CNTL_REG0,
174 .mask = 0x1,
175 .shift = 0,
176 .flags = CLK_MUX_ROUND_CLOSEST,
177 },
178 .hw.init = &(struct clk_init_data){
179 .name = "ao_clk81",
180 .ops = &clk_regmap_mux_ro_ops,
181 .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk",
182 "ao_cts_rtc_oscin" },
183 .num_parents = 2,
184 .flags = CLK_SET_RATE_PARENT,
185 },
186};
187
188static struct clk_regmap ao_cts_cec = {
189 .data = &(struct clk_regmap_mux_data) {
190 .offset = AO_CRT_CLK_CNTL1,
191 .mask = 0x1,
192 .shift = 27,
193 .flags = CLK_MUX_ROUND_CLOSEST,
194 },
195 .hw.init = &(struct clk_init_data){
196 .name = "ao_cts_cec",
197 .ops = &clk_regmap_mux_ops,
198 /*
199 * FIXME: The 'fixme' parent obviously does not exist.
200 *
201 * ATM, CCF won't call get_parent() if num_parents is 1. It
202 * does not allow NULL as a parent name either.
203 *
204 * On this particular mux, we only know the input #1 parent
205 * but, on boot, unknown input #0 is set, so it is critical
206 * to call .get_parent() on it
207 *
208 * Until CCF gets fixed, adding this fake parent that won't
209 * ever be registered should work around the problem
210 */
211 .parent_names = (const char *[]){ "fixme",
212 "ao_cts_rtc_oscin" },
213 .num_parents = 2,
214 .flags = CLK_SET_RATE_PARENT,
41 }, 215 },
42}; 216};
43 217
@@ -50,13 +224,21 @@ static const unsigned int gxbb_aoclk_reset[] = {
50 [RESET_AO_IR_BLASTER] = 23, 224 [RESET_AO_IR_BLASTER] = 23,
51}; 225};
52 226
53static struct clk_regmap *gxbb_aoclk_gate[] = { 227static struct clk_regmap *gxbb_aoclk[] = {
54 [CLKID_AO_REMOTE] = &remote_ao, 228 &remote_ao,
55 [CLKID_AO_I2C_MASTER] = &i2c_master_ao, 229 &i2c_master_ao,
56 [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao, 230 &i2c_slave_ao,
57 [CLKID_AO_UART1] = &uart1_ao, 231 &uart1_ao,
58 [CLKID_AO_UART2] = &uart2_ao, 232 &uart2_ao,
59 [CLKID_AO_IR_BLASTER] = &ir_blaster_ao, 233 &ir_blaster_ao,
234 &ao_cts_oscin,
235 &ao_32k_pre,
236 &ao_32k_div,
237 &ao_32k_sel,
238 &ao_32k,
239 &ao_cts_rtc_oscin,
240 &ao_clk81,
241 &ao_cts_cec,
60}; 242};
61 243
62static const struct clk_hw_onecell_data gxbb_aoclk_onecell_data = { 244static const struct clk_hw_onecell_data gxbb_aoclk_onecell_data = {
@@ -67,52 +249,38 @@ static const struct clk_hw_onecell_data gxbb_aoclk_onecell_data = {
67 [CLKID_AO_UART1] = &uart1_ao.hw, 249 [CLKID_AO_UART1] = &uart1_ao.hw,
68 [CLKID_AO_UART2] = &uart2_ao.hw, 250 [CLKID_AO_UART2] = &uart2_ao.hw,
69 [CLKID_AO_IR_BLASTER] = &ir_blaster_ao.hw, 251 [CLKID_AO_IR_BLASTER] = &ir_blaster_ao.hw,
70 [CLKID_AO_CEC_32K] = &cec_32k_ao.hw, 252 [CLKID_AO_CEC_32K] = &ao_cts_cec.hw,
253 [CLKID_AO_CTS_OSCIN] = &ao_cts_oscin.hw,
254 [CLKID_AO_32K_PRE] = &ao_32k_pre.hw,
255 [CLKID_AO_32K_DIV] = &ao_32k_div.hw,
256 [CLKID_AO_32K_SEL] = &ao_32k_sel.hw,
257 [CLKID_AO_32K] = &ao_32k.hw,
258 [CLKID_AO_CTS_RTC_OSCIN] = &ao_cts_rtc_oscin.hw,
259 [CLKID_AO_CLK81] = &ao_clk81.hw,
71 }, 260 },
72 .num = NR_CLKS, 261 .num = NR_CLKS,
73}; 262};
74 263
75static int gxbb_register_cec_ao_32k(struct platform_device *pdev) 264static const struct meson_aoclk_input gxbb_aoclk_inputs[] = {
76{ 265 { .name = "xtal", .required = true, },
77 struct device *dev = &pdev->dev; 266 { .name = "mpeg-clk", .required = true, },
78 struct regmap *regmap; 267 {. name = "ext-32k-0", .required = false, },
79 int ret; 268 {. name = "ext-32k-1", .required = false, },
80 269 {. name = "ext-32k-2", .required = false, },
81 regmap = syscon_node_to_regmap(of_get_parent(dev->of_node)); 270};
82 if (IS_ERR(regmap)) {
83 dev_err(dev, "failed to get regmap\n");
84 return PTR_ERR(regmap);
85 }
86
87 /* Specific clocks */
88 cec_32k_ao.regmap = regmap;
89 ret = devm_clk_hw_register(dev, &cec_32k_ao.hw);
90 if (ret) {
91 dev_err(&pdev->dev, "clk cec_32k_ao register failed.\n");
92 return ret;
93 }
94
95 return 0;
96}
97 271
98static const struct meson_aoclk_data gxbb_aoclkc_data = { 272static const struct meson_aoclk_data gxbb_aoclkc_data = {
99 .reset_reg = AO_RTI_GEN_CNTL_REG0, 273 .reset_reg = AO_RTI_GEN_CNTL_REG0,
100 .num_reset = ARRAY_SIZE(gxbb_aoclk_reset), 274 .num_reset = ARRAY_SIZE(gxbb_aoclk_reset),
101 .reset = gxbb_aoclk_reset, 275 .reset = gxbb_aoclk_reset,
102 .num_clks = ARRAY_SIZE(gxbb_aoclk_gate), 276 .num_clks = ARRAY_SIZE(gxbb_aoclk),
103 .clks = gxbb_aoclk_gate, 277 .clks = gxbb_aoclk,
104 .hw_data = &gxbb_aoclk_onecell_data, 278 .hw_data = &gxbb_aoclk_onecell_data,
279 .inputs = gxbb_aoclk_inputs,
280 .num_inputs = ARRAY_SIZE(gxbb_aoclk_inputs),
281 .input_prefix = IN_PREFIX,
105}; 282};
106 283
107static int gxbb_aoclkc_probe(struct platform_device *pdev)
108{
109 int ret = gxbb_register_cec_ao_32k(pdev);
110 if (ret)
111 return ret;
112
113 return meson_aoclkc_probe(pdev);
114}
115
116static const struct of_device_id gxbb_aoclkc_match_table[] = { 284static const struct of_device_id gxbb_aoclkc_match_table[] = {
117 { 285 {
118 .compatible = "amlogic,meson-gx-aoclkc", 286 .compatible = "amlogic,meson-gx-aoclkc",
@@ -122,7 +290,7 @@ static const struct of_device_id gxbb_aoclkc_match_table[] = {
122}; 290};
123 291
124static struct platform_driver gxbb_aoclkc_driver = { 292static struct platform_driver gxbb_aoclkc_driver = {
125 .probe = gxbb_aoclkc_probe, 293 .probe = meson_aoclkc_probe,
126 .driver = { 294 .driver = {
127 .name = "gxbb-aoclkc", 295 .name = "gxbb-aoclkc",
128 .of_match_table = gxbb_aoclkc_match_table, 296 .of_match_table = gxbb_aoclkc_match_table,
diff --git a/drivers/clk/meson/gxbb-aoclk.h b/drivers/clk/meson/gxbb-aoclk.h
index c514493d989a..1db16f9b37d4 100644
--- a/drivers/clk/meson/gxbb-aoclk.h
+++ b/drivers/clk/meson/gxbb-aoclk.h
@@ -7,25 +7,7 @@
7#ifndef __GXBB_AOCLKC_H 7#ifndef __GXBB_AOCLKC_H
8#define __GXBB_AOCLKC_H 8#define __GXBB_AOCLKC_H
9 9
10#define NR_CLKS 7 10#define NR_CLKS 14
11
12/* AO Configuration Clock registers offsets */
13#define AO_RTI_PWR_CNTL_REG1 0x0c
14#define AO_RTI_PWR_CNTL_REG0 0x10
15#define AO_RTI_GEN_CNTL_REG0 0x40
16#define AO_OSCIN_CNTL 0x58
17#define AO_CRT_CLK_CNTL1 0x68
18#define AO_RTC_ALT_CLK_CNTL0 0x94
19#define AO_RTC_ALT_CLK_CNTL1 0x98
20
21struct aoclk_cec_32k {
22 struct clk_hw hw;
23 struct regmap *regmap;
24};
25
26#define to_aoclk_cec_32k(_hw) container_of(_hw, struct aoclk_cec_32k, hw)
27
28extern const struct clk_ops meson_aoclk_cec_32k_ops;
29 11
30#include <dt-bindings/clock/gxbb-aoclkc.h> 12#include <dt-bindings/clock/gxbb-aoclkc.h>
31#include <dt-bindings/reset/gxbb-aoclkc.h> 13#include <dt-bindings/reset/gxbb-aoclkc.h>
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 65f2599e5243..04df2e208ed6 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -4,17 +4,20 @@
4 * Michael Turquette <mturquette@baylibre.com> 4 * Michael Turquette <mturquette@baylibre.com>
5 */ 5 */
6 6
7#include <linux/clk.h>
8#include <linux/clk-provider.h> 7#include <linux/clk-provider.h>
9#include <linux/init.h> 8#include <linux/init.h>
10#include <linux/of_device.h> 9#include <linux/of_device.h>
11#include <linux/mfd/syscon.h>
12#include <linux/platform_device.h> 10#include <linux/platform_device.h>
13#include <linux/regmap.h>
14 11
15#include "clkc.h"
16#include "gxbb.h" 12#include "gxbb.h"
13#include "clk-input.h"
17#include "clk-regmap.h" 14#include "clk-regmap.h"
15#include "clk-pll.h"
16#include "clk-mpll.h"
17#include "meson-eeclk.h"
18#include "vid-pll-div.h"
19
20#define IN_PREFIX "ee-in-"
18 21
19static DEFINE_SPINLOCK(meson_clk_lock); 22static DEFINE_SPINLOCK(meson_clk_lock);
20 23
@@ -118,7 +121,7 @@ static struct clk_regmap gxbb_fixed_pll_dco = {
118 .hw.init = &(struct clk_init_data){ 121 .hw.init = &(struct clk_init_data){
119 .name = "fixed_pll_dco", 122 .name = "fixed_pll_dco",
120 .ops = &meson_clk_pll_ro_ops, 123 .ops = &meson_clk_pll_ro_ops,
121 .parent_names = (const char *[]){ "xtal" }, 124 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
122 .num_parents = 1, 125 .num_parents = 1,
123 }, 126 },
124}; 127};
@@ -148,7 +151,7 @@ static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = {
148 .hw.init = &(struct clk_init_data){ 151 .hw.init = &(struct clk_init_data){
149 .name = "hdmi_pll_pre_mult", 152 .name = "hdmi_pll_pre_mult",
150 .ops = &clk_fixed_factor_ops, 153 .ops = &clk_fixed_factor_ops,
151 .parent_names = (const char *[]){ "xtal" }, 154 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
152 .num_parents = 1, 155 .num_parents = 1,
153 }, 156 },
154}; 157};
@@ -241,7 +244,7 @@ static struct clk_regmap gxl_hdmi_pll_dco = {
241 .hw.init = &(struct clk_init_data){ 244 .hw.init = &(struct clk_init_data){
242 .name = "hdmi_pll_dco", 245 .name = "hdmi_pll_dco",
243 .ops = &meson_clk_pll_ro_ops, 246 .ops = &meson_clk_pll_ro_ops,
244 .parent_names = (const char *[]){ "xtal" }, 247 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
245 .num_parents = 1, 248 .num_parents = 1,
246 /* 249 /*
247 * Display directly handle hdmi pll registers ATM, we need 250 * Display directly handle hdmi pll registers ATM, we need
@@ -378,7 +381,7 @@ static struct clk_regmap gxbb_sys_pll_dco = {
378 .hw.init = &(struct clk_init_data){ 381 .hw.init = &(struct clk_init_data){
379 .name = "sys_pll_dco", 382 .name = "sys_pll_dco",
380 .ops = &meson_clk_pll_ro_ops, 383 .ops = &meson_clk_pll_ro_ops,
381 .parent_names = (const char *[]){ "xtal" }, 384 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
382 .num_parents = 1, 385 .num_parents = 1,
383 }, 386 },
384}; 387};
@@ -439,7 +442,7 @@ static struct clk_regmap gxbb_gp0_pll_dco = {
439 .hw.init = &(struct clk_init_data){ 442 .hw.init = &(struct clk_init_data){
440 .name = "gp0_pll_dco", 443 .name = "gp0_pll_dco",
441 .ops = &meson_clk_pll_ops, 444 .ops = &meson_clk_pll_ops,
442 .parent_names = (const char *[]){ "xtal" }, 445 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
443 .num_parents = 1, 446 .num_parents = 1,
444 }, 447 },
445}; 448};
@@ -491,7 +494,7 @@ static struct clk_regmap gxl_gp0_pll_dco = {
491 .hw.init = &(struct clk_init_data){ 494 .hw.init = &(struct clk_init_data){
492 .name = "gp0_pll_dco", 495 .name = "gp0_pll_dco",
493 .ops = &meson_clk_pll_ops, 496 .ops = &meson_clk_pll_ops,
494 .parent_names = (const char *[]){ "xtal" }, 497 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
495 .num_parents = 1, 498 .num_parents = 1,
496 }, 499 },
497}; 500};
@@ -789,7 +792,7 @@ static struct clk_regmap gxbb_mpll2 = {
789 792
790static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; 793static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 };
791static const char * const clk81_parent_names[] = { 794static const char * const clk81_parent_names[] = {
792 "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4", 795 IN_PREFIX "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
793 "fclk_div3", "fclk_div5" 796 "fclk_div3", "fclk_div5"
794}; 797};
795 798
@@ -852,7 +855,7 @@ static struct clk_regmap gxbb_sar_adc_clk_sel = {
852 .name = "sar_adc_clk_sel", 855 .name = "sar_adc_clk_sel",
853 .ops = &clk_regmap_mux_ops, 856 .ops = &clk_regmap_mux_ops,
854 /* NOTE: The datasheet doesn't list the parents for bit 10 */ 857 /* NOTE: The datasheet doesn't list the parents for bit 10 */
855 .parent_names = (const char *[]){ "xtal", "clk81", }, 858 .parent_names = (const char *[]){ IN_PREFIX "xtal", "clk81", },
856 .num_parents = 2, 859 .num_parents = 2,
857 }, 860 },
858}; 861};
@@ -891,7 +894,7 @@ static struct clk_regmap gxbb_sar_adc_clk = {
891 */ 894 */
892 895
893static const char * const gxbb_mali_0_1_parent_names[] = { 896static const char * const gxbb_mali_0_1_parent_names[] = {
894 "xtal", "gp0_pll", "mpll2", "mpll1", "fclk_div7", 897 IN_PREFIX "xtal", "gp0_pll", "mpll2", "mpll1", "fclk_div7",
895 "fclk_div4", "fclk_div3", "fclk_div5" 898 "fclk_div4", "fclk_div3", "fclk_div5"
896}; 899};
897 900
@@ -1153,7 +1156,7 @@ static struct clk_regmap gxbb_32k_clk = {
1153}; 1156};
1154 1157
1155static const char * const gxbb_32k_clk_parent_names[] = { 1158static const char * const gxbb_32k_clk_parent_names[] = {
1156 "xtal", "cts_slow_oscin", "fclk_div3", "fclk_div5" 1159 IN_PREFIX "xtal", "cts_slow_oscin", "fclk_div3", "fclk_div5"
1157}; 1160};
1158 1161
1159static struct clk_regmap gxbb_32k_clk_sel = { 1162static struct clk_regmap gxbb_32k_clk_sel = {
@@ -1172,7 +1175,7 @@ static struct clk_regmap gxbb_32k_clk_sel = {
1172}; 1175};
1173 1176
1174static const char * const gxbb_sd_emmc_clk0_parent_names[] = { 1177static const char * const gxbb_sd_emmc_clk0_parent_names[] = {
1175 "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7", 1178 IN_PREFIX "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
1176 1179
1177 /* 1180 /*
1178 * Following these parent clocks, we should also have had mpll2, mpll3 1181 * Following these parent clocks, we should also have had mpll2, mpll3
@@ -2138,7 +2141,7 @@ static struct clk_regmap gxbb_hdmi_tx = {
2138/* HDMI Clocks */ 2141/* HDMI Clocks */
2139 2142
2140static const char * const gxbb_hdmi_parent_names[] = { 2143static const char * const gxbb_hdmi_parent_names[] = {
2141 "xtal", "fclk_div4", "fclk_div3", "fclk_div5" 2144 IN_PREFIX "xtal", "fclk_div4", "fclk_div3", "fclk_div5"
2142}; 2145};
2143 2146
2144static struct clk_regmap gxbb_hdmi_sel = { 2147static struct clk_regmap gxbb_hdmi_sel = {
@@ -2285,7 +2288,7 @@ static struct clk_regmap gxbb_vdec_hevc = {
2285static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8, 2288static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8,
2286 9, 10, 11, 13, 14, }; 2289 9, 10, 11, 13, 14, };
2287static const char * const gen_clk_parent_names[] = { 2290static const char * const gen_clk_parent_names[] = {
2288 "xtal", "vdec_1", "vdec_hevc", "mpll0", "mpll1", "mpll2", 2291 IN_PREFIX "xtal", "vdec_1", "vdec_hevc", "mpll0", "mpll1", "mpll2",
2289 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll", 2292 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll",
2290}; 2293};
2291 2294
@@ -2854,6 +2857,192 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
2854}; 2857};
2855 2858
2856static struct clk_regmap *const gxbb_clk_regmaps[] = { 2859static struct clk_regmap *const gxbb_clk_regmaps[] = {
2860 &gxbb_clk81,
2861 &gxbb_ddr,
2862 &gxbb_dos,
2863 &gxbb_isa,
2864 &gxbb_pl301,
2865 &gxbb_periphs,
2866 &gxbb_spicc,
2867 &gxbb_i2c,
2868 &gxbb_sar_adc,
2869 &gxbb_smart_card,
2870 &gxbb_rng0,
2871 &gxbb_uart0,
2872 &gxbb_sdhc,
2873 &gxbb_stream,
2874 &gxbb_async_fifo,
2875 &gxbb_sdio,
2876 &gxbb_abuf,
2877 &gxbb_hiu_iface,
2878 &gxbb_assist_misc,
2879 &gxbb_spi,
2880 &gxbb_i2s_spdif,
2881 &gxbb_eth,
2882 &gxbb_demux,
2883 &gxbb_aiu_glue,
2884 &gxbb_iec958,
2885 &gxbb_i2s_out,
2886 &gxbb_amclk,
2887 &gxbb_aififo2,
2888 &gxbb_mixer,
2889 &gxbb_mixer_iface,
2890 &gxbb_adc,
2891 &gxbb_blkmv,
2892 &gxbb_aiu,
2893 &gxbb_uart1,
2894 &gxbb_g2d,
2895 &gxbb_usb0,
2896 &gxbb_usb1,
2897 &gxbb_reset,
2898 &gxbb_nand,
2899 &gxbb_dos_parser,
2900 &gxbb_usb,
2901 &gxbb_vdin1,
2902 &gxbb_ahb_arb0,
2903 &gxbb_efuse,
2904 &gxbb_boot_rom,
2905 &gxbb_ahb_data_bus,
2906 &gxbb_ahb_ctrl_bus,
2907 &gxbb_hdmi_intr_sync,
2908 &gxbb_hdmi_pclk,
2909 &gxbb_usb1_ddr_bridge,
2910 &gxbb_usb0_ddr_bridge,
2911 &gxbb_mmc_pclk,
2912 &gxbb_dvin,
2913 &gxbb_uart2,
2914 &gxbb_sana,
2915 &gxbb_vpu_intr,
2916 &gxbb_sec_ahb_ahb3_bridge,
2917 &gxbb_clk81_a53,
2918 &gxbb_vclk2_venci0,
2919 &gxbb_vclk2_venci1,
2920 &gxbb_vclk2_vencp0,
2921 &gxbb_vclk2_vencp1,
2922 &gxbb_gclk_venci_int0,
2923 &gxbb_gclk_vencp_int,
2924 &gxbb_dac_clk,
2925 &gxbb_aoclk_gate,
2926 &gxbb_iec958_gate,
2927 &gxbb_enc480p,
2928 &gxbb_rng1,
2929 &gxbb_gclk_venci_int1,
2930 &gxbb_vclk2_venclmcc,
2931 &gxbb_vclk2_vencl,
2932 &gxbb_vclk_other,
2933 &gxbb_edp,
2934 &gxbb_ao_media_cpu,
2935 &gxbb_ao_ahb_sram,
2936 &gxbb_ao_ahb_bus,
2937 &gxbb_ao_iface,
2938 &gxbb_ao_i2c,
2939 &gxbb_emmc_a,
2940 &gxbb_emmc_b,
2941 &gxbb_emmc_c,
2942 &gxbb_sar_adc_clk,
2943 &gxbb_mali_0,
2944 &gxbb_mali_1,
2945 &gxbb_cts_amclk,
2946 &gxbb_cts_mclk_i958,
2947 &gxbb_32k_clk,
2948 &gxbb_sd_emmc_a_clk0,
2949 &gxbb_sd_emmc_b_clk0,
2950 &gxbb_sd_emmc_c_clk0,
2951 &gxbb_vpu_0,
2952 &gxbb_vpu_1,
2953 &gxbb_vapb_0,
2954 &gxbb_vapb_1,
2955 &gxbb_vapb,
2956 &gxbb_mpeg_clk_div,
2957 &gxbb_sar_adc_clk_div,
2958 &gxbb_mali_0_div,
2959 &gxbb_mali_1_div,
2960 &gxbb_cts_mclk_i958_div,
2961 &gxbb_32k_clk_div,
2962 &gxbb_sd_emmc_a_clk0_div,
2963 &gxbb_sd_emmc_b_clk0_div,
2964 &gxbb_sd_emmc_c_clk0_div,
2965 &gxbb_vpu_0_div,
2966 &gxbb_vpu_1_div,
2967 &gxbb_vapb_0_div,
2968 &gxbb_vapb_1_div,
2969 &gxbb_mpeg_clk_sel,
2970 &gxbb_sar_adc_clk_sel,
2971 &gxbb_mali_0_sel,
2972 &gxbb_mali_1_sel,
2973 &gxbb_mali,
2974 &gxbb_cts_amclk_sel,
2975 &gxbb_cts_mclk_i958_sel,
2976 &gxbb_cts_i958,
2977 &gxbb_32k_clk_sel,
2978 &gxbb_sd_emmc_a_clk0_sel,
2979 &gxbb_sd_emmc_b_clk0_sel,
2980 &gxbb_sd_emmc_c_clk0_sel,
2981 &gxbb_vpu_0_sel,
2982 &gxbb_vpu_1_sel,
2983 &gxbb_vpu,
2984 &gxbb_vapb_0_sel,
2985 &gxbb_vapb_1_sel,
2986 &gxbb_vapb_sel,
2987 &gxbb_mpll0,
2988 &gxbb_mpll1,
2989 &gxbb_mpll2,
2990 &gxbb_mpll0_div,
2991 &gxbb_mpll1_div,
2992 &gxbb_mpll2_div,
2993 &gxbb_cts_amclk_div,
2994 &gxbb_fixed_pll,
2995 &gxbb_sys_pll,
2996 &gxbb_mpll_prediv,
2997 &gxbb_fclk_div2,
2998 &gxbb_fclk_div3,
2999 &gxbb_fclk_div4,
3000 &gxbb_fclk_div5,
3001 &gxbb_fclk_div7,
3002 &gxbb_vdec_1_sel,
3003 &gxbb_vdec_1_div,
3004 &gxbb_vdec_1,
3005 &gxbb_vdec_hevc_sel,
3006 &gxbb_vdec_hevc_div,
3007 &gxbb_vdec_hevc,
3008 &gxbb_gen_clk_sel,
3009 &gxbb_gen_clk_div,
3010 &gxbb_gen_clk,
3011 &gxbb_fixed_pll_dco,
3012 &gxbb_sys_pll_dco,
3013 &gxbb_gp0_pll,
3014 &gxbb_vid_pll,
3015 &gxbb_vid_pll_sel,
3016 &gxbb_vid_pll_div,
3017 &gxbb_vclk,
3018 &gxbb_vclk_sel,
3019 &gxbb_vclk_div,
3020 &gxbb_vclk_input,
3021 &gxbb_vclk_div1,
3022 &gxbb_vclk_div2_en,
3023 &gxbb_vclk_div4_en,
3024 &gxbb_vclk_div6_en,
3025 &gxbb_vclk_div12_en,
3026 &gxbb_vclk2,
3027 &gxbb_vclk2_sel,
3028 &gxbb_vclk2_div,
3029 &gxbb_vclk2_input,
3030 &gxbb_vclk2_div1,
3031 &gxbb_vclk2_div2_en,
3032 &gxbb_vclk2_div4_en,
3033 &gxbb_vclk2_div6_en,
3034 &gxbb_vclk2_div12_en,
3035 &gxbb_cts_enci,
3036 &gxbb_cts_enci_sel,
3037 &gxbb_cts_encp,
3038 &gxbb_cts_encp_sel,
3039 &gxbb_cts_vdac,
3040 &gxbb_cts_vdac_sel,
3041 &gxbb_hdmi_tx,
3042 &gxbb_hdmi_tx_sel,
3043 &gxbb_hdmi_sel,
3044 &gxbb_hdmi_div,
3045 &gxbb_hdmi,
2857 &gxbb_gp0_pll_dco, 3046 &gxbb_gp0_pll_dco,
2858 &gxbb_hdmi_pll, 3047 &gxbb_hdmi_pll,
2859 &gxbb_hdmi_pll_od, 3048 &gxbb_hdmi_pll_od,
@@ -2862,14 +3051,6 @@ static struct clk_regmap *const gxbb_clk_regmaps[] = {
2862}; 3051};
2863 3052
2864static struct clk_regmap *const gxl_clk_regmaps[] = { 3053static struct clk_regmap *const gxl_clk_regmaps[] = {
2865 &gxl_gp0_pll_dco,
2866 &gxl_hdmi_pll,
2867 &gxl_hdmi_pll_od,
2868 &gxl_hdmi_pll_od2,
2869 &gxl_hdmi_pll_dco,
2870};
2871
2872static struct clk_regmap *const gx_clk_regmaps[] = {
2873 &gxbb_clk81, 3054 &gxbb_clk81,
2874 &gxbb_ddr, 3055 &gxbb_ddr,
2875 &gxbb_dos, 3056 &gxbb_dos,
@@ -3056,23 +3237,22 @@ static struct clk_regmap *const gx_clk_regmaps[] = {
3056 &gxbb_hdmi_sel, 3237 &gxbb_hdmi_sel,
3057 &gxbb_hdmi_div, 3238 &gxbb_hdmi_div,
3058 &gxbb_hdmi, 3239 &gxbb_hdmi,
3240 &gxl_gp0_pll_dco,
3241 &gxl_hdmi_pll,
3242 &gxl_hdmi_pll_od,
3243 &gxl_hdmi_pll_od2,
3244 &gxl_hdmi_pll_dco,
3059}; 3245};
3060 3246
3061struct clkc_data { 3247static const struct meson_eeclkc_data gxbb_clkc_data = {
3062 struct clk_regmap *const *regmap_clks;
3063 unsigned int regmap_clks_count;
3064 struct clk_hw_onecell_data *hw_onecell_data;
3065};
3066
3067static const struct clkc_data gxbb_clkc_data = {
3068 .regmap_clks = gxbb_clk_regmaps, 3248 .regmap_clks = gxbb_clk_regmaps,
3069 .regmap_clks_count = ARRAY_SIZE(gxbb_clk_regmaps), 3249 .regmap_clk_num = ARRAY_SIZE(gxbb_clk_regmaps),
3070 .hw_onecell_data = &gxbb_hw_onecell_data, 3250 .hw_onecell_data = &gxbb_hw_onecell_data,
3071}; 3251};
3072 3252
3073static const struct clkc_data gxl_clkc_data = { 3253static const struct meson_eeclkc_data gxl_clkc_data = {
3074 .regmap_clks = gxl_clk_regmaps, 3254 .regmap_clks = gxl_clk_regmaps,
3075 .regmap_clks_count = ARRAY_SIZE(gxl_clk_regmaps), 3255 .regmap_clk_num = ARRAY_SIZE(gxl_clk_regmaps),
3076 .hw_onecell_data = &gxl_hw_onecell_data, 3256 .hw_onecell_data = &gxl_hw_onecell_data,
3077}; 3257};
3078 3258
@@ -3082,52 +3262,8 @@ static const struct of_device_id clkc_match_table[] = {
3082 {}, 3262 {},
3083}; 3263};
3084 3264
3085static int gxbb_clkc_probe(struct platform_device *pdev)
3086{
3087 const struct clkc_data *clkc_data;
3088 struct regmap *map;
3089 int ret, i;
3090 struct device *dev = &pdev->dev;
3091
3092 clkc_data = of_device_get_match_data(dev);
3093 if (!clkc_data)
3094 return -EINVAL;
3095
3096 /* Get the hhi system controller node if available */
3097 map = syscon_node_to_regmap(of_get_parent(dev->of_node));
3098 if (IS_ERR(map)) {
3099 dev_err(dev, "failed to get HHI regmap\n");
3100 return PTR_ERR(map);
3101 }
3102
3103 /* Populate regmap for the common regmap backed clocks */
3104 for (i = 0; i < ARRAY_SIZE(gx_clk_regmaps); i++)
3105 gx_clk_regmaps[i]->map = map;
3106
3107 /* Populate regmap for soc specific clocks */
3108 for (i = 0; i < clkc_data->regmap_clks_count; i++)
3109 clkc_data->regmap_clks[i]->map = map;
3110
3111 /* Register all clks */
3112 for (i = 0; i < clkc_data->hw_onecell_data->num; i++) {
3113 /* array might be sparse */
3114 if (!clkc_data->hw_onecell_data->hws[i])
3115 continue;
3116
3117 ret = devm_clk_hw_register(dev,
3118 clkc_data->hw_onecell_data->hws[i]);
3119 if (ret) {
3120 dev_err(dev, "Clock registration failed\n");
3121 return ret;
3122 }
3123 }
3124
3125 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
3126 clkc_data->hw_onecell_data);
3127}
3128
3129static struct platform_driver gxbb_driver = { 3265static struct platform_driver gxbb_driver = {
3130 .probe = gxbb_clkc_probe, 3266 .probe = meson_eeclkc_probe,
3131 .driver = { 3267 .driver = {
3132 .name = "gxbb-clkc", 3268 .name = "gxbb-clkc",
3133 .of_match_table = clkc_match_table, 3269 .of_match_table = clkc_match_table,
diff --git a/drivers/clk/meson/meson-aoclk.c b/drivers/clk/meson/meson-aoclk.c
index f965845917e3..b67951909e04 100644
--- a/drivers/clk/meson/meson-aoclk.c
+++ b/drivers/clk/meson/meson-aoclk.c
@@ -14,9 +14,11 @@
14#include <linux/reset-controller.h> 14#include <linux/reset-controller.h>
15#include <linux/mfd/syscon.h> 15#include <linux/mfd/syscon.h>
16#include <linux/of_device.h> 16#include <linux/of_device.h>
17#include "clk-regmap.h" 17#include <linux/slab.h>
18#include "meson-aoclk.h" 18#include "meson-aoclk.h"
19 19
20#include "clk-input.h"
21
20static int meson_aoclk_do_reset(struct reset_controller_dev *rcdev, 22static int meson_aoclk_do_reset(struct reset_controller_dev *rcdev,
21 unsigned long id) 23 unsigned long id)
22{ 24{
@@ -31,6 +33,37 @@ static const struct reset_control_ops meson_aoclk_reset_ops = {
31 .reset = meson_aoclk_do_reset, 33 .reset = meson_aoclk_do_reset,
32}; 34};
33 35
36static int meson_aoclkc_register_inputs(struct device *dev,
37 struct meson_aoclk_data *data)
38{
39 struct clk_hw *hw;
40 char *str;
41 int i;
42
43 for (i = 0; i < data->num_inputs; i++) {
44 const struct meson_aoclk_input *in = &data->inputs[i];
45
46 str = kasprintf(GFP_KERNEL, "%s%s", data->input_prefix,
47 in->name);
48 if (!str)
49 return -ENOMEM;
50
51 hw = meson_clk_hw_register_input(dev, in->name, str, 0);
52 kfree(str);
53
54 if (IS_ERR(hw)) {
55 if (!in->required && PTR_ERR(hw) == -ENOENT)
56 continue;
57 else if (PTR_ERR(hw) != -EPROBE_DEFER)
58 dev_err(dev, "failed to register input %s\n",
59 in->name);
60 return PTR_ERR(hw);
61 }
62 }
63
64 return 0;
65}
66
34int meson_aoclkc_probe(struct platform_device *pdev) 67int meson_aoclkc_probe(struct platform_device *pdev)
35{ 68{
36 struct meson_aoclk_reset_controller *rstc; 69 struct meson_aoclk_reset_controller *rstc;
@@ -53,6 +86,10 @@ int meson_aoclkc_probe(struct platform_device *pdev)
53 return PTR_ERR(regmap); 86 return PTR_ERR(regmap);
54 } 87 }
55 88
89 ret = meson_aoclkc_register_inputs(dev, data);
90 if (ret)
91 return ret;
92
56 /* Reset Controller */ 93 /* Reset Controller */
57 rstc->data = data; 94 rstc->data = data;
58 rstc->regmap = regmap; 95 rstc->regmap = regmap;
@@ -65,15 +102,20 @@ int meson_aoclkc_probe(struct platform_device *pdev)
65 return ret; 102 return ret;
66 } 103 }
67 104
68 /* 105 /* Populate regmap */
69 * Populate regmap and register all clks 106 for (clkid = 0; clkid < data->num_clks; clkid++)
70 */
71 for (clkid = 0; clkid < data->num_clks; clkid++) {
72 data->clks[clkid]->map = regmap; 107 data->clks[clkid]->map = regmap;
73 108
109 /* Register all clks */
110 for (clkid = 0; clkid < data->hw_data->num; clkid++) {
111 if (!data->hw_data->hws[clkid])
112 continue;
113
74 ret = devm_clk_hw_register(dev, data->hw_data->hws[clkid]); 114 ret = devm_clk_hw_register(dev, data->hw_data->hws[clkid]);
75 if (ret) 115 if (ret) {
116 dev_err(dev, "Clock registration failed\n");
76 return ret; 117 return ret;
118 }
77 } 119 }
78 120
79 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, 121 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
diff --git a/drivers/clk/meson/meson-aoclk.h b/drivers/clk/meson/meson-aoclk.h
index ab2819e88922..999cde3868f7 100644
--- a/drivers/clk/meson/meson-aoclk.h
+++ b/drivers/clk/meson/meson-aoclk.h
@@ -11,16 +11,27 @@
11#ifndef __MESON_AOCLK_H__ 11#ifndef __MESON_AOCLK_H__
12#define __MESON_AOCLK_H__ 12#define __MESON_AOCLK_H__
13 13
14#include <linux/clk-provider.h>
14#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/regmap.h>
15#include <linux/reset-controller.h> 17#include <linux/reset-controller.h>
18
16#include "clk-regmap.h" 19#include "clk-regmap.h"
17 20
21struct meson_aoclk_input {
22 const char *name;
23 bool required;
24};
25
18struct meson_aoclk_data { 26struct meson_aoclk_data {
19 const unsigned int reset_reg; 27 const unsigned int reset_reg;
20 const int num_reset; 28 const int num_reset;
21 const unsigned int *reset; 29 const unsigned int *reset;
22 int num_clks; 30 const int num_clks;
23 struct clk_regmap **clks; 31 struct clk_regmap **clks;
32 const int num_inputs;
33 const struct meson_aoclk_input *inputs;
34 const char *input_prefix;
24 const struct clk_hw_onecell_data *hw_data; 35 const struct clk_hw_onecell_data *hw_data;
25}; 36};
26 37
diff --git a/drivers/clk/meson/meson-eeclk.c b/drivers/clk/meson/meson-eeclk.c
new file mode 100644
index 000000000000..37a34c9c3885
--- /dev/null
+++ b/drivers/clk/meson/meson-eeclk.c
@@ -0,0 +1,63 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2019 BayLibre, SAS.
4 * Author: Jerome Brunet <jbrunet@baylibre.com>
5 */
6
7#include <linux/clk-provider.h>
8#include <linux/of_device.h>
9#include <linux/platform_device.h>
10#include <linux/mfd/syscon.h>
11#include <linux/regmap.h>
12
13#include "clk-input.h"
14#include "clk-regmap.h"
15#include "meson-eeclk.h"
16
17int meson_eeclkc_probe(struct platform_device *pdev)
18{
19 const struct meson_eeclkc_data *data;
20 struct device *dev = &pdev->dev;
21 struct clk_hw *input;
22 struct regmap *map;
23 int ret, i;
24
25 data = of_device_get_match_data(dev);
26 if (!data)
27 return -EINVAL;
28
29 /* Get the hhi system controller node */
30 map = syscon_node_to_regmap(of_get_parent(dev->of_node));
31 if (IS_ERR(map)) {
32 dev_err(dev,
33 "failed to get HHI regmap\n");
34 return PTR_ERR(map);
35 }
36
37 input = meson_clk_hw_register_input(dev, "xtal", IN_PREFIX "xtal", 0);
38 if (IS_ERR(input)) {
39 ret = PTR_ERR(input);
40 if (ret != -EPROBE_DEFER)
41 dev_err(dev, "failed to get input clock");
42 return ret;
43 }
44
45 /* Populate regmap for the regmap backed clocks */
46 for (i = 0; i < data->regmap_clk_num; i++)
47 data->regmap_clks[i]->map = map;
48
49 for (i = 0; i < data->hw_onecell_data->num; i++) {
50 /* array might be sparse */
51 if (!data->hw_onecell_data->hws[i])
52 continue;
53
54 ret = devm_clk_hw_register(dev, data->hw_onecell_data->hws[i]);
55 if (ret) {
56 dev_err(dev, "Clock registration failed\n");
57 return ret;
58 }
59 }
60
61 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
62 data->hw_onecell_data);
63}
diff --git a/drivers/clk/meson/meson-eeclk.h b/drivers/clk/meson/meson-eeclk.h
new file mode 100644
index 000000000000..1b809b1419fe
--- /dev/null
+++ b/drivers/clk/meson/meson-eeclk.h
@@ -0,0 +1,25 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2019 BayLibre, SAS.
4 * Author: Jerome Brunet <jbrunet@baylibre.com>
5 */
6
7#ifndef __MESON_CLKC_H
8#define __MESON_CLKC_H
9
10#include <linux/clk-provider.h>
11#include "clk-regmap.h"
12
13#define IN_PREFIX "ee-in-"
14
15struct platform_device;
16
17struct meson_eeclkc_data {
18 struct clk_regmap *const *regmap_clks;
19 unsigned int regmap_clk_num;
20 struct clk_hw_onecell_data *hw_onecell_data;
21};
22
23int meson_eeclkc_probe(struct platform_device *pdev);
24
25#endif /* __MESON_CLKC_H */
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index 950d0e548c75..576ad42252d0 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -16,9 +16,10 @@
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/regmap.h> 17#include <linux/regmap.h>
18 18
19#include "clkc.h"
20#include "meson8b.h" 19#include "meson8b.h"
21#include "clk-regmap.h" 20#include "clk-regmap.h"
21#include "clk-pll.h"
22#include "clk-mpll.h"
22 23
23static DEFINE_SPINLOCK(meson_clk_lock); 24static DEFINE_SPINLOCK(meson_clk_lock);
24 25
@@ -803,16 +804,16 @@ static struct clk_fixed_factor meson8b_cpu_clk_div8 = {
803 }, 804 },
804}; 805};
805 806
806static u32 mux_table_abp[] = { 1, 2, 3, 4, 5, 6, 7 }; 807static u32 mux_table_apb[] = { 1, 2, 3, 4, 5, 6, 7 };
807static struct clk_regmap meson8b_abp_clk_sel = { 808static struct clk_regmap meson8b_apb_clk_sel = {
808 .data = &(struct clk_regmap_mux_data){ 809 .data = &(struct clk_regmap_mux_data){
809 .offset = HHI_SYS_CPU_CLK_CNTL1, 810 .offset = HHI_SYS_CPU_CLK_CNTL1,
810 .mask = 0x7, 811 .mask = 0x7,
811 .shift = 3, 812 .shift = 3,
812 .table = mux_table_abp, 813 .table = mux_table_apb,
813 }, 814 },
814 .hw.init = &(struct clk_init_data){ 815 .hw.init = &(struct clk_init_data){
815 .name = "abp_clk_sel", 816 .name = "apb_clk_sel",
816 .ops = &clk_regmap_mux_ops, 817 .ops = &clk_regmap_mux_ops,
817 .parent_names = (const char *[]){ "cpu_clk_div2", 818 .parent_names = (const char *[]){ "cpu_clk_div2",
818 "cpu_clk_div3", 819 "cpu_clk_div3",
@@ -825,16 +826,16 @@ static struct clk_regmap meson8b_abp_clk_sel = {
825 }, 826 },
826}; 827};
827 828
828static struct clk_regmap meson8b_abp_clk_gate = { 829static struct clk_regmap meson8b_apb_clk_gate = {
829 .data = &(struct clk_regmap_gate_data){ 830 .data = &(struct clk_regmap_gate_data){
830 .offset = HHI_SYS_CPU_CLK_CNTL1, 831 .offset = HHI_SYS_CPU_CLK_CNTL1,
831 .bit_idx = 16, 832 .bit_idx = 16,
832 .flags = CLK_GATE_SET_TO_DISABLE, 833 .flags = CLK_GATE_SET_TO_DISABLE,
833 }, 834 },
834 .hw.init = &(struct clk_init_data){ 835 .hw.init = &(struct clk_init_data){
835 .name = "abp_clk_dis", 836 .name = "apb_clk_dis",
836 .ops = &clk_regmap_gate_ro_ops, 837 .ops = &clk_regmap_gate_ro_ops,
837 .parent_names = (const char *[]){ "abp_clk_sel" }, 838 .parent_names = (const char *[]){ "apb_clk_sel" },
838 .num_parents = 1, 839 .num_parents = 1,
839 .flags = CLK_SET_RATE_PARENT, 840 .flags = CLK_SET_RATE_PARENT,
840 }, 841 },
@@ -1573,6 +1574,135 @@ static struct clk_regmap meson8b_hdmi_sys = {
1573 }, 1574 },
1574}; 1575};
1575 1576
1577/*
1578 * The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
1579 * muxed by a glitch-free switch on Meson8b and Meson8m2. Meson8 only
1580 * has mali_0 and no glitch-free mux.
1581 */
1582static const char * const meson8b_mali_0_1_parent_names[] = {
1583 "xtal", "mpll2", "mpll1", "fclk_div7", "fclk_div4", "fclk_div3",
1584 "fclk_div5"
1585};
1586
1587static u32 meson8b_mali_0_1_mux_table[] = { 0, 2, 3, 4, 5, 6, 7 };
1588
1589static struct clk_regmap meson8b_mali_0_sel = {
1590 .data = &(struct clk_regmap_mux_data){
1591 .offset = HHI_MALI_CLK_CNTL,
1592 .mask = 0x7,
1593 .shift = 9,
1594 .table = meson8b_mali_0_1_mux_table,
1595 },
1596 .hw.init = &(struct clk_init_data){
1597 .name = "mali_0_sel",
1598 .ops = &clk_regmap_mux_ops,
1599 .parent_names = meson8b_mali_0_1_parent_names,
1600 .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_names),
1601 /*
1602 * Don't propagate rate changes up because the only changeable
1603 * parents are mpll1 and mpll2 but we need those for audio and
1604 * RGMII (Ethernet). We don't want to change the audio or
1605 * Ethernet clocks when setting the GPU frequency.
1606 */
1607 .flags = 0,
1608 },
1609};
1610
1611static struct clk_regmap meson8b_mali_0_div = {
1612 .data = &(struct clk_regmap_div_data){
1613 .offset = HHI_MALI_CLK_CNTL,
1614 .shift = 0,
1615 .width = 7,
1616 },
1617 .hw.init = &(struct clk_init_data){
1618 .name = "mali_0_div",
1619 .ops = &clk_regmap_divider_ops,
1620 .parent_names = (const char *[]){ "mali_0_sel" },
1621 .num_parents = 1,
1622 .flags = CLK_SET_RATE_PARENT,
1623 },
1624};
1625
1626static struct clk_regmap meson8b_mali_0 = {
1627 .data = &(struct clk_regmap_gate_data){
1628 .offset = HHI_MALI_CLK_CNTL,
1629 .bit_idx = 8,
1630 },
1631 .hw.init = &(struct clk_init_data){
1632 .name = "mali_0",
1633 .ops = &clk_regmap_gate_ops,
1634 .parent_names = (const char *[]){ "mali_0_div" },
1635 .num_parents = 1,
1636 .flags = CLK_SET_RATE_PARENT,
1637 },
1638};
1639
1640static struct clk_regmap meson8b_mali_1_sel = {
1641 .data = &(struct clk_regmap_mux_data){
1642 .offset = HHI_MALI_CLK_CNTL,
1643 .mask = 0x7,
1644 .shift = 25,
1645 .table = meson8b_mali_0_1_mux_table,
1646 },
1647 .hw.init = &(struct clk_init_data){
1648 .name = "mali_1_sel",
1649 .ops = &clk_regmap_mux_ops,
1650 .parent_names = meson8b_mali_0_1_parent_names,
1651 .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_names),
1652 /*
1653 * Don't propagate rate changes up because the only changeable
1654 * parents are mpll1 and mpll2 but we need those for audio and
1655 * RGMII (Ethernet). We don't want to change the audio or
1656 * Ethernet clocks when setting the GPU frequency.
1657 */
1658 .flags = 0,
1659 },
1660};
1661
1662static struct clk_regmap meson8b_mali_1_div = {
1663 .data = &(struct clk_regmap_div_data){
1664 .offset = HHI_MALI_CLK_CNTL,
1665 .shift = 16,
1666 .width = 7,
1667 },
1668 .hw.init = &(struct clk_init_data){
1669 .name = "mali_1_div",
1670 .ops = &clk_regmap_divider_ops,
1671 .parent_names = (const char *[]){ "mali_1_sel" },
1672 .num_parents = 1,
1673 .flags = CLK_SET_RATE_PARENT,
1674 },
1675};
1676
1677static struct clk_regmap meson8b_mali_1 = {
1678 .data = &(struct clk_regmap_gate_data){
1679 .offset = HHI_MALI_CLK_CNTL,
1680 .bit_idx = 24,
1681 },
1682 .hw.init = &(struct clk_init_data){
1683 .name = "mali_1",
1684 .ops = &clk_regmap_gate_ops,
1685 .parent_names = (const char *[]){ "mali_1_div" },
1686 .num_parents = 1,
1687 .flags = CLK_SET_RATE_PARENT,
1688 },
1689};
1690
1691static struct clk_regmap meson8b_mali = {
1692 .data = &(struct clk_regmap_mux_data){
1693 .offset = HHI_MALI_CLK_CNTL,
1694 .mask = 1,
1695 .shift = 31,
1696 },
1697 .hw.init = &(struct clk_init_data){
1698 .name = "mali",
1699 .ops = &clk_regmap_mux_ops,
1700 .parent_names = (const char *[]){ "mali_0", "mali_1" },
1701 .num_parents = 2,
1702 .flags = CLK_SET_RATE_PARENT,
1703 },
1704};
1705
1576/* Everything Else (EE) domain gates */ 1706/* Everything Else (EE) domain gates */
1577 1707
1578static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0); 1708static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0);
@@ -1659,6 +1789,188 @@ static MESON_GATE(meson8b_ao_ahb_sram, HHI_GCLK_AO, 1);
1659static MESON_GATE(meson8b_ao_ahb_bus, HHI_GCLK_AO, 2); 1789static MESON_GATE(meson8b_ao_ahb_bus, HHI_GCLK_AO, 2);
1660static MESON_GATE(meson8b_ao_iface, HHI_GCLK_AO, 3); 1790static MESON_GATE(meson8b_ao_iface, HHI_GCLK_AO, 3);
1661 1791
1792static struct clk_hw_onecell_data meson8_hw_onecell_data = {
1793 .hws = {
1794 [CLKID_XTAL] = &meson8b_xtal.hw,
1795 [CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
1796 [CLKID_PLL_VID] = &meson8b_vid_pll.hw,
1797 [CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
1798 [CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw,
1799 [CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw,
1800 [CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw,
1801 [CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
1802 [CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
1803 [CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
1804 [CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw,
1805 [CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw,
1806 [CLKID_CLK81] = &meson8b_clk81.hw,
1807 [CLKID_DDR] = &meson8b_ddr.hw,
1808 [CLKID_DOS] = &meson8b_dos.hw,
1809 [CLKID_ISA] = &meson8b_isa.hw,
1810 [CLKID_PL301] = &meson8b_pl301.hw,
1811 [CLKID_PERIPHS] = &meson8b_periphs.hw,
1812 [CLKID_SPICC] = &meson8b_spicc.hw,
1813 [CLKID_I2C] = &meson8b_i2c.hw,
1814 [CLKID_SAR_ADC] = &meson8b_sar_adc.hw,
1815 [CLKID_SMART_CARD] = &meson8b_smart_card.hw,
1816 [CLKID_RNG0] = &meson8b_rng0.hw,
1817 [CLKID_UART0] = &meson8b_uart0.hw,
1818 [CLKID_SDHC] = &meson8b_sdhc.hw,
1819 [CLKID_STREAM] = &meson8b_stream.hw,
1820 [CLKID_ASYNC_FIFO] = &meson8b_async_fifo.hw,
1821 [CLKID_SDIO] = &meson8b_sdio.hw,
1822 [CLKID_ABUF] = &meson8b_abuf.hw,
1823 [CLKID_HIU_IFACE] = &meson8b_hiu_iface.hw,
1824 [CLKID_ASSIST_MISC] = &meson8b_assist_misc.hw,
1825 [CLKID_SPI] = &meson8b_spi.hw,
1826 [CLKID_I2S_SPDIF] = &meson8b_i2s_spdif.hw,
1827 [CLKID_ETH] = &meson8b_eth.hw,
1828 [CLKID_DEMUX] = &meson8b_demux.hw,
1829 [CLKID_AIU_GLUE] = &meson8b_aiu_glue.hw,
1830 [CLKID_IEC958] = &meson8b_iec958.hw,
1831 [CLKID_I2S_OUT] = &meson8b_i2s_out.hw,
1832 [CLKID_AMCLK] = &meson8b_amclk.hw,
1833 [CLKID_AIFIFO2] = &meson8b_aififo2.hw,
1834 [CLKID_MIXER] = &meson8b_mixer.hw,
1835 [CLKID_MIXER_IFACE] = &meson8b_mixer_iface.hw,
1836 [CLKID_ADC] = &meson8b_adc.hw,
1837 [CLKID_BLKMV] = &meson8b_blkmv.hw,
1838 [CLKID_AIU] = &meson8b_aiu.hw,
1839 [CLKID_UART1] = &meson8b_uart1.hw,
1840 [CLKID_G2D] = &meson8b_g2d.hw,
1841 [CLKID_USB0] = &meson8b_usb0.hw,
1842 [CLKID_USB1] = &meson8b_usb1.hw,
1843 [CLKID_RESET] = &meson8b_reset.hw,
1844 [CLKID_NAND] = &meson8b_nand.hw,
1845 [CLKID_DOS_PARSER] = &meson8b_dos_parser.hw,
1846 [CLKID_USB] = &meson8b_usb.hw,
1847 [CLKID_VDIN1] = &meson8b_vdin1.hw,
1848 [CLKID_AHB_ARB0] = &meson8b_ahb_arb0.hw,
1849 [CLKID_EFUSE] = &meson8b_efuse.hw,
1850 [CLKID_BOOT_ROM] = &meson8b_boot_rom.hw,
1851 [CLKID_AHB_DATA_BUS] = &meson8b_ahb_data_bus.hw,
1852 [CLKID_AHB_CTRL_BUS] = &meson8b_ahb_ctrl_bus.hw,
1853 [CLKID_HDMI_INTR_SYNC] = &meson8b_hdmi_intr_sync.hw,
1854 [CLKID_HDMI_PCLK] = &meson8b_hdmi_pclk.hw,
1855 [CLKID_USB1_DDR_BRIDGE] = &meson8b_usb1_ddr_bridge.hw,
1856 [CLKID_USB0_DDR_BRIDGE] = &meson8b_usb0_ddr_bridge.hw,
1857 [CLKID_MMC_PCLK] = &meson8b_mmc_pclk.hw,
1858 [CLKID_DVIN] = &meson8b_dvin.hw,
1859 [CLKID_UART2] = &meson8b_uart2.hw,
1860 [CLKID_SANA] = &meson8b_sana.hw,
1861 [CLKID_VPU_INTR] = &meson8b_vpu_intr.hw,
1862 [CLKID_SEC_AHB_AHB3_BRIDGE] = &meson8b_sec_ahb_ahb3_bridge.hw,
1863 [CLKID_CLK81_A9] = &meson8b_clk81_a9.hw,
1864 [CLKID_VCLK2_VENCI0] = &meson8b_vclk2_venci0.hw,
1865 [CLKID_VCLK2_VENCI1] = &meson8b_vclk2_venci1.hw,
1866 [CLKID_VCLK2_VENCP0] = &meson8b_vclk2_vencp0.hw,
1867 [CLKID_VCLK2_VENCP1] = &meson8b_vclk2_vencp1.hw,
1868 [CLKID_GCLK_VENCI_INT] = &meson8b_gclk_venci_int.hw,
1869 [CLKID_GCLK_VENCP_INT] = &meson8b_gclk_vencp_int.hw,
1870 [CLKID_DAC_CLK] = &meson8b_dac_clk.hw,
1871 [CLKID_AOCLK_GATE] = &meson8b_aoclk_gate.hw,
1872 [CLKID_IEC958_GATE] = &meson8b_iec958_gate.hw,
1873 [CLKID_ENC480P] = &meson8b_enc480p.hw,
1874 [CLKID_RNG1] = &meson8b_rng1.hw,
1875 [CLKID_GCLK_VENCL_INT] = &meson8b_gclk_vencl_int.hw,
1876 [CLKID_VCLK2_VENCLMCC] = &meson8b_vclk2_venclmcc.hw,
1877 [CLKID_VCLK2_VENCL] = &meson8b_vclk2_vencl.hw,
1878 [CLKID_VCLK2_OTHER] = &meson8b_vclk2_other.hw,
1879 [CLKID_EDP] = &meson8b_edp.hw,
1880 [CLKID_AO_MEDIA_CPU] = &meson8b_ao_media_cpu.hw,
1881 [CLKID_AO_AHB_SRAM] = &meson8b_ao_ahb_sram.hw,
1882 [CLKID_AO_AHB_BUS] = &meson8b_ao_ahb_bus.hw,
1883 [CLKID_AO_IFACE] = &meson8b_ao_iface.hw,
1884 [CLKID_MPLL0] = &meson8b_mpll0.hw,
1885 [CLKID_MPLL1] = &meson8b_mpll1.hw,
1886 [CLKID_MPLL2] = &meson8b_mpll2.hw,
1887 [CLKID_MPLL0_DIV] = &meson8b_mpll0_div.hw,
1888 [CLKID_MPLL1_DIV] = &meson8b_mpll1_div.hw,
1889 [CLKID_MPLL2_DIV] = &meson8b_mpll2_div.hw,
1890 [CLKID_CPU_IN_SEL] = &meson8b_cpu_in_sel.hw,
1891 [CLKID_CPU_IN_DIV2] = &meson8b_cpu_in_div2.hw,
1892 [CLKID_CPU_IN_DIV3] = &meson8b_cpu_in_div3.hw,
1893 [CLKID_CPU_SCALE_DIV] = &meson8b_cpu_scale_div.hw,
1894 [CLKID_CPU_SCALE_OUT_SEL] = &meson8b_cpu_scale_out_sel.hw,
1895 [CLKID_MPLL_PREDIV] = &meson8b_mpll_prediv.hw,
1896 [CLKID_FCLK_DIV2_DIV] = &meson8b_fclk_div2_div.hw,
1897 [CLKID_FCLK_DIV3_DIV] = &meson8b_fclk_div3_div.hw,
1898 [CLKID_FCLK_DIV4_DIV] = &meson8b_fclk_div4_div.hw,
1899 [CLKID_FCLK_DIV5_DIV] = &meson8b_fclk_div5_div.hw,
1900 [CLKID_FCLK_DIV7_DIV] = &meson8b_fclk_div7_div.hw,
1901 [CLKID_NAND_SEL] = &meson8b_nand_clk_sel.hw,
1902 [CLKID_NAND_DIV] = &meson8b_nand_clk_div.hw,
1903 [CLKID_NAND_CLK] = &meson8b_nand_clk_gate.hw,
1904 [CLKID_PLL_FIXED_DCO] = &meson8b_fixed_pll_dco.hw,
1905 [CLKID_HDMI_PLL_DCO] = &meson8b_hdmi_pll_dco.hw,
1906 [CLKID_PLL_SYS_DCO] = &meson8b_sys_pll_dco.hw,
1907 [CLKID_CPU_CLK_DIV2] = &meson8b_cpu_clk_div2.hw,
1908 [CLKID_CPU_CLK_DIV3] = &meson8b_cpu_clk_div3.hw,
1909 [CLKID_CPU_CLK_DIV4] = &meson8b_cpu_clk_div4.hw,
1910 [CLKID_CPU_CLK_DIV5] = &meson8b_cpu_clk_div5.hw,
1911 [CLKID_CPU_CLK_DIV6] = &meson8b_cpu_clk_div6.hw,
1912 [CLKID_CPU_CLK_DIV7] = &meson8b_cpu_clk_div7.hw,
1913 [CLKID_CPU_CLK_DIV8] = &meson8b_cpu_clk_div8.hw,
1914 [CLKID_APB_SEL] = &meson8b_apb_clk_sel.hw,
1915 [CLKID_APB] = &meson8b_apb_clk_gate.hw,
1916 [CLKID_PERIPH_SEL] = &meson8b_periph_clk_sel.hw,
1917 [CLKID_PERIPH] = &meson8b_periph_clk_gate.hw,
1918 [CLKID_AXI_SEL] = &meson8b_axi_clk_sel.hw,
1919 [CLKID_AXI] = &meson8b_axi_clk_gate.hw,
1920 [CLKID_L2_DRAM_SEL] = &meson8b_l2_dram_clk_sel.hw,
1921 [CLKID_L2_DRAM] = &meson8b_l2_dram_clk_gate.hw,
1922 [CLKID_HDMI_PLL_LVDS_OUT] = &meson8b_hdmi_pll_lvds_out.hw,
1923 [CLKID_HDMI_PLL_HDMI_OUT] = &meson8b_hdmi_pll_hdmi_out.hw,
1924 [CLKID_VID_PLL_IN_SEL] = &meson8b_vid_pll_in_sel.hw,
1925 [CLKID_VID_PLL_IN_EN] = &meson8b_vid_pll_in_en.hw,
1926 [CLKID_VID_PLL_PRE_DIV] = &meson8b_vid_pll_pre_div.hw,
1927 [CLKID_VID_PLL_POST_DIV] = &meson8b_vid_pll_post_div.hw,
1928 [CLKID_VID_PLL_FINAL_DIV] = &meson8b_vid_pll_final_div.hw,
1929 [CLKID_VCLK_IN_SEL] = &meson8b_vclk_in_sel.hw,
1930 [CLKID_VCLK_IN_EN] = &meson8b_vclk_in_en.hw,
1931 [CLKID_VCLK_DIV1] = &meson8b_vclk_div1_gate.hw,
1932 [CLKID_VCLK_DIV2_DIV] = &meson8b_vclk_div2_div.hw,
1933 [CLKID_VCLK_DIV2] = &meson8b_vclk_div2_div_gate.hw,
1934 [CLKID_VCLK_DIV4_DIV] = &meson8b_vclk_div4_div.hw,
1935 [CLKID_VCLK_DIV4] = &meson8b_vclk_div4_div_gate.hw,
1936 [CLKID_VCLK_DIV6_DIV] = &meson8b_vclk_div6_div.hw,
1937 [CLKID_VCLK_DIV6] = &meson8b_vclk_div6_div_gate.hw,
1938 [CLKID_VCLK_DIV12_DIV] = &meson8b_vclk_div12_div.hw,
1939 [CLKID_VCLK_DIV12] = &meson8b_vclk_div12_div_gate.hw,
1940 [CLKID_VCLK2_IN_SEL] = &meson8b_vclk2_in_sel.hw,
1941 [CLKID_VCLK2_IN_EN] = &meson8b_vclk2_clk_in_en.hw,
1942 [CLKID_VCLK2_DIV1] = &meson8b_vclk2_div1_gate.hw,
1943 [CLKID_VCLK2_DIV2_DIV] = &meson8b_vclk2_div2_div.hw,
1944 [CLKID_VCLK2_DIV2] = &meson8b_vclk2_div2_div_gate.hw,
1945 [CLKID_VCLK2_DIV4_DIV] = &meson8b_vclk2_div4_div.hw,
1946 [CLKID_VCLK2_DIV4] = &meson8b_vclk2_div4_div_gate.hw,
1947 [CLKID_VCLK2_DIV6_DIV] = &meson8b_vclk2_div6_div.hw,
1948 [CLKID_VCLK2_DIV6] = &meson8b_vclk2_div6_div_gate.hw,
1949 [CLKID_VCLK2_DIV12_DIV] = &meson8b_vclk2_div12_div.hw,
1950 [CLKID_VCLK2_DIV12] = &meson8b_vclk2_div12_div_gate.hw,
1951 [CLKID_CTS_ENCT_SEL] = &meson8b_cts_enct_sel.hw,
1952 [CLKID_CTS_ENCT] = &meson8b_cts_enct.hw,
1953 [CLKID_CTS_ENCP_SEL] = &meson8b_cts_encp_sel.hw,
1954 [CLKID_CTS_ENCP] = &meson8b_cts_encp.hw,
1955 [CLKID_CTS_ENCI_SEL] = &meson8b_cts_enci_sel.hw,
1956 [CLKID_CTS_ENCI] = &meson8b_cts_enci.hw,
1957 [CLKID_HDMI_TX_PIXEL_SEL] = &meson8b_hdmi_tx_pixel_sel.hw,
1958 [CLKID_HDMI_TX_PIXEL] = &meson8b_hdmi_tx_pixel.hw,
1959 [CLKID_CTS_ENCL_SEL] = &meson8b_cts_encl_sel.hw,
1960 [CLKID_CTS_ENCL] = &meson8b_cts_encl.hw,
1961 [CLKID_CTS_VDAC0_SEL] = &meson8b_cts_vdac0_sel.hw,
1962 [CLKID_CTS_VDAC0] = &meson8b_cts_vdac0.hw,
1963 [CLKID_HDMI_SYS_SEL] = &meson8b_hdmi_sys_sel.hw,
1964 [CLKID_HDMI_SYS_DIV] = &meson8b_hdmi_sys_div.hw,
1965 [CLKID_HDMI_SYS] = &meson8b_hdmi_sys.hw,
1966 [CLKID_MALI_0_SEL] = &meson8b_mali_0_sel.hw,
1967 [CLKID_MALI_0_DIV] = &meson8b_mali_0_div.hw,
1968 [CLKID_MALI] = &meson8b_mali_0.hw,
1969 [CLK_NR_CLKS] = NULL,
1970 },
1971 .num = CLK_NR_CLKS,
1972};
1973
1662static struct clk_hw_onecell_data meson8b_hw_onecell_data = { 1974static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
1663 .hws = { 1975 .hws = {
1664 [CLKID_XTAL] = &meson8b_xtal.hw, 1976 [CLKID_XTAL] = &meson8b_xtal.hw,
@@ -1781,8 +2093,8 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
1781 [CLKID_CPU_CLK_DIV6] = &meson8b_cpu_clk_div6.hw, 2093 [CLKID_CPU_CLK_DIV6] = &meson8b_cpu_clk_div6.hw,
1782 [CLKID_CPU_CLK_DIV7] = &meson8b_cpu_clk_div7.hw, 2094 [CLKID_CPU_CLK_DIV7] = &meson8b_cpu_clk_div7.hw,
1783 [CLKID_CPU_CLK_DIV8] = &meson8b_cpu_clk_div8.hw, 2095 [CLKID_CPU_CLK_DIV8] = &meson8b_cpu_clk_div8.hw,
1784 [CLKID_ABP_SEL] = &meson8b_abp_clk_sel.hw, 2096 [CLKID_APB_SEL] = &meson8b_apb_clk_sel.hw,
1785 [CLKID_ABP] = &meson8b_abp_clk_gate.hw, 2097 [CLKID_APB] = &meson8b_apb_clk_gate.hw,
1786 [CLKID_PERIPH_SEL] = &meson8b_periph_clk_sel.hw, 2098 [CLKID_PERIPH_SEL] = &meson8b_periph_clk_sel.hw,
1787 [CLKID_PERIPH] = &meson8b_periph_clk_gate.hw, 2099 [CLKID_PERIPH] = &meson8b_periph_clk_gate.hw,
1788 [CLKID_AXI_SEL] = &meson8b_axi_clk_sel.hw, 2100 [CLKID_AXI_SEL] = &meson8b_axi_clk_sel.hw,
@@ -1833,6 +2145,13 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
1833 [CLKID_HDMI_SYS_SEL] = &meson8b_hdmi_sys_sel.hw, 2145 [CLKID_HDMI_SYS_SEL] = &meson8b_hdmi_sys_sel.hw,
1834 [CLKID_HDMI_SYS_DIV] = &meson8b_hdmi_sys_div.hw, 2146 [CLKID_HDMI_SYS_DIV] = &meson8b_hdmi_sys_div.hw,
1835 [CLKID_HDMI_SYS] = &meson8b_hdmi_sys.hw, 2147 [CLKID_HDMI_SYS] = &meson8b_hdmi_sys.hw,
2148 [CLKID_MALI_0_SEL] = &meson8b_mali_0_sel.hw,
2149 [CLKID_MALI_0_DIV] = &meson8b_mali_0_div.hw,
2150 [CLKID_MALI_0] = &meson8b_mali_0.hw,
2151 [CLKID_MALI_1_SEL] = &meson8b_mali_1_sel.hw,
2152 [CLKID_MALI_1_DIV] = &meson8b_mali_1_div.hw,
2153 [CLKID_MALI_1] = &meson8b_mali_1.hw,
2154 [CLKID_MALI] = &meson8b_mali.hw,
1836 [CLK_NR_CLKS] = NULL, 2155 [CLK_NR_CLKS] = NULL,
1837 }, 2156 },
1838 .num = CLK_NR_CLKS, 2157 .num = CLK_NR_CLKS,
@@ -1943,8 +2262,8 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = {
1943 &meson8b_fixed_pll_dco, 2262 &meson8b_fixed_pll_dco,
1944 &meson8b_hdmi_pll_dco, 2263 &meson8b_hdmi_pll_dco,
1945 &meson8b_sys_pll_dco, 2264 &meson8b_sys_pll_dco,
1946 &meson8b_abp_clk_sel, 2265 &meson8b_apb_clk_sel,
1947 &meson8b_abp_clk_gate, 2266 &meson8b_apb_clk_gate,
1948 &meson8b_periph_clk_sel, 2267 &meson8b_periph_clk_sel,
1949 &meson8b_periph_clk_gate, 2268 &meson8b_periph_clk_gate,
1950 &meson8b_axi_clk_sel, 2269 &meson8b_axi_clk_sel,
@@ -1988,6 +2307,13 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = {
1988 &meson8b_hdmi_sys_sel, 2307 &meson8b_hdmi_sys_sel,
1989 &meson8b_hdmi_sys_div, 2308 &meson8b_hdmi_sys_div,
1990 &meson8b_hdmi_sys, 2309 &meson8b_hdmi_sys,
2310 &meson8b_mali_0_sel,
2311 &meson8b_mali_0_div,
2312 &meson8b_mali_0,
2313 &meson8b_mali_1_sel,
2314 &meson8b_mali_1_div,
2315 &meson8b_mali_1,
2316 &meson8b_mali,
1991}; 2317};
1992 2318
1993static const struct meson8b_clk_reset_line { 2319static const struct meson8b_clk_reset_line {
@@ -2132,7 +2458,6 @@ static int meson8b_cpu_clk_notifier_cb(struct notifier_block *nb,
2132 2458
2133static struct meson8b_nb_data meson8b_cpu_nb_data = { 2459static struct meson8b_nb_data meson8b_cpu_nb_data = {
2134 .nb.notifier_call = meson8b_cpu_clk_notifier_cb, 2460 .nb.notifier_call = meson8b_cpu_clk_notifier_cb,
2135 .onecell_data = &meson8b_hw_onecell_data,
2136}; 2461};
2137 2462
2138static const struct regmap_config clkc_regmap_config = { 2463static const struct regmap_config clkc_regmap_config = {
@@ -2141,7 +2466,8 @@ static const struct regmap_config clkc_regmap_config = {
2141 .reg_stride = 4, 2466 .reg_stride = 4,
2142}; 2467};
2143 2468
2144static void __init meson8b_clkc_init(struct device_node *np) 2469static void __init meson8b_clkc_init_common(struct device_node *np,
2470 struct clk_hw_onecell_data *clk_hw_onecell_data)
2145{ 2471{
2146 struct meson8b_clk_reset *rstc; 2472 struct meson8b_clk_reset *rstc;
2147 const char *notifier_clk_name; 2473 const char *notifier_clk_name;
@@ -2192,14 +2518,16 @@ static void __init meson8b_clkc_init(struct device_node *np)
2192 */ 2518 */
2193 for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) { 2519 for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) {
2194 /* array might be sparse */ 2520 /* array might be sparse */
2195 if (!meson8b_hw_onecell_data.hws[i]) 2521 if (!clk_hw_onecell_data->hws[i])
2196 continue; 2522 continue;
2197 2523
2198 ret = clk_hw_register(NULL, meson8b_hw_onecell_data.hws[i]); 2524 ret = clk_hw_register(NULL, clk_hw_onecell_data->hws[i]);
2199 if (ret) 2525 if (ret)
2200 return; 2526 return;
2201 } 2527 }
2202 2528
2529 meson8b_cpu_nb_data.onecell_data = clk_hw_onecell_data;
2530
2203 /* 2531 /*
2204 * FIXME we shouldn't program the muxes in notifier handlers. The 2532 * FIXME we shouldn't program the muxes in notifier handlers. The
2205 * tricky programming sequence will be handled by the forthcoming 2533 * tricky programming sequence will be handled by the forthcoming
@@ -2215,13 +2543,23 @@ static void __init meson8b_clkc_init(struct device_node *np)
2215 } 2543 }
2216 2544
2217 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, 2545 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
2218 &meson8b_hw_onecell_data); 2546 clk_hw_onecell_data);
2219 if (ret) 2547 if (ret)
2220 pr_err("%s: failed to register clock provider\n", __func__); 2548 pr_err("%s: failed to register clock provider\n", __func__);
2221} 2549}
2222 2550
2551static void __init meson8_clkc_init(struct device_node *np)
2552{
2553 return meson8b_clkc_init_common(np, &meson8_hw_onecell_data);
2554}
2555
2556static void __init meson8b_clkc_init(struct device_node *np)
2557{
2558 return meson8b_clkc_init_common(np, &meson8b_hw_onecell_data);
2559}
2560
2223CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc", 2561CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc",
2224 meson8b_clkc_init); 2562 meson8_clkc_init);
2225CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc", 2563CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc",
2226 meson8b_clkc_init); 2564 meson8b_clkc_init);
2227CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc", 2565CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc",
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
index 87fba739af81..b8c58faeae52 100644
--- a/drivers/clk/meson/meson8b.h
+++ b/drivers/clk/meson/meson8b.h
@@ -33,6 +33,7 @@
33#define HHI_VID_CLK_CNTL2 0x194 /* 0x65 offset in data sheet */ 33#define HHI_VID_CLK_CNTL2 0x194 /* 0x65 offset in data sheet */
34#define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */ 34#define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */
35#define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */ 35#define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */
36#define HHI_MALI_CLK_CNTL 0x1b0 /* 0x6c offset in data sheet */
36#define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 offset in data sheet */ 37#define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 offset in data sheet */
37#define HHI_NAND_CLK_CNTL 0x25c /* 0x97 offset in data sheet */ 38#define HHI_NAND_CLK_CNTL 0x25c /* 0x97 offset in data sheet */
38#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */ 39#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */
@@ -91,7 +92,7 @@
91#define CLKID_CPU_CLK_DIV6 120 92#define CLKID_CPU_CLK_DIV6 120
92#define CLKID_CPU_CLK_DIV7 121 93#define CLKID_CPU_CLK_DIV7 121
93#define CLKID_CPU_CLK_DIV8 122 94#define CLKID_CPU_CLK_DIV8 122
94#define CLKID_ABP_SEL 123 95#define CLKID_APB_SEL 123
95#define CLKID_PERIPH_SEL 125 96#define CLKID_PERIPH_SEL 125
96#define CLKID_AXI_SEL 127 97#define CLKID_AXI_SEL 127
97#define CLKID_L2_DRAM_SEL 129 98#define CLKID_L2_DRAM_SEL 129
@@ -139,8 +140,14 @@
139#define CLKID_HDMI_SYS_SEL 172 140#define CLKID_HDMI_SYS_SEL 172
140#define CLKID_HDMI_SYS_DIV 173 141#define CLKID_HDMI_SYS_DIV 173
141#define CLKID_HDMI_SYS 174 142#define CLKID_HDMI_SYS 174
143#define CLKID_MALI_0_SEL 175
144#define CLKID_MALI_0_DIV 176
145#define CLKID_MALI_0 177
146#define CLKID_MALI_1_SEL 178
147#define CLKID_MALI_1_DIV 179
148#define CLKID_MALI_1 180
142 149
143#define CLK_NR_CLKS 175 150#define CLK_NR_CLKS 181
144 151
145/* 152/*
146 * include the CLKID and RESETID that have 153 * include the CLKID and RESETID that have
diff --git a/drivers/clk/meson/parm.h b/drivers/clk/meson/parm.h
new file mode 100644
index 000000000000..3c9ef1b505ce
--- /dev/null
+++ b/drivers/clk/meson/parm.h
@@ -0,0 +1,46 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2015 Endless Mobile, Inc.
4 * Author: Carlo Caione <carlo@endlessm.com>
5 */
6
7#ifndef __MESON_PARM_H
8#define __MESON_PARM_H
9
10#include <linux/bits.h>
11#include <linux/regmap.h>
12
13#define PMASK(width) GENMASK(width - 1, 0)
14#define SETPMASK(width, shift) GENMASK(shift + width - 1, shift)
15#define CLRPMASK(width, shift) (~SETPMASK(width, shift))
16
17#define PARM_GET(width, shift, reg) \
18 (((reg) & SETPMASK(width, shift)) >> (shift))
19#define PARM_SET(width, shift, reg, val) \
20 (((reg) & CLRPMASK(width, shift)) | ((val) << (shift)))
21
22#define MESON_PARM_APPLICABLE(p) (!!((p)->width))
23
24struct parm {
25 u16 reg_off;
26 u8 shift;
27 u8 width;
28};
29
30static inline unsigned int meson_parm_read(struct regmap *map, struct parm *p)
31{
32 unsigned int val;
33
34 regmap_read(map, p->reg_off, &val);
35 return PARM_GET(p->width, p->shift, val);
36}
37
38static inline void meson_parm_write(struct regmap *map, struct parm *p,
39 unsigned int val)
40{
41 regmap_update_bits(map, p->reg_off, SETPMASK(p->width, p->shift),
42 val << p->shift);
43}
44
45#endif /* __MESON_PARM_H */
46
diff --git a/drivers/clk/meson/sclk-div.c b/drivers/clk/meson/sclk-div.c
index bc64019b8eeb..3acf03780221 100644
--- a/drivers/clk/meson/sclk-div.c
+++ b/drivers/clk/meson/sclk-div.c
@@ -16,7 +16,11 @@
16 * duty_cycle = (1 + hi) / (1 + val) 16 * duty_cycle = (1 + hi) / (1 + val)
17 */ 17 */
18 18
19#include "clkc-audio.h" 19#include <linux/clk-provider.h>
20#include <linux/module.h>
21
22#include "clk-regmap.h"
23#include "sclk-div.h"
20 24
21static inline struct meson_sclk_div_data * 25static inline struct meson_sclk_div_data *
22meson_sclk_div_data(struct clk_regmap *clk) 26meson_sclk_div_data(struct clk_regmap *clk)
@@ -241,3 +245,7 @@ const struct clk_ops meson_sclk_div_ops = {
241 .init = sclk_div_init, 245 .init = sclk_div_init,
242}; 246};
243EXPORT_SYMBOL_GPL(meson_sclk_div_ops); 247EXPORT_SYMBOL_GPL(meson_sclk_div_ops);
248
249MODULE_DESCRIPTION("Amlogic Sample divider driver");
250MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
251MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clkc-audio.h b/drivers/clk/meson/sclk-div.h
index 0a7c157ebf81..b64b2a32005f 100644
--- a/drivers/clk/meson/clkc-audio.h
+++ b/drivers/clk/meson/sclk-div.h
@@ -4,16 +4,11 @@
4 * Author: Jerome Brunet <jbrunet@baylibre.com> 4 * Author: Jerome Brunet <jbrunet@baylibre.com>
5 */ 5 */
6 6
7#ifndef __MESON_CLKC_AUDIO_H 7#ifndef __MESON_SCLK_DIV_H
8#define __MESON_CLKC_AUDIO_H 8#define __MESON_SCLK_DIV_H
9 9
10#include "clkc.h" 10#include <linux/clk-provider.h>
11 11#include "parm.h"
12struct meson_clk_triphase_data {
13 struct parm ph0;
14 struct parm ph1;
15 struct parm ph2;
16};
17 12
18struct meson_sclk_div_data { 13struct meson_sclk_div_data {
19 struct parm div; 14 struct parm div;
@@ -22,7 +17,6 @@ struct meson_sclk_div_data {
22 struct clk_duty cached_duty; 17 struct clk_duty cached_duty;
23}; 18};
24 19
25extern const struct clk_ops meson_clk_triphase_ops;
26extern const struct clk_ops meson_sclk_div_ops; 20extern const struct clk_ops meson_sclk_div_ops;
27 21
28#endif /* __MESON_CLKC_AUDIO_H */ 22#endif /* __MESON_SCLK_DIV_H */
diff --git a/drivers/clk/meson/vid-pll-div.c b/drivers/clk/meson/vid-pll-div.c
index 88af0e282ea0..08bcc01c0923 100644
--- a/drivers/clk/meson/vid-pll-div.c
+++ b/drivers/clk/meson/vid-pll-div.c
@@ -5,7 +5,10 @@
5 */ 5 */
6 6
7#include <linux/clk-provider.h> 7#include <linux/clk-provider.h>
8#include "clkc.h" 8#include <linux/module.h>
9
10#include "clk-regmap.h"
11#include "vid-pll-div.h"
9 12
10static inline struct meson_vid_pll_div_data * 13static inline struct meson_vid_pll_div_data *
11meson_vid_pll_div_data(struct clk_regmap *clk) 14meson_vid_pll_div_data(struct clk_regmap *clk)
@@ -89,3 +92,8 @@ static unsigned long meson_vid_pll_div_recalc_rate(struct clk_hw *hw,
89const struct clk_ops meson_vid_pll_div_ro_ops = { 92const struct clk_ops meson_vid_pll_div_ro_ops = {
90 .recalc_rate = meson_vid_pll_div_recalc_rate, 93 .recalc_rate = meson_vid_pll_div_recalc_rate,
91}; 94};
95EXPORT_SYMBOL_GPL(meson_vid_pll_div_ro_ops);
96
97MODULE_DESCRIPTION("Amlogic video pll divider driver");
98MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
99MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/vid-pll-div.h b/drivers/clk/meson/vid-pll-div.h
new file mode 100644
index 000000000000..c0128e33ccf9
--- /dev/null
+++ b/drivers/clk/meson/vid-pll-div.h
@@ -0,0 +1,20 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2019 BayLibre, SAS.
4 * Author: Jerome Brunet <jbrunet@baylibre.com>
5 */
6
7#ifndef __MESON_VID_PLL_DIV_H
8#define __MESON_VID_PLL_DIV_H
9
10#include <linux/clk-provider.h>
11#include "parm.h"
12
13struct meson_vid_pll_div_data {
14 struct parm val;
15 struct parm sel;
16};
17
18extern const struct clk_ops meson_vid_pll_div_ro_ops;
19
20#endif /* __MESON_VID_PLL_DIV_H */
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index d083b860f083..a60a1be937ad 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -229,9 +229,10 @@ static struct mmp_param_gate_clk apmu_gate_clks[] = {
229 {MMP2_CLK_SDH1, "sdh1_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, 229 {MMP2_CLK_SDH1, "sdh1_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
230 {MMP2_CLK_SDH2, "sdh2_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH2, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, 230 {MMP2_CLK_SDH2, "sdh2_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH2, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
231 {MMP2_CLK_SDH3, "sdh3_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH3, 0x1b, 0x1b, 0x0, 0, &sdh_lock}, 231 {MMP2_CLK_SDH3, "sdh3_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH3, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
232 {MMP2_CLK_DISP0, "disp0_clk", "disp0_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1b, 0x1b, 0x0, 0, &disp0_lock}, 232 {MMP2_CLK_DISP0, "disp0_clk", "disp0_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x09, 0x09, 0x0, 0, &disp0_lock},
233 {MMP2_CLK_DISP0_LCDC, "disp0_lcdc_clk", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 0x12, 0x12, 0x0, 0, &disp0_lock},
233 {MMP2_CLK_DISP0_SPHY, "disp0_sphy_clk", "disp0_sphy_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1024, 0x1024, 0x0, 0, &disp0_lock}, 234 {MMP2_CLK_DISP0_SPHY, "disp0_sphy_clk", "disp0_sphy_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1024, 0x1024, 0x0, 0, &disp0_lock},
234 {MMP2_CLK_DISP1, "disp1_clk", "disp1_div", CLK_SET_RATE_PARENT, APMU_DISP1, 0x1b, 0x1b, 0x0, 0, &disp1_lock}, 235 {MMP2_CLK_DISP1, "disp1_clk", "disp1_div", CLK_SET_RATE_PARENT, APMU_DISP1, 0x09, 0x09, 0x0, 0, &disp1_lock},
235 {MMP2_CLK_CCIC_ARBITER, "ccic_arbiter", "vctcxo", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1800, 0x1800, 0x0, 0, &ccic0_lock}, 236 {MMP2_CLK_CCIC_ARBITER, "ccic_arbiter", "vctcxo", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1800, 0x1800, 0x0, 0, &ccic0_lock},
236 {MMP2_CLK_CCIC0, "ccic0_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1b, 0x1b, 0x0, 0, &ccic0_lock}, 237 {MMP2_CLK_CCIC0, "ccic0_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1b, 0x1b, 0x0, 0, &ccic0_lock},
237 {MMP2_CLK_CCIC0_PHY, "ccic0_phy_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x24, 0x24, 0x0, 0, &ccic0_lock}, 238 {MMP2_CLK_CCIC0_PHY, "ccic0_phy_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x24, 0x24, 0x0, 0, &ccic0_lock},
diff --git a/drivers/clk/mvebu/armada-370.c b/drivers/clk/mvebu/armada-370.c
index 7dedfaa6e152..5c6bbee396b3 100644
--- a/drivers/clk/mvebu/armada-370.c
+++ b/drivers/clk/mvebu/armada-370.c
@@ -175,8 +175,10 @@ static void __init a370_clk_init(struct device_node *np)
175 175
176 mvebu_coreclk_setup(np, &a370_coreclks); 176 mvebu_coreclk_setup(np, &a370_coreclks);
177 177
178 if (cgnp) 178 if (cgnp) {
179 mvebu_clk_gating_setup(cgnp, a370_gating_desc); 179 mvebu_clk_gating_setup(cgnp, a370_gating_desc);
180 of_node_put(cgnp);
181 }
180} 182}
181CLK_OF_DECLARE(a370_clk, "marvell,armada-370-core-clock", a370_clk_init); 183CLK_OF_DECLARE(a370_clk, "marvell,armada-370-core-clock", a370_clk_init);
182 184
diff --git a/drivers/clk/mvebu/armada-xp.c b/drivers/clk/mvebu/armada-xp.c
index e8f03293ec83..fa1568279c23 100644
--- a/drivers/clk/mvebu/armada-xp.c
+++ b/drivers/clk/mvebu/armada-xp.c
@@ -226,7 +226,9 @@ static void __init axp_clk_init(struct device_node *np)
226 226
227 mvebu_coreclk_setup(np, &axp_coreclks); 227 mvebu_coreclk_setup(np, &axp_coreclks);
228 228
229 if (cgnp) 229 if (cgnp) {
230 mvebu_clk_gating_setup(cgnp, axp_gating_desc); 230 mvebu_clk_gating_setup(cgnp, axp_gating_desc);
231 of_node_put(cgnp);
232 }
231} 233}
232CLK_OF_DECLARE(axp_clk, "marvell,armada-xp-core-clock", axp_clk_init); 234CLK_OF_DECLARE(axp_clk, "marvell,armada-xp-core-clock", axp_clk_init);
diff --git a/drivers/clk/mvebu/dove.c b/drivers/clk/mvebu/dove.c
index e0dd99f36bf4..0bd09d33f9cf 100644
--- a/drivers/clk/mvebu/dove.c
+++ b/drivers/clk/mvebu/dove.c
@@ -188,10 +188,14 @@ static void __init dove_clk_init(struct device_node *np)
188 188
189 mvebu_coreclk_setup(np, &dove_coreclks); 189 mvebu_coreclk_setup(np, &dove_coreclks);
190 190
191 if (ddnp) 191 if (ddnp) {
192 dove_divider_clk_init(ddnp); 192 dove_divider_clk_init(ddnp);
193 of_node_put(ddnp);
194 }
193 195
194 if (cgnp) 196 if (cgnp) {
195 mvebu_clk_gating_setup(cgnp, dove_gating_desc); 197 mvebu_clk_gating_setup(cgnp, dove_gating_desc);
198 of_node_put(cgnp);
199 }
196} 200}
197CLK_OF_DECLARE(dove_clk, "marvell,dove-core-clock", dove_clk_init); 201CLK_OF_DECLARE(dove_clk, "marvell,dove-core-clock", dove_clk_init);
diff --git a/drivers/clk/mvebu/kirkwood.c b/drivers/clk/mvebu/kirkwood.c
index 6f784167bda4..35af3aa18f1c 100644
--- a/drivers/clk/mvebu/kirkwood.c
+++ b/drivers/clk/mvebu/kirkwood.c
@@ -331,6 +331,8 @@ static void __init kirkwood_clk_init(struct device_node *np)
331 if (cgnp) { 331 if (cgnp) {
332 mvebu_clk_gating_setup(cgnp, kirkwood_gating_desc); 332 mvebu_clk_gating_setup(cgnp, kirkwood_gating_desc);
333 kirkwood_clk_muxing_setup(cgnp, kirkwood_mux_desc); 333 kirkwood_clk_muxing_setup(cgnp, kirkwood_mux_desc);
334
335 of_node_put(cgnp);
334 } 336 }
335} 337}
336CLK_OF_DECLARE(kirkwood_clk, "marvell,kirkwood-core-clock", 338CLK_OF_DECLARE(kirkwood_clk, "marvell,kirkwood-core-clock",
diff --git a/drivers/clk/mvebu/mv98dx3236.c b/drivers/clk/mvebu/mv98dx3236.c
index 0a74cf7a7725..1c8ab4f834ba 100644
--- a/drivers/clk/mvebu/mv98dx3236.c
+++ b/drivers/clk/mvebu/mv98dx3236.c
@@ -172,7 +172,9 @@ static void __init mv98dx3236_clk_init(struct device_node *np)
172 172
173 mvebu_coreclk_setup(np, &mv98dx3236_core_clocks); 173 mvebu_coreclk_setup(np, &mv98dx3236_core_clocks);
174 174
175 if (cgnp) 175 if (cgnp) {
176 mvebu_clk_gating_setup(cgnp, mv98dx3236_gating_desc); 176 mvebu_clk_gating_setup(cgnp, mv98dx3236_gating_desc);
177 of_node_put(cgnp);
178 }
177} 179}
178CLK_OF_DECLARE(mv98dx3236_clk, "marvell,mv98dx3236-core-clock", mv98dx3236_clk_init); 180CLK_OF_DECLARE(mv98dx3236_clk, "marvell,mv98dx3236-core-clock", mv98dx3236_clk_init);
diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index e5eca8a1abe4..c25b57c3cbc8 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -71,7 +71,6 @@ struct src_sel {
71 * @freq_tbl: frequency table 71 * @freq_tbl: frequency table
72 * @clkr: regmap clock handle 72 * @clkr: regmap clock handle
73 * @lock: register lock 73 * @lock: register lock
74 *
75 */ 74 */
76struct clk_rcg { 75struct clk_rcg {
77 u32 ns_reg; 76 u32 ns_reg;
@@ -107,7 +106,6 @@ extern const struct clk_ops clk_rcg_lcc_ops;
107 * @freq_tbl: frequency table 106 * @freq_tbl: frequency table
108 * @clkr: regmap clock handle 107 * @clkr: regmap clock handle
109 * @lock: register lock 108 * @lock: register lock
110 *
111 */ 109 */
112struct clk_dyn_rcg { 110struct clk_dyn_rcg {
113 u32 ns_reg[2]; 111 u32 ns_reg[2];
@@ -140,7 +138,7 @@ extern const struct clk_ops clk_dyn_rcg_ops;
140 * @parent_map: map from software's parent index to hardware's src_sel field 138 * @parent_map: map from software's parent index to hardware's src_sel field
141 * @freq_tbl: frequency table 139 * @freq_tbl: frequency table
142 * @clkr: regmap clock handle 140 * @clkr: regmap clock handle
143 * 141 * @cfg_off: defines the cfg register offset from the CMD_RCGR + CFG_REG
144 */ 142 */
145struct clk_rcg2 { 143struct clk_rcg2 {
146 u32 cmd_rcgr; 144 u32 cmd_rcgr;
@@ -150,6 +148,7 @@ struct clk_rcg2 {
150 const struct parent_map *parent_map; 148 const struct parent_map *parent_map;
151 const struct freq_tbl *freq_tbl; 149 const struct freq_tbl *freq_tbl;
152 struct clk_regmap clkr; 150 struct clk_regmap clkr;
151 u8 cfg_off;
153}; 152};
154 153
155#define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr) 154#define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr)
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 6e3bd195d012..8c02bffe50df 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -41,6 +41,11 @@
41#define N_REG 0xc 41#define N_REG 0xc
42#define D_REG 0x10 42#define D_REG 0x10
43 43
44#define RCG_CFG_OFFSET(rcg) ((rcg)->cmd_rcgr + (rcg)->cfg_off + CFG_REG)
45#define RCG_M_OFFSET(rcg) ((rcg)->cmd_rcgr + (rcg)->cfg_off + M_REG)
46#define RCG_N_OFFSET(rcg) ((rcg)->cmd_rcgr + (rcg)->cfg_off + N_REG)
47#define RCG_D_OFFSET(rcg) ((rcg)->cmd_rcgr + (rcg)->cfg_off + D_REG)
48
44/* Dynamic Frequency Scaling */ 49/* Dynamic Frequency Scaling */
45#define MAX_PERF_LEVEL 8 50#define MAX_PERF_LEVEL 8
46#define SE_CMD_DFSR_OFFSET 0x14 51#define SE_CMD_DFSR_OFFSET 0x14
@@ -74,7 +79,7 @@ static u8 clk_rcg2_get_parent(struct clk_hw *hw)
74 u32 cfg; 79 u32 cfg;
75 int i, ret; 80 int i, ret;
76 81
77 ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg); 82 ret = regmap_read(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), &cfg);
78 if (ret) 83 if (ret)
79 goto err; 84 goto err;
80 85
@@ -123,7 +128,7 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index)
123 int ret; 128 int ret;
124 u32 cfg = rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT; 129 u32 cfg = rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
125 130
126 ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, 131 ret = regmap_update_bits(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg),
127 CFG_SRC_SEL_MASK, cfg); 132 CFG_SRC_SEL_MASK, cfg);
128 if (ret) 133 if (ret)
129 return ret; 134 return ret;
@@ -162,13 +167,13 @@ clk_rcg2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
162 struct clk_rcg2 *rcg = to_clk_rcg2(hw); 167 struct clk_rcg2 *rcg = to_clk_rcg2(hw);
163 u32 cfg, hid_div, m = 0, n = 0, mode = 0, mask; 168 u32 cfg, hid_div, m = 0, n = 0, mode = 0, mask;
164 169
165 regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg); 170 regmap_read(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), &cfg);
166 171
167 if (rcg->mnd_width) { 172 if (rcg->mnd_width) {
168 mask = BIT(rcg->mnd_width) - 1; 173 mask = BIT(rcg->mnd_width) - 1;
169 regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + M_REG, &m); 174 regmap_read(rcg->clkr.regmap, RCG_M_OFFSET(rcg), &m);
170 m &= mask; 175 m &= mask;
171 regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + N_REG, &n); 176 regmap_read(rcg->clkr.regmap, RCG_N_OFFSET(rcg), &n);
172 n = ~n; 177 n = ~n;
173 n &= mask; 178 n &= mask;
174 n += m; 179 n += m;
@@ -263,17 +268,17 @@ static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
263 if (rcg->mnd_width && f->n) { 268 if (rcg->mnd_width && f->n) {
264 mask = BIT(rcg->mnd_width) - 1; 269 mask = BIT(rcg->mnd_width) - 1;
265 ret = regmap_update_bits(rcg->clkr.regmap, 270 ret = regmap_update_bits(rcg->clkr.regmap,
266 rcg->cmd_rcgr + M_REG, mask, f->m); 271 RCG_M_OFFSET(rcg), mask, f->m);
267 if (ret) 272 if (ret)
268 return ret; 273 return ret;
269 274
270 ret = regmap_update_bits(rcg->clkr.regmap, 275 ret = regmap_update_bits(rcg->clkr.regmap,
271 rcg->cmd_rcgr + N_REG, mask, ~(f->n - f->m)); 276 RCG_N_OFFSET(rcg), mask, ~(f->n - f->m));
272 if (ret) 277 if (ret)
273 return ret; 278 return ret;
274 279
275 ret = regmap_update_bits(rcg->clkr.regmap, 280 ret = regmap_update_bits(rcg->clkr.regmap,
276 rcg->cmd_rcgr + D_REG, mask, ~f->n); 281 RCG_D_OFFSET(rcg), mask, ~f->n);
277 if (ret) 282 if (ret)
278 return ret; 283 return ret;
279 } 284 }
@@ -284,8 +289,7 @@ static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
284 cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT; 289 cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
285 if (rcg->mnd_width && f->n && (f->m != f->n)) 290 if (rcg->mnd_width && f->n && (f->m != f->n))
286 cfg |= CFG_MODE_DUAL_EDGE; 291 cfg |= CFG_MODE_DUAL_EDGE;
287 292 return regmap_update_bits(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg),
288 return regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
289 mask, cfg); 293 mask, cfg);
290} 294}
291 295
diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c
index 9f4fc7773fb2..c3fd632af119 100644
--- a/drivers/clk/qcom/clk-rpmh.c
+++ b/drivers/clk/qcom/clk-rpmh.c
@@ -18,6 +18,31 @@
18#define CLK_RPMH_ARC_EN_OFFSET 0 18#define CLK_RPMH_ARC_EN_OFFSET 0
19#define CLK_RPMH_VRM_EN_OFFSET 4 19#define CLK_RPMH_VRM_EN_OFFSET 4
20 20
21#define BCM_TCS_CMD_COMMIT_MASK 0x40000000
22#define BCM_TCS_CMD_VALID_SHIFT 29
23#define BCM_TCS_CMD_VOTE_MASK 0x3fff
24#define BCM_TCS_CMD_VOTE_SHIFT 0
25
26#define BCM_TCS_CMD(valid, vote) \
27 (BCM_TCS_CMD_COMMIT_MASK | \
28 ((valid) << BCM_TCS_CMD_VALID_SHIFT) | \
29 ((vote & BCM_TCS_CMD_VOTE_MASK) \
30 << BCM_TCS_CMD_VOTE_SHIFT))
31
32/**
33 * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager(BCM)
34 * @unit: divisor used to convert Hz value to an RPMh msg
35 * @width: multiplier used to convert Hz value to an RPMh msg
36 * @vcd: virtual clock domain that this bcm belongs to
37 * @reserved: reserved to pad the struct
38 */
39struct bcm_db {
40 __le32 unit;
41 __le16 width;
42 u8 vcd;
43 u8 reserved;
44};
45
21/** 46/**
22 * struct clk_rpmh - individual rpmh clock data structure 47 * struct clk_rpmh - individual rpmh clock data structure
23 * @hw: handle between common and hardware-specific interfaces 48 * @hw: handle between common and hardware-specific interfaces
@@ -29,6 +54,7 @@
29 * @aggr_state: rpmh clock aggregated state 54 * @aggr_state: rpmh clock aggregated state
30 * @last_sent_aggr_state: rpmh clock last aggr state sent to RPMh 55 * @last_sent_aggr_state: rpmh clock last aggr state sent to RPMh
31 * @valid_state_mask: mask to determine the state of the rpmh clock 56 * @valid_state_mask: mask to determine the state of the rpmh clock
57 * @unit: divisor to convert rate to rpmh msg in magnitudes of Khz
32 * @dev: device to which it is attached 58 * @dev: device to which it is attached
33 * @peer: pointer to the clock rpmh sibling 59 * @peer: pointer to the clock rpmh sibling
34 */ 60 */
@@ -42,6 +68,7 @@ struct clk_rpmh {
42 u32 aggr_state; 68 u32 aggr_state;
43 u32 last_sent_aggr_state; 69 u32 last_sent_aggr_state;
44 u32 valid_state_mask; 70 u32 valid_state_mask;
71 u32 unit;
45 struct device *dev; 72 struct device *dev;
46 struct clk_rpmh *peer; 73 struct clk_rpmh *peer;
47}; 74};
@@ -98,6 +125,17 @@ static DEFINE_MUTEX(rpmh_clk_lock);
98 __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name, \ 125 __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name, \
99 CLK_RPMH_VRM_EN_OFFSET, 1, _div) 126 CLK_RPMH_VRM_EN_OFFSET, 1, _div)
100 127
128#define DEFINE_CLK_RPMH_BCM(_platform, _name, _res_name) \
129 static struct clk_rpmh _platform##_##_name = { \
130 .res_name = _res_name, \
131 .valid_state_mask = BIT(RPMH_ACTIVE_ONLY_STATE), \
132 .div = 1, \
133 .hw.init = &(struct clk_init_data){ \
134 .ops = &clk_rpmh_bcm_ops, \
135 .name = #_name, \
136 }, \
137 }
138
101static inline struct clk_rpmh *to_clk_rpmh(struct clk_hw *_hw) 139static inline struct clk_rpmh *to_clk_rpmh(struct clk_hw *_hw)
102{ 140{
103 return container_of(_hw, struct clk_rpmh, hw); 141 return container_of(_hw, struct clk_rpmh, hw);
@@ -210,6 +248,96 @@ static const struct clk_ops clk_rpmh_ops = {
210 .recalc_rate = clk_rpmh_recalc_rate, 248 .recalc_rate = clk_rpmh_recalc_rate,
211}; 249};
212 250
251static int clk_rpmh_bcm_send_cmd(struct clk_rpmh *c, bool enable)
252{
253 struct tcs_cmd cmd = { 0 };
254 u32 cmd_state;
255 int ret;
256
257 mutex_lock(&rpmh_clk_lock);
258
259 cmd_state = 0;
260 if (enable) {
261 cmd_state = 1;
262 if (c->aggr_state)
263 cmd_state = c->aggr_state;
264 }
265
266 if (c->last_sent_aggr_state == cmd_state) {
267 mutex_unlock(&rpmh_clk_lock);
268 return 0;
269 }
270
271 cmd.addr = c->res_addr;
272 cmd.data = BCM_TCS_CMD(enable, cmd_state);
273
274 ret = rpmh_write_async(c->dev, RPMH_ACTIVE_ONLY_STATE, &cmd, 1);
275 if (ret) {
276 dev_err(c->dev, "set active state of %s failed: (%d)\n",
277 c->res_name, ret);
278 mutex_unlock(&rpmh_clk_lock);
279 return ret;
280 }
281
282 c->last_sent_aggr_state = cmd_state;
283
284 mutex_unlock(&rpmh_clk_lock);
285
286 return 0;
287}
288
289static int clk_rpmh_bcm_prepare(struct clk_hw *hw)
290{
291 struct clk_rpmh *c = to_clk_rpmh(hw);
292
293 return clk_rpmh_bcm_send_cmd(c, true);
294};
295
296static void clk_rpmh_bcm_unprepare(struct clk_hw *hw)
297{
298 struct clk_rpmh *c = to_clk_rpmh(hw);
299
300 clk_rpmh_bcm_send_cmd(c, false);
301};
302
303static int clk_rpmh_bcm_set_rate(struct clk_hw *hw, unsigned long rate,
304 unsigned long parent_rate)
305{
306 struct clk_rpmh *c = to_clk_rpmh(hw);
307
308 c->aggr_state = rate / c->unit;
309 /*
310 * Since any non-zero value sent to hw would result in enabling the
311 * clock, only send the value if the clock has already been prepared.
312 */
313 if (clk_hw_is_prepared(hw))
314 clk_rpmh_bcm_send_cmd(c, true);
315
316 return 0;
317};
318
319static long clk_rpmh_round_rate(struct clk_hw *hw, unsigned long rate,
320 unsigned long *parent_rate)
321{
322 return rate;
323}
324
325static unsigned long clk_rpmh_bcm_recalc_rate(struct clk_hw *hw,
326 unsigned long prate)
327{
328 struct clk_rpmh *c = to_clk_rpmh(hw);
329
330 return c->aggr_state * c->unit;
331}
332
333static const struct clk_ops clk_rpmh_bcm_ops = {
334 .prepare = clk_rpmh_bcm_prepare,
335 .unprepare = clk_rpmh_bcm_unprepare,
336 .set_rate = clk_rpmh_bcm_set_rate,
337 .round_rate = clk_rpmh_round_rate,
338 .recalc_rate = clk_rpmh_bcm_recalc_rate,
339};
340
213/* Resource name must match resource id present in cmd-db. */ 341/* Resource name must match resource id present in cmd-db. */
214DEFINE_CLK_RPMH_ARC(sdm845, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 2); 342DEFINE_CLK_RPMH_ARC(sdm845, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 2);
215DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 2); 343DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 2);
@@ -217,6 +345,7 @@ DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk3, ln_bb_clk3_ao, "lnbclka3", 2);
217DEFINE_CLK_RPMH_VRM(sdm845, rf_clk1, rf_clk1_ao, "rfclka1", 1); 345DEFINE_CLK_RPMH_VRM(sdm845, rf_clk1, rf_clk1_ao, "rfclka1", 1);
218DEFINE_CLK_RPMH_VRM(sdm845, rf_clk2, rf_clk2_ao, "rfclka2", 1); 346DEFINE_CLK_RPMH_VRM(sdm845, rf_clk2, rf_clk2_ao, "rfclka2", 1);
219DEFINE_CLK_RPMH_VRM(sdm845, rf_clk3, rf_clk3_ao, "rfclka3", 1); 347DEFINE_CLK_RPMH_VRM(sdm845, rf_clk3, rf_clk3_ao, "rfclka3", 1);
348DEFINE_CLK_RPMH_BCM(sdm845, ipa, "IP0");
220 349
221static struct clk_hw *sdm845_rpmh_clocks[] = { 350static struct clk_hw *sdm845_rpmh_clocks[] = {
222 [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, 351 [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
@@ -231,6 +360,7 @@ static struct clk_hw *sdm845_rpmh_clocks[] = {
231 [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw, 360 [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw,
232 [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw, 361 [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw,
233 [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw, 362 [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw,
363 [RPMH_IPA_CLK] = &sdm845_ipa.hw,
234}; 364};
235 365
236static const struct clk_rpmh_desc clk_rpmh_sdm845 = { 366static const struct clk_rpmh_desc clk_rpmh_sdm845 = {
@@ -267,6 +397,8 @@ static int clk_rpmh_probe(struct platform_device *pdev)
267 397
268 for (i = 0; i < desc->num_clks; i++) { 398 for (i = 0; i < desc->num_clks; i++) {
269 u32 res_addr; 399 u32 res_addr;
400 size_t aux_data_len;
401 const struct bcm_db *data;
270 402
271 rpmh_clk = to_clk_rpmh(hw_clks[i]); 403 rpmh_clk = to_clk_rpmh(hw_clks[i]);
272 res_addr = cmd_db_read_addr(rpmh_clk->res_name); 404 res_addr = cmd_db_read_addr(rpmh_clk->res_name);
@@ -275,6 +407,20 @@ static int clk_rpmh_probe(struct platform_device *pdev)
275 rpmh_clk->res_name); 407 rpmh_clk->res_name);
276 return -ENODEV; 408 return -ENODEV;
277 } 409 }
410
411 data = cmd_db_read_aux_data(rpmh_clk->res_name, &aux_data_len);
412 if (IS_ERR(data)) {
413 ret = PTR_ERR(data);
414 dev_err(&pdev->dev,
415 "error reading RPMh aux data for %s (%d)\n",
416 rpmh_clk->res_name, ret);
417 return ret;
418 }
419
420 /* Convert unit from Khz to Hz */
421 if (aux_data_len == sizeof(*data))
422 rpmh_clk->unit = le32_to_cpu(data->unit) * 1000ULL;
423
278 rpmh_clk->res_addr += res_addr; 424 rpmh_clk->res_addr += res_addr;
279 rpmh_clk->dev = &pdev->dev; 425 rpmh_clk->dev = &pdev->dev;
280 426
diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c
index d3aadaeb2903..22dd42ad9223 100644
--- a/drivers/clk/qcom/clk-smd-rpm.c
+++ b/drivers/clk/qcom/clk-smd-rpm.c
@@ -655,10 +655,73 @@ static const struct rpm_smd_clk_desc rpm_clk_qcs404 = {
655 .num_clks = ARRAY_SIZE(qcs404_clks), 655 .num_clks = ARRAY_SIZE(qcs404_clks),
656}; 656};
657 657
658/* msm8998 */
659DEFINE_CLK_SMD_RPM(msm8998, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
660DEFINE_CLK_SMD_RPM(msm8998, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2);
661DEFINE_CLK_SMD_RPM(msm8998, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0);
662DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, div_clk1, div_clk1_a, 0xb);
663DEFINE_CLK_SMD_RPM(msm8998, ipa_clk, ipa_a_clk, QCOM_SMD_RPM_IPA_CLK, 0);
664DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, ln_bb_clk1, ln_bb_clk1_a, 1);
665DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, ln_bb_clk2, ln_bb_clk2_a, 2);
666DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, ln_bb_clk3_pin, ln_bb_clk3_a_pin,
667 3);
668DEFINE_CLK_SMD_RPM(msm8998, mmssnoc_axi_rpm_clk, mmssnoc_axi_rpm_a_clk,
669 QCOM_SMD_RPM_MMAXI_CLK, 0);
670DEFINE_CLK_SMD_RPM(msm8998, aggre1_noc_clk, aggre1_noc_a_clk,
671 QCOM_SMD_RPM_AGGR_CLK, 1);
672DEFINE_CLK_SMD_RPM(msm8998, aggre2_noc_clk, aggre2_noc_a_clk,
673 QCOM_SMD_RPM_AGGR_CLK, 2);
674DEFINE_CLK_SMD_RPM_QDSS(msm8998, qdss_clk, qdss_a_clk,
675 QCOM_SMD_RPM_MISC_CLK, 1);
676DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk1, rf_clk1_a, 4);
677DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk2_pin, rf_clk2_a_pin, 5);
678DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk3, rf_clk3_a, 6);
679DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk3_pin, rf_clk3_a_pin, 6);
680static struct clk_smd_rpm *msm8998_clks[] = {
681 [RPM_SMD_SNOC_CLK] = &msm8998_snoc_clk,
682 [RPM_SMD_SNOC_A_CLK] = &msm8998_snoc_a_clk,
683 [RPM_SMD_CNOC_CLK] = &msm8998_cnoc_clk,
684 [RPM_SMD_CNOC_A_CLK] = &msm8998_cnoc_a_clk,
685 [RPM_SMD_CE1_CLK] = &msm8998_ce1_clk,
686 [RPM_SMD_CE1_A_CLK] = &msm8998_ce1_a_clk,
687 [RPM_SMD_DIV_CLK1] = &msm8998_div_clk1,
688 [RPM_SMD_DIV_A_CLK1] = &msm8998_div_clk1_a,
689 [RPM_SMD_IPA_CLK] = &msm8998_ipa_clk,
690 [RPM_SMD_IPA_A_CLK] = &msm8998_ipa_a_clk,
691 [RPM_SMD_LN_BB_CLK1] = &msm8998_ln_bb_clk1,
692 [RPM_SMD_LN_BB_CLK1_A] = &msm8998_ln_bb_clk1_a,
693 [RPM_SMD_LN_BB_CLK2] = &msm8998_ln_bb_clk2,
694 [RPM_SMD_LN_BB_CLK2_A] = &msm8998_ln_bb_clk2_a,
695 [RPM_SMD_LN_BB_CLK3_PIN] = &msm8998_ln_bb_clk3_pin,
696 [RPM_SMD_LN_BB_CLK3_A_PIN] = &msm8998_ln_bb_clk3_a_pin,
697 [RPM_SMD_MMAXI_CLK] = &msm8998_mmssnoc_axi_rpm_clk,
698 [RPM_SMD_MMAXI_A_CLK] = &msm8998_mmssnoc_axi_rpm_a_clk,
699 [RPM_SMD_AGGR1_NOC_CLK] = &msm8998_aggre1_noc_clk,
700 [RPM_SMD_AGGR1_NOC_A_CLK] = &msm8998_aggre1_noc_a_clk,
701 [RPM_SMD_AGGR2_NOC_CLK] = &msm8998_aggre2_noc_clk,
702 [RPM_SMD_AGGR2_NOC_A_CLK] = &msm8998_aggre2_noc_a_clk,
703 [RPM_SMD_QDSS_CLK] = &msm8998_qdss_clk,
704 [RPM_SMD_QDSS_A_CLK] = &msm8998_qdss_a_clk,
705 [RPM_SMD_RF_CLK1] = &msm8998_rf_clk1,
706 [RPM_SMD_RF_CLK1_A] = &msm8998_rf_clk1_a,
707 [RPM_SMD_RF_CLK2_PIN] = &msm8998_rf_clk2_pin,
708 [RPM_SMD_RF_CLK2_A_PIN] = &msm8998_rf_clk2_a_pin,
709 [RPM_SMD_RF_CLK3] = &msm8998_rf_clk3,
710 [RPM_SMD_RF_CLK3_A] = &msm8998_rf_clk3_a,
711 [RPM_SMD_RF_CLK3_PIN] = &msm8998_rf_clk3_pin,
712 [RPM_SMD_RF_CLK3_A_PIN] = &msm8998_rf_clk3_a_pin,
713};
714
715static const struct rpm_smd_clk_desc rpm_clk_msm8998 = {
716 .clks = msm8998_clks,
717 .num_clks = ARRAY_SIZE(msm8998_clks),
718};
719
658static const struct of_device_id rpm_smd_clk_match_table[] = { 720static const struct of_device_id rpm_smd_clk_match_table[] = {
659 { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 }, 721 { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 },
660 { .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 }, 722 { .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 },
661 { .compatible = "qcom,rpmcc-msm8996", .data = &rpm_clk_msm8996 }, 723 { .compatible = "qcom,rpmcc-msm8996", .data = &rpm_clk_msm8996 },
724 { .compatible = "qcom,rpmcc-msm8998", .data = &rpm_clk_msm8998 },
662 { .compatible = "qcom,rpmcc-qcs404", .data = &rpm_clk_qcs404 }, 725 { .compatible = "qcom,rpmcc-qcs404", .data = &rpm_clk_qcs404 },
663 { } 726 { }
664}; 727};
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
index 0a48ed56833b..a6b2f86112d8 100644
--- a/drivers/clk/qcom/common.c
+++ b/drivers/clk/qcom/common.c
@@ -231,6 +231,8 @@ int qcom_cc_really_probe(struct platform_device *pdev,
231 struct gdsc_desc *scd; 231 struct gdsc_desc *scd;
232 size_t num_clks = desc->num_clks; 232 size_t num_clks = desc->num_clks;
233 struct clk_regmap **rclks = desc->clks; 233 struct clk_regmap **rclks = desc->clks;
234 size_t num_clk_hws = desc->num_clk_hws;
235 struct clk_hw **clk_hws = desc->clk_hws;
234 236
235 cc = devm_kzalloc(dev, sizeof(*cc), GFP_KERNEL); 237 cc = devm_kzalloc(dev, sizeof(*cc), GFP_KERNEL);
236 if (!cc) 238 if (!cc)
@@ -269,6 +271,12 @@ int qcom_cc_really_probe(struct platform_device *pdev,
269 271
270 qcom_cc_drop_protected(dev, cc); 272 qcom_cc_drop_protected(dev, cc);
271 273
274 for (i = 0; i < num_clk_hws; i++) {
275 ret = devm_clk_hw_register(dev, clk_hws[i]);
276 if (ret)
277 return ret;
278 }
279
272 for (i = 0; i < num_clks; i++) { 280 for (i = 0; i < num_clks; i++) {
273 if (!rclks[i]) 281 if (!rclks[i])
274 continue; 282 continue;
diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h
index 4aa33ee70bae..1e2a8bdac55a 100644
--- a/drivers/clk/qcom/common.h
+++ b/drivers/clk/qcom/common.h
@@ -27,6 +27,8 @@ struct qcom_cc_desc {
27 size_t num_resets; 27 size_t num_resets;
28 struct gdsc **gdscs; 28 struct gdsc **gdscs;
29 size_t num_gdscs; 29 size_t num_gdscs;
30 struct clk_hw **clk_hws;
31 size_t num_clk_hws;
30}; 32};
31 33
32/** 34/**
diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
index 505c6263141d..0e32892b438c 100644
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -4715,18 +4715,12 @@ static const struct qcom_cc_desc gcc_ipq8074_desc = {
4715 .num_clks = ARRAY_SIZE(gcc_ipq8074_clks), 4715 .num_clks = ARRAY_SIZE(gcc_ipq8074_clks),
4716 .resets = gcc_ipq8074_resets, 4716 .resets = gcc_ipq8074_resets,
4717 .num_resets = ARRAY_SIZE(gcc_ipq8074_resets), 4717 .num_resets = ARRAY_SIZE(gcc_ipq8074_resets),
4718 .clk_hws = gcc_ipq8074_hws,
4719 .num_clk_hws = ARRAY_SIZE(gcc_ipq8074_hws),
4718}; 4720};
4719 4721
4720static int gcc_ipq8074_probe(struct platform_device *pdev) 4722static int gcc_ipq8074_probe(struct platform_device *pdev)
4721{ 4723{
4722 int ret, i;
4723
4724 for (i = 0; i < ARRAY_SIZE(gcc_ipq8074_hws); i++) {
4725 ret = devm_clk_hw_register(&pdev->dev, gcc_ipq8074_hws[i]);
4726 if (ret)
4727 return ret;
4728 }
4729
4730 return qcom_cc_probe(pdev, &gcc_ipq8074_desc); 4724 return qcom_cc_probe(pdev, &gcc_ipq8074_desc);
4731} 4725}
4732 4726
diff --git a/drivers/clk/qcom/gcc-mdm9615.c b/drivers/clk/qcom/gcc-mdm9615.c
index 849046fbed6d..8c6d93144b9c 100644
--- a/drivers/clk/qcom/gcc-mdm9615.c
+++ b/drivers/clk/qcom/gcc-mdm9615.c
@@ -1702,6 +1702,8 @@ static const struct qcom_cc_desc gcc_mdm9615_desc = {
1702 .num_clks = ARRAY_SIZE(gcc_mdm9615_clks), 1702 .num_clks = ARRAY_SIZE(gcc_mdm9615_clks),
1703 .resets = gcc_mdm9615_resets, 1703 .resets = gcc_mdm9615_resets,
1704 .num_resets = ARRAY_SIZE(gcc_mdm9615_resets), 1704 .num_resets = ARRAY_SIZE(gcc_mdm9615_resets),
1705 .clk_hws = gcc_mdm9615_hws,
1706 .num_clk_hws = ARRAY_SIZE(gcc_mdm9615_hws),
1705}; 1707};
1706 1708
1707static const struct of_device_id gcc_mdm9615_match_table[] = { 1709static const struct of_device_id gcc_mdm9615_match_table[] = {
@@ -1712,21 +1714,12 @@ MODULE_DEVICE_TABLE(of, gcc_mdm9615_match_table);
1712 1714
1713static int gcc_mdm9615_probe(struct platform_device *pdev) 1715static int gcc_mdm9615_probe(struct platform_device *pdev)
1714{ 1716{
1715 struct device *dev = &pdev->dev;
1716 struct regmap *regmap; 1717 struct regmap *regmap;
1717 int ret;
1718 int i;
1719 1718
1720 regmap = qcom_cc_map(pdev, &gcc_mdm9615_desc); 1719 regmap = qcom_cc_map(pdev, &gcc_mdm9615_desc);
1721 if (IS_ERR(regmap)) 1720 if (IS_ERR(regmap))
1722 return PTR_ERR(regmap); 1721 return PTR_ERR(regmap);
1723 1722
1724 for (i = 0; i < ARRAY_SIZE(gcc_mdm9615_hws); i++) {
1725 ret = devm_clk_hw_register(dev, gcc_mdm9615_hws[i]);
1726 if (ret)
1727 return ret;
1728 }
1729
1730 return qcom_cc_really_probe(pdev, &gcc_mdm9615_desc, regmap); 1723 return qcom_cc_really_probe(pdev, &gcc_mdm9615_desc, regmap);
1731} 1724}
1732 1725
diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
index 9d136172c27c..4632b9272b7f 100644
--- a/drivers/clk/qcom/gcc-msm8996.c
+++ b/drivers/clk/qcom/gcc-msm8996.c
@@ -3656,6 +3656,8 @@ static const struct qcom_cc_desc gcc_msm8996_desc = {
3656 .num_resets = ARRAY_SIZE(gcc_msm8996_resets), 3656 .num_resets = ARRAY_SIZE(gcc_msm8996_resets),
3657 .gdscs = gcc_msm8996_gdscs, 3657 .gdscs = gcc_msm8996_gdscs,
3658 .num_gdscs = ARRAY_SIZE(gcc_msm8996_gdscs), 3658 .num_gdscs = ARRAY_SIZE(gcc_msm8996_gdscs),
3659 .clk_hws = gcc_msm8996_hws,
3660 .num_clk_hws = ARRAY_SIZE(gcc_msm8996_hws),
3659}; 3661};
3660 3662
3661static const struct of_device_id gcc_msm8996_match_table[] = { 3663static const struct of_device_id gcc_msm8996_match_table[] = {
@@ -3666,8 +3668,6 @@ MODULE_DEVICE_TABLE(of, gcc_msm8996_match_table);
3666 3668
3667static int gcc_msm8996_probe(struct platform_device *pdev) 3669static int gcc_msm8996_probe(struct platform_device *pdev)
3668{ 3670{
3669 struct device *dev = &pdev->dev;
3670 int i, ret;
3671 struct regmap *regmap; 3671 struct regmap *regmap;
3672 3672
3673 regmap = qcom_cc_map(pdev, &gcc_msm8996_desc); 3673 regmap = qcom_cc_map(pdev, &gcc_msm8996_desc);
@@ -3680,12 +3680,6 @@ static int gcc_msm8996_probe(struct platform_device *pdev)
3680 */ 3680 */
3681 regmap_update_bits(regmap, 0x52008, BIT(21), BIT(21)); 3681 regmap_update_bits(regmap, 0x52008, BIT(21), BIT(21));
3682 3682
3683 for (i = 0; i < ARRAY_SIZE(gcc_msm8996_hws); i++) {
3684 ret = devm_clk_hw_register(dev, gcc_msm8996_hws[i]);
3685 if (ret)
3686 return ret;
3687 }
3688
3689 return qcom_cc_really_probe(pdev, &gcc_msm8996_desc, regmap); 3683 return qcom_cc_really_probe(pdev, &gcc_msm8996_desc, regmap);
3690} 3684}
3691 3685
diff --git a/drivers/clk/qcom/gcc-msm8998.c b/drivers/clk/qcom/gcc-msm8998.c
index 1b779396e04f..c240fba794c7 100644
--- a/drivers/clk/qcom/gcc-msm8998.c
+++ b/drivers/clk/qcom/gcc-msm8998.c
@@ -1112,6 +1112,7 @@ static struct clk_rcg2 ufs_axi_clk_src = {
1112 1112
1113static const struct freq_tbl ftbl_usb30_master_clk_src[] = { 1113static const struct freq_tbl ftbl_usb30_master_clk_src[] = {
1114 F(19200000, P_XO, 1, 0, 0), 1114 F(19200000, P_XO, 1, 0, 0),
1115 F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
1115 F(120000000, P_GPLL0_OUT_MAIN, 5, 0, 0), 1116 F(120000000, P_GPLL0_OUT_MAIN, 5, 0, 0),
1116 F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), 1117 F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
1117 { } 1118 { }
@@ -1189,6 +1190,7 @@ static struct clk_branch gcc_aggre1_ufs_axi_clk = {
1189 "ufs_axi_clk_src", 1190 "ufs_axi_clk_src",
1190 }, 1191 },
1191 .num_parents = 1, 1192 .num_parents = 1,
1193 .flags = CLK_SET_RATE_PARENT,
1192 .ops = &clk_branch2_ops, 1194 .ops = &clk_branch2_ops,
1193 }, 1195 },
1194 }, 1196 },
@@ -1206,6 +1208,7 @@ static struct clk_branch gcc_aggre1_usb3_axi_clk = {
1206 "usb30_master_clk_src", 1208 "usb30_master_clk_src",
1207 }, 1209 },
1208 .num_parents = 1, 1210 .num_parents = 1,
1211 .flags = CLK_SET_RATE_PARENT,
1209 .ops = &clk_branch2_ops, 1212 .ops = &clk_branch2_ops,
1210 }, 1213 },
1211 }, 1214 },
@@ -1288,6 +1291,7 @@ static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
1288 "blsp1_qup1_i2c_apps_clk_src", 1291 "blsp1_qup1_i2c_apps_clk_src",
1289 }, 1292 },
1290 .num_parents = 1, 1293 .num_parents = 1,
1294 .flags = CLK_SET_RATE_PARENT,
1291 .ops = &clk_branch2_ops, 1295 .ops = &clk_branch2_ops,
1292 }, 1296 },
1293 }, 1297 },
@@ -1305,6 +1309,7 @@ static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
1305 "blsp1_qup1_spi_apps_clk_src", 1309 "blsp1_qup1_spi_apps_clk_src",
1306 }, 1310 },
1307 .num_parents = 1, 1311 .num_parents = 1,
1312 .flags = CLK_SET_RATE_PARENT,
1308 .ops = &clk_branch2_ops, 1313 .ops = &clk_branch2_ops,
1309 }, 1314 },
1310 }, 1315 },
@@ -1322,6 +1327,7 @@ static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
1322 "blsp1_qup2_i2c_apps_clk_src", 1327 "blsp1_qup2_i2c_apps_clk_src",
1323 }, 1328 },
1324 .num_parents = 1, 1329 .num_parents = 1,
1330 .flags = CLK_SET_RATE_PARENT,
1325 .ops = &clk_branch2_ops, 1331 .ops = &clk_branch2_ops,
1326 }, 1332 },
1327 }, 1333 },
@@ -1339,6 +1345,7 @@ static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
1339 "blsp1_qup2_spi_apps_clk_src", 1345 "blsp1_qup2_spi_apps_clk_src",
1340 }, 1346 },
1341 .num_parents = 1, 1347 .num_parents = 1,
1348 .flags = CLK_SET_RATE_PARENT,
1342 .ops = &clk_branch2_ops, 1349 .ops = &clk_branch2_ops,
1343 }, 1350 },
1344 }, 1351 },
@@ -1356,6 +1363,7 @@ static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
1356 "blsp1_qup3_i2c_apps_clk_src", 1363 "blsp1_qup3_i2c_apps_clk_src",
1357 }, 1364 },
1358 .num_parents = 1, 1365 .num_parents = 1,
1366 .flags = CLK_SET_RATE_PARENT,
1359 .ops = &clk_branch2_ops, 1367 .ops = &clk_branch2_ops,
1360 }, 1368 },
1361 }, 1369 },
@@ -1373,6 +1381,7 @@ static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
1373 "blsp1_qup3_spi_apps_clk_src", 1381 "blsp1_qup3_spi_apps_clk_src",
1374 }, 1382 },
1375 .num_parents = 1, 1383 .num_parents = 1,
1384 .flags = CLK_SET_RATE_PARENT,
1376 .ops = &clk_branch2_ops, 1385 .ops = &clk_branch2_ops,
1377 }, 1386 },
1378 }, 1387 },
@@ -1390,6 +1399,7 @@ static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
1390 "blsp1_qup4_i2c_apps_clk_src", 1399 "blsp1_qup4_i2c_apps_clk_src",
1391 }, 1400 },
1392 .num_parents = 1, 1401 .num_parents = 1,
1402 .flags = CLK_SET_RATE_PARENT,
1393 .ops = &clk_branch2_ops, 1403 .ops = &clk_branch2_ops,
1394 }, 1404 },
1395 }, 1405 },
@@ -1407,6 +1417,7 @@ static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
1407 "blsp1_qup4_spi_apps_clk_src", 1417 "blsp1_qup4_spi_apps_clk_src",
1408 }, 1418 },
1409 .num_parents = 1, 1419 .num_parents = 1,
1420 .flags = CLK_SET_RATE_PARENT,
1410 .ops = &clk_branch2_ops, 1421 .ops = &clk_branch2_ops,
1411 }, 1422 },
1412 }, 1423 },
@@ -1424,6 +1435,7 @@ static struct clk_branch gcc_blsp1_qup5_i2c_apps_clk = {
1424 "blsp1_qup5_i2c_apps_clk_src", 1435 "blsp1_qup5_i2c_apps_clk_src",
1425 }, 1436 },
1426 .num_parents = 1, 1437 .num_parents = 1,
1438 .flags = CLK_SET_RATE_PARENT,
1427 .ops = &clk_branch2_ops, 1439 .ops = &clk_branch2_ops,
1428 }, 1440 },
1429 }, 1441 },
@@ -1441,6 +1453,7 @@ static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = {
1441 "blsp1_qup5_spi_apps_clk_src", 1453 "blsp1_qup5_spi_apps_clk_src",
1442 }, 1454 },
1443 .num_parents = 1, 1455 .num_parents = 1,
1456 .flags = CLK_SET_RATE_PARENT,
1444 .ops = &clk_branch2_ops, 1457 .ops = &clk_branch2_ops,
1445 }, 1458 },
1446 }, 1459 },
@@ -1458,6 +1471,7 @@ static struct clk_branch gcc_blsp1_qup6_i2c_apps_clk = {
1458 "blsp1_qup6_i2c_apps_clk_src", 1471 "blsp1_qup6_i2c_apps_clk_src",
1459 }, 1472 },
1460 .num_parents = 1, 1473 .num_parents = 1,
1474 .flags = CLK_SET_RATE_PARENT,
1461 .ops = &clk_branch2_ops, 1475 .ops = &clk_branch2_ops,
1462 }, 1476 },
1463 }, 1477 },
@@ -1475,6 +1489,7 @@ static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = {
1475 "blsp1_qup6_spi_apps_clk_src", 1489 "blsp1_qup6_spi_apps_clk_src",
1476 }, 1490 },
1477 .num_parents = 1, 1491 .num_parents = 1,
1492 .flags = CLK_SET_RATE_PARENT,
1478 .ops = &clk_branch2_ops, 1493 .ops = &clk_branch2_ops,
1479 }, 1494 },
1480 }, 1495 },
@@ -1505,6 +1520,7 @@ static struct clk_branch gcc_blsp1_uart1_apps_clk = {
1505 "blsp1_uart1_apps_clk_src", 1520 "blsp1_uart1_apps_clk_src",
1506 }, 1521 },
1507 .num_parents = 1, 1522 .num_parents = 1,
1523 .flags = CLK_SET_RATE_PARENT,
1508 .ops = &clk_branch2_ops, 1524 .ops = &clk_branch2_ops,
1509 }, 1525 },
1510 }, 1526 },
@@ -1522,6 +1538,7 @@ static struct clk_branch gcc_blsp1_uart2_apps_clk = {
1522 "blsp1_uart2_apps_clk_src", 1538 "blsp1_uart2_apps_clk_src",
1523 }, 1539 },
1524 .num_parents = 1, 1540 .num_parents = 1,
1541 .flags = CLK_SET_RATE_PARENT,
1525 .ops = &clk_branch2_ops, 1542 .ops = &clk_branch2_ops,
1526 }, 1543 },
1527 }, 1544 },
@@ -1539,6 +1556,7 @@ static struct clk_branch gcc_blsp1_uart3_apps_clk = {
1539 "blsp1_uart3_apps_clk_src", 1556 "blsp1_uart3_apps_clk_src",
1540 }, 1557 },
1541 .num_parents = 1, 1558 .num_parents = 1,
1559 .flags = CLK_SET_RATE_PARENT,
1542 .ops = &clk_branch2_ops, 1560 .ops = &clk_branch2_ops,
1543 }, 1561 },
1544 }, 1562 },
@@ -1569,6 +1587,7 @@ static struct clk_branch gcc_blsp2_qup1_i2c_apps_clk = {
1569 "blsp2_qup1_i2c_apps_clk_src", 1587 "blsp2_qup1_i2c_apps_clk_src",
1570 }, 1588 },
1571 .num_parents = 1, 1589 .num_parents = 1,
1590 .flags = CLK_SET_RATE_PARENT,
1572 .ops = &clk_branch2_ops, 1591 .ops = &clk_branch2_ops,
1573 }, 1592 },
1574 }, 1593 },
@@ -1586,6 +1605,7 @@ static struct clk_branch gcc_blsp2_qup1_spi_apps_clk = {
1586 "blsp2_qup1_spi_apps_clk_src", 1605 "blsp2_qup1_spi_apps_clk_src",
1587 }, 1606 },
1588 .num_parents = 1, 1607 .num_parents = 1,
1608 .flags = CLK_SET_RATE_PARENT,
1589 .ops = &clk_branch2_ops, 1609 .ops = &clk_branch2_ops,
1590 }, 1610 },
1591 }, 1611 },
@@ -1603,6 +1623,7 @@ static struct clk_branch gcc_blsp2_qup2_i2c_apps_clk = {
1603 "blsp2_qup2_i2c_apps_clk_src", 1623 "blsp2_qup2_i2c_apps_clk_src",
1604 }, 1624 },
1605 .num_parents = 1, 1625 .num_parents = 1,
1626 .flags = CLK_SET_RATE_PARENT,
1606 .ops = &clk_branch2_ops, 1627 .ops = &clk_branch2_ops,
1607 }, 1628 },
1608 }, 1629 },
@@ -1620,6 +1641,7 @@ static struct clk_branch gcc_blsp2_qup2_spi_apps_clk = {
1620 "blsp2_qup2_spi_apps_clk_src", 1641 "blsp2_qup2_spi_apps_clk_src",
1621 }, 1642 },
1622 .num_parents = 1, 1643 .num_parents = 1,
1644 .flags = CLK_SET_RATE_PARENT,
1623 .ops = &clk_branch2_ops, 1645 .ops = &clk_branch2_ops,
1624 }, 1646 },
1625 }, 1647 },
@@ -1637,6 +1659,7 @@ static struct clk_branch gcc_blsp2_qup3_i2c_apps_clk = {
1637 "blsp2_qup3_i2c_apps_clk_src", 1659 "blsp2_qup3_i2c_apps_clk_src",
1638 }, 1660 },
1639 .num_parents = 1, 1661 .num_parents = 1,
1662 .flags = CLK_SET_RATE_PARENT,
1640 .ops = &clk_branch2_ops, 1663 .ops = &clk_branch2_ops,
1641 }, 1664 },
1642 }, 1665 },
@@ -1654,6 +1677,7 @@ static struct clk_branch gcc_blsp2_qup3_spi_apps_clk = {
1654 "blsp2_qup3_spi_apps_clk_src", 1677 "blsp2_qup3_spi_apps_clk_src",
1655 }, 1678 },
1656 .num_parents = 1, 1679 .num_parents = 1,
1680 .flags = CLK_SET_RATE_PARENT,
1657 .ops = &clk_branch2_ops, 1681 .ops = &clk_branch2_ops,
1658 }, 1682 },
1659 }, 1683 },
@@ -1671,6 +1695,7 @@ static struct clk_branch gcc_blsp2_qup4_i2c_apps_clk = {
1671 "blsp2_qup4_i2c_apps_clk_src", 1695 "blsp2_qup4_i2c_apps_clk_src",
1672 }, 1696 },
1673 .num_parents = 1, 1697 .num_parents = 1,
1698 .flags = CLK_SET_RATE_PARENT,
1674 .ops = &clk_branch2_ops, 1699 .ops = &clk_branch2_ops,
1675 }, 1700 },
1676 }, 1701 },
@@ -1688,6 +1713,7 @@ static struct clk_branch gcc_blsp2_qup4_spi_apps_clk = {
1688 "blsp2_qup4_spi_apps_clk_src", 1713 "blsp2_qup4_spi_apps_clk_src",
1689 }, 1714 },
1690 .num_parents = 1, 1715 .num_parents = 1,
1716 .flags = CLK_SET_RATE_PARENT,
1691 .ops = &clk_branch2_ops, 1717 .ops = &clk_branch2_ops,
1692 }, 1718 },
1693 }, 1719 },
@@ -1705,6 +1731,7 @@ static struct clk_branch gcc_blsp2_qup5_i2c_apps_clk = {
1705 "blsp2_qup5_i2c_apps_clk_src", 1731 "blsp2_qup5_i2c_apps_clk_src",
1706 }, 1732 },
1707 .num_parents = 1, 1733 .num_parents = 1,
1734 .flags = CLK_SET_RATE_PARENT,
1708 .ops = &clk_branch2_ops, 1735 .ops = &clk_branch2_ops,
1709 }, 1736 },
1710 }, 1737 },
@@ -1722,6 +1749,7 @@ static struct clk_branch gcc_blsp2_qup5_spi_apps_clk = {
1722 "blsp2_qup5_spi_apps_clk_src", 1749 "blsp2_qup5_spi_apps_clk_src",
1723 }, 1750 },
1724 .num_parents = 1, 1751 .num_parents = 1,
1752 .flags = CLK_SET_RATE_PARENT,
1725 .ops = &clk_branch2_ops, 1753 .ops = &clk_branch2_ops,
1726 }, 1754 },
1727 }, 1755 },
@@ -1739,6 +1767,7 @@ static struct clk_branch gcc_blsp2_qup6_i2c_apps_clk = {
1739 "blsp2_qup6_i2c_apps_clk_src", 1767 "blsp2_qup6_i2c_apps_clk_src",
1740 }, 1768 },
1741 .num_parents = 1, 1769 .num_parents = 1,
1770 .flags = CLK_SET_RATE_PARENT,
1742 .ops = &clk_branch2_ops, 1771 .ops = &clk_branch2_ops,
1743 }, 1772 },
1744 }, 1773 },
@@ -1756,6 +1785,7 @@ static struct clk_branch gcc_blsp2_qup6_spi_apps_clk = {
1756 "blsp2_qup6_spi_apps_clk_src", 1785 "blsp2_qup6_spi_apps_clk_src",
1757 }, 1786 },
1758 .num_parents = 1, 1787 .num_parents = 1,
1788 .flags = CLK_SET_RATE_PARENT,
1759 .ops = &clk_branch2_ops, 1789 .ops = &clk_branch2_ops,
1760 }, 1790 },
1761 }, 1791 },
@@ -1786,6 +1816,7 @@ static struct clk_branch gcc_blsp2_uart1_apps_clk = {
1786 "blsp2_uart1_apps_clk_src", 1816 "blsp2_uart1_apps_clk_src",
1787 }, 1817 },
1788 .num_parents = 1, 1818 .num_parents = 1,
1819 .flags = CLK_SET_RATE_PARENT,
1789 .ops = &clk_branch2_ops, 1820 .ops = &clk_branch2_ops,
1790 }, 1821 },
1791 }, 1822 },
@@ -1803,6 +1834,7 @@ static struct clk_branch gcc_blsp2_uart2_apps_clk = {
1803 "blsp2_uart2_apps_clk_src", 1834 "blsp2_uart2_apps_clk_src",
1804 }, 1835 },
1805 .num_parents = 1, 1836 .num_parents = 1,
1837 .flags = CLK_SET_RATE_PARENT,
1806 .ops = &clk_branch2_ops, 1838 .ops = &clk_branch2_ops,
1807 }, 1839 },
1808 }, 1840 },
@@ -1820,6 +1852,7 @@ static struct clk_branch gcc_blsp2_uart3_apps_clk = {
1820 "blsp2_uart3_apps_clk_src", 1852 "blsp2_uart3_apps_clk_src",
1821 }, 1853 },
1822 .num_parents = 1, 1854 .num_parents = 1,
1855 .flags = CLK_SET_RATE_PARENT,
1823 .ops = &clk_branch2_ops, 1856 .ops = &clk_branch2_ops,
1824 }, 1857 },
1825 }, 1858 },
@@ -1837,6 +1870,7 @@ static struct clk_branch gcc_cfg_noc_usb3_axi_clk = {
1837 "usb30_master_clk_src", 1870 "usb30_master_clk_src",
1838 }, 1871 },
1839 .num_parents = 1, 1872 .num_parents = 1,
1873 .flags = CLK_SET_RATE_PARENT,
1840 .ops = &clk_branch2_ops, 1874 .ops = &clk_branch2_ops,
1841 }, 1875 },
1842 }, 1876 },
@@ -1854,6 +1888,7 @@ static struct clk_branch gcc_gp1_clk = {
1854 "gp1_clk_src", 1888 "gp1_clk_src",
1855 }, 1889 },
1856 .num_parents = 1, 1890 .num_parents = 1,
1891 .flags = CLK_SET_RATE_PARENT,
1857 .ops = &clk_branch2_ops, 1892 .ops = &clk_branch2_ops,
1858 }, 1893 },
1859 }, 1894 },
@@ -1871,6 +1906,7 @@ static struct clk_branch gcc_gp2_clk = {
1871 "gp2_clk_src", 1906 "gp2_clk_src",
1872 }, 1907 },
1873 .num_parents = 1, 1908 .num_parents = 1,
1909 .flags = CLK_SET_RATE_PARENT,
1874 .ops = &clk_branch2_ops, 1910 .ops = &clk_branch2_ops,
1875 }, 1911 },
1876 }, 1912 },
@@ -1888,6 +1924,7 @@ static struct clk_branch gcc_gp3_clk = {
1888 "gp3_clk_src", 1924 "gp3_clk_src",
1889 }, 1925 },
1890 .num_parents = 1, 1926 .num_parents = 1,
1927 .flags = CLK_SET_RATE_PARENT,
1891 .ops = &clk_branch2_ops, 1928 .ops = &clk_branch2_ops,
1892 }, 1929 },
1893 }, 1930 },
@@ -1957,6 +1994,7 @@ static struct clk_branch gcc_hmss_ahb_clk = {
1957 "hmss_ahb_clk_src", 1994 "hmss_ahb_clk_src",
1958 }, 1995 },
1959 .num_parents = 1, 1996 .num_parents = 1,
1997 .flags = CLK_SET_RATE_PARENT,
1960 .ops = &clk_branch2_ops, 1998 .ops = &clk_branch2_ops,
1961 }, 1999 },
1962 }, 2000 },
@@ -1987,6 +2025,7 @@ static struct clk_branch gcc_hmss_rbcpr_clk = {
1987 "hmss_rbcpr_clk_src", 2025 "hmss_rbcpr_clk_src",
1988 }, 2026 },
1989 .num_parents = 1, 2027 .num_parents = 1,
2028 .flags = CLK_SET_RATE_PARENT,
1990 .ops = &clk_branch2_ops, 2029 .ops = &clk_branch2_ops,
1991 }, 2030 },
1992 }, 2031 },
@@ -2088,6 +2127,7 @@ static struct clk_branch gcc_pcie_0_aux_clk = {
2088 "pcie_aux_clk_src", 2127 "pcie_aux_clk_src",
2089 }, 2128 },
2090 .num_parents = 1, 2129 .num_parents = 1,
2130 .flags = CLK_SET_RATE_PARENT,
2091 .ops = &clk_branch2_ops, 2131 .ops = &clk_branch2_ops,
2092 }, 2132 },
2093 }, 2133 },
@@ -2157,6 +2197,7 @@ static struct clk_branch gcc_pcie_phy_aux_clk = {
2157 "pcie_aux_clk_src", 2197 "pcie_aux_clk_src",
2158 }, 2198 },
2159 .num_parents = 1, 2199 .num_parents = 1,
2200 .flags = CLK_SET_RATE_PARENT,
2160 .ops = &clk_branch2_ops, 2201 .ops = &clk_branch2_ops,
2161 }, 2202 },
2162 }, 2203 },
@@ -2174,6 +2215,7 @@ static struct clk_branch gcc_pdm2_clk = {
2174 "pdm2_clk_src", 2215 "pdm2_clk_src",
2175 }, 2216 },
2176 .num_parents = 1, 2217 .num_parents = 1,
2218 .flags = CLK_SET_RATE_PARENT,
2177 .ops = &clk_branch2_ops, 2219 .ops = &clk_branch2_ops,
2178 }, 2220 },
2179 }, 2221 },
@@ -2243,6 +2285,7 @@ static struct clk_branch gcc_sdcc2_apps_clk = {
2243 "sdcc2_apps_clk_src", 2285 "sdcc2_apps_clk_src",
2244 }, 2286 },
2245 .num_parents = 1, 2287 .num_parents = 1,
2288 .flags = CLK_SET_RATE_PARENT,
2246 .ops = &clk_branch2_ops, 2289 .ops = &clk_branch2_ops,
2247 }, 2290 },
2248 }, 2291 },
@@ -2273,6 +2316,7 @@ static struct clk_branch gcc_sdcc4_apps_clk = {
2273 "sdcc4_apps_clk_src", 2316 "sdcc4_apps_clk_src",
2274 }, 2317 },
2275 .num_parents = 1, 2318 .num_parents = 1,
2319 .flags = CLK_SET_RATE_PARENT,
2276 .ops = &clk_branch2_ops, 2320 .ops = &clk_branch2_ops,
2277 }, 2321 },
2278 }, 2322 },
@@ -2316,6 +2360,7 @@ static struct clk_branch gcc_tsif_ref_clk = {
2316 "tsif_ref_clk_src", 2360 "tsif_ref_clk_src",
2317 }, 2361 },
2318 .num_parents = 1, 2362 .num_parents = 1,
2363 .flags = CLK_SET_RATE_PARENT,
2319 .ops = &clk_branch2_ops, 2364 .ops = &clk_branch2_ops,
2320 }, 2365 },
2321 }, 2366 },
@@ -2346,6 +2391,7 @@ static struct clk_branch gcc_ufs_axi_clk = {
2346 "ufs_axi_clk_src", 2391 "ufs_axi_clk_src",
2347 }, 2392 },
2348 .num_parents = 1, 2393 .num_parents = 1,
2394 .flags = CLK_SET_RATE_PARENT,
2349 .ops = &clk_branch2_ops, 2395 .ops = &clk_branch2_ops,
2350 }, 2396 },
2351 }, 2397 },
@@ -2441,6 +2487,7 @@ static struct clk_branch gcc_usb30_master_clk = {
2441 "usb30_master_clk_src", 2487 "usb30_master_clk_src",
2442 }, 2488 },
2443 .num_parents = 1, 2489 .num_parents = 1,
2490 .flags = CLK_SET_RATE_PARENT,
2444 .ops = &clk_branch2_ops, 2491 .ops = &clk_branch2_ops,
2445 }, 2492 },
2446 }, 2493 },
@@ -2458,6 +2505,7 @@ static struct clk_branch gcc_usb30_mock_utmi_clk = {
2458 "usb30_mock_utmi_clk_src", 2505 "usb30_mock_utmi_clk_src",
2459 }, 2506 },
2460 .num_parents = 1, 2507 .num_parents = 1,
2508 .flags = CLK_SET_RATE_PARENT,
2461 .ops = &clk_branch2_ops, 2509 .ops = &clk_branch2_ops,
2462 }, 2510 },
2463 }, 2511 },
@@ -2488,6 +2536,7 @@ static struct clk_branch gcc_usb3_phy_aux_clk = {
2488 "usb3_phy_aux_clk_src", 2536 "usb3_phy_aux_clk_src",
2489 }, 2537 },
2490 .num_parents = 1, 2538 .num_parents = 1,
2539 .flags = CLK_SET_RATE_PARENT,
2491 .ops = &clk_branch2_ops, 2540 .ops = &clk_branch2_ops,
2492 }, 2541 },
2493 }, 2542 },
@@ -2495,7 +2544,7 @@ static struct clk_branch gcc_usb3_phy_aux_clk = {
2495 2544
2496static struct clk_branch gcc_usb3_phy_pipe_clk = { 2545static struct clk_branch gcc_usb3_phy_pipe_clk = {
2497 .halt_reg = 0x50004, 2546 .halt_reg = 0x50004,
2498 .halt_check = BRANCH_HALT, 2547 .halt_check = BRANCH_HALT_SKIP,
2499 .clkr = { 2548 .clkr = {
2500 .enable_reg = 0x50004, 2549 .enable_reg = 0x50004,
2501 .enable_mask = BIT(0), 2550 .enable_mask = BIT(0),
@@ -2910,6 +2959,10 @@ static const struct regmap_config gcc_msm8998_regmap_config = {
2910 .fast_io = true, 2959 .fast_io = true,
2911}; 2960};
2912 2961
2962static struct clk_hw *gcc_msm8998_hws[] = {
2963 &xo.hw,
2964};
2965
2913static const struct qcom_cc_desc gcc_msm8998_desc = { 2966static const struct qcom_cc_desc gcc_msm8998_desc = {
2914 .config = &gcc_msm8998_regmap_config, 2967 .config = &gcc_msm8998_regmap_config,
2915 .clks = gcc_msm8998_clocks, 2968 .clks = gcc_msm8998_clocks,
@@ -2918,6 +2971,8 @@ static const struct qcom_cc_desc gcc_msm8998_desc = {
2918 .num_resets = ARRAY_SIZE(gcc_msm8998_resets), 2971 .num_resets = ARRAY_SIZE(gcc_msm8998_resets),
2919 .gdscs = gcc_msm8998_gdscs, 2972 .gdscs = gcc_msm8998_gdscs,
2920 .num_gdscs = ARRAY_SIZE(gcc_msm8998_gdscs), 2973 .num_gdscs = ARRAY_SIZE(gcc_msm8998_gdscs),
2974 .clk_hws = gcc_msm8998_hws,
2975 .num_clk_hws = ARRAY_SIZE(gcc_msm8998_hws),
2921}; 2976};
2922 2977
2923static int gcc_msm8998_probe(struct platform_device *pdev) 2978static int gcc_msm8998_probe(struct platform_device *pdev)
@@ -2937,10 +2992,6 @@ static int gcc_msm8998_probe(struct platform_device *pdev)
2937 if (ret) 2992 if (ret)
2938 return ret; 2993 return ret;
2939 2994
2940 ret = devm_clk_hw_register(&pdev->dev, &xo.hw);
2941 if (ret)
2942 return ret;
2943
2944 return qcom_cc_really_probe(pdev, &gcc_msm8998_desc, regmap); 2995 return qcom_cc_really_probe(pdev, &gcc_msm8998_desc, regmap);
2945} 2996}
2946 2997
diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c
index 64da032bb9ed..5a62f64ada93 100644
--- a/drivers/clk/qcom/gcc-qcs404.c
+++ b/drivers/clk/qcom/gcc-qcs404.c
@@ -678,6 +678,7 @@ static struct clk_rcg2 blsp1_uart3_apps_clk_src = {
678 .cmd_rcgr = 0x4014, 678 .cmd_rcgr = 0x4014,
679 .mnd_width = 16, 679 .mnd_width = 16,
680 .hid_width = 5, 680 .hid_width = 5,
681 .cfg_off = 0x20,
681 .parent_map = gcc_parent_map_0, 682 .parent_map = gcc_parent_map_0,
682 .freq_tbl = ftbl_blsp1_uart0_apps_clk_src, 683 .freq_tbl = ftbl_blsp1_uart0_apps_clk_src,
683 .clkr.hw.init = &(struct clk_init_data){ 684 .clkr.hw.init = &(struct clk_init_data){
@@ -2692,6 +2693,8 @@ static const struct qcom_cc_desc gcc_qcs404_desc = {
2692 .num_clks = ARRAY_SIZE(gcc_qcs404_clocks), 2693 .num_clks = ARRAY_SIZE(gcc_qcs404_clocks),
2693 .resets = gcc_qcs404_resets, 2694 .resets = gcc_qcs404_resets,
2694 .num_resets = ARRAY_SIZE(gcc_qcs404_resets), 2695 .num_resets = ARRAY_SIZE(gcc_qcs404_resets),
2696 .clk_hws = gcc_qcs404_hws,
2697 .num_clk_hws = ARRAY_SIZE(gcc_qcs404_hws),
2695}; 2698};
2696 2699
2697static const struct of_device_id gcc_qcs404_match_table[] = { 2700static const struct of_device_id gcc_qcs404_match_table[] = {
@@ -2703,7 +2706,6 @@ MODULE_DEVICE_TABLE(of, gcc_qcs404_match_table);
2703static int gcc_qcs404_probe(struct platform_device *pdev) 2706static int gcc_qcs404_probe(struct platform_device *pdev)
2704{ 2707{
2705 struct regmap *regmap; 2708 struct regmap *regmap;
2706 int ret, i;
2707 2709
2708 regmap = qcom_cc_map(pdev, &gcc_qcs404_desc); 2710 regmap = qcom_cc_map(pdev, &gcc_qcs404_desc);
2709 if (IS_ERR(regmap)) 2711 if (IS_ERR(regmap))
@@ -2711,12 +2713,6 @@ static int gcc_qcs404_probe(struct platform_device *pdev)
2711 2713
2712 clk_alpha_pll_configure(&gpll3_out_main, regmap, &gpll3_config); 2714 clk_alpha_pll_configure(&gpll3_out_main, regmap, &gpll3_config);
2713 2715
2714 for (i = 0; i < ARRAY_SIZE(gcc_qcs404_hws); i++) {
2715 ret = devm_clk_hw_register(&pdev->dev, gcc_qcs404_hws[i]);
2716 if (ret)
2717 return ret;
2718 }
2719
2720 return qcom_cc_really_probe(pdev, &gcc_qcs404_desc, regmap); 2716 return qcom_cc_really_probe(pdev, &gcc_qcs404_desc, regmap);
2721} 2717}
2722 2718
diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c
index ba239ea4c842..8827db23066f 100644
--- a/drivers/clk/qcom/gcc-sdm660.c
+++ b/drivers/clk/qcom/gcc-sdm660.c
@@ -2420,6 +2420,8 @@ static const struct qcom_cc_desc gcc_sdm660_desc = {
2420 .num_resets = ARRAY_SIZE(gcc_sdm660_resets), 2420 .num_resets = ARRAY_SIZE(gcc_sdm660_resets),
2421 .gdscs = gcc_sdm660_gdscs, 2421 .gdscs = gcc_sdm660_gdscs,
2422 .num_gdscs = ARRAY_SIZE(gcc_sdm660_gdscs), 2422 .num_gdscs = ARRAY_SIZE(gcc_sdm660_gdscs),
2423 .clk_hws = gcc_sdm660_hws,
2424 .num_clk_hws = ARRAY_SIZE(gcc_sdm660_hws),
2423}; 2425};
2424 2426
2425static const struct of_device_id gcc_sdm660_match_table[] = { 2427static const struct of_device_id gcc_sdm660_match_table[] = {
@@ -2431,7 +2433,7 @@ MODULE_DEVICE_TABLE(of, gcc_sdm660_match_table);
2431 2433
2432static int gcc_sdm660_probe(struct platform_device *pdev) 2434static int gcc_sdm660_probe(struct platform_device *pdev)
2433{ 2435{
2434 int i, ret; 2436 int ret;
2435 struct regmap *regmap; 2437 struct regmap *regmap;
2436 2438
2437 regmap = qcom_cc_map(pdev, &gcc_sdm660_desc); 2439 regmap = qcom_cc_map(pdev, &gcc_sdm660_desc);
@@ -2446,13 +2448,6 @@ static int gcc_sdm660_probe(struct platform_device *pdev)
2446 if (ret) 2448 if (ret)
2447 return ret; 2449 return ret;
2448 2450
2449 /* Register the hws */
2450 for (i = 0; i < ARRAY_SIZE(gcc_sdm660_hws); i++) {
2451 ret = devm_clk_hw_register(&pdev->dev, gcc_sdm660_hws[i]);
2452 if (ret)
2453 return ret;
2454 }
2455
2456 return qcom_cc_really_probe(pdev, &gcc_sdm660_desc, regmap); 2451 return qcom_cc_really_probe(pdev, &gcc_sdm660_desc, regmap);
2457} 2452}
2458 2453
diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index 58fa5c247af1..7131dcf9b060 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -1703,6 +1703,9 @@ static struct clk_branch gcc_pcie_0_pipe_clk = {
1703 .enable_mask = BIT(4), 1703 .enable_mask = BIT(4),
1704 .hw.init = &(struct clk_init_data){ 1704 .hw.init = &(struct clk_init_data){
1705 .name = "gcc_pcie_0_pipe_clk", 1705 .name = "gcc_pcie_0_pipe_clk",
1706 .parent_names = (const char *[]){ "pcie_0_pipe_clk" },
1707 .num_parents = 1,
1708 .flags = CLK_SET_RATE_PARENT,
1706 .ops = &clk_branch2_ops, 1709 .ops = &clk_branch2_ops,
1707 }, 1710 },
1708 }, 1711 },
@@ -1802,6 +1805,8 @@ static struct clk_branch gcc_pcie_1_pipe_clk = {
1802 .enable_mask = BIT(30), 1805 .enable_mask = BIT(30),
1803 .hw.init = &(struct clk_init_data){ 1806 .hw.init = &(struct clk_init_data){
1804 .name = "gcc_pcie_1_pipe_clk", 1807 .name = "gcc_pcie_1_pipe_clk",
1808 .parent_names = (const char *[]){ "pcie_1_pipe_clk" },
1809 .num_parents = 1,
1805 .ops = &clk_branch2_ops, 1810 .ops = &clk_branch2_ops,
1806 }, 1811 },
1807 }, 1812 },
diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c
index 7d4ee109435c..7235510eac94 100644
--- a/drivers/clk/qcom/mmcc-msm8996.c
+++ b/drivers/clk/qcom/mmcc-msm8996.c
@@ -3347,6 +3347,8 @@ static const struct qcom_cc_desc mmcc_msm8996_desc = {
3347 .num_resets = ARRAY_SIZE(mmcc_msm8996_resets), 3347 .num_resets = ARRAY_SIZE(mmcc_msm8996_resets),
3348 .gdscs = mmcc_msm8996_gdscs, 3348 .gdscs = mmcc_msm8996_gdscs,
3349 .num_gdscs = ARRAY_SIZE(mmcc_msm8996_gdscs), 3349 .num_gdscs = ARRAY_SIZE(mmcc_msm8996_gdscs),
3350 .clk_hws = mmcc_msm8996_hws,
3351 .num_clk_hws = ARRAY_SIZE(mmcc_msm8996_hws),
3350}; 3352};
3351 3353
3352static const struct of_device_id mmcc_msm8996_match_table[] = { 3354static const struct of_device_id mmcc_msm8996_match_table[] = {
@@ -3357,8 +3359,6 @@ MODULE_DEVICE_TABLE(of, mmcc_msm8996_match_table);
3357 3359
3358static int mmcc_msm8996_probe(struct platform_device *pdev) 3360static int mmcc_msm8996_probe(struct platform_device *pdev)
3359{ 3361{
3360 struct device *dev = &pdev->dev;
3361 int i, ret;
3362 struct regmap *regmap; 3362 struct regmap *regmap;
3363 3363
3364 regmap = qcom_cc_map(pdev, &mmcc_msm8996_desc); 3364 regmap = qcom_cc_map(pdev, &mmcc_msm8996_desc);
@@ -3370,12 +3370,6 @@ static int mmcc_msm8996_probe(struct platform_device *pdev)
3370 /* Disable the NoC FSM for mmss_mmagic_cfg_ahb_clk */ 3370 /* Disable the NoC FSM for mmss_mmagic_cfg_ahb_clk */
3371 regmap_update_bits(regmap, 0x5054, BIT(15), 0); 3371 regmap_update_bits(regmap, 0x5054, BIT(15), 0);
3372 3372
3373 for (i = 0; i < ARRAY_SIZE(mmcc_msm8996_hws); i++) {
3374 ret = devm_clk_hw_register(dev, mmcc_msm8996_hws[i]);
3375 if (ret)
3376 return ret;
3377 }
3378
3379 return qcom_cc_really_probe(pdev, &mmcc_msm8996_desc, regmap); 3373 return qcom_cc_really_probe(pdev, &mmcc_msm8996_desc, regmap);
3380} 3374}
3381 3375
diff --git a/drivers/clk/renesas/r8a774a1-cpg-mssr.c b/drivers/clk/renesas/r8a774a1-cpg-mssr.c
index 10e852518870..4d92b27a6153 100644
--- a/drivers/clk/renesas/r8a774a1-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a774a1-cpg-mssr.c
@@ -21,7 +21,7 @@
21 21
22enum clk_ids { 22enum clk_ids {
23 /* Core Clock Outputs exported to DT */ 23 /* Core Clock Outputs exported to DT */
24 LAST_DT_CORE_CLK = R8A774A1_CLK_OSC, 24 LAST_DT_CORE_CLK = R8A774A1_CLK_CANFD,
25 25
26 /* External Input Clocks */ 26 /* External Input Clocks */
27 CLK_EXTAL, 27 CLK_EXTAL,
@@ -102,6 +102,7 @@ static const struct cpg_core_clk r8a774a1_core_clks[] __initconst = {
102 DEF_FIXED("cp", R8A774A1_CLK_CP, CLK_EXTAL, 2, 1), 102 DEF_FIXED("cp", R8A774A1_CLK_CP, CLK_EXTAL, 2, 1),
103 DEF_FIXED("cpex", R8A774A1_CLK_CPEX, CLK_EXTAL, 2, 1), 103 DEF_FIXED("cpex", R8A774A1_CLK_CPEX, CLK_EXTAL, 2, 1),
104 104
105 DEF_DIV6P1("canfd", R8A774A1_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
105 DEF_DIV6P1("csi0", R8A774A1_CLK_CSI0, CLK_PLL1_DIV4, 0x00c), 106 DEF_DIV6P1("csi0", R8A774A1_CLK_CSI0, CLK_PLL1_DIV4, 0x00c),
106 DEF_DIV6P1("mso", R8A774A1_CLK_MSO, CLK_PLL1_DIV4, 0x014), 107 DEF_DIV6P1("mso", R8A774A1_CLK_MSO, CLK_PLL1_DIV4, 0x014),
107 DEF_DIV6P1("hdmi", R8A774A1_CLK_HDMI, CLK_PLL1_DIV4, 0x250), 108 DEF_DIV6P1("hdmi", R8A774A1_CLK_HDMI, CLK_PLL1_DIV4, 0x250),
@@ -191,6 +192,7 @@ static const struct mssr_mod_clk r8a774a1_mod_clks[] __initconst = {
191 DEF_MOD("gpio2", 910, R8A774A1_CLK_S3D4), 192 DEF_MOD("gpio2", 910, R8A774A1_CLK_S3D4),
192 DEF_MOD("gpio1", 911, R8A774A1_CLK_S3D4), 193 DEF_MOD("gpio1", 911, R8A774A1_CLK_S3D4),
193 DEF_MOD("gpio0", 912, R8A774A1_CLK_S3D4), 194 DEF_MOD("gpio0", 912, R8A774A1_CLK_S3D4),
195 DEF_MOD("can-fd", 914, R8A774A1_CLK_S3D2),
194 DEF_MOD("can-if1", 915, R8A774A1_CLK_S3D4), 196 DEF_MOD("can-if1", 915, R8A774A1_CLK_S3D4),
195 DEF_MOD("can-if0", 916, R8A774A1_CLK_S3D4), 197 DEF_MOD("can-if0", 916, R8A774A1_CLK_S3D4),
196 DEF_MOD("i2c6", 918, R8A774A1_CLK_S0D6), 198 DEF_MOD("i2c6", 918, R8A774A1_CLK_S0D6),
diff --git a/drivers/clk/renesas/r8a774c0-cpg-mssr.c b/drivers/clk/renesas/r8a774c0-cpg-mssr.c
index 10b96895d452..34e274f2a273 100644
--- a/drivers/clk/renesas/r8a774c0-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a774c0-cpg-mssr.c
@@ -22,7 +22,7 @@
22 22
23enum clk_ids { 23enum clk_ids {
24 /* Core Clock Outputs exported to DT */ 24 /* Core Clock Outputs exported to DT */
25 LAST_DT_CORE_CLK = R8A774C0_CLK_CPEX, 25 LAST_DT_CORE_CLK = R8A774C0_CLK_CANFD,
26 26
27 /* External Input Clocks */ 27 /* External Input Clocks */
28 CLK_EXTAL, 28 CLK_EXTAL,
@@ -33,6 +33,7 @@ enum clk_ids {
33 CLK_PLL1, 33 CLK_PLL1,
34 CLK_PLL3, 34 CLK_PLL3,
35 CLK_PLL0D4, 35 CLK_PLL0D4,
36 CLK_PLL0D6,
36 CLK_PLL0D8, 37 CLK_PLL0D8,
37 CLK_PLL0D20, 38 CLK_PLL0D20,
38 CLK_PLL0D24, 39 CLK_PLL0D24,
@@ -61,6 +62,7 @@ static const struct cpg_core_clk r8a774c0_core_clks[] __initconst = {
61 62
62 DEF_FIXED(".pll0", CLK_PLL0, CLK_MAIN, 1, 100), 63 DEF_FIXED(".pll0", CLK_PLL0, CLK_MAIN, 1, 100),
63 DEF_FIXED(".pll0d4", CLK_PLL0D4, CLK_PLL0, 4, 1), 64 DEF_FIXED(".pll0d4", CLK_PLL0D4, CLK_PLL0, 4, 1),
65 DEF_FIXED(".pll0d6", CLK_PLL0D6, CLK_PLL0, 6, 1),
64 DEF_FIXED(".pll0d8", CLK_PLL0D8, CLK_PLL0, 8, 1), 66 DEF_FIXED(".pll0d8", CLK_PLL0D8, CLK_PLL0, 8, 1),
65 DEF_FIXED(".pll0d20", CLK_PLL0D20, CLK_PLL0, 20, 1), 67 DEF_FIXED(".pll0d20", CLK_PLL0D20, CLK_PLL0, 20, 1),
66 DEF_FIXED(".pll0d24", CLK_PLL0D24, CLK_PLL0, 24, 1), 68 DEF_FIXED(".pll0d24", CLK_PLL0D24, CLK_PLL0, 24, 1),
@@ -112,6 +114,7 @@ static const struct cpg_core_clk r8a774c0_core_clks[] __initconst = {
112 DEF_GEN3_PE("s3d2c", R8A774C0_CLK_S3D2C, CLK_S3, 2, CLK_PE, 2), 114 DEF_GEN3_PE("s3d2c", R8A774C0_CLK_S3D2C, CLK_S3, 2, CLK_PE, 2),
113 DEF_GEN3_PE("s3d4c", R8A774C0_CLK_S3D4C, CLK_S3, 4, CLK_PE, 4), 115 DEF_GEN3_PE("s3d4c", R8A774C0_CLK_S3D4C, CLK_S3, 4, CLK_PE, 4),
114 116
117 DEF_DIV6P1("canfd", R8A774C0_CLK_CANFD, CLK_PLL0D6, 0x244),
115 DEF_DIV6P1("csi0", R8A774C0_CLK_CSI0, CLK_PLL1D2, 0x00c), 118 DEF_DIV6P1("csi0", R8A774C0_CLK_CSI0, CLK_PLL1D2, 0x00c),
116 DEF_DIV6P1("mso", R8A774C0_CLK_MSO, CLK_PLL1D2, 0x014), 119 DEF_DIV6P1("mso", R8A774C0_CLK_MSO, CLK_PLL1D2, 0x014),
117 120
@@ -119,6 +122,11 @@ static const struct cpg_core_clk r8a774c0_core_clks[] __initconst = {
119}; 122};
120 123
121static const struct mssr_mod_clk r8a774c0_mod_clks[] __initconst = { 124static const struct mssr_mod_clk r8a774c0_mod_clks[] __initconst = {
125 DEF_MOD("tmu4", 121, R8A774C0_CLK_S0D6C),
126 DEF_MOD("tmu3", 122, R8A774C0_CLK_S3D2C),
127 DEF_MOD("tmu2", 123, R8A774C0_CLK_S3D2C),
128 DEF_MOD("tmu1", 124, R8A774C0_CLK_S3D2C),
129 DEF_MOD("tmu0", 125, R8A774C0_CLK_CP),
122 DEF_MOD("scif5", 202, R8A774C0_CLK_S3D4C), 130 DEF_MOD("scif5", 202, R8A774C0_CLK_S3D4C),
123 DEF_MOD("scif4", 203, R8A774C0_CLK_S3D4C), 131 DEF_MOD("scif4", 203, R8A774C0_CLK_S3D4C),
124 DEF_MOD("scif3", 204, R8A774C0_CLK_S3D4C), 132 DEF_MOD("scif3", 204, R8A774C0_CLK_S3D4C),
@@ -172,8 +180,8 @@ static const struct mssr_mod_clk r8a774c0_mod_clks[] __initconst = {
172 DEF_MOD("ehci0", 703, R8A774C0_CLK_S3D4), 180 DEF_MOD("ehci0", 703, R8A774C0_CLK_S3D4),
173 DEF_MOD("hsusb", 704, R8A774C0_CLK_S3D4), 181 DEF_MOD("hsusb", 704, R8A774C0_CLK_S3D4),
174 DEF_MOD("csi40", 716, R8A774C0_CLK_CSI0), 182 DEF_MOD("csi40", 716, R8A774C0_CLK_CSI0),
175 DEF_MOD("du1", 723, R8A774C0_CLK_S2D1), 183 DEF_MOD("du1", 723, R8A774C0_CLK_S1D1),
176 DEF_MOD("du0", 724, R8A774C0_CLK_S2D1), 184 DEF_MOD("du0", 724, R8A774C0_CLK_S1D1),
177 DEF_MOD("lvds", 727, R8A774C0_CLK_S2D1), 185 DEF_MOD("lvds", 727, R8A774C0_CLK_S2D1),
178 186
179 DEF_MOD("vin5", 806, R8A774C0_CLK_S1D2), 187 DEF_MOD("vin5", 806, R8A774C0_CLK_S1D2),
@@ -187,6 +195,7 @@ static const struct mssr_mod_clk r8a774c0_mod_clks[] __initconst = {
187 DEF_MOD("gpio2", 910, R8A774C0_CLK_S3D4), 195 DEF_MOD("gpio2", 910, R8A774C0_CLK_S3D4),
188 DEF_MOD("gpio1", 911, R8A774C0_CLK_S3D4), 196 DEF_MOD("gpio1", 911, R8A774C0_CLK_S3D4),
189 DEF_MOD("gpio0", 912, R8A774C0_CLK_S3D4), 197 DEF_MOD("gpio0", 912, R8A774C0_CLK_S3D4),
198 DEF_MOD("can-fd", 914, R8A774C0_CLK_S3D2),
190 DEF_MOD("can-if1", 915, R8A774C0_CLK_S3D4), 199 DEF_MOD("can-if1", 915, R8A774C0_CLK_S3D4),
191 DEF_MOD("can-if0", 916, R8A774C0_CLK_S3D4), 200 DEF_MOD("can-if0", 916, R8A774C0_CLK_S3D4),
192 DEF_MOD("i2c6", 918, R8A774C0_CLK_S3D2), 201 DEF_MOD("i2c6", 918, R8A774C0_CLK_S3D2),
diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c
index 25a3083b6764..f9e07fcc0d96 100644
--- a/drivers/clk/renesas/r8a77980-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c
@@ -41,6 +41,7 @@ enum clk_ids {
41 CLK_S2, 41 CLK_S2,
42 CLK_S3, 42 CLK_S3,
43 CLK_SDSRC, 43 CLK_SDSRC,
44 CLK_RPCSRC,
44 CLK_OCO, 45 CLK_OCO,
45 46
46 /* Module Clocks */ 47 /* Module Clocks */
@@ -65,8 +66,14 @@ static const struct cpg_core_clk r8a77980_core_clks[] __initconst = {
65 DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), 66 DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1),
66 DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), 67 DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1),
67 DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), 68 DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1),
69 DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1),
68 DEF_RATE(".oco", CLK_OCO, 32768), 70 DEF_RATE(".oco", CLK_OCO, 32768),
69 71
72 DEF_BASE("rpc", R8A77980_CLK_RPC, CLK_TYPE_GEN3_RPC,
73 CLK_RPCSRC),
74 DEF_BASE("rpcd2", R8A77980_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2,
75 R8A77980_CLK_RPC),
76
70 /* Core Clock Outputs */ 77 /* Core Clock Outputs */
71 DEF_FIXED("ztr", R8A77980_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), 78 DEF_FIXED("ztr", R8A77980_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
72 DEF_FIXED("ztrd2", R8A77980_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), 79 DEF_FIXED("ztrd2", R8A77980_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
@@ -164,6 +171,7 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
164 DEF_MOD("gpio1", 911, R8A77980_CLK_CP), 171 DEF_MOD("gpio1", 911, R8A77980_CLK_CP),
165 DEF_MOD("gpio0", 912, R8A77980_CLK_CP), 172 DEF_MOD("gpio0", 912, R8A77980_CLK_CP),
166 DEF_MOD("can-fd", 914, R8A77980_CLK_S3D2), 173 DEF_MOD("can-fd", 914, R8A77980_CLK_S3D2),
174 DEF_MOD("rpc-if", 917, R8A77980_CLK_RPC),
167 DEF_MOD("i2c4", 927, R8A77980_CLK_S0D6), 175 DEF_MOD("i2c4", 927, R8A77980_CLK_S0D6),
168 DEF_MOD("i2c3", 928, R8A77980_CLK_S0D6), 176 DEF_MOD("i2c3", 928, R8A77980_CLK_S0D6),
169 DEF_MOD("i2c2", 929, R8A77980_CLK_S3D2), 177 DEF_MOD("i2c2", 929, R8A77980_CLK_S3D2),
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
index be2ccbd6d623..9a8071a8114d 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.c
+++ b/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -30,6 +30,21 @@
30 30
31#define CPG_RCKCR_CKSEL BIT(15) /* RCLK Clock Source Select */ 31#define CPG_RCKCR_CKSEL BIT(15) /* RCLK Clock Source Select */
32 32
33static spinlock_t cpg_lock;
34
35static void cpg_reg_modify(void __iomem *reg, u32 clear, u32 set)
36{
37 unsigned long flags;
38 u32 val;
39
40 spin_lock_irqsave(&cpg_lock, flags);
41 val = readl(reg);
42 val &= ~clear;
43 val |= set;
44 writel(val, reg);
45 spin_unlock_irqrestore(&cpg_lock, flags);
46};
47
33struct cpg_simple_notifier { 48struct cpg_simple_notifier {
34 struct notifier_block nb; 49 struct notifier_block nb;
35 void __iomem *reg; 50 void __iomem *reg;
@@ -118,7 +133,6 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
118 struct cpg_z_clk *zclk = to_z_clk(hw); 133 struct cpg_z_clk *zclk = to_z_clk(hw);
119 unsigned int mult; 134 unsigned int mult;
120 unsigned int i; 135 unsigned int i;
121 u32 val, kick;
122 136
123 /* Factor of 2 is for fixed divider */ 137 /* Factor of 2 is for fixed divider */
124 mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL * 2, parent_rate); 138 mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL * 2, parent_rate);
@@ -127,17 +141,14 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
127 if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK) 141 if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK)
128 return -EBUSY; 142 return -EBUSY;
129 143
130 val = readl(zclk->reg) & ~zclk->mask; 144 cpg_reg_modify(zclk->reg, zclk->mask,
131 val |= ((32 - mult) << __ffs(zclk->mask)) & zclk->mask; 145 ((32 - mult) << __ffs(zclk->mask)) & zclk->mask);
132 writel(val, zclk->reg);
133 146
134 /* 147 /*
135 * Set KICK bit in FRQCRB to update hardware setting and wait for 148 * Set KICK bit in FRQCRB to update hardware setting and wait for
136 * clock change completion. 149 * clock change completion.
137 */ 150 */
138 kick = readl(zclk->kick_reg); 151 cpg_reg_modify(zclk->kick_reg, 0, CPG_FRQCRB_KICK);
139 kick |= CPG_FRQCRB_KICK;
140 writel(kick, zclk->kick_reg);
141 152
142 /* 153 /*
143 * Note: There is no HW information about the worst case latency. 154 * Note: There is no HW information about the worst case latency.
@@ -266,12 +277,10 @@ static const struct sd_div_table cpg_sd_div_table[] = {
266static int cpg_sd_clock_enable(struct clk_hw *hw) 277static int cpg_sd_clock_enable(struct clk_hw *hw)
267{ 278{
268 struct sd_clock *clock = to_sd_clock(hw); 279 struct sd_clock *clock = to_sd_clock(hw);
269 u32 val = readl(clock->csn.reg);
270
271 val &= ~(CPG_SD_STP_MASK);
272 val |= clock->div_table[clock->cur_div_idx].val & CPG_SD_STP_MASK;
273 280
274 writel(val, clock->csn.reg); 281 cpg_reg_modify(clock->csn.reg, CPG_SD_STP_MASK,
282 clock->div_table[clock->cur_div_idx].val &
283 CPG_SD_STP_MASK);
275 284
276 return 0; 285 return 0;
277} 286}
@@ -280,7 +289,7 @@ static void cpg_sd_clock_disable(struct clk_hw *hw)
280{ 289{
281 struct sd_clock *clock = to_sd_clock(hw); 290 struct sd_clock *clock = to_sd_clock(hw);
282 291
283 writel(readl(clock->csn.reg) | CPG_SD_STP_MASK, clock->csn.reg); 292 cpg_reg_modify(clock->csn.reg, 0, CPG_SD_STP_MASK);
284} 293}
285 294
286static int cpg_sd_clock_is_enabled(struct clk_hw *hw) 295static int cpg_sd_clock_is_enabled(struct clk_hw *hw)
@@ -327,7 +336,6 @@ static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate,
327{ 336{
328 struct sd_clock *clock = to_sd_clock(hw); 337 struct sd_clock *clock = to_sd_clock(hw);
329 unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate); 338 unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate);
330 u32 val;
331 unsigned int i; 339 unsigned int i;
332 340
333 for (i = 0; i < clock->div_num; i++) 341 for (i = 0; i < clock->div_num; i++)
@@ -339,10 +347,9 @@ static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate,
339 347
340 clock->cur_div_idx = i; 348 clock->cur_div_idx = i;
341 349
342 val = readl(clock->csn.reg); 350 cpg_reg_modify(clock->csn.reg, CPG_SD_STP_MASK | CPG_SD_FC_MASK,
343 val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK); 351 clock->div_table[i].val &
344 val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK); 352 (CPG_SD_STP_MASK | CPG_SD_FC_MASK));
345 writel(val, clock->csn.reg);
346 353
347 return 0; 354 return 0;
348} 355}
@@ -415,6 +422,92 @@ free_clock:
415 return clk; 422 return clk;
416} 423}
417 424
425struct rpc_clock {
426 struct clk_divider div;
427 struct clk_gate gate;
428 /*
429 * One notifier covers both RPC and RPCD2 clocks as they are both
430 * controlled by the same RPCCKCR register...
431 */
432 struct cpg_simple_notifier csn;
433};
434
435static const struct clk_div_table cpg_rpcsrc_div_table[] = {
436 { 2, 5 }, { 3, 6 }, { 0, 0 },
437};
438
439static const struct clk_div_table cpg_rpc_div_table[] = {
440 { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 }, { 0, 0 },
441};
442
443static struct clk * __init cpg_rpc_clk_register(const char *name,
444 void __iomem *base, const char *parent_name,
445 struct raw_notifier_head *notifiers)
446{
447 struct rpc_clock *rpc;
448 struct clk *clk;
449
450 rpc = kzalloc(sizeof(*rpc), GFP_KERNEL);
451 if (!rpc)
452 return ERR_PTR(-ENOMEM);
453
454 rpc->div.reg = base + CPG_RPCCKCR;
455 rpc->div.width = 3;
456 rpc->div.table = cpg_rpc_div_table;
457 rpc->div.lock = &cpg_lock;
458
459 rpc->gate.reg = base + CPG_RPCCKCR;
460 rpc->gate.bit_idx = 8;
461 rpc->gate.flags = CLK_GATE_SET_TO_DISABLE;
462 rpc->gate.lock = &cpg_lock;
463
464 rpc->csn.reg = base + CPG_RPCCKCR;
465
466 clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
467 &rpc->div.hw, &clk_divider_ops,
468 &rpc->gate.hw, &clk_gate_ops, 0);
469 if (IS_ERR(clk)) {
470 kfree(rpc);
471 return clk;
472 }
473
474 cpg_simple_notifier_register(notifiers, &rpc->csn);
475 return clk;
476}
477
478struct rpcd2_clock {
479 struct clk_fixed_factor fixed;
480 struct clk_gate gate;
481};
482
483static struct clk * __init cpg_rpcd2_clk_register(const char *name,
484 void __iomem *base,
485 const char *parent_name)
486{
487 struct rpcd2_clock *rpcd2;
488 struct clk *clk;
489
490 rpcd2 = kzalloc(sizeof(*rpcd2), GFP_KERNEL);
491 if (!rpcd2)
492 return ERR_PTR(-ENOMEM);
493
494 rpcd2->fixed.mult = 1;
495 rpcd2->fixed.div = 2;
496
497 rpcd2->gate.reg = base + CPG_RPCCKCR;
498 rpcd2->gate.bit_idx = 9;
499 rpcd2->gate.flags = CLK_GATE_SET_TO_DISABLE;
500 rpcd2->gate.lock = &cpg_lock;
501
502 clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
503 &rpcd2->fixed.hw, &clk_fixed_factor_ops,
504 &rpcd2->gate.hw, &clk_gate_ops, 0);
505 if (IS_ERR(clk))
506 kfree(rpcd2);
507
508 return clk;
509}
510
418 511
419static const struct rcar_gen3_cpg_pll_config *cpg_pll_config __initdata; 512static const struct rcar_gen3_cpg_pll_config *cpg_pll_config __initdata;
420static unsigned int cpg_clk_extalr __initdata; 513static unsigned int cpg_clk_extalr __initdata;
@@ -593,6 +686,21 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
593 } 686 }
594 break; 687 break;
595 688
689 case CLK_TYPE_GEN3_RPCSRC:
690 return clk_register_divider_table(NULL, core->name,
691 __clk_get_name(parent), 0,
692 base + CPG_RPCCKCR, 3, 2, 0,
693 cpg_rpcsrc_div_table,
694 &cpg_lock);
695
696 case CLK_TYPE_GEN3_RPC:
697 return cpg_rpc_clk_register(core->name, base,
698 __clk_get_name(parent), notifiers);
699
700 case CLK_TYPE_GEN3_RPCD2:
701 return cpg_rpcd2_clk_register(core->name, base,
702 __clk_get_name(parent));
703
596 default: 704 default:
597 return ERR_PTR(-EINVAL); 705 return ERR_PTR(-EINVAL);
598 } 706 }
@@ -613,5 +721,8 @@ int __init rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config,
613 if (attr) 721 if (attr)
614 cpg_quirks = (uintptr_t)attr->data; 722 cpg_quirks = (uintptr_t)attr->data;
615 pr_debug("%s: mode = 0x%x quirks = 0x%x\n", __func__, mode, cpg_quirks); 723 pr_debug("%s: mode = 0x%x quirks = 0x%x\n", __func__, mode, cpg_quirks);
724
725 spin_lock_init(&cpg_lock);
726
616 return 0; 727 return 0;
617} 728}
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h
index f4fb6cf16688..eac1b057455a 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.h
+++ b/drivers/clk/renesas/rcar-gen3-cpg.h
@@ -23,6 +23,9 @@ enum rcar_gen3_clk_types {
23 CLK_TYPE_GEN3_Z2, 23 CLK_TYPE_GEN3_Z2,
24 CLK_TYPE_GEN3_OSC, /* OSC EXTAL predivider and fixed divider */ 24 CLK_TYPE_GEN3_OSC, /* OSC EXTAL predivider and fixed divider */
25 CLK_TYPE_GEN3_RCKSEL, /* Select parent/divider using RCKCR.CKSEL */ 25 CLK_TYPE_GEN3_RCKSEL, /* Select parent/divider using RCKCR.CKSEL */
26 CLK_TYPE_GEN3_RPCSRC,
27 CLK_TYPE_GEN3_RPC,
28 CLK_TYPE_GEN3_RPCD2,
26 29
27 /* SoC specific definitions start here */ 30 /* SoC specific definitions start here */
28 CLK_TYPE_GEN3_SOC_BASE, 31 CLK_TYPE_GEN3_SOC_BASE,
@@ -57,6 +60,7 @@ struct rcar_gen3_cpg_pll_config {
57 u8 osc_prediv; 60 u8 osc_prediv;
58}; 61};
59 62
63#define CPG_RPCCKCR 0x238
60#define CPG_RCKCR 0x240 64#define CPG_RCKCR 0x240
61 65
62struct clk *rcar_gen3_cpg_clk_register(struct device *dev, 66struct clk *rcar_gen3_cpg_clk_register(struct device *dev,
diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index 7ea20341e870..5ecf28854876 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -586,12 +586,12 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
586 COMPOSITE(0, "dclk_lcdc0_src", mux_pll_src_cpll_gpll_p, 0, 586 COMPOSITE(0, "dclk_lcdc0_src", mux_pll_src_cpll_gpll_p, 0,
587 RK2928_CLKSEL_CON(27), 0, 1, MFLAGS, 8, 8, DFLAGS, 587 RK2928_CLKSEL_CON(27), 0, 1, MFLAGS, 8, 8, DFLAGS,
588 RK2928_CLKGATE_CON(3), 1, GFLAGS), 588 RK2928_CLKGATE_CON(3), 1, GFLAGS),
589 MUX(DCLK_LCDC0, "dclk_lcdc0", mux_rk3066_lcdc0_p, 0, 589 MUX(DCLK_LCDC0, "dclk_lcdc0", mux_rk3066_lcdc0_p, CLK_SET_RATE_PARENT,
590 RK2928_CLKSEL_CON(27), 4, 1, MFLAGS), 590 RK2928_CLKSEL_CON(27), 4, 1, MFLAGS),
591 COMPOSITE(0, "dclk_lcdc1_src", mux_pll_src_cpll_gpll_p, 0, 591 COMPOSITE(0, "dclk_lcdc1_src", mux_pll_src_cpll_gpll_p, 0,
592 RK2928_CLKSEL_CON(28), 0, 1, MFLAGS, 8, 8, DFLAGS, 592 RK2928_CLKSEL_CON(28), 0, 1, MFLAGS, 8, 8, DFLAGS,
593 RK2928_CLKGATE_CON(3), 2, GFLAGS), 593 RK2928_CLKGATE_CON(3), 2, GFLAGS),
594 MUX(DCLK_LCDC1, "dclk_lcdc1", mux_rk3066_lcdc1_p, 0, 594 MUX(DCLK_LCDC1, "dclk_lcdc1", mux_rk3066_lcdc1_p, CLK_SET_RATE_PARENT,
595 RK2928_CLKSEL_CON(28), 4, 1, MFLAGS), 595 RK2928_CLKSEL_CON(28), 4, 1, MFLAGS),
596 596
597 COMPOSITE_NOMUX(0, "cif1_pre", "cif_src", 0, 597 COMPOSITE_NOMUX(0, "cif1_pre", "cif_src", 0,
diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c
index faa94adb2a37..65ab5c2f48b0 100644
--- a/drivers/clk/rockchip/clk-rk3328.c
+++ b/drivers/clk/rockchip/clk-rk3328.c
@@ -78,17 +78,17 @@ static struct rockchip_pll_rate_table rk3328_pll_rates[] = {
78 78
79static struct rockchip_pll_rate_table rk3328_pll_frac_rates[] = { 79static struct rockchip_pll_rate_table rk3328_pll_frac_rates[] = {
80 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ 80 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
81 RK3036_PLL_RATE(1016064000, 3, 127, 1, 1, 0, 134217), 81 RK3036_PLL_RATE(1016064000, 3, 127, 1, 1, 0, 134218),
82 /* vco = 1016064000 */ 82 /* vco = 1016064000 */
83 RK3036_PLL_RATE(983040000, 24, 983, 1, 1, 0, 671088), 83 RK3036_PLL_RATE(983040000, 24, 983, 1, 1, 0, 671089),
84 /* vco = 983040000 */ 84 /* vco = 983040000 */
85 RK3036_PLL_RATE(491520000, 24, 983, 2, 1, 0, 671088), 85 RK3036_PLL_RATE(491520000, 24, 983, 2, 1, 0, 671089),
86 /* vco = 983040000 */ 86 /* vco = 983040000 */
87 RK3036_PLL_RATE(61440000, 6, 215, 7, 2, 0, 671088), 87 RK3036_PLL_RATE(61440000, 6, 215, 7, 2, 0, 671089),
88 /* vco = 860156000 */ 88 /* vco = 860156000 */
89 RK3036_PLL_RATE(56448000, 12, 451, 4, 4, 0, 9797894), 89 RK3036_PLL_RATE(56448000, 12, 451, 4, 4, 0, 9797895),
90 /* vco = 903168000 */ 90 /* vco = 903168000 */
91 RK3036_PLL_RATE(40960000, 12, 409, 4, 5, 0, 10066329), 91 RK3036_PLL_RATE(40960000, 12, 409, 4, 5, 0, 10066330),
92 /* vco = 819200000 */ 92 /* vco = 819200000 */
93 { /* sentinel */ }, 93 { /* sentinel */ },
94}; 94};
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index 59d4d46667ce..54066e6508d3 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -1028,6 +1028,7 @@ static unsigned long __init exynos4_get_xom(void)
1028 xom = readl(chipid_base + 8); 1028 xom = readl(chipid_base + 8);
1029 1029
1030 iounmap(chipid_base); 1030 iounmap(chipid_base);
1031 of_node_put(np);
1031 } 1032 }
1032 1033
1033 return xom; 1034 return xom;
diff --git a/drivers/clk/samsung/clk-exynos5-subcmu.c b/drivers/clk/samsung/clk-exynos5-subcmu.c
index 93306283d764..8ae44b5db4c2 100644
--- a/drivers/clk/samsung/clk-exynos5-subcmu.c
+++ b/drivers/clk/samsung/clk-exynos5-subcmu.c
@@ -136,15 +136,20 @@ static int __init exynos5_clk_register_subcmu(struct device *parent,
136{ 136{
137 struct of_phandle_args genpdspec = { .np = pd_node }; 137 struct of_phandle_args genpdspec = { .np = pd_node };
138 struct platform_device *pdev; 138 struct platform_device *pdev;
139 int ret;
140
141 pdev = platform_device_alloc("exynos5-subcmu", PLATFORM_DEVID_AUTO);
142 if (!pdev)
143 return -ENOMEM;
139 144
140 pdev = platform_device_alloc(info->pd_name, -1);
141 pdev->dev.parent = parent; 145 pdev->dev.parent = parent;
142 pdev->driver_override = "exynos5-subcmu";
143 platform_set_drvdata(pdev, (void *)info); 146 platform_set_drvdata(pdev, (void *)info);
144 of_genpd_add_device(&genpdspec, &pdev->dev); 147 of_genpd_add_device(&genpdspec, &pdev->dev);
145 platform_device_add(pdev); 148 ret = platform_device_add(pdev);
149 if (ret)
150 platform_device_put(pdev);
146 151
147 return 0; 152 return ret;
148} 153}
149 154
150static int __init exynos5_clk_probe(struct platform_device *pdev) 155static int __init exynos5_clk_probe(struct platform_device *pdev)
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index 751e2c4fb65b..dae1c96de933 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -559,7 +559,7 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
559 /* ENABLE_ACLK_TOP */ 559 /* ENABLE_ACLK_TOP */
560 GATE(CLK_ACLK_G3D_400, "aclk_g3d_400", "div_aclk_g3d_400", 560 GATE(CLK_ACLK_G3D_400, "aclk_g3d_400", "div_aclk_g3d_400",
561 ENABLE_ACLK_TOP, 30, CLK_IS_CRITICAL, 0), 561 ENABLE_ACLK_TOP, 30, CLK_IS_CRITICAL, 0),
562 GATE(CLK_ACLK_IMEM_SSX_266, "aclk_imem_ssx_266", 562 GATE(CLK_ACLK_IMEM_SSSX_266, "aclk_imem_sssx_266",
563 "div_aclk_imem_sssx_266", ENABLE_ACLK_TOP, 563 "div_aclk_imem_sssx_266", ENABLE_ACLK_TOP,
564 29, CLK_IGNORE_UNUSED, 0), 564 29, CLK_IGNORE_UNUSED, 0),
565 GATE(CLK_ACLK_BUS0_400, "aclk_bus0_400", "div_aclk_bus0_400", 565 GATE(CLK_ACLK_BUS0_400, "aclk_bus0_400", "div_aclk_bus0_400",
@@ -568,10 +568,10 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
568 GATE(CLK_ACLK_BUS1_400, "aclk_bus1_400", "div_aclk_bus1_400", 568 GATE(CLK_ACLK_BUS1_400, "aclk_bus1_400", "div_aclk_bus1_400",
569 ENABLE_ACLK_TOP, 25, 569 ENABLE_ACLK_TOP, 25,
570 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), 570 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
571 GATE(CLK_ACLK_IMEM_200, "aclk_imem_200", "div_aclk_imem_266", 571 GATE(CLK_ACLK_IMEM_200, "aclk_imem_200", "div_aclk_imem_200",
572 ENABLE_ACLK_TOP, 24, 572 ENABLE_ACLK_TOP, 24,
573 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), 573 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
574 GATE(CLK_ACLK_IMEM_266, "aclk_imem_266", "div_aclk_imem_200", 574 GATE(CLK_ACLK_IMEM_266, "aclk_imem_266", "div_aclk_imem_266",
575 ENABLE_ACLK_TOP, 23, 575 ENABLE_ACLK_TOP, 23,
576 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), 576 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0),
577 GATE(CLK_ACLK_PERIC_66, "aclk_peric_66", "div_aclk_peric_66_b", 577 GATE(CLK_ACLK_PERIC_66, "aclk_peric_66", "div_aclk_peric_66_b",
@@ -5467,6 +5467,35 @@ static const struct samsung_cmu_info cam1_cmu_info __initconst = {
5467 .clk_name = "aclk_cam1_400", 5467 .clk_name = "aclk_cam1_400",
5468}; 5468};
5469 5469
5470/*
5471 * Register offset definitions for CMU_IMEM
5472 */
5473#define ENABLE_ACLK_IMEM_SLIMSSS 0x080c
5474#define ENABLE_PCLK_IMEM_SLIMSSS 0x0908
5475
5476static const unsigned long imem_clk_regs[] __initconst = {
5477 ENABLE_ACLK_IMEM_SLIMSSS,
5478 ENABLE_PCLK_IMEM_SLIMSSS,
5479};
5480
5481static const struct samsung_gate_clock imem_gate_clks[] __initconst = {
5482 /* ENABLE_ACLK_IMEM_SLIMSSS */
5483 GATE(CLK_ACLK_SLIMSSS, "aclk_slimsss", "aclk_imem_sssx_266",
5484 ENABLE_ACLK_IMEM_SLIMSSS, 0, CLK_IGNORE_UNUSED, 0),
5485
5486 /* ENABLE_PCLK_IMEM_SLIMSSS */
5487 GATE(CLK_PCLK_SLIMSSS, "pclk_slimsss", "aclk_imem_200",
5488 ENABLE_PCLK_IMEM_SLIMSSS, 0, CLK_IGNORE_UNUSED, 0),
5489};
5490
5491static const struct samsung_cmu_info imem_cmu_info __initconst = {
5492 .gate_clks = imem_gate_clks,
5493 .nr_gate_clks = ARRAY_SIZE(imem_gate_clks),
5494 .nr_clk_ids = IMEM_NR_CLK,
5495 .clk_regs = imem_clk_regs,
5496 .nr_clk_regs = ARRAY_SIZE(imem_clk_regs),
5497 .clk_name = "aclk_imem_200",
5498};
5470 5499
5471struct exynos5433_cmu_data { 5500struct exynos5433_cmu_data {
5472 struct samsung_clk_reg_dump *clk_save; 5501 struct samsung_clk_reg_dump *clk_save;
@@ -5655,6 +5684,9 @@ static const struct of_device_id exynos5433_cmu_of_match[] = {
5655 .compatible = "samsung,exynos5433-cmu-mscl", 5684 .compatible = "samsung,exynos5433-cmu-mscl",
5656 .data = &mscl_cmu_info, 5685 .data = &mscl_cmu_info,
5657 }, { 5686 }, {
5687 .compatible = "samsung,exynos5433-cmu-imem",
5688 .data = &imem_cmu_info,
5689 }, {
5658 }, 5690 },
5659}; 5691};
5660 5692
diff --git a/drivers/clk/samsung/clk-s3c2443.c b/drivers/clk/samsung/clk-s3c2443.c
index 884067e4f1a1..f38f0e24e3b6 100644
--- a/drivers/clk/samsung/clk-s3c2443.c
+++ b/drivers/clk/samsung/clk-s3c2443.c
@@ -389,7 +389,7 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
389 ARRAY_SIZE(s3c2450_gates)); 389 ARRAY_SIZE(s3c2450_gates));
390 samsung_clk_register_alias(ctx, s3c2450_aliases, 390 samsung_clk_register_alias(ctx, s3c2450_aliases,
391 ARRAY_SIZE(s3c2450_aliases)); 391 ARRAY_SIZE(s3c2450_aliases));
392 /* fall through, as s3c2450 extends the s3c2416 clocks */ 392 /* fall through - as s3c2450 extends the s3c2416 clocks */
393 case S3C2416: 393 case S3C2416:
394 samsung_clk_register_div(ctx, s3c2416_dividers, 394 samsung_clk_register_div(ctx, s3c2416_dividers,
395 ARRAY_SIZE(s3c2416_dividers)); 395 ARRAY_SIZE(s3c2416_dividers));
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index c3f309d7100d..9cfaca5fbcdb 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -26,7 +26,7 @@ struct samsung_clk_provider {
26 void __iomem *reg_base; 26 void __iomem *reg_base;
27 struct device *dev; 27 struct device *dev;
28 spinlock_t lock; 28 spinlock_t lock;
29 /* clk_data must be the last entry due to variable lenght 'hws' array */ 29 /* clk_data must be the last entry due to variable length 'hws' array */
30 struct clk_hw_onecell_data clk_data; 30 struct clk_hw_onecell_data clk_data;
31}; 31};
32 32
diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c
index aa7a6e6a15b6..73e03328d5c5 100644
--- a/drivers/clk/socfpga/clk-gate.c
+++ b/drivers/clk/socfpga/clk-gate.c
@@ -176,8 +176,7 @@ static struct clk_ops gateclk_ops = {
176 .set_parent = socfpga_clk_set_parent, 176 .set_parent = socfpga_clk_set_parent,
177}; 177};
178 178
179static void __init __socfpga_gate_init(struct device_node *node, 179void __init socfpga_gate_init(struct device_node *node)
180 const struct clk_ops *ops)
181{ 180{
182 u32 clk_gate[2]; 181 u32 clk_gate[2];
183 u32 div_reg[3]; 182 u32 div_reg[3];
@@ -188,12 +187,17 @@ static void __init __socfpga_gate_init(struct device_node *node,
188 const char *clk_name = node->name; 187 const char *clk_name = node->name;
189 const char *parent_name[SOCFPGA_MAX_PARENTS]; 188 const char *parent_name[SOCFPGA_MAX_PARENTS];
190 struct clk_init_data init; 189 struct clk_init_data init;
190 struct clk_ops *ops;
191 int rc; 191 int rc;
192 192
193 socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); 193 socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
194 if (WARN_ON(!socfpga_clk)) 194 if (WARN_ON(!socfpga_clk))
195 return; 195 return;
196 196
197 ops = kmemdup(&gateclk_ops, sizeof(gateclk_ops), GFP_KERNEL);
198 if (WARN_ON(!ops))
199 return;
200
197 rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2); 201 rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2);
198 if (rc) 202 if (rc)
199 clk_gate[0] = 0; 203 clk_gate[0] = 0;
@@ -202,8 +206,8 @@ static void __init __socfpga_gate_init(struct device_node *node,
202 socfpga_clk->hw.reg = clk_mgr_base_addr + clk_gate[0]; 206 socfpga_clk->hw.reg = clk_mgr_base_addr + clk_gate[0];
203 socfpga_clk->hw.bit_idx = clk_gate[1]; 207 socfpga_clk->hw.bit_idx = clk_gate[1];
204 208
205 gateclk_ops.enable = clk_gate_ops.enable; 209 ops->enable = clk_gate_ops.enable;
206 gateclk_ops.disable = clk_gate_ops.disable; 210 ops->disable = clk_gate_ops.disable;
207 } 211 }
208 212
209 rc = of_property_read_u32(node, "fixed-divider", &fixed_div); 213 rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
@@ -234,6 +238,11 @@ static void __init __socfpga_gate_init(struct device_node *node,
234 init.flags = 0; 238 init.flags = 0;
235 239
236 init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS); 240 init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS);
241 if (init.num_parents < 2) {
242 ops->get_parent = NULL;
243 ops->set_parent = NULL;
244 }
245
237 init.parent_names = parent_name; 246 init.parent_names = parent_name;
238 socfpga_clk->hw.hw.init = &init; 247 socfpga_clk->hw.hw.init = &init;
239 248
@@ -246,8 +255,3 @@ static void __init __socfpga_gate_init(struct device_node *node,
246 if (WARN_ON(rc)) 255 if (WARN_ON(rc))
247 return; 256 return;
248} 257}
249
250void __init socfpga_gate_init(struct device_node *node)
251{
252 __socfpga_gate_init(node, &gateclk_ops);
253}
diff --git a/drivers/clk/socfpga/clk-pll-a10.c b/drivers/clk/socfpga/clk-pll-a10.c
index 35fabe1a32c3..269467e8e07e 100644
--- a/drivers/clk/socfpga/clk-pll-a10.c
+++ b/drivers/clk/socfpga/clk-pll-a10.c
@@ -95,6 +95,7 @@ static struct clk * __init __socfpga_pll_init(struct device_node *node,
95 95
96 clkmgr_np = of_find_compatible_node(NULL, NULL, "altr,clk-mgr"); 96 clkmgr_np = of_find_compatible_node(NULL, NULL, "altr,clk-mgr");
97 clk_mgr_a10_base_addr = of_iomap(clkmgr_np, 0); 97 clk_mgr_a10_base_addr = of_iomap(clkmgr_np, 0);
98 of_node_put(clkmgr_np);
98 BUG_ON(!clk_mgr_a10_base_addr); 99 BUG_ON(!clk_mgr_a10_base_addr);
99 pll_clk->hw.reg = clk_mgr_a10_base_addr + reg; 100 pll_clk->hw.reg = clk_mgr_a10_base_addr + reg;
100 101
diff --git a/drivers/clk/socfpga/clk-pll.c b/drivers/clk/socfpga/clk-pll.c
index c7f463172e4b..b4b44e9b5901 100644
--- a/drivers/clk/socfpga/clk-pll.c
+++ b/drivers/clk/socfpga/clk-pll.c
@@ -100,6 +100,7 @@ static __init struct clk *__socfpga_pll_init(struct device_node *node,
100 100
101 clkmgr_np = of_find_compatible_node(NULL, NULL, "altr,clk-mgr"); 101 clkmgr_np = of_find_compatible_node(NULL, NULL, "altr,clk-mgr");
102 clk_mgr_base_addr = of_iomap(clkmgr_np, 0); 102 clk_mgr_base_addr = of_iomap(clkmgr_np, 0);
103 of_node_put(clkmgr_np);
103 BUG_ON(!clk_mgr_base_addr); 104 BUG_ON(!clk_mgr_base_addr);
104 pll_clk->hw.reg = clk_mgr_base_addr + reg; 105 pll_clk->hw.reg = clk_mgr_base_addr + reg;
105 106
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
index a4fa2945f230..4b5f8f4e4ab8 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
@@ -144,7 +144,7 @@ static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_mipi_clk, "pll-mipi",
144 8, 4, /* N */ 144 8, 4, /* N */
145 4, 2, /* K */ 145 4, 2, /* K */
146 0, 4, /* M */ 146 0, 4, /* M */
147 BIT(31), /* gate */ 147 BIT(31) | BIT(23) | BIT(22), /* gate */
148 BIT(28), /* lock */ 148 BIT(28), /* lock */
149 CLK_SET_RATE_UNGATE); 149 CLK_SET_RATE_UNGATE);
150 150
diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c
index 0400e5b1d627..1fc71baae13b 100644
--- a/drivers/clk/tegra/clk-dfll.c
+++ b/drivers/clk/tegra/clk-dfll.c
@@ -1293,8 +1293,8 @@ static int attr_enable_set(void *data, u64 val)
1293 1293
1294 return val ? dfll_enable(td) : dfll_disable(td); 1294 return val ? dfll_enable(td) : dfll_disable(td);
1295} 1295}
1296DEFINE_SIMPLE_ATTRIBUTE(enable_fops, attr_enable_get, attr_enable_set, 1296DEFINE_DEBUGFS_ATTRIBUTE(enable_fops, attr_enable_get, attr_enable_set,
1297 "%llu\n"); 1297 "%llu\n");
1298 1298
1299static int attr_lock_get(void *data, u64 *val) 1299static int attr_lock_get(void *data, u64 *val)
1300{ 1300{
@@ -1310,8 +1310,7 @@ static int attr_lock_set(void *data, u64 val)
1310 1310
1311 return val ? dfll_lock(td) : dfll_unlock(td); 1311 return val ? dfll_lock(td) : dfll_unlock(td);
1312} 1312}
1313DEFINE_SIMPLE_ATTRIBUTE(lock_fops, attr_lock_get, attr_lock_set, 1313DEFINE_DEBUGFS_ATTRIBUTE(lock_fops, attr_lock_get, attr_lock_set, "%llu\n");
1314 "%llu\n");
1315 1314
1316static int attr_rate_get(void *data, u64 *val) 1315static int attr_rate_get(void *data, u64 *val)
1317{ 1316{
@@ -1328,7 +1327,7 @@ static int attr_rate_set(void *data, u64 val)
1328 1327
1329 return dfll_request_rate(td, val); 1328 return dfll_request_rate(td, val);
1330} 1329}
1331DEFINE_SIMPLE_ATTRIBUTE(rate_fops, attr_rate_get, attr_rate_set, "%llu\n"); 1330DEFINE_DEBUGFS_ATTRIBUTE(rate_fops, attr_rate_get, attr_rate_set, "%llu\n");
1332 1331
1333static int attr_registers_show(struct seq_file *s, void *data) 1332static int attr_registers_show(struct seq_file *s, void *data)
1334{ 1333{
@@ -1379,10 +1378,11 @@ static void dfll_debug_init(struct tegra_dfll *td)
1379 root = debugfs_create_dir("tegra_dfll_fcpu", NULL); 1378 root = debugfs_create_dir("tegra_dfll_fcpu", NULL);
1380 td->debugfs_dir = root; 1379 td->debugfs_dir = root;
1381 1380
1382 debugfs_create_file("enable", S_IRUGO | S_IWUSR, root, td, &enable_fops); 1381 debugfs_create_file_unsafe("enable", 0644, root, td,
1383 debugfs_create_file("lock", S_IRUGO, root, td, &lock_fops); 1382 &enable_fops);
1384 debugfs_create_file("rate", S_IRUGO, root, td, &rate_fops); 1383 debugfs_create_file_unsafe("lock", 0444, root, td, &lock_fops);
1385 debugfs_create_file("registers", S_IRUGO, root, td, &attr_registers_fops); 1384 debugfs_create_file_unsafe("rate", 0444, root, td, &rate_fops);
1385 debugfs_create_file("registers", 0444, root, td, &attr_registers_fops);
1386} 1386}
1387 1387
1388#else 1388#else
diff --git a/drivers/clk/ti/adpll.c b/drivers/clk/ti/adpll.c
index 688e403333b9..0c210984765a 100644
--- a/drivers/clk/ti/adpll.c
+++ b/drivers/clk/ti/adpll.c
@@ -614,7 +614,7 @@ static int ti_adpll_init_clkout(struct ti_adpll_data *d,
614 614
615 init.name = child_name; 615 init.name = child_name;
616 init.ops = ops; 616 init.ops = ops;
617 init.flags = CLK_IS_BASIC; 617 init.flags = 0;
618 co->hw.init = &init; 618 co->hw.init = &init;
619 parent_names[0] = __clk_get_name(clk0); 619 parent_names[0] = __clk_get_name(clk0);
620 parent_names[1] = __clk_get_name(clk1); 620 parent_names[1] = __clk_get_name(clk1);
diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c
index 222f68bc3f2a..015a657d3382 100644
--- a/drivers/clk/ti/apll.c
+++ b/drivers/clk/ti/apll.c
@@ -165,7 +165,7 @@ static void __init omap_clk_register_apll(void *user,
165 165
166 ad->clk_bypass = __clk_get_hw(clk); 166 ad->clk_bypass = __clk_get_hw(clk);
167 167
168 clk = ti_clk_register(NULL, &clk_hw->hw, node->name); 168 clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, node->name);
169 if (!IS_ERR(clk)) { 169 if (!IS_ERR(clk)) {
170 of_clk_add_provider(node, of_clk_src_simple_get, clk); 170 of_clk_add_provider(node, of_clk_src_simple_get, clk);
171 kfree(clk_hw->hw.init->parent_names); 171 kfree(clk_hw->hw.init->parent_names);
@@ -402,7 +402,7 @@ static void __init of_omap2_apll_setup(struct device_node *node)
402 if (ret) 402 if (ret)
403 goto cleanup; 403 goto cleanup;
404 404
405 clk = clk_register(NULL, &clk_hw->hw); 405 clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, node->name);
406 if (!IS_ERR(clk)) { 406 if (!IS_ERR(clk)) {
407 of_clk_add_provider(node, of_clk_src_simple_get, clk); 407 of_clk_add_provider(node, of_clk_src_simple_get, clk);
408 kfree(init); 408 kfree(init);
diff --git a/drivers/clk/ti/autoidle.c b/drivers/clk/ti/autoidle.c
index 7bb9afbe4058..1cae226759dd 100644
--- a/drivers/clk/ti/autoidle.c
+++ b/drivers/clk/ti/autoidle.c
@@ -35,7 +35,44 @@ struct clk_ti_autoidle {
35#define AUTOIDLE_LOW 0x1 35#define AUTOIDLE_LOW 0x1
36 36
37static LIST_HEAD(autoidle_clks); 37static LIST_HEAD(autoidle_clks);
38static LIST_HEAD(clk_hw_omap_clocks); 38
39/*
40 * we have some non-atomic read/write
41 * operations behind it, so lets
42 * take one lock for handling autoidle
43 * of all clocks
44 */
45static DEFINE_SPINLOCK(autoidle_spinlock);
46
47static int _omap2_clk_deny_idle(struct clk_hw_omap *clk)
48{
49 if (clk->ops && clk->ops->deny_idle) {
50 unsigned long irqflags;
51
52 spin_lock_irqsave(&autoidle_spinlock, irqflags);
53 clk->autoidle_count++;
54 if (clk->autoidle_count == 1)
55 clk->ops->deny_idle(clk);
56
57 spin_unlock_irqrestore(&autoidle_spinlock, irqflags);
58 }
59 return 0;
60}
61
62static int _omap2_clk_allow_idle(struct clk_hw_omap *clk)
63{
64 if (clk->ops && clk->ops->allow_idle) {
65 unsigned long irqflags;
66
67 spin_lock_irqsave(&autoidle_spinlock, irqflags);
68 clk->autoidle_count--;
69 if (clk->autoidle_count == 0)
70 clk->ops->allow_idle(clk);
71
72 spin_unlock_irqrestore(&autoidle_spinlock, irqflags);
73 }
74 return 0;
75}
39 76
40/** 77/**
41 * omap2_clk_deny_idle - disable autoidle on an OMAP clock 78 * omap2_clk_deny_idle - disable autoidle on an OMAP clock
@@ -45,12 +82,15 @@ static LIST_HEAD(clk_hw_omap_clocks);
45 */ 82 */
46int omap2_clk_deny_idle(struct clk *clk) 83int omap2_clk_deny_idle(struct clk *clk)
47{ 84{
48 struct clk_hw_omap *c; 85 struct clk_hw *hw = __clk_get_hw(clk);
49 86
50 c = to_clk_hw_omap(__clk_get_hw(clk)); 87 if (omap2_clk_is_hw_omap(hw)) {
51 if (c->ops && c->ops->deny_idle) 88 struct clk_hw_omap *c = to_clk_hw_omap(hw);
52 c->ops->deny_idle(c); 89
53 return 0; 90 return _omap2_clk_deny_idle(c);
91 }
92
93 return -EINVAL;
54} 94}
55 95
56/** 96/**
@@ -61,12 +101,15 @@ int omap2_clk_deny_idle(struct clk *clk)
61 */ 101 */
62int omap2_clk_allow_idle(struct clk *clk) 102int omap2_clk_allow_idle(struct clk *clk)
63{ 103{
64 struct clk_hw_omap *c; 104 struct clk_hw *hw = __clk_get_hw(clk);
65 105
66 c = to_clk_hw_omap(__clk_get_hw(clk)); 106 if (omap2_clk_is_hw_omap(hw)) {
67 if (c->ops && c->ops->allow_idle) 107 struct clk_hw_omap *c = to_clk_hw_omap(hw);
68 c->ops->allow_idle(c); 108
69 return 0; 109 return _omap2_clk_allow_idle(c);
110 }
111
112 return -EINVAL;
70} 113}
71 114
72static void _allow_autoidle(struct clk_ti_autoidle *clk) 115static void _allow_autoidle(struct clk_ti_autoidle *clk)
@@ -168,26 +211,6 @@ int __init of_ti_clk_autoidle_setup(struct device_node *node)
168} 211}
169 212
170/** 213/**
171 * omap2_init_clk_hw_omap_clocks - initialize an OMAP clock
172 * @hw: struct clk_hw * to initialize
173 *
174 * Add an OMAP clock @clk to the internal list of OMAP clocks. Used
175 * temporarily for autoidle handling, until this support can be
176 * integrated into the common clock framework code in some way. No
177 * return value.
178 */
179void omap2_init_clk_hw_omap_clocks(struct clk_hw *hw)
180{
181 struct clk_hw_omap *c;
182
183 if (clk_hw_get_flags(hw) & CLK_IS_BASIC)
184 return;
185
186 c = to_clk_hw_omap(hw);
187 list_add(&c->node, &clk_hw_omap_clocks);
188}
189
190/**
191 * omap2_clk_enable_autoidle_all - enable autoidle on all OMAP clocks that 214 * omap2_clk_enable_autoidle_all - enable autoidle on all OMAP clocks that
192 * support it 215 * support it
193 * 216 *
@@ -198,11 +221,11 @@ void omap2_init_clk_hw_omap_clocks(struct clk_hw *hw)
198 */ 221 */
199int omap2_clk_enable_autoidle_all(void) 222int omap2_clk_enable_autoidle_all(void)
200{ 223{
201 struct clk_hw_omap *c; 224 int ret;
202 225
203 list_for_each_entry(c, &clk_hw_omap_clocks, node) 226 ret = omap2_clk_for_each(_omap2_clk_allow_idle);
204 if (c->ops && c->ops->allow_idle) 227 if (ret)
205 c->ops->allow_idle(c); 228 return ret;
206 229
207 _clk_generic_allow_autoidle_all(); 230 _clk_generic_allow_autoidle_all();
208 231
@@ -220,11 +243,11 @@ int omap2_clk_enable_autoidle_all(void)
220 */ 243 */
221int omap2_clk_disable_autoidle_all(void) 244int omap2_clk_disable_autoidle_all(void)
222{ 245{
223 struct clk_hw_omap *c; 246 int ret;
224 247
225 list_for_each_entry(c, &clk_hw_omap_clocks, node) 248 ret = omap2_clk_for_each(_omap2_clk_deny_idle);
226 if (c->ops && c->ops->deny_idle) 249 if (ret)
227 c->ops->deny_idle(c); 250 return ret;
228 251
229 _clk_generic_deny_autoidle_all(); 252 _clk_generic_deny_autoidle_all();
230 253
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 5d7fb2eecce4..ba17cc5bd04b 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -31,6 +31,7 @@
31#undef pr_fmt 31#undef pr_fmt
32#define pr_fmt(fmt) "%s: " fmt, __func__ 32#define pr_fmt(fmt) "%s: " fmt, __func__
33 33
34static LIST_HEAD(clk_hw_omap_clocks);
34struct ti_clk_ll_ops *ti_clk_ll_ops; 35struct ti_clk_ll_ops *ti_clk_ll_ops;
35static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS]; 36static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS];
36 37
@@ -191,9 +192,13 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[])
191 clkdev_add(&c->lk); 192 clkdev_add(&c->lk);
192 } else { 193 } else {
193 if (num_args && !has_clkctrl_data) { 194 if (num_args && !has_clkctrl_data) {
194 if (of_find_compatible_node(NULL, NULL, 195 struct device_node *np;
195 "ti,clkctrl")) { 196
197 np = of_find_compatible_node(NULL, NULL,
198 "ti,clkctrl");
199 if (np) {
196 has_clkctrl_data = true; 200 has_clkctrl_data = true;
201 of_node_put(np);
197 } else { 202 } else {
198 clkctrl_nodes_missing = true; 203 clkctrl_nodes_missing = true;
199 204
@@ -520,3 +525,74 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
520 525
521 return clk; 526 return clk;
522} 527}
528
529/**
530 * ti_clk_register_omap_hw - register a clk_hw_omap to the clock framework
531 * @dev: device for this clock
532 * @hw: hardware clock handle
533 * @con: connection ID for this clock
534 *
535 * Registers a clk_hw_omap clock to the clock framewor, adds a clock alias
536 * for it, and adds the list to the available clk_hw_omap type clocks.
537 * Returns a handle to the registered clock if successful, ERR_PTR value
538 * in failure.
539 */
540struct clk *ti_clk_register_omap_hw(struct device *dev, struct clk_hw *hw,
541 const char *con)
542{
543 struct clk *clk;
544 struct clk_hw_omap *oclk;
545
546 clk = ti_clk_register(dev, hw, con);
547 if (IS_ERR(clk))
548 return clk;
549
550 oclk = to_clk_hw_omap(hw);
551
552 list_add(&oclk->node, &clk_hw_omap_clocks);
553
554 return clk;
555}
556
557/**
558 * omap2_clk_for_each - call function for each registered clk_hw_omap
559 * @fn: pointer to a callback function
560 *
561 * Call @fn for each registered clk_hw_omap, passing @hw to each
562 * function. @fn must return 0 for success or any other value for
563 * failure. If @fn returns non-zero, the iteration across clocks
564 * will stop and the non-zero return value will be passed to the
565 * caller of omap2_clk_for_each().
566 */
567int omap2_clk_for_each(int (*fn)(struct clk_hw_omap *hw))
568{
569 int ret;
570 struct clk_hw_omap *hw;
571
572 list_for_each_entry(hw, &clk_hw_omap_clocks, node) {
573 ret = (*fn)(hw);
574 if (ret)
575 break;
576 }
577
578 return ret;
579}
580
581/**
582 * omap2_clk_is_hw_omap - check if the provided clk_hw is OMAP clock
583 * @hw: clk_hw to check if it is an omap clock or not
584 *
585 * Checks if the provided clk_hw is OMAP clock or not. Returns true if
586 * it is, false otherwise.
587 */
588bool omap2_clk_is_hw_omap(struct clk_hw *hw)
589{
590 struct clk_hw_omap *oclk;
591
592 list_for_each_entry(oclk, &clk_hw_omap_clocks, node) {
593 if (&oclk->hw == hw)
594 return true;
595 }
596
597 return false;
598}
diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c
index 40630eb950fc..639f515e08f0 100644
--- a/drivers/clk/ti/clkctrl.c
+++ b/drivers/clk/ti/clkctrl.c
@@ -276,7 +276,7 @@ _ti_clkctrl_clk_register(struct omap_clkctrl_provider *provider,
276 init.parent_names = parents; 276 init.parent_names = parents;
277 init.num_parents = num_parents; 277 init.num_parents = num_parents;
278 init.ops = ops; 278 init.ops = ops;
279 init.flags = CLK_IS_BASIC; 279 init.flags = 0;
280 280
281 clk = ti_clk_register(NULL, clk_hw, init.name); 281 clk = ti_clk_register(NULL, clk_hw, init.name);
282 if (IS_ERR_OR_NULL(clk)) { 282 if (IS_ERR_OR_NULL(clk)) {
@@ -530,7 +530,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
530 * Create default clkdm name, replace _cm from end of parent 530 * Create default clkdm name, replace _cm from end of parent
531 * node name with _clkdm 531 * node name with _clkdm
532 */ 532 */
533 provider->clkdm_name[strlen(provider->clkdm_name) - 5] = 0; 533 provider->clkdm_name[strlen(provider->clkdm_name) - 2] = 0;
534 } else { 534 } else {
535 provider->clkdm_name = kasprintf(GFP_KERNEL, "%pOFn", node); 535 provider->clkdm_name = kasprintf(GFP_KERNEL, "%pOFn", node);
536 if (!provider->clkdm_name) { 536 if (!provider->clkdm_name) {
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 9f312a219510..1c0fac59d809 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -203,6 +203,8 @@ typedef void (*ti_of_clk_init_cb_t)(void *, struct device_node *);
203 203
204struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw, 204struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
205 const char *con); 205 const char *con);
206struct clk *ti_clk_register_omap_hw(struct device *dev, struct clk_hw *hw,
207 const char *con);
206int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con); 208int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con);
207void ti_clk_add_aliases(void); 209void ti_clk_add_aliases(void);
208 210
@@ -221,7 +223,6 @@ int ti_clk_retry_init(struct device_node *node, void *user,
221 ti_of_clk_init_cb_t func); 223 ti_of_clk_init_cb_t func);
222int ti_clk_add_component(struct device_node *node, struct clk_hw *hw, int type); 224int ti_clk_add_component(struct device_node *node, struct clk_hw *hw, int type);
223 225
224void omap2_init_clk_hw_omap_clocks(struct clk_hw *hw);
225int of_ti_clk_autoidle_setup(struct device_node *node); 226int of_ti_clk_autoidle_setup(struct device_node *node);
226void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks); 227void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks);
227 228
@@ -301,6 +302,8 @@ long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
301 unsigned long *parent_rate); 302 unsigned long *parent_rate);
302int omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, 303int omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw,
303 struct clk_rate_request *req); 304 struct clk_rate_request *req);
305int omap2_clk_for_each(int (*fn)(struct clk_hw_omap *hw));
306bool omap2_clk_is_hw_omap(struct clk_hw *hw);
304 307
305extern struct ti_clk_ll_ops *ti_clk_ll_ops; 308extern struct ti_clk_ll_ops *ti_clk_ll_ops;
306 309
diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
index 07a805125e98..423a99b9f10c 100644
--- a/drivers/clk/ti/clockdomain.c
+++ b/drivers/clk/ti/clockdomain.c
@@ -143,7 +143,7 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
143 continue; 143 continue;
144 } 144 }
145 clk_hw = __clk_get_hw(clk); 145 clk_hw = __clk_get_hw(clk);
146 if (clk_hw_get_flags(clk_hw) & CLK_IS_BASIC) { 146 if (!omap2_clk_is_hw_omap(clk_hw)) {
147 pr_warn("can't setup clkdm for basic clk %s\n", 147 pr_warn("can't setup clkdm for basic clk %s\n",
148 __clk_get_name(clk)); 148 __clk_get_name(clk));
149 continue; 149 continue;
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
index 0241450f3eb3..4786e0ebc2e8 100644
--- a/drivers/clk/ti/divider.c
+++ b/drivers/clk/ti/divider.c
@@ -336,7 +336,7 @@ static struct clk *_register_divider(struct device *dev, const char *name,
336 336
337 init.name = name; 337 init.name = name;
338 init.ops = &ti_clk_divider_ops; 338 init.ops = &ti_clk_divider_ops;
339 init.flags = flags | CLK_IS_BASIC; 339 init.flags = flags;
340 init.parent_names = (parent_name ? &parent_name : NULL); 340 init.parent_names = (parent_name ? &parent_name : NULL);
341 init.num_parents = (parent_name ? 1 : 0); 341 init.num_parents = (parent_name ? 1 : 0);
342 342
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index 6c3329bc116f..659dadb23279 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -192,10 +192,9 @@ static void __init _register_dpll(void *user,
192 dd->clk_bypass = __clk_get_hw(clk); 192 dd->clk_bypass = __clk_get_hw(clk);
193 193
194 /* register the clock */ 194 /* register the clock */
195 clk = ti_clk_register(NULL, &clk_hw->hw, node->name); 195 clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, node->name);
196 196
197 if (!IS_ERR(clk)) { 197 if (!IS_ERR(clk)) {
198 omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
199 of_clk_add_provider(node, of_clk_src_simple_get, clk); 198 of_clk_add_provider(node, of_clk_src_simple_get, clk);
200 kfree(clk_hw->hw.init->parent_names); 199 kfree(clk_hw->hw.init->parent_names);
201 kfree(clk_hw->hw.init); 200 kfree(clk_hw->hw.init);
@@ -265,14 +264,12 @@ static void _register_dpll_x2(struct device_node *node,
265#endif 264#endif
266 265
267 /* register the clock */ 266 /* register the clock */
268 clk = ti_clk_register(NULL, &clk_hw->hw, name); 267 clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
269 268
270 if (IS_ERR(clk)) { 269 if (IS_ERR(clk))
271 kfree(clk_hw); 270 kfree(clk_hw);
272 } else { 271 else
273 omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
274 of_clk_add_provider(node, of_clk_src_simple_get, clk); 272 of_clk_add_provider(node, of_clk_src_simple_get, clk);
275 }
276} 273}
277#endif 274#endif
278 275
diff --git a/drivers/clk/ti/dpll3xxx.c b/drivers/clk/ti/dpll3xxx.c
index 44b6b6403753..3dde6c8c3354 100644
--- a/drivers/clk/ti/dpll3xxx.c
+++ b/drivers/clk/ti/dpll3xxx.c
@@ -731,7 +731,7 @@ static struct clk_hw_omap *omap3_find_clkoutx2_dpll(struct clk_hw *hw)
731 do { 731 do {
732 do { 732 do {
733 hw = clk_hw_get_parent(hw); 733 hw = clk_hw_get_parent(hw);
734 } while (hw && (clk_hw_get_flags(hw) & CLK_IS_BASIC)); 734 } while (hw && (!omap2_clk_is_hw_omap(hw)));
735 if (!hw) 735 if (!hw)
736 break; 736 break;
737 pclk = to_clk_hw_omap(hw); 737 pclk = to_clk_hw_omap(hw);
diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c
index 1c78fff5513c..504c0e91cdc7 100644
--- a/drivers/clk/ti/gate.c
+++ b/drivers/clk/ti/gate.c
@@ -123,7 +123,7 @@ static struct clk *_register_gate(struct device *dev, const char *name,
123 123
124 init.flags = flags; 124 init.flags = flags;
125 125
126 clk = ti_clk_register(NULL, &clk_hw->hw, name); 126 clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
127 127
128 if (IS_ERR(clk)) 128 if (IS_ERR(clk))
129 kfree(clk_hw); 129 kfree(clk_hw);
diff --git a/drivers/clk/ti/interface.c b/drivers/clk/ti/interface.c
index 87e00c2ee957..83e34429d3b1 100644
--- a/drivers/clk/ti/interface.c
+++ b/drivers/clk/ti/interface.c
@@ -57,12 +57,10 @@ static struct clk *_register_interface(struct device *dev, const char *name,
57 init.num_parents = 1; 57 init.num_parents = 1;
58 init.parent_names = &parent_name; 58 init.parent_names = &parent_name;
59 59
60 clk = ti_clk_register(NULL, &clk_hw->hw, name); 60 clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
61 61
62 if (IS_ERR(clk)) 62 if (IS_ERR(clk))
63 kfree(clk_hw); 63 kfree(clk_hw);
64 else
65 omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
66 64
67 return clk; 65 return clk;
68} 66}
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 883bdde94d04..b7f9a4f068bf 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -143,7 +143,7 @@ static struct clk *_register_mux(struct device *dev, const char *name,
143 143
144 init.name = name; 144 init.name = name;
145 init.ops = &ti_clk_mux_ops; 145 init.ops = &ti_clk_mux_ops;
146 init.flags = flags | CLK_IS_BASIC; 146 init.flags = flags;
147 init.parent_names = parent_names; 147 init.parent_names = parent_names;
148 init.num_parents = num_parents; 148 init.num_parents = num_parents;
149 149
diff --git a/drivers/clk/uniphier/clk-uniphier-cpugear.c b/drivers/clk/uniphier/clk-uniphier-cpugear.c
index ec11f55594ad..5d2d42b7e182 100644
--- a/drivers/clk/uniphier/clk-uniphier-cpugear.c
+++ b/drivers/clk/uniphier/clk-uniphier-cpugear.c
@@ -47,7 +47,7 @@ static int uniphier_clk_cpugear_set_parent(struct clk_hw *hw, u8 index)
47 return ret; 47 return ret;
48 48
49 ret = regmap_write_bits(gear->regmap, 49 ret = regmap_write_bits(gear->regmap,
50 gear->regbase + UNIPHIER_CLK_CPUGEAR_SET, 50 gear->regbase + UNIPHIER_CLK_CPUGEAR_UPD,
51 UNIPHIER_CLK_CPUGEAR_UPD_BIT, 51 UNIPHIER_CLK_CPUGEAR_UPD_BIT,
52 UNIPHIER_CLK_CPUGEAR_UPD_BIT); 52 UNIPHIER_CLK_CPUGEAR_UPD_BIT);
53 if (ret) 53 if (ret)
diff --git a/drivers/clk/x86/clk-lpt.c b/drivers/clk/x86/clk-lpt.c
index 6b40eb89ae19..68bd3abaef2c 100644
--- a/drivers/clk/x86/clk-lpt.c
+++ b/drivers/clk/x86/clk-lpt.c
@@ -13,7 +13,7 @@
13#include <linux/clk-provider.h> 13#include <linux/clk-provider.h>
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/platform_data/clk-lpss.h> 16#include <linux/platform_data/x86/clk-lpss.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18 18
19static int lpt_clk_probe(struct platform_device *pdev) 19static int lpt_clk_probe(struct platform_device *pdev)
diff --git a/drivers/clk/x86/clk-st.c b/drivers/clk/x86/clk-st.c
index 3a0996f2d556..25d4b97aff9b 100644
--- a/drivers/clk/x86/clk-st.c
+++ b/drivers/clk/x86/clk-st.c
@@ -52,7 +52,8 @@ static int st_clk_probe(struct platform_device *pdev)
52 0, st_data->base + MISCCLKCNTL1, OSCCLKENB, 52 0, st_data->base + MISCCLKCNTL1, OSCCLKENB,
53 CLK_GATE_SET_TO_DISABLE, NULL); 53 CLK_GATE_SET_TO_DISABLE, NULL);
54 54
55 clk_hw_register_clkdev(hws[ST_CLK_GATE], "oscout1", NULL); 55 devm_clk_hw_register_clkdev(&pdev->dev, hws[ST_CLK_GATE], "oscout1",
56 NULL);
56 57
57 return 0; 58 return 0;
58} 59}
diff --git a/include/dt-bindings/clock/actions,s500-cmu.h b/include/dt-bindings/clock/actions,s500-cmu.h
new file mode 100644
index 000000000000..030981cd2d56
--- /dev/null
+++ b/include/dt-bindings/clock/actions,s500-cmu.h
@@ -0,0 +1,78 @@
1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Device Tree binding constants for Actions Semi S500 Clock Management Unit
4 *
5 * Copyright (c) 2014 Actions Semi Inc.
6 * Copyright (c) 2018 LSI-TEC - Caninos Loucos
7 */
8
9#ifndef __DT_BINDINGS_CLOCK_S500_CMU_H
10#define __DT_BINDINGS_CLOCK_S500_CMU_H
11
12#define CLK_NONE 0
13
14/* fixed rate clocks */
15#define CLK_LOSC 1
16#define CLK_HOSC 2
17
18/* pll clocks */
19#define CLK_CORE_PLL 3
20#define CLK_DEV_PLL 4
21#define CLK_DDR_PLL 5
22#define CLK_NAND_PLL 6
23#define CLK_DISPLAY_PLL 7
24#define CLK_ETHERNET_PLL 8
25#define CLK_AUDIO_PLL 9
26
27/* system clock */
28#define CLK_DEV 10
29#define CLK_H 11
30#define CLK_AHBPREDIV 12
31#define CLK_AHB 13
32#define CLK_DE 14
33#define CLK_BISP 15
34#define CLK_VCE 16
35#define CLK_VDE 17
36
37/* peripheral device clock */
38#define CLK_TIMER 18
39#define CLK_I2C0 19
40#define CLK_I2C1 20
41#define CLK_I2C2 21
42#define CLK_I2C3 22
43#define CLK_PWM0 23
44#define CLK_PWM1 24
45#define CLK_PWM2 25
46#define CLK_PWM3 26
47#define CLK_PWM4 27
48#define CLK_PWM5 28
49#define CLK_SD0 29
50#define CLK_SD1 30
51#define CLK_SD2 31
52#define CLK_SENSOR0 32
53#define CLK_SENSOR1 33
54#define CLK_SPI0 34
55#define CLK_SPI1 35
56#define CLK_SPI2 36
57#define CLK_SPI3 37
58#define CLK_UART0 38
59#define CLK_UART1 39
60#define CLK_UART2 40
61#define CLK_UART3 41
62#define CLK_UART4 42
63#define CLK_UART5 43
64#define CLK_UART6 44
65#define CLK_DE1 45
66#define CLK_DE2 46
67#define CLK_I2SRX 47
68#define CLK_I2STX 48
69#define CLK_HDMI_AUDIO 49
70#define CLK_HDMI 50
71#define CLK_SPDIF 51
72#define CLK_NAND 52
73#define CLK_ECC 53
74#define CLK_RMII_REF 54
75
76#define CLK_NR_CLKS (CLK_RMII_REF + 1)
77
78#endif /* __DT_BINDINGS_CLOCK_S500_CMU_H */
diff --git a/include/dt-bindings/clock/axg-aoclkc.h b/include/dt-bindings/clock/axg-aoclkc.h
index 61955016a55b..8ec4a269c7a6 100644
--- a/include/dt-bindings/clock/axg-aoclkc.h
+++ b/include/dt-bindings/clock/axg-aoclkc.h
@@ -21,6 +21,11 @@
21#define CLKID_AO_SAR_ADC_SEL 8 21#define CLKID_AO_SAR_ADC_SEL 8
22#define CLKID_AO_SAR_ADC_DIV 9 22#define CLKID_AO_SAR_ADC_DIV 9
23#define CLKID_AO_SAR_ADC_CLK 10 23#define CLKID_AO_SAR_ADC_CLK 10
24#define CLKID_AO_ALT_XTAL 11 24#define CLKID_AO_CTS_OSCIN 11
25#define CLKID_AO_32K_PRE 12
26#define CLKID_AO_32K_DIV 13
27#define CLKID_AO_32K_SEL 14
28#define CLKID_AO_32K 15
29#define CLKID_AO_CTS_RTC_OSCIN 16
25 30
26#endif 31#endif
diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h
index 98bd85ce1e45..25ffa53573a5 100644
--- a/include/dt-bindings/clock/exynos5433.h
+++ b/include/dt-bindings/clock/exynos5433.h
@@ -156,7 +156,7 @@
156#define CLK_ACLK_G2D_266 220 156#define CLK_ACLK_G2D_266 220
157#define CLK_ACLK_G2D_400 221 157#define CLK_ACLK_G2D_400 221
158#define CLK_ACLK_G3D_400 222 158#define CLK_ACLK_G3D_400 222
159#define CLK_ACLK_IMEM_SSX_266 223 159#define CLK_ACLK_IMEM_SSSX_266 223
160#define CLK_ACLK_BUS0_400 224 160#define CLK_ACLK_BUS0_400 224
161#define CLK_ACLK_BUS1_400 225 161#define CLK_ACLK_BUS1_400 225
162#define CLK_ACLK_IMEM_200 226 162#define CLK_ACLK_IMEM_200 226
@@ -1406,4 +1406,10 @@
1406 1406
1407#define CAM1_NR_CLK 113 1407#define CAM1_NR_CLK 113
1408 1408
1409/* CMU_IMEM */
1410#define CLK_ACLK_SLIMSSS 2
1411#define CLK_PCLK_SLIMSSS 35
1412
1413#define IMEM_NR_CLK 36
1414
1409#endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */ 1415#endif /* _DT_BINDINGS_CLOCK_EXYNOS5433_H */
diff --git a/include/dt-bindings/clock/g12a-aoclkc.h b/include/dt-bindings/clock/g12a-aoclkc.h
new file mode 100644
index 000000000000..8db01ffbeb06
--- /dev/null
+++ b/include/dt-bindings/clock/g12a-aoclkc.h
@@ -0,0 +1,34 @@
1/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
2/*
3 * Copyright (c) 2016 BayLibre, SAS
4 * Author: Neil Armstrong <narmstrong@baylibre.com>
5 *
6 * Copyright (c) 2018 Amlogic, inc.
7 * Author: Qiufang Dai <qiufang.dai@amlogic.com>
8 */
9
10#ifndef DT_BINDINGS_CLOCK_AMLOGIC_MESON_G12A_AOCLK
11#define DT_BINDINGS_CLOCK_AMLOGIC_MESON_G12A_AOCLK
12
13#define CLKID_AO_AHB 0
14#define CLKID_AO_IR_IN 1
15#define CLKID_AO_I2C_M0 2
16#define CLKID_AO_I2C_S0 3
17#define CLKID_AO_UART 4
18#define CLKID_AO_PROD_I2C 5
19#define CLKID_AO_UART2 6
20#define CLKID_AO_IR_OUT 7
21#define CLKID_AO_SAR_ADC 8
22#define CLKID_AO_MAILBOX 9
23#define CLKID_AO_M3 10
24#define CLKID_AO_AHB_SRAM 11
25#define CLKID_AO_RTI 12
26#define CLKID_AO_M4_FCLK 13
27#define CLKID_AO_M4_HCLK 14
28#define CLKID_AO_CLK81 15
29#define CLKID_AO_SAR_ADC_CLK 18
30#define CLKID_AO_32K 23
31#define CLKID_AO_CEC 27
32#define CLKID_AO_CTS_RTC_OSCIN 28
33
34#endif
diff --git a/include/dt-bindings/clock/g12a-clkc.h b/include/dt-bindings/clock/g12a-clkc.h
new file mode 100644
index 000000000000..83b657038d1e
--- /dev/null
+++ b/include/dt-bindings/clock/g12a-clkc.h
@@ -0,0 +1,135 @@
1/* SPDX-License-Identifier: GPL-2.0+ OR MIT */
2/*
3 * Meson-G12A clock tree IDs
4 *
5 * Copyright (c) 2018 Amlogic, Inc. All rights reserved.
6 */
7
8#ifndef __G12A_CLKC_H
9#define __G12A_CLKC_H
10
11#define CLKID_SYS_PLL 0
12#define CLKID_FIXED_PLL 1
13#define CLKID_FCLK_DIV2 2
14#define CLKID_FCLK_DIV3 3
15#define CLKID_FCLK_DIV4 4
16#define CLKID_FCLK_DIV5 5
17#define CLKID_FCLK_DIV7 6
18#define CLKID_GP0_PLL 7
19#define CLKID_CLK81 10
20#define CLKID_MPLL0 11
21#define CLKID_MPLL1 12
22#define CLKID_MPLL2 13
23#define CLKID_MPLL3 14
24#define CLKID_DDR 15
25#define CLKID_DOS 16
26#define CLKID_AUDIO_LOCKER 17
27#define CLKID_MIPI_DSI_HOST 18
28#define CLKID_ETH_PHY 19
29#define CLKID_ISA 20
30#define CLKID_PL301 21
31#define CLKID_PERIPHS 22
32#define CLKID_SPICC0 23
33#define CLKID_I2C 24
34#define CLKID_SANA 25
35#define CLKID_SD 26
36#define CLKID_RNG0 27
37#define CLKID_UART0 28
38#define CLKID_SPICC1 29
39#define CLKID_HIU_IFACE 30
40#define CLKID_MIPI_DSI_PHY 31
41#define CLKID_ASSIST_MISC 32
42#define CLKID_SD_EMMC_A 33
43#define CLKID_SD_EMMC_B 34
44#define CLKID_SD_EMMC_C 35
45#define CLKID_AUDIO_CODEC 36
46#define CLKID_AUDIO 37
47#define CLKID_ETH 38
48#define CLKID_DEMUX 39
49#define CLKID_AUDIO_IFIFO 40
50#define CLKID_ADC 41
51#define CLKID_UART1 42
52#define CLKID_G2D 43
53#define CLKID_RESET 44
54#define CLKID_PCIE_COMB 45
55#define CLKID_PARSER 46
56#define CLKID_USB 47
57#define CLKID_PCIE_PHY 48
58#define CLKID_AHB_ARB0 49
59#define CLKID_AHB_DATA_BUS 50
60#define CLKID_AHB_CTRL_BUS 51
61#define CLKID_HTX_HDCP22 52
62#define CLKID_HTX_PCLK 53
63#define CLKID_BT656 54
64#define CLKID_USB1_DDR_BRIDGE 55
65#define CLKID_MMC_PCLK 56
66#define CLKID_UART2 57
67#define CLKID_VPU_INTR 58
68#define CLKID_GIC 59
69#define CLKID_SD_EMMC_A_CLK0 60
70#define CLKID_SD_EMMC_B_CLK0 61
71#define CLKID_SD_EMMC_C_CLK0 62
72#define CLKID_HIFI_PLL 74
73#define CLKID_VCLK2_VENCI0 80
74#define CLKID_VCLK2_VENCI1 81
75#define CLKID_VCLK2_VENCP0 82
76#define CLKID_VCLK2_VENCP1 83
77#define CLKID_VCLK2_VENCT0 84
78#define CLKID_VCLK2_VENCT1 85
79#define CLKID_VCLK2_OTHER 86
80#define CLKID_VCLK2_ENCI 87
81#define CLKID_VCLK2_ENCP 88
82#define CLKID_DAC_CLK 89
83#define CLKID_AOCLK 90
84#define CLKID_IEC958 91
85#define CLKID_ENC480P 92
86#define CLKID_RNG1 93
87#define CLKID_VCLK2_ENCT 94
88#define CLKID_VCLK2_ENCL 95
89#define CLKID_VCLK2_VENCLMMC 96
90#define CLKID_VCLK2_VENCL 97
91#define CLKID_VCLK2_OTHER1 98
92#define CLKID_FCLK_DIV2P5 99
93#define CLKID_DMA 105
94#define CLKID_EFUSE 106
95#define CLKID_ROM_BOOT 107
96#define CLKID_RESET_SEC 108
97#define CLKID_SEC_AHB_APB3 109
98#define CLKID_VPU_0_SEL 110
99#define CLKID_VPU_0 112
100#define CLKID_VPU_1_SEL 113
101#define CLKID_VPU_1 115
102#define CLKID_VPU 116
103#define CLKID_VAPB_0_SEL 117
104#define CLKID_VAPB_0 119
105#define CLKID_VAPB_1_SEL 120
106#define CLKID_VAPB_1 122
107#define CLKID_VAPB_SEL 123
108#define CLKID_VAPB 124
109#define CLKID_HDMI_PLL 128
110#define CLKID_VID_PLL 129
111#define CLKID_VCLK 138
112#define CLKID_VCLK2 139
113#define CLKID_VCLK_DIV1 148
114#define CLKID_VCLK_DIV2 149
115#define CLKID_VCLK_DIV4 150
116#define CLKID_VCLK_DIV6 151
117#define CLKID_VCLK_DIV12 152
118#define CLKID_VCLK2_DIV1 153
119#define CLKID_VCLK2_DIV2 154
120#define CLKID_VCLK2_DIV4 155
121#define CLKID_VCLK2_DIV6 156
122#define CLKID_VCLK2_DIV12 157
123#define CLKID_CTS_ENCI 162
124#define CLKID_CTS_ENCP 163
125#define CLKID_CTS_VDAC 164
126#define CLKID_HDMI_TX 165
127#define CLKID_HDMI 168
128#define CLKID_MALI_0_SEL 169
129#define CLKID_MALI_0 171
130#define CLKID_MALI_1_SEL 172
131#define CLKID_MALI_1 174
132#define CLKID_MALI 175
133#define CLKID_MPLL_5OM 177
134
135#endif /* __G12A_CLKC_H */
diff --git a/include/dt-bindings/clock/gxbb-aoclkc.h b/include/dt-bindings/clock/gxbb-aoclkc.h
index 9d15e2221fdb..ec3b26319fc4 100644
--- a/include/dt-bindings/clock/gxbb-aoclkc.h
+++ b/include/dt-bindings/clock/gxbb-aoclkc.h
@@ -63,5 +63,12 @@
63#define CLKID_AO_UART2 4 63#define CLKID_AO_UART2 4
64#define CLKID_AO_IR_BLASTER 5 64#define CLKID_AO_IR_BLASTER 5
65#define CLKID_AO_CEC_32K 6 65#define CLKID_AO_CEC_32K 6
66#define CLKID_AO_CTS_OSCIN 7
67#define CLKID_AO_32K_PRE 8
68#define CLKID_AO_32K_DIV 9
69#define CLKID_AO_32K_SEL 10
70#define CLKID_AO_32K 11
71#define CLKID_AO_CTS_RTC_OSCIN 12
72#define CLKID_AO_CLK81 13
66 73
67#endif 74#endif
diff --git a/include/dt-bindings/clock/imx5-clock.h b/include/dt-bindings/clock/imx5-clock.h
index d382fc71aa83..a81be5be6700 100644
--- a/include/dt-bindings/clock/imx5-clock.h
+++ b/include/dt-bindings/clock/imx5-clock.h
@@ -214,6 +214,7 @@
214#define IMX5_CLK_IEEE1588_SEL 202 214#define IMX5_CLK_IEEE1588_SEL 202
215#define IMX5_CLK_IEEE1588_PODF 203 215#define IMX5_CLK_IEEE1588_PODF 203
216#define IMX5_CLK_IEEE1588_GATE 204 216#define IMX5_CLK_IEEE1588_GATE 204
217#define IMX5_CLK_END 205 217#define IMX5_CLK_SCC2_IPG_GATE 205
218#define IMX5_CLK_END 206
218 219
219#endif /* __DT_BINDINGS_CLOCK_IMX5_H */ 220#endif /* __DT_BINDINGS_CLOCK_IMX5_H */
diff --git a/include/dt-bindings/clock/imx8mm-clock.h b/include/dt-bindings/clock/imx8mm-clock.h
new file mode 100644
index 000000000000..1b4353e7b486
--- /dev/null
+++ b/include/dt-bindings/clock/imx8mm-clock.h
@@ -0,0 +1,244 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright 2017-2018 NXP
4 */
5
6#ifndef __DT_BINDINGS_CLOCK_IMX8MM_H
7#define __DT_BINDINGS_CLOCK_IMX8MM_H
8
9#define IMX8MM_CLK_DUMMY 0
10#define IMX8MM_CLK_32K 1
11#define IMX8MM_CLK_24M 2
12#define IMX8MM_OSC_HDMI_CLK 3
13#define IMX8MM_CLK_EXT1 4
14#define IMX8MM_CLK_EXT2 5
15#define IMX8MM_CLK_EXT3 6
16#define IMX8MM_CLK_EXT4 7
17#define IMX8MM_AUDIO_PLL1_REF_SEL 8
18#define IMX8MM_AUDIO_PLL2_REF_SEL 9
19#define IMX8MM_VIDEO_PLL1_REF_SEL 10
20#define IMX8MM_DRAM_PLL_REF_SEL 11
21#define IMX8MM_GPU_PLL_REF_SEL 12
22#define IMX8MM_VPU_PLL_REF_SEL 13
23#define IMX8MM_ARM_PLL_REF_SEL 14
24#define IMX8MM_SYS_PLL1_REF_SEL 15
25#define IMX8MM_SYS_PLL2_REF_SEL 16
26#define IMX8MM_SYS_PLL3_REF_SEL 17
27#define IMX8MM_AUDIO_PLL1 18
28#define IMX8MM_AUDIO_PLL2 19
29#define IMX8MM_VIDEO_PLL1 20
30#define IMX8MM_DRAM_PLL 21
31#define IMX8MM_GPU_PLL 22
32#define IMX8MM_VPU_PLL 23
33#define IMX8MM_ARM_PLL 24
34#define IMX8MM_SYS_PLL1 25
35#define IMX8MM_SYS_PLL2 26
36#define IMX8MM_SYS_PLL3 27
37#define IMX8MM_AUDIO_PLL1_BYPASS 28
38#define IMX8MM_AUDIO_PLL2_BYPASS 29
39#define IMX8MM_VIDEO_PLL1_BYPASS 30
40#define IMX8MM_DRAM_PLL_BYPASS 31
41#define IMX8MM_GPU_PLL_BYPASS 32
42#define IMX8MM_VPU_PLL_BYPASS 33
43#define IMX8MM_ARM_PLL_BYPASS 34
44#define IMX8MM_SYS_PLL1_BYPASS 35
45#define IMX8MM_SYS_PLL2_BYPASS 36
46#define IMX8MM_SYS_PLL3_BYPASS 37
47#define IMX8MM_AUDIO_PLL1_OUT 38
48#define IMX8MM_AUDIO_PLL2_OUT 39
49#define IMX8MM_VIDEO_PLL1_OUT 40
50#define IMX8MM_DRAM_PLL_OUT 41
51#define IMX8MM_GPU_PLL_OUT 42
52#define IMX8MM_VPU_PLL_OUT 43
53#define IMX8MM_ARM_PLL_OUT 44
54#define IMX8MM_SYS_PLL1_OUT 45
55#define IMX8MM_SYS_PLL2_OUT 46
56#define IMX8MM_SYS_PLL3_OUT 47
57#define IMX8MM_SYS_PLL1_40M 48
58#define IMX8MM_SYS_PLL1_80M 49
59#define IMX8MM_SYS_PLL1_100M 50
60#define IMX8MM_SYS_PLL1_133M 51
61#define IMX8MM_SYS_PLL1_160M 52
62#define IMX8MM_SYS_PLL1_200M 53
63#define IMX8MM_SYS_PLL1_266M 54
64#define IMX8MM_SYS_PLL1_400M 55
65#define IMX8MM_SYS_PLL1_800M 56
66#define IMX8MM_SYS_PLL2_50M 57
67#define IMX8MM_SYS_PLL2_100M 58
68#define IMX8MM_SYS_PLL2_125M 59
69#define IMX8MM_SYS_PLL2_166M 60
70#define IMX8MM_SYS_PLL2_200M 61
71#define IMX8MM_SYS_PLL2_250M 62
72#define IMX8MM_SYS_PLL2_333M 63
73#define IMX8MM_SYS_PLL2_500M 64
74#define IMX8MM_SYS_PLL2_1000M 65
75
76/* core */
77#define IMX8MM_CLK_A53_SRC 66
78#define IMX8MM_CLK_M4_SRC 67
79#define IMX8MM_CLK_VPU_SRC 68
80#define IMX8MM_CLK_GPU3D_SRC 69
81#define IMX8MM_CLK_GPU2D_SRC 70
82#define IMX8MM_CLK_A53_CG 71
83#define IMX8MM_CLK_M4_CG 72
84#define IMX8MM_CLK_VPU_CG 73
85#define IMX8MM_CLK_GPU3D_CG 74
86#define IMX8MM_CLK_GPU2D_CG 75
87#define IMX8MM_CLK_A53_DIV 76
88#define IMX8MM_CLK_M4_DIV 77
89#define IMX8MM_CLK_VPU_DIV 78
90#define IMX8MM_CLK_GPU3D_DIV 79
91#define IMX8MM_CLK_GPU2D_DIV 80
92
93/* bus */
94#define IMX8MM_CLK_MAIN_AXI 81
95#define IMX8MM_CLK_ENET_AXI 82
96#define IMX8MM_CLK_NAND_USDHC_BUS 83
97#define IMX8MM_CLK_VPU_BUS 84
98#define IMX8MM_CLK_DISP_AXI 85
99#define IMX8MM_CLK_DISP_APB 86
100#define IMX8MM_CLK_DISP_RTRM 87
101#define IMX8MM_CLK_USB_BUS 88
102#define IMX8MM_CLK_GPU_AXI 89
103#define IMX8MM_CLK_GPU_AHB 90
104#define IMX8MM_CLK_NOC 91
105#define IMX8MM_CLK_NOC_APB 92
106
107#define IMX8MM_CLK_AHB 93
108#define IMX8MM_CLK_AUDIO_AHB 94
109#define IMX8MM_CLK_IPG_ROOT 95
110#define IMX8MM_CLK_IPG_AUDIO_ROOT 96
111
112#define IMX8MM_CLK_DRAM_ALT 97
113#define IMX8MM_CLK_DRAM_APB 98
114#define IMX8MM_CLK_VPU_G1 99
115#define IMX8MM_CLK_VPU_G2 100
116#define IMX8MM_CLK_DISP_DTRC 101
117#define IMX8MM_CLK_DISP_DC8000 102
118#define IMX8MM_CLK_PCIE1_CTRL 103
119#define IMX8MM_CLK_PCIE1_PHY 104
120#define IMX8MM_CLK_PCIE1_AUX 105
121#define IMX8MM_CLK_DC_PIXEL 106
122#define IMX8MM_CLK_LCDIF_PIXEL 107
123#define IMX8MM_CLK_SAI1 108
124#define IMX8MM_CLK_SAI2 109
125#define IMX8MM_CLK_SAI3 110
126#define IMX8MM_CLK_SAI4 111
127#define IMX8MM_CLK_SAI5 112
128#define IMX8MM_CLK_SAI6 113
129#define IMX8MM_CLK_SPDIF1 114
130#define IMX8MM_CLK_SPDIF2 115
131#define IMX8MM_CLK_ENET_REF 116
132#define IMX8MM_CLK_ENET_TIMER 117
133#define IMX8MM_CLK_ENET_PHY_REF 118
134#define IMX8MM_CLK_NAND 119
135#define IMX8MM_CLK_QSPI 120
136#define IMX8MM_CLK_USDHC1 121
137#define IMX8MM_CLK_USDHC2 122
138#define IMX8MM_CLK_I2C1 123
139#define IMX8MM_CLK_I2C2 124
140#define IMX8MM_CLK_I2C3 125
141#define IMX8MM_CLK_I2C4 126
142#define IMX8MM_CLK_UART1 127
143#define IMX8MM_CLK_UART2 128
144#define IMX8MM_CLK_UART3 129
145#define IMX8MM_CLK_UART4 130
146#define IMX8MM_CLK_USB_CORE_REF 131
147#define IMX8MM_CLK_USB_PHY_REF 132
148#define IMX8MM_CLK_ECSPI1 133
149#define IMX8MM_CLK_ECSPI2 134
150#define IMX8MM_CLK_PWM1 135
151#define IMX8MM_CLK_PWM2 136
152#define IMX8MM_CLK_PWM3 137
153#define IMX8MM_CLK_PWM4 138
154#define IMX8MM_CLK_GPT1 139
155#define IMX8MM_CLK_WDOG 140
156#define IMX8MM_CLK_WRCLK 141
157#define IMX8MM_CLK_DSI_CORE 142
158#define IMX8MM_CLK_DSI_PHY_REF 143
159#define IMX8MM_CLK_DSI_DBI 144
160#define IMX8MM_CLK_USDHC3 145
161#define IMX8MM_CLK_CSI1_CORE 146
162#define IMX8MM_CLK_CSI1_PHY_REF 147
163#define IMX8MM_CLK_CSI1_ESC 148
164#define IMX8MM_CLK_CSI2_CORE 149
165#define IMX8MM_CLK_CSI2_PHY_REF 150
166#define IMX8MM_CLK_CSI2_ESC 151
167#define IMX8MM_CLK_PCIE2_CTRL 152
168#define IMX8MM_CLK_PCIE2_PHY 153
169#define IMX8MM_CLK_PCIE2_AUX 154
170#define IMX8MM_CLK_ECSPI3 155
171#define IMX8MM_CLK_PDM 156
172#define IMX8MM_CLK_VPU_H1 157
173#define IMX8MM_CLK_CLKO1 158
174
175#define IMX8MM_CLK_ECSPI1_ROOT 159
176#define IMX8MM_CLK_ECSPI2_ROOT 160
177#define IMX8MM_CLK_ECSPI3_ROOT 161
178#define IMX8MM_CLK_ENET1_ROOT 162
179#define IMX8MM_CLK_GPT1_ROOT 163
180#define IMX8MM_CLK_I2C1_ROOT 164
181#define IMX8MM_CLK_I2C2_ROOT 165
182#define IMX8MM_CLK_I2C3_ROOT 166
183#define IMX8MM_CLK_I2C4_ROOT 167
184#define IMX8MM_CLK_OCOTP_ROOT 168
185#define IMX8MM_CLK_PCIE1_ROOT 169
186#define IMX8MM_CLK_PWM1_ROOT 170
187#define IMX8MM_CLK_PWM2_ROOT 171
188#define IMX8MM_CLK_PWM3_ROOT 172
189#define IMX8MM_CLK_PWM4_ROOT 173
190#define IMX8MM_CLK_QSPI_ROOT 174
191#define IMX8MM_CLK_NAND_ROOT 175
192#define IMX8MM_CLK_SAI1_ROOT 176
193#define IMX8MM_CLK_SAI1_IPG 177
194#define IMX8MM_CLK_SAI2_ROOT 178
195#define IMX8MM_CLK_SAI2_IPG 179
196#define IMX8MM_CLK_SAI3_ROOT 180
197#define IMX8MM_CLK_SAI3_IPG 181
198#define IMX8MM_CLK_SAI4_ROOT 182
199#define IMX8MM_CLK_SAI4_IPG 183
200#define IMX8MM_CLK_SAI5_ROOT 184
201#define IMX8MM_CLK_SAI5_IPG 185
202#define IMX8MM_CLK_SAI6_ROOT 186
203#define IMX8MM_CLK_SAI6_IPG 187
204#define IMX8MM_CLK_UART1_ROOT 188
205#define IMX8MM_CLK_UART2_ROOT 189
206#define IMX8MM_CLK_UART3_ROOT 190
207#define IMX8MM_CLK_UART4_ROOT 191
208#define IMX8MM_CLK_USB1_CTRL_ROOT 192
209#define IMX8MM_CLK_GPU3D_ROOT 193
210#define IMX8MM_CLK_USDHC1_ROOT 194
211#define IMX8MM_CLK_USDHC2_ROOT 195
212#define IMX8MM_CLK_WDOG1_ROOT 196
213#define IMX8MM_CLK_WDOG2_ROOT 197
214#define IMX8MM_CLK_WDOG3_ROOT 198
215#define IMX8MM_CLK_VPU_G1_ROOT 199
216#define IMX8MM_CLK_GPU_BUS_ROOT 200
217#define IMX8MM_CLK_VPU_H1_ROOT 201
218#define IMX8MM_CLK_VPU_G2_ROOT 202
219#define IMX8MM_CLK_PDM_ROOT 203
220#define IMX8MM_CLK_DISP_ROOT 204
221#define IMX8MM_CLK_DISP_AXI_ROOT 205
222#define IMX8MM_CLK_DISP_APB_ROOT 206
223#define IMX8MM_CLK_DISP_RTRM_ROOT 207
224#define IMX8MM_CLK_USDHC3_ROOT 208
225#define IMX8MM_CLK_TMU_ROOT 209
226#define IMX8MM_CLK_VPU_DEC_ROOT 210
227#define IMX8MM_CLK_SDMA1_ROOT 211
228#define IMX8MM_CLK_SDMA2_ROOT 212
229#define IMX8MM_CLK_SDMA3_ROOT 213
230#define IMX8MM_CLK_GPT_3M 214
231#define IMX8MM_CLK_ARM 215
232#define IMX8MM_CLK_PDM_IPG 216
233#define IMX8MM_CLK_GPU2D_ROOT 217
234#define IMX8MM_CLK_MU_ROOT 218
235#define IMX8MM_CLK_CSI1_ROOT 219
236
237#define IMX8MM_CLK_DRAM_CORE 220
238#define IMX8MM_CLK_DRAM_ALT_ROOT 221
239
240#define IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK 222
241
242#define IMX8MM_CLK_END 223
243
244#endif
diff --git a/include/dt-bindings/clock/imx8mq-clock.h b/include/dt-bindings/clock/imx8mq-clock.h
index 04f7ac345984..6677e920dc2d 100644
--- a/include/dt-bindings/clock/imx8mq-clock.h
+++ b/include/dt-bindings/clock/imx8mq-clock.h
@@ -245,151 +245,160 @@
245/* USB_CORE_REF */ 245/* USB_CORE_REF */
246#define IMX8MQ_CLK_USB_CORE_REF 152 246#define IMX8MQ_CLK_USB_CORE_REF 152
247/* USB_PHY_REF */ 247/* USB_PHY_REF */
248#define IMX8MQ_CLK_USB_PHY_REF 163 248#define IMX8MQ_CLK_USB_PHY_REF 153
249/* ECSPI1 */ 249/* ECSPI1 */
250#define IMX8MQ_CLK_ECSPI1 164 250#define IMX8MQ_CLK_ECSPI1 154
251/* ECSPI2 */ 251/* ECSPI2 */
252#define IMX8MQ_CLK_ECSPI2 165 252#define IMX8MQ_CLK_ECSPI2 155
253/* PWM1 */ 253/* PWM1 */
254#define IMX8MQ_CLK_PWM1 166 254#define IMX8MQ_CLK_PWM1 156
255/* PWM2 */ 255/* PWM2 */
256#define IMX8MQ_CLK_PWM2 167 256#define IMX8MQ_CLK_PWM2 157
257/* PWM3 */ 257/* PWM3 */
258#define IMX8MQ_CLK_PWM3 168 258#define IMX8MQ_CLK_PWM3 158
259/* PWM4 */ 259/* PWM4 */
260#define IMX8MQ_CLK_PWM4 169 260#define IMX8MQ_CLK_PWM4 159
261/* GPT1 */ 261/* GPT1 */
262#define IMX8MQ_CLK_GPT1 170 262#define IMX8MQ_CLK_GPT1 160
263/* WDOG */ 263/* WDOG */
264#define IMX8MQ_CLK_WDOG 171 264#define IMX8MQ_CLK_WDOG 161
265/* WRCLK */ 265/* WRCLK */
266#define IMX8MQ_CLK_WRCLK 172 266#define IMX8MQ_CLK_WRCLK 162
267/* DSI_CORE */ 267/* DSI_CORE */
268#define IMX8MQ_CLK_DSI_CORE 173 268#define IMX8MQ_CLK_DSI_CORE 163
269/* DSI_PHY */ 269/* DSI_PHY */
270#define IMX8MQ_CLK_DSI_PHY_REF 174 270#define IMX8MQ_CLK_DSI_PHY_REF 164
271/* DSI_DBI */ 271/* DSI_DBI */
272#define IMX8MQ_CLK_DSI_DBI 175 272#define IMX8MQ_CLK_DSI_DBI 165
273/*DSI_ESC */ 273/*DSI_ESC */
274#define IMX8MQ_CLK_DSI_ESC 176 274#define IMX8MQ_CLK_DSI_ESC 166
275/* CSI1_CORE */ 275/* CSI1_CORE */
276#define IMX8MQ_CLK_CSI1_CORE 177 276#define IMX8MQ_CLK_CSI1_CORE 167
277/* CSI1_PHY */ 277/* CSI1_PHY */
278#define IMX8MQ_CLK_CSI1_PHY_REF 178 278#define IMX8MQ_CLK_CSI1_PHY_REF 168
279/* CSI_ESC */ 279/* CSI_ESC */
280#define IMX8MQ_CLK_CSI1_ESC 179 280#define IMX8MQ_CLK_CSI1_ESC 169
281/* CSI2_CORE */ 281/* CSI2_CORE */
282#define IMX8MQ_CLK_CSI2_CORE 170 282#define IMX8MQ_CLK_CSI2_CORE 170
283/* CSI2_PHY */ 283/* CSI2_PHY */
284#define IMX8MQ_CLK_CSI2_PHY_REF 181 284#define IMX8MQ_CLK_CSI2_PHY_REF 171
285/* CSI2_ESC */ 285/* CSI2_ESC */
286#define IMX8MQ_CLK_CSI2_ESC 182 286#define IMX8MQ_CLK_CSI2_ESC 172
287/* PCIE2_CTRL */ 287/* PCIE2_CTRL */
288#define IMX8MQ_CLK_PCIE2_CTRL 183 288#define IMX8MQ_CLK_PCIE2_CTRL 173
289/* PCIE2_PHY */ 289/* PCIE2_PHY */
290#define IMX8MQ_CLK_PCIE2_PHY 184 290#define IMX8MQ_CLK_PCIE2_PHY 174
291/* PCIE2_AUX */ 291/* PCIE2_AUX */
292#define IMX8MQ_CLK_PCIE2_AUX 185 292#define IMX8MQ_CLK_PCIE2_AUX 175
293/* ECSPI3 */ 293/* ECSPI3 */
294#define IMX8MQ_CLK_ECSPI3 186 294#define IMX8MQ_CLK_ECSPI3 176
295 295
296/* CCGR clocks */ 296/* CCGR clocks */
297#define IMX8MQ_CLK_A53_ROOT 187 297#define IMX8MQ_CLK_A53_ROOT 177
298#define IMX8MQ_CLK_DRAM_ROOT 188 298#define IMX8MQ_CLK_DRAM_ROOT 178
299#define IMX8MQ_CLK_ECSPI1_ROOT 189 299#define IMX8MQ_CLK_ECSPI1_ROOT 179
300#define IMX8MQ_CLK_ECSPI2_ROOT 180 300#define IMX8MQ_CLK_ECSPI2_ROOT 180
301#define IMX8MQ_CLK_ECSPI3_ROOT 181 301#define IMX8MQ_CLK_ECSPI3_ROOT 181
302#define IMX8MQ_CLK_ENET1_ROOT 182 302#define IMX8MQ_CLK_ENET1_ROOT 182
303#define IMX8MQ_CLK_GPT1_ROOT 193 303#define IMX8MQ_CLK_GPT1_ROOT 183
304#define IMX8MQ_CLK_I2C1_ROOT 194 304#define IMX8MQ_CLK_I2C1_ROOT 184
305#define IMX8MQ_CLK_I2C2_ROOT 195 305#define IMX8MQ_CLK_I2C2_ROOT 185
306#define IMX8MQ_CLK_I2C3_ROOT 196 306#define IMX8MQ_CLK_I2C3_ROOT 186
307#define IMX8MQ_CLK_I2C4_ROOT 197 307#define IMX8MQ_CLK_I2C4_ROOT 187
308#define IMX8MQ_CLK_M4_ROOT 198 308#define IMX8MQ_CLK_M4_ROOT 188
309#define IMX8MQ_CLK_PCIE1_ROOT 199 309#define IMX8MQ_CLK_PCIE1_ROOT 189
310#define IMX8MQ_CLK_PCIE2_ROOT 200 310#define IMX8MQ_CLK_PCIE2_ROOT 190
311#define IMX8MQ_CLK_PWM1_ROOT 201 311#define IMX8MQ_CLK_PWM1_ROOT 191
312#define IMX8MQ_CLK_PWM2_ROOT 202 312#define IMX8MQ_CLK_PWM2_ROOT 192
313#define IMX8MQ_CLK_PWM3_ROOT 203 313#define IMX8MQ_CLK_PWM3_ROOT 193
314#define IMX8MQ_CLK_PWM4_ROOT 204 314#define IMX8MQ_CLK_PWM4_ROOT 194
315#define IMX8MQ_CLK_QSPI_ROOT 205 315#define IMX8MQ_CLK_QSPI_ROOT 195
316#define IMX8MQ_CLK_SAI1_ROOT 206 316#define IMX8MQ_CLK_SAI1_ROOT 196
317#define IMX8MQ_CLK_SAI2_ROOT 207 317#define IMX8MQ_CLK_SAI2_ROOT 197
318#define IMX8MQ_CLK_SAI3_ROOT 208 318#define IMX8MQ_CLK_SAI3_ROOT 198
319#define IMX8MQ_CLK_SAI4_ROOT 209 319#define IMX8MQ_CLK_SAI4_ROOT 199
320#define IMX8MQ_CLK_SAI5_ROOT 210 320#define IMX8MQ_CLK_SAI5_ROOT 200
321#define IMX8MQ_CLK_SAI6_ROOT 212 321#define IMX8MQ_CLK_SAI6_ROOT 201
322#define IMX8MQ_CLK_UART1_ROOT 213 322#define IMX8MQ_CLK_UART1_ROOT 202
323#define IMX8MQ_CLK_UART2_ROOT 214 323#define IMX8MQ_CLK_UART2_ROOT 203
324#define IMX8MQ_CLK_UART3_ROOT 215 324#define IMX8MQ_CLK_UART3_ROOT 204
325#define IMX8MQ_CLK_UART4_ROOT 216 325#define IMX8MQ_CLK_UART4_ROOT 205
326#define IMX8MQ_CLK_USB1_CTRL_ROOT 217 326#define IMX8MQ_CLK_USB1_CTRL_ROOT 206
327#define IMX8MQ_CLK_USB2_CTRL_ROOT 218 327#define IMX8MQ_CLK_USB2_CTRL_ROOT 207
328#define IMX8MQ_CLK_USB1_PHY_ROOT 219 328#define IMX8MQ_CLK_USB1_PHY_ROOT 208
329#define IMX8MQ_CLK_USB2_PHY_ROOT 220 329#define IMX8MQ_CLK_USB2_PHY_ROOT 209
330#define IMX8MQ_CLK_USDHC1_ROOT 221 330#define IMX8MQ_CLK_USDHC1_ROOT 210
331#define IMX8MQ_CLK_USDHC2_ROOT 222 331#define IMX8MQ_CLK_USDHC2_ROOT 211
332#define IMX8MQ_CLK_WDOG1_ROOT 223 332#define IMX8MQ_CLK_WDOG1_ROOT 212
333#define IMX8MQ_CLK_WDOG2_ROOT 224 333#define IMX8MQ_CLK_WDOG2_ROOT 213
334#define IMX8MQ_CLK_WDOG3_ROOT 225 334#define IMX8MQ_CLK_WDOG3_ROOT 214
335#define IMX8MQ_CLK_GPU_ROOT 226 335#define IMX8MQ_CLK_GPU_ROOT 215
336#define IMX8MQ_CLK_HEVC_ROOT 227 336#define IMX8MQ_CLK_HEVC_ROOT 216
337#define IMX8MQ_CLK_AVC_ROOT 228 337#define IMX8MQ_CLK_AVC_ROOT 217
338#define IMX8MQ_CLK_VP9_ROOT 229 338#define IMX8MQ_CLK_VP9_ROOT 218
339#define IMX8MQ_CLK_HEVC_INTER_ROOT 230 339#define IMX8MQ_CLK_HEVC_INTER_ROOT 219
340#define IMX8MQ_CLK_DISP_ROOT 231 340#define IMX8MQ_CLK_DISP_ROOT 220
341#define IMX8MQ_CLK_HDMI_ROOT 232 341#define IMX8MQ_CLK_HDMI_ROOT 221
342#define IMX8MQ_CLK_HDMI_PHY_ROOT 233 342#define IMX8MQ_CLK_HDMI_PHY_ROOT 222
343#define IMX8MQ_CLK_VPU_DEC_ROOT 234 343#define IMX8MQ_CLK_VPU_DEC_ROOT 223
344#define IMX8MQ_CLK_CSI1_ROOT 235 344#define IMX8MQ_CLK_CSI1_ROOT 224
345#define IMX8MQ_CLK_CSI2_ROOT 236 345#define IMX8MQ_CLK_CSI2_ROOT 225
346#define IMX8MQ_CLK_RAWNAND_ROOT 237 346#define IMX8MQ_CLK_RAWNAND_ROOT 226
347#define IMX8MQ_CLK_SDMA1_ROOT 238 347#define IMX8MQ_CLK_SDMA1_ROOT 227
348#define IMX8MQ_CLK_SDMA2_ROOT 239 348#define IMX8MQ_CLK_SDMA2_ROOT 228
349#define IMX8MQ_CLK_VPU_G1_ROOT 240 349#define IMX8MQ_CLK_VPU_G1_ROOT 229
350#define IMX8MQ_CLK_VPU_G2_ROOT 241 350#define IMX8MQ_CLK_VPU_G2_ROOT 230
351 351
352/* SCCG PLL GATE */ 352/* SCCG PLL GATE */
353#define IMX8MQ_SYS1_PLL_OUT 242 353#define IMX8MQ_SYS1_PLL_OUT 231
354#define IMX8MQ_SYS2_PLL_OUT 243 354#define IMX8MQ_SYS2_PLL_OUT 232
355#define IMX8MQ_SYS3_PLL_OUT 244 355#define IMX8MQ_SYS3_PLL_OUT 233
356#define IMX8MQ_DRAM_PLL_OUT 245 356#define IMX8MQ_DRAM_PLL_OUT 234
357 357
358#define IMX8MQ_GPT_3M_CLK 246 358#define IMX8MQ_GPT_3M_CLK 235
359 359
360#define IMX8MQ_CLK_IPG_ROOT 247 360#define IMX8MQ_CLK_IPG_ROOT 236
361#define IMX8MQ_CLK_IPG_AUDIO_ROOT 248 361#define IMX8MQ_CLK_IPG_AUDIO_ROOT 237
362#define IMX8MQ_CLK_SAI1_IPG 249 362#define IMX8MQ_CLK_SAI1_IPG 238
363#define IMX8MQ_CLK_SAI2_IPG 250 363#define IMX8MQ_CLK_SAI2_IPG 239
364#define IMX8MQ_CLK_SAI3_IPG 251 364#define IMX8MQ_CLK_SAI3_IPG 240
365#define IMX8MQ_CLK_SAI4_IPG 252 365#define IMX8MQ_CLK_SAI4_IPG 241
366#define IMX8MQ_CLK_SAI5_IPG 253 366#define IMX8MQ_CLK_SAI5_IPG 242
367#define IMX8MQ_CLK_SAI6_IPG 254 367#define IMX8MQ_CLK_SAI6_IPG 243
368 368
369/* DSI AHB/IPG clocks */ 369/* DSI AHB/IPG clocks */
370/* rxesc clock */ 370/* rxesc clock */
371#define IMX8MQ_CLK_DSI_AHB 255 371#define IMX8MQ_CLK_DSI_AHB 244
372/* txesc clock */ 372/* txesc clock */
373#define IMX8MQ_CLK_DSI_IPG_DIV 256 373#define IMX8MQ_CLK_DSI_IPG_DIV 245
374 374
375#define IMX8MQ_CLK_TMU_ROOT 257 375#define IMX8MQ_CLK_TMU_ROOT 246
376 376
377/* Display root clocks */ 377/* Display root clocks */
378#define IMX8MQ_CLK_DISP_AXI_ROOT 258 378#define IMX8MQ_CLK_DISP_AXI_ROOT 247
379#define IMX8MQ_CLK_DISP_APB_ROOT 259 379#define IMX8MQ_CLK_DISP_APB_ROOT 248
380#define IMX8MQ_CLK_DISP_RTRM_ROOT 260 380#define IMX8MQ_CLK_DISP_RTRM_ROOT 249
381 381
382#define IMX8MQ_CLK_OCOTP_ROOT 261 382#define IMX8MQ_CLK_OCOTP_ROOT 250
383 383
384#define IMX8MQ_CLK_DRAM_ALT_ROOT 262 384#define IMX8MQ_CLK_DRAM_ALT_ROOT 251
385#define IMX8MQ_CLK_DRAM_CORE 263 385#define IMX8MQ_CLK_DRAM_CORE 252
386 386
387#define IMX8MQ_CLK_MU_ROOT 264 387#define IMX8MQ_CLK_MU_ROOT 253
388#define IMX8MQ_VIDEO2_PLL_OUT 265 388#define IMX8MQ_VIDEO2_PLL_OUT 254
389 389
390#define IMX8MQ_CLK_CLKO2 266 390#define IMX8MQ_CLK_CLKO2 255
391 391
392#define IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK 267 392#define IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK 256
393 393
394#define IMX8MQ_CLK_END 268 394#define IMX8MQ_CLK_CLKO1 257
395#define IMX8MQ_CLK_ARM 258
396
397#define IMX8MQ_CLK_GPIO1_ROOT 259
398#define IMX8MQ_CLK_GPIO2_ROOT 260
399#define IMX8MQ_CLK_GPIO3_ROOT 261
400#define IMX8MQ_CLK_GPIO4_ROOT 262
401#define IMX8MQ_CLK_GPIO5_ROOT 263
402
403#define IMX8MQ_CLK_END 264
395#endif /* __DT_BINDINGS_CLOCK_IMX8MQ_H */ 404#endif /* __DT_BINDINGS_CLOCK_IMX8MQ_H */
diff --git a/include/dt-bindings/clock/marvell,mmp2.h b/include/dt-bindings/clock/marvell,mmp2.h
index 228a5e234af0..e785c6eb3561 100644
--- a/include/dt-bindings/clock/marvell,mmp2.h
+++ b/include/dt-bindings/clock/marvell,mmp2.h
@@ -71,6 +71,7 @@
71#define MMP2_CLK_CCIC1_MIX 117 71#define MMP2_CLK_CCIC1_MIX 117
72#define MMP2_CLK_CCIC1_PHY 118 72#define MMP2_CLK_CCIC1_PHY 118
73#define MMP2_CLK_CCIC1_SPHY 119 73#define MMP2_CLK_CCIC1_SPHY 119
74#define MMP2_CLK_DISP0_LCDC 120
74 75
75#define MMP2_NR_CLKS 200 76#define MMP2_NR_CLKS 200
76#endif 77#endif
diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h
index 5fe2923382d0..8067077a62ca 100644
--- a/include/dt-bindings/clock/meson8b-clkc.h
+++ b/include/dt-bindings/clock/meson8b-clkc.h
@@ -104,6 +104,7 @@
104#define CLKID_MPLL2 95 104#define CLKID_MPLL2 95
105#define CLKID_NAND_CLK 112 105#define CLKID_NAND_CLK 112
106#define CLKID_ABP 124 106#define CLKID_ABP 124
107#define CLKID_APB 124
107#define CLKID_PERIPH 126 108#define CLKID_PERIPH 126
108#define CLKID_AXI 128 109#define CLKID_AXI 128
109#define CLKID_L2_DRAM 130 110#define CLKID_L2_DRAM 130
diff --git a/include/dt-bindings/clock/mt2712-clk.h b/include/dt-bindings/clock/mt2712-clk.h
index 76265836a1e1..c3b29dff9c0e 100644
--- a/include/dt-bindings/clock/mt2712-clk.h
+++ b/include/dt-bindings/clock/mt2712-clk.h
@@ -228,7 +228,8 @@
228#define CLK_TOP_NFI2X_EN 189 228#define CLK_TOP_NFI2X_EN 189
229#define CLK_TOP_NFIECC_EN 190 229#define CLK_TOP_NFIECC_EN 190
230#define CLK_TOP_NFI1X_CK_EN 191 230#define CLK_TOP_NFI1X_CK_EN 191
231#define CLK_TOP_NR_CLK 192 231#define CLK_TOP_APLL2_D3 192
232#define CLK_TOP_NR_CLK 193
232 233
233/* INFRACFG */ 234/* INFRACFG */
234 235
diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h
index 8aea623dd518..76e4e5b65353 100644
--- a/include/dt-bindings/clock/mt8173-clk.h
+++ b/include/dt-bindings/clock/mt8173-clk.h
@@ -194,7 +194,8 @@
194#define CLK_INFRA_PMICWRAP 11 194#define CLK_INFRA_PMICWRAP 11
195#define CLK_INFRA_CLK_13M 12 195#define CLK_INFRA_CLK_13M 12
196#define CLK_INFRA_CA53SEL 13 196#define CLK_INFRA_CA53SEL 13
197#define CLK_INFRA_CA57SEL 14 197#define CLK_INFRA_CA57SEL 14 /* Deprecated. Don't use it. */
198#define CLK_INFRA_CA72SEL 14
198#define CLK_INFRA_NR_CLK 15 199#define CLK_INFRA_NR_CLK 15
199 200
200/* PERI_SYS */ 201/* PERI_SYS */
diff --git a/include/dt-bindings/clock/qcom,rpmcc.h b/include/dt-bindings/clock/qcom,rpmcc.h
index 3658b0c14966..ede93a0ca156 100644
--- a/include/dt-bindings/clock/qcom,rpmcc.h
+++ b/include/dt-bindings/clock/qcom,rpmcc.h
@@ -127,5 +127,15 @@
127#define RPM_SMD_BIMC_GPU_A_CLK 77 127#define RPM_SMD_BIMC_GPU_A_CLK 77
128#define RPM_SMD_QPIC_CLK 78 128#define RPM_SMD_QPIC_CLK 78
129#define RPM_SMD_QPIC_CLK_A 79 129#define RPM_SMD_QPIC_CLK_A 79
130#define RPM_SMD_LN_BB_CLK1 80
131#define RPM_SMD_LN_BB_CLK1_A 81
132#define RPM_SMD_LN_BB_CLK2 82
133#define RPM_SMD_LN_BB_CLK2_A 83
134#define RPM_SMD_LN_BB_CLK3_PIN 84
135#define RPM_SMD_LN_BB_CLK3_A_PIN 85
136#define RPM_SMD_RF_CLK3 86
137#define RPM_SMD_RF_CLK3_A 87
138#define RPM_SMD_RF_CLK3_PIN 88
139#define RPM_SMD_RF_CLK3_A_PIN 89
130 140
131#endif 141#endif
diff --git a/include/dt-bindings/clock/qcom,rpmh.h b/include/dt-bindings/clock/qcom,rpmh.h
index f48fbd6f2095..edcab3f7b7d3 100644
--- a/include/dt-bindings/clock/qcom,rpmh.h
+++ b/include/dt-bindings/clock/qcom,rpmh.h
@@ -18,5 +18,6 @@
18#define RPMH_RF_CLK2_A 9 18#define RPMH_RF_CLK2_A 9
19#define RPMH_RF_CLK3 10 19#define RPMH_RF_CLK3 10
20#define RPMH_RF_CLK3_A 11 20#define RPMH_RF_CLK3_A 11
21#define RPMH_IPA_CLK 12
21 22
22#endif 23#endif
diff --git a/include/dt-bindings/clock/r8a774a1-cpg-mssr.h b/include/dt-bindings/clock/r8a774a1-cpg-mssr.h
index 9bc5d45ff4b5..e355363f40c2 100644
--- a/include/dt-bindings/clock/r8a774a1-cpg-mssr.h
+++ b/include/dt-bindings/clock/r8a774a1-cpg-mssr.h
@@ -54,5 +54,6 @@
54#define R8A774A1_CLK_CPEX 43 54#define R8A774A1_CLK_CPEX 43
55#define R8A774A1_CLK_R 44 55#define R8A774A1_CLK_R 44
56#define R8A774A1_CLK_OSC 45 56#define R8A774A1_CLK_OSC 45
57#define R8A774A1_CLK_CANFD 46
57 58
58#endif /* __DT_BINDINGS_CLOCK_R8A774A1_CPG_MSSR_H__ */ 59#endif /* __DT_BINDINGS_CLOCK_R8A774A1_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/r8a774c0-cpg-mssr.h b/include/dt-bindings/clock/r8a774c0-cpg-mssr.h
index 8fe51b6aca28..8ad9cd6be8e9 100644
--- a/include/dt-bindings/clock/r8a774c0-cpg-mssr.h
+++ b/include/dt-bindings/clock/r8a774c0-cpg-mssr.h
@@ -56,5 +56,6 @@
56#define R8A774C0_CLK_CSI0 45 56#define R8A774C0_CLK_CSI0 45
57#define R8A774C0_CLK_CP 46 57#define R8A774C0_CLK_CP 46
58#define R8A774C0_CLK_CPEX 47 58#define R8A774C0_CLK_CPEX 47
59#define R8A774C0_CLK_CANFD 48
59 60
60#endif /* __DT_BINDINGS_CLOCK_R8A774C0_CPG_MSSR_H__ */ 61#endif /* __DT_BINDINGS_CLOCK_R8A774C0_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h
index 90ec780bfc68..4cdaf135829c 100644
--- a/include/dt-bindings/clock/stm32mp1-clks.h
+++ b/include/dt-bindings/clock/stm32mp1-clks.h
@@ -248,7 +248,4 @@
248 248
249#define STM32MP1_LAST_CLK 232 249#define STM32MP1_LAST_CLK 232
250 250
251#define LTDC_K LTDC_PX
252#define ETHMAC_K ETHCK_K
253
254#endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */ 251#endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */
diff --git a/include/dt-bindings/reset/g12a-aoclkc.h b/include/dt-bindings/reset/g12a-aoclkc.h
new file mode 100644
index 000000000000..bd2e2337135c
--- /dev/null
+++ b/include/dt-bindings/reset/g12a-aoclkc.h
@@ -0,0 +1,18 @@
1/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
2/*
3 * Copyright (c) 2016 BayLibre, SAS
4 * Author: Neil Armstrong <narmstrong@baylibre.com>
5 */
6
7#ifndef DT_BINDINGS_RESET_AMLOGIC_MESON_G12A_AOCLK
8#define DT_BINDINGS_RESET_AMLOGIC_MESON_G12A_AOCLK
9
10#define RESET_AO_IR_IN 0
11#define RESET_AO_UART 1
12#define RESET_AO_I2C_M 2
13#define RESET_AO_I2C_S 3
14#define RESET_AO_SAR_ADC 4
15#define RESET_AO_UART2 5
16#define RESET_AO_IR_OUT 6
17
18#endif
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index e443fa9fa859..b7cf80a71293 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -792,6 +792,9 @@ unsigned int __clk_get_enable_count(struct clk *clk);
792unsigned long clk_hw_get_rate(const struct clk_hw *hw); 792unsigned long clk_hw_get_rate(const struct clk_hw *hw);
793unsigned long __clk_get_flags(struct clk *clk); 793unsigned long __clk_get_flags(struct clk *clk);
794unsigned long clk_hw_get_flags(const struct clk_hw *hw); 794unsigned long clk_hw_get_flags(const struct clk_hw *hw);
795#define clk_hw_can_set_rate_parent(hw) \
796 (clk_hw_get_flags((hw)) & CLK_SET_RATE_PARENT)
797
795bool clk_hw_is_prepared(const struct clk_hw *hw); 798bool clk_hw_is_prepared(const struct clk_hw *hw);
796bool clk_hw_rate_is_protected(const struct clk_hw *hw); 799bool clk_hw_rate_is_protected(const struct clk_hw *hw);
797bool clk_hw_is_enabled(const struct clk_hw *hw); 800bool clk_hw_is_enabled(const struct clk_hw *hw);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index a7773b5c0b9f..d8bc1a856b39 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -384,6 +384,17 @@ int __must_check devm_clk_bulk_get_all(struct device *dev,
384struct clk *devm_clk_get(struct device *dev, const char *id); 384struct clk *devm_clk_get(struct device *dev, const char *id);
385 385
386/** 386/**
387 * devm_clk_get_optional - lookup and obtain a managed reference to an optional
388 * clock producer.
389 * @dev: device for clock "consumer"
390 * @id: clock consumer ID
391 *
392 * Behaves the same as devm_clk_get() except where there is no clock producer.
393 * In this case, instead of returning -ENOENT, the function returns NULL.
394 */
395struct clk *devm_clk_get_optional(struct device *dev, const char *id);
396
397/**
387 * devm_get_clk_from_child - lookup and obtain a managed reference to a 398 * devm_get_clk_from_child - lookup and obtain a managed reference to a
388 * clock producer from child node. 399 * clock producer from child node.
389 * @dev: device for clock "consumer" 400 * @dev: device for clock "consumer"
@@ -718,6 +729,12 @@ static inline struct clk *devm_clk_get(struct device *dev, const char *id)
718 return NULL; 729 return NULL;
719} 730}
720 731
732static inline struct clk *devm_clk_get_optional(struct device *dev,
733 const char *id)
734{
735 return NULL;
736}
737
721static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, 738static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
722 struct clk_bulk_data *clks) 739 struct clk_bulk_data *clks)
723{ 740{
@@ -862,6 +879,25 @@ static inline void clk_bulk_disable_unprepare(int num_clks,
862 clk_bulk_unprepare(num_clks, clks); 879 clk_bulk_unprepare(num_clks, clks);
863} 880}
864 881
882/**
883 * clk_get_optional - lookup and obtain a reference to an optional clock
884 * producer.
885 * @dev: device for clock "consumer"
886 * @id: clock consumer ID
887 *
888 * Behaves the same as clk_get() except where there is no clock producer. In
889 * this case, instead of returning -ENOENT, the function returns NULL.
890 */
891static inline struct clk *clk_get_optional(struct device *dev, const char *id)
892{
893 struct clk *clk = clk_get(dev, id);
894
895 if (clk == ERR_PTR(-ENOENT))
896 return NULL;
897
898 return clk;
899}
900
865#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) 901#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
866struct clk *of_clk_get(struct device_node *np, int index); 902struct clk *of_clk_get(struct device_node *np, int index);
867struct clk *of_clk_get_by_name(struct device_node *np, const char *name); 903struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index eacc5df57b99..78872efc7be0 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -160,6 +160,7 @@ struct clk_hw_omap {
160 struct clockdomain *clkdm; 160 struct clockdomain *clkdm;
161 const struct clk_hw_omap_ops *ops; 161 const struct clk_hw_omap_ops *ops;
162 u32 context; 162 u32 context;
163 int autoidle_count;
163}; 164};
164 165
165/* 166/*
diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
index 4890ff033220..ccb32af5848b 100644
--- a/include/linux/clkdev.h
+++ b/include/linux/clkdev.h
@@ -52,4 +52,8 @@ int clk_add_alias(const char *, const char *, const char *, struct device *);
52int clk_register_clkdev(struct clk *, const char *, const char *); 52int clk_register_clkdev(struct clk *, const char *, const char *);
53int clk_hw_register_clkdev(struct clk_hw *, const char *, const char *); 53int clk_hw_register_clkdev(struct clk_hw *, const char *, const char *);
54 54
55int devm_clk_hw_register_clkdev(struct device *dev, struct clk_hw *hw,
56 const char *con_id, const char *dev_id);
57void devm_clk_release_clkdev(struct device *dev, const char *con_id,
58 const char *dev_id);
55#endif 59#endif
diff --git a/include/linux/platform_data/clk-lpss.h b/include/linux/platform_data/x86/clk-lpss.h
index 23901992b9dd..23901992b9dd 100644
--- a/include/linux/platform_data/clk-lpss.h
+++ b/include/linux/platform_data/x86/clk-lpss.h